diff options
17 files changed, 295 insertions, 80 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0446178..866eaaa 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1489,8 +1489,17 @@ android:value="true" /> </activity> - <activity - android:name="Settings$PublicVolumeSettingsActivity" + <activity android:name="Settings$PrivateVolumeSettingsActivity" + android:label="@string/storage_settings_title" + android:taskAffinity="com.android.settings" + android:parentActivityName="Settings$StorageSettingsActivity"> + <meta-data android:name="com.android.settings.FRAGMENT_CLASS" + android:value="com.android.settings.deviceinfo.PrivateVolumeSettings" /> + <meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID" + android:resource="@id/storage_settings" /> + </activity> + + <activity android:name="Settings$PublicVolumeSettingsActivity" android:label="@string/storage_settings_title" android:taskAffinity="com.android.settings" android:parentActivityName="Settings$StorageSettingsActivity"> @@ -1508,8 +1517,7 @@ android:resource="@id/storage_settings" /> </activity> - <activity - android:name="Settings$PrivateVolumeForgetActivity" + <activity android:name="Settings$PrivateVolumeForgetActivity" android:label="@string/storage_settings_title" android:taskAffinity="com.android.settings" android:parentActivityName="Settings$StorageSettingsActivity" @@ -1541,17 +1549,20 @@ android:exported="false" /> <activity android:name=".deviceinfo.StorageWizardMigrateProgress" android:taskAffinity="com.android.settings.storage_wizard" - android:exported="false" /> + android:exported="true" + android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <activity android:name=".deviceinfo.StorageWizardReady" android:taskAffinity="com.android.settings.storage_wizard" - android:exported="false" /> + android:exported="true" + android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <activity android:name=".deviceinfo.StorageWizardMoveConfirm" android:taskAffinity="com.android.settings.storage_wizard" android:exported="false" /> <activity android:name=".deviceinfo.StorageWizardMoveProgress" android:taskAffinity="com.android.settings.storage_wizard" - android:exported="false" /> + android:exported="true" + android:permission="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <!-- Exported for SystemUI to trigger --> <receiver android:name=".deviceinfo.StorageUnmountReceiver" diff --git a/res/menu/storage_volume.xml b/res/menu/storage_volume.xml index 093a4bb..b461f46 100644 --- a/res/menu/storage_volume.xml +++ b/res/menu/storage_volume.xml @@ -28,6 +28,9 @@ android:id="@+id/storage_format" android:title="@string/storage_menu_format" /> <item + android:id="@+id/storage_migrate" + android:title="@string/storage_menu_migrate" /> + <item android:id="@+id/storage_usb" android:title="@string/storage_menu_usb" /> </menu> diff --git a/res/values/strings.xml b/res/values/strings.xml index f7d5900..6e597ca 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2285,10 +2285,12 @@ <string name="storage_menu_format">Erase & format</string> <!-- Storage setting. Menu option for erasing and formatting a storage device [CHAR LIMIT=30]--> <string name="storage_menu_format_internal">Erase & format as internal storage</string> - <!-- Storage setting. Menu option for USB transfer settings [CHAR LIMIT=30]--> - <string name="storage_menu_usb">USB computer connection</string> + <!-- Storage setting. Menu option for migrating data to a storage device [CHAR LIMIT=30]--> + <string name="storage_menu_migrate">Migrate data</string> <!-- Storage setting. Menu option for forgetting a storage device [CHAR LIMIT=30]--> <string name="storage_menu_forget">Forget</string> + <!-- Storage setting. Menu option for USB transfer settings [CHAR LIMIT=30]--> + <string name="storage_menu_usb">USB computer connection</string> <!-- Storage setting. Title for USB transfer settings [CHAR LIMIT=30]--> <string name="storage_title_usb">USB computer connection</string> @@ -2402,7 +2404,7 @@ <!-- Title of wizard step prompting user to start data migration [CHAR LIMIT=32] --> <string name="storage_wizard_migrate_confirm_title">Move data now</string> <!-- Body of wizard step providing details about data migration [CHAR LIMIT=NONE] --> - <string name="storage_wizard_migrate_confirm_body"><b>The move takes about <xliff:g id="time" example="1 hour">^1</xliff:g>. It will free <xliff:g id="size" example="1.2 GB">^2</xliff:g> of internal storage.</b></string> + <string name="storage_wizard_migrate_confirm_body"><b>The move takes about <xliff:g id="time" example="1 hour">^1</xliff:g>. It will free <xliff:g id="size" example="1.2 GB">^2</xliff:g> on <xliff:g id="name" example="Internal storage">^3</xliff:g>.</b></string> <!-- Title of wizard button prompting user to start data migration [CHAR LIMIT=32] --> <string name="storage_wizard_migrate_confirm_next">Move</string> diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index 88c8316..f073b43 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -33,8 +33,9 @@ public class Settings extends SettingsActivity { public static class VpnSettingsActivity extends SettingsActivity { /* empty */ } public static class DateTimeSettingsActivity extends SettingsActivity { /* empty */ } public static class StorageSettingsActivity extends SettingsActivity { /* empty */ } - public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ } public static class PrivateVolumeForgetActivity extends SettingsActivity { /* empty */ } + public static class PrivateVolumeSettingsActivity extends SettingsActivity { /* empty */ } + public static class PublicVolumeSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiSettingsActivity extends SettingsActivity { /* empty */ } public static class WifiP2pSettingsActivity extends SettingsActivity { /* empty */ } public static class InputMethodAndLanguageSettingsActivity extends SettingsActivity { /* empty */ } diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 5e1acb1..1ae923a 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -84,6 +84,7 @@ import com.android.settings.dashboard.DashboardTile; import com.android.settings.dashboard.NoHomeDialogFragment; import com.android.settings.dashboard.SearchResultsSummary; import com.android.settings.deviceinfo.PrivateVolumeForget; +import com.android.settings.deviceinfo.PrivateVolumeSettings; import com.android.settings.deviceinfo.PublicVolumeSettings; import com.android.settings.deviceinfo.StorageSettings; import com.android.settings.deviceinfo.UsbSettings; @@ -310,8 +311,9 @@ public class SettingsActivity extends Activity com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment.class.getName(), TextToSpeechSettings.class.getName(), StorageSettings.class.getName(), - PublicVolumeSettings.class.getName(), PrivateVolumeForget.class.getName(), + PrivateVolumeSettings.class.getName(), + PublicVolumeSettings.class.getName(), DevelopmentSettings.class.getName(), UsbSettings.class.getName(), AndroidBeam.class.getName(), diff --git a/src/com/android/settings/deviceinfo/MigrateEstimateTask.java b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java new file mode 100644 index 0000000..bc8ff92 --- /dev/null +++ b/src/com/android/settings/deviceinfo/MigrateEstimateTask.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.deviceinfo; + +import static com.android.settings.deviceinfo.StorageSettings.TAG; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.net.TrafficStats; +import android.os.AsyncTask; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.VolumeInfo; +import android.telecom.Log; +import android.text.format.DateUtils; +import android.text.format.Formatter; + +import com.android.internal.app.IMediaContainerService; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +public abstract class MigrateEstimateTask extends AsyncTask<Void, Void, Long> implements + ServiceConnection { + private static final String EXTRA_SIZE_BYTES = "size_bytes"; + + private static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName( + "com.android.defcontainer", "com.android.defcontainer.DefaultContainerService"); + + /** + * Assume roughly a Class 10 card. + */ + private static final long SPEED_ESTIMATE_BPS = 10 * TrafficStats.MB_IN_BYTES; + + private final Context mContext; + private final StorageManager mStorage; + + private final CountDownLatch mConnected = new CountDownLatch(1); + private IMediaContainerService mService; + + private long mSizeBytes = -1; + private long mTimeMillis = -1; + + public MigrateEstimateTask(Context context) { + mContext = context; + mStorage = context.getSystemService(StorageManager.class); + } + + public void copyFrom(Intent intent) { + mSizeBytes = intent.getLongExtra(EXTRA_SIZE_BYTES, -1); + } + + public void copyTo(Intent intent) { + intent.putExtra(EXTRA_SIZE_BYTES, mSizeBytes); + } + + @Override + protected Long doInBackground(Void... params) { + if (mSizeBytes != -1) { + return mSizeBytes; + } + + final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume(); + final VolumeInfo emulatedVol = mStorage.findEmulatedForPrivate(privateVol); + + final String path = emulatedVol.getPath().getAbsolutePath(); + Log.d(TAG, "Estimating for current path " + path); + + final Intent intent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT); + mContext.bindServiceAsUser(intent, this, Context.BIND_AUTO_CREATE, UserHandle.OWNER); + + try { + if (mConnected.await(15, TimeUnit.SECONDS)) { + return mService.calculateDirectorySize(path); + } + } catch (InterruptedException | RemoteException e) { + Log.w(TAG, "Failed to measure " + path); + } finally { + mContext.unbindService(this); + } + + return -1L; + } + + @Override + protected void onPostExecute(Long result) { + mSizeBytes = result; + mTimeMillis = (mSizeBytes * DateUtils.SECOND_IN_MILLIS) / SPEED_ESTIMATE_BPS; + + final String size = Formatter.formatFileSize(mContext, mSizeBytes); + final String time = DateUtils.formatDuration(mTimeMillis).toString(); + onPostExecute(size, time); + } + + public abstract void onPostExecute(String size, String time); + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + mService = IMediaContainerService.Stub.asInterface(service); + mConnected.countDown(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + // Ignored; we leave service in place for the background thread to + // run into DeadObjectException + } +} diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java index e16778f..669f2ed 100644 --- a/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java +++ b/src/com/android/settings/deviceinfo/PrivateVolumeFormat.java @@ -67,6 +67,7 @@ public class PrivateVolumeFormat extends InstrumentedFragment { final Intent intent = new Intent(getActivity(), StorageWizardFormatProgress.class); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORMAT_PRIVATE, false); + intent.putExtra(StorageWizardFormatConfirm.EXTRA_FORGET_UUID, mVolume.getFsUuid()); startActivity(intent); getActivity().finish(); } diff --git a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java index 3e2b570..e5f50dd 100644 --- a/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java +++ b/src/com/android/settings/deviceinfo/PrivateVolumeSettings.java @@ -34,6 +34,7 @@ import android.os.Bundle; import android.os.Environment; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.DiskInfo; import android.os.storage.StorageEventListener; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; @@ -271,6 +272,7 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { final MenuItem mount = menu.findItem(R.id.storage_mount); final MenuItem unmount = menu.findItem(R.id.storage_unmount); final MenuItem format = menu.findItem(R.id.storage_format); + final MenuItem migrate = menu.findItem(R.id.storage_migrate); final MenuItem usb = menu.findItem(R.id.storage_usb); // Actions live in menu for non-internal private volumes; they're shown @@ -287,6 +289,11 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { format.setVisible(true); } + // Only offer to migrate when not current storage + final VolumeInfo privateVol = getActivity().getPackageManager() + .getPrimaryStorageCurrentVolume(); + migrate.setVisible(!Objects.equals(mVolume, privateVol)); + // TODO: show usb if we jumped past first screen usb.setVisible(false); } @@ -312,6 +319,11 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { startFragment(this, PrivateVolumeFormat.class.getCanonicalName(), R.string.storage_menu_format, 0, args); return true; + case R.id.storage_migrate: + final Intent intent = new Intent(context, StorageWizardMigrateConfirm.class); + intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId()); + startActivity(intent); + return true; case R.id.storage_usb: startFragment(this, UsbSettings.class.getCanonicalName(), R.string.storage_title_usb, 0, null); @@ -442,8 +454,8 @@ public class PrivateVolumeSettings extends SettingsPreferenceFragment { } @Override - public void onVolumeMetadataChanged(String fsUuid) { - if (Objects.equals(mVolume.getFsUuid(), fsUuid)) { + public void onVolumeRecordChanged(VolumeRecord rec) { + if (Objects.equals(mVolume.getFsUuid(), rec.getFsUuid())) { mVolume = mStorageManager.findVolumeById(mVolumeId); update(); } diff --git a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java index 1d7991d..dee644a 100644 --- a/src/com/android/settings/deviceinfo/PublicVolumeSettings.java +++ b/src/com/android/settings/deviceinfo/PublicVolumeSettings.java @@ -24,6 +24,7 @@ import android.os.storage.DiskInfo; import android.os.storage.StorageEventListener; import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; +import android.os.storage.VolumeRecord; import android.preference.Preference; import android.preference.PreferenceScreen; import android.provider.DocumentsContract; @@ -220,8 +221,8 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment { } @Override - public void onVolumeMetadataChanged(String fsUuid) { - if (Objects.equals(mVolume.getFsUuid(), fsUuid)) { + public void onVolumeRecordChanged(VolumeRecord rec) { + if (Objects.equals(mVolume.getFsUuid(), rec.getFsUuid())) { mVolume = mStorageManager.findVolumeById(mVolumeId); update(); } diff --git a/src/com/android/settings/deviceinfo/StorageWizardBase.java b/src/com/android/settings/deviceinfo/StorageWizardBase.java index 42c74a5..31f7af4 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardBase.java +++ b/src/com/android/settings/deviceinfo/StorageWizardBase.java @@ -35,6 +35,8 @@ import com.android.setupwizardlib.view.NavigationBar; import com.android.setupwizardlib.view.NavigationBar.NavigationBarListener; import java.text.NumberFormat; +import java.util.List; +import java.util.Objects; public abstract class StorageWizardBase extends Activity implements NavigationBarListener { protected StorageManager mStorage; @@ -56,7 +58,7 @@ public abstract class StorageWizardBase extends Activity implements NavigationBa final String diskId = getIntent().getStringExtra(DiskInfo.EXTRA_DISK_ID); if (!TextUtils.isEmpty(diskId)) { mDisk = mStorage.findDiskById(diskId); - } else { + } else if (mVolume != null) { mDisk = mVolume.getDisk(); } @@ -130,4 +132,14 @@ public abstract class StorageWizardBase extends Activity implements NavigationBa public void onNavigateNext() { throw new UnsupportedOperationException(); } + + protected VolumeInfo findFirstVolume(int type) { + final List<VolumeInfo> vols = mStorage.getVolumes(); + for (VolumeInfo vol : vols) { + if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type)) { + return vol; + } + } + return null; + } } diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java index 81073d6..33f2173 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java +++ b/src/com/android/settings/deviceinfo/StorageWizardFormatConfirm.java @@ -25,6 +25,7 @@ import com.android.settings.R; public class StorageWizardFormatConfirm extends StorageWizardBase { public static final String EXTRA_FORMAT_PRIVATE = "format_private"; + public static final String EXTRA_FORGET_UUID = "forget_uuid"; private boolean mFormatPrivate; @@ -56,6 +57,7 @@ public class StorageWizardFormatConfirm extends StorageWizardBase { final Intent intent = new Intent(this, StorageWizardFormatProgress.class); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); intent.putExtra(EXTRA_FORMAT_PRIVATE, mFormatPrivate); + intent.putExtra(EXTRA_FORGET_UUID, getIntent().getStringExtra(EXTRA_FORGET_UUID)); startActivity(intent); finishAffinity(); } diff --git a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java index e60bbcf..9ab714a 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java +++ b/src/com/android/settings/deviceinfo/StorageWizardFormatProgress.java @@ -23,6 +23,8 @@ import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.os.storage.DiskInfo; +import android.os.storage.VolumeInfo; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Toast; @@ -72,12 +74,25 @@ public class StorageWizardFormatProgress extends StorageWizardBase { protected void onPostExecute(Exception e) { final Context context = StorageWizardFormatProgress.this; if (e == null) { + final String forgetUuid = getIntent().getStringExtra( + StorageWizardFormatConfirm.EXTRA_FORGET_UUID); + if (!TextUtils.isEmpty(forgetUuid)) { + mStorage.forgetVolume(forgetUuid); + } + + final boolean offerMigrate; if (mFormatPrivate) { - // TODO: bring back migration once implemented -// final Intent intent = new Intent(context, StorageWizardMigrate.class); -// intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); -// startActivity(intent); - final Intent intent = new Intent(context, StorageWizardReady.class); + // Offer to migrate only if storage is currently internal + final VolumeInfo privateVol = getPackageManager() + .getPrimaryStorageCurrentVolume(); + offerMigrate = (privateVol != null + && VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.getId())); + } else { + offerMigrate = false; + } + + if (offerMigrate) { + final Intent intent = new Intent(context, StorageWizardMigrate.class); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); startActivity(intent); } else { diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrate.java b/src/com/android/settings/deviceinfo/StorageWizardMigrate.java index 4d42613..7831a07 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMigrate.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMigrate.java @@ -19,8 +19,6 @@ package com.android.settings.deviceinfo; import android.content.Intent; import android.os.Bundle; import android.os.storage.DiskInfo; -import android.text.format.DateUtils; -import android.text.format.Formatter; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; @@ -29,6 +27,8 @@ import com.android.internal.util.Preconditions; import com.android.settings.R; public class StorageWizardMigrate extends StorageWizardBase { + private MigrateEstimateTask mEstimate; + private RadioButton mRadioNow; private RadioButton mRadioLater; @@ -39,11 +39,8 @@ public class StorageWizardMigrate extends StorageWizardBase { Preconditions.checkNotNull(mDisk); - final String time = DateUtils.formatDuration(0).toString(); - final String size = Formatter.formatFileSize(this, 0); - setHeaderText(R.string.storage_wizard_migrate_title, mDisk.getDescription()); - setBodyText(R.string.storage_wizard_migrate_body, mDisk.getDescription(), time, size); + setBodyText(R.string.memory_calculating_size); mRadioNow = (RadioButton) findViewById(R.id.storage_wizard_migrate_now); mRadioLater = (RadioButton) findViewById(R.id.storage_wizard_migrate_later); @@ -52,6 +49,17 @@ public class StorageWizardMigrate extends StorageWizardBase { mRadioLater.setOnCheckedChangeListener(mRadioListener); mRadioNow.setChecked(true); + + mEstimate = new MigrateEstimateTask(this) { + @Override + public void onPostExecute(String size, String time) { + setBodyText(R.string.storage_wizard_migrate_body, + mDisk.getDescription(), time, size); + } + }; + + mEstimate.copyFrom(getIntent()); + mEstimate.execute(); } private final OnCheckedChangeListener mRadioListener = new OnCheckedChangeListener() { @@ -72,6 +80,7 @@ public class StorageWizardMigrate extends StorageWizardBase { if (mRadioNow.isChecked()) { final Intent intent = new Intent(this, StorageWizardMigrateConfirm.class); intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); + mEstimate.copyTo(intent); startActivity(intent); } else if (mRadioLater.isChecked()) { final Intent intent = new Intent(this, StorageWizardReady.class); diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java index 9aa1441..daa76d7 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateConfirm.java @@ -17,36 +17,54 @@ package com.android.settings.deviceinfo; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Bundle; -import android.os.storage.DiskInfo; -import android.text.format.DateUtils; -import android.text.format.Formatter; +import android.os.storage.VolumeInfo; -import com.android.internal.util.Preconditions; import com.android.settings.R; public class StorageWizardMigrateConfirm extends StorageWizardBase { + private MigrateEstimateTask mEstimate; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.storage_wizard_generic); - Preconditions.checkNotNull(mDisk); + // When called with just disk, find the first private volume + if (mVolume == null) { + mVolume = findFirstVolume(VolumeInfo.TYPE_PRIVATE); + } + + final VolumeInfo sourceVol = getPackageManager().getPrimaryStorageCurrentVolume(); + final String sourceDescrip = mStorage.getBestVolumeDescription(sourceVol); + final String targetDescrip = mStorage.getBestVolumeDescription(mVolume); - final String time = DateUtils.formatDuration(0).toString(); - final String size = Formatter.formatFileSize(this, 0); + setHeaderText(R.string.storage_wizard_migrate_confirm_title, targetDescrip); + setBodyText(R.string.memory_calculating_size); + setSecondaryBodyText(R.string.storage_wizard_migrate_details, targetDescrip); - setHeaderText(R.string.storage_wizard_migrate_confirm_title, mDisk.getDescription()); - setBodyText(R.string.storage_wizard_migrate_confirm_body, time, size); - setSecondaryBodyText(R.string.storage_wizard_migrate_details, mDisk.getDescription()); + mEstimate = new MigrateEstimateTask(this) { + @Override + public void onPostExecute(String size, String time) { + setBodyText(R.string.storage_wizard_migrate_confirm_body, time, size, + sourceDescrip); + } + }; + + mEstimate.copyFrom(getIntent()); + mEstimate.execute(); getNextButton().setText(R.string.storage_wizard_migrate_confirm_next); } @Override public void onNavigateNext() { + final int moveId = getPackageManager().movePrimaryStorage(mVolume); + final Intent intent = new Intent(this, StorageWizardMigrateProgress.class); - intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); + intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, mVolume.getId()); + intent.putExtra(PackageManager.EXTRA_MOVE_ID, moveId); startActivity(intent); finishAffinity(); } diff --git a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java index b53b250..70d93f8 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMigrateProgress.java @@ -16,13 +16,15 @@ package com.android.settings.deviceinfo; +import static android.content.pm.PackageManager.EXTRA_MOVE_ID; import static com.android.settings.deviceinfo.StorageSettings.TAG; import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.MoveCallback; import android.os.Bundle; -import android.os.SystemClock; +import android.os.Handler; import android.os.storage.DiskInfo; import android.util.Log; import android.view.View; @@ -32,45 +34,51 @@ import com.android.internal.util.Preconditions; import com.android.settings.R; public class StorageWizardMigrateProgress extends StorageWizardBase { + private int mMoveId; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.storage_wizard_progress); - Preconditions.checkNotNull(mDisk); + Preconditions.checkNotNull(mVolume); - setHeaderText(R.string.storage_wizard_migrate_progress_title, mDisk.getDescription()); - setBodyText(R.string.storage_wizard_migrate_details, mDisk.getDescription()); + mMoveId = getIntent().getIntExtra(EXTRA_MOVE_ID, -1); - setCurrentProgress(20); + final String descrip = mStorage.getBestVolumeDescription(mVolume); + setHeaderText(R.string.storage_wizard_migrate_progress_title, descrip); + setBodyText(R.string.storage_wizard_migrate_details, descrip); getNextButton().setVisibility(View.GONE); - new MigrateTask().execute(); + // Register for updates and push through current status + getPackageManager().registerMoveCallback(mCallback, new Handler()); + mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1); } - public class MigrateTask extends AsyncTask<Void, Void, Exception> { + private final MoveCallback mCallback = new MoveCallback() { @Override - protected Exception doInBackground(Void... params) { - // TODO: wire up migration - SystemClock.sleep(2000); - return null; - } + public void onStatusChanged(int moveId, int status, long estMillis) { + if (mMoveId != moveId) return; - @Override - protected void onPostExecute(Exception e) { final Context context = StorageWizardMigrateProgress.this; - if (e == null) { - final Intent intent = new Intent(context, StorageWizardReady.class); - intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); - startActivity(intent); + if (PackageManager.isMoveStatusFinished(status)) { + Log.d(TAG, "Finished with status " + status); + if (status == PackageManager.MOVE_SUCCEEDED) { + if (mDisk != null) { + final Intent intent = new Intent(context, StorageWizardReady.class); + intent.putExtra(DiskInfo.EXTRA_DISK_ID, mDisk.getId()); + startActivity(intent); + } + } else { + Toast.makeText(context, getString(R.string.insufficient_storage), + Toast.LENGTH_LONG).show(); + } finishAffinity(); } else { - Log.e(TAG, "Failed to migrate", e); - Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show(); - finishAffinity(); + setCurrentProgress(status); } } - } + }; } diff --git a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java index 1202b9e..86e623f 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java +++ b/src/com/android/settings/deviceinfo/StorageWizardMoveProgress.java @@ -49,7 +49,7 @@ public class StorageWizardMoveProgress extends StorageWizardBase { // Register for updates and push through current status getPackageManager().registerMoveCallback(mCallback, new Handler()); - mCallback.onStatusChanged(mMoveId, null, getPackageManager().getMoveStatus(mMoveId), -1); + mCallback.onStatusChanged(mMoveId, getPackageManager().getMoveStatus(mMoveId), -1); } @Override @@ -60,7 +60,7 @@ public class StorageWizardMoveProgress extends StorageWizardBase { private final MoveCallback mCallback = new MoveCallback() { @Override - public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) { + public void onStatusChanged(int moveId, int status, long estMillis) { if (mMoveId != moveId) return; if (PackageManager.isMoveStatusFinished(status)) { diff --git a/src/com/android/settings/deviceinfo/StorageWizardReady.java b/src/com/android/settings/deviceinfo/StorageWizardReady.java index 26038ce..6d8846b 100644 --- a/src/com/android/settings/deviceinfo/StorageWizardReady.java +++ b/src/com/android/settings/deviceinfo/StorageWizardReady.java @@ -22,9 +22,6 @@ import android.os.storage.VolumeInfo; import com.android.internal.util.Preconditions; import com.android.settings.R; -import java.util.List; -import java.util.Objects; - public class StorageWizardReady extends StorageWizardBase { @Override protected void onCreate(Bundle savedInstanceState) { @@ -37,19 +34,14 @@ public class StorageWizardReady extends StorageWizardBase { // TODO: handle mixed partition cases instead of just guessing based on // first volume type we encounter - final List<VolumeInfo> vols = mStorage.getVolumes(); - for (VolumeInfo vol : vols) { - if (!Objects.equals(mDisk.getId(), vol.getDiskId())) continue; - - if (vol.getType() == VolumeInfo.TYPE_PUBLIC) { - setBodyText(R.string.storage_wizard_ready_external_body, - mDisk.getDescription()); - break; - } else if (vol.getType() == VolumeInfo.TYPE_PRIVATE) { - setBodyText(R.string.storage_wizard_ready_internal_body, - mDisk.getDescription()); - break; - } + final VolumeInfo publicVol = findFirstVolume(VolumeInfo.TYPE_PUBLIC); + final VolumeInfo privateVol = findFirstVolume(VolumeInfo.TYPE_PRIVATE); + if (publicVol != null) { + setBodyText(R.string.storage_wizard_ready_external_body, + mDisk.getDescription()); + } else if (privateVol != null) { + setBodyText(R.string.storage_wizard_ready_internal_body, + mDisk.getDescription()); } getNextButton().setText(R.string.done); |