Merge "Returning to wizard, split move events." into mnc-dev

This commit is contained in:
Jeff Sharkey
2015-04-30 00:38:30 +00:00
committed by Android (Google) Code Review
12 changed files with 370 additions and 109 deletions

View File

@@ -62,6 +62,7 @@ import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -1561,13 +1562,7 @@ final class ApplicationPackageManager extends PackageManager {
public @Nullable VolumeInfo getPrimaryStorageCurrentVolume() {
final StorageManager storage = mContext.getSystemService(StorageManager.class);
final String volumeUuid = storage.getPrimaryStorageUuid();
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
return storage.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
} else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
return storage.getPrimaryPhysicalVolume();
} else {
return storage.findVolumeByUuid(volumeUuid);
}
return storage.findVolumeByQualifiedUuid(volumeUuid);
}
@Override
@@ -2055,7 +2050,8 @@ final class ApplicationPackageManager extends PackageManager {
/** {@hide} */
private static class MoveCallbackDelegate extends IPackageMoveObserver.Stub implements
Handler.Callback {
private static final int MSG_STATUS_CHANGED = 1;
private static final int MSG_CREATED = 1;
private static final int MSG_STATUS_CHANGED = 2;
final MoveCallback mCallback;
final Handler mHandler;
@@ -2068,23 +2064,36 @@ final class ApplicationPackageManager extends PackageManager {
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_STATUS_CHANGED:
case MSG_CREATED: {
final SomeArgs args = (SomeArgs) msg.obj;
mCallback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
(long) args.arg4);
mCallback.onCreated(args.argi1, (Bundle) args.arg2);
args.recycle();
return true;
}
case MSG_STATUS_CHANGED: {
final SomeArgs args = (SomeArgs) msg.obj;
mCallback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
args.recycle();
return true;
}
}
return false;
}
@Override
public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
public void onCreated(int moveId, Bundle extras) {
final SomeArgs args = SomeArgs.obtain();
args.argi1 = moveId;
args.arg2 = moveTitle;
args.argi3 = status;
args.arg4 = estMillis;
args.arg2 = extras;
mHandler.obtainMessage(MSG_CREATED, args).sendToTarget();
}
@Override
public void onStatusChanged(int moveId, int status, long estMillis) {
final SomeArgs args = SomeArgs.obtain();
args.argi1 = moveId;
args.argi2 = status;
args.arg3 = estMillis;
mHandler.obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
}
}

View File

@@ -17,10 +17,13 @@
package android.content.pm;
import android.os.Bundle;
/**
* Callback for moving package resources from the Package Manager.
* @hide
*/
oneway interface IPackageMoveObserver {
void onStatusChanged(int moveId, String moveTitle, int status, long estMillis);
void onCreated(int moveId, in Bundle extras);
void onStatusChanged(int moveId, int status, long estMillis);
}

View File

