Merge "Watch for voice recognition service changes for all users" into jb-mr1-dev
diff --git a/services/java/com/android/server/RecognitionManagerService.java b/services/java/com/android/server/RecognitionManagerService.java
index 3567cfc..1e0755d 100644
--- a/services/java/com/android/server/RecognitionManagerService.java
+++ b/services/java/com/android/server/RecognitionManagerService.java
@@ -18,13 +18,18 @@
 
 import com.android.internal.content.PackageMonitor;
 
+import android.app.AppGlobals;
+import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Binder;
+import android.os.RemoteException;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.speech.RecognitionService;
 import android.text.TextUtils;
@@ -34,68 +39,82 @@
 
 public class RecognitionManagerService extends Binder {
     final static String TAG = "RecognitionManagerService";
-    
-    final Context mContext;
-    final MyPackageMonitor mMonitor;
-    
+
+    private final Context mContext;
+    private final MyPackageMonitor mMonitor;
+    private final IPackageManager mIPm;
+
+    private static final boolean DEBUG = false;
+
     class MyPackageMonitor extends PackageMonitor {
         public void onSomePackagesChanged() {
-            ComponentName comp = getCurRecognizer();
+            int userHandle = getChangingUserId();
+            if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle);
+            ComponentName comp = getCurRecognizer(userHandle);
             if (comp == null) {
                 if (anyPackagesAppearing()) {
-                    comp = findAvailRecognizer(null);
+                    comp = findAvailRecognizer(null, userHandle);
                     if (comp != null) {
-                        setCurRecognizer(comp);
+                        setCurRecognizer(comp, userHandle);
                     }
                 }
                 return;
             }
-            
+
             int change = isPackageDisappearing(comp.getPackageName()); 
             if (change == PACKAGE_PERMANENT_CHANGE
                     || change == PACKAGE_TEMPORARY_CHANGE) {
-                setCurRecognizer(findAvailRecognizer(null));
+                setCurRecognizer(findAvailRecognizer(null, userHandle), userHandle);
                 
             } else if (isPackageModified(comp.getPackageName())) {
-                setCurRecognizer(findAvailRecognizer(comp.getPackageName()));
+                setCurRecognizer(findAvailRecognizer(comp.getPackageName(), userHandle),
+                        userHandle);
             }
         }
     }
-    
+
     RecognitionManagerService(Context context) {
         mContext = context;
         mMonitor = new MyPackageMonitor();
-        mMonitor.register(context, null, true);
+        mMonitor.register(context, null, UserHandle.ALL, true);
+        mIPm = AppGlobals.getPackageManager();
+        mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL,
+                new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
     }
-    
+
     public void systemReady() {
-        ComponentName comp = getCurRecognizer();
+        initForUser(UserHandle.USER_OWNER);
+    }
+
+    private void initForUser(int userHandle) {
+        if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle);
+        ComponentName comp = getCurRecognizer(userHandle);
         if (comp != null) {
             // See if the current recognizer is no longer available.
             try {
-                mContext.getPackageManager().getServiceInfo(comp, 0);
-            } catch (NameNotFoundException e) {
-                comp = findAvailRecognizer(null);
+                mIPm.getServiceInfo(comp, 0, userHandle);
+            } catch (RemoteException e) {
+                comp = findAvailRecognizer(null, userHandle);
                 if (comp != null) {
-                    setCurRecognizer(comp);
+                    setCurRecognizer(comp, userHandle);
                 }
             }
         } else {
-            comp = findAvailRecognizer(null);
+            comp = findAvailRecognizer(null, userHandle);
             if (comp != null) {
-                setCurRecognizer(comp);
+                setCurRecognizer(comp, userHandle);
             }
         }
     }
-    
-    ComponentName findAvailRecognizer(String prefPackage) {
+
+    ComponentName findAvailRecognizer(String prefPackage, int userHandle) {
         List<ResolveInfo> available =
-                mContext.getPackageManager().queryIntentServices(
-                        new Intent(RecognitionService.SERVICE_INTERFACE), 0);
+                mContext.getPackageManager().queryIntentServicesAsUser(
+                        new Intent(RecognitionService.SERVICE_INTERFACE), 0, userHandle);
         int numAvailable = available.size();
-    
+
         if (numAvailable == 0) {
-            Slog.w(TAG, "no available voice recognition services found");
+            Slog.w(TAG, "no available voice recognition services found for user " + userHandle);
             return null;
         } else {
             if (prefPackage != null) {
@@ -109,25 +128,42 @@
             if (numAvailable > 1) {
                 Slog.w(TAG, "more than one voice recognition service found, picking first");
             }
-    
+
             ServiceInfo serviceInfo = available.get(0).serviceInfo;
             return new ComponentName(serviceInfo.packageName, serviceInfo.name);
         }
     }
-    
-    ComponentName getCurRecognizer() {
-        String curRecognizer = Settings.Secure.getString(
+
+    ComponentName getCurRecognizer(int userHandle) {
+        String curRecognizer = Settings.Secure.getStringForUser(
                 mContext.getContentResolver(),
-                Settings.Secure.VOICE_RECOGNITION_SERVICE);
+                Settings.Secure.VOICE_RECOGNITION_SERVICE, userHandle);
         if (TextUtils.isEmpty(curRecognizer)) {
             return null;
         }
+        if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer
+                + " user=" + userHandle);
         return ComponentName.unflattenFromString(curRecognizer);
     }
-    
-    void setCurRecognizer(ComponentName comp) {
-        Settings.Secure.putString(mContext.getContentResolver(),
+
+    void setCurRecognizer(ComponentName comp, int userHandle) {
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
                 Settings.Secure.VOICE_RECOGNITION_SERVICE,
-                comp != null ? comp.flattenToShortString() : "");
+                comp != null ? comp.flattenToShortString() : "", userHandle);
+        if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp
+                + " user=" + userHandle);
     }
+
+    BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (DEBUG) Slog.i(TAG, "received " + action);
+            if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+                int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                if (userHandle > 0) {
+                    initForUser(userHandle);
+                }
+            }
+        }
+    };
 }