Apps on sdcard: Add new broadcasts
Add new broadcasts ACTION_MEDIA_RESOURCES_AVAILABLE and
ACTION_MEDIA_RESOURCES_UNAVAILABLE that get broadcast by
PackageManagerService when sdcard gets mounted/unmounted
by MountService so that packages on sdcard get recognized by
various system services as being installed/available or
removed/unavailable by the system.
The broadcasts are sent before the actual package cleanup which includes
mounting/unmounting the packages and we force a gc right after so
that any lingering file references to resources on sdcard get
released.
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 405dc2e..dc942a2 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -335,6 +335,22 @@
class PackageReceiver extends android.content.BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ String pkgList[] = null;
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+ Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ Uri uri = intent.getData();
+ String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ if (pkg != null) {
+ pkgList = new String[] { pkg };
+ }
+ } else if (Intent.ACTION_MEDIA_RESOURCES_AVAILABLE.equals(action) ||
+ Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE.equals(action)) {
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ }
+ if (pkgList == null || pkgList.length == 0) {
+ return;
+ }
synchronized (mMethodMap) {
buildInputMethodListLocked(mMethodList, mMethodMap);
@@ -352,38 +368,45 @@
boolean changed = false;
- Uri uri = intent.getData();
- String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
- if (curIm != null && curIm.getPackageName().equals(pkg)) {
- ServiceInfo si = null;
- try {
- si = mContext.getPackageManager().getServiceInfo(
- curIm.getComponent(), 0);
- } catch (PackageManager.NameNotFoundException ex) {
- }
- if (si == null) {
- // Uh oh, current input method is no longer around!
- // Pick another one...
- Log.i(TAG, "Current input method removed: " + curInputMethodId);
- if (!chooseNewDefaultIME()) {
- changed = true;
- curIm = null;
- curInputMethodId = "";
- Log.i(TAG, "Unsetting current input method");
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- curInputMethodId);
+ if (curIm != null) {
+ boolean foundPkg = false;
+ for (String pkg : pkgList) {
+ if (curIm.getPackageName().equals(pkg)) {
+ foundPkg = true;
+ break;
}
}
+ if (foundPkg) {
+ ServiceInfo si = null;
+ try {
+ si = mContext.getPackageManager().getServiceInfo(
+ curIm.getComponent(), 0);
+ } catch (PackageManager.NameNotFoundException ex) {
+ }
+ if (si == null) {
+ // Uh oh, current input method is no longer around!
+ // Pick another one...
+ Log.i(TAG, "Current input method removed: " + curInputMethodId);
+ if (!chooseNewDefaultIME()) {
+ changed = true;
+ curIm = null;
+ curInputMethodId = "";
+ Log.i(TAG, "Unsetting current input method");
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ curInputMethodId);
+ }
+ }
- } else if (curIm == null) {
- // We currently don't have a default input method... is
- // one now available?
- changed = chooseNewDefaultIME();
- }
+ } else if (curIm == null) {
+ // We currently don't have a default input method... is
+ // one now available?
+ changed = chooseNewDefaultIME();
+ }
- if (changed) {
- updateFromSettingsLocked();
+ if (changed) {
+ updateFromSettingsLocked();
+ }
}
}
}
@@ -415,13 +438,19 @@
}
});
+ PackageReceiver mBroadcastReceiver = new PackageReceiver();
IntentFilter packageFilt = new IntentFilter();
packageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
packageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
packageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
packageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED);
packageFilt.addDataScheme("package");
- mContext.registerReceiver(new PackageReceiver(), packageFilt);
+ mContext.registerReceiver(mBroadcastReceiver, packageFilt);
+ // Register for events related to sdcard installation.
+ IntentFilter sdFilter = new IntentFilter();
+ sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_AVAILABLE);
+ sdFilter.addAction(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE);
+ mContext.registerReceiver(mBroadcastReceiver, sdFilter);
IntentFilter screenOnOffFilt = new IntentFilter();
screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON);