More multi-user stuff.

- New public APIs to find out when a user goes to the foreground,
  background, and is first initializing.
- New activity manager callback to be involved in the user switch
  process, allowing other services to let it know when it is safe
  to stop freezing the screen.
- Wallpaper service now implements this to handle its user switch,
  telling the activity manager when it is done.  (Currently this is
  only handling the old wallpaper going away, we need a little more
  work to correctly wait for the new wallpaper to get added.)
- Lock screen now implements the callback to do its user switch.  It
  also now locks itself when this happens, instead of relying on
  some other entity making sure it is locked.
- Pre-boot broadcasts now go to all users.
- WallpaperManager now has an API to find out if a named wallpaper is
  in use by any users.

Change-Id: I27877aef1d82126c0a1428c3d1861619ee5f8653
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index bf77f6e..eae3b1f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1734,6 +1734,22 @@
             return true;
         }
 
+        case REGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
+                    data.readStrongBinder());
+            registerUserSwitchObserver(observer);
+            return true;
+        }
+
+        case UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
+                    data.readStrongBinder());
+            unregisterUserSwitchObserver(observer);
+            return true;
+        }
+
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -3955,5 +3971,27 @@
         return result;
     }
 
+    public void registerUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
+        mRemote.transact(REGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(observer != null ? observer.asBinder() : null);
+        mRemote.transact(UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }