diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index ff4cb577c8de6..1eaa3c512fefa 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -323,20 +323,21 @@ public abstract class ContentCaptureService extends Service { mSessionUids.put(sessionId, uid); onCreateContentCaptureSession(context, new ContentCaptureSessionId(sessionId)); - final int flags = context.getFlags(); - if ((flags & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0) { - setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_BY_FLAG_SECURE, - mClientInterface.asBinder()); - return; + final int clientFlags = context.getFlags(); + int stateFlags = 0; + if ((clientFlags & ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE) != 0) { + stateFlags |= ContentCaptureSession.STATE_FLAG_SECURE; } - if ((flags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0) { - setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_BY_APP, - mClientInterface.asBinder()); - return; + if ((clientFlags & ContentCaptureContext.FLAG_DISABLED_BY_APP) != 0) { + stateFlags |= ContentCaptureSession.STATE_BY_APP; } + if (stateFlags == 0) { + stateFlags = ContentCaptureSession.STATE_ACTIVE; + } else { + stateFlags |= ContentCaptureSession.STATE_DISABLED; - setClientState(clientReceiver, ContentCaptureSession.STATE_ACTIVE, - mClientInterface.asBinder()); + } + setClientState(clientReceiver, stateFlags, mClientInterface.asBinder()); } private void handleSendEvents(int uid, diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java index 55e66cab10262..81b2e01dfbc75 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -35,7 +35,6 @@ import com.android.internal.util.Preconditions; import com.android.internal.util.SyncResultReceiver; import java.io.PrintWriter; -import java.util.concurrent.atomic.AtomicBoolean; /* * NOTE: all methods in this class should return right away, or do the real work in a handler @@ -125,7 +124,7 @@ public final class ContentCaptureManager { synchronized (mLock) { if (mMainSession == null) { mMainSession = new MainContentCaptureSession(mContext, mHandler, mService, - new AtomicBoolean(mDisabled)); + mDisabled); if (VERBOSE) { Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession); } diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java index 9aad931a75b3b..2123308dbdebe 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -21,6 +21,7 @@ import static android.view.contentcapture.ContentCaptureManager.VERBOSE; import android.annotation.CallSuper; import android.annotation.NonNull; import android.annotation.Nullable; +import android.util.DebugUtils; import android.util.Log; import android.view.View; import android.view.ViewStructure; @@ -56,49 +57,58 @@ public abstract class ContentCaptureSession implements AutoCloseable { * * @hide */ - public static final int STATE_UNKNOWN = 0; + // NOTE: not prefixed by STATE_ so it's not printed on getStateAsString() + public static final int UNKNWON_STATE = 0x0; /** * Service's startSession() was called, but server didn't confirm it was created yet. * * @hide */ - public static final int STATE_WAITING_FOR_SERVER = 1; + public static final int STATE_WAITING_FOR_SERVER = 0x1; /** * Session is active. * * @hide */ - public static final int STATE_ACTIVE = 2; + public static final int STATE_ACTIVE = 0x2; /** * Session is disabled because there is no service for this user. * * @hide */ - public static final int STATE_DISABLED_NO_SERVICE = 3; + public static final int STATE_DISABLED = 0x4; /** * Session is disabled because its id already existed on server. * * @hide */ - public static final int STATE_DISABLED_DUPLICATED_ID = 4; + public static final int STATE_DUPLICATED_ID = 0x8; + + /** + * Session is disabled because service is not set for user. + * + * @hide + */ + public static final int STATE_NO_SERVICE = 0x10; /** * Session is disabled by FLAG_SECURE * * @hide */ - public static final int STATE_DISABLED_BY_FLAG_SECURE = 5; + public static final int STATE_FLAG_SECURE = 0x20; /** * Session is disabled manually by the specific app. * * @hide */ - public static final int STATE_DISABLED_BY_APP = 6; + public static final int STATE_BY_APP = 0x40; + private static final int INITIAL_CHILDREN_CAPACITY = 5; @@ -117,7 +127,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { @Nullable protected final String mId; - private int mState = STATE_UNKNOWN; + private int mState = UNKNWON_STATE; // Lazily created on demand. private ContentCaptureSessionId mContentCaptureSessionId; @@ -389,23 +399,7 @@ public abstract class ContentCaptureSession implements AutoCloseable { */ @NonNull protected static String getStateAsString(int state) { - switch (state) { - case STATE_UNKNOWN: - return "UNKNOWN"; - case STATE_WAITING_FOR_SERVER: - return "WAITING_FOR_SERVER"; - case STATE_ACTIVE: - return "ACTIVE"; - case STATE_DISABLED_NO_SERVICE: - return "DISABLED_NO_SERVICE"; - case STATE_DISABLED_DUPLICATED_ID: - 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; - } + return state + " (" + (state == UNKNWON_STATE ? "UNKNOWN" + : DebugUtils.flagsToString(ContentCaptureSession.class, "STATE_", state)) + ")"; } } diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java index 18ae454cc5f5c..1d9018c1682c2 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -88,6 +88,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { */ 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; @@ -113,7 +114,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { @Nullable private DeathRecipient mDirectServiceVulture; - private int mState = STATE_UNKNOWN; + private int mState = UNKNWON_STATE; @Nullable private IBinder mApplicationToken; @@ -133,11 +134,11 @@ public final class MainContentCaptureSession extends ContentCaptureSession { /** @hide */ protected MainContentCaptureSession(@NonNull Context context, @NonNull Handler handler, @Nullable IContentCaptureManager systemServerInterface, - @NonNull AtomicBoolean disabled) { + @NonNull boolean disabled) { mContext = context; mHandler = handler; mSystemServerInterface = systemServerInterface; - mDisabled = disabled; + mDisabled = new AtomicBoolean(disabled); } @Override @@ -184,7 +185,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { private void handleStartSession(@NonNull IBinder token, @NonNull ComponentName componentName, int flags) { - if (mState != STATE_UNKNOWN) { + if (mState != UNKNWON_STATE) { // TODO(b/111276913): revisit this scenario Log.w(TAG, "ignoring handleStartSession(" + token + ") while on state " + getStateAsString(mState)); @@ -247,18 +248,14 @@ 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_APP) { + if ((mState & STATE_DISABLED) != 0) { mDisabled.set(true); handleResetSession(/* resetState= */ false); } else { mDisabled.set(false); } if (VERBOSE) { - Log.v(TAG, "handleSessionStarted() result: code=" + resultCode + ", id=" + mId + Log.v(TAG, "handleSessionStarted() result: id=" + mId + ", state=" + getStateAsString(mState) + ", disabled=" + mDisabled.get() + ", binder=" + binder + ", events=" + (mEvents == null ? 0 : mEvents.size())); } @@ -408,7 +405,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { // clearings out. private void handleResetSession(boolean resetState) { if (resetState) { - mState = STATE_UNKNOWN; + mState = UNKNWON_STATE; } // TODO(b/122454205): must reset children (which currently is owned by superclass) @@ -497,8 +494,7 @@ public final class MainContentCaptureSession extends ContentCaptureSession { } pw.print(prefix); pw.print("mDisabled: "); pw.println(mDisabled.get()); pw.print(prefix); pw.print("isEnabled(): "); pw.println(isContentCaptureEnabled()); - pw.print(prefix); pw.print("state: "); pw.print(mState); pw.print(" ("); - pw.print(getStateAsString(mState)); pw.println(")"); + pw.print(prefix); pw.print("state: "); pw.println(getStateAsString(mState)); if (mApplicationToken != null) { pw.print(prefix); pw.print("app token: "); pw.println(mApplicationToken); } diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 09aa4212654ea..01778cd673e6c 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -17,6 +17,9 @@ package com.android.server.contentcapture; import static android.service.contentcapture.ContentCaptureService.setClientState; +import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED; +import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID; +import static android.view.contentcapture.ContentCaptureSession.STATE_NO_SERVICE; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA; @@ -39,7 +42,6 @@ import android.service.contentcapture.ContentCaptureService; import android.service.contentcapture.SnapshotData; import android.util.ArrayMap; import android.util.Slog; -import android.view.contentcapture.ContentCaptureSession; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.IResultReceiver; @@ -165,7 +167,7 @@ final class ContentCapturePerUserService if (!isEnabledLocked()) { // TODO: it would be better to split in differet reasons, like // STATE_DISABLED_NO_SERVICE and STATE_DISABLED_BY_DEVICE_POLICY - setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_NO_SERVICE, + setClientState(clientReceiver, STATE_DISABLED | STATE_NO_SERVICE, /* binder= */ null); return; } @@ -184,7 +186,7 @@ final class ContentCapturePerUserService if (existingSession != null) { Slog.w(TAG, "startSession(id=" + existingSession + ", token=" + activityToken + ": ignoring because it already exists for " + existingSession.mActivityToken); - setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_DUPLICATED_ID, + setClientState(clientReceiver, STATE_DISABLED | STATE_DUPLICATED_ID, /* binder=*/ null); return; } @@ -197,8 +199,7 @@ final class ContentCapturePerUserService // TODO(b/119613670): log metrics Slog.w(TAG, "startSession(id=" + existingSession + ", token=" + activityToken + ": ignoring because service is not set"); - // TODO(b/111276913): use a new disabled state? - setClientState(clientReceiver, ContentCaptureSession.STATE_DISABLED_NO_SERVICE, + setClientState(clientReceiver, STATE_DISABLED | STATE_NO_SERVICE, /* binder= */ null); return; }