1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.chrome.browser;
6 
7 import android.content.pm.PackageInfo;
8 import android.content.pm.PackageManager;
9 
10 import androidx.annotation.Nullable;
11 import androidx.annotation.VisibleForTesting;
12 
13 import com.google.android.gms.common.ConnectionResult;
14 import com.google.android.gms.common.GoogleApiAvailability;
15 
16 import org.chromium.base.ContextUtils;
17 import org.chromium.base.annotations.CalledByNative;
18 import org.chromium.chrome.browser.banners.AppDetailsDelegate;
19 import org.chromium.chrome.browser.customtabs.CustomTabsConnection;
20 import org.chromium.chrome.browser.directactions.DirectActionCoordinator;
21 import org.chromium.chrome.browser.externalauth.ExternalAuthUtils;
22 import org.chromium.chrome.browser.feedback.FeedbackReporter;
23 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher;
24 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
25 import org.chromium.chrome.browser.gsa.GSAHelper;
26 import org.chromium.chrome.browser.historyreport.AppIndexingReporter;
27 import org.chromium.chrome.browser.init.ChromeStartupDelegate;
28 import org.chromium.chrome.browser.init.ProcessInitializationHandler;
29 import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
30 import org.chromium.chrome.browser.lens.LensController;
31 import org.chromium.chrome.browser.locale.LocaleManager;
32 import org.chromium.chrome.browser.metrics.VariationsSession;
33 import org.chromium.chrome.browser.notifications.chime.ChimeDelegate;
34 import org.chromium.chrome.browser.omaha.RequestGenerator;
35 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmark;
36 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksProviderIterator;
37 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
38 import org.chromium.chrome.browser.password_manager.GooglePasswordManagerUIProvider;
39 import org.chromium.chrome.browser.policy.PolicyAuditor;
40 import org.chromium.chrome.browser.rlz.RevenueStats;
41 import org.chromium.chrome.browser.signin.GoogleActivityController;
42 import org.chromium.chrome.browser.survey.SurveyController;
43 import org.chromium.chrome.browser.sync.TrustedVaultClient;
44 import org.chromium.chrome.browser.tab.Tab;
45 import org.chromium.chrome.browser.usage_stats.DigitalWellbeingClient;
46 import org.chromium.chrome.browser.webapps.GooglePlayWebApkInstallDelegate;
47 import org.chromium.chrome.browser.xsurface.ProcessScope;
48 import org.chromium.chrome.browser.xsurface.ProcessScopeDependencyProvider;
49 import org.chromium.chrome.modules.image_editor.ImageEditorModuleProvider;
50 import org.chromium.components.browser_ui.widget.FeatureHighlightProvider;
51 import org.chromium.components.external_intents.AuthenticatorNavigationInterceptor;
52 import org.chromium.components.policy.AppRestrictionsProvider;
53 import org.chromium.components.policy.CombinedPolicyProvider;
54 import org.chromium.components.signin.AccountManagerDelegate;
55 import org.chromium.components.signin.SystemAccountManagerDelegate;
56 
57 import java.util.Collections;
58 import java.util.List;
59 
60 /**
61  * Base class for defining methods where different behavior is required by downstream targets.
62  * The correct version of {@link AppHooksImpl} will be determined at compile time via build rules.
63  * See http://crbug/560466.
64  */
65 public abstract class AppHooks {
66     private static AppHooksImpl sInstance;
67 
68     @Nullable
69     private ExternalAuthUtils mExternalAuthUtils;
70 
71     /**
72      * Sets a mocked instance for testing.
73      */
74     @VisibleForTesting
setInstanceForTesting(AppHooksImpl instance)75     public static void setInstanceForTesting(AppHooksImpl instance) {
76         sInstance = instance;
77     }
78 
79     @CalledByNative
get()80     public static AppHooks get() {
81         if (sInstance == null) sInstance = new AppHooksImpl();
82         return sInstance;
83     }
84 
85     /**
86      * Creates a new {@link AccountManagerDelegate}.
87      * @return the created {@link AccountManagerDelegate}.
88      */
createAccountManagerDelegate()89     public AccountManagerDelegate createAccountManagerDelegate() {
90         return new SystemAccountManagerDelegate();
91     }
92 
93     /**
94      * @return An instance of AppDetailsDelegate that can be queried about app information for the
95      *         App Banner feature.  Will be null if one is unavailable.
96      */
createAppDetailsDelegate()97     public AppDetailsDelegate createAppDetailsDelegate() {
98         return null;
99     }
100 
101     /**
102      * Creates a new {@link AppIndexingReporter}.
103      * @return the created {@link AppIndexingReporter}.
104      */
createAppIndexingReporter()105     public AppIndexingReporter createAppIndexingReporter() {
106         return new AppIndexingReporter();
107     }
108 
109     /**
110      * Return a {@link AuthenticatorNavigationInterceptor} for the given {@link Tab}.
111      * This can be null if there are no applicable interceptor to be built.
112      */
createAuthenticatorNavigationInterceptor(Tab tab)113     public AuthenticatorNavigationInterceptor createAuthenticatorNavigationInterceptor(Tab tab) {
114         return null;
115     }
116 
117     /**
118      * @return An instance of {@link CustomTabsConnection}. Should not be called
119      * outside of {@link CustomTabsConnection#getInstance()}.
120      */
createCustomTabsConnection()121     public CustomTabsConnection createCustomTabsConnection() {
122         return new CustomTabsConnection();
123     }
124 
125     /**
126      * Returns a new {@link DirectActionCoordinator} instance, if available.
127      */
128     @Nullable
createDirectActionCoordinator()129     public DirectActionCoordinator createDirectActionCoordinator() {
130         return null;
131     }
132 
133     /**
134      * Creates a new {@link SurveyController}.
135      * @return The created {@link SurveyController}.
136      */
createSurveyController()137     public SurveyController createSurveyController() {
138         return new SurveyController();
139     }
140 
141     /**
142      * @return An instance of ExternalAuthUtils to be installed as a singleton.
143      */
createExternalAuthUtils()144     protected ExternalAuthUtils createExternalAuthUtils() {
145         return new ExternalAuthUtils();
146     }
147 
148     /**
149      * @return The singleton instance of ExternalAuthUtils.
150      */
getExternalAuthUtils()151     public ExternalAuthUtils getExternalAuthUtils() {
152         if (mExternalAuthUtils == null) {
153             mExternalAuthUtils = createExternalAuthUtils();
154         }
155 
156         return mExternalAuthUtils;
157     }
158 
159     /**
160      * @return An instance of {@link FeedbackReporter} to report feedback.
161      */
createFeedbackReporter()162     public FeedbackReporter createFeedbackReporter() {
163         return new FeedbackReporter() {};
164     }
165 
166     /**
167      * @return An instance of GoogleActivityController.
168      */
createGoogleActivityController()169     public GoogleActivityController createGoogleActivityController() {
170         return new GoogleActivityController();
171     }
172 
173     /**
174      * @return An instance of {@link GSAHelper} that handles the start point of chrome's integration
175      *         with GSA.
176      */
createGsaHelper()177     public GSAHelper createGsaHelper() {
178         return new GSAHelper();
179     }
180 
181     /**
182      * Returns a new instance of HelpAndFeedbackLauncher.
183      */
createHelpAndFeedbackLauncher()184     public HelpAndFeedbackLauncher createHelpAndFeedbackLauncher() {
185         return new HelpAndFeedbackLauncherImpl();
186     }
187 
createInstantAppsHandler()188     public InstantAppsHandler createInstantAppsHandler() {
189         return new InstantAppsHandler();
190     }
191 
createLensController()192     public LensController createLensController() {
193         return new LensController();
194     }
195 
196     /**
197      * @return An instance of {@link LocaleManager} that handles customized locale related logic.
198      */
createLocaleManager()199     public LocaleManager createLocaleManager() {
200         return new LocaleManager();
201     }
202 
203     /**
204      * @return An instance of {@link GooglePasswordManagerUIProvider}. Will be null if one is not
205      *         available.
206      */
createGooglePasswordManagerUIProvider()207     public GooglePasswordManagerUIProvider createGooglePasswordManagerUIProvider() {
208         return null;
209     }
210 
211     /**
212      * @return An instance of RequestGenerator to be used for Omaha XML creation.  Will be null if
213      *         a generator is unavailable.
214      */
createOmahaRequestGenerator()215     public RequestGenerator createOmahaRequestGenerator() {
216         return null;
217     }
218 
219     /**
220      * @return a new {@link ProcessInitializationHandler} instance.
221      */
createProcessInitializationHandler()222     public ProcessInitializationHandler createProcessInitializationHandler() {
223         return new ProcessInitializationHandler();
224     }
225 
226     /**
227      * @return An instance of RevenueStats to be installed as a singleton.
228      */
createRevenueStatsInstance()229     public RevenueStats createRevenueStatsInstance() {
230         return new RevenueStats();
231     }
232 
233     /**
234      * Returns a new instance of VariationsSession.
235      */
createVariationsSession()236     public VariationsSession createVariationsSession() {
237         return new VariationsSession();
238     }
239 
240     /** Returns the singleton instance of GooglePlayWebApkInstallDelegate. */
getGooglePlayWebApkInstallDelegate()241     public GooglePlayWebApkInstallDelegate getGooglePlayWebApkInstallDelegate() {
242         return null;
243     }
244 
245     /**
246      * @return An instance of PolicyAuditor that notifies the policy system of the user's activity.
247      * Only applicable when the user has a policy active, that is tracking the activity.
248      */
getPolicyAuditor()249     public PolicyAuditor getPolicyAuditor() {
250         // This class has a protected constructor to prevent accidental instantiation.
251         return new PolicyAuditor() {};
252     }
253 
registerPolicyProviders(CombinedPolicyProvider combinedProvider)254     public void registerPolicyProviders(CombinedPolicyProvider combinedProvider) {
255         combinedProvider.registerProvider(
256                 new AppRestrictionsProvider(ContextUtils.getApplicationContext()));
257     }
258 
259     /**
260      * TODO(crbug.com/1102812) : Remove this method after updating the downstream to use the new
261      * method {@link getOfflinePagesCctAllowlist} instead.
262      * @return A list of allowlisted apps that are allowed to receive notification when the
263      * set of offlined pages downloaded on their behalf has changed. Apps are listed by their
264      * package name.
265      */
getOfflinePagesCctWhitelist()266     public List<String> getOfflinePagesCctWhitelist() {
267         return Collections.emptyList();
268     }
269 
270     /**
271      * @return A list of allowlisted apps that are allowed to receive notification when the
272      * set of offlined pages downloaded on their behalf has changed. Apps are listed by their
273      * package name.
274      */
getOfflinePagesCctAllowlist()275     public List<String> getOfflinePagesCctAllowlist() {
276         return Collections.emptyList();
277     }
278 
279     /**
280      * @return A list of allowlisted app package names whose completed notifications
281      * we should suppress.
282      */
getOfflinePagesSuppressNotificationPackages()283     public List<String> getOfflinePagesSuppressNotificationPackages() {
284         return Collections.emptyList();
285     }
286 
287     /**
288      * @return An iterator of partner bookmarks.
289      */
290     @Nullable
getPartnerBookmarkIterator()291     public PartnerBookmark.BookmarkIterator getPartnerBookmarkIterator() {
292         return PartnerBookmarksProviderIterator.createIfAvailable();
293     }
294 
295     /**
296      * @return An instance of PartnerBrowserCustomizations.Provider that provides customizations
297      * specified by partners.
298      */
getCustomizationProvider()299     public PartnerBrowserCustomizations.Provider getCustomizationProvider() {
300         return new PartnerBrowserCustomizations.ProviderPackage();
301     }
302 
303     /**
304      * @return A new {@link FeatureHighlightProvider}.
305      */
createFeatureHighlightProvider()306     public FeatureHighlightProvider createFeatureHighlightProvider() {
307         return new FeatureHighlightProvider();
308     }
309 
310     /**
311      * @return A new {@link DigitalWellbeingClient} instance.
312      */
createDigitalWellbeingClient()313     public DigitalWellbeingClient createDigitalWellbeingClient() {
314         return new DigitalWellbeingClient();
315     }
316 
317     /**
318      * Checks the Google Play services availability on the this device.
319      *
320      * This is a workaround for the
321      * versioned API of {@link GoogleApiAvailability#isGooglePlayServicesAvailable()}. The current
322      * Google Play services SDK version doesn't have this API yet.
323      *
324      * TODO(zqzhang): Remove this method after the SDK is updated.
325      *
326      * @return status code indicating whether there was an error. The possible return values are the
327      * same as {@link GoogleApiAvailability#isGooglePlayServicesAvailable()}.
328      */
isGoogleApiAvailableWithMinApkVersion(int minApkVersion)329     public int isGoogleApiAvailableWithMinApkVersion(int minApkVersion) {
330         try {
331             PackageInfo gmsPackageInfo =
332                     ContextUtils.getApplicationContext().getPackageManager().getPackageInfo(
333                             GoogleApiAvailability.GOOGLE_PLAY_SERVICES_PACKAGE, /* flags= */ 0);
334             int apkVersion = gmsPackageInfo.versionCode;
335             if (apkVersion >= minApkVersion) return ConnectionResult.SUCCESS;
336         } catch (PackageManager.NameNotFoundException e) {
337             return ConnectionResult.SERVICE_MISSING;
338         }
339         return ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED;
340     }
341 
342     /**
343      * Returns a new {@link TrustedVaultClient.Backend} instance.
344      */
createSyncTrustedVaultClientBackend()345     public TrustedVaultClient.Backend createSyncTrustedVaultClientBackend() {
346         return new TrustedVaultClient.EmptyBackend();
347     }
348 
349     /**
350      * Returns a new {@link SurfaceRenderer} if the xsurface implementation is included in the
351      * apk. Otherwise null is returned.
352      */
getExternalSurfaceProcessScope( ProcessScopeDependencyProvider dependencies)353     public @Nullable ProcessScope getExternalSurfaceProcessScope(
354             ProcessScopeDependencyProvider dependencies) {
355         return null;
356     }
357 
358     /**
359      * Returns the URL to the WebAPK creation/update server.
360      */
getWebApkServerUrl()361     public String getWebApkServerUrl() {
362         return "";
363     }
364 
365     /**
366      * Returns a Chime Delegate if the chime module is defined.
367      */
getChimeDelegate()368     public ChimeDelegate getChimeDelegate() {
369         return new ChimeDelegate();
370     }
371 
getImageEditorModuleProvider()372     public @Nullable ImageEditorModuleProvider getImageEditorModuleProvider() {
373         return null;
374     }
375 
createChromeStartupDelegate()376     public ChromeStartupDelegate createChromeStartupDelegate() {
377         return new ChromeStartupDelegate();
378     }
379 }
380