Integrate content capture with FLAG_SECURE

Change-Id: I4e2c7d8063ca224d2037c01b7ddb24f8a7d85cbf
Fixes: 119254124
Test: atest CtsContentCaptureServiceTestCases
Test: atest android.contentcaptureservice.cts.LoginActivityTest#testStateDisabledByFlagSecure
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index fdb71bb..c89848e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -121,6 +121,7 @@
 import android.view.autofill.AutofillManager.AutofillClient;
 import android.view.autofill.AutofillPopupWindow;
 import android.view.autofill.IAutofillWindowPresenter;
+import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureManager;
 import android.widget.AdapterView;
 import android.widget.Toast;
@@ -1045,14 +1046,19 @@
 
     private void notifyContentCaptureManagerIfNeeded(@ContentCaptureNotificationType int type) {
         final ContentCaptureManager cm = getContentCaptureManager();
-        if (cm == null || !cm.isContentCaptureEnabled()) {
+        if (cm == null) {
             return;
         }
         switch (type) {
             case CONTENT_CAPTURE_START:
                 //TODO(b/111276913): decide whether the InteractionSessionId should be
                 // saved / restored in the activity bundle - probably not
-                cm.onActivityStarted(mToken, getComponentName());
+                int flags = 0;
+                if ((getWindow().getAttributes().flags
+                        & WindowManager.LayoutParams.FLAG_SECURE) != 0) {
+                    flags |= ContentCaptureContext.FLAG_DISABLED_BY_FLAG_SECURE;
+                }
+                cm.onActivityStarted(mToken, getComponentName(), flags);
                 break;
             case CONTENT_CAPTURE_FLUSH:
                 cm.flush();
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 26bf361..adcb7a5 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -311,6 +311,14 @@
             @NonNull String sessionId, int uid, IResultReceiver clientReceiver) {
         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;
+        }
+
         setClientState(clientReceiver, ContentCaptureSession.STATE_ACTIVE,
                 mClientInterface.asBinder());
     }
@@ -392,15 +400,16 @@
     }
 
     /**
-     * Sends the state of the {@link ContentCaptureManager} in the cleint app.
+     * Sends the state of the {@link ContentCaptureManager} in the client app.
      *
      * @param clientReceiver receiver in the client app.
+     * @param sessionState state of the session
      * @param binder handle to the {@code IContentCaptureDirectManager} object that resides in the
      * service.
      * @hide
      */
     public static void setClientState(@NonNull IResultReceiver clientReceiver,
-            int sessionStatus, @Nullable IBinder binder) {
+            int sessionState, @Nullable IBinder binder) {
         try {
             final Bundle extras;
             if (binder != null) {
@@ -409,7 +418,7 @@
             } else {
                 extras = null;
             }
-            clientReceiver.send(sessionStatus, extras);
+            clientReceiver.send(sessionState, extras);
         } catch (RemoteException e) {
             Slog.w(TAG, "Error async reporting result to client: " + e);
         }
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index e962e7c..fe050ac 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -116,8 +116,8 @@
 
     /** @hide */
     public void onActivityStarted(@NonNull IBinder applicationToken,
-            @NonNull ComponentName activityComponent) {
-        getMainContentCaptureSession().start(applicationToken, activityComponent);
+            @NonNull ComponentName activityComponent, int flags) {
+        getMainContentCaptureSession().start(applicationToken, activityComponent, flags);
     }
 
     /** @hide */
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 344b9973..2119073 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -86,6 +86,13 @@
      */
     public static final int STATE_DISABLED_DUPLICATED_ID = 4;
 
+    /**
+     * Session is disabled by FLAG_SECURE
+     *
+     * @hide
+     */
+    public static final int STATE_DISABLED_BY_FLAG_SECURE = 5;
+
     private static final int INITIAL_CHILDREN_CAPACITY = 5;
 
     private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -356,6 +363,8 @@
                 return "DISABLED_NO_SERVICE";
             case STATE_DISABLED_DUPLICATED_ID:
                 return "DISABLED_DUPLICATED_ID";
+            case STATE_DISABLED_BY_FLAG_SECURE:
+                return "DISABLED_FLAG_SECURE";
             default:
                 return "INVALID:" + state;
         }
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 8be887b..a29aaf0 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -157,7 +157,8 @@
      *
      * @hide
      */
-    void start(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent) {
+    void start(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent,
+            int flags) {
         if (!isContentCaptureEnabled()) return;
 
         if (VERBOSE) {
@@ -166,7 +167,7 @@
         }
 
         mHandler.sendMessage(obtainMessage(MainContentCaptureSession::handleStartSession, this,
-                applicationToken, activityComponent));
+                applicationToken, activityComponent, flags));
     }
 
     @Override
@@ -181,7 +182,8 @@
                 obtainMessage(MainContentCaptureSession::handleDestroySession, this));
     }
 
-    private void handleStartSession(@NonNull IBinder token, @NonNull ComponentName componentName) {
+    private void handleStartSession(@NonNull IBinder token, @NonNull ComponentName componentName,
+            int flags) {
         if (mState != STATE_UNKNOWN) {
             // TODO(b/111276913): revisit this scenario
             Log.w(TAG, "ignoring handleStartSession(" + token + ") while on state "
@@ -196,7 +198,6 @@
             Log.v(TAG, "handleStartSession(): token=" + token + ", act="
                     + getActivityDebugName() + ", id=" + mId);
         }
-        final int flags = 0; // TODO(b/111276913): get proper flags
 
         try {
             if (mSystemServerInterface == null) return;
@@ -245,7 +246,11 @@
                 Log.w(TAG, "Failed to link to death on " + binder + ": " + e);
             }
         }
-        if (resultCode == STATE_DISABLED_NO_SERVICE || resultCode == STATE_DISABLED_DUPLICATED_ID) {
+
+        // 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) {
             mDisabled.set(true);
             handleResetSession(/* resetState= */ false);
         } else {