Migrate package movement to use new API.

We now kick off the move immediately, and pass along the "ID" of the
move in progress.  This allows the progress activity to be completely
destroyed and recreated without kicking off a second conflicting move
operation.

Also uses new cleaner movement API that accepts direct VolumeInfo.

Bug: 19993667
Change-Id: I28bc268fcb42dfc9152020b16ef7058d63157597
This commit is contained in:
Jeff Sharkey
2015-04-23 19:37:41 -07:00
parent 3a8a17d733
commit 954d8dad5e
3 changed files with 57 additions and 84 deletions

View File

@@ -168,7 +168,7 @@ public class AppStorageSettings extends AppInfoWithHeader
// If not current volume, kick off move wizard // If not current volume, kick off move wizard
final VolumeInfo targetVol = (VolumeInfo) value; final VolumeInfo targetVol = (VolumeInfo) value;
final VolumeInfo currentVol = context.getPackageManager().getApplicationCurrentVolume( final VolumeInfo currentVol = context.getPackageManager().getPackageCurrentVolume(
mAppEntry.info); mAppEntry.info);
if (!Objects.equals(targetVol, currentVol)) { if (!Objects.equals(targetVol, currentVol)) {
final Intent intent = new Intent(context, StorageWizardMoveConfirm.class); final Intent intent = new Intent(context, StorageWizardMoveConfirm.class);
@@ -261,7 +261,7 @@ public class AppStorageSettings extends AppInfoWithHeader
refreshSizeInfo(); refreshSizeInfo();
final VolumeInfo currentVol = getActivity().getPackageManager() final VolumeInfo currentVol = getActivity().getPackageManager()
.getApplicationCurrentVolume(mAppEntry.info); .getPackageCurrentVolume(mAppEntry.info);
mMoveDropDown.setSelectedValue(currentVol); mMoveDropDown.setSelectedValue(currentVol);
return true; return true;
@@ -303,7 +303,7 @@ public class AppStorageSettings extends AppInfoWithHeader
final StorageManager storage = context.getSystemService(StorageManager.class); final StorageManager storage = context.getSystemService(StorageManager.class);
final List<VolumeInfo> candidates = context.getPackageManager() final List<VolumeInfo> candidates = context.getPackageManager()
.getApplicationCandidateVolumes(mAppEntry.info); .getPackageCandidateVolumes(mAppEntry.info);
Collections.sort(candidates, VolumeInfo.getDescriptionComparator()); Collections.sort(candidates, VolumeInfo.getDescriptionComparator());
mMoveDropDown.clearItems(); mMoveDropDown.clearItems();

View File

@@ -16,11 +16,15 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.EXTRA_TITLE;
import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
import static android.os.storage.VolumeInfo.EXTRA_VOLUME_ID;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle; import android.os.Bundle;
import android.os.storage.VolumeInfo;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.settings.R; import com.android.settings.R;
@@ -35,7 +39,7 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
setContentView(R.layout.storage_wizard_generic); setContentView(R.layout.storage_wizard_generic);
try { try {
mPackageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); mPackageName = getIntent().getStringExtra(EXTRA_PACKAGE_NAME);
mApp = getPackageManager().getApplicationInfo(mPackageName, 0); mApp = getPackageManager().getApplicationInfo(mPackageName, 0);
} catch (NameNotFoundException e) { } catch (NameNotFoundException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -46,7 +50,7 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
// Sanity check that target volume is candidate // Sanity check that target volume is candidate
Preconditions.checkState( Preconditions.checkState(
getPackageManager().getApplicationCandidateVolumes(mApp).contains(mVolume)); getPackageManager().getPackageCandidateVolumes(mApp).contains(mVolume));
final String appName = getPackageManager().getApplicationLabel(mApp).toString(); final String appName = getPackageManager().getApplicationLabel(mApp).toString();
final String volumeName = mStorage.getBestVolumeDescription(mVolume); final String volumeName = mStorage.getBestVolumeDescription(mVolume);
@@ -59,9 +63,14 @@ public class StorageWizardMoveConfirm extends StorageWizardBase {
@Override @Override
public void onNavigateNext() { public void onNavigateNext() {
// Kick off move before we transition
final String appName = getPackageManager().getApplicationLabel(mApp).toString();
final int moveId = getPackageManager().movePackage(mPackageName, mVolume);
final Intent intent = new Intent(this, StorageWizardMoveProgress.class); final Intent intent = new Intent(this, StorageWizardMoveProgress.class);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId()); intent.putExtra(EXTRA_MOVE_ID, moveId);
intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mPackageName); intent.putExtra(EXTRA_TITLE, appName);
intent.putExtra(EXTRA_VOLUME_ID, mVolume.getId());
startActivity(intent); startActivity(intent);
finishAffinity(); finishAffinity();
} }

View File

@@ -16,59 +16,72 @@
package com.android.settings.deviceinfo; package com.android.settings.deviceinfo;
import static android.content.Intent.EXTRA_TITLE;
import static android.content.pm.PackageManager.EXTRA_MOVE_ID;
import static com.android.settings.deviceinfo.StorageSettings.TAG; import static com.android.settings.deviceinfo.StorageSettings.TAG;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.MoveCallback;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.Handler;
import android.os.storage.VolumeInfo;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import com.android.internal.util.Preconditions;
import com.android.settings.R; import com.android.settings.R;
import java.util.concurrent.CountDownLatch;
public class StorageWizardMoveProgress extends StorageWizardBase { public class StorageWizardMoveProgress extends StorageWizardBase {
private String mPackageName; private int mMoveId;
private ApplicationInfo mApp;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.storage_wizard_progress); setContentView(R.layout.storage_wizard_progress);
try { mMoveId = getIntent().getIntExtra(EXTRA_MOVE_ID, -1);
mPackageName = getIntent().getStringExtra(Intent.EXTRA_PACKAGE_NAME); final String appName = getIntent().getStringExtra(EXTRA_TITLE);
mApp = getPackageManager().getApplicationInfo(mPackageName, 0);
} catch (NameNotFoundException e) {
throw new RuntimeException(e);
}
Preconditions.checkNotNull(mVolume);
Preconditions.checkNotNull(mApp);
final String appName = getPackageManager().getApplicationLabel(mApp).toString();
final String volumeName = mStorage.getBestVolumeDescription(mVolume); final String volumeName = mStorage.getBestVolumeDescription(mVolume);
setHeaderText(R.string.storage_wizard_move_progress_title, appName); setHeaderText(R.string.storage_wizard_move_progress_title, appName);
setBodyText(R.string.storage_wizard_move_progress_body, volumeName, appName); setBodyText(R.string.storage_wizard_move_progress_body, volumeName, appName);
setCurrentProgress(20);
getNextButton().setVisibility(View.GONE); getNextButton().setVisibility(View.GONE);
new MoveTask().execute(); // Register for updates and push through current status
getPackageManager().registerMoveCallback(mCallback, new Handler());
mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1);
} }
@Override
protected void onDestroy() {
super.onDestroy();
getPackageManager().unregisterMoveCallback(mCallback);
}
private final MoveCallback mCallback = new MoveCallback() {
@Override
public void onStarted(int moveId, String title) {
// Ignored
}
@Override
public void onStatusChanged(int moveId, int status, long estMillis) {
if (mMoveId != moveId) return;
if (PackageManager.isMoveStatusFinished(status)) {
Log.d(TAG, "Finished with status " + status);
if (status != PackageManager.MOVE_SUCCEEDED) {
Toast.makeText(StorageWizardMoveProgress.this, moveStatusToMessage(status),
Toast.LENGTH_LONG).show();
}
finishAffinity();
} else {
setCurrentProgress(status);
}
}
};
private CharSequence moveStatusToMessage(int returnCode) { private CharSequence moveStatusToMessage(int returnCode) {
switch (returnCode) { switch (returnCode) {
case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE: case PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE:
@@ -86,53 +99,4 @@ public class StorageWizardMoveProgress extends StorageWizardBase {
return getString(R.string.insufficient_storage); return getString(R.string.insufficient_storage);
} }
} }
private class LocalPackageMoveObserver extends IPackageMoveObserver.Stub {
public int returnCode;
public CountDownLatch finished = new CountDownLatch(1);
@Override
public void packageMoved(String packageName, int returnCode) throws RemoteException {
this.returnCode = returnCode;
this.finished.countDown();
}
}
public class MoveTask extends AsyncTask<Void, Void, Integer> {
@Override
protected Integer doInBackground(Void... params) {
try {
final LocalPackageMoveObserver observer = new LocalPackageMoveObserver();
if (mApp.isExternalAsec()) {
getPackageManager().movePackage(mPackageName, observer,
PackageManager.MOVE_INTERNAL);
} else if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) {
getPackageManager().movePackage(mPackageName, observer,
PackageManager.MOVE_EXTERNAL_MEDIA);
} else {
getPackageManager().movePackageAndData(mPackageName, mVolume.fsUuid, observer);
}
observer.finished.await();
return observer.returnCode;
} catch (Exception e) {
Log.e(TAG, "Failed to move", e);
return PackageManager.MOVE_FAILED_INTERNAL_ERROR;
}
}
@Override
protected void onPostExecute(Integer returnCode) {
final Context context = StorageWizardMoveProgress.this;
if (returnCode == PackageManager.MOVE_SUCCEEDED) {
finishAffinity();
} else {
Log.w(TAG, "Move failed with status " + returnCode);
Toast.makeText(context, moveStatusToMessage(returnCode), Toast.LENGTH_LONG).show();
finishAffinity();
}
}
}
} }