Commit 6460aa02 authored by Ella Ge's avatar Ella Ge Committed by Commit Bot

Merge Webapk/TWA disclosure controller 1

This CL moves WebappDisclosureSnackbarController to browserservices
folder, makes it use TrustedWebActivityModel and the
DisclosureInfobar as TrustedWebActivityDisclosureController.

This will change the text in unbound webapk's disclosure snackbar text
to be the same as TWA one.

Bug: 1128675
Change-Id: I900c41c04a6f36489bed1e08cf81c74f89e2801e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453896Reviewed-by: default avatarAndrew Grieve <agrieve@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Commit-Queue: Ella Ge <eirage@chromium.org>
Cr-Commit-Position: refs/heads/master@{#817516}
parent 4dad5674
...@@ -218,6 +218,7 @@ chrome_java_sources = [ ...@@ -218,6 +218,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/AddToHomescreenVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/AddToHomescreenVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebApkVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebApkVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureController.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java", "java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashController.java",
"java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashDelegate.java", "java/src/org/chromium/chrome/browser/browserservices/ui/splashscreen/SplashDelegate.java",
...@@ -1679,7 +1680,6 @@ chrome_java_sources = [ ...@@ -1679,7 +1680,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java", "java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java",
"java/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupWithStorageHandler.java", "java/src/org/chromium/chrome/browser/webapps/WebappDeferredStartupWithStorageHandler.java",
"java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java", "java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java",
"java/src/org/chromium/chrome/browser/webapps/WebappDisclosureSnackbarController.java",
"java/src/org/chromium/chrome/browser/webapps/WebappExtras.java", "java/src/org/chromium/chrome/browser/webapps/WebappExtras.java",
"java/src/org/chromium/chrome/browser/webapps/WebappIcon.java", "java/src/org/chromium/chrome/browser/webapps/WebappIcon.java",
"java/src/org/chromium/chrome/browser/webapps/WebappInfo.java", "java/src/org/chromium/chrome/browser/webapps/WebappInfo.java",
......
...@@ -33,6 +33,7 @@ chrome_junit_test_java_sources = [ ...@@ -33,6 +33,7 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityDisclosureControllerTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TrustedWebActivityOpenTimeRecorderTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifierTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/controller/trustedwebactivity/TwaVerifierTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/controller/webapps/WebappDisclosureControllerTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/DisclosureAcceptanceBroadcastReceiverTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/DisclosureAcceptanceBroadcastReceiverTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/DisclosureUiPickerTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/DisclosureUiPickerTest.java",
"junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/FilledLazy.java", "junit/src/org/chromium/chrome/browser/browserservices/ui/trustedwebactivity/FilledLazy.java",
...@@ -250,7 +251,6 @@ chrome_junit_test_java_sources = [ ...@@ -250,7 +251,6 @@ chrome_junit_test_java_sources = [
"junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappDisclosureSnackbarControllerTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebappInfoTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappIntentUtilsTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebappIntentUtilsTest.java",
"junit/src/org/chromium/chrome/browser/webapps/WebappLauncherActivityTest.java", "junit/src/org/chromium/chrome/browser/webapps/WebappLauncherActivityTest.java",
......
...@@ -413,7 +413,7 @@ specific_include_rules = { ...@@ -413,7 +413,7 @@ specific_include_rules = {
"WebappDeferredStartupWithStorageHandler\.java": [ "WebappDeferredStartupWithStorageHandler\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
], ],
"WebappDisclosureSnackbarController\.java": [ "WebappDisclosureController\.java": [
"+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java", "+chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java",
], ],
"AddToHomescreenCoordinator\.java": [ "AddToHomescreenCoordinator\.java": [
......
...@@ -2,18 +2,27 @@ ...@@ -2,18 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
package org.chromium.chrome.browser.webapps; package org.chromium.chrome.browser.browserservices.ui.controller.webapps;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_EVENTS_CALLBACK;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_DISMISSED_BY_USER;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_SHOWN;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.PACKAGE_NAME;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel;
import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; import org.chromium.chrome.browser.lifecycle.NativeInitObserver;
import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.webapps.WebApkExtras;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.WebappDeferredStartupWithStorageHandler;
import org.chromium.chrome.browser.webapps.WebappExtras;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.components.webapk.lib.common.WebApkConstants; import org.chromium.components.webapk.lib.common.WebApkConstants;
import javax.inject.Inject; import javax.inject.Inject;
...@@ -28,18 +37,24 @@ import javax.inject.Inject; ...@@ -28,18 +37,24 @@ import javax.inject.Inject;
* next time the app is opened if it hasn't been acknowledged. * next time the app is opened if it hasn't been acknowledged.
*/ */
@ActivityScope @ActivityScope
public class WebappDisclosureSnackbarController public class WebappDisclosureController
implements SnackbarManager.SnackbarController, PauseResumeWithNativeObserver { implements NativeInitObserver, TrustedWebActivityModel.DisclosureEventsCallback {
private final ChromeActivity mActivity;
private final BrowserServicesIntentDataProvider mIntentDataProvider; private final BrowserServicesIntentDataProvider mIntentDataProvider;
private final TrustedWebActivityModel mModel;
@Inject @Inject
public WebappDisclosureSnackbarController(ChromeActivity<?> activity, public WebappDisclosureController(ChromeActivity<?> activity,
BrowserServicesIntentDataProvider intentDataProvider, BrowserServicesIntentDataProvider intentDataProvider, TrustedWebActivityModel model,
WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler, WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler,
ActivityLifecycleDispatcher lifecycleDispatcher) { ActivityLifecycleDispatcher lifecycleDispatcher) {
mActivity = activity;
mIntentDataProvider = intentDataProvider; mIntentDataProvider = intentDataProvider;
mModel = model;
model.set(DISCLOSURE_EVENTS_CALLBACK, this);
WebApkExtras webApkExtras = mIntentDataProvider.getWebApkExtras();
if (webApkExtras != null && webApkExtras.webApkPackageName != null) {
model.set(PACKAGE_NAME, webApkExtras.webApkPackageName);
}
lifecycleDispatcher.register(this); lifecycleDispatcher.register(this);
...@@ -62,7 +77,7 @@ public class WebappDisclosureSnackbarController ...@@ -62,7 +77,7 @@ public class WebappDisclosureSnackbarController
} }
@Override @Override
public void onResumeWithNative() { public void onFinishNativeInitialization() {
WebappExtras webappExtras = mIntentDataProvider.getWebappExtras(); WebappExtras webappExtras = mIntentDataProvider.getWebappExtras();
WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage( WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(
mIntentDataProvider.getWebappExtras().id); mIntentDataProvider.getWebappExtras().id);
...@@ -72,23 +87,18 @@ public class WebappDisclosureSnackbarController ...@@ -72,23 +87,18 @@ public class WebappDisclosureSnackbarController
} }
@Override @Override
public void onPauseWithNative() {} public void onDisclosureAccepted() {
WebappExtras webappExtras = mIntentDataProvider.getWebappExtras();
/** WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(
* @param actionData an instance of WebappInfo mIntentDataProvider.getWebappExtras().id);
*/ if (storage != null) {
@Override storage.clearShowDisclosure();
public void onAction(Object actionData) {
if (actionData instanceof WebappDataStorage) {
((WebappDataStorage) actionData).clearShowDisclosure();
} }
mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_DISMISSED_BY_USER);
} }
/**
* Stub expected by SnackbarController.
*/
@Override @Override
public void onDismissNoAction(Object actionData) {} public void onDisclosureShown() {}
/** /**
* Shows the disclosure informing the user the Webapp is running in Chrome. * Shows the disclosure informing the user the Webapp is running in Chrome.
...@@ -101,14 +111,8 @@ public class WebappDisclosureSnackbarController ...@@ -101,14 +111,8 @@ public class WebappDisclosureSnackbarController
// If forced we set the bit to show the disclosure. This persists to future instances. // If forced we set the bit to show the disclosure. This persists to future instances.
if (force) storage.setShowDisclosure(); if (force) storage.setShowDisclosure();
if (shouldShowDisclosure(storage)) { if (!isShowing() && shouldShowDisclosure(storage)) {
mActivity.getSnackbarManager().showSnackbar( mModel.set(DISCLOSURE_STATE, DISCLOSURE_STATE_SHOWN);
Snackbar.make(mActivity.getResources().getString(
R.string.app_running_in_chrome_disclosure),
this, Snackbar.TYPE_PERSISTENT,
Snackbar.UMA_WEBAPK_PRIVACY_DISCLOSURE)
.setAction(mActivity.getResources().getString(R.string.ok), storage)
.setSingleLine(false));
} }
} }
...@@ -129,4 +133,8 @@ public class WebappDisclosureSnackbarController ...@@ -129,4 +133,8 @@ public class WebappDisclosureSnackbarController
&& !webApkExtras.webApkPackageName.startsWith( && !webApkExtras.webApkPackageName.startsWith(
WebApkConstants.WEBAPK_PACKAGE_PREFIX); WebApkConstants.WEBAPK_PACKAGE_PREFIX);
} }
public boolean isShowing() {
return mModel.get(DISCLOSURE_STATE) == DISCLOSURE_STATE_SHOWN;
}
} }
...@@ -7,6 +7,8 @@ package org.chromium.chrome.browser.webapps; ...@@ -7,6 +7,8 @@ package org.chromium.chrome.browser.webapps;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.browserservices.ui.controller.webapps.WebappDisclosureController;
import org.chromium.chrome.browser.browserservices.ui.view.trustedwebactivity.DisclosureInfobar;
import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.dependency_injection.ActivityScope;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.lifecycle.Destroyable; import org.chromium.chrome.browser.lifecycle.Destroyable;
...@@ -27,11 +29,11 @@ public class WebApkActivityCoordinator implements Destroyable { ...@@ -27,11 +29,11 @@ public class WebApkActivityCoordinator implements Destroyable {
@Inject @Inject
public WebApkActivityCoordinator(ChromeActivity<?> activity, public WebApkActivityCoordinator(ChromeActivity<?> activity,
WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler, WebappDeferredStartupWithStorageHandler deferredStartupWithStorageHandler,
WebappDisclosureSnackbarController disclosureSnackbarController, WebappDisclosureController disclosureController, DisclosureInfobar disclosureInfobar,
WebApkActivityLifecycleUmaTracker webApkActivityLifecycleUmaTracker, WebApkActivityLifecycleUmaTracker webApkActivityLifecycleUmaTracker,
ActivityLifecycleDispatcher lifecycleDispatcher, ActivityLifecycleDispatcher lifecycleDispatcher,
Lazy<WebApkUpdateManager> webApkUpdateManager) { Lazy<WebApkUpdateManager> webApkUpdateManager) {
// We don't need to do anything with |disclosureSnackbarController| and // We don't need to do anything with |disclosureController|, |disclosureInfobar| and
// |webApkActivityLifecycleUmaTracker|. We just need to resolve // |webApkActivityLifecycleUmaTracker|. We just need to resolve
// them so that they start working. // them so that they start working.
......
...@@ -304,7 +304,7 @@ public class WebappDataStorage { ...@@ -304,7 +304,7 @@ public class WebappDataStorage {
* Deletes the data for a web app by clearing all the information inside the SharedPreferences * Deletes the data for a web app by clearing all the information inside the SharedPreferences
* file. This does NOT delete the file itself but the file is left empty. * file. This does NOT delete the file itself but the file is left empty.
*/ */
void delete() { public void delete() {
deletePendingUpdateRequestFile(); deletePendingUpdateRequestFile();
mPreferences.edit().clear().apply(); mPreferences.edit().clear().apply();
} }
...@@ -455,7 +455,7 @@ public class WebappDataStorage { ...@@ -455,7 +455,7 @@ public class WebappDataStorage {
* Returns whether to show the user a privacy disclosure (used for TWAs and unbound WebAPKs). * Returns whether to show the user a privacy disclosure (used for TWAs and unbound WebAPKs).
* This is not cleared until the user explicitly acknowledges it. * This is not cleared until the user explicitly acknowledges it.
*/ */
boolean shouldShowDisclosure() { public boolean shouldShowDisclosure() {
return mPreferences.getBoolean(KEY_SHOW_DISCLOSURE, false); return mPreferences.getBoolean(KEY_SHOW_DISCLOSURE, false);
} }
...@@ -464,7 +464,7 @@ public class WebappDataStorage { ...@@ -464,7 +464,7 @@ public class WebappDataStorage {
* disclosure on every resume of the Webapp. This should be called when the user has * disclosure on every resume of the Webapp. This should be called when the user has
* acknowledged the disclosure. * acknowledged the disclosure.
*/ */
void clearShowDisclosure() { public void clearShowDisclosure() {
mPreferences.edit().putBoolean(KEY_SHOW_DISCLOSURE, false).apply(); mPreferences.edit().putBoolean(KEY_SHOW_DISCLOSURE, false).apply();
} }
...@@ -473,7 +473,7 @@ public class WebappDataStorage { ...@@ -473,7 +473,7 @@ public class WebappDataStorage {
* This is set the first time an app is opened without storage (either right after install or * This is set the first time an app is opened without storage (either right after install or
* after Chrome's storage is cleared). * after Chrome's storage is cleared).
*/ */
void setShowDisclosure() { public void setShowDisclosure() {
mPreferences.edit().putBoolean(KEY_SHOW_DISCLOSURE, true).apply(); mPreferences.edit().putBoolean(KEY_SHOW_DISCLOSURE, true).apply();
} }
......
...@@ -23,7 +23,10 @@ import javax.inject.Inject; ...@@ -23,7 +23,10 @@ import javax.inject.Inject;
*/ */
@ActivityScope @ActivityScope
public class WebappDeferredStartupWithStorageHandler { public class WebappDeferredStartupWithStorageHandler {
interface Task { /**
* Interface for deferred startup task callbacks.
*/
public interface Task {
/** /**
* Called to run task. * Called to run task.
* @param storage Null if there is no {@link WebappDataStorage} registered for the webapp * @param storage Null if there is no {@link WebappDataStorage} registered for the webapp
......
...@@ -18,6 +18,7 @@ import org.chromium.base.metrics.RecordHistogram; ...@@ -18,6 +18,7 @@ import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.browserservices.ui.SharedActivityCoordinator; import org.chromium.chrome.browser.browserservices.ui.SharedActivityCoordinator;
import org.chromium.chrome.browser.browserservices.ui.controller.webapps.WebappDisclosureController;
import org.chromium.chrome.browser.customtabs.CustomTabOrientationController; import org.chromium.chrome.browser.customtabs.CustomTabOrientationController;
import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule; import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule;
import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule; import org.chromium.chrome.browser.dependency_injection.ModuleOverridesRule;
...@@ -134,8 +135,8 @@ public class WebApkInitializationTest { ...@@ -134,8 +135,8 @@ public class WebApkInitializationTest {
mTrackingActivityLifecycleDispatcher.getRegisteredObserverClassNames(); mTrackingActivityLifecycleDispatcher.getRegisteredObserverClassNames();
assertTrue(registeredObserverClassNames.contains( assertTrue(registeredObserverClassNames.contains(
WebappActionsNotificationManager.class.getName())); WebappActionsNotificationManager.class.getName()));
assertTrue(registeredObserverClassNames.contains( assertTrue(
WebappDisclosureSnackbarController.class.getName())); registeredObserverClassNames.contains(WebappDisclosureController.class.getName()));
assertTrue(registeredObserverClassNames.contains( assertTrue(registeredObserverClassNames.contains(
WebApkActivityLifecycleUmaTracker.class.getName())); WebApkActivityLifecycleUmaTracker.class.getName()));
assertTrue( assertTrue(
......
...@@ -2,19 +2,20 @@ ...@@ -2,19 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
package org.chromium.chrome.browser.webapps; package org.chromium.chrome.browser.browserservices.ui.controller.webapps;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.res.Resources; import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_EVENTS_CALLBACK;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_DISMISSED_BY_USER;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_NOT_SHOWN;
import static org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel.DISCLOSURE_STATE_SHOWN;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
...@@ -27,41 +28,45 @@ import org.chromium.base.task.PostTask; ...@@ -27,41 +28,45 @@ import org.chromium.base.task.PostTask;
import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider; import org.chromium.chrome.browser.browserservices.BrowserServicesIntentDataProvider;
import org.chromium.chrome.browser.browserservices.ui.trustedwebactivity.TrustedWebActivityModel;
import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; import org.chromium.chrome.browser.webapps.WebappActivity;
import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.webapps.WebappDataStorage;
import org.chromium.chrome.browser.webapps.WebappDeferredStartupWithStorageHandler;
import org.chromium.chrome.browser.webapps.WebappIntentUtils;
import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.chrome.test.util.browser.webapps.WebApkIntentDataProviderBuilder; import org.chromium.chrome.test.util.browser.webapps.WebApkIntentDataProviderBuilder;
import org.chromium.components.webapk.lib.common.WebApkConstants; import org.chromium.components.webapk.lib.common.WebApkConstants;
/** /**
* Tests for WebappDisclosureSnackbarController * Tests for WebappDisclosureController
*/ */
@RunWith(BaseRobolectricTestRunner.class) @RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE) @Config(manifest = Config.NONE)
public class WebappDisclosureSnackbarControllerTest { public class WebappDisclosureControllerTest {
@Mock @Mock
public WebappActivity mActivity; public WebappActivity mActivity;
@Mock
public SnackbarManager mManager; public TrustedWebActivityModel mModel;
@Mock
public Resources mResources;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
// Run AsyncTasks synchronously. // Run AsyncTasks synchronously.
PostTask.setPrenativeThreadPoolExecutorForTesting(new RoboExecutorService()); PostTask.setPrenativeThreadPoolExecutorForTesting(new RoboExecutorService());
}
doReturn("test text").when(mResources).getString(anyInt()); @After
doReturn(mManager).when(mActivity).getSnackbarManager(); public void tearDown() {
doReturn(mResources).when(mActivity).getResources(); PostTask.resetPrenativeThreadPoolExecutorForTesting();
} }
private WebappDisclosureSnackbarController buildControllerForWebApk(String webApkPackageName) { private WebappDisclosureController buildControllerForWebApk(String webApkPackageName) {
BrowserServicesIntentDataProvider intentDataProvider = BrowserServicesIntentDataProvider intentDataProvider =
new WebApkIntentDataProviderBuilder(webApkPackageName, "https://pwa.rocks/") new WebApkIntentDataProviderBuilder(webApkPackageName, "https://pwa.rocks/")
.build(); .build();
return new WebappDisclosureSnackbarController(mActivity, intentDataProvider, mModel = new TrustedWebActivityModel();
return new WebappDisclosureController(mActivity, intentDataProvider, mModel,
mock(WebappDeferredStartupWithStorageHandler.class), mock(WebappDeferredStartupWithStorageHandler.class),
mock(ActivityLifecycleDispatcher.class)); mock(ActivityLifecycleDispatcher.class));
} }
...@@ -73,57 +78,80 @@ public class WebappDisclosureSnackbarControllerTest { ...@@ -73,57 +78,80 @@ public class WebappDisclosureSnackbarControllerTest {
} }
public void verifyShownThenDismissedOnNewCreateStorage(String packageName) { public void verifyShownThenDismissedOnNewCreateStorage(String packageName) {
WebappDisclosureSnackbarController controller = buildControllerForWebApk(packageName); WebappDisclosureController controller = buildControllerForWebApk(packageName);
WebappDataStorage storage = registerStorageForWebApk(packageName); WebappDataStorage storage = registerStorageForWebApk(packageName);
// Simulates the case that shows the disclosure when creating a new storage. // Simulates the case that shows the disclosure when creating a new storage.
controller.onDeferredStartupWithStorage(storage, true /* didCreateStorage */); controller.onDeferredStartupWithStorage(storage, true /* didCreateStorage */);
verify(mManager, times(1)).showSnackbar(any(Snackbar.class));
assertTrue(storage.shouldShowDisclosure()); assertTrue(storage.shouldShowDisclosure());
assertSnackbarShown();
// Simulate a restart or a resume. // Dismiss the disclosure.
controller.onResumeWithNative(); mModel.get(DISCLOSURE_EVENTS_CALLBACK).onDisclosureAccepted();
verify(mManager, times(2)).showSnackbar(any(Snackbar.class));
assertTrue(storage.shouldShowDisclosure()); assertSnackbarAccepted();
assertFalse(storage.shouldShowDisclosure());
storage.delete();
}
public void verifyShownThenDismissedOnRestart(String packageName) {
WebappDisclosureController controller = buildControllerForWebApk(packageName);
WebappDataStorage storage = registerStorageForWebApk(packageName);
// Simulates the case that shows the disclosure when finish native initialization.
storage.setShowDisclosure();
controller.onFinishNativeInitialization();
assertSnackbarShown();
// Dismiss the disclosure. // Dismiss the disclosure.
controller.onAction(storage); mModel.get(DISCLOSURE_EVENTS_CALLBACK).onDisclosureAccepted();
// Simulate resuming or starting again this time no disclosure should show. assertSnackbarAccepted();
assertFalse(storage.shouldShowDisclosure()); assertFalse(storage.shouldShowDisclosure());
controller.onResumeWithNative();
verify(mManager, times(2)).showSnackbar(any(Snackbar.class));
storage.delete(); storage.delete();
} }
public void verifyNotShownOnExistingStorageWithoutShouldShowDisclosure(String packageName) { public void verifyNotShownOnExistingStorageWithoutShouldShowDisclosure(String packageName) {
WebappDisclosureSnackbarController controller = buildControllerForWebApk(packageName); WebappDisclosureController controller = buildControllerForWebApk(packageName);
WebappDataStorage storage = registerStorageForWebApk(packageName); WebappDataStorage storage = registerStorageForWebApk(packageName);
// Simulate that starting with existing storage will not cause the disclosure to show. // Simulate that starting with existing storage will not cause the disclosure to show.
assertFalse(storage.shouldShowDisclosure()); assertFalse(storage.shouldShowDisclosure());
controller.onDeferredStartupWithStorage(storage, false /* didCreateStorage */); controller.onDeferredStartupWithStorage(storage, false /* didCreateStorage */);
verify(mManager, times(0)).showSnackbar(any(Snackbar.class)); assertSnackbarNotShown();
storage.delete(); storage.delete();
} }
public void verifyNeverShown(String packageName) { public void verifyNeverShown(String packageName) {
WebappDisclosureSnackbarController controller = buildControllerForWebApk(packageName); WebappDisclosureController controller = buildControllerForWebApk(packageName);
WebappDataStorage storage = registerStorageForWebApk(packageName); WebappDataStorage storage = registerStorageForWebApk(packageName);
// Try to show the disclosure the first time. // Try to show the disclosure the first time.
controller.onDeferredStartupWithStorage(storage, true /* didCreateStorage */); controller.onDeferredStartupWithStorage(storage, true /* didCreateStorage */);
verify(mManager, times(0)).showSnackbar(any(Snackbar.class)); assertSnackbarNotShown();
// Try to the disclosure again this time emulating a restart or a resume. // Try to the disclosure again this time emulating a restart.
controller.onResumeWithNative(); controller.onFinishNativeInitialization();
verify(mManager, times(0)).showSnackbar(any(Snackbar.class)); assertSnackbarNotShown();
storage.delete(); storage.delete();
} }
private void assertSnackbarShown() {
assertEquals(DISCLOSURE_STATE_SHOWN, mModel.get(DISCLOSURE_STATE));
}
private void assertSnackbarAccepted() {
assertEquals(DISCLOSURE_STATE_DISMISSED_BY_USER, mModel.get(DISCLOSURE_STATE));
}
private void assertSnackbarNotShown() {
assertEquals(DISCLOSURE_STATE_NOT_SHOWN, mModel.get(DISCLOSURE_STATE));
}
@Test @Test
@Feature({"Webapps"}) @Feature({"Webapps"})
public void testUnboundWebApkShowDisclosure() { public void testUnboundWebApkShowDisclosure() {
...@@ -131,6 +159,13 @@ public class WebappDisclosureSnackbarControllerTest { ...@@ -131,6 +159,13 @@ public class WebappDisclosureSnackbarControllerTest {
verifyShownThenDismissedOnNewCreateStorage(packageName); verifyShownThenDismissedOnNewCreateStorage(packageName);
} }
@Test
@Feature({"Webapps"})
public void testUnboundWebApkShowDisclosure2() {
String packageName = "unbound";
verifyShownThenDismissedOnRestart(packageName);
}
@Test @Test
@Feature({"Webapps"}) @Feature({"Webapps"})
public void testUnboundWebApkNoDisclosureOnExistingStorage() { public void testUnboundWebApkNoDisclosureOnExistingStorage() {
......
...@@ -3508,9 +3508,6 @@ Data from your Incognito session will only be cleared from Chrome when you <ph n ...@@ -3508,9 +3508,6 @@ Data from your Incognito session will only be cleared from Chrome when you <ph n
</message> </message>
<!-- WebAPK/TWA related strings --> <!-- WebAPK/TWA related strings -->
<message name="IDS_APP_RUNNING_IN_CHROME_DISCLOSURE" desc="Message on the snackbar that indicates an app may use Chrome data.">
This app is running in Chrome
</message>
<message name="IDS_TWA_RUNNING_IN_CHROME" desc="Message on a snackbar indicating that the current Activity may use Chrome data (the rest of the app may not be)."> <message name="IDS_TWA_RUNNING_IN_CHROME" desc="Message on a snackbar indicating that the current Activity may use Chrome data (the rest of the app may not be).">
Running in Chrome Running in Chrome
</message> </message>
......
c148a3b6564ccb24297b4fbd58ba2ad983a11985
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment