Loading core/java/android/os/storage/IMountService.java +8 −1 Original line number Diff line number Diff line Loading @@ -1360,7 +1360,14 @@ public interface IMountService extends IInterface { */ public Parcelable[] getVolumeList() throws RemoteException; public String getSecureContainerFilesystemPath(String id) throws RemoteException; /** * Gets the path on the filesystem for the ASEC container itself. * * @param cid ASEC container ID * @return path to filesystem or {@code null} if it's not found * @throws RemoteException */ public String getSecureContainerFilesystemPath(String cid) throws RemoteException; /* * Fix permissions in a container which has just been created and populated. Loading services/java/com/android/server/MountService.java +35 −22 Original line number Diff line number Diff line Loading @@ -79,6 +79,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.Set; import javax.crypto.SecretKey; Loading Loading @@ -178,7 +180,8 @@ class MountService extends IMountService.Stub final private ArrayList<MountServiceBinderListener> mListeners = new ArrayList<MountServiceBinderListener>(); private boolean mBooted = false; private boolean mReady = false; private CountDownLatch mConnectedSignal = new CountDownLatch(1); private CountDownLatch mAsecsScanned = new CountDownLatch(1); private boolean mSendUmsConnectedOnBoot = false; // true if we should fake MEDIA_MOUNTED state for external storage private boolean mEmulateExternalStorage = false; Loading Loading @@ -446,15 +449,30 @@ class MountService extends IMountService.Stub final private HandlerThread mHandlerThread; final private Handler mHandler; void waitForAsecScan() { waitForLatch(mAsecsScanned); } private void waitForReady() { while (mReady == false) { for (int retries = 5; retries > 0; retries--) { if (mReady) { waitForLatch(mConnectedSignal); } private void waitForLatch(CountDownLatch latch) { if (latch == null) { return; } for (;;) { try { if (latch.await(5000, TimeUnit.MILLISECONDS)) { return; } else { Slog.w(TAG, "Thread " + Thread.currentThread().getName() + " still waiting for MountService ready..."); } SystemClock.sleep(1000); } catch (InterruptedException e) { Slog.w(TAG, "Interrupt while waiting for MountService to be ready."); } Slog.w(TAG, "Waiting too long for mReady!"); } } Loading Loading @@ -627,7 +645,7 @@ class MountService extends IMountService.Stub * Since we'll be calling back into the NativeDaemonConnector, * we need to do our work in a new thread. */ new Thread() { new Thread("MountService#onDaemonConnected") { @Override public void run() { /** Loading Loading @@ -668,14 +686,19 @@ class MountService extends IMountService.Stub updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED); } // Let package manager load internal ASECs. mPms.updateExternalMediaStatus(true, false); /* * Now that we've done our initialization, release * the hounds! */ mReady = true; mConnectedSignal.countDown(); mConnectedSignal = null; // Let package manager load internal ASECs. mPms.scanAvailableAsecs(); // Notify people waiting for ASECs to be scanned that it's done. mAsecsScanned.countDown(); mAsecsScanned = null; } }.start(); } Loading Loading @@ -1158,23 +1181,13 @@ class MountService extends IMountService.Stub // Add OBB Action Handler to MountService thread. mObbActionHandler = new ObbActionHandler(mHandlerThread.getLooper()); /* * Vold does not run in the simulator, so pretend the connector thread * ran and did its thing. */ if ("simulator".equals(SystemProperties.get("ro.product.device"))) { mReady = true; mUmsEnabling = true; return; } /* * Create the connection to vold with a maximum queue of twice the * amount of containers we'd ever expect to have. This keeps an * "asec list" from blocking a thread repeatedly. */ mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25); mReady = false; Thread thread = new Thread(mConnector, VOLD_TAG); thread.start(); Loading services/java/com/android/server/SystemServer.java +22 −11 Original line number Diff line number Diff line Loading @@ -320,6 +320,21 @@ class ServerThread extends Thread { } if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { MountService mountService = null; if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) { try { /* * NotificationManagerService is dependant on MountService, * (for media / usb notifications) so we must start MountService first. */ Slog.i(TAG, "Mount Service"); mountService = new MountService(context); ServiceManager.addService("mount", mountService); } catch (Throwable e) { reportWtf("starting Mount Service", e); } } try { Slog.i(TAG, "LockSettingsService"); lockSettings = new LockSettingsService(context); Loading Loading @@ -441,17 +456,13 @@ class ServerThread extends Thread { reportWtf("starting UpdateLockService", e); } if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) { try { /* * NotificationManagerService is dependant on MountService, * (for media / usb notifications) so we must start MountService first. * MountService has a few dependencies: Notification Manager and * AppWidget Provider. Make sure MountService is completely started * first before continuing. */ Slog.i(TAG, "Mount Service"); ServiceManager.addService("mount", new MountService(context)); } catch (Throwable e) { reportWtf("starting Mount Service", e); } if (mountService != null) { mountService.waitForAsecScan(); } try { Loading services/java/com/android/server/pm/PackageManagerService.java +24 −3 Original line number Diff line number Diff line Loading @@ -240,6 +240,9 @@ public class PackageManagerService extends IPackageManager.Stub { // This is where all application persistent data goes for secondary users. final File mUserAppDataDir; /** The location for ASEC container files on internal storage. */ final String mAsecInternalPath; // This is the object monitoring the framework dir. final FileObserver mFrameworkInstallObserver; Loading Loading @@ -907,6 +910,7 @@ public class PackageManagerService extends IPackageManager.Stub { File dataDir = Environment.getDataDirectory(); mAppDataDir = new File(dataDir, "data"); mAsecInternalPath = new File(dataDir, "app-asec").getPath(); mUserAppDataDir = new File(dataDir, "user"); mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); Loading Loading @@ -6479,6 +6483,11 @@ public class PackageManagerService extends IPackageManager.Stub { } } private boolean isAsecExternal(String cid) { final String asecPath = PackageHelper.getSdFilesystem(cid); return !asecPath.startsWith(mAsecInternalPath); } /** * Extract the MountService "container ID" from the full code path of an * .apk. Loading Loading @@ -6517,7 +6526,7 @@ public class PackageManagerService extends IPackageManager.Stub { } AsecInstallArgs(String cid) { super(null, null, 0, null, null); super(null, null, isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0, null, null); this.cid = cid; setCachePath(PackageHelper.getSdDir(cid)); } Loading Loading @@ -8659,6 +8668,14 @@ public class PackageManagerService extends IPackageManager.Stub { }); } /** * Called by MountService when the initial ASECs to scan are available. * Should block until all the ASEC containers are finished being scanned. */ public void scanAvailableAsecs() { updateExternalMediaStatusInner(true, false); } /* * Collect information of applications on external media, map them against * existing containers and update information based on current mount status. Loading Loading @@ -8793,7 +8810,11 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } // Parse package int parseFlags = PackageParser.PARSE_ON_SDCARD | mDefParseFlags; int parseFlags = mDefParseFlags; if (args.isExternal()) { parseFlags |= PackageParser.PARSE_ON_SDCARD; } doGc = true; synchronized (mInstallLock) { final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, Loading Loading
core/java/android/os/storage/IMountService.java +8 −1 Original line number Diff line number Diff line Loading @@ -1360,7 +1360,14 @@ public interface IMountService extends IInterface { */ public Parcelable[] getVolumeList() throws RemoteException; public String getSecureContainerFilesystemPath(String id) throws RemoteException; /** * Gets the path on the filesystem for the ASEC container itself. * * @param cid ASEC container ID * @return path to filesystem or {@code null} if it's not found * @throws RemoteException */ public String getSecureContainerFilesystemPath(String cid) throws RemoteException; /* * Fix permissions in a container which has just been created and populated. Loading
services/java/com/android/server/MountService.java +35 −22 Original line number Diff line number Diff line Loading @@ -79,6 +79,8 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.Set; import javax.crypto.SecretKey; Loading Loading @@ -178,7 +180,8 @@ class MountService extends IMountService.Stub final private ArrayList<MountServiceBinderListener> mListeners = new ArrayList<MountServiceBinderListener>(); private boolean mBooted = false; private boolean mReady = false; private CountDownLatch mConnectedSignal = new CountDownLatch(1); private CountDownLatch mAsecsScanned = new CountDownLatch(1); private boolean mSendUmsConnectedOnBoot = false; // true if we should fake MEDIA_MOUNTED state for external storage private boolean mEmulateExternalStorage = false; Loading Loading @@ -446,15 +449,30 @@ class MountService extends IMountService.Stub final private HandlerThread mHandlerThread; final private Handler mHandler; void waitForAsecScan() { waitForLatch(mAsecsScanned); } private void waitForReady() { while (mReady == false) { for (int retries = 5; retries > 0; retries--) { if (mReady) { waitForLatch(mConnectedSignal); } private void waitForLatch(CountDownLatch latch) { if (latch == null) { return; } for (;;) { try { if (latch.await(5000, TimeUnit.MILLISECONDS)) { return; } else { Slog.w(TAG, "Thread " + Thread.currentThread().getName() + " still waiting for MountService ready..."); } SystemClock.sleep(1000); } catch (InterruptedException e) { Slog.w(TAG, "Interrupt while waiting for MountService to be ready."); } Slog.w(TAG, "Waiting too long for mReady!"); } } Loading Loading @@ -627,7 +645,7 @@ class MountService extends IMountService.Stub * Since we'll be calling back into the NativeDaemonConnector, * we need to do our work in a new thread. */ new Thread() { new Thread("MountService#onDaemonConnected") { @Override public void run() { /** Loading Loading @@ -668,14 +686,19 @@ class MountService extends IMountService.Stub updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED); } // Let package manager load internal ASECs. mPms.updateExternalMediaStatus(true, false); /* * Now that we've done our initialization, release * the hounds! */ mReady = true; mConnectedSignal.countDown(); mConnectedSignal = null; // Let package manager load internal ASECs. mPms.scanAvailableAsecs(); // Notify people waiting for ASECs to be scanned that it's done. mAsecsScanned.countDown(); mAsecsScanned = null; } }.start(); } Loading Loading @@ -1158,23 +1181,13 @@ class MountService extends IMountService.Stub // Add OBB Action Handler to MountService thread. mObbActionHandler = new ObbActionHandler(mHandlerThread.getLooper()); /* * Vold does not run in the simulator, so pretend the connector thread * ran and did its thing. */ if ("simulator".equals(SystemProperties.get("ro.product.device"))) { mReady = true; mUmsEnabling = true; return; } /* * Create the connection to vold with a maximum queue of twice the * amount of containers we'd ever expect to have. This keeps an * "asec list" from blocking a thread repeatedly. */ mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25); mReady = false; Thread thread = new Thread(mConnector, VOLD_TAG); thread.start(); Loading
services/java/com/android/server/SystemServer.java +22 −11 Original line number Diff line number Diff line Loading @@ -320,6 +320,21 @@ class ServerThread extends Thread { } if (factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) { MountService mountService = null; if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) { try { /* * NotificationManagerService is dependant on MountService, * (for media / usb notifications) so we must start MountService first. */ Slog.i(TAG, "Mount Service"); mountService = new MountService(context); ServiceManager.addService("mount", mountService); } catch (Throwable e) { reportWtf("starting Mount Service", e); } } try { Slog.i(TAG, "LockSettingsService"); lockSettings = new LockSettingsService(context); Loading Loading @@ -441,17 +456,13 @@ class ServerThread extends Thread { reportWtf("starting UpdateLockService", e); } if (!"0".equals(SystemProperties.get("system_init.startmountservice"))) { try { /* * NotificationManagerService is dependant on MountService, * (for media / usb notifications) so we must start MountService first. * MountService has a few dependencies: Notification Manager and * AppWidget Provider. Make sure MountService is completely started * first before continuing. */ Slog.i(TAG, "Mount Service"); ServiceManager.addService("mount", new MountService(context)); } catch (Throwable e) { reportWtf("starting Mount Service", e); } if (mountService != null) { mountService.waitForAsecScan(); } try { Loading
services/java/com/android/server/pm/PackageManagerService.java +24 −3 Original line number Diff line number Diff line Loading @@ -240,6 +240,9 @@ public class PackageManagerService extends IPackageManager.Stub { // This is where all application persistent data goes for secondary users. final File mUserAppDataDir; /** The location for ASEC container files on internal storage. */ final String mAsecInternalPath; // This is the object monitoring the framework dir. final FileObserver mFrameworkInstallObserver; Loading Loading @@ -907,6 +910,7 @@ public class PackageManagerService extends IPackageManager.Stub { File dataDir = Environment.getDataDirectory(); mAppDataDir = new File(dataDir, "data"); mAsecInternalPath = new File(dataDir, "app-asec").getPath(); mUserAppDataDir = new File(dataDir, "user"); mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); Loading Loading @@ -6479,6 +6483,11 @@ public class PackageManagerService extends IPackageManager.Stub { } } private boolean isAsecExternal(String cid) { final String asecPath = PackageHelper.getSdFilesystem(cid); return !asecPath.startsWith(mAsecInternalPath); } /** * Extract the MountService "container ID" from the full code path of an * .apk. Loading Loading @@ -6517,7 +6526,7 @@ public class PackageManagerService extends IPackageManager.Stub { } AsecInstallArgs(String cid) { super(null, null, 0, null, null); super(null, null, isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0, null, null); this.cid = cid; setCachePath(PackageHelper.getSdDir(cid)); } Loading Loading @@ -8659,6 +8668,14 @@ public class PackageManagerService extends IPackageManager.Stub { }); } /** * Called by MountService when the initial ASECs to scan are available. * Should block until all the ASEC containers are finished being scanned. */ public void scanAvailableAsecs() { updateExternalMediaStatusInner(true, false); } /* * Collect information of applications on external media, map them against * existing containers and update information based on current mount status. Loading Loading @@ -8793,7 +8810,11 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } // Parse package int parseFlags = PackageParser.PARSE_ON_SDCARD | mDefParseFlags; int parseFlags = mDefParseFlags; if (args.isExternal()) { parseFlags |= PackageParser.PARSE_ON_SDCARD; } doGc = true; synchronized (mInstallLock) { final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, Loading