8000 Feature/david/fdroid compliance (#1107) · libandroid/Android@9db2c67 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9db2c67

Browse files
authored
Feature/david/fdroid compliance (duckduckgo#1107)
* adding new flavor to differentiate between play store and fdroid * separating referrer listener for each of the stores * cleaning up naming convention * updated fastlane release file
1 parent 088dd73 commit 9db2c67

File tree

9 files changed

+321
-173
lines changed

9 files changed

+321
-173
lines changed

app/build.gradle

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ android {
6262
]
6363
}
6464
}
65+
flavorDimensions "store"
66+
productFlavors {
67+
fdroid{
68+
dimension "store"
69+
}
70+
play{
71+
dimension "store"
72+
}
73+
}
74+
variantFilter { variant ->
75+
def names = variant.flavors*.name
76+
if (names.contains("fdroid") && variant.buildType.name == "debug") {
77+
// We only need the F-Droid release version
78+
setIgnore(true)
79+
}
80+
}
6581
externalNativeBuild {
6682

6783
cmake {
@@ -178,7 +194,7 @@ dependencies {
178194
implementation "com.airbnb.android:lottie:_"
179195

180196
// Play Store referrer library
181-
implementation("com.android.installreferrer:installreferrer:_")
197+
playImplementation("com.android.installreferrer:installreferrer:_")
182198

183199
// Testing dependencies
184200
androidTestImplementation AndroidX.test.runner

app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import javax.inject.Singleton
7373
AppUsageModule::class,
7474
FileModule::class,
7575
UncaughtExceptionModule::class,
76-
PlayStoreReferralModule::class,
76+
StoreReferralModule::class,
7777
CoroutinesModule::class,
7878
CertificateTrustedStoreModule::class,
7979
WelcomePageModule::class
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2019 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.di
18+
19+
import android.content.Context
20+
import com.duckduckgo.app.referral.*
21+
import com.duckduckgo.app.statistics.AtbInitializerListener
22+
import com.duckduckgo.referral.FDroidReferrerStateListener
23+
import dagger.Module
24+
import dagger.Provides
25+
import dagger.multibindings.IntoSet
26+
import javax.inject.Singleton
27+
28+
@Module
29+
class StoreReferralModule {
30+
31+
@Provides
32+
fun appInstallationReferrerParser(): AppInstallationReferrerParser {
33+
return QueryParamReferrerParser()
34+
}
35+
36+
@Provides
37+
@Singleton
38+
fun appInstallationReferrerStateListener(
39+
referrerStateListener: FDroidReferrerStateListener
40+
): AppInstallationReferrerStateListener = referrerStateListener
41+
42+
@Provides
43+
@IntoSet
44+
fun providedReferrerAtbInitializerListener(
45+
referrerStateListener: FDroidReferrerStateListener
46+
): AtbInitializerListener = referrerStateListener
47+
48+
@Provides
49+
@Singleton
50+
fun appReferrerDataStore(context: Context): AppReferrerDataStore {
51+
return AppReferenceSharePreferences(context)
52+
}
53+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2019 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.referral
18+
19+
import com.duckduckgo.app.referral.*
20+
import com.duckduckgo.app.referral.AppInstallationReferrerStateListener.Companion.MAX_REFERRER_WAIT_TIME_MS
21+
import com.duckduckgo.app.referral.ParsedReferrerResult.*
22+
import com.duckduckgo.app.statistics.AtbInitializerListener
23+
import timber.log.Timber
24+
import javax.inject.Inject
25+
import javax.inject.Singleton
26+
27+
@Singleton
28+
class FDroidReferrerStateListener @Inject constructor() : AppInstallationReferrerStateListener, AtbInitializerListener {
29+
30+
private var referralResult: ParsedReferrerResult = ReferrerInitialising
31+
32+
/**
33+
* Initialises the referrer service. This should only be called once.
34+
*/
35+
override fun initialiseReferralRetrieval() {
36+
Timber.d("Referrer from F-Droid, nothing to do here")
37+
referralResult = ReferrerNotFound()
38+
}
39+
40+
/**
41+
* Retrieves the app installation referral code.
42+
* This might return a result immediately or might wait for a result to become available. There is no guarantee that a result will ever be returned.
43+
*
44+
* It is the caller's responsibility to guard against this function not returning a result in a timely manner, or not returning a result ever.
45+
*/
46+
override suspend fun waitForReferrerCode(): ParsedReferrerResult {
47+
if (referralResult != ReferrerInitialising) {
48+
Timber.d("Referrer already determined; immediately answering")
49+
return referralResult
50+
}
51+
52+
return referralResult
53+
}
54+
55+
override suspend fun beforeAtbInit() {
56+
waitForReferrerCode()
57+
}
58+
59+
override fun beforeAtbInitTimeoutMillis(): Long = MAX_REFERRER_WAIT_TIME_MS
60+
}

app/src/main/java/com/duckduckgo/app/di/AppComponent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ import javax.inject.Singleton
7171
AppUsageModule::class,
7272
FileModule::class,
7373
UncaughtExceptionModule::class,
74-
PlayStoreReferralModule::class,
74+
StoreReferralModule::class,
7575
CoroutinesModule::class,
7676
CertificateTrustedStoreModule::class,
7777
WelcomePageModule::class

app/src/main/java/com/duckduckgo/app/referral/AppInstallationReferrerStateListener.kt

Lines changed: 0 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,6 @@
1616

1717
package com.duckduckgo.app.referral
1818

19-
import android.content.ComponentName
20-
import android.content.Context
21-
import android.content.Intent
22-
import android.content.pm.PackageManager
23-
import com.android.installreferrer.api.InstallReferrerClient
24-
import com.android.installreferrer.api.InstallReferrerClient.InstallReferrerResponse.*
25-
import com.android.installreferrer.api.InstallReferrerStateListener
26-
import com.duckduckgo.app.playstore.PlayStoreAndroidUtils.Companion.PLAY_STORE_PACKAGE
27-
import com.duckduckgo.app.playstore.PlayStoreAndroidUtils.Companion.PLAY_STORE_REFERRAL_SERVICE
28-
import com.duckduckgo.app.referral.AppInstallationReferrerStateListener.Companion.MAX_REFERRER_WAIT_TIME_MS
29-
import com.duckduckgo.app.referral.ParseFailureReason.*
30-
import com.duckduckgo.app.referral.ParsedReferrerResult.*
31-
import com.duckduckgo.app.statistics.AtbInitializerListener
32-
import com.duckduckgo.app.statistics.VariantManager
33-
import kotlinx.coroutines.delay
34-
import timber.log.Timber
35-
import javax.inject.Inject
36-
import javax.inject.Singleton
37-
3819
interface AppInstallationReferrerStateListener {
3920

4021
fun initialiseReferralRetrieval()
@@ -45,151 +26,3 @@ interface AppInstallationReferrerStateListener {
4526
}
4627

4728
}
48-
49-
@Singleton
50-
class PlayStoreAppReferrerStateListener @Inject constructor(
51-
val context: Context,
52-
private val packageManager: PackageManager,
53-
private val appInstallationReferrerParser: AppInstallationReferrerParser,
54-
private val appReferrerDataStore: AppReferrerDataStore,
55-
private val variantManager: VariantManager
56-
) : InstallReferrerStateListener, AppInstallationReferrerStateListener, AtbInitializerListener {
57-
58-
private val referralClient = InstallReferrerClient.newBuilder(context).build()
59-
private var initialisationStartTime: Long = 0
60-
61-
private var referralResult: ParsedReferrerResult = ReferrerInitialising
62-
63-
/**
64-
* Initialises the referrer service. This should only be called once.
65-
*/
66-
override fun initialiseReferralRetrieval() {
67-
try {
68-
initialisationStartTime = System.currentTimeMillis()
69-
70-
if (appReferrerDataStore.referrerCheckedPreviously) {
71-
72-
referralResult = if (appReferrerDataStore.installedFromEuAuction) {
73-
EuAuctionReferrerFound(fromCache = true)
74-
} else {
75-
loadPreviousReferrerData()
76-
}
77-
78-
Timber.i("Already inspected this referrer data")
79-
return
80-
}
81-
82-
if (playStoreReferralServiceInstalled()) {
83-
referralClient.startConnection(this)
84-
} else {
85-
referralResult = ParseFailure(ReferralServiceUnavailable)
86-
}
87-
} catch (e: RuntimeException) {
88-
Timber.w(e, "Failed to obtain referrer information")
89-
referralResult = ParseFailure(UnknownError)
90-
}
91-
}
92-
93-
private fun loadPreviousReferrerData(): ParsedReferrerResult {
94-
val suffix = loadFromDataStore()
95-
return if (suffix == null) {
96-
Timber.i("Already saw referrer data, but no campaign suffix saved")
97-
ReferrerNotFound(fromCache = true)
98-
} else {
99-
Timber.i("Already have referrer data from previous run - $suffix")
100-
CampaignReferrerFound(suffix, fromCache = true)
101-
}
102-
}
103-
104-
override fun onInstallReferrerSetupFinished(responseCode: Int) {
105-
val referrerRetrievalDurationMs = System.currentTimeMillis() - initialisationStartTime
106-
Timber.i("Took ${referrerRetrievalDurationMs}ms to get initial referral data callback")
107-
try {
108-
when (responseCode) {
109-
OK -> {
110-
Timber.d("Successfully connected to Referrer service")
111-
val response = referralClient.installReferrer
112-
val referrer = response.installReferrer
113-
val parsedResult = appInstallationReferrerParser.parse(referrer)
114-
referralResultReceived(parsedResult)
115-
}
116-
FEATURE_NOT_SUPPORTED -> referralResultFailed(FeatureNotSupported)
117-
SERVICE_UNAVAILABLE -> referralResultFailed(ServiceUnavailable)
118-
DEVELOPER_ERROR -> referralResultFailed(DeveloperError)
119-
SERVICE_DISCONNECTED -> referralResultFailed(ServiceDisconnected)
120-
else -> referralResultFailed(UnknownError)
121-
122-
}
123-
124-
referralClient.endConnection()
125-
} catch (e: RuntimeException) {
126-
Timber.w(e, "Failed to retrieve referrer data")
127-
referralResultFailed(UnknownError)
128-
}
129-
}
130-
131-
/**
132-
* Retrieves the app installation referral code.
133-
* This might return a result immediately or might wait for a result to become available. There is no guarantee that a result will ever be returned.
134-
*
135-
* It is the caller's responsibility to guard against this function not returning a result in a timely manner, or not returning a result ever.
136-
*/
137-
override suspend fun waitForReferrerCode(): ParsedReferrerResult {
138-
if (referralResult != ReferrerInitialising) {
139-
Timber.d("Referrer already determined; immediately answering")
140-
return referralResult
141-
}
142-
143-
Timber.i("Referrer: Retrieving referral code from Play Store referrer service")
144-
145-
// poll, awaiting referral result to become available
146-
while (referralResult == ReferrerInitialising) {
147-
Timber.v("Still initialising - waiting")
148-
delay(10)
149-
}
150-
151-
return referralResult
152-
}
153-
154-
private fun loadFromDataStore(): String? {
155-
return appReferrerDataStore.campaignSuffix
156-
}
157-
158-
private fun playStoreReferralServiceInstalled(): Boolean {
159-
val playStoreConnectionServiceIntent = Intent()
160-
playStoreConnectionServiceIntent.component = ComponentName(PLAY_STORE_PACKAGE, PLAY_STORE_REFERRAL_SERVICE)
161-
val matchingServices = packageManager.queryIntentServices(playStoreConnectionServiceIntent, 0)
162-
return matchingServices.size > 0
163-
}
164-
165-
private fun referralResultReceived(result: ParsedReferrerResult) {
166-
referralResult = result
167-
168-
when (result) {
169-
is CampaignReferrerFound -> {
170-
variantManager.updateAppReferrerVariant(result.campaignSuffix)
171-
appReferrerDataStore.campaignSuffix = result.campaignSuffix
172-
}
173-
is EuAuctionReferrerFound -> {
174-
variantManager.updateAppReferrerVariant(VariantManager.RESERVED_EU_AUCTION_VARIANT)
175-
appReferrerDataStore.installedFromEuAuction = true
176-
}
177-
}
178-
179-
appReferrerDataStore.referrerCheckedPreviously = true
180-
}
181-
182-
private fun referralResultFailed(reason: ParseFailureReason) {
183-
referralResult = ParseFailure(reason)
184-
}
185-
186-
override fun onInstallReferrerServiceDisconnected() {
187-
Timber.i("Referrer: ServiceDisconnected")
188-
}
189-
190-
override suspend fun beforeAtbInit() {
191-
waitForReferrerCode()
192-
}
193-
194-
override fun beforeAtbInitTimeoutMillis(): Long = MAX_REFERRER_WAIT_TIME_MS
195-
}

app/src/main/java/com/duckduckgo/app/di/PlayStoreReferralModule.kt renamed to app/src/play/java/com/duckduckgo/app/di/StoreReferralModule.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ package com.duckduckgo.app.di
1919
import android.content.Context
2020
import com.duckduckgo.app.referral.*
2121
import com.duckduckgo.app.statistics.AtbInitializerListener
22+
import com.duckduckgo.referral.PlayStoreAppReferrerStateListener
2223
import dagger.Module
2324
import dagger.Provides
2425
import dagger.multibindings.IntoSet
2526
import javax.inject.Singleton
2627

2728
@Module
28-
class PlayStoreReferralModule {
29+
class StoreReferralModule {
2930

3031
@Provides
3132
fun appInstallationReferrerParser(): AppInstallationReferrerParser {

0 commit comments

Comments
 (0)
0