Assist: Allow disabling the disclosure animation

Change-Id: I6e7ed00f066fda7cc268119e7aa4133010aa69c1
Fixes: 30809067
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5da55b1..9383a8b 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6019,6 +6019,17 @@
         public static final String ASSIST_SCREENSHOT_ENABLED = "assist_screenshot_enabled";
 
         /**
+         * Specifies whether the screen will show an animation if screen contents are sent to the
+         * assist application (active voice interaction service).
+         *
+         * Note that the disclosure will be forced for third-party assistants or if the device
+         * does not support disabling it.
+         *
+         * @hide
+         */
+        public static final String ASSIST_DISCLOSURE_ENABLED = "assist_disclosure_enabled";
+
+        /**
          * Names of the service components that the current user has explicitly allowed to
          * see all of the user's notifications, separated by ':'.
          *
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 56c5cc9..2940079 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -16,10 +16,13 @@
 
 package com.android.internal.app;
 
+import com.android.internal.R;
+
 import android.app.SearchManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
@@ -166,4 +169,41 @@
         return null;
     }
 
+    public static boolean isPreinstalledAssistant(Context context, ComponentName assistant) {
+        if (assistant == null) {
+            return false;
+        }
+        ApplicationInfo applicationInfo;
+        try {
+            applicationInfo = context.getPackageManager().getApplicationInfo(
+                    assistant.getPackageName(), 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+        return applicationInfo.isSystemApp() || applicationInfo.isUpdatedSystemApp();
+    }
+
+    private static boolean isDisclosureEnabled(Context context) {
+        return Settings.Secure.getInt(context.getContentResolver(),
+                Settings.Secure.ASSIST_DISCLOSURE_ENABLED, 0) != 0;
+    }
+
+    /**
+     * @return if the disclosure animation should trigger for the given assistant.
+     *
+     * Third-party assistants will always need to disclose, while the user can configure this for
+     * pre-installed assistants.
+     */
+    public static boolean shouldDisclose(Context context, ComponentName assistant) {
+        if (!allowDisablingAssistDisclosure(context)) {
+            return true;
+        }
+
+        return isDisclosureEnabled(context) || !isPreinstalledAssistant(context, assistant);
+    }
+
+    public static boolean allowDisablingAssistDisclosure(Context context) {
+        return context.getResources().getBoolean(
+                com.android.internal.R.bool.config_allowDisablingAssistDisclosure);
+    }
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2835c6f..8636bcc 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2500,6 +2500,10 @@
     <!-- Flag indicating whether round icons should be parsed from the application manifest. -->
     <bool name="config_useRoundIcon">false</bool>
 
+    <!-- Flag indicating whether the assist disclosure can be disabled using
+         ASSIST_DISCLOSURE_ENABLED. -->
+    <bool name="config_allowDisablingAssistDisclosure">false</bool>
+
     <!-- True if the device supports system navigation keys. -->
     <bool name="config_supportSystemNavigationKeys">false</bool>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2a40c08..349c896 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2674,6 +2674,7 @@
   <java-symbol type="drawable" name="ic_doc_generic" />
 
   <java-symbol type="bool" name="config_nightDisplayAvailable" />
+  <java-symbol type="bool" name="config_allowDisablingAssistDisclosure" />
   <java-symbol type="integer" name="config_defaultNightDisplayAutoMode" />
   <java-symbol type="integer" name="config_defaultNightDisplayCustomStartTime" />
   <java-symbol type="integer" name="config_defaultNightDisplayCustomEndTime" />
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index b0cc2ac..c3075b3 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -46,6 +46,7 @@
 import android.view.IWindowManager;
 import android.view.WindowManager;
 
+import com.android.internal.app.AssistUtils;
 import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.app.IVoiceInteractionSessionShowCallback;
 import com.android.internal.app.IVoiceInteractor;
@@ -301,7 +302,7 @@
             } else {
                 mScreenshot = null;
             }
-            if (needDisclosure) {
+            if (needDisclosure && AssistUtils.shouldDisclose(mContext, mSessionComponentName)) {
                 mHandler.post(mShowAssistDisclosureRunnable);
             }
             if (mSession != null) {