Commit 4fd275d3 authored by Finnur Thorarinsson's avatar Finnur Thorarinsson Committed by Commit Bot

[Android] Move and modularize android/banners.

This CL moves AppBanner* code from:
  chrome/android/banners
... to ...
  chrome/browser/banners/android
... and modularizes it in the process.

Bug: 1135551
Change-Id: I8773b293e55f03ca66da15551e27a06e26e2ae96
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2489917
Commit-Queue: Finnur Thorarinsson <finnur@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821646}
parent 27bfe08c
......@@ -302,6 +302,7 @@ android_library("chrome_java") {
"//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java",
"//chrome/browser/android/crypto:java",
"//chrome/browser/android/lifecycle:java",
"//chrome/browser/banners/android:java",
"//chrome/browser/browser_controls/android:java",
"//chrome/browser/contextmenu:java",
"//chrome/browser/device:java",
......@@ -802,6 +803,7 @@ junit_binary("chrome_junit_tests") {
"//chrome/android/webapk/libs/common:splash_java",
"//chrome/android/webapk/test:junit_test_support",
"//chrome/browser/android/lifecycle:java",
"//chrome/browser/banners/android:java",
"//chrome/browser/browser_controls/android:java",
"//chrome/browser/browser_controls/android:junit",
"//chrome/browser/contextmenu:java",
......@@ -1017,6 +1019,7 @@ android_library("chrome_test_java") {
"//chrome/android/webapk/libs/common:common_java",
"//chrome/browser/android/crypto:java",
"//chrome/browser/android/lifecycle:java",
"//chrome/browser/banners/android:java",
"//chrome/browser/browser_controls/android:java",
"//chrome/browser/contextmenu:java",
"//chrome/browser/device:java",
......@@ -2521,6 +2524,7 @@ chrome_test_apk_tmpl("chrome_public_test_apk") {
"//chrome/android/features/keyboard_accessory:test_java",
"//chrome/android/webapk/libs/runtime_library:runtime_library_javatests",
"//chrome/android/webapk/shell_apk:shell_apk_javatests",
"//chrome/browser/banners/android:javatests",
"//chrome/browser/download/android:download_java_tests",
"//chrome/browser/engagement/android:javatests",
"//chrome/browser/flags:javatests",
......@@ -3156,7 +3160,7 @@ generate_jni("chrome_jni_headers") {
"java/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncChromeWakeUpTask.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/ProxyNativeTask.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManagerHelper.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java",
"java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java",
"java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/InstalledWebappBridge.java",
......
......@@ -140,12 +140,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeBackgroundTaskFactory.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/ChromeNativeBackgroundTaskDelegate.java",
"java/src/org/chromium/chrome/browser/background_task_scheduler/ProxyNativeTask.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpController.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpControllerFactory.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpControllerProvider.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"java/src/org/chromium/chrome/browser/banners/AppData.java",
"java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManagerHelper.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkActivity.java",
"java/src/org/chromium/chrome/browser/bookmarks/BookmarkAddActivity.java",
......
......@@ -67,7 +67,6 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillTestRule.java",
"javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java",
"javatests/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncTest.java",
"javatests/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkBridgeTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkEditTest.java",
"javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkModelTest.java",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.banners;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.vr.VrModuleProvider;
/**
* This class is a helper class for the C++ layer. It responds whether the
* feature is supported (and facilitates testing). It was split out of
* AppBannerManager during a modularization effort because ShortcutHelper hadn't
* been modularized. Once that is done, this functionality can move back into
* AppBannerManager.
*/
@JNINamespace("banners")
public class AppBannerManagerHelper {
/** Whether add to home screen is permitted by the system. */
private static Boolean sIsSupported;
/**
* Checks if the add to home screen intent is supported.
* @return true if add to home screen is supported, false otherwise.
*/
public static boolean isSupported() {
// TODO(mthiesse, https://crbug.com/840811): Support the app banner dialog in VR.
if (VrModuleProvider.getDelegate().isInVr()) return false;
if (sIsSupported == null) {
sIsSupported = ShortcutHelper.isAddToHomeIntentSupported();
}
return sIsSupported;
}
/**
* Checks if app banners are enabled for the tab which this manager is attached to.
* @return true if app banners can be shown for this tab, false otherwise.
*/
@CalledByNative
private static boolean isEnabledForTab() {
return isSupported();
}
/** Overrides whether the system supports add to home screen. Used in testing. */
@VisibleForTesting
public static void setIsSupported(boolean state) {
sIsSupported = state;
}
}
......@@ -46,6 +46,7 @@ import org.chromium.chrome.browser.crash.MinidumpUploadServiceImpl;
import org.chromium.chrome.browser.download.DownloadController;
import org.chromium.chrome.browser.download.DownloadManagerService;
import org.chromium.chrome.browser.download.OfflineContentAvailabilityStatusProvider;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.firstrun.ForcedSigninProcessor;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
......@@ -214,6 +215,7 @@ public class ProcessInitializationHandler {
ChromeActivitySessionTracker.getInstance().initializeWithNative();
ProfileManagerUtils.removeSessionCookiesForAllProfiles();
AppBannerManager.setAppDetailsDelegate(AppHooks.get().createAppDetailsDelegate());
AppBannerManager.setTrackerFromProfileFactory(TrackerFactory::getTrackerForProfile);
ChromeLifetimeController.initialize();
Clipboard.getInstance().setImageFileProvider(new ClipboardImageFileProvider());
......
......@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutManager;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager;
import org.chromium.chrome.browser.datareduction.DataReductionPromoScreen;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.fullscreen.BrowserControlsManager;
......@@ -328,7 +329,9 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
mAppBannerInProductHelpController =
AppBannerInProductHelpControllerFactory.createAppBannerInProductHelpController(
mActivity, mAppMenuCoordinator.getAppMenuHandler(),
() -> mActivity.getToolbarManager().getMenuButtonView());
()
-> mActivity.getToolbarManager().getMenuButtonView(),
R.id.add_to_homescreen_id, TrackerFactory::getTrackerForProfile);
AppBannerInProductHelpControllerFactory.attach(
mActivity.getWindowAndroid(), mAppBannerInProductHelpController);
}
......
file://chrome/browser/banners/OWNERS
# COMPONENT: UI>Browser>WebAppInstalls
......@@ -3123,6 +3123,7 @@ static_library("browser") {
"//chrome/android:jni_headers",
"//chrome/android/modules/extra_icu/provider:native",
"//chrome/browser/android/webapk:proto",
"//chrome/browser/banners/android:jni_headers",
"//chrome/browser/endpoint_fetcher:jni_headers",
"//chrome/browser/flags:flags_android",
"//chrome/browser/notifications/chime/android",
......
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
android_library("java") {
sources = [
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpController.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpControllerFactory.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerInProductHelpControllerProvider.java",
"java/src/org/chromium/chrome/browser/banners/AppBannerManager.java",
"java/src/org/chromium/chrome/browser/banners/AppData.java",
"java/src/org/chromium/chrome/browser/banners/AppDetailsDelegate.java",
]
deps = [
":java_resources",
":jni_headers",
"//base:base_java",
"//base:jni_java",
"//chrome/android:chrome_jni_headers",
"//chrome/browser/profiles/android:java",
"//chrome/browser/tab:java",
"//chrome/browser/ui/android/appmenu:java",
"//chrome/browser/user_education:java",
"//components/feature_engagement/public:public_java",
"//content/public/android:content_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//ui/android:ui_no_recycler_view_java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
resources_package = "org.chromium.chrome.browser.banners"
}
android_resources("java_resources") {
deps = [
"//chrome/browser/ui/android/strings:ui_strings_grd",
"//components/browser_ui/strings/android:browser_ui_strings_grd",
]
}
generate_jni("jni_headers") {
sources =
[ "java/src/org/chromium/chrome/browser/banners/AppBannerManager.java" ]
}
android_library("javatests") {
testonly = true
sources = [
"java/src/org/chromium/chrome/browser/banners/AppBannerManagerTest.java",
]
deps = [
":java",
"//base:base_java",
"//base:base_java_test_support",
"//chrome/android:chrome_java",
"//chrome/android:chrome_test_java",
"//chrome/android:chrome_test_util_java",
"//chrome/browser/engagement/android:java",
"//chrome/browser/flags:java",
"//chrome/browser/profiles/android:java",
"//chrome/browser/tab:java",
"//chrome/browser/ui/android/appmenu/test:test_support_java",
"//chrome/test/android:chrome_java_test_support",
"//components/feature_engagement/public:public_java",
"//components/infobars/android:java",
"//components/signin/core/browser/android:java",
"//components/signin/core/browser/android:signin_java_test_support",
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//net/android:net_java_test_support",
"//third_party/android_deps:androidx_test_runner_java",
"//third_party/android_deps:espresso_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/hamcrest:hamcrest_java",
"//third_party/junit:junit",
"//third_party/mockito:mockito_java",
"//third_party/ub-uiautomator:ub_uiautomator_java",
"//ui/android:ui_full_java",
]
}
include_rules = [
"+components/infobars/android/java/src/org/chromium/components/infobars/InfoBar.java",
"+components/infobars/android/java/src/org/chromium/components/infobars/InfoBarAnimationListener.java",
"+components/infobars/android/java/src/org/chromium/components/infobars/InfoBarUiItem.java",
"+content/public/android/java/src/org/chromium/content_public/browser/UiThreadTaskTraits.java",
"+content/public/android/java/src/org/chromium/content_public/browser/WebContents.java",
"+content/public/android/java/src/org/chromium/content_public/common/ContentUrlConstants.java"
]
......@@ -8,14 +8,17 @@ import android.app.Activity;
import android.os.Handler;
import android.view.View;
import androidx.annotation.IdRes;
import org.chromium.base.Function;
import org.chromium.base.UnownedUserData;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
import org.chromium.chrome.browser.user_education.IPHCommandBuilder;
import org.chromium.chrome.browser.user_education.UserEducationHelper;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.components.feature_engagement.Tracker;
/**
* This class is responsible for managing the in-product help for the PWA app banners.
......@@ -26,20 +29,25 @@ public class AppBannerInProductHelpController implements UnownedUserData {
private final Supplier<View> mMenuButtonView;
private final Handler mHandler = new Handler();
private final UserEducationHelper mUserEducationHelper;
private final @IdRes int mHiglightMenuItemId;
/**
* Constructs an AppBannerInProductHelpController.
* @param activity The current activity.
* @param appMenuHandler The app menu containing the menu entry to highlight.
* @param menuButtonView The menu button view to anchor the bubble to.
* @param higlightMenuItemId The id of the menu item to highlight.
* @param trackerFromProfileFactory The factory to obtain a tracker from.
*/
public AppBannerInProductHelpController(
Activity activity, AppMenuHandler appMenuHandler, Supplier<View> menuButtonView) {
public AppBannerInProductHelpController(Activity activity, AppMenuHandler appMenuHandler,
Supplier<View> menuButtonView, @IdRes int higlightMenuItemId,
Function<Profile, Tracker> trackerFromProfileFactory) {
mActivity = activity;
mAppMenuHandler = appMenuHandler;
mMenuButtonView = menuButtonView;
mHiglightMenuItemId = higlightMenuItemId;
mUserEducationHelper =
new UserEducationHelper(mActivity, mHandler, TrackerFactory::getTrackerForProfile);
new UserEducationHelper(mActivity, mHandler, trackerFromProfileFactory);
}
/**
......@@ -57,7 +65,7 @@ public class AppBannerInProductHelpController implements UnownedUserData {
}
private void turnOnHighlightForMenu() {
mAppMenuHandler.setMenuHighlight(R.id.add_to_homescreen_id, true);
mAppMenuHandler.setMenuHighlight(mHiglightMenuItemId, true);
}
private void turnOffHighlightForMenu() {
......
......@@ -7,8 +7,13 @@ package org.chromium.chrome.browser.banners;
import android.app.Activity;
import android.view.View;
import androidx.annotation.IdRes;
import org.chromium.base.Function;
import org.chromium.base.supplier.Supplier;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.ui.base.WindowAndroid;
/**
......@@ -16,8 +21,10 @@ import org.chromium.ui.base.WindowAndroid;
*/
public class AppBannerInProductHelpControllerFactory {
public static AppBannerInProductHelpController createAppBannerInProductHelpController(
Activity activity, AppMenuHandler appMenuHandler, Supplier<View> menuButtonView) {
return new AppBannerInProductHelpController(activity, appMenuHandler, menuButtonView);
Activity activity, AppMenuHandler appMenuHandler, Supplier<View> menuButtonView,
@IdRes int higlightMenuItemId, Function<Profile, Tracker> trackerFromProfileFactory) {
return new AppBannerInProductHelpController(activity, appMenuHandler, menuButtonView,
higlightMenuItemId, trackerFromProfileFactory);
}
public static void attach(
......
......@@ -11,16 +11,13 @@ import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.ContextUtils;
import org.chromium.base.Function;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ShortcutHelper;
import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.vr.VrModuleProvider;
import org.chromium.components.feature_engagement.FeatureConstants;
import org.chromium.components.feature_engagement.Tracker;
import org.chromium.content_public.browser.WebContents;
......@@ -62,34 +59,11 @@ public class AppBannerManager {
/** Retrieves information about a given package. */
private static AppDetailsDelegate sAppDetailsDelegate;
/** Whether add to home screen is permitted by the system. */
private static Boolean sIsSupported;
private static Function<Profile, Tracker> sTrackerFromProfileFactory;
/** Pointer to the native side AppBannerManager. */
private long mNativePointer;
/**
* Checks if the add to home screen intent is supported.
* @return true if add to home screen is supported, false otherwise.
*/
public static boolean isSupported() {
// TODO(mthiesse, https://crbug.com/840811): Support the app banner dialog in VR.
if (VrModuleProvider.getDelegate().isInVr()) return false;
if (sIsSupported == null) {
sIsSupported = ShortcutHelper.isAddToHomeIntentSupported();
}
return sIsSupported;
}
/**
* Checks if app banners are enabled for the tab which this manager is attached to.
* @return true if app banners can be shown for this tab, false otherwise.
*/
@CalledByNative
private boolean isEnabledForTab() {
return isSupported();
}
/**
* Sets the delegate that provides information about a given package.
* @param delegate Delegate to use. Previously set ones are destroyed.
......@@ -99,6 +73,15 @@ public class AppBannerManager {
sAppDetailsDelegate = delegate;
}
/**
* Sets the factory to obtain a Tracker from.
* @param trackerFromProfileFactory The factory to use.
*/
public static void setTrackerFromProfileFactory(
Function<Profile, Tracker> trackerFromProfileFactory) {
sTrackerFromProfileFactory = trackerFromProfileFactory;
}
/**
* Constructs an AppBannerManager.
* @param nativePointer the native-side object that owns this AppBannerManager.
......@@ -128,8 +111,8 @@ public class AppBannerManager {
if (sAppDetailsDelegate == null) return;
Context context = ContextUtils.getApplicationContext();
int iconSizeInPx = Math.round(
context.getResources().getDisplayMetrics().density * iconSizeInDp);
int iconSizeInPx =
Math.round(context.getResources().getDisplayMetrics().density * iconSizeInDp);
sAppDetailsDelegate.getAppDetailsAsynchronously(
createAppDetailsObserver(), url, packageName, referrer, iconSizeInPx);
}
......@@ -142,7 +125,8 @@ public class AppBannerManager {
@CalledByNative
private String showInProductHelp(WebContents webContents) {
// Consult the tracker to see if the IPH can be shown.
Tracker tracker = TrackerFactory.getTrackerForProfile(Profile.fromWebContents(webContents));
final Tracker tracker =
sTrackerFromProfileFactory.apply(Profile.fromWebContents(webContents));
if (!tracker.wouldTriggerHelpUI(FeatureConstants.PWA_INSTALL_AVAILABLE_FEATURE)) {
// Tracker replied that the request to show will not be honored. Return whether the
// limit of how often to show has been exceeded.
......@@ -190,12 +174,6 @@ public class AppBannerManager {
}
}
/** Overrides whether the system supports add to home screen. Used in testing. */
@VisibleForTesting
public static void setIsSupported(boolean state) {
sIsSupported = state;
}
/** Sets the app-banner-showing logic to ignore the Chrome channel. */
@VisibleForTesting
public static void ignoreChromeChannelForTesting() {
......
......@@ -217,7 +217,7 @@ public class AppBannerManagerTest {
@Before
public void setUp() throws Exception {
AppBannerManager.setIsSupported(true);
AppBannerManagerHelper.setIsSupported(true);
ShortcutHelper.setDelegateForTests(new ShortcutHelper.Delegate() {
@Override
public void addShortcutToHomescreen(
......
......@@ -13,7 +13,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/android/chrome_jni_headers/AppBannerManager_jni.h"
#include "chrome/android/chrome_jni_headers/AppBannerManagerHelper_jni.h"
#include "chrome/browser/android/shortcut_helper.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/android/tab_web_contents_delegate_android.h"
......@@ -23,6 +23,7 @@
#include "chrome/browser/android/webapk/webapk_web_manifest_checker.h"
#include "chrome/browser/android/webapps/add_to_homescreen_coordinator.h"
#include "chrome/browser/android/webapps/add_to_homescreen_params.h"
#include "chrome/browser/banners/android/jni_headers/AppBannerManager_jni.h"
#include "chrome/browser/banners/app_banner_metrics.h"
#include "chrome/browser/banners/app_banner_settings_helper.h"
#include "chrome/browser/feature_engagement/tracker_factory.h"
......@@ -136,7 +137,7 @@ bool AppBannerManagerAndroid::OnAppDetailsRetrieved(
void AppBannerManagerAndroid::RequestAppBanner(const GURL& validated_url) {
JNIEnv* env = base::android::AttachCurrentThread();
if (!Java_AppBannerManager_isEnabledForTab(env, java_banner_manager_))
if (!Java_AppBannerManagerHelper_isEnabledForTab(env))
return;
TabAndroid* tab = TabAndroid::FromWebContents(web_contents());
......
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