Improved ContentCaptureManagerSession state.
Test: atest CtsContentCaptureServiceTestCases
Bug: 111276913
Change-Id: I8b1f36174582d89913d5d170abb65789a16818ec
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index ff4cb57..1eaa3c5 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -323,20 +323,21 @@
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 55e66ca..81b2e01 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.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 @@
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 9aad931..2123308 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -21,6 +21,7 @@
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 @@
*
* @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 @@
@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 @@
*/
@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 18ae454..1d9018c 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -88,6 +88,7 @@
*/
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 @@
@Nullable
private DeathRecipient mDirectServiceVulture;
- private int mState = STATE_UNKNOWN;
+ private int mState = UNKNWON_STATE;
@Nullable
private IBinder mApplicationToken;
@@ -133,11 +134,11 @@
/** @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 @@
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 @@
}
}
- // 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 @@
// 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 @@
}
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 09aa421..01778cd 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.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 @@
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 @@
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 @@
// 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;
}