Migrate primary external storage.

Wire up through MountService to call down into vold.  Watch for
unsolicited events that report progress, including special value "82"
that signals that copy has finished.  We use this value to persist
the volumeUuid in case of unexpected reboot, since it indicates the
new volume is ready.

Wire progress updates through existing callback pipeline.

Update the volume mounting code to match against the persisted UUID
when selecting the primary external storage.

Bug: 19993667
Change-Id: Id46957610fb43517bbfbc368f29b7d430664590d
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 10f5960..16a2430 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1556,6 +1556,7 @@
         }
     }
 
+    @Override
     public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final String volumeUuid = storage.getPrimaryStorageUuid();
@@ -1568,6 +1569,7 @@
         }
     }
 
+    @Override
     public @NonNull List<VolumeInfo> getPrimaryStorageCandidateVolumes() {
         final StorageManager storage = mContext.getSystemService(StorageManager.class);
         final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 0b1031c..16e0bf7 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -16,6 +16,7 @@
 
 package android.os.storage;
 
+import android.content.pm.IPackageMoveObserver;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.IInterface;
@@ -1082,12 +1083,14 @@
             }
 
             @Override
-            public void setPrimaryStorageUuid(String volumeUuid) throws RemoteException {
+            public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
+                    throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
                     _data.writeString(volumeUuid);
+                    _data.writeStrongBinder((callback != null ? callback.asBinder() : null));
                     mRemote.transact(Stub.TRANSACTION_setPrimaryStorageUuid, _data, _reply, 0);
                     _reply.readException();
                 } finally {
@@ -1714,7 +1717,9 @@
                 case TRANSACTION_setPrimaryStorageUuid: {
                     data.enforceInterface(DESCRIPTOR);
                     String volumeUuid = data.readString();
-                    setPrimaryStorageUuid(volumeUuid);
+                    IPackageMoveObserver listener = IPackageMoveObserver.Stub.asInterface(
+                            data.readStrongBinder());
+                    setPrimaryStorageUuid(volumeUuid, listener);
                     reply.writeNoException();
                     return true;
                 }
@@ -2020,5 +2025,6 @@
     public void setVolumeUserFlags(String volId, int flags, int mask) throws RemoteException;
 
     public String getPrimaryStorageUuid() throws RemoteException;
-    public void setPrimaryStorageUuid(String volumeUuid) throws RemoteException;
+    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
+            throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 747fb40..6116aef 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -22,6 +22,8 @@
 import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.pm.IPackageMoveObserver;
+import android.content.pm.PackageManager;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -642,7 +644,12 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * This is not the API you're looking for.
+     *
+     * @see PackageManager#getPrimaryStorageCurrentVolume()
+     * @hide
+     */
     public String getPrimaryStorageUuid() {
         try {
             return mMountService.getPrimaryStorageUuid();
@@ -651,10 +658,15 @@
         }
     }
 
-    /** {@hide} */
-    public void setPrimaryStorageUuid(String volumeUuid) {
+    /**
+     * This is not the API you're looking for.
+     *
+     * @see PackageManager#movePrimaryStorage(VolumeInfo)
+     * @hide
+     */
+    public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
         try {
-            mMountService.setPrimaryStorageUuid(volumeUuid);
+            mMountService.setPrimaryStorageUuid(volumeUuid, callback);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }