Fixed ContentCaptureManager.isContentCaptureEnabled() when main session is disabled.
Each ContentCaptureManager has a MainContentCaptureSession associated with, and the main session
has a mDisabled state that's set to true when it failed to start (for example, because there's no
service associated with the user). Both objects used to share a common AtomicBoolean for the
disabled state, but a recent refactoring split then in a way that the manager's mDisabled was never
updated.
Test: atest ChildlessActivityTest#testGetContentCapture_enabledWhenNoService
Test: atest CtsContentCaptureServiceTestCases # sanityCheck
Bug: 123579223
Bug: 123307965
Bug: 123658889
Change-Id: Ib1f08f23721f208b28d0f339f39b21262b55e30d
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index fde0ced..f31856c 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -67,9 +67,6 @@
private final Object mLock = new Object();
- @GuardedBy("mLock")
- private boolean mDisabled;
-
@NonNull
private final Context mContext;
@@ -115,8 +112,7 @@
public MainContentCaptureSession getMainContentCaptureSession() {
synchronized (mLock) {
if (mMainSession == null) {
- mMainSession = new MainContentCaptureSession(mContext, mHandler, mService,
- mDisabled);
+ mMainSession = new MainContentCaptureSession(mContext, this, mHandler, mService);
if (VERBOSE) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
}
return mMainSession;
@@ -180,9 +176,17 @@
* </ul>
*/
public boolean isContentCaptureEnabled() {
+ if (mService == null) return false;
+
+ final MainContentCaptureSession mainSession;
synchronized (mLock) {
- return mService != null && !mDisabled;
+ mainSession = mMainSession;
}
+ // The main session is only set when the activity starts, so we need to return true until
+ // then.
+ if (mainSession != null && mainSession.isDisabled()) return false;
+
+ return true;
}
/**
@@ -287,7 +291,8 @@
public void dump(String prefix, PrintWriter pw) {
synchronized (mLock) {
pw.print(prefix); pw.println("ContentCaptureManager");
- pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
+ pw.print(prefix); pw.print("isContentCaptureEnabled(): ");
+ pw.println(isContentCaptureEnabled());
pw.print(prefix); pw.print("Context: "); pw.println(mContext);
pw.print(prefix); pw.print("User: "); pw.println(mContext.getUserId());
if (mService != null) {
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 2eca51f..034c8fa 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -89,21 +89,23 @@
*/
public static final String EXTRA_BINDER = "binder";
- // TODO(b/111276913): make sure disabled state is in sync with manager's disabled
@NonNull
- private final AtomicBoolean mDisabled;
+ private final AtomicBoolean mDisabled = new AtomicBoolean(false);
@NonNull
private final Context mContext;
@NonNull
+ private final ContentCaptureManager mManager;
+
+ @NonNull
private final Handler mHandler;
/**
* Interface to the system_server binder object - it's only used to start the session (and
* notify when the session is finished).
*/
- @Nullable
+ @Nullable // TODO(b/122959591): shoul never be null, we should make main session null instead
private final IContentCaptureManager mSystemServerInterface;
/**
@@ -136,13 +138,13 @@
private final LocalLog mFlushHistory = new LocalLog(10);
/** @hide */
- protected MainContentCaptureSession(@NonNull Context context, @NonNull Handler handler,
- @Nullable IContentCaptureManager systemServerInterface,
- @NonNull boolean disabled) {
+ protected MainContentCaptureSession(@NonNull Context context,
+ @NonNull ContentCaptureManager manager, @NonNull Handler handler,
+ @Nullable IContentCaptureManager systemServerInterface) {
mContext = context;
+ mManager = manager;
mHandler = handler;
mSystemServerInterface = systemServerInterface;
- mDisabled = new AtomicBoolean(disabled);
}
@Override
@@ -235,8 +237,8 @@
/**
* Callback from {@code system_server} after call to
- * {@link IContentCaptureManager#startSession(int, IBinder, ComponentName, String,
- * int, IResultReceiver)}.
+ * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
+ * IResultReceiver)}
*
* @param resultCode session state
* @param binder handle to {@code IContentCaptureDirectManager}
@@ -517,8 +519,12 @@
@Override
boolean isContentCaptureEnabled() {
- return super.isContentCaptureEnabled() && mSystemServerInterface != null
- && !mDisabled.get();
+ return super.isContentCaptureEnabled() && mManager.isContentCaptureEnabled();
+ }
+
+ // Called by ContentCaptureManager.isContentCaptureEnabled
+ boolean isDisabled() {
+ return mDisabled.get();
}
// TODO(b/122454205): refactor "notifyXXXX" methods below to a common "Buffer" object that is