1 // Copyright 2014 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.
5 package org.chromium.chrome.browser.util;
7 import android.annotation.SuppressLint;
8 import android.annotation.TargetApi;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.pm.PackageManager;
12 import android.content.pm.ResolveInfo;
13 import android.os.Build;
14 import android.os.Bundle;
15 import android.os.UserManager;
16 import android.speech.RecognizerIntent;
18 import org.chromium.base.ThreadUtils;
19 import org.chromium.base.VisibleForTesting;
20 import org.chromium.sync.signin.AccountManagerHelper;
22 import java.util.List;
25 * A utility {@code class} meant to help determine whether or not certain features are supported by
28 public class FeatureUtilities {
29 private static Boolean sHasGoogleAccountAuthenticator;
30 private static Boolean sHasRecognitionIntentHandler;
33 * Determines whether or not the {@link RecognizerIntent#ACTION_WEB_SEARCH} {@link Intent}
34 * is handled by any {@link android.app.Activity}s in the system. The result will be cached for
35 * future calls. Passing {@code false} to {@code useCachedValue} will force it to re-query any
36 * {@link android.app.Activity}s that can process the {@link Intent}.
37 * @param context The {@link Context} to use to check to see if the {@link Intent} will
39 * @param useCachedValue Whether or not to use the cached value from a previous result.
40 * @return {@code true} if recognition is supported. {@code false} otherwise.
42 public static boolean isRecognitionIntentPresent(Context context, boolean useCachedValue) {
43 ThreadUtils.assertOnUiThread();
44 if (sHasRecognitionIntentHandler == null || !useCachedValue) {
45 PackageManager pm = context.getPackageManager();
46 List<ResolveInfo> activities = pm.queryIntentActivities(
47 new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
48 sHasRecognitionIntentHandler = activities.size() > 0;
51 return sHasRecognitionIntentHandler;
55 * Determines whether or not the user has a Google account (so we can sync) or can add one.
56 * @param context The {@link Context} that we should check accounts under.
57 * @return Whether or not sync is allowed on this device.
59 public static boolean canAllowSync(Context context) {
60 return (hasGoogleAccountAuthenticator(context) && hasSyncPermissions(context)) ||
61 hasGoogleAccounts(context);
65 static boolean hasGoogleAccountAuthenticator(Context context) {
66 if (sHasGoogleAccountAuthenticator == null) {
67 AccountManagerHelper accountHelper = AccountManagerHelper.get(context);
68 sHasGoogleAccountAuthenticator = accountHelper.hasGoogleAccountAuthenticator();
70 return sHasGoogleAccountAuthenticator;
74 static boolean hasGoogleAccounts(Context context) {
75 return AccountManagerHelper.get(context).hasGoogleAccounts();
78 @SuppressLint("InlinedApi")
79 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
80 private static boolean hasSyncPermissions(Context context) {
81 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return true;
83 UserManager manager = (UserManager) context.getSystemService(Context.USER_SERVICE);
84 Bundle userRestrictions = manager.getUserRestrictions();
85 return !userRestrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false);
89 * Records the current document mode state with native-side feature utilities.
90 * @param enabled Whether the document mode is enabled.
92 public static void setDocumentModeEnabled(boolean enabled) {
93 nativeSetDocumentModeEnabled(enabled);
96 private static native void nativeSetDocumentModeEnabled(boolean enabled);