Added new APIs to let Settings enable / disable ContentCapture

Bug: 123286662
Test: atest ChildlessActivityTest#testSetContentCaptureFeatureEnabled_disabledBySettings \
        ChildlessActivityTest#testSetContentCaptureFeatureEnabled_disabledThenReEnabledBySettings\
        FrameworksCoreTests:SettingsBackupTest#secureSettingsBackedUpOrBlacklisted
Test: atest CtsContentCaptureServiceTestCases # for sanity check

Change-Id: I7cd2c36c1d7e23efb9acacf4f18cecd8838f5ac5
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 852b65a..3f00793 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5656,6 +5656,14 @@
                 "autofill_user_data_min_value_length";
 
         /**
+         * Defines whether Content Capture is enabled  for the user.
+         * @hide
+         */
+        @SystemApi
+        @TestApi
+        public static final String CONTENT_CAPTURE_ENABLED = "content_capture_enabled";
+
+        /**
          * @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead
          */
         @Deprecated
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 07c9101..07dedd6 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -19,6 +19,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.UiThread;
 import android.content.ComponentName;
@@ -108,9 +109,7 @@
             if (mMainSession == null) {
                 mMainSession = new MainContentCaptureSession(mContext, mHandler, mService,
                         mDisabled);
-                if (VERBOSE) {
-                    Log.v(TAG, "getDefaultContentCaptureSession(): created " + mMainSession);
-                }
+                if (VERBOSE) Log.v(TAG, "getMainContentCaptureSession(): created " + mMainSession);
             }
             return mMainSession;
         }
@@ -147,13 +146,9 @@
      */
     @Nullable
     public ComponentName getServiceComponentName() {
-        if (!isContentCaptureEnabled()) {
-            return null;
-        }
-        // Wait for system server to return the component name.
+        if (!isContentCaptureEnabled()) return null;
+
         final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
-
-
         try {
             mService.getServiceComponentName(resultReceiver);
             return resultReceiver.getParcelableResult();
@@ -164,6 +159,17 @@
 
     /**
      * Checks whether content capture is enabled for this activity.
+     *
+     * <p>There are many reasons it could be disabled, such as:
+     * <ul>
+     *   <li>App itself disabled content capture through {@link #setContentCaptureEnabled(boolean)}.
+     *   <li>Service disabled content capture for this specific activity.
+     *   <li>Service disabled content capture for all activities of this package.
+     *   <li>Service disabled content capture globally.
+     *   <li>User disabled content capture globally (through Settings).
+     *   <li>OEM disabled content capture globally.
+     *   <li>Transient errors.
+     * </ul>
      */
     public boolean isContentCaptureEnabled() {
         synchronized (mLock) {
@@ -184,6 +190,28 @@
     }
 
     /**
+     * Gets whether Content Capture is enabled for the given user.
+     *
+     * <p>This method is typically used by the Content Capture Service settings page, so it can
+     * provide a toggle to enable / disable it.
+     *
+     * @hide
+     */
+    @SystemApi
+    public boolean isContentCaptureFeatureEnabled() {
+        if (mService == null) return false;
+
+        final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
+        try {
+            mService.isContentCaptureFeatureEnabled(resultReceiver);
+            return resultReceiver.getIntResult() == 1;
+        } catch (RemoteException e) {
+            // Unable to retrieve component name in a reasonable amount of time.
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Called by the app to request the Content Capture service to remove user-data associated with
      * some context.
      *
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index c425e7b..e6ee6ed 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -99,7 +99,8 @@
     public static final int STATE_FLAG_SECURE = 0x20;
 
     /**
-     * Session is disabled manually by the specific app.
+     * Session is disabled manually by the specific app
+     * (through {@link ContentCaptureManager#setContentCaptureEnabled(boolean)}).
      *
      * @hide
      */
diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
index 56ed8bf..e3b0372 100644
--- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl
+++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
@@ -62,4 +62,9 @@
      * Requests the removal of user data for the calling user.
      */
     void removeUserData(in UserDataRemovalRequest request);
+
+    /**
+     * Returns whether the content capture feature is enabled for the calling user.
+     */
+    void isContentCaptureFeatureEnabled(in IResultReceiver result);
 }
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index bd7f852..4e71821 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -605,6 +605,7 @@
                  Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
                  Settings.Secure.COMPLETED_CATEGORY_PREFIX,
                  Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
+                 Settings.Secure.CONTENT_CAPTURE_ENABLED,
                  Settings.Secure.DEFAULT_INPUT_METHOD,
                  Settings.Secure.DEVICE_PAIRED,
                  Settings.Secure.DIALER_DEFAULT_APPLICATION,