| // Copyright 2014 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.util; |
| |
| import android.annotation.SuppressLint; |
| import android.annotation.TargetApi; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.content.pm.PackageManager; |
| import android.content.pm.ResolveInfo; |
| import android.os.Build; |
| import android.os.Bundle; |
| import android.os.UserManager; |
| import android.speech.RecognizerIntent; |
| |
| import org.chromium.base.ThreadUtils; |
| import org.chromium.base.VisibleForTesting; |
| import org.chromium.sync.signin.AccountManagerHelper; |
| |
| import java.util.List; |
| |
| /** |
| * A utility {@code class} meant to help determine whether or not certain features are supported by |
| * this device. |
| */ |
| public class FeatureUtilities { |
| private static Boolean sHasGoogleAccountAuthenticator; |
| private static Boolean sHasRecognitionIntentHandler; |
| |
| /** |
| * Determines whether or not the {@link RecognizerIntent#ACTION_WEB_SEARCH} {@link Intent} |
| * is handled by any {@link android.app.Activity}s in the system. The result will be cached for |
| * future calls. Passing {@code false} to {@code useCachedValue} will force it to re-query any |
| * {@link android.app.Activity}s that can process the {@link Intent}. |
| * @param context The {@link Context} to use to check to see if the {@link Intent} will |
| * be handled. |
| * @param useCachedValue Whether or not to use the cached value from a previous result. |
| * @return {@code true} if recognition is supported. {@code false} otherwise. |
| */ |
| public static boolean isRecognitionIntentPresent(Context context, boolean useCachedValue) { |
| ThreadUtils.assertOnUiThread(); |
| if (sHasRecognitionIntentHandler == null || !useCachedValue) { |
| PackageManager pm = context.getPackageManager(); |
| List<ResolveInfo> activities = pm.queryIntentActivities( |
| new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0); |
| sHasRecognitionIntentHandler = activities.size() > 0; |
| } |
| |
| return sHasRecognitionIntentHandler; |
| } |
| |
| /** |
| * Determines whether or not the user has a Google account (so we can sync) or can add one. |
| * @param context The {@link Context} that we should check accounts under. |
| * @return Whether or not sync is allowed on this device. |
| */ |
| public static boolean canAllowSync(Context context) { |
| return (hasGoogleAccountAuthenticator(context) && hasSyncPermissions(context)) || |
| hasGoogleAccounts(context); |
| } |
| |
| @VisibleForTesting |
| static boolean hasGoogleAccountAuthenticator(Context context) { |
| if (sHasGoogleAccountAuthenticator == null) { |
| AccountManagerHelper accountHelper = AccountManagerHelper.get(context); |
| sHasGoogleAccountAuthenticator = accountHelper.hasGoogleAccountAuthenticator(); |
| } |
| return sHasGoogleAccountAuthenticator; |
| } |
| |
| @VisibleForTesting |
| static boolean hasGoogleAccounts(Context context) { |
| return AccountManagerHelper.get(context).hasGoogleAccounts(); |
| } |
| |
| @SuppressLint("InlinedApi") |
| @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) |
| private static boolean hasSyncPermissions(Context context) { |
| if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) return true; |
| |
| UserManager manager = (UserManager) context.getSystemService(Context.USER_SERVICE); |
| Bundle userRestrictions = manager.getUserRestrictions(); |
| return !userRestrictions.getBoolean(UserManager.DISALLOW_MODIFY_ACCOUNTS, false); |
| } |
| |
| /** |
| * Records the current document mode state with native-side feature utilities. |
| * @param enabled Whether the document mode is enabled. |
| */ |
| public static void setDocumentModeEnabled(boolean enabled) { |
| nativeSetDocumentModeEnabled(enabled); |
| } |
| |
| private static native void nativeSetDocumentModeEnabled(boolean enabled); |
| } |