@@ -4212,8 +4212,8 @@ public abstract class PackageManager {
/** {@hide} */
public static abstract class MoveCallback {
public abstract void onStatusChanged(int moveId, String moveTitle, int status,
long estMillis);
public void onCreated(int moveId, Bundle extras) {}
public abstract void onStatusChanged(int moveId, int status, long estMillis);
}
/** {@hide} */

View File

@@ -758,7 +758,6 @@ public class Environment {
* @hide
*/
public static File maybeTranslateEmulatedPathToInternal(File path) {
// TODO: bring back this optimization
return path;
return StorageManager.maybeTranslateEmulatedPathToInternal(path);
}
}

View File

@@ -390,7 +390,7 @@ public class FileUtils {
* attacks.
*/
public static boolean contains(File dir, File file) {
if (file == null) return false;
if (dir == null || file == null) return false;
String dirPath = dir.getAbsolutePath();
String filePath = file.getAbsolutePath();

View File

@@ -91,10 +91,17 @@ public interface IMountServiceListener extends IInterface {
reply.writeNoException();
return true;
}
case TRANSACTION_onVolumeMetadataChanged: {
case TRANSACTION_onVolumeRecordChanged: {
data.enforceInterface(DESCRIPTOR);
final VolumeRecord rec = (VolumeRecord) data.readParcelable(null);
onVolumeRecordChanged(rec);
reply.writeNoException();
return true;
}
case TRANSACTION_onVolumeForgotten: {
data.enforceInterface(DESCRIPTOR);
final String fsUuid = data.readString();
onVolumeMetadataChanged(fsUuid);
onVolumeForgotten(fsUuid);
reply.writeNoException();
return true;
}
@@ -192,13 +199,29 @@ public interface IMountServiceListener extends IInterface {
}
@Override
public void onVolumeMetadataChanged(String fsUuid) throws RemoteException {
public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeParcelable(rec, 0);
mRemote.transact(Stub.TRANSACTION_onVolumeRecordChanged, _data, _reply,
android.os.IBinder.FLAG_ONEWAY);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void onVolumeForgotten(String fsUuid) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(fsUuid);
mRemote.transact(Stub.TRANSACTION_onVolumeMetadataChanged, _data, _reply,
mRemote.transact(Stub.TRANSACTION_onVolumeForgotten, _data, _reply,
android.os.IBinder.FLAG_ONEWAY);
_reply.readException();
} finally {
@@ -228,8 +251,9 @@ public interface IMountServiceListener extends IInterface {
static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_onVolumeStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_onVolumeMetadataChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_onVolumeRecordChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_onVolumeForgotten = (IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 5);
}
/**
@@ -252,8 +276,8 @@ public interface IMountServiceListener extends IInterface {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
throws RemoteException;
public void onVolumeMetadataChanged(String fsUuid) throws RemoteException;
public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException;
public void onVolumeForgotten(String fsUuid) throws RemoteException;
public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
}

View File

@@ -41,7 +41,10 @@ public class StorageEventListener {
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
}
public void onVolumeMetadataChanged(String fsUuid) {
public void onVolumeRecordChanged(VolumeRecord rec) {
}
public void onVolumeForgotten(String fsUuid) {
}
public void onDiskScanned(DiskInfo disk, int volumeCount) {

View File

@@ -93,8 +93,9 @@ public class StorageManager {
Handler.Callback {
private static final int MSG_STORAGE_STATE_CHANGED = 1;
private static final int MSG_VOLUME_STATE_CHANGED = 2;
private static final int MSG_VOLUME_METADATA_CHANGED = 3;
private static final int MSG_DISK_SCANNED = 4;
private static final int MSG_VOLUME_RECORD_CHANGED = 3;
private static final int MSG_VOLUME_FORGOTTEN = 4;
private static final int MSG_DISK_SCANNED = 5;
final StorageEventListener mCallback;
final Handler mHandler;
@@ -117,8 +118,12 @@ public class StorageManager {
mCallback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
args.recycle();
return true;
case MSG_VOLUME_METADATA_CHANGED:
mCallback.onVolumeMetadataChanged((String) args.arg1);
case MSG_VOLUME_RECORD_CHANGED:
mCallback.onVolumeRecordChanged((VolumeRecord) args.arg1);
args.recycle();
return true;
case MSG_VOLUME_FORGOTTEN:
mCallback.onVolumeForgotten((String) args.arg1);
args.recycle();
return true;
case MSG_DISK_SCANNED:
@@ -154,10 +159,17 @@ public class StorageManager {
}
@Override
public void onVolumeMetadataChanged(String fsUuid) {
public void onVolumeRecordChanged(VolumeRecord rec) {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = rec;
mHandler.obtainMessage(MSG_VOLUME_RECORD_CHANGED, args).sendToTarget();
}
@Override
public void onVolumeForgotten(String fsUuid) {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = fsUuid;
mHandler.obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
mHandler.obtainMessage(MSG_VOLUME_FORGOTTEN, args).sendToTarget();
}
@Override
@@ -246,8 +258,9 @@ public class StorageManager {
}
/** {@hide} */
@Deprecated
public static StorageManager from(Context context) {
return (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
return context.getSystemService(StorageManager.class);
}
/**
@@ -535,6 +548,17 @@ public class StorageManager {
return findVolumeById(privateVol.getId().replace("private", "emulated"));
}
/** {@hide} */
public @Nullable VolumeInfo findVolumeByQualifiedUuid(String volumeUuid) {
if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
return findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL);
} else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
return getPrimaryPhysicalVolume();
} else {
return findVolumeByUuid(volumeUuid);
}
}
/** {@hide} */
public @NonNull List<VolumeInfo> getVolumes() {
try {
@@ -555,6 +579,8 @@ public class StorageManager {
/** {@hide} */
public @Nullable String getBestVolumeDescription(VolumeInfo vol) {
if (vol == null) return null;
// Nickname always takes precedence when defined
if (!TextUtils.isEmpty(vol.fsUuid)) {
final VolumeRecord rec = findRecordByUuid(vol.fsUuid);
@@ -861,6 +887,27 @@ public class StorageManager {
DEFAULT_FULL_THRESHOLD_BYTES);
}
/** {@hide} */
public static File maybeTranslateEmulatedPathToInternal(File path) {
final IMountService mountService = IMountService.Stub.asInterface(
ServiceManager.getService("mount"));
try {
final VolumeInfo[] vols = mountService.getVolumes(0);
for (VolumeInfo vol : vols) {
if ((vol.getType() == VolumeInfo.TYPE_EMULATED
|| vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) {
final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(),
vol.getInternalPath(), path);
if (internalPath != null) {
return internalPath;
}
}
}
} catch (RemoteException ignored) {
}
return path;
}
/// Consts to match the password types in cryptfs.h
/** @hide */
public static final int CRYPT_TYPE_PASSWORD = 0;

View File

@@ -129,6 +129,7 @@ public class VolumeInfo implements Parcelable {
public String fsUuid;
public String fsLabel;
public String path;
public String internalPath;
/** Framework state */
public final int mtpIndex;
@@ -155,6 +156,7 @@ public class VolumeInfo implements Parcelable {
fsUuid = parcel.readString();
fsLabel = parcel.readString();
path = parcel.readString();
internalPath = parcel.readString();
mtpIndex = parcel.readInt();
}
@@ -248,7 +250,11 @@ public class VolumeInfo implements Parcelable {
}
public File getPath() {
return new File(path);
return (path != null) ? new File(path) : null;
}
public File getInternalPath() {
return (internalPath != null) ? new File(internalPath) : null;
}
public File getPathForUser(int userId) {
@@ -335,14 +341,11 @@ public class VolumeInfo implements Parcelable {
final Uri uri;
if (type == VolumeInfo.TYPE_PUBLIC) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid);
} else if (VolumeInfo.ID_EMULATED_INTERNAL.equals(id)) {
} else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
DOCUMENT_ROOT_PRIMARY_EMULATED);
} else if (type == VolumeInfo.TYPE_EMULATED) {
// TODO: build intent once supported
uri = null;
} else {
throw new IllegalArgumentException();
return null;
}
final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE_DOCUMENT_ROOT);
@@ -372,6 +375,7 @@ public class VolumeInfo implements Parcelable {
pw.printPair("fsLabel", fsLabel);
pw.println();
pw.printPair("path", path);
pw.printPair("internalPath", internalPath);
pw.printPair("mtpIndex", mtpIndex);
pw.decreaseIndent();
pw.println();
@@ -437,6 +441,7 @@ public class VolumeInfo implements Parcelable {
parcel.writeString(fsUuid);
parcel.writeString(fsLabel);
parcel.writeString(path);
parcel.writeString(internalPath);
parcel.writeInt(mtpIndex);
}
}

View File

@@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.MoveCallback;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.os.storage.DiskInfo;
@@ -36,6 +37,7 @@ import android.os.storage.VolumeRecord;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.R;
import com.android.systemui.SystemUI;
@@ -57,6 +59,16 @@ public class StorageNotification extends SystemUI {
private NotificationManager mNotificationManager;
private StorageManager mStorageManager;
private static class MoveInfo {
public int moveId;
public Bundle extras;
public String packageName;
public String label;
public String volumeUuid;
}
private final SparseArray<MoveInfo> mMoves = new SparseArray<>();
private final StorageEventListener mListener = new StorageEventListener() {
@Override
public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
@@ -64,20 +76,20 @@ public class StorageNotification extends SystemUI {
}
@Override
public void onVolumeMetadataChanged(String fsUuid) {
public void onVolumeRecordChanged(VolumeRecord rec) {
// Avoid kicking notifications when getting early metadata before
// mounted. If already mounted, we're being kicked because of a
// nickname or init'ed change.
final VolumeInfo vol = mStorageManager.findVolumeByUuid(fsUuid);
final VolumeInfo vol = mStorageManager.findVolumeByUuid(rec.getFsUuid());
if (vol != null && vol.isMountedReadable()) {
onVolumeStateChangedInternal(vol);
}
}
final VolumeRecord rec = mStorageManager.findRecordByUuid(fsUuid);
if (rec == null) {
// Private volume was probably just forgotten
mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
}
@Override
public void onVolumeForgotten(String fsUuid) {
// Stop annoying the user
mNotificationManager.cancelAsUser(fsUuid, PRIVATE_ID, UserHandle.ALL);
}
@Override
@@ -97,11 +109,30 @@ public class StorageNotification extends SystemUI {
private final MoveCallback mMoveCallback = new MoveCallback() {
@Override
public void onStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
public void onCreated(int moveId, Bundle extras) {
final MoveInfo move = new MoveInfo();
move.moveId = moveId;
move.extras = extras;
if (extras != null) {
move.packageName = extras.getString(Intent.EXTRA_PACKAGE_NAME);
move.label = extras.getString(Intent.EXTRA_TITLE);
move.volumeUuid = extras.getString(VolumeRecord.EXTRA_FS_UUID);
}
mMoves.put(moveId, move);
}
@Override
public void onStatusChanged(int moveId, int status, long estMillis) {
final MoveInfo move = mMoves.get(moveId);
if (move == null) {
Log.w(TAG, "Ignoring unknown move " + moveId);
return;
}
if (PackageManager.isMoveStatusFinished(status)) {
onMoveFinished(moveId, moveTitle, status);
onMoveFinished(move, status);
} else {
onMoveProgress(moveId, moveTitle, status, estMillis);
onMoveProgress(move, status, estMillis);
}
}
};
@@ -149,10 +180,10 @@ public class StorageNotification extends SystemUI {
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
.setContentIntent(buildForgetPendingIntent(rec))
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setContentIntent(buildForgetPendingIntent(rec))
.setCategory(Notification.CATEGORY_SYSTEM)
.setOngoing(true)
.build();
@@ -175,10 +206,10 @@ public class StorageNotification extends SystemUI {
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
.setContentIntent(buildInitPendingIntent(disk))
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setContentIntent(buildInitPendingIntent(disk))
.setCategory(Notification.CATEGORY_ERROR)
.build();
@@ -280,13 +311,13 @@ public class StorageNotification extends SystemUI {
final CharSequence text = mContext.getString(
R.string.ext_media_new_notification_message, disk.getDescription());
final PendingIntent initAction = buildInitPendingIntent(vol);
final PendingIntent initIntent = buildInitPendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
.addAction(new Action(0, mContext.getString(R.string.ext_media_init_action),
initAction))
initIntent))
.addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(initAction)
.setContentIntent(initIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
.setCategory(Notification.CATEGORY_SYSTEM)
.build();
@@ -296,13 +327,13 @@ public class StorageNotification extends SystemUI {
final CharSequence text = mContext.getString(
R.string.ext_media_ready_notification_message, disk.getDescription());
final PendingIntent browseAction = buildBrowsePendingIntent(vol);
final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
return buildNotificationBuilder(vol, title, text)
.addAction(new Action(0, mContext.getString(R.string.ext_media_browse_action),
browseAction))
browseIntent))
.addAction(new Action(0, mContext.getString(R.string.ext_media_unmount_action),
buildUnmountPendingIntent(vol)))
.setContentIntent(browseAction)
.setContentIntent(browseIntent)
.setDeleteIntent(buildSnoozeIntent(vol))
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW)
@@ -337,7 +368,7 @@ public class StorageNotification extends SystemUI {
R.string.ext_media_unmountable_notification_message, disk.getDescription());
return buildNotificationBuilder(vol, title, text)
.setContentIntent(buildDetailsPendingIntent(vol))
.setContentIntent(buildVolumeSettingsPendingIntent(vol))
.setCategory(Notification.CATEGORY_ERROR)
.build();
}
@@ -376,10 +407,10 @@ public class StorageNotification extends SystemUI {
.build();
}
private void onMoveProgress(int moveId, String moveTitle, int status, long estMillis) {
private void onMoveProgress(MoveInfo move, int status, long estMillis) {
final CharSequence title;
if (!TextUtils.isEmpty(moveTitle)) {
title = mContext.getString(R.string.ext_media_move_specific_title, moveTitle);
if (!TextUtils.isEmpty(move.label)) {
title = mContext.getString(R.string.ext_media_move_specific_title, move.label);
} else {
title = mContext.getString(R.string.ext_media_move_title);
}
@@ -391,11 +422,19 @@ public class StorageNotification extends SystemUI {
text = DateUtils.formatDuration(estMillis);
}
final PendingIntent intent;
if (move.packageName != null) {
intent = buildWizardMovePendingIntent(move);
} else {
intent = buildWizardMigratePendingIntent(move);
}
final Notification notif = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.stat_notify_sdcard)
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
.setContentIntent(intent)
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
@@ -405,19 +444,19 @@ public class StorageNotification extends SystemUI {
.setOngoing(true)
.build();
mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
}
private void onMoveFinished(int moveId, String moveTitle, int status) {
if (!TextUtils.isEmpty(moveTitle)) {
private void onMoveFinished(MoveInfo move, int status) {
if (move.packageName != null) {
// We currently ignore finished app moves; just clear the last
// published progress
mNotificationManager.cancelAsUser(moveTitle, MOVE_ID, UserHandle.ALL);
mNotificationManager.cancelAsUser(move.packageName, MOVE_ID, UserHandle.ALL);
return;
}
final VolumeInfo vol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
final String descrip = mStorageManager.getBestVolumeDescription(vol);
final VolumeInfo privateVol = mContext.getPackageManager().getPrimaryStorageCurrentVolume();
final String descrip = mStorageManager.getBestVolumeDescription(privateVol);
final CharSequence title;
final CharSequence text;
@@ -429,19 +468,29 @@ public class StorageNotification extends SystemUI {
text = mContext.getString(R.string.ext_media_move_failure_message);
}
// Jump back into the wizard flow if we moved to a real disk
final PendingIntent intent;
if (privateVol != null && privateVol.getDisk() != null) {
intent = buildWizardReadyPendingIntent(privateVol.getDisk());
} else {
intent = buildVolumeSettingsPendingIntent(privateVol);
}
final Notification notif = new Notification.Builder(mContext)
.setSmallIcon(R.drawable.stat_notify_sdcard)
.setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentTitle(title)
.setContentText(text)
.setContentIntent(intent)
.setStyle(new Notification.BigTextStyle().bigText(text))
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setLocalOnly(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW)
.setAutoCancel(true)
.build();
mNotificationManager.notifyAsUser(moveTitle, MOVE_ID, notif, UserHandle.ALL);
mNotificationManager.notifyAsUser(move.packageName, MOVE_ID, notif, UserHandle.ALL);
}
private int getSmallIcon(DiskInfo disk, int state) {
@@ -513,10 +562,20 @@ public class StorageNotification extends SystemUI {
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
private PendingIntent buildDetailsPendingIntent(VolumeInfo vol) {
private PendingIntent buildVolumeSettingsPendingIntent(VolumeInfo vol) {
final Intent intent = new Intent();
intent.setClassName("com.android.settings",
"com.android.settings.Settings$PublicVolumeSettingsActivity");
switch (vol.getType()) {
case VolumeInfo.TYPE_PRIVATE:
intent.setClassName("com.android.settings",
"com.android.settings.Settings$PrivateVolumeSettingsActivity");
break;
case VolumeInfo.TYPE_PUBLIC:
intent.setClassName("com.android.settings",
"com.android.settings.Settings$PublicVolumeSettingsActivity");
break;
default:
return null;
}
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
final int requestKey = vol.getId().hashCode();
@@ -543,4 +602,38 @@ public class StorageNotification extends SystemUI {
return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
private PendingIntent buildWizardMigratePendingIntent(MoveInfo move) {
final Intent intent = new Intent();
intent.setClassName("com.android.settings",
"com.android.settings.deviceinfo.StorageWizardMigrateProgress");
intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
private PendingIntent buildWizardMovePendingIntent(MoveInfo move) {
final Intent intent = new Intent();
intent.setClassName("com.android.settings",
"com.android.settings.deviceinfo.StorageWizardMoveProgress");
intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
private PendingIntent buildWizardReadyPendingIntent(DiskInfo disk) {
final Intent intent = new Intent();
intent.setClassName("com.android.settings",
"com.android.settings.deviceinfo.StorageWizardReady");
intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.getId());
final int requestKey = disk.getId().hashCode();
return PendingIntent.getActivityAsUser(mContext, requestKey, intent,
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
}

View File

@@ -229,6 +229,7 @@ class MountService extends IMountService.Stub
public static final int VOLUME_FS_UUID_CHANGED = 653;
public static final int VOLUME_FS_LABEL_CHANGED = 654;
public static final int VOLUME_PATH_CHANGED = 655;
public static final int VOLUME_INTERNAL_PATH_CHANGED = 656;
public static final int VOLUME_DESTROYED = 659;
public static final int MOVE_STATUS = 660;
@@ -661,6 +662,9 @@ class MountService extends IMountService.Stub
try {
mConnector.execute("volume", "reset");
for (int userId : mStartedUsers) {
mConnector.execute("volume", "start_user", userId);
}
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to reset vold", e);
}
@@ -902,6 +906,14 @@ class MountService extends IMountService.Stub
}
break;
}
case VoldResponseCode.VOLUME_INTERNAL_PATH_CHANGED: {
if (cooked.length != 3) break;
final VolumeInfo vol = mVolumes.get(cooked[1]);
if (vol != null) {
vol.internalPath = cooked[2];
}
break;
}
case VoldResponseCode.VOLUME_DESTROYED: {
if (cooked.length != 2) break;
mVolumes.remove(cooked[1]);
@@ -1076,7 +1088,7 @@ class MountService extends IMountService.Stub
// TODO: estimate remaining time
try {
mMoveCallback.onStatusChanged(-1, null, status, -1);
mMoveCallback.onStatusChanged(-1, status, -1);
} catch (RemoteException ignored) {
}
@@ -1433,10 +1445,11 @@ class MountService extends IMountService.Stub
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
Preconditions.checkNotNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
rec.nickname = nickname;
mCallbacks.notifyVolumeMetadataChanged(fsUuid);
mCallbacks.notifyVolumeRecordChanged(rec);
writeSettingsLocked();
}
}
@@ -1446,10 +1459,11 @@ class MountService extends IMountService.Stub
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
Preconditions.checkNotNull(fsUuid);
synchronized (mLock) {
final VolumeRecord rec = mRecords.get(fsUuid);
rec.userFlags = (rec.userFlags & ~mask) | (flags & mask);
mCallbacks.notifyVolumeMetadataChanged(fsUuid);
mCallbacks.notifyVolumeRecordChanged(rec);
writeSettingsLocked();
}
}
@@ -1459,13 +1473,39 @@ class MountService extends IMountService.Stub
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
waitForReady();
Preconditions.checkNotNull(fsUuid);
synchronized (mLock) {
mRecords.remove(fsUuid);
mCallbacks.notifyVolumeMetadataChanged(fsUuid);
// TODO: tell vold to forget keys
// If this had been primary storage, revert back to internal and
// reset vold so we bind into new volume into place.
if (Objects.equals(mPrimaryStorageUuid, fsUuid)) {
mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
resetIfReadyAndConnected();
}
mCallbacks.notifyVolumeForgotten(fsUuid);
writeSettingsLocked();
}
}
private void forgetAll() {
synchronized (mLock) {
for (int i = 0; i < mRecords.size(); i++) {
final String fsUuid = mRecords.keyAt(i);
mCallbacks.notifyVolumeForgotten(fsUuid);
}
mRecords.clear();
writeSettingsLocked();
mPrimaryStorageUuid = StorageManager.UUID_PRIVATE_INTERNAL;
resetIfReadyAndConnected();
}
}
@Override
public String getPrimaryStorageUuid() {
enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
@@ -2818,8 +2858,9 @@ class MountService extends IMountService.Stub
private static class Callbacks extends Handler {
private static final int MSG_STORAGE_STATE_CHANGED = 1;
private static final int MSG_VOLUME_STATE_CHANGED = 2;
private static final int MSG_VOLUME_METADATA_CHANGED = 3;
private static final int MSG_DISK_SCANNED = 4;
private static final int MSG_VOLUME_RECORD_CHANGED = 3;
private static final int MSG_VOLUME_FORGOTTEN = 4;
private static final int MSG_DISK_SCANNED = 5;
private final RemoteCallbackList<IMountServiceListener>
mCallbacks = new RemoteCallbackList<>();
@@ -2863,8 +2904,12 @@ class MountService extends IMountService.Stub
callback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
break;
}
case MSG_VOLUME_METADATA_CHANGED: {
callback.onVolumeMetadataChanged((String) args.arg1);
case MSG_VOLUME_RECORD_CHANGED: {
callback.onVolumeRecordChanged((VolumeRecord) args.arg1);
break;
}
case MSG_VOLUME_FORGOTTEN: {
callback.onVolumeForgotten((String) args.arg1);
break;
}
case MSG_DISK_SCANNED: {
@@ -2890,10 +2935,16 @@ class MountService extends IMountService.Stub
obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget();
}
private void notifyVolumeMetadataChanged(String fsUuid) {
private void notifyVolumeRecordChanged(VolumeRecord rec) {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = rec.clone();
obtainMessage(MSG_VOLUME_RECORD_CHANGED, args).sendToTarget();
}
private void notifyVolumeForgotten(String fsUuid) {
final SomeArgs args = SomeArgs.obtain();
args.arg1 = fsUuid;
obtainMessage(MSG_VOLUME_METADATA_CHANGED, args).sendToTarget();
obtainMessage(MSG_VOLUME_FORGOTTEN, args).sendToTarget();
}
private void notifyDiskScanned(DiskInfo disk, int volumeCount) {
@@ -2909,11 +2960,8 @@ class MountService extends IMountService.Stub
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
for (String arg : args) {
if ("--clear".equals(arg)) {
synchronized (mLock) {
mRecords.clear();
writeSettingsLocked();
}
if ("--forget-all".equals(arg)) {
forgetAll();
}
}

View File

@@ -155,6 +155,7 @@ import android.os.storage.IMountService;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.security.KeyStore;
import android.security.SystemKeyStore;
import android.system.ErrnoException;
@@ -1558,6 +1559,11 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
}
@Override
public void onVolumeForgotten(String fsUuid) {
// TODO: remove all packages hosted on this uuid
}
};
private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int userId) {
@@ -14203,7 +14209,7 @@ public class PackageManagerService extends IPackageManager.Stub {
movePackageInternal(packageName, volumeUuid, moveId);
} catch (PackageManagerException e) {
Slog.d(TAG, "Failed to move " + packageName, e);
mMoveCallbacks.notifyStatusChanged(moveId, null,
mMoveCallbacks.notifyStatusChanged(moveId,
PackageManager.MOVE_FAILED_INTERNAL_ERROR);
}
return moveId;
@@ -14221,7 +14227,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final String packageAbiOverride;
final int appId;
final String seinfo;
final String moveTitle;
final String label;
// reader
synchronized (mPackages) {
@@ -14251,9 +14257,14 @@ public class PackageManagerService extends IPackageManager.Stub {
packageAbiOverride = ps.cpuAbiOverrideString;
appId = UserHandle.getAppId(pkg.applicationInfo.uid);
seinfo = pkg.applicationInfo.seinfo;
moveTitle = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
}
final Bundle extras = new Bundle();
extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
extras.putString(Intent.EXTRA_TITLE, label);
mMoveCallbacks.notifyCreated(moveId, extras);
int installFlags;
final boolean moveData;
@@ -14279,7 +14290,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
Slog.d(TAG, "Moving " + packageName + " from " + currentVolumeUuid + " to " + volumeUuid);
mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 10);
mMoveCallbacks.notifyStatusChanged(moveId, 10);
if (moveData) {
synchronized (mInstallLock) {
@@ -14299,7 +14310,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
mMoveCallbacks.notifyStatusChanged(moveId, moveTitle, 50);
mMoveCallbacks.notifyStatusChanged(moveId, 50);
final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
@Override
@@ -14326,15 +14337,15 @@ public class PackageManagerService extends IPackageManager.Stub {
final int status = PackageManager.installStatusToPublicStatus(returnCode);
switch (status) {
case PackageInstaller.STATUS_SUCCESS:
mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
mMoveCallbacks.notifyStatusChanged(moveId,
PackageManager.MOVE_SUCCEEDED);
break;
case PackageInstaller.STATUS_FAILURE_STORAGE:
mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
mMoveCallbacks.notifyStatusChanged(moveId,
PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
break;
default:
mMoveCallbacks.notifyStatusChanged(moveId, moveTitle,
mMoveCallbacks.notifyStatusChanged(moveId,
PackageManager.MOVE_FAILED_INTERNAL_ERROR);
break;
}
@@ -14357,12 +14368,19 @@ public class PackageManagerService extends IPackageManager.Stub {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
final int realMoveId = mNextMoveId.getAndIncrement();
final String realTitle = null;
final Bundle extras = new Bundle();
extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
mMoveCallbacks.notifyCreated(realMoveId, extras);
final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
@Override
public void onStatusChanged(int moveId, String title, int status, long estMillis) {
mMoveCallbacks.notifyStatusChanged(realMoveId, realTitle, status, estMillis);
public void onCreated(int moveId, Bundle extras) {
// Ignored
}
@Override
public void onStatusChanged(int moveId, int status, long estMillis) {
mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
}
};
@@ -14717,6 +14735,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
private static class MoveCallbacks extends Handler {
private static final int MSG_CREATED = 1;
private static final int MSG_STATUS_CHANGED = 2;
private final RemoteCallbackList<IPackageMoveObserver>
@@ -14754,26 +14773,37 @@ public class PackageManagerService extends IPackageManager.Stub {
private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
throws RemoteException {
switch (what) {
case MSG_CREATED: {
callback.onCreated(args.argi1, (Bundle) args.arg2);
break;
}
case MSG_STATUS_CHANGED: {
callback.onStatusChanged(args.argi1, (String) args.arg2, args.argi3,
(long) args.arg4);
callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
break;
}
}
}
private void notifyStatusChanged(int moveId, String moveTitle, int status) {
notifyStatusChanged(moveId, moveTitle, status, -1);
private void notifyCreated(int moveId, Bundle extras) {
Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
final SomeArgs args = SomeArgs.obtain();
args.argi1 = moveId;
args.arg2 = extras;
obtainMessage(MSG_CREATED, args).sendToTarget();
}
private void notifyStatusChanged(int moveId, String moveTitle, int status, long estMillis) {
private void notifyStatusChanged(int moveId, int status) {
notifyStatusChanged(moveId, status, -1);
}
private void notifyStatusChanged(int moveId, int status, long estMillis) {
Slog.v(TAG, "Move " + moveId + " status " + status);
final SomeArgs args = SomeArgs.obtain();
args.argi1 = moveId;
args.arg2 = moveTitle;
args.argi3 = status;
args.arg4 = estMillis;
args.argi2 = status;
args.arg3 = estMillis;
obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
synchronized (mLastStatus) {