summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/system-current.txt6
-rw-r--r--api/test-current.txt1
-rw-r--r--core/java/android/provider/Settings.java8
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java102
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureSession.java3
-rw-r--r--core/java/android/view/contentcapture/IContentCaptureManager.aidl10
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java230
-rw-r--r--services/core/java/com/android/server/infra/AbstractMasterSystemService.java19
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) {