Skip to content

Commit 8a8f0ae

Browse files
committed
Merge branch 'release/5.23.0'
2 parents bde06b2 + 7de849b commit 8a8f0ae

File tree

23 files changed

+256
-108
lines changed

23 files changed

+256
-108
lines changed

app/src/androidTest/java/com/duckduckgo/app/cta/ui/CtaViewModelTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,21 +174,21 @@ class CtaViewModelTest {
174174
fun whenCtaShownPixelIsFired() {
175175
testee.onSurveyChanged(Survey("abc", "http://example.com", 1, SCHEDULED))
176176
testee.onCtaShown()
177-
verify(mockPixel).fire(eq(SURVEY_CTA_SHOWN), any())
177+
verify(mockPixel).fire(eq(SURVEY_CTA_SHOWN), any(), eq(false))
178178
}
179179

180180
@Test
181181
fun whenCtaLaunchedPixelIsFired() {
182182
testee.onSurveyChanged(Survey("abc", "http://example.com", 1, SCHEDULED))
183183
testee.onCtaLaunched()
184-
verify(mockPixel).fire(eq(SURVEY_CTA_LAUNCHED), any())
184+
verify(mockPixel).fire(eq(SURVEY_CTA_LAUNCHED), any(), eq(false))
185185
}
186186

187187
@Test
188188
fun whenCtaDismissedPixelIsFired() {
189189
testee.onSurveyChanged(Survey("abc", "http://example.com", 1, SCHEDULED))
190190
testee.onCtaDismissed()
191-
verify(mockPixel).fire(eq(SURVEY_CTA_DISMISSED), any())
191+
verify(mockPixel).fire(eq(SURVEY_CTA_DISMISSED), any(), eq(false))
192192
}
193193

194194
@Test

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ class StubStatisticsModule {
5151
fun stubPixel(): Pixel {
5252
return object : Pixel {
5353

54-
override fun fire(pixel: Pixel.PixelName, parameters: Map<String, String?>) {
54+
override fun fire(pixel: Pixel.PixelName, parameters: Map<String, String?>, includeLocale: Boolean) {
5555
}
5656

57-
override fun fire(pixelName: String, parameters: Map<String, String?>) {
57+
override fun fire(pixelName: String, parameters: Map<String, String?>, includeLocale: Boolean) {
5858

5959
}
6060

app/src/androidTest/java/com/duckduckgo/app/notification/NotificationHandlerServiceTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class NotificationHandlerServiceTest {
5050
intent.type = CLEAR_DATA_LAUNCH
5151
intent.putExtra(PIXEL_SUFFIX_EXTRA, "abc")
5252
testee.onHandleIntent(intent)
53-
verify(mockPixel).fire(eq("mnot_l_abc"), any())
53+
verify(mockPixel).fire(eq("mnot_l_abc"), any(), any())
5454
}
5555

5656
@Test
@@ -59,6 +59,6 @@ class NotificationHandlerServiceTest {
5959
intent.type = CANCEL
6060
intent.putExtra(PIXEL_SUFFIX_EXTRA, "abc")
6161
testee.onHandleIntent(intent)
62-
verify(mockPixel).fire(eq("mnot_c_abc"), any())
62+
verify(mockPixel).fire(eq("mnot_c_abc"), any(), any())
6363
}
6464
}

app/src/androidTest/java/com/duckduckgo/app/notification/NotificationRegistrarTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,31 +56,31 @@ class NotificationRegistrarTest {
5656
fun whenNotificationsPreviouslyOffAndNowOnThenPixelIsFiredAndSettingsUpdated() {
5757
whenever(mockSettingsDataStore.appNotificationsEnabled).thenReturn(false)
5858
testee.updateStatus(true)
59-
verify(mockPixel).fire(eq(Pixel.PixelName.NOTIFICATIONS_ENABLED), any())
59+
verify(mockPixel).fire(eq(Pixel.PixelName.NOTIFICATIONS_ENABLED), any(), eq(false))
6060
verify(mockSettingsDataStore).appNotificationsEnabled = true
6161
}
6262

6363
@Test
6464
fun whenNotificationsPreviouslyOffAndStillOffThenNoPixelIsFiredAndSettingsUnchanged() {
6565
whenever(mockSettingsDataStore.appNotificationsEnabled).thenReturn(false)
6666
testee.updateStatus(false)
67-
verify(mockPixel, never()).fire(any<Pixel.PixelName>(), any())
67+
verify(mockPixel, never()).fire(any<Pixel.PixelName>(), any(), eq(false))
6868
verify(mockSettingsDataStore, never()).appNotificationsEnabled = true
6969
}
7070

7171
@Test
7272
fun whenNotificationsPreviouslyOnAndStillOnThenNoPixelIsFiredAndSettingsUnchanged() {
7373
whenever(mockSettingsDataStore.appNotificationsEnabled).thenReturn(true)
7474
testee.updateStatus(true)
75-
verify(mockPixel, never()).fire(any<Pixel.PixelName>(), any())
75+
verify(mockPixel, never()).fire(any<Pixel.PixelName>(), any(), eq(false))
7676
verify(mockSettingsDataStore, never()).appNotificationsEnabled = false
7777
}
7878

7979
@Test
8080
fun whenNotificationsPreviouslyOnAndNowOffPixelIsFiredAndSettingsUpdated() {
8181
whenever(mockSettingsDataStore.appNotificationsEnabled).thenReturn(true)
8282
testee.updateStatus(false)
83-
verify(mockPixel).fire(eq(Pixel.PixelName.NOTIFICATIONS_DISABLED), any())
83+
verify(mockPixel).fire(eq(Pixel.PixelName.NOTIFICATIONS_DISABLED), any(), eq(false))
8484
verify(mockSettingsDataStore).appNotificationsEnabled = false
8585
}
8686
}

app/src/androidTest/java/com/duckduckgo/app/settings/SettingsViewModelTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,15 @@ class SettingsViewModelTest {
169169

170170
@Test
171171
fun whenDefaultBrowserAppAlreadySetToOursThenIsDefaultBrowserFlagIsTrue() {
172-
whenever(mockDefaultBrowserDetector.isCurrentlyConfiguredAsDefaultBrowser()).thenReturn(true)
172+
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(true)
173173
testee.start()
174174
val viewState = latestViewState()
175175
assertTrue(viewState.isAppDefaultBrowser)
176176
}
177177

178178
@Test
179179
fun whenDefaultBrowserAppNotSetToOursThenIsDefaultBrowserFlagIsFalse() {
180-
whenever(mockDefaultBrowserDetector.isCurrentlyConfiguredAsDefaultBrowser()).thenReturn(false)
180+
whenever(mockDefaultBrowserDetector.isDefaultBrowser()).thenReturn(false)
181181
testee.start()
182182
val viewState = latestViewState()
183183
assertFalse(viewState.isAppDefaultBrowser)

app/src/androidTest/java/com/duckduckgo/app/statistics/ApiBasedPixelTest.kt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,35 @@ class ApiBasedPixelTest {
120120
pixel.fire(PRIVACY_DASHBOARD_OPENED)
121121
verify(mockPixelService).fire("mp", "phone", "atbvariant", params)
122122
}
123+
124+
@Test
125+
fun whenPixelFiredWithAdditionalParametersAndLocaleThenPixelServiceCalledWithBothSetsOfParameters() {
126+
whenever(mockPixelService.fire(any(), any(), any(), any())).thenReturn(Completable.complete())
127+
whenever(mockStatisticsDataStore.atb).thenReturn(Atb("atb"))
128+
whenever(mockVariantManager.getVariant()).thenReturn(Variant("variant"))
129+
whenever(mockDeviceInfo.formFactor()).thenReturn(DeviceInfo.FormFactor.PHONE)
130+
whenever(mockDeviceInfo.country).thenReturn("us")
131+
whenever(mockDeviceInfo.language).thenReturn("es")
132+
133+
val pixel = ApiBasedPixel(mockPixelService, mockStatisticsDataStore, mockVariantManager, mockDeviceInfo)
134+
val params = mapOf("param1" to "value1")
135+
val localeParams = mapOf("lg" to "es", "co" to "us")
136+
pixel.fire(PRIVACY_DASHBOARD_OPENED, params, includeLocale = true)
137+
verify(mockPixelService).fire("mp", "phone", "atbvariant", params.plus(localeParams))
138+
}
139+
140+
@Test
141+
fun whenPixelFiredWithLocaleAndNoAdditionalParametersThenPixelServiceCalledWithLocaleParameters() {
142+
whenever(mockPixelService.fire(any(), any(), any(), any())).thenReturn(Completable.complete())
143+
whenever(mockStatisticsDataStore.atb).thenReturn(Atb("atb"))
144+
whenever(mockVariantManager.getVariant()).thenReturn(Variant("variant"))
145+
whenever(mockDeviceInfo.formFactor()).thenReturn(DeviceInfo.FormFactor.PHONE)
146+
whenever(mockDeviceInfo.country).thenReturn("us")
147+
whenever(mockDeviceInfo.language).thenReturn("es")
148+
149+
val pixel = ApiBasedPixel(mockPixelService, mockStatisticsDataStore, mockVariantManager, mockDeviceInfo)
150+
val localeParams = mapOf("lg" to "es", "co" to "us")
151+
pixel.fire(PRIVACY_DASHBOARD_OPENED, includeLocale = true)
152+
verify(mockPixelService).fire("mp", "phone", "atbvariant", localeParams)
153+
}
123154
}

app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import com.duckduckgo.app.global.view.*
4242
import com.duckduckgo.app.playstore.PlayStoreUtils
4343
import com.duckduckgo.app.privacy.ui.PrivacyDashboardActivity
4444
import com.duckduckgo.app.settings.SettingsActivity
45+
import com.duckduckgo.app.statistics.pixels.Pixel
4546
import com.duckduckgo.app.tabs.model.TabEntity
4647
import com.duckduckgo.app.tabs.ui.TabSwitcherActivity
4748
import kotlinx.android.synthetic.main.activity_browser.*
@@ -59,6 +60,9 @@ class BrowserActivity : DuckDuckGoActivity() {
5960
@Inject
6061
lateinit var dataClearer: DataClearer
6162

63+
@Inject
64+
lateinit var pixel: Pixel
65+
6266
@Inject
6367
lateinit var playStoreUtils: PlayStoreUtils
6468

@@ -173,6 +177,13 @@ class BrowserActivity : DuckDuckGoActivity() {
173177
Toast.makeText(applicationContext, R.string.fireDataCleared, Toast.LENGTH_LONG).show()
174178
}
175179

180+
if (launchedFromWidget(intent)) {
181+
Timber.w("new tab requested from widget")
182+
pixel.fire(Pixel.PixelName.WIDGET_LAUNCHED, includeLocale = true)
183+
viewModel.onNewTabRequested()
184+
return
185+
}
186+
176187
if (launchNewSearch(intent)) {
177188
Timber.w("new tab requested")
178189
viewModel.onNewTabRequested()
@@ -234,6 +245,10 @@ class BrowserActivity : DuckDuckGoActivity() {
234245
}
235246
}
236247

248+
private fun launchedFromWidget(intent: Intent): Boolean {
249+
return intent.getBooleanExtra(WIDGET_SEARCH_EXTRA, false)
250+
}
251+
237252
private fun launchNewSearch(intent: Intent): Boolean {
238253
return intent.getBooleanExtra(NEW_SEARCH_EXTRA, false) || intent.action == Intent.ACTION_ASSIST
239254
}
@@ -294,15 +309,17 @@ class BrowserActivity : DuckDuckGoActivity() {
294309

295310
companion object {
296311

297-
fun intent(context: Context, queryExtra: String? = null, newSearch: Boolean = false, launchedFromFireAction: Boolean = false): Intent {
312+
fun intent(context: Context, queryExtra: String? = null, newSearch: Boolean = false, widgetSearch: Boolean = false, launchedFromFireAction: Boolean = false): Intent {
298313
val intent = Intent(context, BrowserActivity::class.java)
299314
intent.putExtra(EXTRA_TEXT, queryExtra)
300315
intent.putExtra(NEW_SEARCH_EXTRA, newSearch)
316+
intent.putExtra(WIDGET_SEARCH_EXTRA, widgetSearch)
301317
intent.putExtra(LAUNCHED_FROM_FIRE_EXTRA, launchedFromFireAction)
302318
return intent
303319
}
304320

305321
const val NEW_SEARCH_EXTRA = "NEW_SEARCH_EXTRA"
322+
const val WIDGET_SEARCH_EXTRA = "WIDGET_SEARCH_EXTRA"
306323
const val PERFORM_FIRE_ON_ENTRY_EXTRA = "PERFORM_FIRE_ON_ENTRY_EXTRA"
307324
const val LAUNCHED_FROM_FIRE_EXTRA = "LAUNCHED_FROM_FIRE_EXTRA"
308325

app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/DefaultBrowserDetector.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import javax.inject.Inject
2929

3030
interface DefaultBrowserDetector {
3131
fun deviceSupportsDefaultBrowserConfiguration(): Boolean
32-
fun isCurrentlyConfiguredAsDefaultBrowser(): Boolean
32+
fun isDefaultBrowser(): Boolean
3333
}
3434

3535
class AndroidDefaultBrowserDetector @Inject constructor(private val context: Context) : DefaultBrowserDetector {
@@ -38,7 +38,7 @@ class AndroidDefaultBrowserDetector @Inject constructor(private val context: Con
3838
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
3939
}
4040

41-
override fun isCurrentlyConfiguredAsDefaultBrowser(): Boolean {
41+
override fun isDefaultBrowser(): Boolean {
4242
val intent = Intent(ACTION_VIEW, Uri.parse("https://"))
4343
val resolutionInfo: ResolveInfo? = context.packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)
4444
val defaultAlready = resolutionInfo?.activityInfo?.packageName == BuildConfig.APPLICATION_ID

app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/DefaultBrowserInfoActivity.kt

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@ import android.content.Intent
2323
import android.os.Build
2424
import android.os.Bundle
2525
import android.provider.Settings
26-
import androidx.annotation.RequiresApi
2726
import android.widget.Toast
27+
import androidx.annotation.RequiresApi
2828
import com.duckduckgo.app.browser.R
2929
import com.duckduckgo.app.global.DuckDuckGoActivity
30-
import com.duckduckgo.app.statistics.pixels.Pixel
31-
import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.*
3230
import kotlinx.android.synthetic.main.activity_default_browser_info.*
3331
import timber.log.Timber
3432
import javax.inject.Inject
@@ -38,17 +36,10 @@ class DefaultBrowserInfoActivity : DuckDuckGoActivity() {
3836
@Inject
3937
lateinit var defaultBrowserDetector: DefaultBrowserDetector
4038

41-
@Inject
42-
lateinit var pixel: Pixel
43-
4439
override fun onCreate(savedInstanceState: Bundle?) {
4540
super.onCreate(savedInstanceState)
4641
setContentView(R.layout.activity_default_browser_info)
4742
configureUiEventHandlers()
48-
49-
if (savedInstanceState == null) {
50-
pixel.fire(DEFAULT_BROWSER_INFO_VIEWED)
51-
}
5243
}
5344

5445
@TargetApi(Build.VERSION_CODES.N)
@@ -73,30 +64,21 @@ class DefaultBrowserInfoActivity : DuckDuckGoActivity() {
7364
override fun onResume() {
7465
super.onResume()
7566

76-
if (defaultBrowserDetector.isCurrentlyConfiguredAsDefaultBrowser()) {
67+
if (defaultBrowserDetector.isDefaultBrowser()) {
7768
finish()
7869
}
7970
}
8071

8172
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
8273
when (requestCode) {
8374
DEFAULT_BROWSER_REQUEST_CODE -> {
84-
fireDefaultBrowserPixel()
75+
val wasSet = if (defaultBrowserDetector.isDefaultBrowser()) "was" else "was not"
76+
Timber.i("User returned from default settings; DDG $wasSet set as the default")
8577
}
8678
else -> super.onActivityResult(requestCode, resultCode, data)
8779
}
8880
}
8981

90-
private fun fireDefaultBrowserPixel() {
91-
if (defaultBrowserDetector.isCurrentlyConfiguredAsDefaultBrowser()) {
92-
Timber.i("User returned from default settings; DDG is now the default")
93-
pixel.fire(DEFAULT_BROWSER_SET)
94-
} else {
95-
Timber.i("User returned from default settings; DDG was not set default")
96-
pixel.fire(DEFAULT_BROWSER_NOT_SET)
97-
}
98-
}
99-
10082
override fun onBackPressed() {
10183
exitActivity()
10284
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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.browser.defaultbrowsing
18+
19+
import androidx.lifecycle.Lifecycle
20+
import androidx.lifecycle.LifecycleObserver
21+
import androidx.lifecycle.OnLifecycleEvent
22+
import com.duckduckgo.app.global.install.AppInstallStore
23+
import com.duckduckgo.app.statistics.pixels.Pixel
24+
25+
class DefaultBrowserObserver(
26+
private val defaultBrowserDetector: DefaultBrowserDetector,
27+
private val appInstallStore: AppInstallStore,
28+
private val pixel: Pixel
29+
) : LifecycleObserver {
30+
31+
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
32+
fun onApplicationResumed() {
33+
val isDefaultBrowser = defaultBrowserDetector.isDefaultBrowser()
34+
if (appInstallStore.defaultBrowser != isDefaultBrowser) {
35+
appInstallStore.defaultBrowser = isDefaultBrowser
36+
when {
37+
isDefaultBrowser -> pixel.fire(Pixel.PixelName.DEFAULT_BROWSER_SET, includeLocale = true)
38+
else -> pixel.fire(Pixel.PixelName.DEFAULT_BROWSER_UNSET, includeLocale = true)
39+
}
40+
}
41+
42+
}
43+
}

0 commit comments

Comments
 (0)