diff options
5 files changed, 62 insertions, 29 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 98c5a0fb59be..f2f76638038c 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1048,9 +1048,8 @@ public class Activity extends ContextThemeWrapper private void notifyContentCaptureManagerIfNeeded(@ContentCaptureNotificationType int type) { final ContentCaptureManager cm = getContentCaptureManager(); - if (cm == null) { - return; - } + if (cm == null) return; + switch (type) { case CONTENT_CAPTURE_START: //TODO(b/111276913): decide whether the InteractionSessionId should be diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index e5e028d22d97..ff4cb577c8de 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -329,6 +329,11 @@ public abstract class ContentCaptureService extends Service { mClientInterface.asBinder()); return; } + if ((flags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0) { + setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_BY_APP, + mClientInterface.asBinder()); + return; + } setClientState(clientReceiver, ContentCaptureSession.STATE_ACTIVE, mClientInterface.asBinder()); diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index ff45efd944cd..55e66cab1026 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -29,6 +29,7 @@ import android.os.IBinder; import android.os.RemoteException; import android.util.Log; +import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; import com.android.internal.util.Preconditions; import com.android.internal.util.SyncResultReceiver; @@ -62,8 +63,10 @@ public final class ContentCaptureManager { static final boolean VERBOSE = false; static final boolean DEBUG = true; // STOPSHIP if not set to false - @NonNull - private final AtomicBoolean mDisabled = new AtomicBoolean(); + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private boolean mDisabled; @NonNull private final Context mContext; @@ -71,11 +74,16 @@ public final class ContentCaptureManager { @Nullable private final IContentCaptureManager mService; + // Flags used for starting session. + @GuardedBy("mLock") + private int mFlags; + // TODO(b/119220549): use UI Thread directly (as calls are one-way) or a shared thread / handler // held at the Application level @NonNull private final Handler mHandler; + @GuardedBy("mLock") private MainContentCaptureSession mMainSession; /** @hide */ @@ -114,20 +122,25 @@ public final class ContentCaptureManager { @NonNull @UiThread public MainContentCaptureSession getMainContentCaptureSession() { - if (mMainSession == null) { - mMainSession = new MainContentCaptureSession(mContext, mHandler, mService, - mDisabled); - if (VERBOSE) { - Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession); + synchronized (mLock) { + if (mMainSession == null) { + mMainSession = new MainContentCaptureSession(mContext, mHandler, mService, + new AtomicBoolean(mDisabled)); + if (VERBOSE) { + Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession); + } } + return mMainSession; } - return mMainSession; } /** @hide */ public void onActivityStarted(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent, int flags) { - getMainContentCaptureSession().start(applicationToken, activityComponent, flags); + synchronized (mLock) { + mFlags |= flags; + getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags); + } } /** @hide */ @@ -173,7 +186,9 @@ public final class ContentCaptureManager { * Checks whether content capture is enabled for this activity. */ public boolean isContentCaptureEnabled() { - return mService != null && !mDisabled.get(); + synchronized (mLock) { + return mService != null && !mDisabled; + } } /** @@ -183,7 +198,9 @@ public final class ContentCaptureManager { * it on {@link android.app.Activity#onCreate(android.os.Bundle, android.os.PersistableBundle)}. */ public void setContentCaptureEnabled(boolean enabled) { - //TODO(b/111276913): implement (need to finish / disable all sessions) + synchronized (mLock) { + mFlags |= enabled ? 0 : ContentCaptureContext.FLAG_DISABLED_BY_APP; + } } /** @@ -198,20 +215,22 @@ public final class ContentCaptureManager { /** @hide */ public void dump(String prefix, PrintWriter pw) { - pw.print(prefix); pw.println("ContentCaptureManager"); - - pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled.get()); - pw.print(prefix); pw.print("Context: "); pw.println(mContext); - pw.print(prefix); pw.print("User: "); pw.println(mContext.getUserId()); - if (mService != null) { - pw.print(prefix); pw.print("Service: "); pw.println(mService); - } - if (mMainSession != null) { - final String prefix2 = prefix + " "; - pw.print(prefix); pw.println("Main session:"); - mMainSession.dump(prefix2, pw); - } else { - pw.print(prefix); pw.println("No sessions"); + synchronized (mLock) { + pw.print(prefix); pw.println("ContentCaptureManager"); + pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled); + pw.print(prefix); pw.print("Context: "); pw.println(mContext); + pw.print(prefix); pw.print("User: "); pw.println(mContext.getUserId()); + if (mService != null) { + pw.print(prefix); pw.print("Service: "); pw.println(mService); + } + pw.print(prefix); pw.print("Flags: "); pw.println(mFlags); + if (mMainSession != null) { + final String prefix2 = prefix + " "; + pw.print(prefix); pw.println("Main session:"); + mMainSession.dump(prefix2, pw); + } else { + pw.print(prefix); pw.println("No sessions"); + } } } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index d9a8416dcb4d..9aad931a75b3 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -93,6 +93,13 @@ public abstract class ContentCaptureSession implements AutoCloseable { */ public static final int STATE_DISABLED_BY_FLAG_SECURE = 5; + /** + * Session is disabled manually by the specific app. + * + * @hide + */ + public static final int STATE_DISABLED_BY_APP = 6; + private static final int INITIAL_CHILDREN_CAPACITY = 5; private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -395,6 +402,8 @@ public abstract class ContentCaptureSession implements AutoCloseable { return "DISABLED_DUPLICATED_ID"; case STATE_DISABLED_BY_FLAG_SECURE: return "DISABLED_FLAG_SECURE"; + case STATE_DISABLED_BY_APP: + return "DISABLED_BY_APP"; default: return "INVALID:" + state; } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index a29aaf013d49..18ae454cc5f5 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -250,7 +250,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { // TODO(b/111276913): change the resultCode to use flags so there's just one flag for // disabled stuff if (resultCode == STATE_DISABLED_NO_SERVICE || resultCode == STATE_DISABLED_DUPLICATED_ID - || resultCode == STATE_DISABLED_BY_FLAG_SECURE) { + || resultCode == STATE_DISABLED_BY_FLAG_SECURE + || resultCode == STATE_DISABLED_BY_APP) { mDisabled.set(true); handleResetSession(/* resetState= */ false); } else { |