diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 85685fa663ae..f574b81e01fd 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -11,31 +11,31 @@ cmake_minimum_required(VERSION 3.4.1) # Gradle automatically packages shared libraries with your APK. add_library( # Sets the name of the library. - adblockclient-lib + adblockclient-lib - # Sets the library as a shared library. - SHARED + # Sets the library as a shared library. + SHARED - # Provides a relative path to your source file(s). - src/main/cpp/adblockclient-lib.cpp - src/main/cpp/third-party/ad-block/ad_block_client.cc - src/main/cpp/third-party/ad-block/cosmetic_filter.cc - src/main/cpp/third-party/ad-block/filter.cc - src/main/cpp/third-party/bloom-filter-cpp/BloomFilter.cpp - src/main/cpp/third-party/bloom-filter-cpp/hashFn.cpp - src/main/cpp/third-party/hashset-cpp/HashSet.cpp - ) + # Provides a relative path to your source file(s). + src/main/cpp/adblockclient-lib.cpp + src/main/cpp/third-party/ad-block/ad_block_client.cc + src/main/cpp/third-party/ad-block/cosmetic_filter.cc + src/main/cpp/third-party/ad-block/filter.cc + src/main/cpp/third-party/bloom-filter-cpp/BloomFilter.cpp + src/main/cpp/third-party/bloom-filter-cpp/hashFn.cpp + src/main/cpp/third-party/hashset-cpp/HashSet.cpp + ) add_library( # Sets the name of the library. - https-bloom-lib + https-bloom-lib - # Sets the library as a shared library. - SHARED + # Sets the library as a shared library. + SHARED - # Provides a relative path to your source file(s). - src/main/cpp/https-bloom-lib.cpp - src/main/cpp/third-party/bloom_cpp/src/BloomFilter.cpp - ) + # Provides a relative path to your source file(s). + src/main/cpp/https-bloom-lib.cpp + src/main/cpp/third-party/bloom_cpp/src/BloomFilter.cpp + ) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by @@ -44,19 +44,19 @@ add_library( # Sets the name of the library. # completing its build. find_library( # Sets the name of the path variable. - log-lib + log-lib - # Specifies the name of the NDK library that - # you want CMake to locate. - log ) + # Specifies the name of the NDK library that + # you want CMake to locate. + log) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # Specifies the target library. - adblockclient-lib + adblockclient-lib - # Links the target library to the log library - # included in the NDK. - ${log-lib} ) \ No newline at end of file + # Links the target library to the log library + # included in the NDK. + ${log-lib}) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index e400c21600db..c06ef2b4a0e7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'kotlin-kapt' apply from: '../versioning.gradle' ext { - VERSION_NAME = "5.10.2" + VERSION_NAME = "5.10.3" USE_ORCHESTRATOR = project.hasProperty('orchestrator') ? project.property('orchestrator') : false } diff --git a/app/src/androidTest/java/com/duckduckgo/app/TestApplication.kt b/app/src/androidTest/java/com/duckduckgo/app/TestApplication.kt index 2560ff940bfa..bb611bcfe4c2 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/TestApplication.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/TestApplication.kt @@ -30,9 +30,9 @@ class TestApplication : DuckDuckGoApplication() { override fun configureDependencyInjection() { DaggerTestAppComponent.builder() - .application(this) - .create(this) - .inject(this) + .application(this) + .create(this) + .inject(this) } // We don't need to actually use leak canary for tests diff --git a/app/src/androidTest/java/com/duckduckgo/app/bookmarks/db/BookmarksDaoTest.kt b/app/src/androidTest/java/com/duckduckgo/app/bookmarks/db/BookmarksDaoTest.kt index 6c02f50fedb4..3d10e653b4a0 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/bookmarks/db/BookmarksDaoTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/bookmarks/db/BookmarksDaoTest.kt @@ -39,8 +39,8 @@ class BookmarksDaoTest { @Before fun before() { db = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(), AppDatabase::class.java) - .allowMainThreadQueries() - .build() + .allowMainThreadQueries() + .build() dao = db.bookmarksDao() } diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt index 89d8aa92b5bc..1fdbbb9d90ab 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt @@ -32,8 +32,6 @@ import com.duckduckgo.app.browser.BrowserTabViewModel.Command.DisplayMessage import com.duckduckgo.app.browser.BrowserTabViewModel.Command.Navigate import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.DownloadFile import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.OpenInNewTab -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserNotification import com.duckduckgo.app.browser.favicon.FaviconDownloader import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter import com.duckduckgo.app.browser.session.WebViewSessionStorage @@ -47,7 +45,6 @@ import com.duckduckgo.app.privacy.db.SiteVisitedEntity import com.duckduckgo.app.privacy.model.PrivacyGrade import com.duckduckgo.app.privacy.store.TermsOfServiceStore import com.duckduckgo.app.settings.db.SettingsDataStore -import com.duckduckgo.app.statistics.VariantManager import com.duckduckgo.app.statistics.api.StatisticsUpdater import com.duckduckgo.app.tabs.model.TabRepository import com.duckduckgo.app.trackerdetection.model.TrackerNetwork @@ -104,21 +101,12 @@ class BrowserTabViewModelTest { @Mock private lateinit var mockOmnibarConverter: OmnibarEntryConverter - @Mock - private lateinit var mockDefaultBrowserDetector: DefaultBrowserDetector - - @Mock - private lateinit var mockDefaultBrowserNotification: DefaultBrowserNotification - @Mock private lateinit var mockTabsRepository: TabRepository @Mock private lateinit var webViewSessionStorage: WebViewSessionStorage - @Mock - private lateinit var variantManager: VariantManager - @Mock private lateinit var mockFaviconDownloader: FaviconDownloader @@ -154,14 +142,11 @@ class BrowserTabViewModelTest { autoCompleteApi = mockAutoCompleteApi, appSettingsPreferencesStore = mockSettingsStore, bookmarksDao = bookmarksDao, - defaultBrowserNotification = mockDefaultBrowserNotification, - defaultBrowserDetector = mockDefaultBrowserDetector, longPressHandler = mockLongPressHandler, appConfigurationDao = appConfigurationDao, webViewSessionStorage = webViewSessionStorage, specialUrlDetector = SpecialUrlDetector(), - faviconDownloader = mockFaviconDownloader, - variantManager = variantManager + faviconDownloader = mockFaviconDownloader ) testee.loadData("abc", null) diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/WebViewRequestInterceptorTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/WebViewRequestInterceptorTest.kt index efe839263bba..ff25418c6352 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/WebViewRequestInterceptorTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/WebViewRequestInterceptorTest.kt @@ -22,9 +22,9 @@ import android.support.test.annotation.UiThreadTest import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse import android.webkit.WebView +import com.duckduckgo.app.httpsupgrade.HttpsUpgrader import com.duckduckgo.app.surrogates.ResourceSurrogates import com.duckduckgo.app.surrogates.SurrogateResponse -import com.duckduckgo.app.httpsupgrade.HttpsUpgrader import com.duckduckgo.app.trackerdetection.TrackerDetector import com.duckduckgo.app.trackerdetection.model.TrackingEvent import com.nhaarman.mockito_kotlin.* @@ -56,9 +56,9 @@ class WebViewRequestInterceptorTest { MockitoAnnotations.initMocks(this) testee = WebViewRequestInterceptor( - trackerDetector = mockTrackerDetector, - httpsUpgrader = mockHttpsUpgrader, - resourceSurrogates = mockResourceSurrogates + trackerDetector = mockTrackerDetector, + httpsUpgrader = mockHttpsUpgrader, + resourceSurrogates = mockResourceSurrogates ) val context = InstrumentationRegistry.getTargetContext() @@ -70,10 +70,11 @@ class WebViewRequestInterceptorTest { fun whenUrlShouldBeUpgradedThenUpgraderInvoked() { configureShouldUpgrade() testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) verify(mockHttpsUpgrader).upgrade(any()) } @@ -82,10 +83,11 @@ class WebViewRequestInterceptorTest { fun whenUrlShouldBeUpgradedThenCancelledResponseReturned() { configureShouldUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) assertCancelledResponse(response) } @@ -95,10 +97,11 @@ class WebViewRequestInterceptorTest { configureShouldUpgrade() whenever(mockRequest.isForMainFrame).thenReturn(false) testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) verify(mockHttpsUpgrader, never()).upgrade(any()) } @@ -108,10 +111,11 @@ class WebViewRequestInterceptorTest { configureShouldUpgrade() whenever(mockRequest.url).thenReturn(null) testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) verify(mockHttpsUpgrader, never()).upgrade(any()) } @@ -120,10 +124,11 @@ class WebViewRequestInterceptorTest { fun whenUrlShouldNotBeUpgradedThenUpgraderNotInvoked() { whenever(mockHttpsUpgrader.shouldUpgrade(any())).thenReturn(false) testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) verify(mockHttpsUpgrader, never()).upgrade(any()) } @@ -132,10 +137,11 @@ class WebViewRequestInterceptorTest { fun whenCurrentUrlIsNullThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = null, - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = null, + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -143,10 +149,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_DuckDuckGo_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "duckduckgo.com/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "duckduckgo.com/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -155,10 +162,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_DontTrack_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "donttrack.us/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "donttrack.us/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -167,10 +175,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_SpreadPrivacy_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "spreadprivacy.com/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "spreadprivacy.com/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -179,10 +188,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_DuckDuckHack_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "duckduckhack.com/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "duckduckhack.com/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -191,10 +201,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_PrivateBrowsingMyths_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "privatebrowsingmyths.com/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "privatebrowsingmyths.com/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -203,10 +214,11 @@ class WebViewRequestInterceptorTest { fun whenIsTrustedSite_DuckDotCo_ThenShouldContinueToLoad() { configureShouldNotUpgrade() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "duck.co/a/b/c?q=123", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "duck.co/a/b/c?q=123", + webView = webView, + webViewClientListener = null + ) assertRequestCanContinueToLoad(response) } @@ -218,10 +230,11 @@ class WebViewRequestInterceptorTest { val mockListener = mock() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "foo.com", - webView = webView, - webViewClientListener = mockListener) + request = mockRequest, + currentUrl = "foo.com", + webView = webView, + webViewClientListener = mockListener + ) verify(mockListener).pageHasHttpResources(anyString()) assertRequestCanContinueToLoad(response) @@ -234,10 +247,11 @@ class WebViewRequestInterceptorTest { val mockListener = mock() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "foo.com", - webView = webView, - webViewClientListener = mockListener) + request = mockRequest, + currentUrl = "foo.com", + webView = webView, + webViewClientListener = mockListener + ) verify(mockListener, never()).pageHasHttpResources(anyString()) assertRequestCanContinueToLoad(response) @@ -251,10 +265,11 @@ class WebViewRequestInterceptorTest { configureShouldNotUpgrade() configureShouldBlock() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "foo.com", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "foo.com", + webView = webView, + webViewClientListener = null + ) assertCancelledResponse(response) } @@ -262,18 +277,20 @@ class WebViewRequestInterceptorTest { @Test fun whenRequestShouldBlockButThereIsASurrogateThen() { val availableSurrogate = SurrogateResponse( - responseAvailable = true, - mimeType = "application/javascript", - jsFunction = "javascript replacement function goes here") + responseAvailable = true, + mimeType = "application/javascript", + jsFunction = "javascript replacement function goes here" + ) whenever(mockResourceSurrogates.get(any())).thenReturn(availableSurrogate) configureShouldNotUpgrade() configureShouldBlock() val response = testee.shouldIntercept( - request = mockRequest, - currentUrl = "foo.com", - webView = webView, - webViewClientListener = null) + request = mockRequest, + currentUrl = "foo.com", + webView = webView, + webViewClientListener = null + ) assertEquals(availableSurrogate.jsFunction.byteInputStream().read(), response!!.data.read()) } @@ -283,10 +300,12 @@ class WebViewRequestInterceptorTest { } private fun configureShouldBlock() { - val blockTrackingEvent = TrackingEvent(blocked = true, - documentUrl = "", - trackerUrl = "", - trackerNetwork = null) + val blockTrackingEvent = TrackingEvent( + blocked = true, + documentUrl = "", + trackerUrl = "", + trackerNetwork = null + ) whenever(mockRequest.isForMainFrame).thenReturn(false) whenever(mockTrackerDetector.evaluate(any(), any(), any())).thenReturn(blockTrackingEvent) } diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserBannerNotificationTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserBannerNotificationTest.kt deleted file mode 100644 index de51b2457c05..000000000000 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserBannerNotificationTest.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2018 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.defaultBrowsing - -import com.duckduckgo.app.global.install.AppInstallStore -import com.duckduckgo.app.statistics.Variant -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowBanner -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.whenever -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test -import java.util.concurrent.TimeUnit - -class DefaultBrowserBannerNotificationTest { - - private lateinit var testee: DefaultBrowserTimeBasedNotification - - private val mockDetector: DefaultBrowserDetector = mock() - private val appInstallStore: AppInstallStore = mock() - private val variantManager: VariantManager = mock() - - @Before - fun setup() { - testee = DefaultBrowserTimeBasedNotification(mockDetector, appInstallStore, variantManager) - } - - @Test - fun whenDefaultBrowserNotSupportedByDeviceThenNotificationNotShown() { - configureEnvironment(false, true, true, false) - assertFalse(testee.shouldShowBannerNotification(browserShowing = true)) - } - - @Test - fun whenDefaultBrowserFeatureNotSupportedThenNotificationNotShown() { - configureEnvironment(true, false, true, false) - assertFalse(testee.shouldShowBannerNotification(browserShowing = true)) - } - - @Test - fun whenNoAppInstallTimeRecordedThenNotificationNotShown() { - configureEnvironment(true, true, false, false) - assertFalse(testee.shouldShowBannerNotification(browserShowing = true)) - } - - @Test - fun whenUserDeclinedPreviouslyThenNotificationNotShown() { - configureEnvironment(true, true, true, true) - assertFalse(testee.shouldShowBannerNotification(browserShowing = true)) - } - - @Test - fun whenNotEnoughTimeHasPassedSinceInstallThenNotificationNotShown() { - configureEnvironment(true, true, true, false) - whenever(appInstallStore.installTimestamp).thenReturn(0) - assertFalse(testee.shouldShowBannerNotification(browserShowing = true, timeNow = TimeUnit.SECONDS.toMillis(10))) - } - - @Test - fun whenEnoughTimeHasPassedSinceInstallThenNotificationShown() { - configureEnvironment(true, true, true, false) - whenever(appInstallStore.installTimestamp).thenReturn(0) - assertTrue(testee.shouldShowBannerNotification(browserShowing = true, timeNow = TimeUnit.DAYS.toMillis(100))) - } - - @Test - fun whenUserDeclinedHomeScreenCallToActionPreviouslyThenNotificationStillShown() { - configureEnvironment(true, true, true, false) - whenever(appInstallStore.hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously()).thenReturn(true) - assertTrue(testee.shouldShowBannerNotification(browserShowing = true)) - } - - private fun configureEnvironment(deviceSupported: Boolean, featureEnabled: Boolean, timestampRecorded: Boolean, previousDecline: Boolean) { - whenever(mockDetector.deviceSupportsDefaultBrowserConfiguration()).thenReturn(deviceSupported) - whenever(variantManager.getVariant()).thenReturn(if (featureEnabled) variantWithFeatureEnabled() else variantWithFeatureDisabled()) - whenever(appInstallStore.hasInstallTimestampRecorded()).thenReturn(timestampRecorded) - whenever(appInstallStore.hasUserDeclinedDefaultBrowserBannerPreviously()).thenReturn(previousDecline) - } - - private fun variantWithFeatureEnabled() = Variant("", 0.0, listOf(ShowBanner)) - private fun variantWithFeatureDisabled() = Variant("", 0.0, listOf()) -} \ No newline at end of file diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserHomeScreenCallToActionTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserHomeScreenCallToActionTest.kt deleted file mode 100644 index 7c82e1ff0e22..000000000000 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserHomeScreenCallToActionTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2018 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.defaultBrowsing - -import com.duckduckgo.app.global.install.AppInstallStore -import com.duckduckgo.app.statistics.Variant -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionSimpleButton -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.whenever -import org.junit.Assert.assertFalse -import org.junit.Assert.assertTrue -import org.junit.Before -import org.junit.Test - -class DefaultBrowserHomeScreenCallToActionTest { - - private lateinit var testee: DefaultBrowserTimeBasedNotification - - private val mockDetector: DefaultBrowserDetector = mock() - private val appInstallStore: AppInstallStore = mock() - private val variantManager: VariantManager = mock() - - @Before - fun setup() { - testee = DefaultBrowserTimeBasedNotification(mockDetector, appInstallStore, variantManager) - } - - @Test - fun whenDefaultBrowserNotSupportedByDeviceThenCallToActionNotShown() { - configureEnvironment(false, true, true, false) - assertFalse(testee.shouldShowHomeScreenCallToActionNotification()) - } - - @Test - fun whenDefaultBrowserFeatureNotSupportedThenCallToActionNotShown() { - configureEnvironment(true, false, true, false) - assertFalse(testee.shouldShowHomeScreenCallToActionNotification( )) - } - - @Test - fun whenNoAppInstallTimeRecordedThenCallToActionNotShown() { - configureEnvironment(true, true, false, false) - assertFalse(testee.shouldShowHomeScreenCallToActionNotification( )) - } - - @Test - fun whenUserDeclinedPreviouslyThenCallToActionNotShown() { - configureEnvironment(true, true, true, true) - assertFalse(testee.shouldShowHomeScreenCallToActionNotification( )) - } - - @Test - fun whenAllOtherConditionsPassThenCallToActionShown() { - configureEnvironment(true, true, true, false) - whenever(appInstallStore.installTimestamp).thenReturn(0) - assertTrue(testee.shouldShowHomeScreenCallToActionNotification()) - } - - private fun configureEnvironment(deviceSupported: Boolean, featureEnabled: Boolean, timestampRecorded: Boolean, previousDecline: Boolean) { - whenever(mockDetector.deviceSupportsDefaultBrowserConfiguration()).thenReturn(deviceSupported) - whenever(variantManager.getVariant()).thenReturn(if (featureEnabled) variantWithFeatureEnabled() else variantWithFeatureDisabled()) - whenever(appInstallStore.hasInstallTimestampRecorded()).thenReturn(timestampRecorded) - whenever(appInstallStore.hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously()).thenReturn(previousDecline) - } - - private fun variantWithFeatureEnabled() = Variant("", 0.0, listOf(ShowHomeScreenCallToActionSimpleButton)) - private fun variantWithFeatureDisabled() = Variant("", 0.0, listOf()) -} \ No newline at end of file diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/useragent/UserAgentProviderTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/useragent/UserAgentProviderTest.kt index 32fd3d5c208d..915662a85157 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/useragent/UserAgentProviderTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/useragent/UserAgentProviderTest.kt @@ -20,18 +20,18 @@ import org.junit.Assert.assertTrue import org.junit.Test private const val CHROME_UA_MOBILE = - "Mozilla/5.0 (Linux; Android 8.1.0; Nexus 6P Build/OPM3.171019.014) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36" + "Mozilla/5.0 (Linux; Android 8.1.0; Nexus 6P Build/OPM3.171019.014) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.137 Mobile Safari/537.36" // Some values will be dynamic based on OS/Architecture/Software versions, so use Regex to match around dynamic values private val CHROME_UA_DESKTOP_REGEX = Regex( - "Mozilla/5.0 \\(X11; Linux .*?\\) AppleWebKit\\/[.0-9]+ \\(KHTML, like Gecko\\) Chrome\\/[.0-9]+ Safari/[.0-9]+" + "Mozilla/5.0 \\(X11; Linux .*?\\) AppleWebKit\\/[.0-9]+ \\(KHTML, like Gecko\\) Chrome\\/[.0-9]+ Safari/[.0-9]+" ) private val CHROME_UA_MOBILE_REGEX = Regex( - "Mozilla/5.0 \\(Linux; Android .*?\\) AppleWebKit\\/[.0-9]+ \\(KHTML, like Gecko\\) Chrome\\/[.0-9]+ Mobile Safari/[.0-9]+" + "Mozilla/5.0 \\(Linux; Android .*?\\) AppleWebKit\\/[.0-9]+ \\(KHTML, like Gecko\\) Chrome\\/[.0-9]+ Mobile Safari/[.0-9]+" ) private val CHROME_UA_MOBILE_REGEX_MISSING_APPLE_WEBKIT_DETAILS = Regex( - "Mozilla/5.0 \\(Linux; Android .*?\\)" + "Mozilla/5.0 \\(Linux; Android .*?\\)" ) class UserAgentProviderTest { diff --git a/app/src/androidTest/java/com/duckduckgo/app/di/StubDatabaseModule.kt b/app/src/androidTest/java/com/duckduckgo/app/di/StubDatabaseModule.kt index ac7565670382..9e0724f8cea5 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/di/StubDatabaseModule.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/di/StubDatabaseModule.kt @@ -31,7 +31,7 @@ class StubDatabaseModule { @Singleton fun provideDatabase(context: Context): AppDatabase { return Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java) - .allowMainThreadQueries() - .build() + .allowMainThreadQueries() + .build() } } \ No newline at end of file diff --git a/app/src/androidTest/java/com/duckduckgo/app/di/StubJobSchedulerModule.kt b/app/src/androidTest/java/com/duckduckgo/app/di/StubJobSchedulerModule.kt index 8b03de33c574..0e54b9d3da37 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/di/StubJobSchedulerModule.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/di/StubJobSchedulerModule.kt @@ -29,16 +29,16 @@ class StubJobSchedulerModule { @Singleton @Provides fun providesJobScheduler(): JobScheduler { - return object: JobScheduler() { + return object : JobScheduler() { override fun enqueue(job: JobInfo?, work: JobWorkItem?): Int = JobScheduler.RESULT_SUCCESS - override fun schedule(job: JobInfo?): Int = JobScheduler.RESULT_SUCCESS + override fun schedule(job: JobInfo?): Int = JobScheduler.RESULT_SUCCESS override fun cancel(jobId: Int) {} override fun cancelAll() {} - override fun getAllPendingJobs(): MutableList = mutableListOf() + override fun getAllPendingJobs(): MutableList = mutableListOf() override fun getPendingJob(jobId: Int): JobInfo? = null diff --git a/app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt b/app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt index 0f786424fa6f..72ffbcb52ba6 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/di/TestAppComponent.kt @@ -20,7 +20,6 @@ import android.app.Application import com.duckduckgo.app.TestApplication import com.duckduckgo.app.browser.autoComplete.BrowserAutoCompleteModule import com.duckduckgo.app.browser.di.BrowserModule -import com.duckduckgo.app.browser.di.DefaultBrowserModule import com.duckduckgo.app.browser.favicon.FaviconModule import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule import com.duckduckgo.app.onboarding.di.OnboardingModule @@ -34,32 +33,33 @@ import javax.inject.Singleton @Singleton -@Component(modules = [ +@Component( + modules = [ - /* test doubled modules */ - StubDatabaseModule::class, - StubJobSchedulerModule::class, - StubAppConfigurationDownloadModule::class, - StubStatisticsModule::class, + /* test doubled modules */ + StubDatabaseModule::class, + StubJobSchedulerModule::class, + StubAppConfigurationDownloadModule::class, + StubStatisticsModule::class, - /* real modules */ - ApplicationModule::class, - AndroidBindingModule::class, - AndroidSupportInjectionModule::class, - NetworkModule::class, - StoreModule::class, - JsonModule::class, - BrowserModule::class, - BrowserAutoCompleteModule::class, - HttpsUpgraderModule::class, - ResourceSurrogateModule::class, - TrackerDetectionModule::class, - NotificationModule::class, - DefaultBrowserModule::class, - OnboardingModule::class, - VariantModule::class, - FaviconModule::class -]) + /* real modules */ + ApplicationModule::class, + AndroidBindingModule::class, + AndroidSupportInjectionModule::class, + NetworkModule::class, + StoreModule::class, + JsonModule::class, + BrowserModule::class, + BrowserAutoCompleteModule::class, + HttpsUpgraderModule::class, + ResourceSurrogateModule::class, + TrackerDetectionModule::class, + NotificationModule::class, + OnboardingModule::class, + VariantModule::class, + FaviconModule::class + ] +) interface TestAppComponent : AndroidInjector { @Component.Builder diff --git a/app/src/androidTest/java/com/duckduckgo/app/feedback/ui/FeedbackViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/feedback/ui/FeedbackViewModelTest.kt index d480f81b4259..70c010e029c8 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/feedback/ui/FeedbackViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/feedback/ui/FeedbackViewModelTest.kt @@ -4,9 +4,12 @@ import android.arch.core.executor.testing.InstantTaskExecutorRule import android.arch.lifecycle.Observer import com.duckduckgo.app.InstantSchedulersRule import com.duckduckgo.app.feedback.api.FeedbackSender -import com.duckduckgo.app.feedback.ui.FeedbackViewModel.* -import com.nhaarman.mockito_kotlin.* -import org.junit.Assert.* +import com.duckduckgo.app.feedback.ui.FeedbackViewModel.Command +import com.nhaarman.mockito_kotlin.any +import com.nhaarman.mockito_kotlin.never +import com.nhaarman.mockito_kotlin.verify +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test diff --git a/app/src/androidTest/java/com/duckduckgo/app/global/db/AppDatabaseTest.kt b/app/src/androidTest/java/com/duckduckgo/app/global/db/AppDatabaseTest.kt index 7e0f177d39c8..d4425b3ab324 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/global/db/AppDatabaseTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/global/db/AppDatabaseTest.kt @@ -89,10 +89,10 @@ class AppDatabaseTest { private fun database(): AppDatabase { val database = Room - .databaseBuilder(InstrumentationRegistry.getTargetContext(), AppDatabase::class.java, TEST_DB_NAME) - .addMigrations(AppDatabase.MIGRATION_1_TO_2, AppDatabase.MIGRATION_2_TO_3, AppDatabase.MIGRATION_3_TO_4, AppDatabase.MIGRATION_4_TO_5) - .allowMainThreadQueries() - .build() + .databaseBuilder(InstrumentationRegistry.getTargetContext(), AppDatabase::class.java, TEST_DB_NAME) + .addMigrations(AppDatabase.MIGRATION_1_TO_2, AppDatabase.MIGRATION_2_TO_3, AppDatabase.MIGRATION_3_TO_4, AppDatabase.MIGRATION_4_TO_5) + .allowMainThreadQueries() + .build() testHelper.closeWhenFinished(database) diff --git a/app/src/androidTest/java/com/duckduckgo/app/global/install/AppInstallSharedPreferencesTest.kt b/app/src/androidTest/java/com/duckduckgo/app/global/install/AppInstallSharedPreferencesTest.kt index 71a69b1a766a..7ba678a7f7e1 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/global/install/AppInstallSharedPreferencesTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/global/install/AppInstallSharedPreferencesTest.kt @@ -35,16 +35,6 @@ class AppInstallSharedPreferencesTest { testee = AppInstallSharedPreferences(context) } - @Test - fun whenInitializedThenUserHasNotBeenMarkedAsHavingPreviouslyDeclinedBanner() { - assertFalse(testee.hasUserDeclinedDefaultBrowserBannerPreviously()) - } - - @Test - fun whenInitializedThenUserHasNotBeenMarkedAsHavingPreviouslyDeclinedHomeScreenCallToAction() { - assertFalse(testee.hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously()) - } - @Test fun whenInitializedThenInstallTimestampNotYetRecorded() { assertFalse(testee.hasInstallTimestampRecorded()) @@ -63,19 +53,4 @@ class AppInstallSharedPreferencesTest { testee.installTimestamp = timestamp assertEquals(timestamp, testee.installTimestamp) } - - @Test - fun whenUserPreviouslyDeclinedBannerThenThatIsReturnedWhenQueried() { - val timestamp = 1L - testee.recordUserDeclinedBannerToSetDefaultBrowser(timestamp) - assertTrue(testee.hasUserDeclinedDefaultBrowserBannerPreviously()) - } - - @Test - fun whenUserPreviouslyDeclinedHomeScreenCallToActionThenThatIsReturnedWhenQueried() { - val timestamp = 1L - testee.recordUserDeclinedHomeScreenCallToActionToSetDefaultBrowser(timestamp) - assertTrue(testee.hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously()) - } - } \ No newline at end of file diff --git a/app/src/androidTest/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModelTest.kt index e8c098e57833..070090d8fd6d 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModelTest.kt @@ -19,9 +19,7 @@ package com.duckduckgo.app.onboarding.ui import android.arch.core.executor.testing.InstantTaskExecutorRule import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector import com.duckduckgo.app.onboarding.store.OnboardingStore -import com.duckduckgo.app.statistics.Variant import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowInOnboarding import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.never import com.nhaarman.mockito_kotlin.verify @@ -43,7 +41,7 @@ class OnboardingViewModelTest { private var variantManager: VariantManager = mock() private val testee: OnboardingViewModel by lazy { - OnboardingViewModel(onboardingStore, mockDefaultBrowserDetector, variantManager) + OnboardingViewModel(onboardingStore, mockDefaultBrowserDetector) } @Test @@ -66,33 +64,17 @@ class OnboardingViewModelTest { } @Test - fun whenThirdPageRequestedWithFeatureEnabledAndDefaultBrowserCapableThenDefaultBrowserPageReturned() { - whenever(variantManager.getVariant()).thenReturn(variantWithOnboardingEnabled()) + fun whenThirdPageRequestedWithDefaultBrowserCapableThenDefaultBrowserPageReturned() { whenever(mockDefaultBrowserDetector.deviceSupportsDefaultBrowserConfiguration()).thenReturn(true) val page = testee.getItem(2) assertTrue(page is OnboardingPageFragment.DefaultBrowserPage) } - @Test - fun whenThirdPageRequestedWithFeatureDisabledAndDefaultBrowserCapableThenNoPageReturned() { - whenever(variantManager.getVariant()).thenReturn(variantWithOnboardingDisabled()) - whenever(mockDefaultBrowserDetector.deviceSupportsDefaultBrowserConfiguration()).thenReturn(true) - val page = testee.getItem(2) - assertNull(page) - } - @Test fun whenThirdPageRequestedButDefaultBrowserNotCapableThenNoPageReturned() { - whenever(variantManager.getVariant()).thenReturn(variantWithOnboardingEnabled()) whenever(mockDefaultBrowserDetector.deviceSupportsDefaultBrowserConfiguration()).thenReturn(false) val page = testee.getItem(2) assertNull(page) } - private fun variantWithOnboardingEnabled(): Variant = - Variant("", 0.0, listOf(ShowInOnboarding)) - - private fun variantWithOnboardingDisabled(): Variant = - Variant("", 0.0, listOf()) - } \ No newline at end of file diff --git a/app/src/androidTest/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtensionTest.kt b/app/src/androidTest/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtensionTest.kt index 5498df3c861e..332113d6a8d0 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtensionTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtensionTest.kt @@ -144,12 +144,13 @@ class SitePrivacyGradeExtensionTest { @Test fun whenPotentialScoreThenTrackerMetricsIgnored() { val site = site( - TrackerNetwork("", "", "", 5, true), - TermsOfService(classification = "D"), - NONE, - 11, - true, - true) + TrackerNetwork("", "", "", 5, true), + TermsOfService(classification = "D"), + NONE, + 11, + true, + true + ) assertEquals(defaultScore + 6, site.score) assertEquals(defaultScore + 3, site.potentialScore) } @@ -157,36 +158,40 @@ class SitePrivacyGradeExtensionTest { @Test fun whenAllTrackersBlockedThenImprovedScoreIsEqualToPotentialScore() { val site = site( - TrackerNetwork("", "", "", 5, true), - TermsOfService(classification = "D"), - NONE, - 5, - true, - true, - allTrackerBlocked = true) + TrackerNetwork("", "", "", 5, true), + TermsOfService(classification = "D"), + NONE, + 5, + true, + true, + allTrackerBlocked = true + ) assertEquals(site.potentialScore, site.improvedScore) } @Test fun whenNotAllTrackersBlockedThenImprovedScoreIsEqualToScore() { val site = site( - TrackerNetwork("", "", "", 5, true), - TermsOfService(classification = "D"), - NONE, - 5, - true, - true, - allTrackerBlocked = false) + TrackerNetwork("", "", "", 5, true), + TermsOfService(classification = "D"), + NONE, + 5, + true, + true, + allTrackerBlocked = false + ) assertEquals(site.score, site.improvedScore) } - private fun site(memberNetwork: TrackerNetwork? = null, - terms: TermsOfService = TermsOfService(), - https: HttpsStatus = SECURE, - trackerCount: Int = 0, - hasTrackerFromMajorNetwork: Boolean = false, - hasObscureTracker: Boolean = false, - allTrackerBlocked: Boolean = true): Site { + private fun site( + memberNetwork: TrackerNetwork? = null, + terms: TermsOfService = TermsOfService(), + https: HttpsStatus = SECURE, + trackerCount: Int = 0, + hasTrackerFromMajorNetwork: Boolean = false, + hasObscureTracker: Boolean = false, + allTrackerBlocked: Boolean = true + ): Site { val site: Site = mock() whenever(site.memberNetwork).thenReturn(memberNetwork) whenever(site.termsOfService).thenReturn(terms) diff --git a/app/src/androidTest/java/com/duckduckgo/app/privacy/renderer/TrackersRendererTest.kt b/app/src/androidTest/java/com/duckduckgo/app/privacy/renderer/TrackersRendererTest.kt index b7c61e4239f0..6531ddf51e4b 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/privacy/renderer/TrackersRendererTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/privacy/renderer/TrackersRendererTest.kt @@ -18,7 +18,7 @@ package com.duckduckgo.app.privacy.renderer import android.support.test.InstrumentationRegistry import com.duckduckgo.app.browser.R -import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.* +import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.NetworkTally import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test diff --git a/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModelTest.kt index 9ffa429863f6..7c14ae600d6d 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModelTest.kt @@ -27,7 +27,7 @@ import com.duckduckgo.app.privacy.model.PrivacyGrade import com.duckduckgo.app.privacy.model.TermsOfService import com.duckduckgo.app.privacy.store.PrivacySettingsStore import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.* +import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.PRIVACY_DASHBOARD_OPENED import com.nhaarman.mockito_kotlin.mock import com.nhaarman.mockito_kotlin.verify import com.nhaarman.mockito_kotlin.whenever diff --git a/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/ScorecardViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/ScorecardViewModelTest.kt index a74f203b990d..b0d12af4749f 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/ScorecardViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/privacy/ui/ScorecardViewModelTest.kt @@ -146,13 +146,15 @@ class ScorecardViewModelTest { assertFalse(testee.viewState.value!!.showEnhancedGrade) } - private fun site(https: HttpsStatus = HttpsStatus.SECURE, - trackerCount: Int = 0, - majorNetworkCount: Int = 0, - hasTrackerFromMajorNetwork: Boolean = false, - allTrackersBlocked: Boolean = true, - terms: TermsOfService = TermsOfService(), - memberNetwork: TrackerNetwork? = null): Site { + private fun site( + https: HttpsStatus = HttpsStatus.SECURE, + trackerCount: Int = 0, + majorNetworkCount: Int = 0, + hasTrackerFromMajorNetwork: Boolean = false, + allTrackersBlocked: Boolean = true, + terms: TermsOfService = TermsOfService(), + memberNetwork: TrackerNetwork? = null + ): Site { val site: Site = mock() whenever(site.https).thenReturn(https) whenever(site.memberNetwork).thenReturn(memberNetwork) diff --git a/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt b/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt index 514d8c387a3b..9abca16331f6 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt @@ -16,38 +16,14 @@ package com.duckduckgo.app.statistics -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionBottomSheet -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionSimpleButton -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.fail import org.junit.Test class VariantManagerTest { private val variants = VariantManager.ACTIVE_VARIANTS - @Test - fun homeScreenCallToActionButtonVariantConfiguredCorrectly() { - val variant = variants.firstOrNull { it.key == "mq" } - assertEqualsDouble(1.0, variant!!.weight) - assertTrue(variant.hasFeature(ShowHomeScreenCallToActionSimpleButton)) - assertEquals(1, variant.features.size) - } - - @Test - fun homeScreenCallToActionBottomSheetVariantConfiguredCorrectly() { - val variant = variants.firstOrNull { it.key == "mp" } - assertEqualsDouble(1.0, variant!!.weight) - assertTrue(variant.hasFeature(ShowHomeScreenCallToActionBottomSheet)) - assertEquals(1, variant.features.size) - } - - @Test - fun controlVariantConfiguredCorrectly() { - val variant = variants.firstOrNull { it.key == "mr" } - assertEqualsDouble(1.0, variant!!.weight) - assertEquals(0, variant.features.size) - } - @Test fun serpVariantAConfiguredCorrectly() { val variant = variants.firstOrNull { it.key == "sa" } diff --git a/app/src/androidTest/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoaderTest.kt b/app/src/androidTest/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoaderTest.kt index 06555435a080..02fa25c445b4 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoaderTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoaderTest.kt @@ -105,7 +105,7 @@ class ResourceSurrogateLoaderTest { assertEquals(6, surrogates.size) } - private fun initialiseFile(filename: String) : List { + private fun initialiseFile(filename: String): List { return testee.convertBytes(readFile(filename)) } diff --git a/app/src/androidTest/java/com/duckduckgo/app/tabs/model/TabDataRepositoryTest.kt b/app/src/androidTest/java/com/duckduckgo/app/tabs/model/TabDataRepositoryTest.kt index 9f9e4355d552..f45b3abddd45 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/tabs/model/TabDataRepositoryTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/tabs/model/TabDataRepositoryTest.kt @@ -30,7 +30,6 @@ import org.junit.Assert.* import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.MockitoAnnotations diff --git a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/AdBlockClientTest.kt b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/AdBlockClientTest.kt index 3b5da7113e3e..5ce2a026be3c 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/AdBlockClientTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/AdBlockClientTest.kt @@ -67,5 +67,5 @@ class AdBlockClientTest { } private fun data(): ByteArray = - javaClass.classLoader.getResource("binary/easylist_sample").readBytes() + javaClass.classLoader.getResource("binary/easylist_sample").readBytes() } diff --git a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/TrackerDetectorTest.kt b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/TrackerDetectorTest.kt index d6824dbeecc2..be6addb23959 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/TrackerDetectorTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/TrackerDetectorTest.kt @@ -123,7 +123,7 @@ class TrackerDetectorTest { @Test fun whenTrackerIsPartOfNetworkThenEvaluateReturnsTrackingEventWithNetwork() { val networks = arrayListOf( - DisconnectTracker("thirdparty.com", "category", network, "http://network.com") + DisconnectTracker("thirdparty.com", "category", network, "http://network.com") ) whenever(settingStore.privacyOn).thenReturn(true) networkTrackers.updateData(networks) @@ -172,8 +172,8 @@ class TrackerDetectorTest { @Test fun whenUrlSharesSameNetworkNameAsDocumentThenEvaluateReturnsNull() { val networks = arrayListOf( - DisconnectTracker("thirdparty.com", "Social", network, "http://network.com"), - DisconnectTracker("example.com", "Advertising", network, "http://network.com") + DisconnectTracker("thirdparty.com", "Social", network, "http://network.com"), + DisconnectTracker("example.com", "Advertising", network, "http://network.com") ) networkTrackers.updateData(networks) trackerDetector.addClient(alwaysMatchingClient(EASYLIST)) diff --git a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDaoTest.kt b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDaoTest.kt index 0073f096ba65..38ed4e790cfe 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDaoTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDaoTest.kt @@ -21,11 +21,12 @@ import android.support.test.InstrumentationRegistry import com.duckduckgo.app.global.db.AppDatabase import com.duckduckgo.app.trackerdetection.model.DisconnectTracker import org.junit.After -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test -class TrackerDataDaoTest { +class TrackerDataDaoTest { private lateinit var db: AppDatabase private lateinit var dao: TrackerDataDao @@ -93,7 +94,7 @@ class TrackerDataDaoTest { } fun createTracker(url: String): DisconnectTracker { - return DisconnectTracker(url, "","", "") + return DisconnectTracker(url, "", "", "") } companion object { diff --git a/app/src/androidTest/resources/json/atb.json b/app/src/androidTest/resources/json/atb.json index 16b85f38a007..247b1ad29413 100644 --- a/app/src/androidTest/resources/json/atb.json +++ b/app/src/androidTest/resources/json/atb.json @@ -1,6 +1,6 @@ { - "for_more_info": "https://duck.co/help/privacy/atb", - "minorVersion": 3, - "majorVersion": 105, - "version": "v105-3" + "for_more_info": "https://duck.co/help/privacy/atb", + "minorVersion": 3, + "majorVersion": 105, + "version": "v105-3" } diff --git a/app/src/androidTest/resources/json/disconnect.json b/app/src/androidTest/resources/json/disconnect.json index 6075c87b4d53..a4d193ac95c5 100644 --- a/app/src/androidTest/resources/json/disconnect.json +++ b/app/src/androidTest/resources/json/disconnect.json @@ -10,8 +10,8 @@ }, { "ItsATracker": { - "dnt": "eff", - "https://itisatracker.com/": [ + "dnt": "eff", + "https://itisatracker.com/": [ "itisatracker.com" ] } diff --git a/app/src/androidTest/resources/json/disconnect_mismatched.json b/app/src/androidTest/resources/json/disconnect_mismatched.json index c89f2daca4ee..624a18686a35 100644 --- a/app/src/androidTest/resources/json/disconnect_mismatched.json +++ b/app/src/androidTest/resources/json/disconnect_mismatched.json @@ -1,24 +1,29 @@ { - "categories": { - "Advertising": [{ - "anadurl.com": { - "http://anadurl.com/": [ - "99anadurl.com" - ] - } - }], - "Social": [{ - "http://asocialurl.com/": [ - "99asocialurl.com" - ] - }, { - "anothersocialurl.com": { - "http://www.anothersocialurl.com/": [ - "anothersocialurl.com", - "55anothersocialurl.com", - "99anothersocialurl.com" - ] - } - }] - } + "categories": { + "Advertising": [ + { + "anadurl.com": { + "http://anadurl.com/": [ + "99anadurl.com" + ] + } + } + ], + "Social": [ + { + "http://asocialurl.com/": [ + "99asocialurl.com" + ] + }, + { + "anothersocialurl.com": { + "http://www.anothersocialurl.com/": [ + "anothersocialurl.com", + "55anothersocialurl.com", + "99anothersocialurl.com" + ] + } + } + ] + } } diff --git a/app/src/androidTest/resources/json/tosdr.json b/app/src/androidTest/resources/json/tosdr.json index 29ff7c7cea8e..75cb9a7bafb0 100644 --- a/app/src/androidTest/resources/json/tosdr.json +++ b/app/src/androidTest/resources/json/tosdr.json @@ -1,60 +1,60 @@ { - "example.com": { - "score": -20, - "all": { - "bad": [ - "they can delete your account without prior notice and without a reason", - "class action waiver", - "targeted third-party advertising", - "no promise to inform/notify", - "sets third-party cookies and/or ads", - "no liability for unauthorized access", - "user needs to check tosback.org" - ], - "good": [ - "easy to read", - "you can request access and deletion of personal data" - ] - }, - "match": { - "bad": [ - "targeted third-party advertising", - "some other issue", - "yet another issue" - ], - "good": [ - "you can request access and deletion of personal data" - ] - }, - "class": false + "example.com": { + "score": -20, + "all": { + "bad": [ + "they can delete your account without prior notice and without a reason", + "class action waiver", + "targeted third-party advertising", + "no promise to inform/notify", + "sets third-party cookies and/or ads", + "no liability for unauthorized access", + "user needs to check tosback.org" + ], + "good": [ + "easy to read", + "you can request access and deletion of personal data" + ] }, - "anotherexample.com": { - "score": 50, - "all": { - "bad": [ - "no quality guarantee", - "promotional communications are not opt-out", - "no quality guarantee", - "user needs to check tosback.org", - "they can delete your account without prior notice and without a reason", - "responsible and indemnify", - "they become the owner of ideas you give them" - ], - "good": [ - "pseudonyms allowed", - "info given about security practices", - "no third-party access without a warrant", - "only necessary logs are kept", - "only temporary session cookies", - "legal documents published under reusable license" - ] - }, - "match": { - "bad": [], - "good": [ - "no third-party access without a warrant" - ] - }, - "class": "B" - } + "match": { + "bad": [ + "targeted third-party advertising", + "some other issue", + "yet another issue" + ], + "good": [ + "you can request access and deletion of personal data" + ] + }, + "class": false + }, + "anotherexample.com": { + "score": 50, + "all": { + "bad": [ + "no quality guarantee", + "promotional communications are not opt-out", + "no quality guarantee", + "user needs to check tosback.org", + "they can delete your account without prior notice and without a reason", + "responsible and indemnify", + "they become the owner of ideas you give them" + ], + "good": [ + "pseudonyms allowed", + "info given about security practices", + "no third-party access without a warrant", + "only necessary logs are kept", + "only temporary session cookies", + "legal documents published under reusable license" + ] + }, + "match": { + "bad": [], + "good": [ + "no third-party access without a warrant" + ] + }, + "class": "B" + } } diff --git a/app/src/androidTest/resources/json/tosdr_mismatched.json b/app/src/androidTest/resources/json/tosdr_mismatched.json index 0b4f39b591b5..615d380bc2fb 100644 --- a/app/src/androidTest/resources/json/tosdr_mismatched.json +++ b/app/src/androidTest/resources/json/tosdr_mismatched.json @@ -1,7 +1,7 @@ { - "somedomain.com": { - "match": { - }, - "class": false - } + "somedomain.com": { + "match": { + }, + "class": false + } } diff --git a/app/src/main/cpp/adblockclient-lib.cpp b/app/src/main/cpp/adblockclient-lib.cpp index 39c55ae41bb5..1b503e26f4ad 100644 --- a/app/src/main/cpp/adblockclient-lib.cpp +++ b/app/src/main/cpp/adblockclient-lib.cpp @@ -14,10 +14,10 @@ extern "C" JNIEXPORT void JNICALL Java_com_duckduckgo_app_trackerdetection_AdBlockClient_releaseClient(JNIEnv *env, - jobject, - jlong clientPointer, - jlong rawDataPointer, - jlong processedDataPointer) { + jobject, + jlong clientPointer, + jlong rawDataPointer, + jlong processedDataPointer) { AdBlockClient *client = (AdBlockClient *) clientPointer; delete client; @@ -51,9 +51,9 @@ extern "C" JNIEXPORT jlong JNICALL Java_com_duckduckgo_app_trackerdetection_AdBlockClient_loadProcessedData(JNIEnv *env, - jobject /* this */, - jlong clientPointer, - jbyteArray data) { + jobject /* this */, + jlong clientPointer, + jbyteArray data) { int dataLength = env->GetArrayLength(data); char *dataChars = new char[dataLength]; @@ -73,8 +73,8 @@ extern "C" JNIEXPORT jbyteArray JNICALL Java_com_duckduckgo_app_trackerdetection_AdBlockClient_getProcessedData(JNIEnv *env, - jobject /* this */, - jlong clientPointer) { + jobject /* this */, + jlong clientPointer) { AdBlockClient *client = (AdBlockClient *) clientPointer; @@ -92,11 +92,11 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_duckduckgo_app_trackerdetection_AdBlockClient_matches(JNIEnv *env, - jobject /* this */, - jlong clientPointer, - jstring url, - jstring documentUrl, - jint filterOption) { + jobject /* this */, + jlong clientPointer, + jstring url, + jstring documentUrl, + jint filterOption) { jboolean isUrlCopy; const char *urlChars = env->GetStringUTFChars(url, &isUrlCopy); diff --git a/app/src/main/cpp/https-bloom-lib.cpp b/app/src/main/cpp/https-bloom-lib.cpp index 0af60c87afa5..d4152e796565 100644 --- a/app/src/main/cpp/https-bloom-lib.cpp +++ b/app/src/main/cpp/https-bloom-lib.cpp @@ -8,7 +8,7 @@ Java_com_duckduckgo_app_httpsupgrade_BloomFilter_createBloomFilter(JNIEnv *env, jobject, jint maxItems, jdouble targetProbability) { - BloomFilter* filter = new BloomFilter(maxItems, targetProbability); + BloomFilter *filter = new BloomFilter(maxItems, targetProbability); return (long) filter; } @@ -17,13 +17,13 @@ extern "C" JNIEXPORT long JNICALL Java_com_duckduckgo_app_httpsupgrade_BloomFilter_createBloomFilterFromFile(JNIEnv *env, - jobject, - jstring path, - jint maxItems) { + jobject, + jstring path, + jint maxItems) { jboolean isElementCopy; const char *pathChars = env->GetStringUTFChars(path, &isElementCopy); - BloomFilter* filter = new BloomFilter(pathChars, maxItems); + BloomFilter *filter = new BloomFilter(pathChars, maxItems); env->ReleaseStringUTFChars(path, pathChars); return (long) filter; } @@ -33,8 +33,8 @@ extern "C" JNIEXPORT void JNICALL Java_com_duckduckgo_app_httpsupgrade_BloomFilter_releaseBloomFilter(JNIEnv *env, - jobject, - jlong pointer) { + jobject, + jlong pointer) { BloomFilter *filter = (BloomFilter *) pointer; delete filter; } @@ -43,9 +43,9 @@ extern "C" JNIEXPORT void JNICALL Java_com_duckduckgo_app_httpsupgrade_BloomFilter_add(JNIEnv *env, - jobject, - jlong pointer, - jstring element) { + jobject, + jlong pointer, + jstring element) { jboolean isElementCopy; const char *elementChars = env->GetStringUTFChars(element, &isElementCopy); @@ -59,9 +59,9 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_duckduckgo_app_httpsupgrade_BloomFilter_contains(JNIEnv *env, - jobject, - jlong pointer, - jstring element) { + jobject, + jlong pointer, + jstring element) { jboolean isElementCopy; const char *elementChars = env->GetStringUTFChars(element, &isElementCopy); diff --git a/app/src/main/java/com/duckduckgo/app/bookmarks/db/BookmarkEntity.kt b/app/src/main/java/com/duckduckgo/app/bookmarks/db/BookmarkEntity.kt index 100a39d9d8db..40cbc6ab3f65 100644 --- a/app/src/main/java/com/duckduckgo/app/bookmarks/db/BookmarkEntity.kt +++ b/app/src/main/java/com/duckduckgo/app/bookmarks/db/BookmarkEntity.kt @@ -20,6 +20,8 @@ import android.arch.persistence.room.Entity import android.arch.persistence.room.PrimaryKey @Entity(tableName = "bookmarks") -data class BookmarkEntity(@PrimaryKey(autoGenerate = true) var id: Int = 0, - var title: String?, - var url: String) +data class BookmarkEntity( + @PrimaryKey(autoGenerate = true) var id: Int = 0, + var title: String?, + var url: String +) diff --git a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksActivity.kt b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksActivity.kt index 24009de25885..541194411b06 100644 --- a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksActivity.kt @@ -18,7 +18,6 @@ package com.duckduckgo.app.bookmarks.ui import android.app.AlertDialog import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.net.Uri @@ -35,7 +34,6 @@ import com.duckduckgo.app.bookmarks.db.BookmarkEntity import com.duckduckgo.app.browser.BrowserActivity import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.baseHost import com.duckduckgo.app.global.faviconLocation import com.duckduckgo.app.global.image.GlideApp @@ -46,18 +44,13 @@ import kotlinx.android.synthetic.main.include_toolbar.* import kotlinx.android.synthetic.main.view_bookmark_entry.view.* import org.jetbrains.anko.alert import timber.log.Timber -import javax.inject.Inject class BookmarksActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory lateinit var adapter: BookmarksAdapter private var deleteDialog: AlertDialog? = null - private val viewModel: BookmarksViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(BookmarksViewModel::class.java) - } + private val viewModel: BookmarksViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -148,8 +141,10 @@ class BookmarksActivity : DuckDuckGoActivity() { private const val EDIT_BOOKMARK_FRAGMENT_TAG = "EDIT_BOOKMARK" } - class BookmarksAdapter(private val context: Context, - private val viewModel: BookmarksViewModel) : Adapter() { + class BookmarksAdapter( + private val context: Context, + private val viewModel: BookmarksViewModel + ) : Adapter() { var bookmarks: List = emptyList() set(value) { @@ -202,10 +197,10 @@ class BookmarksActivity : DuckDuckGoActivity() { val faviconUrl = Uri.parse(url).faviconLocation() GlideApp.with(itemView) - .load(faviconUrl) - .placeholder(R.drawable.ic_globe_white_16dp) - .error(R.drawable.ic_globe_white_16dp) - .into(itemView.favicon) + .load(faviconUrl) + .placeholder(R.drawable.ic_globe_white_16dp) + .error(R.drawable.ic_globe_white_16dp) + .into(itemView.favicon) } private fun parseDisplayUrl(urlString: String): String { diff --git a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModel.kt b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModel.kt index 7a3fa0becb52..b69a4abf3835 100644 --- a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModel.kt @@ -27,10 +27,12 @@ import com.duckduckgo.app.bookmarks.ui.SaveBookmarkDialogFragment.SaveBookmarkLi import com.duckduckgo.app.global.SingleLiveEvent import io.reactivex.schedulers.Schedulers -class BookmarksViewModel(val dao: BookmarksDao): SaveBookmarkListener, ViewModel() { +class BookmarksViewModel(val dao: BookmarksDao) : SaveBookmarkListener, ViewModel() { - data class ViewState(val showBookmarks: Boolean = false, - val bookmarks: List = emptyList()) + data class ViewState( + val showBookmarks: Boolean = false, + val bookmarks: List = emptyList() + ) sealed class Command { diff --git a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/SaveBookmarkDialogFragment.kt b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/SaveBookmarkDialogFragment.kt index 848680d57201..a4537ba94f06 100644 --- a/app/src/main/java/com/duckduckgo/app/bookmarks/ui/SaveBookmarkDialogFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/bookmarks/ui/SaveBookmarkDialogFragment.kt @@ -61,10 +61,10 @@ class SaveBookmarkDialogFragment : DialogFragment() { private fun userAcceptedDialog(titleInput: EditText, urlInput: EditText) { listener?.onBookmarkSaved( - getExistingId(), - titleInput.text.toString(), - urlInput.text.toString() - ) + getExistingId(), + titleInput.text.toString(), + urlInput.text.toString() + ) } private fun showKeyboard(titleInput: EditText, alert: AlertDialog) { @@ -96,7 +96,8 @@ class SaveBookmarkDialogFragment : DialogFragment() { val args = arguments!! if (!args.containsKey(KEY_IS_EDIT_MODE) || !args.containsKey(KEY_PREEXISTING_TITLE) || - !args.containsKey(KEY_PREEXISTING_URL)) { + !args.containsKey(KEY_PREEXISTING_URL) + ) { throw IllegalArgumentException("Bundle arguments required [KEY_IS_EDIT_MODE, KEY_PREEXISTING_TITLE, KEY_PREEXISTING_URL]") } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt index cd05c16962fa..5ab309bed7c8 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.browser import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.content.Intent.EXTRA_TEXT @@ -29,7 +28,6 @@ import com.duckduckgo.app.browser.BrowserViewModel.Command.Query import com.duckduckgo.app.browser.BrowserViewModel.Command.Refresh import com.duckduckgo.app.feedback.ui.FeedbackActivity import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.intentText import com.duckduckgo.app.global.view.ClearPersonalDataAction import com.duckduckgo.app.global.view.FireDialog @@ -46,9 +44,6 @@ import javax.inject.Inject class BrowserActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var clearPersonalDataAction: ClearPersonalDataAction @@ -57,9 +52,7 @@ class BrowserActivity : DuckDuckGoActivity() { private var currentTab: BrowserTabFragment? = null - private val viewModel: BrowserViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(BrowserViewModel::class.java) - } + private val viewModel: BrowserViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserChromeClient.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserChromeClient.kt index cc0664158be0..7e9bf5e0aa5b 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserChromeClient.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserChromeClient.kt @@ -34,7 +34,7 @@ class BrowserChromeClient @Inject constructor() : WebChromeClient() { override fun onShowCustomView(view: View, callback: CustomViewCallback?) { Timber.i("on show custom view") - if(customView != null) { + if (customView != null) { callback?.onCustomViewHidden() return } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index b3cf2abff21d..b590e5993b12 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -21,7 +21,6 @@ import android.animation.LayoutTransition.CHANGING import android.animation.LayoutTransition.DISAPPEARING import android.annotation.SuppressLint import android.app.Activity.RESULT_OK -import android.app.ActivityOptions import android.arch.lifecycle.Observer import android.arch.lifecycle.ViewModelProviders import android.content.Context @@ -34,7 +33,6 @@ import android.os.Bundle import android.os.Environment import android.support.annotation.AnyThread import android.support.annotation.StringRes -import android.support.constraint.ConstraintSet import android.support.design.widget.Snackbar import android.support.v4.app.Fragment import android.support.v4.content.ContextCompat @@ -57,7 +55,6 @@ import androidx.core.view.postDelayed import com.duckduckgo.app.bookmarks.ui.SaveBookmarkDialogFragment import com.duckduckgo.app.browser.BrowserTabViewModel.* import com.duckduckgo.app.browser.autoComplete.BrowserAutoCompleteSuggestionsAdapter -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserInfoActivity import com.duckduckgo.app.browser.downloader.FileDownloadNotificationManager import com.duckduckgo.app.browser.downloader.FileDownloader import com.duckduckgo.app.browser.downloader.FileDownloader.PendingFileDownload @@ -73,9 +70,7 @@ import com.duckduckgo.app.privacy.renderer.icon import com.duckduckgo.app.tabs.model.TabEntity import dagger.android.support.AndroidSupportInjection import kotlinx.android.synthetic.main.fragment_browser_tab.* -import kotlinx.android.synthetic.main.include_banner_notification.* import kotlinx.android.synthetic.main.include_find_in_page.* -import kotlinx.android.synthetic.main.include_home_screen_default_browser_call_to_action.* import kotlinx.android.synthetic.main.include_new_browser_tab.* import kotlinx.android.synthetic.main.include_omnibar_toolbar.* import kotlinx.android.synthetic.main.include_omnibar_toolbar.view.* @@ -86,9 +81,6 @@ import timber.log.Timber import java.io.File import javax.inject.Inject import kotlin.concurrent.thread -import kotlinx.android.synthetic.main.include_home_screen_default_browser_call_to_action_bottom_sheet.homeScreenCallToActionContainer as bottomSheetExperimentContainer -import kotlinx.android.synthetic.main.include_home_screen_default_browser_call_to_action_bottom_sheet.homeScreenCallToActionDismissButton as bottomSheetExperimentDismissButton -import kotlinx.android.synthetic.main.include_home_screen_default_browser_call_to_action_bottom_sheet.launchSettingsButton as bottomSheetExperimentLaunchSettingsButton class BrowserTabFragment : Fragment(), FindListener { @@ -163,16 +155,14 @@ class BrowserTabFragment : Fragment(), FindListener { private val omnibarInputTextWatcher = object : TextChangedWatcher() { override fun afterTextChanged(editable: Editable) { viewModel.onOmnibarInputStateChanged( - omnibarTextInput.text.toString(), - omnibarTextInput.hasFocus() + omnibarTextInput.text.toString(), + omnibarTextInput.hasFocus() ) } } private val logoHidingLayoutChangeListener by lazy { LogoHidingLayoutChangeListener(ddgLogo) } - private val callToActionConfigurator = CallToActionConfigurator() - override fun onAttach(context: Context?) { AndroidSupportInjection.inject(this) super.onAttach(context) @@ -192,7 +182,6 @@ class BrowserTabFragment : Fragment(), FindListener { createPopupMenu() configureObservers() configureToolbar() - configureBannerNotification() configureWebView() viewModel.registerWebViewListener(webViewClient, webChromeClient) configureOmnibarTextInput() @@ -233,8 +222,8 @@ class BrowserTabFragment : Fragment(), FindListener { onMenuItemClicked(view.settingsPopupMenuItem) { browserActivity?.launchSettings() } onMenuItemClicked(view.requestDesktopSiteCheckMenuItem) { viewModel.desktopSiteModeToggled( - urlString = webView?.url, - desktopSiteRequested = view.requestDesktopSiteCheckMenuItem.isChecked + urlString = webView?.url, + desktopSiteRequested = view.requestDesktopSiteCheckMenuItem.isChecked ) } onMenuItemClicked(view.sharePageMenuItem) { viewModel.userSharingLink(webView?.url) } @@ -265,10 +254,6 @@ class BrowserTabFragment : Fragment(), FindListener { it?.let { renderer.renderBrowserViewState(it) } }) - viewModel.defaultBrowserViewState.observe(this, Observer { - it?.let { renderer.renderDefaultBrowserBanner(it) } - }) - viewModel.loadingViewState.observe(this, Observer { it?.let { renderer.renderLoadingIndicator(it) } }) @@ -351,10 +336,10 @@ class BrowserTabFragment : Fragment(), FindListener { } is Command.ShowFullScreen -> { webViewFullScreenContainer.addView( - it.view, ViewGroup.LayoutParams( + it.view, ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT - ) + ) ) } is Command.DownloadImage -> requestImageDownload(it.url) @@ -370,13 +355,9 @@ class BrowserTabFragment : Fragment(), FindListener { addHomeShortcut(it, context) } } - is Command.InflateCallToActionBottomSheet -> { - callToActionConfigurator.configureBottomSheetCallToAction() + is Command.HandleExternalAppLink -> { + externalAppLinkClicked(it) } - is Command.InflateCallToActionSimpleButton -> { - callToActionConfigurator.configureButtonCallToAction() - } - is Command.HandleExternalAppLink -> { externalAppLinkClicked(it) } } } @@ -453,12 +434,12 @@ class BrowserTabFragment : Fragment(), FindListener { val context = context ?: return autoCompleteSuggestionsList.layoutManager = LinearLayoutManager(context) autoCompleteSuggestionsAdapter = BrowserAutoCompleteSuggestionsAdapter( - immediateSearchClickListener = { - userEnteredQuery(it.phrase) - }, - editableSearchClickListener = { - viewModel.onUserSelectedToEditQuery(it.phrase) - } + immediateSearchClickListener = { + userEnteredQuery(it.phrase) + }, + editableSearchClickListener = { + viewModel.onUserSelectedToEditQuery(it.phrase) + } ) autoCompleteSuggestionsList.adapter = autoCompleteSuggestionsAdapter } @@ -493,15 +474,6 @@ class BrowserTabFragment : Fragment(), FindListener { }) } - private fun configureBannerNotification() { - dismissBannerButton.setOnClickListener { - viewModel.userDeclinedBannerToSetAsDefaultBrowser() - } - bannerNotification.setOnClickListener { - launchDefaultAppSystemSettingsFromBanner() - } - } - private fun configureFindInPage() { findInPageInput.setOnFocusChangeListener { _, hasFocus -> if (hasFocus && findInPageInput.text.toString() != viewModel.findInPageViewState.value?.searchTerm) { @@ -545,7 +517,7 @@ class BrowserTabFragment : Fragment(), FindListener { // we want layout transitions for when the size changes; we don't want them when items disappear (can cause glitch on call to action button) newTabLayout.layoutTransition?.enableTransitionType(CHANGING) newTabLayout.layoutTransition?.disableTransitionType(DISAPPEARING) - + rootView.addOnLayoutChangeListener(logoHidingLayoutChangeListener) } @@ -555,7 +527,11 @@ class BrowserTabFragment : Fragment(), FindListener { @SuppressLint("SetJavaScriptEnabled") private fun configureWebView() { - webView = layoutInflater.inflate(R.layout.include_duckduckgo_browser_webview, webViewContainer, true).findViewById(R.id.browserWebView) as WebView + webView = layoutInflater.inflate( + R.layout.include_duckduckgo_browser_webview, + webViewContainer, + true + ).findViewById(R.id.browserWebView) as WebView webView?.let { userAgentProvider = UserAgentProvider(it.settings.userAgentString) @@ -621,25 +597,10 @@ class BrowserTabFragment : Fragment(), FindListener { activity?.share(url, "") } - private fun launchDefaultAppSystemSettingsFromBanner() { - activity?.let { - val options = ActivityOptions.makeSceneTransitionAnimation(it, bannerNotification, "defaultBrowserBannerTransition") - val intent = DefaultBrowserInfoActivity.intent(it) - startActivity(intent, options.toBundle()) - } - } - - private fun launchDefaultAppSystemSettingsFromCallToActionButton() { - activity?.let { - val intent = DefaultBrowserInfoActivity.intent(it) - startActivity(intent) - } - } - private fun addBookmark() { val addBookmarkDialog = SaveBookmarkDialogFragment.createDialogCreationMode( - existingTitle = webView?.title, - existingUrl = webView?.url + existingTitle = webView?.title, + existingUrl = webView?.url ) addBookmarkDialog.show(childFragmentManager, ADD_BOOKMARK_FRAGMENT_TAG) addBookmarkDialog.listener = viewModel @@ -747,18 +708,20 @@ class BrowserTabFragment : Fragment(), FindListener { private fun requestFileDownload(url: String, contentDisposition: String, mimeType: String) { pendingFileDownload = PendingFileDownload( - url = url, - contentDisposition = contentDisposition, - mimeType = mimeType, - subfolder = Environment.DIRECTORY_DOWNLOADS) + url = url, + contentDisposition = contentDisposition, + mimeType = mimeType, + subfolder = Environment.DIRECTORY_DOWNLOADS + ) downloadFileWithPermissionCheck() } private fun requestImageDownload(url: String) { pendingFileDownload = PendingFileDownload( - url = url, - subfolder = Environment.DIRECTORY_PICTURES) + url = url, + subfolder = Environment.DIRECTORY_PICTURES + ) downloadFileWithPermissionCheck() } @@ -851,29 +814,8 @@ class BrowserTabFragment : Fragment(), FindListener { private var lastSeenFindInPageViewState: FindInPageViewState? = null private var lastSeenBrowserViewState: BrowserViewState? = null private var lastSeenGlobalViewState: GlobalLayoutViewState? = null - private var lastSeenDefaultBrowserViewState: DefaultBrowserViewState? = null private var lastSeenAutoCompleteViewState: AutoCompleteViewState? = null - fun renderDefaultBrowserBanner(viewState: DefaultBrowserViewState) { - renderIfChanged(viewState, lastSeenDefaultBrowserViewState) { - lastSeenDefaultBrowserViewState = viewState - - if (viewState.showDefaultBrowserBanner) { - bannerNotification.show() - } else { - bannerNotification.gone() - } - - if (viewState.showHomeScreenCallToActionButton) { - homeScreenCallToActionContainer?.show() - } else { - homeScreenCallToActionContainer?.gone() - } - - logoHidingLayoutChangeListener.update() - } - } - fun renderAutocomplete(viewState: AutoCompleteViewState) { renderIfChanged(viewState, lastSeenAutoCompleteViewState) { lastSeenAutoCompleteViewState = viewState @@ -1056,52 +998,4 @@ class BrowserTabFragment : Fragment(), FindListener { private fun shouldUpdateOmnibarTextInput(viewState: OmnibarViewState, omnibarInput: String?) = !viewState.isEditing && omnibarTextInput.isDifferent(omnibarInput) } - - private inner class CallToActionConfigurator { - - fun configureBottomSheetCallToAction() { - if (callToActionStub == null) return - - callToActionStub.layoutResource = R.layout.include_home_screen_default_browser_call_to_action_bottom_sheet - val container = callToActionStub.inflate() - - adjustLogoConstraintsForCallToAction(container) - - bottomSheetExperimentLaunchSettingsButton.setOnClickListener { launchDefaultAppSystemSettingsFromCallToActionButton() } - bottomSheetExperimentDismissButton.setOnClickListener { viewModel.userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser() } - } - - fun configureButtonCallToAction() { - if (callToActionStub == null) return - - callToActionStub.layoutResource = R.layout.include_home_screen_default_browser_call_to_action - val container = callToActionStub.inflate() - - adjustLogoConstraintsForCallToAction(container) - - val set = ConstraintSet() - set.clone(newTabLayout) - set.constrainPercentWidth(container.id, 0.9f) - set.connect(container.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 10.toPx()) - set.applyTo(newTabLayout) - - homeScreenCallToActionContainer.setOnClickListener { launchDefaultAppSystemSettingsFromCallToActionButton() } - homeScreenCallToActionDismissButton.setOnClickListener { viewModel.userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser() } - } - - /** - * We want to center logo in space available above call to action, but c2a isn't in original view hierarchy. - * After appropriate c2a is loaded, we programmatically apply ConstraintLayout constraints to position logo - */ - private fun adjustLogoConstraintsForCallToAction(callToActionContainer: View) { - - logoHidingLayoutChangeListener.callToActionButton = callToActionContainer - - ConstraintSet().also { - it.clone(newTabLayout) - it.connect(ddgLogo.id, ConstraintSet.BOTTOM, callToActionContainer.id, ConstraintSet.TOP, 0) - it.applyTo(newTabLayout) - } - } - } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt index 887acd2be40d..7c738b5af05d 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt @@ -40,8 +40,6 @@ import com.duckduckgo.app.bookmarks.ui.SaveBookmarkDialogFragment.SaveBookmarkLi import com.duckduckgo.app.browser.BrowserTabViewModel.Command.* import com.duckduckgo.app.browser.LongPressHandler.RequiredAction import com.duckduckgo.app.browser.SpecialUrlDetector.UrlType.IntentType -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserNotification import com.duckduckgo.app.browser.favicon.FaviconDownloader import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter import com.duckduckgo.app.browser.session.WebViewSessionStorage @@ -59,9 +57,6 @@ import com.duckduckgo.app.privacy.db.SiteVisitedEntity import com.duckduckgo.app.privacy.model.PrivacyGrade import com.duckduckgo.app.privacy.model.improvedGrade import com.duckduckgo.app.settings.db.SettingsDataStore -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionBottomSheet -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionSimpleButton import com.duckduckgo.app.statistics.api.StatisticsUpdater import com.duckduckgo.app.tabs.model.TabEntity import com.duckduckgo.app.tabs.model.TabRepository @@ -82,12 +77,9 @@ class BrowserTabViewModel( private val bookmarksDao: BookmarksDao, private val autoCompleteApi: AutoCompleteApi, private val appSettingsPreferencesStore: SettingsDataStore, - private val defaultBrowserDetector: DefaultBrowserDetector, - private val defaultBrowserNotification: DefaultBrowserNotification, private val longPressHandler: LongPressHandler, private val webViewSessionStorage: WebViewSessionStorage, private val specialUrlDetector: SpecialUrlDetector, - private val variantManager: VariantManager, private val faviconDownloader: FaviconDownloader, appConfigurationDao: AppConfigurationDao ) : WebViewClientListener, SaveBookmarkListener, ViewModel() { @@ -136,11 +128,6 @@ class BrowserTabViewModel( val searchResults: AutoCompleteResult = AutoCompleteResult("", emptyList()) ) - data class DefaultBrowserViewState( - val showDefaultBrowserBanner: Boolean = false, - val showHomeScreenCallToActionButton: Boolean = false - ) - sealed class Command { object LandingPage : Command() object Refresh : Command() @@ -161,9 +148,7 @@ class BrowserTabViewModel( object DismissFindInPage : Command() class ShowFileChooser(val filePathCallback: ValueCallback>, val fileChooserParams: WebChromeClient.FileChooserParams) : Command() class HandleExternalAppLink(val appLink: IntentType) : Command() - class AddHomeShortcut(val title: String, val url: String, val icon: Bitmap?= null) : Command() - object InflateCallToActionBottomSheet : Command() - object InflateCallToActionSimpleButton : Command() + class AddHomeShortcut(val title: String, val url: String, val icon: Bitmap? = null) : Command() } val autoCompleteViewState: MutableLiveData = MutableLiveData() @@ -171,7 +156,6 @@ class BrowserTabViewModel( val globalLayoutState: MutableLiveData = MutableLiveData() val loadingViewState: MutableLiveData = MutableLiveData() val omnibarViewState: MutableLiveData = MutableLiveData() - val defaultBrowserViewState: MutableLiveData = MutableLiveData() val findInPageViewState: MutableLiveData = MutableLiveData() val tabs: LiveData> = tabRepository.liveTabs @@ -249,20 +233,6 @@ class BrowserTabViewModel( fun onViewVisible() { command.value = if (url.value == null) ShowKeyboard else Command.HideKeyboard - - val showBanner = defaultBrowserNotification.shouldShowBannerNotification(currentBrowserViewState().browserShowing) - val showCallToAction = defaultBrowserNotification.shouldShowHomeScreenCallToActionNotification() - - if (showCallToAction) { - val variant = variantManager.getVariant() - if (variant.hasFeature(ShowHomeScreenCallToActionBottomSheet)) { - command.value = InflateCallToActionBottomSheet - } else if (variant.hasFeature(ShowHomeScreenCallToActionSimpleButton)) { - command.value = InflateCallToActionSimpleButton - } - } - - defaultBrowserViewState.value = DefaultBrowserViewState(showBanner, showCallToAction) } fun onUserSubmittedQuery(input: String) { @@ -383,8 +353,6 @@ class BrowserTabViewModel( ) if (duckDuckGoUrlDetector.isDuckDuckGoQueryUrl(url)) { - val shouldShowBanner = defaultBrowserNotification.shouldShowBannerNotification(currentBrowserViewState.browserShowing) - defaultBrowserViewState.value = currentDefaultBrowserViewState().copy(showDefaultBrowserBanner = shouldShowBanner) statisticsUpdater.refreshRetentionAtb() } @@ -436,7 +404,6 @@ class BrowserTabViewModel( private fun currentFindInPageViewState(): FindInPageViewState = findInPageViewState.value!! private fun currentOmnibarViewState(): OmnibarViewState = omnibarViewState.value!! private fun currentLoadingViewState(): LoadingViewState = loadingViewState.value!! - private fun currentDefaultBrowserViewState(): DefaultBrowserViewState = defaultBrowserViewState.value!! fun onOmnibarInputStateChanged(query: String, hasFocus: Boolean) { @@ -547,9 +514,11 @@ class BrowserTabViewModel( fun onFindResultsReceived(activeMatchOrdinal: Int, numberOfMatches: Int) { val activeIndex = if (numberOfMatches == 0) 0 else activeMatchOrdinal + 1 val currentViewState = currentFindInPageViewState() - findInPageViewState.value = currentViewState.copy(showNumberMatches = true, - activeMatchIndex = activeIndex, - numberMatches = numberOfMatches) + findInPageViewState.value = currentViewState.copy( + showNumberMatches = true, + activeMatchIndex = activeIndex, + numberMatches = numberOfMatches + ) } fun onWebSessionRestored() { @@ -582,7 +551,6 @@ class BrowserTabViewModel( private fun initializeViewStates() { globalLayoutState.value = GlobalLayoutViewState() - defaultBrowserViewState.value = DefaultBrowserViewState(showHomeScreenCallToActionButton = defaultBrowserNotification.shouldShowHomeScreenCallToActionNotification()) browserViewState.value = BrowserViewState() loadingViewState.value = LoadingViewState() autoCompleteViewState.value = AutoCompleteViewState() @@ -596,18 +564,6 @@ class BrowserTabViewModel( } } - fun userDeclinedBannerToSetAsDefaultBrowser() { - defaultBrowserDetector.userDeclinedBannerToSetAsDefaultBrowser() - val currentDefaultBrowserViewState = currentDefaultBrowserViewState() - defaultBrowserViewState.value = currentDefaultBrowserViewState.copy(showDefaultBrowserBanner = false) - } - - fun userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser() { - defaultBrowserDetector.userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser() - val currentDefaultBrowserViewState = currentDefaultBrowserViewState() - defaultBrowserViewState.value = currentDefaultBrowserViewState.copy(showHomeScreenCallToActionButton = false) - } - fun saveWebViewState(webView: WebView?, tabId: String) { webViewSessionStorage.saveSession(webView, tabId) } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt index 0a056d778a58..32db43e22efe 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserWebViewClient.kt @@ -28,9 +28,9 @@ import javax.inject.Inject class BrowserWebViewClient @Inject constructor( - private val requestRewriter: RequestRewriter, - private val specialUrlDetector: SpecialUrlDetector, - private val webViewRequestInterceptor: WebViewRequestInterceptor + private val requestRewriter: RequestRewriter, + private val specialUrlDetector: SpecialUrlDetector, + private val webViewRequestInterceptor: WebViewRequestInterceptor ) : WebViewClient() { var webViewClientListener: WebViewClientListener? = null @@ -112,7 +112,7 @@ class BrowserWebViewClient @Inject constructor( * Utility to function to execute a function, and then return true * * Useful to reduce clutter in repeatedly including `return true` after doing the real work. - */ + */ private inline fun consume(function: () -> Unit): Boolean { function() return true diff --git a/app/src/main/java/com/duckduckgo/app/browser/TabSwitcherButton.kt b/app/src/main/java/com/duckduckgo/app/browser/TabSwitcherButton.kt index 756c99327c02..b00e5359b237 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/TabSwitcherButton.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/TabSwitcherButton.kt @@ -49,7 +49,7 @@ class TabSwitcherButton(context: Context) : FrameLayout(context) { fun increment(callback: () -> Unit) { anim.progress = 0.0f - anim.addAnimatorListener(object: AnimatorListenerAdapter() { + anim.addAnimatorListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { callback() } @@ -64,7 +64,7 @@ class TabSwitcherButton(context: Context) : FrameLayout(context) { } private fun fadeOutCount(callback: () -> Unit) { - val listener = object: AnimatorListenerAdapter() { + val listener = object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator?) { // otherwise on end keeps being called repeatedly tabCount.animate().setListener(null) diff --git a/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteModule.kt b/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteModule.kt index ab7d06116af1..a070fca5522a 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteModule.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteModule.kt @@ -17,8 +17,8 @@ package com.duckduckgo.app.browser.autoComplete import android.content.Context -import com.duckduckgo.app.settings.db.SettingsSharedPreferences import com.duckduckgo.app.settings.db.SettingsDataStore +import com.duckduckgo.app.settings.db.SettingsSharedPreferences import dagger.Module import dagger.Provides diff --git a/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteSuggestionsAdapter.kt b/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteSuggestionsAdapter.kt index 7aac52f962ca..bb928370462d 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteSuggestionsAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/autoComplete/BrowserAutoCompleteSuggestionsAdapter.kt @@ -30,8 +30,9 @@ import kotlinx.android.synthetic.main.item_autocomplete_suggestion.view.* import javax.inject.Inject class BrowserAutoCompleteSuggestionsAdapter @Inject constructor( - private val immediateSearchClickListener: (AutoCompleteSuggestion) -> Unit, - private val editableSearchClickListener: (AutoCompleteSuggestion) -> Unit) : RecyclerView.Adapter() { + private val immediateSearchClickListener: (AutoCompleteSuggestion) -> Unit, + private val editableSearchClickListener: (AutoCompleteSuggestion) -> Unit +) : RecyclerView.Adapter() { private val suggestions: MutableList = ArrayList() @@ -48,7 +49,7 @@ class BrowserAutoCompleteSuggestionsAdapter @Inject constructor( } override fun getItemViewType(position: Int): Int { - if(suggestions.isEmpty()) { + if (suggestions.isEmpty()) { return EMPTY_TYPE } @@ -86,9 +87,11 @@ class BrowserAutoCompleteSuggestionsAdapter @Inject constructor( sealed class AutoCompleteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class SuggestionViewHolder(itemView: View) : AutoCompleteViewHolder(itemView) { - fun bind(item: AutoCompleteSuggestion, - immediateSearchListener: (AutoCompleteSuggestion) -> Unit, - editableSearchClickListener: (AutoCompleteSuggestion) -> Unit) = with(itemView) { + fun bind( + item: AutoCompleteSuggestion, + immediateSearchListener: (AutoCompleteSuggestion) -> Unit, + editableSearchClickListener: (AutoCompleteSuggestion) -> Unit + ) = with(itemView) { phrase.text = item.phrase diff --git a/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserDetector.kt b/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserDetector.kt index e8888f5192d1..fb6be5602e33 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserDetector.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserDetector.kt @@ -24,19 +24,15 @@ import android.content.pm.ResolveInfo import android.net.Uri import android.os.Build import com.duckduckgo.app.browser.BuildConfig -import com.duckduckgo.app.global.install.AppInstallStore import timber.log.Timber import javax.inject.Inject interface DefaultBrowserDetector { fun deviceSupportsDefaultBrowserConfiguration(): Boolean fun isCurrentlyConfiguredAsDefaultBrowser(): Boolean - fun userDeclinedBannerToSetAsDefaultBrowser(timestamp: Long = System.currentTimeMillis()) - fun userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser(timestamp: Long = System.currentTimeMillis()) } -class AndroidDefaultBrowserDetector @Inject constructor(private val context: Context, private val appInstallStore: AppInstallStore) : - DefaultBrowserDetector { +class AndroidDefaultBrowserDetector @Inject constructor(private val context: Context) : DefaultBrowserDetector { override fun deviceSupportsDefaultBrowserConfiguration(): Boolean { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N @@ -50,12 +46,4 @@ class AndroidDefaultBrowserDetector @Inject constructor(private val context: Con Timber.i("Default browser identified as ${resolutionInfo?.activityInfo?.packageName}") return defaultAlready } - - override fun userDeclinedBannerToSetAsDefaultBrowser(timestamp: Long) { - appInstallStore.recordUserDeclinedBannerToSetDefaultBrowser(timestamp) - } - - override fun userDeclinedHomeScreenCallToActionToSetAsDefaultBrowser(timestamp: Long) { - appInstallStore.recordUserDeclinedHomeScreenCallToActionToSetDefaultBrowser(timestamp) - } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserNotification.kt b/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserNotification.kt deleted file mode 100644 index 64642113ac5e..000000000000 --- a/app/src/main/java/com/duckduckgo/app/browser/defaultBrowsing/DefaultBrowserNotification.kt +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2018 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.defaultBrowsing - -import com.duckduckgo.app.browser.BuildConfig -import com.duckduckgo.app.global.install.AppInstallStore -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowBanner -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionSimpleButton -import java.util.concurrent.TimeUnit -import javax.inject.Inject - - -interface DefaultBrowserNotification { - fun shouldShowBannerNotification( - browserShowing: Boolean, - timeNow: Long = System.currentTimeMillis() - ): Boolean - - fun shouldShowHomeScreenCallToActionNotification(): Boolean -} - -class DefaultBrowserTimeBasedNotification @Inject constructor( - private val defaultBrowserDetector: DefaultBrowserDetector, - private val appInstallStore: AppInstallStore, - private val variantManager: VariantManager -) : DefaultBrowserNotification { - - override fun shouldShowBannerNotification(browserShowing: Boolean, timeNow: Long): Boolean { - - if (!browserShowing) { - return false - } - - if (!isDeviceCapable()) { - return false - } - - if (!isFeatureEnabled(ShowBanner)) { - return false - } - - if (isAlreadyDefaultBrowser()) { - return false - } - - if (appInstallStore.hasUserDeclinedDefaultBrowserBannerPreviously()) { - return false - } - - return hasEnoughTimeElapsed(timeNow) - } - - override fun shouldShowHomeScreenCallToActionNotification(): Boolean { - - if (!isDeviceCapable()) { - return false - } - - if (!isFeatureEnabled(ShowHomeScreenCallToActionSimpleButton) && !isFeatureEnabled(DefaultBrowserFeature.ShowHomeScreenCallToActionBottomSheet)) { - return false - } - - if (isAlreadyDefaultBrowser()) { - return false - } - - if (appInstallStore.hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously()) { - return false - } - - return true - } - - private fun isDeviceCapable(): Boolean { - return defaultBrowserDetector.deviceSupportsDefaultBrowserConfiguration() && appInstallStore.hasInstallTimestampRecorded() - } - - private fun isFeatureEnabled(feature: DefaultBrowserFeature): Boolean { - return variantManager.getVariant().hasFeature(feature) - } - - private fun isAlreadyDefaultBrowser(): Boolean { - return defaultBrowserDetector.isCurrentlyConfiguredAsDefaultBrowser() - } - - private fun hasEnoughTimeElapsed(now: Long): Boolean { - val elapsed = calculateElapsedTime(now) - - return elapsed >= ELAPSED_TIME_THRESHOLD_MS - } - - private fun calculateElapsedTime(now: Long): Long { - return now - appInstallStore.installTimestamp - } - - companion object { - - // time period to wait after first launch before showing notification banner - set much shorter for DEBUG builds so it can be tested - private val ELAPSED_TIME_THRESHOLD_PRODUCTION = TimeUnit.DAYS.toMillis(3) - private val ELAPSED_TIME_THRESHOLD_DEBUG = TimeUnit.SECONDS.toMillis(20) - - private val ELAPSED_TIME_THRESHOLD_MS = if (BuildConfig.DEBUG) ELAPSED_TIME_THRESHOLD_DEBUG else ELAPSED_TIME_THRESHOLD_PRODUCTION - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/browser/di/BrowserModule.kt b/app/src/main/java/com/duckduckgo/app/browser/di/BrowserModule.kt index 4260223f1da8..489b1a350376 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/di/BrowserModule.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/di/BrowserModule.kt @@ -23,7 +23,6 @@ import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector import com.duckduckgo.app.browser.session.WebViewSessionInMemoryStorage import com.duckduckgo.app.browser.session.WebViewSessionStorage import com.duckduckgo.app.global.AppUrl -import com.duckduckgo.app.global.install.AppInstallStore import com.duckduckgo.app.statistics.VariantManager import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.app.statistics.store.StatisticsDataStore @@ -49,8 +48,8 @@ class BrowserModule { } @Provides - fun defaultWebBrowserCapability(context: Context, appInstallStore: AppInstallStore): DefaultBrowserDetector { - return AndroidDefaultBrowserDetector(context, appInstallStore) + fun defaultWebBrowserCapability(context: Context): DefaultBrowserDetector { + return AndroidDefaultBrowserDetector(context) } @Singleton diff --git a/app/src/main/java/com/duckduckgo/app/browser/di/DefaultBrowserModule.kt b/app/src/main/java/com/duckduckgo/app/browser/di/DefaultBrowserModule.kt deleted file mode 100644 index ea89a055cdcb..000000000000 --- a/app/src/main/java/com/duckduckgo/app/browser/di/DefaultBrowserModule.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2018 DuckDuckGo - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.duckduckgo.app.browser.di - -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserNotification -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserTimeBasedNotification -import dagger.Binds -import dagger.Module - - -@Module -abstract class DefaultBrowserModule { - - @Binds - abstract fun defaultBrowserNotification(defaultBrowserNotification: DefaultBrowserTimeBasedNotification): DefaultBrowserNotification -} \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriDownloader.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriDownloader.kt index 415f8d52d0be..19bbd7e2508b 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriDownloader.kt @@ -26,7 +26,8 @@ import java.io.IOException import javax.inject.Inject class DataUriDownloader @Inject constructor( - private val dataUriParser: DataUriParser) { + private val dataUriParser: DataUriParser +) { @WorkerThread fun download(pending: FileDownloader.PendingFileDownload, callback: FileDownloader.FileDownloadListener?) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriParser.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriParser.kt index cd3d28f7b852..6c107433cb4f 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriParser.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/DataUriParser.kt @@ -64,11 +64,11 @@ class DataUriParser @Inject constructor() { object Invalid : ParseResult() data class ParsedDataUri( - val fileTypeGeneral: String, - val fileTypeSpecific: String, - val data: String, - val mimeType: String, - val filename: GeneratedFilename + val fileTypeGeneral: String, + val fileTypeSpecific: String, + val data: String, + val mimeType: String, + val filename: GeneratedFilename ) : ParseResult() } diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloadNotificationManager.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloadNotificationManager.kt index 51a0233bae9a..84456b262d3b 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloadNotificationManager.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloadNotificationManager.kt @@ -31,17 +31,18 @@ import javax.inject.Inject @AnyThread class FileDownloadNotificationManager @Inject constructor( - private val notificationManager: NotificationManager, - private val applicationContext: Context) { + private val notificationManager: NotificationManager, + private val applicationContext: Context +) { fun showDownloadInProgressNotification() { applicationContext.runOnUiThread { applicationContext.longToast(getString(R.string.downloadInProgress)) val notification = NotificationCompat.Builder(applicationContext, NotificationRegistrar.FILE_DOWNLOADING_CHANNEL_ID) - .setContentTitle(applicationContext.getString(R.string.downloadInProgress)) - .setSmallIcon(R.drawable.ic_file_download_white_24dp) - .build() + .setContentTitle(applicationContext.getString(R.string.downloadInProgress)) + .setSmallIcon(R.drawable.ic_file_download_white_24dp) + .build() notificationManager.notify(NOTIFICATION_ID, notification) } @@ -56,12 +57,12 @@ class FileDownloadNotificationManager @Inject constructor( i.setDataAndType(uri, mimeType) val notification = NotificationCompat.Builder(applicationContext, NotificationRegistrar.FILE_DOWNLOADED_CHANNEL_ID) - .setContentTitle(filename) - .setContentText(applicationContext.getString(R.string.downloadComplete)) - .setContentIntent(PendingIntent.getActivity(applicationContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT)) - .setAutoCancel(true) - .setSmallIcon(R.drawable.ic_file_download_white_24dp) - .build() + .setContentTitle(filename) + .setContentText(applicationContext.getString(R.string.downloadComplete)) + .setContentIntent(PendingIntent.getActivity(applicationContext, 0, i, PendingIntent.FLAG_UPDATE_CURRENT)) + .setAutoCancel(true) + .setSmallIcon(R.drawable.ic_file_download_white_24dp) + .build() notificationManager.notify(NOTIFICATION_ID, notification) } @@ -72,9 +73,9 @@ class FileDownloadNotificationManager @Inject constructor( applicationContext.longToast(getString(R.string.downloadFailed)) val notification = NotificationCompat.Builder(applicationContext, NotificationRegistrar.FILE_DOWNLOADED_CHANNEL_ID) - .setContentTitle(applicationContext.getString(R.string.downloadFailed)) - .setSmallIcon(R.drawable.ic_file_download_white_24dp) - .build() + .setContentTitle(applicationContext.getString(R.string.downloadFailed)) + .setSmallIcon(R.drawable.ic_file_download_white_24dp) + .build() notificationManager.notify(NOTIFICATION_ID, notification) } diff --git a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt index a004d9701254..f0d52bac6f71 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/downloader/FileDownloader.kt @@ -23,8 +23,9 @@ import java.io.File import javax.inject.Inject class FileDownloader @Inject constructor( - private val dataUriDownloader: DataUriDownloader, - private val networkDownloader: NetworkFileDownloader) { + private val dataUriDownloader: DataUriDownloader, + private val networkDownloader: NetworkFileDownloader +) { @WorkerThread fun download(pending: PendingFileDownload?, callback: FileDownloadListener?) { @@ -41,11 +42,11 @@ class FileDownloader @Inject constructor( } data class PendingFileDownload( - val url: String, - val contentDisposition: String? = null, - val mimeType: String? = null, - val subfolder: String, - val directory: File = Environment.getExternalStoragePublicDirectory(subfolder) + val url: String, + val contentDisposition: String? = null, + val mimeType: String? = null, + val subfolder: String, + val directory: File = Environment.getExternalStoragePublicDirectory(subfolder) ) interface FileDownloadListener { diff --git a/app/src/main/java/com/duckduckgo/app/browser/filechooser/FileChooserIntentBuilder.kt b/app/src/main/java/com/duckduckgo/app/browser/filechooser/FileChooserIntentBuilder.kt index 0069006984a7..e799341a1cb2 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/filechooser/FileChooserIntentBuilder.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/filechooser/FileChooserIntentBuilder.kt @@ -75,8 +75,8 @@ class FileChooserIntentBuilder @Inject constructor() { val acceptedMimeTypes = mutableSetOf() acceptTypes - .filter { it.isNotBlank() } - .forEach { acceptedMimeTypes.add(it.toLowerCase()) } + .filter { it.isNotBlank() } + .forEach { acceptedMimeTypes.add(it.toLowerCase()) } if (acceptedMimeTypes.isNotEmpty()) { Timber.d("Selectable file types limited to $acceptedMimeTypes") diff --git a/app/src/main/java/com/duckduckgo/app/browser/useragent/UserAgentProvider.kt b/app/src/main/java/com/duckduckgo/app/browser/useragent/UserAgentProvider.kt index a68ab57fc6ba..edf9169ea825 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/useragent/UserAgentProvider.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/useragent/UserAgentProvider.kt @@ -35,9 +35,9 @@ class UserAgentProvider constructor(private val defaultUserAgent: String) { * * We include everything from the original UA string from AppleWebKit onwards (omitting if missing) */ - fun getUserAgent(desktopSiteRequested: Boolean = false) : String{ + fun getUserAgent(desktopSiteRequested: Boolean = false): String { - val platform = if(desktopSiteRequested) desktopUaPrefix() else mobileUaPrefix() + val platform = if (desktopSiteRequested) desktopUaPrefix() else mobileUaPrefix() val userAgentStringSuffix = getWebKitVersionOnwards(desktopSiteRequested) return "$MOZILLA_PREFIX ($platform)$userAgentStringSuffix" @@ -50,7 +50,7 @@ class UserAgentProvider constructor(private val defaultUserAgent: String) { private fun getWebKitVersionOnwards(desktopSiteRequested: Boolean): String { val matches = WEB_KIT_REGEX.find(defaultUserAgent) ?: return "" var result = matches.groupValues[0] - if(desktopSiteRequested) { + if (desktopSiteRequested) { result = result.replace(" Mobile ", " ") } return " $result" diff --git a/app/src/main/java/com/duckduckgo/app/di/AppComponent.kt b/app/src/main/java/com/duckduckgo/app/di/AppComponent.kt index 5a06bcc5200f..8b1e2664b933 100644 --- a/app/src/main/java/com/duckduckgo/app/di/AppComponent.kt +++ b/app/src/main/java/com/duckduckgo/app/di/AppComponent.kt @@ -20,7 +20,6 @@ package com.duckduckgo.app.di import android.app.Application import com.duckduckgo.app.browser.autoComplete.BrowserAutoCompleteModule import com.duckduckgo.app.browser.di.BrowserModule -import com.duckduckgo.app.browser.di.DefaultBrowserModule import com.duckduckgo.app.browser.favicon.FaviconModule import com.duckduckgo.app.global.DuckDuckGoApplication import com.duckduckgo.app.httpsupgrade.di.HttpsUpgraderModule @@ -34,29 +33,30 @@ import dagger.android.support.AndroidSupportInjectionModule import javax.inject.Singleton @Singleton -@Component(modules = [ - ApplicationModule::class, - JobsModule::class, - AndroidBindingModule::class, - AndroidSupportInjectionModule::class, - NetworkModule::class, - AppConfigurationDownloaderModule::class, - StatisticsModule::class, - StoreModule::class, - DatabaseModule::class, - DaoModule::class, - JsonModule::class, - BrowserModule::class, - BrowserAutoCompleteModule::class, - HttpsUpgraderModule::class, - ResourceSurrogateModule::class, - TrackerDetectionModule::class, - NotificationModule::class, - DefaultBrowserModule::class, - OnboardingModule::class, - VariantModule::class, - FaviconModule::class -]) +@Component( + modules = [ + ApplicationModule::class, + JobsModule::class, + AndroidBindingModule::class, + AndroidSupportInjectionModule::class, + NetworkModule::class, + AppConfigurationDownloaderModule::class, + StatisticsModule::class, + StoreModule::class, + DatabaseModule::class, + DaoModule::class, + JsonModule::class, + BrowserModule::class, + BrowserAutoCompleteModule::class, + HttpsUpgraderModule::class, + ResourceSurrogateModule::class, + TrackerDetectionModule::class, + NotificationModule::class, + OnboardingModule::class, + VariantModule::class, + FaviconModule::class + ] +) interface AppComponent : AndroidInjector { @Component.Builder diff --git a/app/src/main/java/com/duckduckgo/app/di/AppConfigurationDownloadModule.kt b/app/src/main/java/com/duckduckgo/app/di/AppConfigurationDownloadModule.kt index 37bbc1d4210a..0f1c2220c1f8 100644 --- a/app/src/main/java/com/duckduckgo/app/di/AppConfigurationDownloadModule.kt +++ b/app/src/main/java/com/duckduckgo/app/di/AppConfigurationDownloadModule.kt @@ -29,10 +29,12 @@ import dagger.Provides open class AppConfigurationDownloaderModule { @Provides - open fun appConfigurationDownloader(trackerDataDownloader: TrackerDataDownloader, - httpsUpgradeDataDownloader: HttpsUpgradeDataDownloader, - resourceSurrogateDownloader: ResourceSurrogateListDownloader, - appDatabase: AppDatabase) : ConfigurationDownloader { + open fun appConfigurationDownloader( + trackerDataDownloader: TrackerDataDownloader, + httpsUpgradeDataDownloader: HttpsUpgradeDataDownloader, + resourceSurrogateDownloader: ResourceSurrogateListDownloader, + appDatabase: AppDatabase + ): ConfigurationDownloader { return AppConfigurationDownloader(trackerDataDownloader, httpsUpgradeDataDownloader, resourceSurrogateDownloader, appDatabase) } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/di/JsonModule.kt b/app/src/main/java/com/duckduckgo/app/di/JsonModule.kt index 0f00b4919554..27118ecbed75 100644 --- a/app/src/main/java/com/duckduckgo/app/di/JsonModule.kt +++ b/app/src/main/java/com/duckduckgo/app/di/JsonModule.kt @@ -32,6 +32,6 @@ class JsonModule { fun moshi(): Moshi = Moshi.Builder() .add(HttpsWhitelistJsonAdapter()) .add(DisconnectListJsonAdapter()) - .add(TermsOfServiceListAdapter()) - .build() + .add(TermsOfServiceListAdapter()) + .build() } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/feedback/ui/FeedbackActivity.kt b/app/src/main/java/com/duckduckgo/app/feedback/ui/FeedbackActivity.kt index 78945057bb04..1eda982c60b6 100644 --- a/app/src/main/java/com/duckduckgo/app/feedback/ui/FeedbackActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/feedback/ui/FeedbackActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.feedback.ui import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -28,21 +27,14 @@ import com.duckduckgo.app.browser.R import com.duckduckgo.app.feedback.ui.FeedbackViewModel.Command import com.duckduckgo.app.feedback.ui.FeedbackViewModel.ViewState import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.view.TextChangedWatcher import kotlinx.android.synthetic.main.activity_feedback.* import org.jetbrains.anko.longToast -import javax.inject.Inject class FeedbackActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: FeedbackViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(FeedbackViewModel::class.java) - } + private val viewModel: FeedbackViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -105,7 +97,7 @@ class FeedbackActivity : DuckDuckGoActivity() { } private fun render(viewState: ViewState) { - val messageHint = if (viewState.isBrokenSite) R.string.feedbackBrokenSiteHint else R.string.feedbackMessageHint + val messageHint = if (viewState.isBrokenSite) R.string.feedbackBrokenSiteHint else R.string.feedbackMessageHint brokenSiteSwitch.isChecked = viewState.isBrokenSite brokenSiteUrl.isVisible = viewState.showUrl brokenSiteUrl.updateText(viewState.url ?: "") diff --git a/app/src/main/java/com/duckduckgo/app/fire/FireActivity.kt b/app/src/main/java/com/duckduckgo/app/fire/FireActivity.kt index 36f9b4a3d3c0..f34c271deba9 100644 --- a/app/src/main/java/com/duckduckgo/app/fire/FireActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/fire/FireActivity.kt @@ -21,7 +21,6 @@ import android.animation.AnimatorListenerAdapter import android.app.Activity import android.app.ActivityManager import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -30,9 +29,7 @@ import android.support.v4.app.ActivityOptionsCompat import com.duckduckgo.app.browser.BrowserActivity import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import kotlinx.android.synthetic.main.activity_fire.* -import javax.inject.Inject /** * Activity which is responsible for killing the main process and restarting it. This Activity will automatically finish itself after a brief time. @@ -49,12 +46,7 @@ import javax.inject.Inject */ class FireActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: FireViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(FireViewModel::class.java) - } + private val viewModel: FireViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/global/AppUrl.kt b/app/src/main/java/com/duckduckgo/app/global/AppUrl.kt index c3b223d60275..12431477d8e8 100644 --- a/app/src/main/java/com/duckduckgo/app/global/AppUrl.kt +++ b/app/src/main/java/com/duckduckgo/app/global/AppUrl.kt @@ -22,7 +22,7 @@ class AppUrl { object Url { const val HOST = "duckduckgo.com" const val API = "https://$HOST" - const val HOME = "https://$HOST" + const val HOME = "https://$HOST" const val ABOUT = "https://$HOST/about" const val TOSDR = "https://tosdr.org" const val PIXEL = "https://improving.duckduckgo.com" diff --git a/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoActivity.kt b/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoActivity.kt index 02522e8ba162..7202b629a4b2 100644 --- a/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoActivity.kt @@ -16,14 +16,20 @@ package com.duckduckgo.app.global +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProviders import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.view.MenuItem import dagger.android.AndroidInjection +import javax.inject.Inject abstract class DuckDuckGoActivity : AppCompatActivity() { + @Inject + lateinit var viewModelFactory: ViewModelFactory + override fun onCreate(savedInstanceState: Bundle?) { AndroidInjection.inject(this) super.onCreate(savedInstanceState) @@ -38,4 +44,6 @@ abstract class DuckDuckGoActivity : AppCompatActivity() { } return super.onOptionsItemSelected(item) } + + protected inline fun bindViewModel() = lazy { ViewModelProviders.of(this, viewModelFactory).get(V::class.java) } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoApplication.kt b/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoApplication.kt index abade181e9a0..6c134554303c 100644 --- a/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoApplication.kt +++ b/app/src/main/java/com/duckduckgo/app/global/DuckDuckGoApplication.kt @@ -31,6 +31,7 @@ import com.duckduckgo.app.fire.FireActivity import com.duckduckgo.app.global.install.AppInstallStore import com.duckduckgo.app.global.notification.NotificationRegistrar import com.duckduckgo.app.global.shortcut.AppShortcutCreator +import com.duckduckgo.app.httpsupgrade.HttpsUpgrader import com.duckduckgo.app.job.AppConfigurationSyncer import com.duckduckgo.app.migration.LegacyMigration import com.duckduckgo.app.statistics.api.StatisticsUpdater @@ -48,6 +49,7 @@ import io.reactivex.schedulers.Schedulers import org.jetbrains.anko.doAsync import timber.log.Timber import javax.inject.Inject +import kotlin.concurrent.thread open class DuckDuckGoApplication : HasActivityInjector, HasServiceInjector, HasSupportFragmentInjector, Application(), LifecycleObserver { @@ -87,6 +89,9 @@ open class DuckDuckGoApplication : HasActivityInjector, HasServiceInjector, HasS @Inject lateinit var appShortcutCreator: AppShortcutCreator + @Inject + lateinit var httpsUpgrader: HttpsUpgrader + override fun onCreate() { super.onCreate() @@ -110,6 +115,9 @@ open class DuckDuckGoApplication : HasActivityInjector, HasServiceInjector, HasS migrateLegacyDb() notificationRegistrar.registerApp() + + initializeHttpsUpgrader() + } private fun recordInstallationTimestamp() { @@ -164,6 +172,10 @@ open class DuckDuckGoApplication : HasActivityInjector, HasServiceInjector, HasS statisticsUpdater.initializeAtb() } + private fun initializeHttpsUpgrader() { + thread { httpsUpgrader.reloadData() } + } + /** * Immediately syncs data. Upon completion (successful or error), * it will schedule a recurring job to keep the data in sync. diff --git a/app/src/main/java/com/duckduckgo/app/global/ThreadExtension.kt b/app/src/main/java/com/duckduckgo/app/global/ThreadExtension.kt index 81bbefcac67a..d0f425b66169 100644 --- a/app/src/main/java/com/duckduckgo/app/global/ThreadExtension.kt +++ b/app/src/main/java/com/duckduckgo/app/global/ThreadExtension.kt @@ -19,6 +19,5 @@ package com.duckduckgo.app.global import android.os.Looper - fun Thread.isAndroidMainThread(): Boolean = - Thread.currentThread().id == Looper.getMainLooper().thread.id \ No newline at end of file + Thread.currentThread().id == Looper.getMainLooper().thread.id \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/global/ViewModelFactory.kt b/app/src/main/java/com/duckduckgo/app/global/ViewModelFactory.kt index 19811686d995..3257ea236c2f 100644 --- a/app/src/main/java/com/duckduckgo/app/global/ViewModelFactory.kt +++ b/app/src/main/java/com/duckduckgo/app/global/ViewModelFactory.kt @@ -23,7 +23,6 @@ import com.duckduckgo.app.bookmarks.db.BookmarksDao import com.duckduckgo.app.bookmarks.ui.BookmarksViewModel import com.duckduckgo.app.browser.* import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector -import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserNotification import com.duckduckgo.app.browser.favicon.FaviconDownloader import com.duckduckgo.app.browser.omnibar.QueryUrlConverter import com.duckduckgo.app.browser.session.WebViewSessionStorage @@ -65,7 +64,6 @@ class ViewModelFactory @Inject constructor( private val bookmarksDao: BookmarksDao, private val autoCompleteApi: AutoCompleteApi, private val appSettingsPreferencesStore: SettingsDataStore, - private val defaultBrowserNotification: DefaultBrowserNotification, private val webViewLongPressHandler: LongPressHandler, private val defaultBrowserDetector: DefaultBrowserDetector, private val variantManager: VariantManager, @@ -81,7 +79,7 @@ class ViewModelFactory @Inject constructor( with(modelClass) { when { isAssignableFrom(LaunchViewModel::class.java) -> LaunchViewModel(onboaringStore) - isAssignableFrom(OnboardingViewModel::class.java) -> OnboardingViewModel(onboaringStore, defaultBrowserDetector, variantManager) + isAssignableFrom(OnboardingViewModel::class.java) -> OnboardingViewModel(onboaringStore, defaultBrowserDetector) isAssignableFrom(BrowserViewModel::class.java) -> BrowserViewModel(tabRepository, queryUrlConverter) isAssignableFrom(BrowserTabViewModel::class.java) -> browserTabViewModel() isAssignableFrom(TabSwitcherViewModel::class.java) -> TabSwitcherViewModel(tabRepository, webViewSessionStorage) @@ -94,7 +92,11 @@ class ViewModelFactory @Inject constructor( isAssignableFrom(TrackerNetworksViewModel::class.java) -> TrackerNetworksViewModel() isAssignableFrom(PrivacyPracticesViewModel::class.java) -> PrivacyPracticesViewModel() isAssignableFrom(FeedbackViewModel::class.java) -> FeedbackViewModel(feedbackSender) - isAssignableFrom(SettingsViewModel::class.java) -> SettingsViewModel(appSettingsPreferencesStore, defaultBrowserDetector, variantManager) + isAssignableFrom(SettingsViewModel::class.java) -> SettingsViewModel( + appSettingsPreferencesStore, + defaultBrowserDetector, + variantManager + ) isAssignableFrom(BookmarksViewModel::class.java) -> BookmarksViewModel(bookmarksDao) isAssignableFrom(FireViewModel::class.java) -> FireViewModel() else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") @@ -110,12 +112,9 @@ class ViewModelFactory @Inject constructor( networkLeaderboardDao = networkLeaderboardDao, bookmarksDao = bookmarksDao, appSettingsPreferencesStore = appSettingsPreferencesStore, - defaultBrowserDetector = defaultBrowserDetector, - defaultBrowserNotification = defaultBrowserNotification, appConfigurationDao = appConfigurationDao, longPressHandler = webViewLongPressHandler, webViewSessionStorage = webViewSessionStorage, - variantManager = variantManager, autoCompleteApi = autoCompleteApi, specialUrlDetector = specialUrlDetector, faviconDownloader = faviconDownloader diff --git a/app/src/main/java/com/duckduckgo/app/global/db/AppConfigurationDao.kt b/app/src/main/java/com/duckduckgo/app/global/db/AppConfigurationDao.kt index 3e9ac68cf656..a364931ad5f5 100644 --- a/app/src/main/java/com/duckduckgo/app/global/db/AppConfigurationDao.kt +++ b/app/src/main/java/com/duckduckgo/app/global/db/AppConfigurationDao.kt @@ -43,7 +43,7 @@ interface AppConfigurationDao { @Entity(tableName = "app_configuration") data class AppConfigurationEntity( - @PrimaryKey val key: String = KEY, - val appConfigurationDownloaded: Boolean + @PrimaryKey val key: String = KEY, + val appConfigurationDownloaded: Boolean ) \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/global/db/AppDatabase.kt b/app/src/main/java/com/duckduckgo/app/global/db/AppDatabase.kt index e5388ada9523..fbb4ca1ccc33 100644 --- a/app/src/main/java/com/duckduckgo/app/global/db/AppDatabase.kt +++ b/app/src/main/java/com/duckduckgo/app/global/db/AppDatabase.kt @@ -35,17 +35,19 @@ import com.duckduckgo.app.tabs.model.TabSelectionEntity import com.duckduckgo.app.trackerdetection.db.TrackerDataDao import com.duckduckgo.app.trackerdetection.model.DisconnectTracker -@Database(exportSchema = true, version = 5, entities = [ - DisconnectTracker::class, - HttpsBloomFilterSpec::class, - HttpsWhitelistedDomain::class, - NetworkLeaderboardEntry::class, - SiteVisitedEntity::class, - AppConfigurationEntity::class, - TabEntity::class, - TabSelectionEntity::class, - BookmarkEntity::class -]) +@Database( + exportSchema = true, version = 5, entities = [ + DisconnectTracker::class, + HttpsBloomFilterSpec::class, + HttpsWhitelistedDomain::class, + NetworkLeaderboardEntry::class, + SiteVisitedEntity::class, + AppConfigurationEntity::class, + TabEntity::class, + TabSelectionEntity::class, + BookmarkEntity::class + ] +) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/com/duckduckgo/app/global/device/Device.kt b/app/src/main/java/com/duckduckgo/app/global/device/Device.kt index 1beae18f06b7..1eb8d7d60f9f 100644 --- a/app/src/main/java/com/duckduckgo/app/global/device/Device.kt +++ b/app/src/main/java/com/duckduckgo/app/global/device/Device.kt @@ -17,8 +17,8 @@ package com.duckduckgo.app.global.device import android.content.Context -import javax.inject.Inject import android.util.TypedValue +import javax.inject.Inject interface DeviceInfo { diff --git a/app/src/main/java/com/duckduckgo/app/global/install/AppInstallStore.kt b/app/src/main/java/com/duckduckgo/app/global/install/AppInstallStore.kt index bb4cda8d129b..2e49b44799ac 100644 --- a/app/src/main/java/com/duckduckgo/app/global/install/AppInstallStore.kt +++ b/app/src/main/java/com/duckduckgo/app/global/install/AppInstallStore.kt @@ -26,11 +26,7 @@ import javax.inject.Inject interface AppInstallStore { var installTimestamp: Long - fun hasInstallTimestampRecorded() : Boolean - fun recordUserDeclinedBannerToSetDefaultBrowser(timestamp: Long = System.currentTimeMillis()) - fun recordUserDeclinedHomeScreenCallToActionToSetDefaultBrowser(timestamp: Long = System.currentTimeMillis()) - fun hasUserDeclinedDefaultBrowserBannerPreviously(): Boolean - fun hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously(): Boolean + fun hasInstallTimestampRecorded(): Boolean } class AppInstallSharedPreferences @Inject constructor(private val context: Context) : AppInstallStore { @@ -40,35 +36,13 @@ class AppInstallSharedPreferences @Inject constructor(private val context: Conte override fun hasInstallTimestampRecorded(): Boolean = preferences.contains(KEY_TIMESTAMP_UTC) - override fun recordUserDeclinedBannerToSetDefaultBrowser(timestamp: Long) { - preferences.edit { - putLong(KEY_TIMESTAMP_USER_DECLINED_BANNER_DEFAULT_BROWSER, timestamp) - } - } - - override fun recordUserDeclinedHomeScreenCallToActionToSetDefaultBrowser(timestamp: Long) { - preferences.edit { - putLong(KEY_TIMESTAMP_USER_DECLINED_CALL_TO_ACTION_DEFAULT_BROWSER, timestamp) - } - } - - override fun hasUserDeclinedDefaultBrowserBannerPreviously(): Boolean { - return preferences.contains(KEY_TIMESTAMP_USER_DECLINED_BANNER_DEFAULT_BROWSER) - } - - override fun hasUserDeclinedDefaultBrowserHomeScreenCallToActionPreviously(): Boolean { - return preferences.contains(KEY_TIMESTAMP_USER_DECLINED_CALL_TO_ACTION_DEFAULT_BROWSER) - } - private val preferences: SharedPreferences - get() = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE) + get() = context.getSharedPreferences(FILENAME, Context.MODE_PRIVATE) - companion object { + companion object { - @VisibleForTesting - const val FILENAME = "com.duckduckgo.app.install.settings" - const val KEY_TIMESTAMP_UTC = "INSTALL_TIMESTAMP_UTC" - const val KEY_TIMESTAMP_USER_DECLINED_BANNER_DEFAULT_BROWSER = "USER_DECLINED_DEFAULT_BROWSER_TIMESTAMP_UTC" - const val KEY_TIMESTAMP_USER_DECLINED_CALL_TO_ACTION_DEFAULT_BROWSER = "USER_DECLINED_DEFAULT_BROWSER_CALL_TO_ACTION_TIMESTAMP_UTC" - } + @VisibleForTesting + const val FILENAME = "com.duckduckgo.app.install.settings" + const val KEY_TIMESTAMP_UTC = "INSTALL_TIMESTAMP_UTC" + } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/global/job/JobBuilder.kt b/app/src/main/java/com/duckduckgo/app/global/job/JobBuilder.kt index f9326a9a5659..5f8af561efff 100644 --- a/app/src/main/java/com/duckduckgo/app/global/job/JobBuilder.kt +++ b/app/src/main/java/com/duckduckgo/app/global/job/JobBuilder.kt @@ -26,15 +26,15 @@ import javax.inject.Inject const val APP_CONFIGURATION_JOB_ID = 1 -class JobBuilder @Inject constructor(){ +class JobBuilder @Inject constructor() { fun appConfigurationJob(context: Context): JobInfo { return JobInfo.Builder(APP_CONFIGURATION_JOB_ID, ComponentName(context, AppConfigurationJobService::class.java)) - .setPeriodic(TimeUnit.HOURS.toMillis(3)) - .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) - .setBackoffCriteria(TimeUnit.MINUTES.toMillis(30), BACKOFF_POLICY_EXPONENTIAL) - .setPersisted(true) - .build() + .setPeriodic(TimeUnit.HOURS.toMillis(3)) + .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) + .setBackoffCriteria(TimeUnit.MINUTES.toMillis(30), BACKOFF_POLICY_EXPONENTIAL) + .setPersisted(true) + .build() } } diff --git a/app/src/main/java/com/duckduckgo/app/global/model/SiteMonitor.kt b/app/src/main/java/com/duckduckgo/app/global/model/SiteMonitor.kt index dc231b689041..23c7753fc4ad 100644 --- a/app/src/main/java/com/duckduckgo/app/global/model/SiteMonitor.kt +++ b/app/src/main/java/com/duckduckgo/app/global/model/SiteMonitor.kt @@ -26,9 +26,11 @@ import com.duckduckgo.app.trackerdetection.model.TrackerNetwork import com.duckduckgo.app.trackerdetection.model.TrackingEvent import java.util.concurrent.CopyOnWriteArrayList -class SiteMonitor(override val url: String, - override val termsOfService: TermsOfService, - override val memberNetwork: TrackerNetwork? = null) : Site { +class SiteMonitor( + override val url: String, + override val termsOfService: TermsOfService, + override val memberNetwork: TrackerNetwork? = null +) : Site { override val uri: Uri? get() = Uri.parse(url) @@ -61,7 +63,7 @@ class SiteMonitor(override val url: String, get() = distinctTrackersByNetwork.count() override val majorNetworkCount: Int - get() = trackingEvents.distinctBy { it.trackerNetwork?.url }.count { it.trackerNetwork?.isMajor ?: false} + get() = trackingEvents.distinctBy { it.trackerNetwork?.url }.count { it.trackerNetwork?.isMajor ?: false } override val hasTrackerFromMajorNetwork: Boolean get() = trackingEvents.any { it.trackerNetwork?.isMajor ?: false } diff --git a/app/src/main/java/com/duckduckgo/app/global/notification/NotificationRegistrar.kt b/app/src/main/java/com/duckduckgo/app/global/notification/NotificationRegistrar.kt index c6d5605f477f..9c538841b242 100644 --- a/app/src/main/java/com/duckduckgo/app/global/notification/NotificationRegistrar.kt +++ b/app/src/main/java/com/duckduckgo/app/global/notification/NotificationRegistrar.kt @@ -42,10 +42,12 @@ class NotificationRegistrar @Inject constructor(private val notificationManager: // downloaded notification val fileDownloadedChannel = NotificationChannel(FILE_DOWNLOADED_CHANNEL_ID, FILE_DOWNLOAD_CHANNEL_NAME, importance) - notificationManager.createNotificationChannels(listOf( + notificationManager.createNotificationChannels( + listOf( fileDownloadedChannel, fileDownloadingChannel - )) + ) + ) } companion object { diff --git a/app/src/main/java/com/duckduckgo/app/global/view/ActivityExtension.kt b/app/src/main/java/com/duckduckgo/app/global/view/ActivityExtension.kt index 040572199ed6..3937bff583b2 100644 --- a/app/src/main/java/com/duckduckgo/app/global/view/ActivityExtension.kt +++ b/app/src/main/java/com/duckduckgo/app/global/view/ActivityExtension.kt @@ -42,8 +42,7 @@ fun Context.launchDefaultAppActivity() { try { val intent = Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS) startActivity(intent) - } - catch (e: ActivityNotFoundException) { + } catch (e: ActivityNotFoundException) { val errorMessage = getString(R.string.cannotLaunchDefaultAppSettings) Timber.w(e, errorMessage) Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show() @@ -53,9 +52,9 @@ fun Context.launchDefaultAppActivity() { fun FragmentActivity.toggleFullScreen() { val newUiOptions = window.decorView.systemUiVisibility - .xor(android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) - .xor(android.view.View.SYSTEM_UI_FLAG_FULLSCREEN) - .xor(android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) + .xor(android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) + .xor(android.view.View.SYSTEM_UI_FLAG_FULLSCREEN) + .xor(android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) window.decorView.systemUiVisibility = newUiOptions } diff --git a/app/src/main/java/com/duckduckgo/app/httpsupgrade/HttpsUpgrader.kt b/app/src/main/java/com/duckduckgo/app/httpsupgrade/HttpsUpgrader.kt index 9dd3375eb941..02ba42c853b6 100644 --- a/app/src/main/java/com/duckduckgo/app/httpsupgrade/HttpsUpgrader.kt +++ b/app/src/main/java/com/duckduckgo/app/httpsupgrade/HttpsUpgrader.kt @@ -24,7 +24,6 @@ import com.duckduckgo.app.httpsupgrade.api.HttpsBloomFilterFactory import com.duckduckgo.app.httpsupgrade.db.HttpsWhitelistDao import timber.log.Timber import java.util.concurrent.locks.ReentrantLock -import kotlin.concurrent.thread interface HttpsUpgrader { @@ -35,6 +34,7 @@ interface HttpsUpgrader { return uri.buildUpon().scheme(UrlScheme.https).build() } + @WorkerThread fun reloadData() } @@ -46,12 +46,6 @@ class HttpsUpgraderImpl( private var httpsBloomFilter: BloomFilter? = null private val dataReloadLock = ReentrantLock() - init { - thread { - reloadData() - } - } - @WorkerThread override fun shouldUpgrade(uri: Uri): Boolean { @@ -72,7 +66,7 @@ class HttpsUpgraderImpl( val initialTime = System.nanoTime() val shouldUpgrade = it.contains(host) val totalTime = System.nanoTime() - initialTime - Timber.d("${host} ${if (shouldUpgrade) "is" else "is not"} upgradable, lookup in ${totalTime/NANO_TO_MILLIS_DIVISOR}ms") + Timber.d("${host} ${if (shouldUpgrade) "is" else "is not"} upgradable, lookup in ${totalTime / NANO_TO_MILLIS_DIVISOR}ms") return shouldUpgrade } diff --git a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationDownloader.kt b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationDownloader.kt index 80f5cf2acf42..eaee635cb41a 100644 --- a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationDownloader.kt @@ -30,10 +30,11 @@ interface ConfigurationDownloader { } class AppConfigurationDownloader( - private val trackerDataDownloader: TrackerDataDownloader, - private val httpsUpgradeDataDownloader: HttpsUpgradeDataDownloader, - private val resourceSurrogateDownloader: ResourceSurrogateListDownloader, - private val appDatabase: AppDatabase) : ConfigurationDownloader { + private val trackerDataDownloader: TrackerDataDownloader, + private val httpsUpgradeDataDownloader: HttpsUpgradeDataDownloader, + private val resourceSurrogateDownloader: ResourceSurrogateListDownloader, + private val appDatabase: AppDatabase +) : ConfigurationDownloader { override fun downloadTask(): Completable { val easyListDownload = trackerDataDownloader.downloadList(EASYLIST) @@ -43,14 +44,16 @@ class AppConfigurationDownloader( val surrogatesDownload = resourceSurrogateDownloader.downloadList() val httpsUpgradeDownload = httpsUpgradeDataDownloader.download() - return Completable.mergeDelayError(listOf( + return Completable.mergeDelayError( + listOf( easyListDownload, easyPrivacyDownload, trackersWhitelist, disconnectDownload, surrogatesDownload, httpsUpgradeDownload - )).doOnComplete { + ) + ).doOnComplete { Timber.i("Download task completed successfully") val appConfiguration = AppConfigurationEntity(appConfigurationDownloaded = true) appDatabase.appConfigurationDao().configurationDownloadSuccessful(appConfiguration) diff --git a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationJobService.kt b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationJobService.kt index d1a0d69cefb2..2138fb9ebe74 100644 --- a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationJobService.kt +++ b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationJobService.kt @@ -40,7 +40,7 @@ class AppConfigurationJobService : JobService() { override fun onStartJob(params: JobParameters?): Boolean { Timber.i("onStartJob") - downloadTask= appConfigurationDownloader.downloadTask() + downloadTask = appConfigurationDownloader.downloadTask() .subscribeOn(Schedulers.io()) .subscribe({ Timber.i("Successfully downloaded all data") diff --git a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationSyncer.kt b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationSyncer.kt index 4f93f9c5656a..2db03ba4f73f 100644 --- a/app/src/main/java/com/duckduckgo/app/job/AppConfigurationSyncer.kt +++ b/app/src/main/java/com/duckduckgo/app/job/AppConfigurationSyncer.kt @@ -25,9 +25,10 @@ import io.reactivex.Completable import timber.log.Timber class AppConfigurationSyncer( - private val jobBuilder: JobBuilder, - private val jobScheduler: JobScheduler, - private val appConfigurationDownloader: ConfigurationDownloader) { + private val jobBuilder: JobBuilder, + private val jobScheduler: JobScheduler, + private val appConfigurationDownloader: ConfigurationDownloader +) { @CheckResult fun scheduleImmediateSync(): Completable { @@ -42,8 +43,8 @@ class AppConfigurationSyncer( */ fun jobScheduled(): Boolean { return jobScheduler.allPendingJobs - .filter { APP_CONFIGURATION_JOB_ID == it.id } - .count() > 0 + .filter { APP_CONFIGURATION_JOB_ID == it.id } + .count() > 0 } fun scheduleRegularSync(context: Context) { diff --git a/app/src/main/java/com/duckduckgo/app/launch/LaunchActivity.kt b/app/src/main/java/com/duckduckgo/app/launch/LaunchActivity.kt index 72e9bb3aefc1..21dcc9e537e6 100644 --- a/app/src/main/java/com/duckduckgo/app/launch/LaunchActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/launch/LaunchActivity.kt @@ -17,24 +17,16 @@ package com.duckduckgo.app.launch import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.os.Bundle import com.duckduckgo.app.browser.BrowserActivity import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.onboarding.ui.OnboardingActivity -import javax.inject.Inject class LaunchActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: LaunchViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(LaunchViewModel::class.java) - } + private val viewModel: LaunchViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/migration/LegacyMigration.kt b/app/src/main/java/com/duckduckgo/app/migration/LegacyMigration.kt index 169882c84e4b..594448cd3d74 100644 --- a/app/src/main/java/com/duckduckgo/app/migration/LegacyMigration.kt +++ b/app/src/main/java/com/duckduckgo/app/migration/LegacyMigration.kt @@ -28,10 +28,11 @@ import timber.log.Timber import javax.inject.Inject class LegacyMigration @Inject constructor( - val database: AppDatabase, - val bookmarksDao: BookmarksDao, - val context: Context, - val queryUrlConverter: QueryUrlConverter) { + val database: AppDatabase, + val bookmarksDao: BookmarksDao, + val context: Context, + val queryUrlConverter: QueryUrlConverter +) { @WorkerThread fun start(completion: (favourites: Int, searches: Int) -> Unit) { @@ -42,7 +43,7 @@ class LegacyMigration @Inject constructor( } - private fun migrate(legacyDb:LegacyDb, completion: (favourites: Int, searches: Int) -> Unit) { + private fun migrate(legacyDb: LegacyDb, completion: (favourites: Int, searches: Int) -> Unit) { var favourites = 0 var searches = 0 @@ -85,7 +86,7 @@ class LegacyMigration @Inject constructor( return count } - private fun migrateFavourites(db: LegacyDb) : Int { + private fun migrateFavourites(db: LegacyDb): Int { val feedObjects = db.selectAll() ?: return 0 var count = 0 diff --git a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyDb.java b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyDb.java index 285ea7ebf650..67d2afb13db5 100644 --- a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyDb.java +++ b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyDb.java @@ -97,6 +97,14 @@ public boolean isSaved(String id) { return out; } + public void close() { + db.close(); + } + + public SQLiteDatabase getSQLiteDB() { + return db; + } + private static class OpenHelper extends SQLiteOpenHelper { private final Context appContext; @@ -302,12 +310,4 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } - public void close() { - db.close(); - } - - public SQLiteDatabase getSQLiteDB() { - return db; - } - } diff --git a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyFeedObject.java b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyFeedObject.java index 7bdb4736badd..2307cf022630 100644 --- a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyFeedObject.java +++ b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyFeedObject.java @@ -18,112 +18,112 @@ public class LegacyFeedObject { - private final String feed; - private final String favicon; - private final String description; - private final String timestamp; - private final String url; - private final String title; - private final String id; - private final String category; - private final String imageUrl; - private final String type; - private final String articleUrl; - private final String html; - private final String hidden; - - - public LegacyFeedObject(String id, String title, String description, String feed, String url, String imageUrl, - String favicon, String timestamp, String category, String type, String articleUrl, String html, String hidden) { - this.id = id; - this.title = title; - this.description = description; - this.feed = feed; - this.url = url; - this.imageUrl = imageUrl; - this.favicon = favicon; - this.timestamp = timestamp; - this.category = category; - this.type = type; - this.articleUrl = articleUrl; - this.html = html; - this.hidden = hidden; - } - - @Override - public String toString() { - String string = "{"; - - string = string.concat("feed:" + this.feed + "\n"); - string = string.concat("favicon:" + this.favicon + "\n"); - string = string.concat("description:" + this.description + "\n"); - string = string.concat("timestamp:" + this.timestamp + "\n"); - string = string.concat("url:" + this.url + "\n"); - string = string.concat("title:" + this.title + "\n"); - string = string.concat("id:" + this.id + "\n"); - string = string.concat("category:" + this.category + "\n"); - string = string.concat("image: " + this.imageUrl + "\n"); - string = string.concat("type: " + this.type + "\n"); - string = string.concat("article_url:" + this.articleUrl + "\n"); - string = string.concat("html:" + this.html + "\n"); - string = string.concat("hidden: " + this.hidden + "}"); - - return string; - } - - public String getFeed() { - return feed; - } - - public String getFavicon() { - return favicon; - } - - public String getTimestamp() { - return timestamp; - } - - public String getDescription() { - return description; - } - - public String getUrl() { - return url; - } - - public String getTitle() { - return title; - } - - public String getId() { - return id; - } - - public String getCategory() { - return category; - } - - public String getImageUrl() { - return imageUrl; - } - - public String getType() { - return type; - } - - public String getHtml() { - return html; - } - - public String getArticleUrl() { - return articleUrl; - } - - public String getHidden() { - return hidden; - } - - public boolean hasPossibleReadability() { - return getArticleUrl().length() != 0; - } + private final String feed; + private final String favicon; + private final String description; + private final String timestamp; + private final String url; + private final String title; + private final String id; + private final String category; + private final String imageUrl; + private final String type; + private final String articleUrl; + private final String html; + private final String hidden; + + + public LegacyFeedObject(String id, String title, String description, String feed, String url, String imageUrl, + String favicon, String timestamp, String category, String type, String articleUrl, String html, String hidden) { + this.id = id; + this.title = title; + this.description = description; + this.feed = feed; + this.url = url; + this.imageUrl = imageUrl; + this.favicon = favicon; + this.timestamp = timestamp; + this.category = category; + this.type = type; + this.articleUrl = articleUrl; + this.html = html; + this.hidden = hidden; + } + + @Override + public String toString() { + String string = "{"; + + string = string.concat("feed:" + this.feed + "\n"); + string = string.concat("favicon:" + this.favicon + "\n"); + string = string.concat("description:" + this.description + "\n"); + string = string.concat("timestamp:" + this.timestamp + "\n"); + string = string.concat("url:" + this.url + "\n"); + string = string.concat("title:" + this.title + "\n"); + string = string.concat("id:" + this.id + "\n"); + string = string.concat("category:" + this.category + "\n"); + string = string.concat("image: " + this.imageUrl + "\n"); + string = string.concat("type: " + this.type + "\n"); + string = string.concat("article_url:" + this.articleUrl + "\n"); + string = string.concat("html:" + this.html + "\n"); + string = string.concat("hidden: " + this.hidden + "}"); + + return string; + } + + public String getFeed() { + return feed; + } + + public String getFavicon() { + return favicon; + } + + public String getTimestamp() { + return timestamp; + } + + public String getDescription() { + return description; + } + + public String getUrl() { + return url; + } + + public String getTitle() { + return title; + } + + public String getId() { + return id; + } + + public String getCategory() { + return category; + } + + public String getImageUrl() { + return imageUrl; + } + + public String getType() { + return type; + } + + public String getHtml() { + return html; + } + + public String getArticleUrl() { + return articleUrl; + } + + public String getHidden() { + return hidden; + } + + public boolean hasPossibleReadability() { + return getArticleUrl().length() != 0; + } } diff --git a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyUtils.java b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyUtils.java index 3380272da6fc..a4a19dbe038c 100644 --- a/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyUtils.java +++ b/app/src/main/java/com/duckduckgo/app/migration/legacy/LegacyUtils.java @@ -16,10 +16,11 @@ package com.duckduckgo.app.migration.legacy; -import java.util.LinkedList; import android.content.SharedPreferences; import android.net.Uri; +import java.util.LinkedList; + /** * This class contains utility static methods, such as loading preferences as an array or decoding bitmaps. */ @@ -28,7 +29,7 @@ public final class LegacyUtils { public static LinkedList loadList(SharedPreferences prefs, String listName) { int size = prefs.getInt(listName + "_size", 0); LinkedList list = new LinkedList(); - for(int i=0;i loadList(SharedPreferences prefs, String listNa * @return */ static public String getQueryIfSerp(String url) { - if(!isSerpUrl(url)) { + if (!isSerpUrl(url)) { return null; } Uri uri = Uri.parse(url); String query = uri.getQueryParameter("q"); - if(query != null) + if (query != null) return query; String lastPath = uri.getLastPathSegment(); - if(lastPath == null) + if (lastPath == null) return null; - if(!lastPath.contains(".html")) { + if (!lastPath.contains(".html")) { return lastPath.replace("_", " "); } diff --git a/app/src/main/java/com/duckduckgo/app/migration/legacy/package-info.java b/app/src/main/java/com/duckduckgo/app/migration/legacy/package-info.java index ea7a10c9741b..950998361d84 100644 --- a/app/src/main/java/com/duckduckgo/app/migration/legacy/package-info.java +++ b/app/src/main/java/com/duckduckgo/app/migration/legacy/package-info.java @@ -16,11 +16,9 @@ /** - * @deprecated - * - * DO NOT USE THE CODE IN THIS PACKAGE. - * + * @deprecated DO NOT USE THE CODE IN THIS PACKAGE. + *

