diff options
9 files changed, 350 insertions, 30 deletions
diff --git a/api/system-current.txt b/api/system-current.txt index a4203497d88c..d454845fd69c 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6028,6 +6028,7 @@ package android.provider { field public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = "autofill_user_data_max_value_length"; field public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = "autofill_user_data_min_value_length"; field public static final String COMPLETED_CATEGORY_PREFIX = "suggested.completed_category."; + field public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled"; field public static final String DOZE_ALWAYS_ON = "doze_always_on"; field public static final String HUSH_GESTURE_USED = "hush_gesture_used"; field public static final String INSTANT_APPS_ENABLED = "instant_apps_enabled"; @@ -9365,6 +9366,11 @@ package android.view.contentcapture { field public static final int TYPE_VIEW_TEXT_CHANGED = 3; // 0x3 } + public final class ContentCaptureManager { + method public boolean isContentCaptureFeatureEnabled(); + method public void setContentCaptureFeatureEnabled(boolean); + } + public final class UserDataRemovalRequest implements android.os.Parcelable { method @NonNull public String getPackageName(); method @NonNull public java.util.List<android.view.contentcapture.UserDataRemovalRequest.UriRequest> getUriRequests(); diff --git a/api/test-current.txt b/api/test-current.txt index e32b71b27523..01faa2360688 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1698,6 +1698,7 @@ package android.provider { field public static final String AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE = "autofill_user_data_max_user_data_size"; field public static final String AUTOFILL_USER_DATA_MAX_VALUE_LENGTH = "autofill_user_data_max_value_length"; field public static final String AUTOFILL_USER_DATA_MIN_VALUE_LENGTH = "autofill_user_data_min_value_length"; + field public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled"; field public static final String DISABLED_PRINT_SERVICES = "disabled_print_services"; field @Deprecated public static final String ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES = "enabled_notification_policy_access_packages"; field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9721ab1aeb09..794c2f1b991b 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5688,6 +5688,14 @@ public final class Settings { "autofill_user_data_min_value_length"; /** + * Defines whether Content Capture is enabled for the user. + * @hide + */ + @SystemApi + @TestApi + public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled"; + + /** * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead */ @Deprecated diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 07c91017a3a5..fde0cedf7db7 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -15,10 +15,12 @@ */ package android.view.contentcapture; +import static android.view.contentcapture.ContentCaptureHelper.DEBUG; import static android.view.contentcapture.ContentCaptureHelper.VERBOSE; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.UiThread; import android.content.ComponentName; @@ -51,6 +53,13 @@ public final class ContentCaptureManager { private static final String TAG = ContentCaptureManager.class.getSimpleName(); + /** @hide */ + public static final int RESULT_CODE_TRUE = 1; + /** @hide */ + public static final int RESULT_CODE_FALSE = 2; + /** @hide */ + public static final int RESULT_CODE_NOT_SERVICE = -1; + /** * Timeout for calls to system_server. */ @@ -108,9 +117,7 @@ public final class ContentCaptureManager { if (mMainSession == null) { mMainSession = new MainContentCaptureSession(mContext, mHandler, mService, mDisabled); - if (VERBOSE) { - Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession); - } + if (VERBOSE) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession); } return mMainSession; } @@ -147,13 +154,9 @@ public final class ContentCaptureManager { */ @Nullable public ComponentName getServiceComponentName() { - if (!isContentCaptureEnabled()) { - return null; - } - // Wait for system server to return the component name. - final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); - + if (!isContentCaptureEnabled()) return null; + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { mService.getServiceComponentName(resultReceiver); return resultReceiver.getParcelableResult(); @@ -164,6 +167,17 @@ public final class ContentCaptureManager { /** * Checks whether content capture is enabled for this activity. + * + * <p>There are many reasons it could be disabled, such as: + * <ul> + * <li>App itself disabled content capture through {@link #setContentCaptureEnabled(boolean)}. + * <li>Service disabled content capture for this specific activity. + * <li>Service disabled content capture for all activities of this package. + * <li>Service disabled content capture globally. + * <li>User disabled content capture globally (through Settings). + * <li>OEM disabled content capture globally. + * <li>Transient errors. + * </ul> */ public boolean isContentCaptureEnabled() { synchronized (mLock) { @@ -178,12 +192,82 @@ public final class ContentCaptureManager { * it on {@link android.app.Activity#onCreate(android.os.Bundle, android.os.PersistableBundle)}. */ public void setContentCaptureEnabled(boolean enabled) { + if (DEBUG) { + Log.d(TAG, "setContentCaptureEnabled(): setting to " + enabled + " for " + mContext); + } + synchronized (mLock) { mFlags |= enabled ? 0 : ContentCaptureContext.FLAG_DISABLED_BY_APP; } } /** + * Gets whether Content Capture is enabled for the given user. + * + * <p>This method is typically used by the Content Capture Service settings page, so it can + * provide a toggle to enable / disable it. + * + * @throws SecurityException if caller is not the app that owns the Content Capture service + * associated with the user. + * + * @hide + */ + @SystemApi + public boolean isContentCaptureFeatureEnabled() { + if (mService == null) return false; + + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); + final int resultCode; + try { + mService.isContentCaptureFeatureEnabled(resultReceiver); + resultCode = resultReceiver.getIntResult(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + switch (resultCode) { + case RESULT_CODE_TRUE: + return true; + case RESULT_CODE_FALSE: + return false; + case RESULT_CODE_NOT_SERVICE: + throw new SecurityException("caller is not user's ContentCapture service"); + default: + throw new IllegalStateException("received invalid result: " + resultCode); + } + } + + /** + * Sets whether Content Capture is enabled for the given user. + * + * @throws SecurityException if caller is not the app that owns the Content Capture service + * associated with the user. + * + * @hide + */ + @SystemApi + public void setContentCaptureFeatureEnabled(boolean enabled) { + if (DEBUG) Log.d(TAG, "setContentCaptureFeatureEnabled(): setting to " + enabled); + + final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); + final int resultCode; + try { + mService.setContentCaptureFeatureEnabled(enabled, resultReceiver); + resultCode = resultReceiver.getIntResult(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + switch (resultCode) { + case RESULT_CODE_TRUE: + // Our work is done here, in our void existance... + return; + case RESULT_CODE_NOT_SERVICE: + throw new SecurityException("caller is not user's ContentCapture service"); + default: + throw new IllegalStateException("received invalid result: " + resultCode); + } + } + + /** * Called by the app to request the Content Capture service to remove user-data associated with * some context. * diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index c425e7bd3700..e6ee6ed6c55f 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -99,7 +99,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { public static final int STATE_FLAG_SECURE = 0x20; /** - * Session is disabled manually by the specific app. + * Session is disabled manually by the specific app + * (through {@link ContentCaptureManager#setContentCaptureEnabled(boolean)}). * * @hide */ diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl index 56ed8bfab9ad..26cf34c1b88e 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -62,4 +62,14 @@ oneway interface IContentCaptureManager { * Requests the removal of user data for the calling user. */ void removeUserData(in UserDataRemovalRequest request); + + /** + * Returns whether the content capture feature is enabled for the calling user. + */ + void isContentCaptureFeatureEnabled(in IResultReceiver result); + + /** + * Sets whether the content capture feature is enabled for the given user. + */ + void setContentCaptureFeatureEnabled(boolean enabled, in IResultReceiver result); } diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index ca2a10614c54..0b5bde767ac9 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -608,6 +608,7 @@ public class SettingsBackupTest { Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG, Settings.Secure.COMPLETED_CATEGORY_PREFIX, Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, + Settings.Secure.CONTENT_CAPTURE_ENABLED, Settings.Secure.DEFAULT_INPUT_METHOD, Settings.Secure.DEVICE_PAIRED, Settings.Secure.DIALER_DEFAULT_APPLICATION, diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 6108aaa860d5..75ee99f8d911 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java @@ -20,10 +20,16 @@ import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE; import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManagerInternal; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.UserInfo; +import android.database.ContentObserver; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; @@ -32,8 +38,11 @@ import android.os.ResultReceiver; import android.os.ShellCallback; import android.os.UserHandle; import android.os.UserManager; +import android.provider.Settings; import android.util.LocalLog; import android.util.Slog; +import android.util.SparseBooleanArray; +import android.view.contentcapture.ContentCaptureManager; import android.view.contentcapture.IContentCaptureManager; import android.view.contentcapture.UserDataRemovalRequest; @@ -49,6 +58,7 @@ import com.android.server.infra.FrameworkResourcesServiceNameResolver; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; /** * A service used to observe the contents of the screen. @@ -60,23 +70,43 @@ import java.util.ArrayList; public final class ContentCaptureManagerService extends AbstractMasterSystemService<ContentCaptureManagerService, ContentCapturePerUserService> { - private static final String TAG = ContentCaptureManagerService.class.getSimpleName(); - static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions"; private static final int MAX_TEMP_SERVICE_DURATION_MS = 1_000 * 60 * 2; // 2 minutes + private final LocalService mLocalService = new LocalService(); + + private final LocalLog mRequestsHistory = new LocalLog(20); + @GuardedBy("mLock") private ActivityManagerInternal mAm; - private final LocalService mLocalService = new LocalService(); + /** + * Users disabled by {@link android.provider.Settings.Secure#CONTENT_CAPTURE_ENABLED}. + */ + @GuardedBy("mLock") + @Nullable + private SparseBooleanArray mDisabledUsers; - private final LocalLog mRequestsHistory = new LocalLog(20); public ContentCaptureManagerService(@NonNull Context context) { super(context, new FrameworkResourcesServiceNameResolver(context, com.android.internal.R.string.config_defaultContentCaptureService), UserManager.DISALLOW_CONTENT_CAPTURE); + // Sets which serviecs are disabled + final UserManager um = getContext().getSystemService(UserManager.class); + final List<UserInfo> users = um.getUsers(); + for (int i = 0; i < users.size(); i++) { + final int userId = users.get(i).id; + final boolean disabled = isDisabledBySettings(userId); + if (disabled) { + Slog.i(mTag, "user " + userId + " disabled by settings"); + if (mDisabledUsers == null) { + mDisabledUsers = new SparseBooleanArray(1); + } + mDisabledUsers.put(userId, true); + } + } } @Override // from AbstractMasterSystemService @@ -100,7 +130,7 @@ public final class ContentCaptureManagerService extends @Override // from AbstractMasterSystemService protected void enforceCallingPermissionForManagement() { - getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, TAG); + getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag); } @Override // from AbstractMasterSystemService @@ -108,9 +138,86 @@ public final class ContentCaptureManagerService extends return MAX_TEMP_SERVICE_DURATION_MS; } + @Override // from AbstractMasterSystemService + protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver, + @NonNull ContentObserver observer) { + resolver.registerContentObserver(Settings.Secure.getUriFor( + Settings.Secure.CONTENT_CAPTURE_ENABLED), false, observer, + UserHandle.USER_ALL); + } + + @Override // from AbstractMasterSystemService + protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) { + switch (property) { + case Settings.Secure.CONTENT_CAPTURE_ENABLED: + setContentCaptureFeatureEnabledFromSettings(userId); + return; + default: + Slog.w(mTag, "Unexpected property (" + property + "); updating cache instead"); + } + } + + @Override // from AbstractMasterSystemService + protected boolean isDisabledLocked(@UserIdInt int userId) { + return isDisabledBySettingsLocked(userId) || super.isDisabledLocked(userId); + } + + private boolean isDisabledBySettingsLocked(@UserIdInt int userId) { + return mDisabledUsers != null && mDisabledUsers.get(userId); + } + + private void setContentCaptureFeatureEnabledFromSettings(@UserIdInt int userId) { + setContentCaptureFeatureEnabledForUser(userId, !isDisabledBySettings(userId)); + } + + private boolean isDisabledBySettings(@UserIdInt int userId) { + final String property = Settings.Secure.CONTENT_CAPTURE_ENABLED; + final String value = Settings.Secure.getStringForUser(getContext().getContentResolver(), + property, userId); + if (value == null) { + if (verbose) { + Slog.v(mTag, "isDisabledBySettings(): assuming false as '" + property + + "' is not set"); + } + return false; + } + + try { + return !Boolean.valueOf(value); + } catch (Exception e) { + Slog.w(mTag, "Invalid value for property " + property + ": " + value); + } + return false; + } + + private void setContentCaptureFeatureEnabledForUser(@UserIdInt int userId, boolean enabled) { + synchronized (mLock) { + if (mDisabledUsers == null) { + mDisabledUsers = new SparseBooleanArray(); + } + final boolean alreadyEnabled = !mDisabledUsers.get(userId); + if (!(enabled ^ alreadyEnabled)) { + if (debug) { + Slog.d(mTag, "setContentCaptureFeatureEnabledForUser(): already " + enabled); + } + return; + } + if (enabled) { + Slog.i(mTag, "setContentCaptureFeatureEnabled(): enabling service for user " + + userId); + mDisabledUsers.delete(userId); + } else { + Slog.i(mTag, "setContentCaptureFeatureEnabled(): disabling service for user " + + userId); + mDisabledUsers.put(userId, true); + } + updateCachedServiceLocked(userId, !enabled); + } + } + // Called by Shell command. void destroySessions(@UserIdInt int userId, @NonNull IResultReceiver receiver) { - Slog.i(TAG, "destroySessions() for userId " + userId); + Slog.i(mTag, "destroySessions() for userId " + userId); enforceCallingPermissionForManagement(); synchronized (mLock) { @@ -133,7 +240,7 @@ public final class ContentCaptureManagerService extends // Called by Shell command. void listSessions(int userId, IResultReceiver receiver) { - Slog.i(TAG, "listSessions() for userId " + userId); + Slog.i(mTag, "listSessions() for userId " + userId); enforceCallingPermissionForManagement(); final Bundle resultData = new Bundle(); @@ -174,6 +281,64 @@ public final class ContentCaptureManagerService extends return mAm; } + @GuardedBy("mLock") + private boolean assertCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId, + int callingUid, @NonNull IResultReceiver result) { + final boolean isService = isCalledByServiceLocked(methodName, userId, callingUid); + if (isService) return true; + + try { + result.send(ContentCaptureManager.RESULT_CODE_NOT_SERVICE, + /* resultData= */ null); + } catch (RemoteException e) { + Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e); + } + return false; + } + + @GuardedBy("mLock") + private boolean isCalledByServiceLocked(@NonNull String methodName, @UserIdInt int userId, + int callingUid) { + + final String serviceName = mServiceNameResolver.getServiceName(userId); + if (serviceName == null) { + Slog.e(mTag, methodName + ": called by UID " + callingUid + + ", but there's no service set for user " + userId); + return false; + } + + final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName); + if (serviceComponent == null) { + Slog.w(mTag, methodName + ": invalid service name: " + serviceName); + return false; + } + + final String servicePackageName = serviceComponent.getPackageName(); + + final PackageManager pm = getContext().getPackageManager(); + final int serviceUid; + try { + serviceUid = pm.getPackageUidAsUser(servicePackageName, UserHandle.getCallingUserId()); + } catch (NameNotFoundException e) { + Slog.w(mTag, methodName + ": could not verify UID for " + serviceName); + return false; + } + if (callingUid != serviceUid) { + Slog.e(mTag, methodName + ": called by UID " + callingUid + ", but service UID is " + + serviceUid); + return false; + } + + return true; + } + + @Override // from AbstractMasterSystemService + protected void dumpLocked(String prefix, PrintWriter pw) { + super.dumpLocked(prefix, pw); + + pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); + } + final class ContentCaptureManagerServiceStub extends IContentCaptureManager.Stub { @Override @@ -222,8 +387,7 @@ public final class ContentCaptureManagerService extends result.send(/* resultCode= */ 0, SyncResultReceiver.bundleFor(connectedServiceComponentName)); } catch (RemoteException e) { - // Ignore exception as we need to be resilient against app behavior. - Slog.w(TAG, "Unable to send service component name: " + e); + Slog.w(mTag, "Unable to send service component name: " + e); } } @@ -238,8 +402,52 @@ public final class ContentCaptureManagerService extends } @Override + public void isContentCaptureFeatureEnabled(@NonNull IResultReceiver result) { + final int userId = UserHandle.getCallingUserId(); + boolean enabled; + synchronized (mLock) { + final boolean isService = assertCalledByServiceLocked( + "isContentCaptureFeatureEnabled()", userId, Binder.getCallingUid(), result); + if (!isService) return; + + enabled = !isDisabledBySettingsLocked(userId); + } + try { + result.send(enabled ? ContentCaptureManager.RESULT_CODE_TRUE + : ContentCaptureManager.RESULT_CODE_FALSE, /* resultData= */null); + } catch (RemoteException e) { + Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e); + } + } + + @Override + public void setContentCaptureFeatureEnabled(boolean enabled, + @NonNull IResultReceiver result) { + final int userId = UserHandle.getCallingUserId(); + final boolean isService; + synchronized (mLock) { + isService = assertCalledByServiceLocked("setContentCaptureFeatureEnabled()", userId, + Binder.getCallingUid(), result); + } + if (!isService) return; + + final long token = Binder.clearCallingIdentity(); + try { + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.CONTENT_CAPTURE_ENABLED, Boolean.toString(enabled), userId); + } finally { + Binder.restoreCallingIdentity(token); + } + try { + result.send(ContentCaptureManager.RESULT_CODE_TRUE, /* resultData= */null); + } catch (RemoteException e) { + Slog.w(mTag, "Unable to send setContentCaptureFeatureEnabled(): " + e); + } + } + + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; + if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return; boolean showHistory = true; if (args != null) { @@ -252,7 +460,7 @@ public final class ContentCaptureManagerService extends pw.println("Usage: dumpsys content_capture [--no-history]"); return; default: - Slog.w(TAG, "Ignoring invalid dump arg: " + arg); + Slog.w(mTag, "Ignoring invalid dump arg: " + arg); } } } diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java index 8e26097cd55d..532aa01f4438 100644 --- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java +++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java @@ -117,7 +117,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem */ @GuardedBy("mLock") @Nullable - private final SparseBooleanArray mDisabledUsers; + private final SparseBooleanArray mDisabledByUserRestriction; /** * Cache of services per user id. @@ -148,9 +148,9 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } if (disallowProperty == null) { - mDisabledUsers = null; + mDisabledByUserRestriction = null; } else { - mDisabledUsers = new SparseBooleanArray(); + mDisabledByUserRestriction = new SparseBooleanArray(); // Hookup with UserManager to disable service when necessary. final UserManager um = context.getSystemService(UserManager.class); final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); @@ -159,15 +159,15 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem final int userId = users.get(i).id; final boolean disabled = umi.getUserRestriction(userId, disallowProperty); if (disabled) { - Slog.i(mTag, "Disabling for user " + userId); - mDisabledUsers.put(userId, disabled); + Slog.i(mTag, "Disabling by restrictions user " + userId); + mDisabledByUserRestriction.put(userId, disabled); } } umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> { final boolean disabledNow = newRestrictions.getBoolean(disallowProperty, false); synchronized (mLock) { - final boolean disabledBefore = mDisabledUsers.get(userId); + final boolean disabledBefore = mDisabledByUserRestriction.get(userId); if (disabledBefore == disabledNow) { // Nothing changed, do nothing. if (debug) { @@ -176,7 +176,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } } Slog.i(mTag, "Updating for user " + userId + ": disabled=" + disabledNow); - mDisabledUsers.put(userId, disabledNow); + mDisabledByUserRestriction.put(userId, disabledNow); updateCachedServiceLocked(userId, disabledNow); } }); @@ -414,7 +414,7 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem * given user. */ protected boolean isDisabledLocked(@UserIdInt int userId) { - return mDisabledUsers == null ? false : mDisabledUsers.get(userId); + return mDisabledByUserRestriction == null ? false : mDisabledByUserRestriction.get(userId); } /** @@ -523,7 +523,8 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem mServiceNameResolver.dumpShort(pw, userId); pw.println(); } } - pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers); + pw.print(prefix); pw.print("Users disabled by restriction: "); + pw.println(mDisabledByUserRestriction); pw.print(prefix); pw.print("Allow instant service: "); pw.println(mAllowInstantService); final String settingsProperty = getServiceSettingsProperty(); if (settingsProperty != null) { |