Merge "Update accessibility to be encryption-aware." into nyc-dev
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 079bdfc..75680e6 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -686,6 +686,11 @@
         return null;
     }
 
+    /** {@hide} */
+    public boolean isEncryptionAware() {
+        return mResolveInfo.serviceInfo.encryptionAware;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 388c8b7..0dbc5be 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -351,6 +351,7 @@
         // user change and unlock
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
+        intentFilter.addAction(Intent.ACTION_USER_UNLOCKED);
         intentFilter.addAction(Intent.ACTION_USER_REMOVED);
         intentFilter.addAction(Intent.ACTION_USER_PRESENT);
         intentFilter.addAction(Intent.ACTION_SETTING_RESTORED);
@@ -361,6 +362,8 @@
                 String action = intent.getAction();
                 if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                     switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
+                } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+                    unlockUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                 } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
                     removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                 } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
@@ -900,6 +903,13 @@
         }
     }
 
+    private void unlockUser(int userId) {
+        synchronized (mLock) {
+            UserState userState = getUserStateLocked(userId);
+            onUserStateChangedLocked(userState);
+        }
+    }
+
     private void removeUser(int userId) {
         synchronized (mLock) {
             mUserStates.remove(userId);
@@ -1002,8 +1012,9 @@
         List<ResolveInfo> installedServices = mPackageManager.queryIntentServicesAsUser(
                 new Intent(AccessibilityService.SERVICE_INTERFACE),
                 PackageManager.GET_SERVICES
-                  | PackageManager.GET_META_DATA
-                  | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
+                        | PackageManager.GET_META_DATA
+                        | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE,
                 mCurrentUserId);
 
         for (int i = 0, count = installedServices.size(); i < count; i++) {
@@ -1236,6 +1247,8 @@
     private void manageServicesLocked(UserState userState) {
         Map<ComponentName, Service> componentNameToServiceMap =
                 userState.mComponentNameToServiceMap;
+        boolean isUnlocked = mContext.getSystemService(UserManager.class)
+                .isUserUnlocked(userState.mUserId);
         boolean isEnabled = userState.mIsAccessibilityEnabled;
 
         for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) {
@@ -1244,6 +1257,12 @@
                     installedService.getId());
             Service service = componentNameToServiceMap.get(componentName);
 
+            // Ignore non-encryption-aware services until user is unlocked
+            if (!isUnlocked && !installedService.isEncryptionAware()) {
+                Slog.d(LOG_TAG, "Ignoring non-encryption-aware service " + componentName);
+                continue;
+            }
+
             if (isEnabled) {
                 // Wait for the binding if it is in process.
                 if (userState.mBindingServices.contains(componentName)) {
@@ -1272,7 +1291,7 @@
 
         // No enabled installed services => disable accessibility to avoid
         // sending accessibility events with no recipient across processes.
-        if (isEnabled && userState.mBoundServices.isEmpty()
+        if (isEnabled && isUnlocked && userState.mBoundServices.isEmpty()
                 && userState.mBindingServices.isEmpty()) {
             userState.mIsAccessibilityEnabled = false;
             final long identity = Binder.clearCallingIdentity();