From e1ff214e32ed5c546a7603b07b054908c4d93312 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Tue, 12 Oct 2010 11:20:01 -0700 Subject: [PATCH] Add API to check for emulated external storage When the storage is emulated, we don't want to install ASEC containers to it. This adds the API to check when the external storage is emulated and uses it to check whether or not to install packages to the external storage in an ASEC container. Bug: 3024387 Change-Id: Ia0318aca9e4938a4897deaada5603a4c7c1d0f48 --- core/java/android/os/Environment.java | 42 ++++++++++++++++--- .../android/os/storage/IMountService.java | 33 +++++++++++++++ libs/storage/IMountService.cpp | 1 + .../defcontainer/DefaultContainerService.java | 2 +- .../java/com/android/server/MountService.java | 4 ++ 5 files changed, 75 insertions(+), 7 deletions(-) diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index e8ae7e6bbd4ac..4688847b0354c 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -31,7 +31,14 @@ public class Environment { private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled"; - private static IMountService mMntSvc = null; + private static class MountServiceHolder { + static IMountService mSingleton = IMountService.Stub.asInterface(ServiceManager + .getService("mount")); + } + + private static final Object mLock = new Object(); + + private volatile static Boolean mIsExternalStorageEmulated = null; /** * Gets the Android root directory. @@ -382,11 +389,8 @@ public class Environment { */ public static String getExternalStorageState() { try { - if (mMntSvc == null) { - mMntSvc = IMountService.Stub.asInterface(ServiceManager - .getService("mount")); - } - return mMntSvc.getVolumeState(getExternalStorageDirectory().toString()); + return MountServiceHolder.mSingleton.getVolumeState(getExternalStorageDirectory() + .toString()); } catch (Exception rex) { return Environment.MEDIA_REMOVED; } @@ -405,6 +409,32 @@ public class Environment { com.android.internal.R.bool.config_externalStorageRemovable); } + /** + * Returns whether the device has an external storage device which is + * emulated. If true, the device does not have real external storage + * and certain system services such as the package manager use this + * to determine where to install an application. + * + * @hide + */ + public static boolean isExternalStorageEmulated() { + if (mIsExternalStorageEmulated == null) { + synchronized (mLock) { + if (mIsExternalStorageEmulated == null) { + boolean externalStorageEmulated; + try { + externalStorageEmulated = + MountServiceHolder.mSingleton.isExternalStorageEmulated(); + } catch (Exception e) { + externalStorageEmulated = false; + } + mIsExternalStorageEmulated = Boolean.valueOf(externalStorageEmulated); + } + } + } + return mIsExternalStorageEmulated; + } + static File getDirectory(String variableName, String defaultPath) { String path = System.getenv(variableName); return path == null ? new File(defaultPath) : new File(path); diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 60ea95c459f7f..57e208a349964 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -565,6 +565,25 @@ public interface IMountService extends IInterface { } return _result; } + + /** + * Returns whether the external storage is emulated. + */ + public boolean isExternalStorageEmulated() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + boolean _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_isExternalStorageEmulated, _data, _reply, 0); + _reply.readException(); + _result = 0 != _reply.readInt(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } } private static final String DESCRIPTOR = "IMountService"; @@ -619,6 +638,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_getMountedObbPath = IBinder.FIRST_CALL_TRANSACTION + 24; + static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -889,6 +910,13 @@ public interface IMountService extends IInterface { reply.writeString(mountedPath); return true; } + case TRANSACTION_isExternalStorageEmulated: { + data.enforceInterface(DESCRIPTOR); + boolean emulated = isExternalStorageEmulated(); + reply.writeNoException(); + reply.writeInt(emulated ? 1 : 0); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1043,4 +1071,9 @@ public interface IMountService extends IInterface { * Unregisters an IMountServiceListener */ public void unregisterListener(IMountServiceListener listener) throws RemoteException; + + /** + * Returns whether or not the external storage is emulated. + */ + public boolean isExternalStorageEmulated() throws RemoteException; } diff --git a/libs/storage/IMountService.cpp b/libs/storage/IMountService.cpp index 3ad9319a8f359..17a961be8d077 100644 --- a/libs/storage/IMountService.cpp +++ b/libs/storage/IMountService.cpp @@ -47,6 +47,7 @@ enum { TRANSACTION_unmountObb, TRANSACTION_isObbMounted, TRANSACTION_getMountedObbPath, + TRANSACTION_isExternalStorageEmulated, }; class BpMountService: public BpInterface diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index ce10f5b71d458..e6624ae11c11b 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -440,7 +440,7 @@ public class DefaultContainerService extends IntentService { String status = Environment.getExternalStorageState(); long availSDSize = -1; boolean mediaAvailable = false; - if (status.equals(Environment.MEDIA_MOUNTED)) { + if (!Environment.isExternalStorageEmulated() && status.equals(Environment.MEDIA_MOUNTED)) { StatFs sdStats = new StatFs( Environment.getExternalStorageDirectory().getPath()); availSDSize = (long)sdStats.getAvailableBlocks() * diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 295047c8b7525..baa5016fc032d 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -1240,6 +1240,10 @@ class MountService extends IMountService.Stub return mLegacyState; } + public boolean isExternalStorageEmulated() { + return mEmulateExternalStorage; + } + public int mountVolume(String path) { validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);