diff options
3 files changed, 52 insertions, 20 deletions
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index a4ee8b774a9e..32f7bc93e393 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.content.Context; import android.content.Intent; import android.content.res.Resources; -import android.mtp.MtpStorage; import android.net.Uri; import android.os.Environment; import android.os.Parcel; @@ -300,6 +299,8 @@ public class VolumeInfo implements Parcelable { } public StorageVolume buildStorageVolume(Context context, int userId) { + final StorageManager storage = context.getSystemService(StorageManager.class); + final boolean removable; final boolean emulated; final boolean allowMassStorage = false; @@ -310,14 +311,7 @@ public class VolumeInfo implements Parcelable { userPath = new File("/dev/null"); } - String description = getDescription(); - if (description == null) { - description = getFsUuid(); - } - if (description == null) { - description = context.getString(android.R.string.unknownName); - } - + String description = null; long mtpReserveSize = 0; long maxFileSize = 0; int mtpStorageId = StorageVolume.STORAGE_ID_INVALID; @@ -325,11 +319,16 @@ public class VolumeInfo implements Parcelable { if (type == TYPE_EMULATED) { emulated = true; + final VolumeInfo privateVol = storage.findPrivateForEmulated(this); + if (privateVol != null) { + description = storage.getBestVolumeDescription(privateVol); + } + if (isPrimary()) { mtpStorageId = StorageVolume.STORAGE_ID_PRIMARY; } - mtpReserveSize = StorageManager.from(context).getStorageLowBytes(userPath); + mtpReserveSize = storage.getStorageLowBytes(userPath); if (ID_EMULATED_INTERNAL.equals(id)) { removable = false; @@ -341,6 +340,8 @@ public class VolumeInfo implements Parcelable { emulated = false; removable = true; + description = storage.getBestVolumeDescription(this); + if (isPrimary()) { mtpStorageId = StorageVolume.STORAGE_ID_PRIMARY; } else { @@ -357,6 +358,10 @@ public class VolumeInfo implements Parcelable { throw new IllegalStateException("Unexpected volume type " + type); } + if (description == null) { + description = context.getString(android.R.string.unknownName); + } + return new StorageVolume(id, mtpStorageId, userPath, description, isPrimary(), removable, emulated, mtpReserveSize, allowMassStorage, maxFileSize, new UserHandle(userId), fsUuid, envState); diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index c7ca1ab19d31..25bd78732615 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -31,6 +31,7 @@ import android.Manifest; import android.annotation.Nullable; import android.app.ActivityManagerNative; import android.app.AppOpsManager; +import android.app.IActivityManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -39,10 +40,10 @@ import android.content.IntentFilter; import android.content.ServiceConnection; import android.content.pm.IPackageMoveObserver; import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.content.res.ObbInfo; -import android.mtp.MtpStorage; import android.net.Uri; import android.os.Binder; import android.os.DropBoxManager; @@ -53,7 +54,6 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; -import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteCallbackList; @@ -73,6 +73,7 @@ import android.os.storage.StorageResultCode; import android.os.storage.StorageVolume; import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; +import android.provider.MediaStore; import android.provider.Settings; import android.text.TextUtils; import android.text.format.DateUtils; @@ -176,7 +177,6 @@ class MountService extends IMountService.Stub } } - private static final boolean LOCAL_LOGD = false; private static final boolean DEBUG_EVENTS = false; private static final boolean DEBUG_OBB = false; @@ -723,10 +723,30 @@ class MountService extends IMountService.Stub MountServiceIdler.scheduleIdlePass(mContext); } + /** + * MediaProvider has a ton of code that makes assumptions about storage + * paths never changing, so we outright kill them to pick up new state. + */ + @Deprecated + private void killMediaProvider() { + final ProviderInfo provider = mPms.resolveContentProvider(MediaStore.AUTHORITY, 0, + UserHandle.USER_OWNER); + if (provider != null) { + final IActivityManager am = ActivityManagerNative.getDefault(); + try { + am.killApplicationWithAppId(provider.applicationInfo.packageName, + UserHandle.getAppId(provider.applicationInfo.uid), "vold reset"); + } catch (RemoteException e) { + } + } + } + private void resetIfReadyAndConnectedLocked() { Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady + ", mDaemonConnected=" + mDaemonConnected); if (mSystemReady && mDaemonConnected) { + killMediaProvider(); + mDisks.clear(); mVolumes.clear(); @@ -1606,7 +1626,9 @@ class MountService extends IMountService.Stub waitForReady(); try { - final NativeDaemonEvent res = mConnector.execute("volume", "benchmark", volId); + // TODO: make benchmark async so we don't block other commands + final NativeDaemonEvent res = mConnector.execute(3 * DateUtils.MINUTE_IN_MILLIS, + "volume", "benchmark", volId); return Long.parseLong(res.getMessage()); } catch (NativeDaemonTimeoutException e) { return Long.MAX_VALUE; diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java index e7979e4310b0..519a2a3f4f88 100644 --- a/services/core/java/com/android/server/NativeDaemonConnector.java +++ b/services/core/java/com/android/server/NativeDaemonConnector.java @@ -69,7 +69,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo private AtomicInteger mSequenceNumber; - private static final int DEFAULT_TIMEOUT = 1 * 60 * 1000; /* 1 minute */ + private static final long DEFAULT_TIMEOUT = 1 * 60 * 1000; /* 1 minute */ private static final long WARN_EXECUTE_DELAY_MS = 500; /* .5 sec */ /** Lock held whenever communicating with native daemon. */ @@ -337,7 +337,12 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo */ public NativeDaemonEvent execute(String cmd, Object... args) throws NativeDaemonConnectorException { - final NativeDaemonEvent[] events = executeForList(cmd, args); + return execute(DEFAULT_TIMEOUT, cmd, args); + } + + public NativeDaemonEvent execute(long timeoutMs, String cmd, Object... args) + throws NativeDaemonConnectorException { + final NativeDaemonEvent[] events = executeForList(timeoutMs, cmd, args); if (events.length != 1) { throw new NativeDaemonConnectorException( "Expected exactly one response, but received " + events.length); @@ -372,7 +377,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo */ public NativeDaemonEvent[] executeForList(String cmd, Object... args) throws NativeDaemonConnectorException { - return execute(DEFAULT_TIMEOUT, cmd, args); + return executeForList(DEFAULT_TIMEOUT, cmd, args); } /** @@ -387,7 +392,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo * {@link NativeDaemonEvent#isClassClientError()} or * {@link NativeDaemonEvent#isClassServerError()}. */ - public NativeDaemonEvent[] execute(int timeout, String cmd, Object... args) + public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args) throws NativeDaemonConnectorException { final long startTime = SystemClock.elapsedRealtime(); @@ -418,7 +423,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo NativeDaemonEvent event = null; do { - event = mResponseQueue.remove(sequenceNumber, timeout, logCmd); + event = mResponseQueue.remove(sequenceNumber, timeoutMs, logCmd); if (event == null) { loge("timed-out waiting for response to " + logCmd); throw new NativeDaemonTimeoutException(logCmd, event); @@ -606,7 +611,7 @@ final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdo // note that the timeout does not count time in deep sleep. If you don't want // the device to sleep, hold a wakelock - public NativeDaemonEvent remove(int cmdNum, int timeoutMs, String logCmd) { + public NativeDaemonEvent remove(int cmdNum, long timeoutMs, String logCmd) { PendingCmd found = null; synchronized (mPendingCmds) { for (PendingCmd pendingCmd : mPendingCmds) { |