blob: 422d51b69e2d72c495524f5ad8ead7a9ac6f093e [file] [log] [blame]
// 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);
}