summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/storage/IMountService.java9
-rw-r--r--services/java/com/android/server/MountService.java57
-rw-r--r--services/java/com/android/server/SystemServer.java33
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java27
4 files changed, 89 insertions, 37 deletions
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index f4abda6..ab64866 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -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.
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d6606f6..13ab586 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -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;
@@ -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;
@@ -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!");
}
}
@@ -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() {
/**
@@ -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();
}
@@ -1159,22 +1182,12 @@ class MountService extends IMountService.Stub
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();
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index bb10358..eaecd4c 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -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);
@@ -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.
- */
- Slog.i(TAG, "Mount Service");
- ServiceManager.addService("mount", new MountService(context));
- } catch (Throwable e) {
- reportWtf("starting Mount Service", e);
- }
+ /*
+ * MountService has a few dependencies: Notification Manager and
+ * AppWidget Provider. Make sure MountService is completely started
+ * first before continuing.
+ */
+ if (mountService != null) {
+ mountService.waitForAsecScan();
}
try {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 3936c18..77c3e78 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -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;
@@ -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");
@@ -1043,7 +1047,7 @@ public class PackageManagerService extends IPackageManager.Stub {
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR,
scanMode | SCAN_NO_DEX, 0);
-
+
// Collect all system packages.
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(
@@ -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.
@@ -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));
}
@@ -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.
@@ -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,