* The code in this package is derived from the Search and Stories application for the purpose of - * migration. + * migration. */ package com.duckduckgo.app.migration.legacy; diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/store/OnboardingSharedPreferences.kt b/app/src/main/java/com/duckduckgo/app/onboarding/store/OnboardingSharedPreferences.kt index 6ac40c12902c..fc824bf5ddaf 100644 --- a/app/src/main/java/com/duckduckgo/app/onboarding/store/OnboardingSharedPreferences.kt +++ b/app/src/main/java/com/duckduckgo/app/onboarding/store/OnboardingSharedPreferences.kt @@ -41,5 +41,5 @@ class OnboardingSharedPreferences @Inject constructor(private val context: Conte const val KEY_VERSION = "com.duckduckgo.app.onboarding.currentVersion" const val CURRENT_VERSION = 1 } - + } diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingActivity.kt b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingActivity.kt index 11ed807f7264..511ea2c8b35c 100644 --- a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingActivity.kt @@ -16,7 +16,6 @@ package com.duckduckgo.app.onboarding.ui -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Build @@ -27,7 +26,6 @@ import android.support.v4.content.ContextCompat import android.view.View import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.view.ColorCombiner import com.duckduckgo.app.global.view.launchDefaultAppActivity import com.duckduckgo.app.onboarding.ui.ColorChangingPageListener.NewColorListener @@ -37,17 +35,12 @@ import javax.inject.Inject class OnboardingActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var colorCombiner: ColorCombiner private lateinit var viewPageAdapter: PagerAdapter - private val viewModel: OnboardingViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(OnboardingViewModel::class.java) - } + private val viewModel: OnboardingViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt index 945d98d56dab..96a310126598 100644 --- a/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/onboarding/ui/OnboardingViewModel.kt @@ -19,13 +19,10 @@ package com.duckduckgo.app.onboarding.ui import android.arch.lifecycle.ViewModel import com.duckduckgo.app.browser.defaultBrowsing.DefaultBrowserDetector import com.duckduckgo.app.onboarding.store.OnboardingStore -import com.duckduckgo.app.statistics.VariantManager -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature class OnboardingViewModel( private val onboardingStore: OnboardingStore, - private val defaultWebBrowserCapability: DefaultBrowserDetector, - private val variantManager: VariantManager + private val defaultWebBrowserCapability: DefaultBrowserDetector ) : ViewModel() { fun pageCount(): Int { @@ -50,10 +47,6 @@ class OnboardingViewModel( } private fun shouldShowDefaultBrowserPage(): Boolean { - val deviceSupported = - defaultWebBrowserCapability.deviceSupportsDefaultBrowserConfiguration() - val featureEnabled = variantManager.getVariant().hasFeature(DefaultBrowserFeature.ShowInOnboarding) - - return deviceSupported && featureEnabled + return defaultWebBrowserCapability.deviceSupportsDefaultBrowserConfiguration() } } diff --git a/app/src/main/java/com/duckduckgo/app/privacy/api/TermsOfServiceJson.kt b/app/src/main/java/com/duckduckgo/app/privacy/api/TermsOfServiceJson.kt index 2da967cb0f6e..a03630ff4678 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/api/TermsOfServiceJson.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/api/TermsOfServiceJson.kt @@ -18,10 +18,12 @@ package com.duckduckgo.app.privacy.api import com.squareup.moshi.Json -data class TermsOfServiceJson(val score: Int, - @field:Json(name = "class") - val classification: Any, - val match: Match) { +data class TermsOfServiceJson( + val score: Int, + @field:Json(name = "class") + val classification: Any, + val match: Match +) { data class Match(val good: List, val bad: List) } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/privacy/db/NetworkLeaderboardEntry.kt b/app/src/main/java/com/duckduckgo/app/privacy/db/NetworkLeaderboardEntry.kt index f57c855aaaef..3cc216768612 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/db/NetworkLeaderboardEntry.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/db/NetworkLeaderboardEntry.kt @@ -18,8 +18,11 @@ package com.duckduckgo.app.privacy.db import android.arch.persistence.room.Entity -@Entity(tableName = "network_leaderboard", - primaryKeys = ["networkName", "domainVisited"]) +@Entity( + tableName = "network_leaderboard", + primaryKeys = ["networkName", "domainVisited"] +) data class NetworkLeaderboardEntry( - val networkName: String, - val domainVisited: String) + val networkName: String, + val domainVisited: String +) diff --git a/app/src/main/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtension.kt b/app/src/main/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtension.kt index 3f05e5554888..c837ebe17f7c 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtension.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/model/SitePrivacyGradeExtension.kt @@ -33,7 +33,8 @@ val Site.score: Int if (score == 0 && termsOfService.classification != "A") { score = 1 } - Timber.v("""Calculating score { + Timber.v( + """Calculating score { memberMajorNetworkPercentage: ${memberNetwork?.percentageOfPages} https: $https termsScore: ${termsOfService.gradingScore} @@ -41,7 +42,8 @@ val Site.score: Int hasTrackerFromMajorNetwork: $hasTrackerFromMajorNetwork hasObscureTracker: $hasObscureTracker score: $score - """) + """ + ) return score } diff --git a/app/src/main/java/com/duckduckgo/app/privacy/model/TermsOfService.kt b/app/src/main/java/com/duckduckgo/app/privacy/model/TermsOfService.kt index 9f4173ebb86a..d8335a11c4b0 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/model/TermsOfService.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/model/TermsOfService.kt @@ -16,11 +16,13 @@ package com.duckduckgo.app.privacy.model -data class TermsOfService(val name: String? = null, - val score: Int = 0, - val classification: String? = null, - val goodPrivacyTerms: List = ArrayList(), - val badPrivacyTerms: List = ArrayList()) { +data class TermsOfService( + val name: String? = null, + val score: Int = 0, + val classification: String? = null, + val goodPrivacyTerms: List = ArrayList(), + val badPrivacyTerms: List = ArrayList() +) { enum class Practices { POOR, diff --git a/app/src/main/java/com/duckduckgo/app/privacy/model/TrustedSites.kt b/app/src/main/java/com/duckduckgo/app/privacy/model/TrustedSites.kt index bd75d2dc1c7b..17878d707bf5 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/model/TrustedSites.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/model/TrustedSites.kt @@ -24,13 +24,13 @@ class TrustedSites { companion object { private val trusted = listOf( - AppUrl.Url.HOST, - "duckduckgo.com", - "donttrack.us", - "spreadprivacy.com", - "duckduckhack.com", - "privatebrowsingmyths.com", - "duck.co" + AppUrl.Url.HOST, + "duckduckgo.com", + "donttrack.us", + "spreadprivacy.com", + "duckduckhack.com", + "privatebrowsingmyths.com", + "duck.co" ) fun isTrusted(url: String): Boolean { diff --git a/app/src/main/java/com/duckduckgo/app/privacy/renderer/TrackersRenderer.kt b/app/src/main/java/com/duckduckgo/app/privacy/renderer/TrackersRenderer.kt index 3837b8adcef0..82d9e95bc9a1 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/renderer/TrackersRenderer.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/renderer/TrackersRenderer.kt @@ -61,9 +61,9 @@ class TrackersRenderer { private fun networkIcon(context: Context, networkName: String, prefix: String): Int? { val drawable = "$prefix$networkName" - .replace(" ", "") - .replace(".", "") - .toLowerCase() + .replace(" ", "") + .replace(".", "") + .toLowerCase() val resource = context.resources.getIdentifier(drawable, "drawable", context.packageName) return if (resource != 0) resource else null } @@ -79,5 +79,5 @@ class TrackersRenderer { 0 -> R.drawable.icon_success else -> R.drawable.icon_fail } - + } diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardActivity.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardActivity.kt index e1002e286aff..2ceba4d4ceed 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardActivity.kt @@ -18,7 +18,6 @@ package com.duckduckgo.app.privacy.ui import android.app.Activity import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -26,7 +25,6 @@ import android.support.v4.content.ContextCompat import android.view.View import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.model.Site import com.duckduckgo.app.global.view.hide import com.duckduckgo.app.global.view.html @@ -44,8 +42,6 @@ import javax.inject.Inject class PrivacyDashboardActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory @Inject lateinit var repository: TabRepository @Inject @@ -54,9 +50,7 @@ class PrivacyDashboardActivity : DuckDuckGoActivity() { private val trackersRenderer = TrackersRenderer() private val upgradeRenderer = PrivacyUpgradeRenderer() - private val viewModel: PrivacyDashboardViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(PrivacyDashboardViewModel::class.java) - } + private val viewModel: PrivacyDashboardViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModel.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModel.kt index 38ddee5e29b7..df225c944b39 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyDashboardViewModel.kt @@ -27,7 +27,7 @@ import com.duckduckgo.app.privacy.db.NetworkLeaderboardDao.NetworkTally import com.duckduckgo.app.privacy.model.* import com.duckduckgo.app.privacy.store.PrivacySettingsStore import com.duckduckgo.app.statistics.pixels.Pixel -import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.* +import com.duckduckgo.app.statistics.pixels.Pixel.PixelName.PRIVACY_DASHBOARD_OPENED class PrivacyDashboardViewModel( private val settingsStore: PrivacySettingsStore, diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesActivity.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesActivity.kt index fccb298614c8..58f78a580cb3 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.privacy.ui import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -27,7 +26,6 @@ import com.duckduckgo.app.browser.BrowserActivity import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.AppUrl.Url import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.model.Site import com.duckduckgo.app.privacy.renderer.banner import com.duckduckgo.app.privacy.renderer.text @@ -39,17 +37,12 @@ import javax.inject.Inject class PrivacyPracticesActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var repository: TabRepository private val practicesAdapter = PrivacyPracticesAdapter() - private val viewModel: PrivacyPracticesViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(PrivacyPracticesViewModel::class.java) - } + private val viewModel: PrivacyPracticesViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesAdapter.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesAdapter.kt index 92be618ca4cb..657e7f7a80b4 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/PrivacyPracticesAdapter.kt @@ -57,9 +57,11 @@ class PrivacyPracticesAdapter : RecyclerView.Adapter, - val badTerms: List + val domain: String, + val practices: TermsOfService.Practices, + val goodTerms: List, + val badTerms: List ) val viewState: MutableLiveData = MutableLiveData() @@ -38,10 +38,10 @@ class PrivacyPracticesViewModel : ViewModel() { private fun resetViewState() { viewState.value = ViewState( - domain = "", - practices = TermsOfService.Practices.UNKNOWN, - goodTerms = ArrayList(), - badTerms = ArrayList() + domain = "", + practices = TermsOfService.Practices.UNKNOWN, + goodTerms = ArrayList(), + badTerms = ArrayList() ) } @@ -51,10 +51,10 @@ class PrivacyPracticesViewModel : ViewModel() { return } viewState.value = viewState.value?.copy( - domain = site.uri?.host ?: "", - practices = site.termsOfService.practices, - goodTerms = site.termsOfService.goodPrivacyTerms, - badTerms = site.termsOfService.badPrivacyTerms + domain = site.uri?.host ?: "", + practices = site.termsOfService.practices, + goodTerms = site.termsOfService.goodPrivacyTerms, + badTerms = site.termsOfService.badPrivacyTerms ) } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardActivity.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardActivity.kt index bdf5718245ce..606cb89de1ec 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.privacy.ui import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -26,9 +25,8 @@ import android.view.View import android.widget.TextView import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory -import com.duckduckgo.app.global.view.html import com.duckduckgo.app.global.model.Site +import com.duckduckgo.app.global.view.html import com.duckduckgo.app.privacy.renderer.* import com.duckduckgo.app.tabs.model.TabRepository import com.duckduckgo.app.tabs.tabId @@ -39,14 +37,12 @@ import javax.inject.Inject class ScorecardActivity : DuckDuckGoActivity() { - @Inject lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var repository: TabRepository + @Inject + lateinit var repository: TabRepository private val trackersRenderer = TrackersRenderer() private val upgradeRenderer = PrivacyUpgradeRenderer() - private val viewModel: ScorecardViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(ScorecardViewModel::class.java) - } + private val viewModel: ScorecardViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardViewModel.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardViewModel.kt index 7e7ca9597d2e..42d280845bea 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/ScorecardViewModel.kt @@ -25,17 +25,17 @@ import com.duckduckgo.app.privacy.store.PrivacySettingsStore class ScorecardViewModel(private val settingsStore: PrivacySettingsStore) : ViewModel() { data class ViewState( - val domain: String, - val beforeGrade: PrivacyGrade, - val afterGrade: PrivacyGrade, - val httpsStatus: HttpsStatus, - val trackerCount: Int, - val majorNetworkCount: Int, - val allTrackersBlocked: Boolean, - val practices: TermsOfService.Practices, - val privacyOn: Boolean, - val showIsMemberOfMajorNetwork: Boolean, - val showEnhancedGrade: Boolean + val domain: String, + val beforeGrade: PrivacyGrade, + val afterGrade: PrivacyGrade, + val httpsStatus: HttpsStatus, + val trackerCount: Int, + val majorNetworkCount: Int, + val allTrackersBlocked: Boolean, + val practices: TermsOfService.Practices, + val privacyOn: Boolean, + val showIsMemberOfMajorNetwork: Boolean, + val showEnhancedGrade: Boolean ) val viewState: MutableLiveData = MutableLiveData() @@ -56,32 +56,32 @@ class ScorecardViewModel(private val settingsStore: PrivacySettingsStore) : View private fun resetViewState() { viewState.value = ViewState( - domain = "", - beforeGrade = PrivacyGrade.UNKNOWN, - afterGrade = PrivacyGrade.UNKNOWN, - httpsStatus = HttpsStatus.SECURE, - trackerCount = 0, - majorNetworkCount = 0, - allTrackersBlocked = true, - practices = TermsOfService.Practices.UNKNOWN, - privacyOn = settingsStore.privacyOn, - showIsMemberOfMajorNetwork = false, - showEnhancedGrade = false + domain = "", + beforeGrade = PrivacyGrade.UNKNOWN, + afterGrade = PrivacyGrade.UNKNOWN, + httpsStatus = HttpsStatus.SECURE, + trackerCount = 0, + majorNetworkCount = 0, + allTrackersBlocked = true, + practices = TermsOfService.Practices.UNKNOWN, + privacyOn = settingsStore.privacyOn, + showIsMemberOfMajorNetwork = false, + showEnhancedGrade = false ) } private fun updateSite(site: Site) { viewState.value = viewState.value?.copy( - domain = site.uri?.host ?: "", - beforeGrade = site.grade, - afterGrade = site.improvedGrade, - trackerCount = site.trackerCount, - majorNetworkCount = site.majorNetworkCount, - httpsStatus = site.https, - allTrackersBlocked = site.allTrackersBlocked, - practices = site.termsOfService.practices, - showIsMemberOfMajorNetwork = site.memberNetwork?.isMajor ?: false, - showEnhancedGrade = site.grade != site.improvedGrade + domain = site.uri?.host ?: "", + beforeGrade = site.grade, + afterGrade = site.improvedGrade, + trackerCount = site.trackerCount, + majorNetworkCount = site.majorNetworkCount, + httpsStatus = site.https, + allTrackersBlocked = site.allTrackersBlocked, + practices = site.termsOfService.practices, + showIsMemberOfMajorNetwork = site.memberNetwork?.isMajor ?: false, + showEnhancedGrade = site.grade != site.improvedGrade ) } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksActivity.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksActivity.kt index a31b25a1c323..ee42e853c9f1 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksActivity.kt @@ -17,14 +17,12 @@ package com.duckduckgo.app.privacy.ui import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle import android.support.v7.widget.LinearLayoutManager import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.model.Site import com.duckduckgo.app.privacy.renderer.TrackersRenderer import com.duckduckgo.app.tabs.model.TabRepository @@ -35,14 +33,12 @@ import javax.inject.Inject class TrackerNetworksActivity : DuckDuckGoActivity() { - @Inject lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var repository: TabRepository + @Inject + lateinit var repository: TabRepository private val trackersRenderer = TrackersRenderer() private val networksAdapter = TrackerNetworksAdapter() - private val viewModel: TrackerNetworksViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(TrackerNetworksViewModel::class.java) - } + private val viewModel: TrackerNetworksViewModel by bindViewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksAdapter.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksAdapter.kt index 90ad2ae34654..605749044ec8 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksAdapter.kt @@ -44,13 +44,17 @@ class TrackerNetworksAdapter : RecyclerView.Adapter() { data class Header(val networkName: String) : ViewData data class Row(val tracker: TrackingEvent) : ViewData - class HeaderViewHolder(val root: View, - val network: TextView, - val icon: ImageView) : RecyclerView.ViewHolder(root) - - class RowViewHolder(val root: View, - val host: TextView, - val category: TextView) : RecyclerView.ViewHolder(root) + class HeaderViewHolder( + val root: View, + val network: TextView, + val icon: ImageView + ) : RecyclerView.ViewHolder(root) + + class RowViewHolder( + val root: View, + val host: TextView, + val category: TextView + ) : RecyclerView.ViewHolder(root) private var viewData: List = ArrayList() private var networkRenderer: TrackersRenderer = TrackersRenderer() diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksViewModel.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksViewModel.kt index 19792c151768..965529065e24 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/TrackerNetworksViewModel.kt @@ -24,10 +24,10 @@ import com.duckduckgo.app.trackerdetection.model.TrackingEvent class TrackerNetworksViewModel : ViewModel() { data class ViewState( - val domain: String, - val allTrackersBlocked: Boolean, - val networkCount: Int, - val trackingEventsByNetwork: Map> + val domain: String, + val allTrackersBlocked: Boolean, + val networkCount: Int, + val trackingEventsByNetwork: Map> ) val viewState: MutableLiveData = MutableLiveData() @@ -38,10 +38,10 @@ class TrackerNetworksViewModel : ViewModel() { private fun resetViewState() { viewState.value = ViewState( - domain = "", - networkCount = 0, - allTrackersBlocked = true, - trackingEventsByNetwork = HashMap() + domain = "", + networkCount = 0, + allTrackersBlocked = true, + trackingEventsByNetwork = HashMap() ) } @@ -51,10 +51,10 @@ class TrackerNetworksViewModel : ViewModel() { return } viewState.value = viewState.value?.copy( - domain = site.uri?.host ?: "", - networkCount = site.networkCount, - allTrackersBlocked = site.allTrackersBlocked, - trackingEventsByNetwork = site.distinctTrackersByNetwork + domain = site.uri?.host ?: "", + networkCount = site.networkCount, + allTrackersBlocked = site.allTrackersBlocked, + trackingEventsByNetwork = site.distinctTrackersByNetwork ) } } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/settings/SettingsActivity.kt b/app/src/main/java/com/duckduckgo/app/settings/SettingsActivity.kt index ba20062465bd..bb8841a326f4 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/SettingsActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/SettingsActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.settings import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Build @@ -29,21 +28,14 @@ import com.duckduckgo.app.about.AboutDuckDuckGoActivity import com.duckduckgo.app.browser.R import com.duckduckgo.app.feedback.ui.FeedbackActivity import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.view.launchDefaultAppActivity import com.duckduckgo.app.onboarding.ui.OnboardingActivity import kotlinx.android.synthetic.main.content_settings.* import kotlinx.android.synthetic.main.include_toolbar.* -import javax.inject.Inject class SettingsActivity : DuckDuckGoActivity() { - @Inject - lateinit var viewModelFactory: ViewModelFactory - - private val viewModel: SettingsViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(SettingsViewModel::class.java) - } + private val viewModel: SettingsViewModel by bindViewModel() private val defaultBrowserChangeListener = OnCheckedChangeListener { _, _ -> launchDefaultAppScreen() } diff --git a/app/src/main/java/com/duckduckgo/app/settings/SettingsViewModel.kt b/app/src/main/java/com/duckduckgo/app/settings/SettingsViewModel.kt index 36191b037096..49924cdfc0fb 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/SettingsViewModel.kt @@ -32,11 +32,12 @@ class SettingsViewModel @Inject constructor( ) : ViewModel() { data class ViewState( - val loading: Boolean = true, - val version: String = "", - val autoCompleteSuggestionsEnabled: Boolean = true, - val showDefaultBrowserSetting: Boolean = false, - val isAppDefaultBrowser: Boolean = false) + val loading: Boolean = true, + val version: String = "", + val autoCompleteSuggestionsEnabled: Boolean = true, + val showDefaultBrowserSetting: Boolean = false, + val isAppDefaultBrowser: Boolean = false + ) private lateinit var currentViewState: ViewState @@ -60,11 +61,13 @@ class SettingsViewModel @Inject constructor( val variantKey = variantManager.getVariant().key - viewState.value = currentViewState.copy(loading = false, - autoCompleteSuggestionsEnabled = autoCompleteEnabled, - isAppDefaultBrowser = defaultBrowserAlready, - showDefaultBrowserSetting = defaultWebBrowserCapability.deviceSupportsDefaultBrowserConfiguration(), - version = obtainVersion(variantKey)) + viewState.value = currentViewState.copy( + loading = false, + autoCompleteSuggestionsEnabled = autoCompleteEnabled, + isAppDefaultBrowser = defaultBrowserAlready, + showDefaultBrowserSetting = defaultWebBrowserCapability.deviceSupportsDefaultBrowserConfiguration(), + version = obtainVersion(variantKey) + ) } fun userRequestedToSendFeedback() { diff --git a/app/src/main/java/com/duckduckgo/app/settings/db/SettingsDataStore.kt b/app/src/main/java/com/duckduckgo/app/settings/db/SettingsDataStore.kt index 6aec0387372e..e1fc244f807b 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/db/SettingsDataStore.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/db/SettingsDataStore.kt @@ -31,8 +31,8 @@ class SettingsSharedPreferences @Inject constructor(private val context: Context get() = preferences.getBoolean(KEY_AUTOCOMPLETE_ENABLED, true) set(enabled) { preferences.edit() - .putBoolean(KEY_AUTOCOMPLETE_ENABLED, enabled) - .apply() + .putBoolean(KEY_AUTOCOMPLETE_ENABLED, enabled) + .apply() } private val preferences: SharedPreferences diff --git a/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt b/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt index fce1b0b55606..98127a4c45e0 100644 --- a/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt +++ b/app/src/main/java/com/duckduckgo/app/statistics/VariantManager.kt @@ -19,8 +19,6 @@ package com.duckduckgo.app.statistics import android.os.Build import android.support.annotation.WorkerThread import com.duckduckgo.app.statistics.VariantManager.Companion.DEFAULT_VARIANT -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionBottomSheet -import com.duckduckgo.app.statistics.VariantManager.VariantFeature.DefaultBrowserFeature.ShowHomeScreenCallToActionSimpleButton import com.duckduckgo.app.statistics.store.StatisticsDataStore import timber.log.Timber @@ -29,12 +27,6 @@ interface VariantManager { sealed class VariantFeature { - sealed class DefaultBrowserFeature : VariantFeature() { - object ShowInOnboarding : DefaultBrowserFeature() - object ShowBanner : DefaultBrowserFeature() - object ShowHomeScreenCallToActionSimpleButton : DefaultBrowserFeature() - object ShowHomeScreenCallToActionBottomSheet : DefaultBrowserFeature() - } } companion object { @@ -43,12 +35,6 @@ interface VariantManager { val DEFAULT_VARIANT = Variant(key = "", features = emptyList()) val ACTIVE_VARIANTS = listOf( - Variant(key = "mp", weight = 1.0, features = listOf(ShowHomeScreenCallToActionBottomSheet)), - Variant(key = "mq", weight = 1.0, features = listOf(ShowHomeScreenCallToActionSimpleButton)), - - // control group - Variant(key = "mr", weight = 1.0, features = emptyList()), - // SERP variants - do not remove Variant(key = "sa", weight = 1.0, features = emptyList()), Variant(key = "sb", weight = 1.0, features = emptyList()) diff --git a/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoader.kt b/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoader.kt index fe46be820d3e..005c6d7f8aef 100644 --- a/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoader.kt +++ b/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogateLoader.kt @@ -24,8 +24,8 @@ import javax.inject.Inject @WorkerThread class ResourceSurrogateLoader @Inject constructor( - private val resourceSurrogates: ResourceSurrogates, - private val surrogatesDataStore: ResourceSurrogateDataStore + private val resourceSurrogates: ResourceSurrogates, + private val surrogatesDataStore: ResourceSurrogateDataStore ) { fun loadData() { @@ -79,11 +79,11 @@ class ResourceSurrogateLoader @Inject constructor( if (it.isBlank()) { surrogates.add( - SurrogateResponse( - name = ruleName, - mimeType = mimeType, - jsFunction = functionBuilder.toString() - ) + SurrogateResponse( + name = ruleName, + mimeType = mimeType, + jsFunction = functionBuilder.toString() + ) ) functionBuilder.setLength(0) diff --git a/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogates.kt b/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogates.kt index 8856b7e8b7dc..31cca84b616f 100644 --- a/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogates.kt +++ b/app/src/main/java/com/duckduckgo/app/surrogates/ResourceSurrogates.kt @@ -46,8 +46,8 @@ class ResourceSurrogatesImpl : ResourceSurrogates { } data class SurrogateResponse( - val responseAvailable: Boolean = true, - val name: String = "", - val jsFunction: String = "", - val mimeType: String = "" + val responseAvailable: Boolean = true, + val name: String = "", + val jsFunction: String = "", + val mimeType: String = "" ) diff --git a/app/src/main/java/com/duckduckgo/app/surrogates/api/ResourceSurrogateListDownloader.kt b/app/src/main/java/com/duckduckgo/app/surrogates/api/ResourceSurrogateListDownloader.kt index ba0b96e9fe93..4f9b2e00bdc5 100644 --- a/app/src/main/java/com/duckduckgo/app/surrogates/api/ResourceSurrogateListDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/surrogates/api/ResourceSurrogateListDownloader.kt @@ -16,9 +16,9 @@ package com.duckduckgo.app.surrogates.api +import com.duckduckgo.app.global.api.isCached import com.duckduckgo.app.surrogates.ResourceSurrogateLoader import com.duckduckgo.app.surrogates.store.ResourceSurrogateDataStore -import com.duckduckgo.app.global.api.isCached import io.reactivex.Completable import timber.log.Timber import java.io.IOException @@ -26,9 +26,9 @@ import javax.inject.Inject class ResourceSurrogateListDownloader @Inject constructor( - private val service: ResourceSurrogateListService, - private val surrogatesDataStore: ResourceSurrogateDataStore, - private val resourceSurrogateLoader: ResourceSurrogateLoader + private val service: ResourceSurrogateListService, + private val surrogatesDataStore: ResourceSurrogateDataStore, + private val resourceSurrogateLoader: ResourceSurrogateLoader ) { fun downloadList(): Completable { diff --git a/app/src/main/java/com/duckduckgo/app/surrogates/di/ResourceSurrogateModule.kt b/app/src/main/java/com/duckduckgo/app/surrogates/di/ResourceSurrogateModule.kt index 15d6629a8b38..fe761bd54350 100644 --- a/app/src/main/java/com/duckduckgo/app/surrogates/di/ResourceSurrogateModule.kt +++ b/app/src/main/java/com/duckduckgo/app/surrogates/di/ResourceSurrogateModule.kt @@ -28,5 +28,5 @@ class ResourceSurrogateModule { @Provides @Singleton - fun analyticsSurrogates() : ResourceSurrogates = ResourceSurrogatesImpl() + fun analyticsSurrogates(): ResourceSurrogates = ResourceSurrogatesImpl() } \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt index 088902d31c17..6bf7d6f23c85 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt @@ -17,7 +17,6 @@ package com.duckduckgo.app.tabs.ui import android.arch.lifecycle.Observer -import android.arch.lifecycle.ViewModelProviders import android.content.Context import android.content.Intent import android.os.Bundle @@ -26,9 +25,9 @@ import android.view.Menu import android.view.MenuItem import com.duckduckgo.app.browser.R import com.duckduckgo.app.global.DuckDuckGoActivity -import com.duckduckgo.app.global.ViewModelFactory import com.duckduckgo.app.global.view.ClearPersonalDataAction import com.duckduckgo.app.global.view.FireDialog +import com.duckduckgo.app.settings.SettingsActivity import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.app.tabs.model.TabEntity import com.duckduckgo.app.tabs.ui.TabSwitcherViewModel.Command @@ -41,18 +40,14 @@ import javax.inject.Inject class TabSwitcherActivity : DuckDuckGoActivity(), TabSwitcherAdapter.TabSwitchedListener { - @Inject - lateinit var viewModelFactory: ViewModelFactory - @Inject lateinit var clearPersonalDataAction: ClearPersonalDataAction @Inject lateinit var pixel: Pixel - private val viewModel: TabSwitcherViewModel by lazy { - ViewModelProviders.of(this, viewModelFactory).get(TabSwitcherViewModel::class.java) - } + private val viewModel: TabSwitcherViewModel by bindViewModel() + private val tabsAdapter = TabSwitcherAdapter(this, this) override fun onCreate(savedInstanceState: Bundle?) { @@ -104,8 +99,9 @@ class TabSwitcherActivity : DuckDuckGoActivity(), TabSwitcherAdapter.TabSwitched override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.fire -> onFire() - R.id.newTab -> onNewTabRequested() + R.id.newTab, R.id.newTabOverflow -> onNewTabRequested() R.id.closeAllTabs -> closeAllTabs() + R.id.settings -> showSettings() } return super.onOptionsItemSelected(item) } @@ -135,6 +131,10 @@ class TabSwitcherActivity : DuckDuckGoActivity(), TabSwitcherAdapter.TabSwitched } } + private fun showSettings() { + startActivity(SettingsActivity.intent(this)) + } + override fun finish() { clearObserversEarlyToStopViewUpdates() super.finish() diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt index 05e4d37a1f17..aab2497d0f9e 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt @@ -56,10 +56,10 @@ class TabSwitcherAdapter(private val context: Context, private val itemClickList holder.root.alpha = if (tab.tabId == selectedTab?.tabId) SELECTED_ALPHA else DEFAULT_ALPHA GlideApp.with(holder.root) - .load(tab.favicon()) - .placeholder(R.drawable.ic_globe_gray_16dp) - .error(R.drawable.ic_globe_gray_16dp) - .into(holder.favicon) + .load(tab.favicon()) + .placeholder(R.drawable.ic_globe_gray_16dp) + .error(R.drawable.ic_globe_gray_16dp) + .into(holder.favicon) attachClickListeners(holder, tab) } @@ -89,12 +89,12 @@ class TabSwitcherAdapter(private val context: Context, private val itemClickList } data class TabViewHolder( - val root: View, - val favicon: ImageView, - val title: TextView, - val url: TextView, - val close: ImageView, - val tabUnread: View + val root: View, + val favicon: ImageView, + val title: TextView, + val url: TextView, + val close: ImageView, + val tabUnread: View ) : RecyclerView.ViewHolder(root) companion object { diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/AdBlockClient.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/AdBlockClient.kt index a00c43363e5f..fbddd49ba67a 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/AdBlockClient.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/AdBlockClient.kt @@ -59,7 +59,7 @@ class AdBlockClient(override val name: ClientName) : Client { private external fun getProcessedData(clientPointer: Long): ByteArray override fun matches(url: String, documentUrl: String, resourceType: ResourceType): Boolean = - matches(nativeClientPointer, url, documentUrl, resourceType.filterOption) + matches(nativeClientPointer, url, documentUrl, resourceType.filterOption) private external fun matches(clientPointer: Long, url: String, documentUrl: String, filterOption: Int): Boolean diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/DisconnectClient.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/DisconnectClient.kt index 080938ef93da..302aae0d10a9 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/DisconnectClient.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/DisconnectClient.kt @@ -24,8 +24,8 @@ class DisconnectClient(override val name: Client.ClientName, private val tracker override fun matches(url: String, documentUrl: String, resourceType: ResourceType): Boolean { return trackers - .filter { bannedCategories().contains(it.category) } - .any { sameOrSubdomain(url, it.url) } + .filter { bannedCategories().contains(it.category) } + .any { sameOrSubdomain(url, it.url) } } private fun bannedCategories(): List = listOf("Analytics", "Advertising", "Social") diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDataLoader.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDataLoader.kt index d18c632effdc..d5398571d7f2 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDataLoader.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDataLoader.kt @@ -17,9 +17,9 @@ package com.duckduckgo.app.trackerdetection import android.support.annotation.WorkerThread +import com.duckduckgo.app.global.store.BinaryDataStore import com.duckduckgo.app.trackerdetection.db.TrackerDataDao import com.duckduckgo.app.trackerdetection.model.TrackerNetworks -import com.duckduckgo.app.global.store.BinaryDataStore import timber.log.Timber import javax.inject.Inject @@ -28,7 +28,8 @@ class TrackerDataLoader @Inject constructor( private val trackerDetector: TrackerDetector, private val binaryDataStore: BinaryDataStore, private val trackerDataDao: TrackerDataDao, - private val networkTrackers: TrackerNetworks) { + private val networkTrackers: TrackerNetworks +) { fun loadData() { diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDetector.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDetector.kt index fcb3a014bf0e..9581d9d4d350 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDetector.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/TrackerDetector.kt @@ -29,9 +29,10 @@ interface TrackerDetector { fun evaluate(url: String, documentUrl: String, resourceType: ResourceType): TrackingEvent? } -class TrackerDetectorImpl ( - private val networkTrackers: TrackerNetworks, - private val settings: PrivacySettingsStore) :TrackerDetector { +class TrackerDetectorImpl( + private val networkTrackers: TrackerNetworks, + private val settings: PrivacySettingsStore +) : TrackerDetector { private val clients = CopyOnWriteArrayList() @@ -67,10 +68,10 @@ class TrackerDetectorImpl ( } private fun firstParty(firstUrl: String, secondUrl: String): Boolean = - sameOrSubdomain(firstUrl, secondUrl) || sameOrSubdomain(secondUrl, firstUrl) || sameNetworkName(firstUrl, secondUrl) + sameOrSubdomain(firstUrl, secondUrl) || sameOrSubdomain(secondUrl, firstUrl) || sameNetworkName(firstUrl, secondUrl) private fun sameNetworkName(firstUrl: String, secondUrl: String): Boolean = - networkTrackers.network(firstUrl) != null && networkTrackers.network(firstUrl)?.name == networkTrackers.network(secondUrl)?.name + networkTrackers.network(firstUrl) != null && networkTrackers.network(firstUrl)?.name == networkTrackers.network(secondUrl)?.name val clientCount get() = clients.count() diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/api/TrackerDataDownloader.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/api/TrackerDataDownloader.kt index 826c6b04a30f..11884feea648 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/api/TrackerDataDownloader.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/api/TrackerDataDownloader.kt @@ -18,12 +18,12 @@ package com.duckduckgo.app.trackerdetection.api import com.duckduckgo.app.global.api.isCached import com.duckduckgo.app.global.db.AppDatabase +import com.duckduckgo.app.global.store.BinaryDataStore import com.duckduckgo.app.trackerdetection.AdBlockClient import com.duckduckgo.app.trackerdetection.Client import com.duckduckgo.app.trackerdetection.Client.ClientName.* import com.duckduckgo.app.trackerdetection.TrackerDataLoader import com.duckduckgo.app.trackerdetection.db.TrackerDataDao -import com.duckduckgo.app.global.store.BinaryDataStore import io.reactivex.Completable import okhttp3.ResponseBody import retrofit2.Call @@ -37,7 +37,8 @@ class TrackerDataDownloader @Inject constructor( private val binaryDataStore: BinaryDataStore, private val trackerDataLoader: TrackerDataLoader, private val trackerDataDao: TrackerDataDao, - private val appDatabase: AppDatabase) { + private val appDatabase: AppDatabase +) { fun downloadList(clientName: Client.ClientName): Completable { diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDao.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDao.kt index 0cfd2ae4dcd7..31f7113f1c5d 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDao.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/db/TrackerDataDao.kt @@ -33,7 +33,7 @@ abstract class TrackerDataDao { } @Query("select * from disconnect_tracker") - abstract fun getAll() : List + abstract fun getAll(): List @Query("select count(*) from disconnect_tracker") abstract fun count(): Int diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/DisconnectTracker.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/DisconnectTracker.kt index dc4ebcdd8d2e..d6f77b33951d 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/DisconnectTracker.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/DisconnectTracker.kt @@ -21,7 +21,8 @@ import android.arch.persistence.room.PrimaryKey @Entity(tableName = "disconnect_tracker") data class DisconnectTracker( - @PrimaryKey val url: String, - val category: String, - val networkName: String, - val networkUrl: String) \ No newline at end of file + @PrimaryKey val url: String, + val category: String, + val networkName: String, + val networkUrl: String +) \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetwork.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetwork.kt index fb0ac7d942e2..309c12d132ca 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetwork.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetwork.kt @@ -16,8 +16,10 @@ package com.duckduckgo.app.trackerdetection.model -data class TrackerNetwork(val name: String, - val url: String, - val category: String? = null, - val percentageOfPages: Int? = null, - val isMajor: Boolean = false) +data class TrackerNetwork( + val name: String, + val url: String, + val category: String? = null, + val percentageOfPages: Int? = null, + val isMajor: Boolean = false +) diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetworks.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetworks.kt index ec6066924c8e..72ab4f6c4fbf 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetworks.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackerNetworks.kt @@ -28,16 +28,16 @@ class TrackerNetworks @Inject constructor() : Serializable { companion object { var majorNetworks = arrayOf( - TrackerNetwork(name = "Google", url = "google.com", percentageOfPages = 84, isMajor = true), - TrackerNetwork(name = "Facebook", url = "facebook.com", percentageOfPages = 36, isMajor = true), - TrackerNetwork(name = "Twitter", url = "twitter.com", percentageOfPages = 16, isMajor = true), - TrackerNetwork(name = "Amazon.com", url = "amazon.com", percentageOfPages = 14, isMajor = true), - TrackerNetwork(name = "AppNexus", url = "appnexus.com", percentageOfPages = 10, isMajor = true), - TrackerNetwork(name = "Oracle", url = "oracle.com", percentageOfPages = 10, isMajor = true), - TrackerNetwork(name = "MediaMath", url = "mediamath.com", percentageOfPages = 9, isMajor = true), - TrackerNetwork(name = "Yahoo!", url = "yahoo.com", percentageOfPages = 9, isMajor = true), - TrackerNetwork(name = "StackPath", url = "stackpath.com", percentageOfPages = 7, isMajor = true), - TrackerNetwork(name = "Automattic", url = "automattic.com", percentageOfPages = 7, isMajor = true) + TrackerNetwork(name = "Google", url = "google.com", percentageOfPages = 84, isMajor = true), + TrackerNetwork(name = "Facebook", url = "facebook.com", percentageOfPages = 36, isMajor = true), + TrackerNetwork(name = "Twitter", url = "twitter.com", percentageOfPages = 16, isMajor = true), + TrackerNetwork(name = "Amazon.com", url = "amazon.com", percentageOfPages = 14, isMajor = true), + TrackerNetwork(name = "AppNexus", url = "appnexus.com", percentageOfPages = 10, isMajor = true), + TrackerNetwork(name = "Oracle", url = "oracle.com", percentageOfPages = 10, isMajor = true), + TrackerNetwork(name = "MediaMath", url = "mediamath.com", percentageOfPages = 9, isMajor = true), + TrackerNetwork(name = "Yahoo!", url = "yahoo.com", percentageOfPages = 9, isMajor = true), + TrackerNetwork(name = "StackPath", url = "stackpath.com", percentageOfPages = 7, isMajor = true), + TrackerNetwork(name = "Automattic", url = "automattic.com", percentageOfPages = 7, isMajor = true) ) } @@ -51,11 +51,12 @@ class TrackerNetworks @Inject constructor() : Serializable { val disconnectEntry = data.find { sameOrSubdomain(url, it.url) || sameOrSubdomain(url, it.networkUrl) } ?: return null val majorEntry = majorNetwork(disconnectEntry.networkName) return TrackerNetwork( - name = disconnectEntry.networkName, - url = disconnectEntry.networkUrl, - category = disconnectEntry.category, - percentageOfPages = majorEntry?.percentageOfPages, - isMajor = majorEntry != null) + name = disconnectEntry.networkName, + url = disconnectEntry.networkUrl, + category = disconnectEntry.category, + percentageOfPages = majorEntry?.percentageOfPages, + isMajor = majorEntry != null + ) } private fun majorNetwork(networkName: String): TrackerNetwork? { diff --git a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackingEvent.kt b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackingEvent.kt index 84dd32821ff5..367bf623594e 100644 --- a/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackingEvent.kt +++ b/app/src/main/java/com/duckduckgo/app/trackerdetection/model/TrackingEvent.kt @@ -17,7 +17,9 @@ package com.duckduckgo.app.trackerdetection.model -data class TrackingEvent(val documentUrl: String, - val trackerUrl: String, - val trackerNetwork: TrackerNetwork?, - val blocked: Boolean) \ No newline at end of file +data class TrackingEvent( + val documentUrl: String, + val trackerUrl: String, + val trackerNetwork: TrackerNetwork?, + val blocked: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/widget/SearchWidget.kt b/app/src/main/java/com/duckduckgo/widget/SearchWidget.kt index fff10e80b4fc..896a1e3dc4c0 100644 --- a/app/src/main/java/com/duckduckgo/widget/SearchWidget.kt +++ b/app/src/main/java/com/duckduckgo/widget/SearchWidget.kt @@ -38,15 +38,17 @@ class SearchWidget : AppWidgetProvider() { companion object { - internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, - appWidgetId: Int) { + internal fun updateAppWidget( + context: Context, appWidgetManager: AppWidgetManager, + appWidgetId: Int + ) { val views = RemoteViews(context.packageName, R.layout.search_widget) views.setOnClickPendingIntent(R.id.widgetContainer, buildPendingIntent(context)) appWidgetManager.updateAppWidget(appWidgetId, views) } - private fun buildPendingIntent(context: Context) : PendingIntent { + private fun buildPendingIntent(context: Context): PendingIntent { val intent = BrowserActivity.intent(context, newSearch = true) return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) } diff --git a/app/src/main/res/color/browser_menu_icon.xml b/app/src/main/res/color/browser_menu_icon.xml index 0843966e256b..6ae2d3cc660f 100644 --- a/app/src/main/res/color/browser_menu_icon.xml +++ b/app/src/main/res/color/browser_menu_icon.xml @@ -16,6 +16,6 @@ --> - - + + \ No newline at end of file diff --git a/app/src/main/res/color/browser_menu_text.xml b/app/src/main/res/color/browser_menu_text.xml index b31f53f7d696..bfa1e77eefc1 100644 --- a/app/src/main/res/color/browser_menu_text.xml +++ b/app/src/main/res/color/browser_menu_text.xml @@ -16,6 +16,6 @@ --> - - + + \ No newline at end of file diff --git a/app/src/main/res/color/modal_card_button_background.xml b/app/src/main/res/color/modal_card_button_background.xml index 78f05512e025..2f472bb3ad82 100644 --- a/app/src/main/res/color/modal_card_button_background.xml +++ b/app/src/main/res/color/modal_card_button_background.xml @@ -16,6 +16,6 @@ --> - - + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_add_gray_30dp.xml b/app/src/main/res/drawable/ic_add_gray_30dp.xml index 0042bf592050..8251c6373977 100644 --- a/app/src/main/res/drawable/ic_add_gray_30dp.xml +++ b/app/src/main/res/drawable/ic_add_gray_30dp.xml @@ -15,11 +15,11 @@ --> + android:width="30dp" + android:height="30dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" /> diff --git a/app/src/main/res/drawable/ic_add_white_24dp.xml b/app/src/main/res/drawable/ic_add_white_24dp.xml index cb0b217c554b..5eb571a38f62 100644 --- a/app/src/main/res/drawable/ic_add_white_24dp.xml +++ b/app/src/main/res/drawable/ic_add_white_24dp.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" /> diff --git a/app/src/main/res/drawable/ic_app_shortcut_fire.xml b/app/src/main/res/drawable/ic_app_shortcut_fire.xml index 55601b386d2c..39565e683a97 100644 --- a/app/src/main/res/drawable/ic_app_shortcut_fire.xml +++ b/app/src/main/res/drawable/ic_app_shortcut_fire.xml @@ -17,8 +17,8 @@ + android:viewportWidth="48" + android:viewportHeight="48"> + android:viewportWidth="48" + android:viewportHeight="48"> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="#FFFFFF" + android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" /> diff --git a/app/src/main/res/drawable/ic_arrow_forward_24px.xml b/app/src/main/res/drawable/ic_arrow_forward_24px.xml index 492de03182a6..3154e2ff9a4b 100644 --- a/app/src/main/res/drawable/ic_arrow_forward_24px.xml +++ b/app/src/main/res/drawable/ic_arrow_forward_24px.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="#FFFFFF" + android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" /> diff --git a/app/src/main/res/drawable/ic_clear_browsnish_24px.xml b/app/src/main/res/drawable/ic_clear_browsnish_24px.xml index 70e4a85b80a2..1052e0370478 100644 --- a/app/src/main/res/drawable/ic_clear_browsnish_24px.xml +++ b/app/src/main/res/drawable/ic_clear_browsnish_24px.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="@color/brownishGray" + android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" /> diff --git a/app/src/main/res/drawable/ic_close_white_18dp.xml b/app/src/main/res/drawable/ic_close_white_18dp.xml index 483511f9fd8c..35c568fb2a39 100644 --- a/app/src/main/res/drawable/ic_close_white_18dp.xml +++ b/app/src/main/res/drawable/ic_close_white_18dp.xml @@ -17,8 +17,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_close_white_24dp.xml b/app/src/main/res/drawable/ic_close_white_24dp.xml index f4ee77177e89..2a3da65280e8 100644 --- a/app/src/main/res/drawable/ic_close_white_24dp.xml +++ b/app/src/main/res/drawable/ic_close_white_24dp.xml @@ -17,8 +17,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_file_download_white_24dp.xml b/app/src/main/res/drawable/ic_file_download_white_24dp.xml index 1771e605a55f..80bc1d8ad16f 100644 --- a/app/src/main/res/drawable/ic_file_download_white_24dp.xml +++ b/app/src/main/res/drawable/ic_file_download_white_24dp.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" /> diff --git a/app/src/main/res/drawable/ic_fire_gray_24dp.xml b/app/src/main/res/drawable/ic_fire_gray_24dp.xml index 5a6818b58b6a..4228a0bc8ab7 100644 --- a/app/src/main/res/drawable/ic_fire_gray_24dp.xml +++ b/app/src/main/res/drawable/ic_fire_gray_24dp.xml @@ -3,8 +3,8 @@ android:height="24dp" android:viewportWidth="19" android:viewportHeight="24"> - + diff --git a/app/src/main/res/drawable/ic_globe_gray_16dp.xml b/app/src/main/res/drawable/ic_globe_gray_16dp.xml index 5a332abc30d5..d934416f7167 100644 --- a/app/src/main/res/drawable/ic_globe_gray_16dp.xml +++ b/app/src/main/res/drawable/ic_globe_gray_16dp.xml @@ -21,6 +21,6 @@ android:viewportWidth="16.0" android:viewportHeight="16.0"> + android:fillColor="#aaa" + android:pathData="M12.72,12.312A1.588,1.588 0,0 0,11.2 11.2h-0.8V8.8c0,-0.44 -0.36,-0.8 -0.8,-0.8H4.8V6.4h1.6c0.44,0 0.8,-0.36 0.8,-0.8V4h1.6c0.88,0 1.6,-0.72 1.6,-1.6v-0.328c2.343,0.952 4,3.248 4,5.928 0,1.664 -0.64,3.176 -1.68,4.312zM7.2,14.344A6.39,6.39 0,0 1,1.6 8c0,-0.496 0.064,-0.968 0.168,-1.432L5.6,10.4v0.8c0,0.88 0.72,1.6 1.6,1.6v1.544zM8,0C3.584,0 0,3.584 0,8s3.584,8 8,8c4.415,0 8,-3.584 8,-8s-3.585,-8 -8,-8z" /> diff --git a/app/src/main/res/drawable/ic_globe_white_16dp.xml b/app/src/main/res/drawable/ic_globe_white_16dp.xml index b20e5f052734..597db8bc21f7 100644 --- a/app/src/main/res/drawable/ic_globe_white_16dp.xml +++ b/app/src/main/res/drawable/ic_globe_white_16dp.xml @@ -21,6 +21,6 @@ android:viewportWidth="16.0" android:viewportHeight="16.0"> + android:fillColor="#FFF" + android:pathData="M12.72,12.312A1.588,1.588 0,0 0,11.2 11.2h-0.8V8.8c0,-0.44 -0.36,-0.8 -0.8,-0.8H4.8V6.4h1.6c0.44,0 0.8,-0.36 0.8,-0.8V4h1.6c0.88,0 1.6,-0.72 1.6,-1.6v-0.328c2.343,0.952 4,3.248 4,5.928 0,1.664 -0.64,3.176 -1.68,4.312zM7.2,14.344A6.39,6.39 0,0 1,1.6 8c0,-0.496 0.064,-0.968 0.168,-1.432L5.6,10.4v0.8c0,0.88 0.72,1.6 1.6,1.6v1.544zM8,0C3.584,0 0,3.584 0,8s3.584,8 8,8c4.415,0 8,-3.584 8,-8s-3.585,-8 -8,-8z" /> diff --git a/app/src/main/res/drawable/ic_icon_heart_26dp.xml b/app/src/main/res/drawable/ic_icon_heart_26dp.xml index b35660820d78..b50ca645b1ec 100644 --- a/app/src/main/res/drawable/ic_icon_heart_26dp.xml +++ b/app/src/main/res/drawable/ic_icon_heart_26dp.xml @@ -19,8 +19,8 @@ android:height="26dp" android:viewportWidth="26" android:viewportHeight="26"> - + diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_down_white_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_down_white_24dp.xml index 9b2cb0f91b37..4c807a72b786 100644 --- a/app/src/main/res/drawable/ic_keyboard_arrow_down_white_24dp.xml +++ b/app/src/main/res/drawable/ic_keyboard_arrow_down_white_24dp.xml @@ -17,8 +17,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_up_white_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_up_white_24dp.xml index 0e07d4acdebe..a314f7d1aa38 100644 --- a/app/src/main/res/drawable/ic_keyboard_arrow_up_white_24dp.xml +++ b/app/src/main/res/drawable/ic_keyboard_arrow_up_white_24dp.xml @@ -17,8 +17,8 @@ + android:viewportWidth="24.0" + android:viewportHeight="24.0"> diff --git a/app/src/main/res/drawable/ic_overflow_gray_24dp.xml b/app/src/main/res/drawable/ic_overflow_gray_24dp.xml index b4f0238b2e11..f33f12f9fcbd 100644 --- a/app/src/main/res/drawable/ic_overflow_gray_24dp.xml +++ b/app/src/main/res/drawable/ic_overflow_gray_24dp.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="#AAA" + android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" /> diff --git a/app/src/main/res/drawable/ic_overflow_white_24dp.xml b/app/src/main/res/drawable/ic_overflow_white_24dp.xml index a8e5a111af4a..aca79972572b 100644 --- a/app/src/main/res/drawable/ic_overflow_white_24dp.xml +++ b/app/src/main/res/drawable/ic_overflow_white_24dp.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="#FFF" + android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" /> diff --git a/app/src/main/res/drawable/ic_refresh_24dp.xml b/app/src/main/res/drawable/ic_refresh_24dp.xml index bf37f24065d9..b074d46662fb 100644 --- a/app/src/main/res/drawable/ic_refresh_24dp.xml +++ b/app/src/main/res/drawable/ic_refresh_24dp.xml @@ -15,11 +15,11 @@ --> + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="#FFFFFF" + android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" /> diff --git a/app/src/main/res/drawable/ic_tabs_gray_24dp.xml b/app/src/main/res/drawable/ic_tabs_gray_24dp.xml index 519b51c75536..34b4744c962f 100644 --- a/app/src/main/res/drawable/ic_tabs_gray_24dp.xml +++ b/app/src/main/res/drawable/ic_tabs_gray_24dp.xml @@ -19,8 +19,8 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> - + diff --git a/app/src/main/res/drawable/icon_smiley_face.xml b/app/src/main/res/drawable/icon_smiley_face.xml index 33b96ad0ef0b..e20dfcaa846e 100644 --- a/app/src/main/res/drawable/icon_smiley_face.xml +++ b/app/src/main/res/drawable/icon_smiley_face.xml @@ -19,8 +19,8 @@ android:height="18dp" android:viewportWidth="18" android:viewportHeight="18"> - + diff --git a/app/src/main/res/drawable/modal_card_button_bg.xml b/app/src/main/res/drawable/modal_card_button_bg.xml index b7ef3feb285c..f4b042a33837 100644 --- a/app/src/main/res/drawable/modal_card_button_bg.xml +++ b/app/src/main/res/drawable/modal_card_button_bg.xml @@ -19,6 +19,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/network_tracker_summary_pill_bg.xml b/app/src/main/res/drawable/network_tracker_summary_pill_bg.xml index d25392b6b500..f64705fd1485 100644 --- a/app/src/main/res/drawable/network_tracker_summary_pill_bg.xml +++ b/app/src/main/res/drawable/network_tracker_summary_pill_bg.xml @@ -16,7 +16,11 @@ --> - - - + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/new_tab_set_default_browser_button_background.xml b/app/src/main/res/drawable/new_tab_set_default_browser_button_background.xml index fec268e1edff..c9081e4cfcdb 100644 --- a/app/src/main/res/drawable/new_tab_set_default_browser_button_background.xml +++ b/app/src/main/res/drawable/new_tab_set_default_browser_button_background.xml @@ -19,6 +19,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/privacygrade_icon_a.xml b/app/src/main/res/drawable/privacygrade_icon_a.xml index 6ccd740e7098..e83dc929a3e8 100644 --- a/app/src/main/res/drawable/privacygrade_icon_a.xml +++ b/app/src/main/res/drawable/privacygrade_icon_a.xml @@ -15,16 +15,16 @@ --> + android:width="22dp" + android:height="22dp" + android:viewportWidth="22.0" + android:viewportHeight="22.0"> + android:pathData="M9.74,12.305h2.52l-1.25,-3.74z" /> + android:pathData="M11,0C4.925,0 0,4.925 0,11s4.925,11 11,11 11,-4.925 11,-11A11,11 0,0 0,11 0zM13.45,15.965l-0.5,-1.43L9.045,14.535l-0.5,1.43L5.65,15.965l3.735,-9.93h3.23l3.735,9.93h-2.9z" /> diff --git a/app/src/main/res/drawable/privacygrade_icon_b.xml b/app/src/main/res/drawable/privacygrade_icon_b.xml index 05fe81ef9df0..2ef5ef9e2dc2 100644 --- a/app/src/main/res/drawable/privacygrade_icon_b.xml +++ b/app/src/main/res/drawable/privacygrade_icon_b.xml @@ -15,16 +15,16 @@ --> + android:width="22dp" + android:height="22dp" + android:viewportWidth="22.0" + android:viewportHeight="22.0"> + android:pathData="M12.77,9.045a0.78,0.78 0,0 0,-0.875 -0.775h-2.5v1.545h2.5a0.77,0.77 0,0 0,0.875 -0.77zM12,12.05H9.405v1.68H12c0.615,0 1,-0.31 1,-0.845 0,-0.535 -0.39,-0.835 -1,-0.835z" /> + android:pathData="M11,0C4.925,0 0,4.925 0,11s4.925,11 11,11 11,-4.925 11,-11A11,11 0,0 0,11 0zM12.65,15.965L6.845,15.965v-9.93L12.5,6.035c2,0 2.9,1.28 2.9,2.53a2.225,2.225 0,0 1,-1.695 2.28,2.375 2.375,0 0,1 1.89,2.425c-0.025,1.445 -0.995,2.695 -2.945,2.695z" /> diff --git a/app/src/main/res/drawable/privacygrade_icon_c.xml b/app/src/main/res/drawable/privacygrade_icon_c.xml index 7a9a187943f5..3275a0579730 100644 --- a/app/src/main/res/drawable/privacygrade_icon_c.xml +++ b/app/src/main/res/drawable/privacygrade_icon_c.xml @@ -15,12 +15,12 @@ --> + android:width="22dp" + android:height="22dp" + android:viewportWidth="22.0" + android:viewportHeight="22.0"> + android:pathData="M11,0C4.925,0 0,4.925 0,11s4.925,11 11,11 11,-4.925 11,-11A11,11 0,0 0,11 0zM11.5,13.875a2.385,2.385 0,0 0,2.13 -1.445l2.205,1.04a4.65,4.65 0,0 1,-4.335 2.665c-3.05,0 -5.375,-2.085 -5.375,-5.135S8.47,5.865 11.5,5.865A4.59,4.59 0,0 1,15.855 8.5L13.65,9.57a2.385,2.385 0,0 0,-2.15 -1.445A2.74,2.74 0,0 0,8.75 11a2.75,2.75 0,0 0,2.75 2.875z" /> diff --git a/app/src/main/res/drawable/privacygrade_icon_d.xml b/app/src/main/res/drawable/privacygrade_icon_d.xml index a912bce5f688..e3fcc33bbb77 100644 --- a/app/src/main/res/drawable/privacygrade_icon_d.xml +++ b/app/src/main/res/drawable/privacygrade_icon_d.xml @@ -15,16 +15,16 @@ --> + android:width="22dp" + android:height="22dp" + android:viewportWidth="22.0" + android:viewportHeight="22.0"> + android:pathData="M10.87,8.27H9.25v5.46h1.605A2.64,2.64 0,0 0,13.61 11a2.54,2.54 0,0 0,-2.74 -2.73z" /> + android:pathData="M11,0C4.925,0 0,4.925 0,11s4.925,11 11,11 11,-4.925 11,-11A11,11 0,0 0,11 0zM10.87,15.965L6.69,15.965v-9.93h4.165c3.125,0 5.375,1.875 5.375,4.955s-2.23,4.975 -5.36,4.975z" /> diff --git a/app/src/main/res/drawable/ripple_light.xml b/app/src/main/res/drawable/ripple_light.xml index 303b3b206844..b66eb3451951 100644 --- a/app/src/main/res/drawable/ripple_light.xml +++ b/app/src/main/res/drawable/ripple_light.xml @@ -16,12 +16,12 @@ --> + android:color="@color/brownishGray"> - + \ No newline at end of file diff --git a/app/src/main/res/drawable/tab_unread.xml b/app/src/main/res/drawable/tab_unread.xml index 12a31c35ab9f..a0412a681e8f 100644 --- a/app/src/main/res/drawable/tab_unread.xml +++ b/app/src/main/res/drawable/tab_unread.xml @@ -15,6 +15,7 @@ ~ limitations under the License. --> - + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_default_browser_info.xml b/app/src/main/res/layout-land/activity_default_browser_info.xml index d119b3191bac..203fcaf060ea 100644 --- a/app/src/main/res/layout-land/activity_default_browser_info.xml +++ b/app/src/main/res/layout-land/activity_default_browser_info.xml @@ -64,8 +64,8 @@ android:id="@+id/description" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginEnd="38dp" android:layout_marginTop="6dp" + android:layout_marginEnd="38dp" android:elevation="@dimen/modalCardHeaderElevation" android:paddingBottom="30dp" android:text="@string/defaultBrowserInfoMessage" @@ -94,9 +94,9 @@ android:id="@+id/dismissButton" android:layout_width="36dp" android:layout_height="36dp" - android:layout_marginEnd="6dp" android:layout_marginStart="14dp" android:layout_marginTop="6dp" + android:layout_marginEnd="6dp" android:background="?attr/selectableItemBackground" android:contentDescription="@string/dismissDefaultBrowserInfo" android:elevation="7dp" diff --git a/app/src/main/res/layout/activity_feedback.xml b/app/src/main/res/layout/activity_feedback.xml index a9467c60c873..ab3bdf09d85c 100644 --- a/app/src/main/res/layout/activity_feedback.xml +++ b/app/src/main/res/layout/activity_feedback.xml @@ -29,10 +29,10 @@ @@ -79,13 +79,13 @@ android:id="@+id/description" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginBottom="19dp" android:layout_marginTop="6dp" + android:layout_marginBottom="19dp" android:elevation="@dimen/modalCardHeaderElevation" android:lineSpacingExtra="4sp" - android:paddingBottom="30dp" - android:paddingEnd="20dp" android:paddingStart="20dp" + android:paddingEnd="20dp" + android:paddingBottom="30dp" android:text="@string/feedbackModalDescription" android:textAlignment="center" android:textColor="@color/white" @@ -117,8 +117,8 @@ android:hint="@string/feedbackUrlHint" android:imeOptions="flagNoExtractUi" android:inputType="textUri" - android:paddingBottom="16dp" android:paddingTop="16dp" + android:paddingBottom="16dp" android:singleLine="true" android:textSize="@dimen/modalCardEditTextSize" android:visibility="gone" @@ -136,8 +136,8 @@ android:imeOptions="flagNoExtractUi" android:inputType="textMultiLine" android:lineSpacingExtra="5sp" - android:paddingBottom="16dp" android:paddingTop="16dp" + android:paddingBottom="16dp" android:textSize="@dimen/modalCardEditTextSize" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -147,10 +147,10 @@ android:id="@+id/submitButton" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginBottom="30dp" - android:layout_marginEnd="20dp" android:layout_marginStart="20dp" android:layout_marginTop="24dp" + android:layout_marginEnd="20dp" + android:layout_marginBottom="30dp" android:background="@drawable/modal_card_button_bg" android:text="@string/feedbackSubmitButton" android:textColor="@color/white" diff --git a/app/src/main/res/layout/add_or_edit_bookmark.xml b/app/src/main/res/layout/add_or_edit_bookmark.xml index 5db2acc4e854..603f8863ec2d 100644 --- a/app/src/main/res/layout/add_or_edit_bookmark.xml +++ b/app/src/main/res/layout/add_or_edit_bookmark.xml @@ -25,8 +25,8 @@ android:id="@+id/bookmarkTitleInputContainer" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginEnd="20dp" - android:layout_marginStart="20dp"> + android:layout_marginStart="20dp" + android:layout_marginEnd="20dp"> @@ -48,8 +48,8 @@ + android:layout_height="match_parent"> + android:paddingBottom="18dp" + app:layoutManager="android.support.v7.widget.LinearLayoutManager" + tools:listItem="@layout/view_bookmark_entry" /> + android:text="@string/noBookmarks" + android:textAlignment="center" + android:textColor="@color/white" + android:textSize="16sp" /> diff --git a/app/src/main/res/layout/content_onboarding_default_browser.xml b/app/src/main/res/layout/content_onboarding_default_browser.xml index 058e6c4fff6d..5cdeb8699c76 100644 --- a/app/src/main/res/layout/content_onboarding_default_browser.xml +++ b/app/src/main/res/layout/content_onboarding_default_browser.xml @@ -20,8 +20,8 @@ android:id="@+id/longDescriptionContainer" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingEnd="44dp" android:paddingStart="44dp" + android:paddingEnd="44dp" android:tag="onboardingDefaultBrowser" tools:background="@color/eastBay" tools:context="com.duckduckgo.app.onboarding.ui.OnboardingActivity"> @@ -33,20 +33,20 @@ android:importantForAccessibility="no" android:paddingTop="20dp" android:src="@drawable/onboarding_image_default_browser" + app:layout_constraintBottom_toTopOf="@id/textContainer" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintBottom_toTopOf="@id/textContainer" app:layout_constraintVertical_bias="0.5" /> @@ -65,10 +65,10 @@