Exempt keyboards from auto revoke

Test: run auto revoke, observe logs, ensure keyboard gets exempted
Bug: 153607914
Change-Id: Idc5f3b75382a249874a2b542e7d1e181b37ac163
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt
index a898918..0181ed5 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt
@@ -53,6 +53,7 @@
 import android.provider.DeviceConfig
 import android.provider.Settings
 import android.util.Log
+import android.view.inputmethod.InputMethod
 import androidx.annotation.MainThread
 import com.android.permissioncontroller.Constants
 import com.android.permissioncontroller.Constants.ACTION_MANAGE_AUTO_REVOKE
@@ -219,6 +220,12 @@
             .getAutoRevokeExemptionGrantedPackages()
     }
 
+    val keyboardPackages = context.packageManager
+            .queryIntentServices(Intent(InputMethod.SERVICE_INTERFACE), 0)
+            .mapNotNull { resolveInfo ->
+                resolveInfo?.serviceInfo?.packageName
+            }
+
     val revokedApps = mutableListOf<Pair<String, UserHandle>>()
     for ((user, userApps) in unusedApps) {
         userApps.forEachInParallel(Main) { pkg: LightPackageInfo ->
@@ -226,6 +233,13 @@
                 return@forEachInParallel
             }
 
+            if (pkg.packageName in keyboardPackages) {
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Skipping IME: ${pkg.packageName}")
+                }
+                return@forEachInParallel
+            }
+
             val packageName = pkg.packageName
             if (isPackageAutoRevokeExempt(context, pkg, manifestExemptPackages)) {
                 return@forEachInParallel