summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-02-22 12:18:01 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-02-22 12:18:01 -0800
commit7e31e0c351a3b2bb70ee5507b34f1c72d62b56d7 (patch)
tree5b177c59b9ab317e3951b6369a5676080afd9788
parentec2c88d835dac156be0d14bd2b73cf3825e2e164 (diff)
parent21f1bd17b2dfe361acbb28453b3f3b1a110932fa (diff)
downloadframeworks_base-7e31e0c351a3b2bb70ee5507b34f1c72d62b56d7.zip
frameworks_base-7e31e0c351a3b2bb70ee5507b34f1c72d62b56d7.tar.gz
frameworks_base-7e31e0c351a3b2bb70ee5507b34f1c72d62b56d7.tar.bz2
Merge "Fix issue #2438980: Implement package watcher for voice recognizer service setting"
-rw-r--r--api/current.xml2
-rw-r--r--core/java/android/app/ApplicationErrorReport.java102
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/app/DeviceAdminInfo.java14
-rw-r--r--core/java/android/app/DevicePolicyManager.java21
-rw-r--r--core/java/android/app/IDevicePolicyManager.aidl1
-rw-r--r--core/java/android/content/ComponentName.java2
-rw-r--r--core/java/android/content/Intent.java21
-rw-r--r--core/java/android/os/BatteryStats.java85
-rw-r--r--core/java/com/android/internal/content/PackageMonitor.java287
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java41
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java4
-rw-r--r--services/java/com/android/server/AccessibilityManagerService.java85
-rw-r--r--services/java/com/android/server/AlarmManagerService.java29
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java62
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java266
-rw-r--r--services/java/com/android/server/LocationManagerService.java15
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java27
-rw-r--r--services/java/com/android/server/PackageManagerService.java12
-rw-r--r--services/java/com/android/server/RecognitionManagerService.java130
-rw-r--r--services/java/com/android/server/SystemServer.java10
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java119
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java199
23 files changed, 1161 insertions, 375 deletions
diff --git a/api/current.xml b/api/current.xml
index 33a8020..a753165 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23748,7 +23748,7 @@
>
<parameter name="parcel" type="android.os.Parcel">
</parameter>
-<parameter name="flags" type="int">
+<parameter name="flagz" type="int">
</parameter>
</method>
<field name="CREATOR"
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index 832f599..fe81056 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -16,8 +16,16 @@
package android.app;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.SystemProperties;
+import android.provider.Settings;
import android.util.Printer;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -38,6 +46,13 @@ import java.io.StringWriter;
*/
public class ApplicationErrorReport implements Parcelable {
+ // System property defining error report receiver for system apps
+ static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
+
+ // System property defining default error report receiver
+ static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
+
+
/**
* Uninitialized error report.
*/
@@ -54,8 +69,13 @@ public class ApplicationErrorReport implements Parcelable {
public static final int TYPE_ANR = 2;
/**
+ * An error report about an application that's consuming too much battery.
+ */
+ public static final int TYPE_BATTERY = 3;
+
+ /**
* Type of this report. Can be one of {@link #TYPE_NONE},
- * {@link #TYPE_CRASH} or {@link #TYPE_ANR}.
+ * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, or {@link #TYPE_BATTERY}.
*/
public int type;
@@ -99,6 +119,11 @@ public class ApplicationErrorReport implements Parcelable {
public AnrInfo anrInfo;
/**
+ * Text containing battery usage data.
+ */
+ public String batteryText;
+
+ /**
* Create an uninitialized instance of {@link ApplicationErrorReport}.
*/
public ApplicationErrorReport() {
@@ -112,6 +137,68 @@ public class ApplicationErrorReport implements Parcelable {
readFromParcel(in);
}
+ public static ComponentName getErrorReportReceiver(Context context,
+ String packageName, int appFlags) {
+ // check if error reporting is enabled in secure settings
+ int enabled = Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.SEND_ACTION_APP_ERROR, 0);
+ if (enabled == 0) {
+ return null;
+ }
+
+ PackageManager pm = context.getPackageManager();
+
+ // look for receiver in the installer package
+ String candidate = pm.getInstallerPackageName(packageName);
+ ComponentName result = getErrorReportReceiver(pm, packageName, candidate);
+ if (result != null) {
+ return result;
+ }
+
+ // if the error app is on the system image, look for system apps
+ // error receiver
+ if ((appFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
+ candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
+ result = getErrorReportReceiver(pm, packageName, candidate);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ // if there is a default receiver, try that
+ candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
+ return getErrorReportReceiver(pm, packageName, candidate);
+ }
+
+ /**
+ * Return activity in receiverPackage that handles ACTION_APP_ERROR.
+ *
+ * @param pm PackageManager isntance
+ * @param errorPackage package which caused the error
+ * @param receiverPackage candidate package to receive the error
+ * @return activity component within receiverPackage which handles
+ * ACTION_APP_ERROR, or null if not found
+ */
+ static ComponentName getErrorReportReceiver(PackageManager pm, String errorPackage,
+ String receiverPackage) {
+ if (receiverPackage == null || receiverPackage.length() == 0) {
+ return null;
+ }
+
+ // break the loop if it's the error report receiver package that crashed
+ if (receiverPackage.equals(errorPackage)) {
+ return null;
+ }
+
+ Intent intent = new Intent(Intent.ACTION_APP_ERROR);
+ intent.setPackage(receiverPackage);
+ ResolveInfo info = pm.resolveActivity(intent, 0);
+ if (info == null || info.activityInfo == null) {
+ return null;
+ }
+ return new ComponentName(receiverPackage, info.activityInfo.name);
+ }
+
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(type);
dest.writeString(packageName);
@@ -127,6 +214,9 @@ public class ApplicationErrorReport implements Parcelable {
case TYPE_ANR:
anrInfo.writeToParcel(dest, flags);
break;
+ case TYPE_BATTERY:
+ dest.writeString(batteryText);
+ break;
}
}
@@ -142,10 +232,17 @@ public class ApplicationErrorReport implements Parcelable {
case TYPE_CRASH:
crashInfo = new CrashInfo(in);
anrInfo = null;
+ batteryText = null;
break;
case TYPE_ANR:
anrInfo = new AnrInfo(in);
crashInfo = null;
+ batteryText = null;
+ break;
+ case TYPE_BATTERY:
+ batteryText = in.readString();
+ anrInfo = null;
+ crashInfo = null;
break;
}
}
@@ -347,6 +444,9 @@ public class ApplicationErrorReport implements Parcelable {
case TYPE_ANR:
anrInfo.dump(pw, prefix);
break;
+ case TYPE_BATTERY:
+ pw.println(batteryText);
+ break;
}
}
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1d004ee..c7c9429 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1146,7 +1146,7 @@ class ContextImpl extends Context {
private DevicePolicyManager getDevicePolicyManager() {
synchronized (mSync) {
if (mDevicePolicyManager == null) {
- mDevicePolicyManager = new DevicePolicyManager(this,
+ mDevicePolicyManager = DevicePolicyManager.create(this,
mMainThread.getHandler());
}
}
diff --git a/core/java/android/app/DeviceAdminInfo.java b/core/java/android/app/DeviceAdminInfo.java
index bedf4b4..61e1bb3 100644
--- a/core/java/android/app/DeviceAdminInfo.java
+++ b/core/java/android/app/DeviceAdminInfo.java
@@ -18,6 +18,7 @@ package android.app;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
import android.content.ComponentName;
import android.content.Context;
@@ -331,6 +332,19 @@ public final class DeviceAdminInfo implements Parcelable {
return res;
}
+ /** @hide */
+ public void writePoliciesToXml(XmlSerializer out)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ out.attribute(null, "flags", Integer.toString(mUsesPolicies));
+ }
+
+ /** @hide */
+ public void readPoliciesFromXml(XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ mUsesPolicies = Integer.parseInt(
+ parser.getAttributeValue(null, "flags"));
+ }
+
public void dump(Printer pw, String prefix) {
pw.println(prefix + "Receiver:");
mReceiver.dump(pw, prefix + " ");
diff --git a/core/java/android/app/DevicePolicyManager.java b/core/java/android/app/DevicePolicyManager.java
index d611807..0e8c1ab 100644
--- a/core/java/android/app/DevicePolicyManager.java
+++ b/core/java/android/app/DevicePolicyManager.java
@@ -49,13 +49,18 @@ public class DevicePolicyManager {
private final Handler mHandler;
- /*package*/ DevicePolicyManager(Context context, Handler handler) {
+ private DevicePolicyManager(Context context, Handler handler) {
mContext = context;
mHandler = handler;
mService = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
}
+ /*package*/ static DevicePolicyManager create(Context context, Handler handler) {
+ DevicePolicyManager me = new DevicePolicyManager(context, handler);
+ return me.mService != null ? me : null;
+ }
+
/**
* Activity action: ask the user to add a new device administrator to the system.
* The desired policy is the ComponentName of the policy in the
@@ -133,6 +138,20 @@ public class DevicePolicyManager {
}
/**
+ * @hide
+ */
+ public boolean packageHasActiveAdmins(String packageName) {
+ if (mService != null) {
+ try {
+ return mService.packageHasActiveAdmins(packageName);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ }
+ return false;
+ }
+
+ /**
* Remove a current administration component. This can only be called
* by the application that owns the administration component; if you
* try to remove someone else's component, a security exception will be
diff --git a/core/java/android/app/IDevicePolicyManager.aidl b/core/java/android/app/IDevicePolicyManager.aidl
index ae5c4bf..b138720 100644
--- a/core/java/android/app/IDevicePolicyManager.aidl
+++ b/core/java/android/app/IDevicePolicyManager.aidl
@@ -49,6 +49,7 @@ interface IDevicePolicyManager {
void setActiveAdmin(in ComponentName policyReceiver);
boolean isAdminActive(in ComponentName policyReceiver);
List<ComponentName> getActiveAdmins();
+ boolean packageHasActiveAdmins(String packageName);
void getRemoveWarning(in ComponentName policyReceiver, in RemoteCallback result);
void removeActiveAdmin(in ComponentName policyReceiver);
diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java
index c4ba05d..7ca0f01 100644
--- a/core/java/android/content/ComponentName.java
+++ b/core/java/android/content/ComponentName.java
@@ -126,7 +126,7 @@ public final class ComponentName implements Parcelable, Cloneable, Comparable<Co
}
/**
- * The samee as {@link #flattenToString()}, but abbreviates the class
+ * The same as {@link #flattenToString()}, but abbreviates the class
* name if it is a suffix of the package. The result can still be used
* with {@link #unflattenFromString(String)}.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1b0437c..607605d 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1316,6 +1316,21 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
/**
+ * @hide
+ * Broadcast Action: Ask system services if there is any reason to
+ * restart the given package. The data contains the name of the
+ * package.
+ * <ul>
+ * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
+ * <li> {@link #EXTRA_PACKAGES} String array of all packages to check.
+ * </ul>
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
+ /**
* Broadcast Action: The user has restarted a package, and all of its
* processes have been killed. All runtime state
* associated with it (processes, alarms, notifications, etc) should
@@ -2098,6 +2113,7 @@ public class Intent implements Parcelable, Cloneable {
* number to call in a {@link android.content.Intent#ACTION_CALL}.
*/
public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
+
/**
* Used as an int extra field in {@link android.content.Intent#ACTION_UID_REMOVED}
* intents to supply the uid the package had been assigned. Also an optional
@@ -2108,6 +2124,11 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_UID = "android.intent.extra.UID";
/**
+ * @hide String array of package names.
+ */
+ public static final String EXTRA_PACKAGES = "android.intent.extra.PACKAGES";
+
+ /**
* Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED}
* intents to indicate whether this represents a full uninstall (removing
* both the code and its data) or a partial uninstall (leaving its data,
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b706c5c..56a05ee 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -750,11 +750,8 @@ public abstract class BatteryStats implements Parcelable {
* Checkin server version of dump to produce more compact, computer-readable log.
*
* NOTE: all times are expressed in 'ms'.
- * @param fd
- * @param pw
- * @param which
*/
- private final void dumpCheckinLocked(PrintWriter pw, int which) {
+ public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
final long rawUptime = SystemClock.uptimeMillis() * 1000;
final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
final long batteryUptime = getBatteryUptime(rawUptime);
@@ -856,19 +853,24 @@ public abstract class BatteryStats implements Parcelable {
getDischargeCurrentLevel());
}
- Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
- if (kernelWakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
- sb.setLength(0);
- printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
-
- dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
- sb.toString());
+ if (reqUid < 0) {
+ Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+ if (kernelWakelocks.size() > 0) {
+ for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
+ sb.setLength(0);
+ printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
+
+ dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
+ sb.toString());
+ }
}
}
for (int iu = 0; iu < NU; iu++) {
final int uid = uidStats.keyAt(iu);
+ if (reqUid >= 0 && uid != reqUid) {
+ continue;
+ }
Uid u = uidStats.valueAt(iu);
// Dump Network stats per uid, if any
long rx = u.getTcpBytesReceived(which);
@@ -987,7 +989,7 @@ public abstract class BatteryStats implements Parcelable {
}
@SuppressWarnings("unused")
- private final void dumpLocked(PrintWriter pw, String prefix, int which) {
+ public final void dumpLocked(PrintWriter pw, String prefix, int which, int reqUid) {
final long rawUptime = SystemClock.uptimeMillis() * 1000;
final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
final long batteryUptime = getBatteryUptime(rawUptime);
@@ -1063,23 +1065,25 @@ public abstract class BatteryStats implements Parcelable {
long fullWakeLockTimeTotalMicros = 0;
long partialWakeLockTimeTotalMicros = 0;
- Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
- if (kernelWakelocks.size() > 0) {
- for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
-
- String linePrefix = ": ";
- sb.setLength(0);
- sb.append(prefix);
- sb.append(" Kernel Wake lock ");
- sb.append(ent.getKey());
- linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
- linePrefix);
- if (!linePrefix.equals(": ")) {
- sb.append(" realtime");
- } else {
- sb.append(": (nothing executed)");
+ if (reqUid < 0) {
+ Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+ if (kernelWakelocks.size() > 0) {
+ for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
+
+ String linePrefix = ": ";
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Kernel Wake lock ");
+ sb.append(ent.getKey());
+ linePrefix = printWakeLock(sb, ent.getValue(), batteryRealtime, null, which,
+ linePrefix);
+ if (!linePrefix.equals(": ")) {
+ sb.append(" realtime");
+ } else {
+ sb.append(": (nothing executed)");
+ }
+ pw.println(sb.toString());
}
- pw.println(sb.toString());
}
}
@@ -1212,7 +1216,12 @@ public abstract class BatteryStats implements Parcelable {
for (int iu=0; iu<NU; iu++) {
final int uid = uidStats.keyAt(iu);
+ if (reqUid >= 0 && uid != reqUid) {
+ continue;
+ }
+
Uid u = uidStats.valueAt(iu);
+
pw.println(prefix + " #" + uid + ":");
boolean uidActivity = false;
@@ -1421,16 +1430,16 @@ public abstract class BatteryStats implements Parcelable {
pw.println("Total Statistics (Current and Historic):");
pw.println(" System starts: " + getStartCount()
+ ", currently on battery: " + getIsOnBattery());
- dumpLocked(pw, "", STATS_TOTAL);
+ dumpLocked(pw, "", STATS_TOTAL, -1);
pw.println("");
pw.println("Last Run Statistics (Previous run of system):");
- dumpLocked(pw, "", STATS_LAST);
+ dumpLocked(pw, "", STATS_LAST, -1);
pw.println("");
pw.println("Current Battery Statistics (Currently running system):");
- dumpLocked(pw, "", STATS_CURRENT);
+ dumpLocked(pw, "", STATS_CURRENT, -1);
pw.println("");
pw.println("Unplugged Statistics (Since last unplugged from power):");
- dumpLocked(pw, "", STATS_UNPLUGGED);
+ dumpLocked(pw, "", STATS_UNPLUGGED, -1);
}
@SuppressWarnings("unused")
@@ -1445,13 +1454,13 @@ public abstract class BatteryStats implements Parcelable {
}
if (isUnpluggedOnly) {
- dumpCheckinLocked(pw, STATS_UNPLUGGED);
+ dumpCheckinLocked(pw, STATS_UNPLUGGED, -1);
}
else {
- dumpCheckinLocked(pw, STATS_TOTAL);
- dumpCheckinLocked(pw, STATS_LAST);
- dumpCheckinLocked(pw, STATS_UNPLUGGED);
- dumpCheckinLocked(pw, STATS_CURRENT);
+ dumpCheckinLocked(pw, STATS_TOTAL, -1);
+ dumpCheckinLocked(pw, STATS_LAST, -1);
+ dumpCheckinLocked(pw, STATS_UNPLUGGED, -1);
+ dumpCheckinLocked(pw, STATS_CURRENT, -1);
}
}
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
new file mode 100644
index 0000000..343041f
--- /dev/null
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -0,0 +1,287 @@
+package com.android.internal.content;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+
+import java.util.HashSet;
+
+/**
+ * Helper class for monitoring the state of packages: adding, removing,
+ * updating, and disappearing and reappearing on the SD card.
+ */
+public abstract class PackageMonitor extends android.content.BroadcastReceiver {
+ static final IntentFilter sPackageFilt = new IntentFilter();
+ static final IntentFilter sNonDataFilt = new IntentFilter();
+ static final IntentFilter sExternalFilt = new IntentFilter();
+
+ static {
+ sPackageFilt.addAction(Intent.ACTION_PACKAGE_ADDED);
+ sPackageFilt.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ sPackageFilt.addAction(Intent.ACTION_PACKAGE_CHANGED);
+ sPackageFilt.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+ sPackageFilt.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ sPackageFilt.addAction(Intent.ACTION_UID_REMOVED);
+ sPackageFilt.addDataScheme("package");
+ sNonDataFilt.addAction(Intent.ACTION_UID_REMOVED);
+ sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+ sExternalFilt.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+ }
+
+ final HashSet<String> mUpdatingPackages = new HashSet<String>();
+
+ Context mRegisteredContext;
+ String[] mDisappearingPackages;
+ String[] mAppearingPackages;
+ String[] mModifiedPackages;
+ int mChangeType;
+ boolean mSomePackagesChanged;
+
+ String[] mTempArray = new String[1];
+
+ public void register(Context context, boolean externalStorage) {
+ if (mRegisteredContext != null) {
+ throw new IllegalStateException("Already registered");
+ }
+ mRegisteredContext = context;
+ context.registerReceiver(this, sPackageFilt);
+ context.registerReceiver(this, sNonDataFilt);
+ if (externalStorage) {
+ context.registerReceiver(this, sExternalFilt);
+ }
+ }
+
+ public void unregister() {
+ if (mRegisteredContext == null) {
+ throw new IllegalStateException("Not registered");
+ }
+ mRegisteredContext.unregisterReceiver(this);
+ mRegisteredContext = null;
+ }
+
+ //not yet implemented
+ boolean isPackageUpdating(String packageName) {
+ synchronized (mUpdatingPackages) {
+ return mUpdatingPackages.contains(packageName);
+ }
+ }
+
+ public void onBeginPackageChanges() {
+ }
+
+ public void onPackageAdded(String packageName, int uid) {
+ }
+
+ public void onPackageRemoved(String packageName, int uid) {
+ }
+
+ public void onPackageUpdateStarted(String packageName, int uid) {
+ }
+
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ }
+
+ public void onPackageChanged(String packageName, int uid, String[] components) {
+ }
+
+ public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
+ return false;
+ }
+
+ public void onUidRemoved(int uid) {
+ }
+
+ public void onPackagesAvailable(String[] packages) {
+ }
+
+ public void onPackagesUnavailable(String[] packages) {
+ }
+
+ public static final int PACKAGE_UNCHANGED = 0;
+ public static final int PACKAGE_UPDATING = 1;
+ public static final int PACKAGE_TEMPORARY_CHANGE = 2;
+ public static final int PACKAGE_PERMANENT_CHANGE = 3;
+
+ public void onPackageDisappeared(String packageName, int reason) {
+ }
+
+ public void onPackageAppeared(String packageName, int reason) {
+ }
+
+ public void onPackageModified(String packageName) {
+ }
+
+ public boolean didSomePackagesChange() {
+ return mSomePackagesChanged;
+ }
+
+ public int isPackageAppearing(String packageName) {
+ if (mAppearingPackages != null) {
+ for (int i=mAppearingPackages.length-1; i>=0; i--) {
+ if (packageName.equals(mAppearingPackages[i])) {
+ return mChangeType;
+ }
+ }
+ }
+ return PACKAGE_UNCHANGED;
+ }
+
+ public boolean anyPackagesAppearing() {
+ return mAppearingPackages != null;
+ }
+
+ public int isPackageDisappearing(String packageName) {
+ if (mDisappearingPackages != null) {
+ for (int i=mDisappearingPackages.length-1; i>=0; i--) {
+ if (packageName.equals(mDisappearingPackages[i])) {
+ return mChangeType;
+ }
+ }
+ }
+ return PACKAGE_UNCHANGED;
+ }
+
+ public boolean anyPackagesDisappearing() {
+ return mDisappearingPackages != null;
+ }
+
+ public boolean isPackageModified(String packageName) {
+ if (mModifiedPackages != null) {
+ for (int i=mModifiedPackages.length-1; i>=0; i--) {
+ if (packageName.equals(mModifiedPackages[i])) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void onSomePackagesChanged() {
+ }
+
+ public void onFinishPackageChanges() {
+ }
+
+ String getPackageName(Intent intent) {
+ Uri uri = intent.getData();
+ String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ return pkg;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onBeginPackageChanges();
+
+ mDisappearingPackages = mAppearingPackages = null;
+ mSomePackagesChanged = false;
+
+ String action = intent.getAction();
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+ String pkg = getPackageName(intent);
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+ // We consider something to have changed regardless of whether
+ // this is just an update, because the update is now finished
+ // and the contents of the package may have changed.
+ mSomePackagesChanged = true;
+ if (pkg != null) {
+ mAppearingPackages = mTempArray;
+ mTempArray[0] = pkg;
+ if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ mModifiedPackages = mTempArray;
+ mChangeType = PACKAGE_UPDATING;
+ onPackageUpdateFinished(pkg, uid);
+ onPackageModified(pkg);
+ } else {
+ mChangeType = PACKAGE_PERMANENT_CHANGE;
+ onPackageAdded(pkg, uid);
+ }
+ onPackageAppeared(pkg, mChangeType);
+ if (mChangeType == PACKAGE_UPDATING) {
+ synchronized (mUpdatingPackages) {
+ mUpdatingPackages.remove(pkg);
+ }
+ }
+ }
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
+ String pkg = getPackageName(intent);
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+ if (pkg != null) {
+ mDisappearingPackages = mTempArray;
+ mTempArray[0] = pkg;
+ if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ mChangeType = PACKAGE_UPDATING;
+ synchronized (mUpdatingPackages) {
+ //not used for now
+ //mUpdatingPackages.add(pkg);
+ }
+ onPackageUpdateStarted(pkg, uid);
+ } else {
+ mChangeType = PACKAGE_PERMANENT_CHANGE;
+ // We only consider something to have changed if this is
+ // not a replace; for a replace, we just need to consider
+ // it when it is re-added.
+ mSomePackagesChanged = true;
+ onPackageRemoved(pkg, uid);
+ }
+ onPackageDisappeared(pkg, mChangeType);
+ }
+ } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
+ String pkg = getPackageName(intent);
+ int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+ String[] components = intent.getStringArrayExtra(
+ Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST);
+ if (pkg != null) {
+ mModifiedPackages = mTempArray;
+ mTempArray[0] = pkg;
+ onPackageChanged(pkg, uid, components);
+ // XXX Don't want this to always cause mSomePackagesChanged,
+ // since it can happen a fair amount.
+ onPackageModified(pkg);
+ }
+ } else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
+ mDisappearingPackages = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+ mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ boolean canRestart = onHandleForceStop(intent,
+ mDisappearingPackages,
+ intent.getIntExtra(Intent.EXTRA_UID, 0), false);
+ if (canRestart) setResultCode(Activity.RESULT_OK);
+ } else if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+ mDisappearingPackages = new String[] {getPackageName(intent)};
+ mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ onHandleForceStop(intent, mDisappearingPackages,
+ intent.getIntExtra(Intent.EXTRA_UID, 0), true);
+ } else if (Intent.ACTION_UID_REMOVED.equals(action)) {
+ onUidRemoved(intent.getIntExtra(Intent.EXTRA_UID, 0));
+ } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action)) {
+ String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ mAppearingPackages = pkgList;
+ mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mSomePackagesChanged = true;
+ if (pkgList != null) {
+ onPackagesAvailable(pkgList);
+ for (int i=0; i<pkgList.length; i++) {
+ onPackageAppeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ }
+ }
+ } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+ String[] pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ mDisappearingPackages = pkgList;
+ mChangeType = PACKAGE_TEMPORARY_CHANGE;
+ mSomePackagesChanged = true;
+ if (pkgList != null) {
+ onPackagesUnavailable(pkgList);
+ for (int i=0; i<pkgList.length; i++) {
+ onPackageDisappeared(pkgList[i], PACKAGE_TEMPORARY_CHANGE);
+ }
+ }
+ }
+
+ if (mSomePackagesChanged) {
+ onSomePackagesChanged();
+ }
+
+ onFinishPackageChanges();
+ }
+}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index cf34d4e..5b616b3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -618,18 +618,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
if (upgradeVersion == 48) {
/*
- * Adding a new setting for which voice recognition service to use.
+ * Default recognition service no longer initialized here,
+ * moved to RecognitionManagerService.
*/
- db.beginTransaction();
- try {
- SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
- + " VALUES(?,?);");
- loadVoiceRecognitionServiceSetting(stmt);
- stmt.close();
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
upgradeVersion = 49;
}
@@ -1028,8 +1019,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
R.bool.def_mount_ums_notify_enabled);
- loadVoiceRecognitionServiceSetting(stmt);
-
stmt.close();
}
@@ -1041,32 +1030,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
R.string.def_backup_transport);
}
- /**
- * Introduced in database version 49.
- */
- private void loadVoiceRecognitionServiceSetting(SQLiteStatement stmt) {
- String selectedService = null;
- List<ResolveInfo> availableRecognitionServices =
- mContext.getPackageManager().queryIntentServices(
- new Intent(RecognitionService.SERVICE_INTERFACE), 0);
- int numAvailable = availableRecognitionServices.size();
-
- if (numAvailable == 0) {
- Log.w(TAG, "no available voice recognition services found");
- } else {
- if (numAvailable > 1) {
- Log.w(TAG, "more than one voice recognition service found, picking first");
- }
-
- ServiceInfo serviceInfo = availableRecognitionServices.get(0).serviceInfo;
- selectedService =
- new ComponentName(serviceInfo.packageName, serviceInfo.name).flattenToString();
- }
-
- loadSetting(stmt, Settings.Secure.VOICE_RECOGNITION_SERVICE,
- selectedService == null ? "" : selectedService);
- }
-
private void loadSetting(SQLiteStatement stmt, String key, Object value) {
stmt.bindString(1, key);
stmt.bindString(2, value.toString());
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 4080a6a..db802d3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -20,7 +20,6 @@ import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
-import java.util.Random;
import android.backup.BackupManager;
import android.content.ContentProvider;
@@ -30,14 +29,11 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
-import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
-import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
-import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.DrmStore;
import android.provider.MediaStore;
diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java
index 477ea0c..c55dcb3 100644
--- a/services/java/com/android/server/AccessibilityManagerService.java
+++ b/services/java/com/android/server/AccessibilityManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.HandlerCaller.SomeArgs;
@@ -56,6 +57,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -145,13 +147,58 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private void registerPackageChangeAndBootCompletedBroadcastReceiver() {
Context context = mContext;
- BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ PackageMonitor monitor = new PackageMonitor() {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onSomePackagesChanged() {
synchronized (mLock) {
populateAccessibilityServiceListLocked();
+ manageServicesLocked();
+ }
+ }
+
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] packages,
+ int uid, boolean doit) {
+ synchronized (mLock) {
+ boolean changed = false;
+ Iterator<ComponentName> it = mEnabledServices.iterator();
+ while (it.hasNext()) {
+ ComponentName comp = it.next();
+ String compPkg = comp.getPackageName();
+ for (String pkg : packages) {
+ if (compPkg.equals(pkg)) {
+ if (!doit) {
+ return true;
+ }
+ it.remove();
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ it = mEnabledServices.iterator();
+ StringBuilder str = new StringBuilder();
+ while (it.hasNext()) {
+ if (str.length() > 0) {
+ str.append(':');
+ }
+ str.append(it.next().flattenToShortString());
+ }
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ str.toString());
+ manageServicesLocked();
+ }
+ return false;
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
+ synchronized (mLock) {
+ populateAccessibilityServiceListLocked();
- if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
// get the accessibility enabled setting on boot
mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
@@ -160,29 +207,23 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
if (mIsEnabled) {
updateClientsLocked();
}
- }
- manageServicesLocked();
+ manageServicesLocked();
+ }
+
+ return;
}
+
+ super.onReceive(context, intent);
}
};
// package changes
- IntentFilter packageFilter = new IntentFilter();
- packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
- packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- packageFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- packageFilter.addDataScheme("package");
- context.registerReceiver(broadcastReceiver, packageFilter);
- // Register for events related to sdcard installation.
- IntentFilter sdFilter = new IntentFilter();
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(broadcastReceiver, sdFilter);
+ monitor.register(context, true);
// boot completed
IntentFilter bootFiler = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
- mContext.registerReceiver(broadcastReceiver, bootFiler);
+ mContext.registerReceiver(monitor, bootFiler);
}
/**
@@ -529,8 +570,14 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
splitter.setString(servicesValue);
while (splitter.hasNext()) {
- ComponentName enabledService = ComponentName.unflattenFromString(splitter.next());
- enabledServices.add(enabledService);
+ String str = splitter.next();
+ if (str == null || str.length() <= 0) {
+ continue;
+ }
+ ComponentName enabledService = ComponentName.unflattenFromString(str);
+ if (enabledService != null) {
+ enabledServices.add(enabledService);
+ }
}
}
}
diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java
index 44cc0bb..f480209 100644
--- a/services/java/com/android/server/AlarmManagerService.java
+++ b/services/java/com/android/server/AlarmManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.app.Activity;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.IAlarmManager;
@@ -344,6 +345,22 @@ class AlarmManagerService extends IAlarmManager.Stub {
}
}
+ public boolean lookForPackageLocked(String packageName) {
+ return lookForPackageLocked(mRtcWakeupAlarms, packageName)
+ || lookForPackageLocked(mRtcAlarms, packageName)
+ || lookForPackageLocked(mElapsedRealtimeWakeupAlarms, packageName)
+ || lookForPackageLocked(mElapsedRealtimeAlarms, packageName);
+ }
+
+ private boolean lookForPackageLocked(ArrayList<Alarm> alarmList, String packageName) {
+ for (int i=alarmList.size()-1; i>=0; i--) {
+ if (alarmList.get(i).operation.getTargetPackage().equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private ArrayList<Alarm> getAlarmList(int type) {
switch (type) {
case AlarmManager.RTC_WAKEUP: return mRtcWakeupAlarms;
@@ -778,6 +795,7 @@ class AlarmManagerService extends IAlarmManager.Stub {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ filter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
filter.addDataScheme("package");
mContext.registerReceiver(this, filter);
// Register for events related to sdcard installation.
@@ -791,7 +809,16 @@ class AlarmManagerService extends IAlarmManager.Stub {
synchronized (mLock) {
String action = intent.getAction();
String pkgList[] = null;
- if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
+ if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+ for (String packageName : pkgList) {
+ if (lookForPackageLocked(packageName)) {
+ setResultCode(Activity.RESULT_OK);
+ return;
+ }
+ }
+ return;
+ } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
} else {
Uri data = intent.getData();
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index a267e0f..ac65aa9 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -17,6 +17,8 @@
package com.android.server;
import com.android.common.FastXmlSerializer;
+import com.android.common.XmlUtils;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.widget.LockPatternUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -34,6 +36,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Binder;
import android.os.IBinder;
import android.os.IPowerManager;
@@ -58,9 +61,10 @@ import java.util.List;
* Implementation of the device policy APIs.
*/
public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
- private static final String TAG = "DevicePolicyManagerService";
+ static final String TAG = "DevicePolicyManagerService";
- private final Context mContext;
+ final Context mContext;
+ final MyPackageMonitor mMonitor;
IPowerManager mIPowerManager;
@@ -89,6 +93,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
void writeToXml(XmlSerializer out)
throws IllegalArgumentException, IllegalStateException, IOException {
+ out.startTag(null, "policies");
+ info.writePoliciesToXml(out);
+ out.endTag(null, "policies");
if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
out.startTag(null, "password-quality");
out.attribute(null, "value", Integer.toString(passwordQuality));
@@ -121,7 +128,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
continue;
}
String tag = parser.getName();
- if ("password-quality".equals(tag)) {
+ if ("policies".equals(tag)) {
+ info.readPoliciesFromXml(parser);
+ } else if ("password-quality".equals(tag)) {
passwordQuality = Integer.parseInt(
parser.getAttributeValue(null, "value"));
} else if ("min-password-length".equals(tag)) {
@@ -133,6 +142,35 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if ("max-failed-password-wipe".equals(tag)) {
maximumFailedPasswordsForWipe = Integer.parseInt(
parser.getAttributeValue(null, "value"));
+ } else {
+ Log.w(TAG, "Unknown admin tag: " + tag);
+ }
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
+ class MyPackageMonitor extends PackageMonitor {
+ public void onSomePackagesChanged() {
+ synchronized (DevicePolicyManagerService.this) {
+ for (int i=mAdminList.size()-1; i>=0; i--) {
+ ActiveAdmin aa = mAdminList.get(i);
+ int change = isPackageDisappearing(aa.info.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ Log.w(TAG, "Admin unexpectedly uninstalled: "
+ + aa.info.getComponent());
+ mAdminList.remove(i);
+ } else if (isPackageModified(aa.info.getPackageName())) {
+ try {
+ mContext.getPackageManager().getReceiverInfo(
+ aa.info.getComponent(), 0);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Admin package change removed component: "
+ + aa.info.getComponent());
+ mAdminList.remove(i);
+ }
+ }
}
}
}
@@ -143,6 +181,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
*/
public DevicePolicyManagerService(Context context) {
mContext = context;
+ mMonitor = new MyPackageMonitor();
+ mMonitor.register(context, true);
}
private IPowerManager getIPowerManager() {
@@ -336,6 +376,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} else if ("failed-password-attempts".equals(tag)) {
mFailedPasswordAttempts = Integer.parseInt(
parser.getAttributeValue(null, "value"));
+ XmlUtils.skipCurrentTag(parser);
+ } else {
+ Log.w(TAG, "Unknown tag: " + tag);
+ XmlUtils.skipCurrentTag(parser);
}
}
} catch (NullPointerException e) {
@@ -420,6 +464,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ public boolean packageHasActiveAdmins(String packageName) {
+ synchronized (this) {
+ final int N = mAdminList.size();
+ for (int i=0; i<N; i++) {
+ if (mAdminList.get(i).info.getPackageName().equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
public void removeActiveAdmin(ComponentName adminReceiver) {
synchronized (this) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 5e96a2f..59d4c9b 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.os.HandlerCaller;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
@@ -48,7 +49,6 @@ import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.ContentObserver;
-import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -332,51 +332,68 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- class PackageReceiver extends android.content.BroadcastReceiver {
+ class MyPackageMonitor extends PackageMonitor {
+
@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 };
+ public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
+ synchronized (mMethodMap) {
+ String curInputMethodId = Settings.Secure.getString(mContext
+ .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ final int N = mMethodList.size();
+ if (curInputMethodId != null) {
+ for (int i=0; i<N; i++) {
+ InputMethodInfo imi = mMethodList.get(i);
+ if (imi.getId().equals(curInputMethodId)) {
+ for (String pkg : packages) {
+ if (imi.getPackageName().equals(pkg)) {
+ if (!doit) {
+ return true;
+ }
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, "");
+ chooseNewDefaultIMELocked();
+ return true;
+ }
+ }
+ }
+ }
}
- } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(action) ||
- Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
- pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
}
- if (pkgList == null || pkgList.length == 0) {
- return;
- }
- synchronized (mMethodMap) {
- buildInputMethodListLocked(mMethodList, mMethodMap);
+ return false;
+ }
+ @Override
+ public void onSomePackagesChanged() {
+ synchronized (mMethodMap) {
InputMethodInfo curIm = null;
- String curInputMethodId = Settings.Secure.getString(context
+ String curInputMethodId = Settings.Secure.getString(mContext
.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
final int N = mMethodList.size();
if (curInputMethodId != null) {
for (int i=0; i<N; i++) {
- if (mMethodList.get(i).getId().equals(curInputMethodId)) {
- curIm = mMethodList.get(i);
+ InputMethodInfo imi = mMethodList.get(i);
+ if (imi.getId().equals(curInputMethodId)) {
+ curIm = imi;
+ }
+ int change = isPackageDisappearing(imi.getPackageName());
+ if (change == PACKAGE_TEMPORARY_CHANGE
+ || change == PACKAGE_PERMANENT_CHANGE) {
+ Log.i(TAG, "Input method uninstalled, disabling: "
+ + imi.getComponent());
+ setInputMethodEnabledLocked(imi.getId(), false);
}
}
}
+ buildInputMethodListLocked(mMethodList, mMethodMap);
+
boolean changed = false;
if (curIm != null) {
- boolean foundPkg = false;
- for (String pkg : pkgList) {
- if (curIm.getPackageName().equals(pkg)) {
- foundPkg = true;
- break;
- }
- }
- if (foundPkg) {
+ int change = isPackageDisappearing(curIm.getPackageName());
+ if (change == PACKAGE_TEMPORARY_CHANGE
+ || change == PACKAGE_PERMANENT_CHANGE) {
ServiceInfo si = null;
try {
si = mContext.getPackageManager().getServiceInfo(
@@ -387,7 +404,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
// Uh oh, current input method is no longer around!
// Pick another one...
Log.i(TAG, "Current input method removed: " + curInputMethodId);
- if (!chooseNewDefaultIME()) {
+ if (!chooseNewDefaultIMELocked()) {
changed = true;
curIm = null;
curInputMethodId = "";
@@ -397,16 +414,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
curInputMethodId);
}
}
-
- } else if (curIm == null) {
- // We currently don't have a default input method... is
- // one now available?
- changed = chooseNewDefaultIME();
}
+ }
+
+ if (curIm == null) {
+ // We currently don't have a default input method... is
+ // one now available?
+ changed = chooseNewDefaultIMELocked();
+ }
- if (changed) {
- updateFromSettingsLocked();
- }
+ if (changed) {
+ updateFromSettingsLocked();
}
}
}
@@ -438,19 +456,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
});
- 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(mBroadcastReceiver, packageFilt);
- // Register for events related to sdcard installation.
- IntentFilter sdFilter = new IntentFilter();
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
- sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- mContext.registerReceiver(mBroadcastReceiver, sdFilter);
+ (new MyPackageMonitor()).register(mContext, true);
IntentFilter screenOnOffFilt = new IntentFilter();
screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON);
@@ -1385,7 +1391,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
& ApplicationInfo.FLAG_SYSTEM) != 0;
}
- private boolean chooseNewDefaultIME() {
+ private boolean chooseNewDefaultIMELocked() {
List<InputMethodInfo> enabled = getEnabledInputMethodListLocked();
if (enabled != null && enabled.size() > 0) {
Settings.Secure.putString(mContext.getContentResolver(),
@@ -1446,7 +1452,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
String defaultIme = Settings.Secure.getString(mContext
.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
if (!map.containsKey(defaultIme)) {
- if (chooseNewDefaultIME()) {
+ if (chooseNewDefaultIMELocked()) {
updateFromSettingsLocked();
}
}
@@ -1557,90 +1563,94 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
"Requires permission "
+ android.Manifest.permission.WRITE_SECURE_SETTINGS);
}
-
+
long ident = Binder.clearCallingIdentity();
try {
- // Make sure this is a valid input method.
- InputMethodInfo imm = mMethodMap.get(id);
- if (imm == null) {
- if (imm == null) {
- throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
- }
- }
+ return setInputMethodEnabledLocked(id, enabled);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ boolean setInputMethodEnabledLocked(String id, boolean enabled) {
+ // Make sure this is a valid input method.
+ InputMethodInfo imm = mMethodMap.get(id);
+ if (imm == null) {
+ if (imm == null) {
+ throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
+ }
+ }
- StringBuilder builder = new StringBuilder(256);
-
- boolean removed = false;
- String firstId = null;
-
- // Look through the currently enabled input methods.
- String enabledStr = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS);
- if (enabledStr != null) {
- final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(enabledStr);
- while (splitter.hasNext()) {
- String curId = splitter.next();
- if (curId.equals(id)) {
- if (enabled) {
- // We are enabling this input method, but it is
- // already enabled. Nothing to do. The previous
- // state was enabled.
- return true;
- }
- // We are disabling this input method, and it is
- // currently enabled. Skip it to remove from the
- // new list.
- removed = true;
- } else if (!enabled) {
- // We are building a new list of input methods that
- // doesn't contain the given one.
- if (firstId == null) firstId = curId;
- if (builder.length() > 0) builder.append(':');
- builder.append(curId);
- }
- }
- }
+ StringBuilder builder = new StringBuilder(256);
- if (!enabled) {
- if (!removed) {
- // We are disabling the input method but it is already
- // disabled. Nothing to do. The previous state was
- // disabled.
- return false;
- }
- // Update the setting with the new list of input methods.
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
- // We the disabled input method is currently selected, switch
- // to another one.
- String selId = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD);
- if (id.equals(selId)) {
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.DEFAULT_INPUT_METHOD,
- firstId != null ? firstId : "");
- }
- // Previous state was enabled.
- return true;
- }
+ boolean removed = false;
+ String firstId = null;
- // Add in the newly enabled input method.
- if (enabledStr == null || enabledStr.length() == 0) {
- enabledStr = id;
- } else {
- enabledStr = enabledStr + ':' + id;
+ // Look through the currently enabled input methods.
+ String enabledStr = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_INPUT_METHODS);
+ if (enabledStr != null) {
+ final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
+ splitter.setString(enabledStr);
+ while (splitter.hasNext()) {
+ String curId = splitter.next();
+ if (curId.equals(id)) {
+ if (enabled) {
+ // We are enabling this input method, but it is
+ // already enabled. Nothing to do. The previous
+ // state was enabled.
+ return true;
+ }
+ // We are disabling this input method, and it is
+ // currently enabled. Skip it to remove from the
+ // new list.
+ removed = true;
+ } else if (!enabled) {
+ // We are building a new list of input methods that
+ // doesn't contain the given one.
+ if (firstId == null) firstId = curId;
+ if (builder.length() > 0) builder.append(':');
+ builder.append(curId);
}
+ }
+ }
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_INPUT_METHODS, enabledStr);
-
- // Previous state was disabled.
+ if (!enabled) {
+ if (!removed) {
+ // We are disabling the input method but it is already
+ // disabled. Nothing to do. The previous state was
+ // disabled.
return false;
- } finally {
- Binder.restoreCallingIdentity(ident);
}
+ // Update the setting with the new list of input methods.
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
+ // We the disabled input method is currently selected, switch
+ // to another one.
+ String selId = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+ if (id.equals(selId)) {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ firstId != null ? firstId : "");
+ }
+ // Previous state was enabled.
+ return true;
+ }
+
+ // Add in the newly enabled input method.
+ if (enabledStr == null || enabledStr.length() == 0) {
+ enabledStr = id;
+ } else {
+ enabledStr = enabledStr + ':' + id;
}
+
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.ENABLED_INPUT_METHODS, enabledStr);
+
+ // Previous state was disabled.
+ return false;
}
// ----------------------------------------------------------------------
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 004fcf1..dd351be 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -27,6 +27,7 @@ import java.util.Observable;
import java.util.Observer;
import java.util.Set;
+import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -506,6 +507,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
// Register for Package Manager updates
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ intentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
mContext.registerReceiver(mBroadcastReceiver, intentFilter);
IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mBroadcastReceiver, sdFilter);
@@ -1539,8 +1541,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
-
- if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ boolean queryRestart = action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART);
+ if (queryRestart
+ || action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)
|| action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
synchronized (mLock) {
@@ -1560,6 +1563,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
for (int j=i.size()-1; j>=0; j--) {
UpdateRecord ur = i.get(j);
if (ur.mReceiver.isPendingIntent() && ur.mUid == uid) {
+ if (queryRestart) {
+ setResultCode(Activity.RESULT_OK);
+ return;
+ }
if (removedRecs == null) {
removedRecs = new ArrayList<Receiver>();
}
@@ -1572,6 +1579,10 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
ArrayList<ProximityAlert> removedAlerts = null;
for (ProximityAlert i : mProximityAlerts.values()) {
if (i.mUid == uid) {
+ if (queryRestart) {
+ setResultCode(Activity.RESULT_OK);
+ return;
+ }
if (removedAlerts == null) {
removedAlerts = new ArrayList<ProximityAlert>();
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 3657133..3c43352 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -307,6 +307,8 @@ class NotificationManagerService extends INotificationManager.Stub
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ boolean queryRestart = false;
+
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
boolean batteryCharging = (intent.getIntExtra("plugged", 0) != 0);
int level = intent.getIntExtra("level", -1);
@@ -330,10 +332,13 @@ class NotificationManagerService extends INotificationManager.Stub
updateAdbNotification();
} else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)
+ || (queryRestart=action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART))
|| action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
String pkgList[] = null;
if (action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
+ } else if (queryRestart) {
+ pkgList = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
} else {
Uri uri = intent.getData();
if (uri == null) {
@@ -347,7 +352,7 @@ class NotificationManagerService extends INotificationManager.Stub
}
if (pkgList != null && (pkgList.length > 0)) {
for (String pkgName : pkgList) {
- cancelAllNotificationsInt(pkgName, 0, 0);
+ cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart);
}
}
} else if (action.equals(Intent.ACTION_SCREEN_ON)) {
@@ -436,11 +441,15 @@ class NotificationManagerService extends INotificationManager.Stub
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_UMS_CONNECTED);
filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
mContext.registerReceiver(mIntentReceiver, filter);
+ IntentFilter pkgFilter = new IntentFilter();
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ pkgFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+ pkgFilter.addDataScheme("package");
+ mContext.registerReceiver(mIntentReceiver, pkgFilter);
IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
mContext.registerReceiver(mIntentReceiver, sdFilter);
@@ -920,8 +929,8 @@ class NotificationManagerService extends INotificationManager.Stub
* Cancels all notifications from a given package that have all of the
* {@code mustHaveFlags}.
*/
- void cancelAllNotificationsInt(String pkg, int mustHaveFlags,
- int mustNotHaveFlags) {
+ boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
+ int mustNotHaveFlags, boolean doit) {
EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, mustHaveFlags);
synchronized (mNotificationList) {
@@ -938,13 +947,17 @@ class NotificationManagerService extends INotificationManager.Stub
if (!r.pkg.equals(pkg)) {
continue;
}
+ canceledSomething = true;
+ if (!doit) {
+ return true;
+ }
mNotificationList.remove(i);
cancelNotificationLocked(r);
- canceledSomething = true;
}
if (canceledSomething) {
updateLightsLocked();
}
+ return canceledSomething;
}
}
@@ -966,7 +979,7 @@ class NotificationManagerService extends INotificationManager.Stub
// Calling from user space, don't allow the canceling of actively
// running foreground services.
- cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE);
+ cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true);
}
void checkIncomingCall(String pkg) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 38d8615..4fdcd59 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -28,7 +28,9 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.app.ActivityManagerNative;
+import android.app.DevicePolicyManager;
import android.app.IActivityManager;
+import android.app.IDevicePolicyManager;
import android.backup.IBackupManager;
import android.content.ComponentName;
import android.content.Context;
@@ -5594,6 +5596,16 @@ class PackageManagerService extends IPackageManager.Stub {
PackageRemovedInfo info = new PackageRemovedInfo();
boolean res;
+ IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+ try {
+ if (dpm != null && dpm.packageHasActiveAdmins(packageName)) {
+ Log.w(TAG, "Not removing package " + packageName + ": has active device admin");
+ return false;
+ }
+ } catch (RemoteException e) {
+ }
+
synchronized (mInstallLock) {
res = deletePackageLI(packageName, deleteCodeAndResources, flags, info);
}
diff --git a/services/java/com/android/server/RecognitionManagerService.java b/services/java/com/android/server/RecognitionManagerService.java
new file mode 100644
index 0000000..7305b07
--- /dev/null
+++ b/services/java/com/android/server/RecognitionManagerService.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import com.android.internal.content.PackageMonitor;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Binder;
+import android.provider.Settings;
+import android.speech.RecognitionService;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.List;
+
+public class RecognitionManagerService extends Binder {
+ final static String TAG = "RecognitionManagerService";
+
+ final Context mContext;
+ final MyPackageMonitor mMonitor;
+
+ class MyPackageMonitor extends PackageMonitor {
+ public void onSomePackagesChanged() {
+ ComponentName comp = getCurRecognizer();
+ if (comp == null) {
+ if (anyPackagesAppearing()) {
+ comp = findAvailRecognizer(null);
+ if (comp != null) {
+ setCurRecognizer(comp);
+ }
+ }
+ return;
+ }
+
+ int change = isPackageDisappearing(comp.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ setCurRecognizer(findAvailRecognizer(null));
+
+ } else if (isPackageModified(comp.getPackageName())) {
+ setCurRecognizer(findAvailRecognizer(comp.getPackageName()));
+ }
+ }
+ }
+
+ RecognitionManagerService(Context context) {
+ mContext = context;
+ mMonitor = new MyPackageMonitor();
+ mMonitor.register(context, true);
+ }
+
+ public void systemReady() {
+ ComponentName comp = getCurRecognizer();
+ if (comp != null) {
+ // See if the current recognizer is no longer available.
+ try {
+ mContext.getPackageManager().getServiceInfo(comp, 0);
+ } catch (NameNotFoundException e) {
+ setCurRecognizer(null);
+ }
+ } else {
+ comp = findAvailRecognizer(null);
+ if (comp != null) {
+ setCurRecognizer(comp);
+ }
+ }
+ }
+
+ ComponentName findAvailRecognizer(String prefPackage) {
+ List<ResolveInfo> available =
+ mContext.getPackageManager().queryIntentServices(
+ new Intent(RecognitionService.SERVICE_INTERFACE), 0);
+ int numAvailable = available.size();
+
+ if (numAvailable == 0) {
+ Log.w(TAG, "no available voice recognition services found");
+ return null;
+ } else {
+ if (prefPackage != null) {
+ for (int i=0; i<numAvailable; i++) {
+ ServiceInfo serviceInfo = available.get(i).serviceInfo;
+ if (prefPackage.equals(serviceInfo.packageName)) {
+ return new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ }
+ }
+ }
+ if (numAvailable > 1) {
+ Log.w(TAG, "more than one voice recognition service found, picking first");
+ }
+
+ ServiceInfo serviceInfo = available.get(0).serviceInfo;
+ return new ComponentName(serviceInfo.packageName, serviceInfo.name);
+ }
+ }
+
+ ComponentName getCurRecognizer() {
+ String curRecognizer = Settings.Secure.getString(
+ mContext.getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE);
+ if (TextUtils.isEmpty(curRecognizer)) {
+ return null;
+ }
+ return ComponentName.unflattenFromString(curRecognizer);
+ }
+
+ void setCurRecognizer(ComponentName comp) {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.VOICE_RECOGNITION_SERVICE,
+ comp != null ? comp.flattenToShortString() : "");
+ }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a09896a..38df02f 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -97,6 +97,7 @@ class ServerThread extends Thread {
BluetoothA2dpService bluetoothA2dp = null;
HeadsetObserver headset = null;
DockObserver dock = null;
+ RecognitionManagerService recognition = null;
// Critical services...
try {
@@ -377,6 +378,13 @@ class ServerThread extends Thread {
}
try {
+ Log.i(TAG, "Recognition Service");
+ recognition = new RecognitionManagerService(context);
+ } catch (Throwable e) {
+ Log.e(TAG, "Failure starting Recognition Service", e);
+ }
+
+ try {
com.android.server.status.StatusBarPolicy.installIcons(context, statusBar);
} catch (Throwable e) {
Log.e(TAG, "Failure installing status bar icons", e);
@@ -435,6 +443,7 @@ class ServerThread extends Thread {
final AppWidgetService appWidgetF = appWidget;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
+ final RecognitionManagerService recognitionF = recognition;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
@@ -449,6 +458,7 @@ class ServerThread extends Thread {
if (batteryF != null) batteryF.systemReady();
if (connectivityF != null) connectivityF.systemReady();
if (dockF != null) dockF.systemReady();
+ if (recognitionF != null) recognitionF.systemReady();
Watchdog.getInstance().start();
// It is now okay to let the various system services start their
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 81255ee..481e6a4 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -65,7 +65,10 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import com.android.internal.content.PackageMonitor;
import com.android.internal.service.wallpaper.ImageWallpaper;
+import com.android.server.DevicePolicyManagerService.ActiveAdmin;
+import com.android.server.DevicePolicyManagerService.MyPackageMonitor;
import com.android.common.FastXmlSerializer;
class WallpaperManagerService extends IWallpaperManager.Stub {
@@ -122,6 +125,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
final Context mContext;
final IWindowManager mIWindowManager;
+ final MyPackageMonitor mMonitor;
int mWidth = -1;
int mHeight = -1;
@@ -150,6 +154,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperConnection mWallpaperConnection;
long mLastDiedTime;
+ boolean mWallpaperUpdating;
class WallpaperConnection extends IWallpaperConnection.Stub
implements ServiceConnection {
@@ -165,6 +170,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public void onServiceConnected(ComponentName name, IBinder service) {
synchronized (mLock) {
if (mWallpaperConnection == this) {
+ mLastDiedTime = SystemClock.uptimeMillis();
mService = IWallpaperService.Stub.asInterface(service);
attachServiceLocked(this);
// XXX should probably do saveSettingsLocked() later
@@ -182,8 +188,8 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
mEngine = null;
if (mWallpaperConnection == this) {
Log.w(TAG, "Wallpaper service gone: " + mWallpaperComponent);
- if ((mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
- < SystemClock.uptimeMillis()) {
+ if (!mWallpaperUpdating && (mLastDiedTime+MIN_WALLPAPER_CRASH_TIME)
+ > SystemClock.uptimeMillis()) {
Log.w(TAG, "Reverting to built-in wallpaper!");
bindWallpaperComponentLocked(null);
}
@@ -205,11 +211,92 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
}
}
+ class MyPackageMonitor extends PackageMonitor {
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ synchronized (mLock) {
+ if (mWallpaperComponent != null &&
+ mWallpaperComponent.getPackageName().equals(packageName)) {
+ mWallpaperUpdating = false;
+ ComponentName comp = mWallpaperComponent;
+ clearWallpaperComponentLocked();
+ bindWallpaperComponentLocked(comp);
+ }
+ }
+ }
+
+ @Override
+ public void onPackageUpdateStarted(String packageName, int uid) {
+ synchronized (mLock) {
+ if (mWallpaperComponent != null &&
+ mWallpaperComponent.getPackageName().equals(packageName)) {
+ mWallpaperUpdating = true;
+ }
+ }
+ }
+
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
+ return doPackagesChanged(doit);
+ }
+
+ @Override
+ public void onSomePackagesChanged() {
+ doPackagesChanged(true);
+ }
+
+ boolean doPackagesChanged(boolean doit) {
+ boolean changed = false;
+ synchronized (mLock) {
+ if (mWallpaperComponent != null) {
+ int change = isPackageDisappearing(mWallpaperComponent.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ changed = true;
+ if (doit) {
+ Log.w(TAG, "Wallpaper uninstalled, removing: " + mWallpaperComponent);
+ clearWallpaperLocked();
+ }
+ }
+ }
+ if (mNextWallpaperComponent != null) {
+ int change = isPackageDisappearing(mNextWallpaperComponent.getPackageName());
+ if (change == PACKAGE_PERMANENT_CHANGE
+ || change == PACKAGE_TEMPORARY_CHANGE) {
+ mNextWallpaperComponent = null;
+ }
+ }
+ if (mWallpaperComponent != null
+ && isPackageModified(mWallpaperComponent.getPackageName())) {
+ try {
+ mContext.getPackageManager().getServiceInfo(
+ mWallpaperComponent, 0);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Wallpaper component gone, removing: " + mWallpaperComponent);
+ clearWallpaperLocked();
+ }
+ }
+ if (mNextWallpaperComponent != null
+ && isPackageModified(mNextWallpaperComponent.getPackageName())) {
+ try {
+ mContext.getPackageManager().getServiceInfo(
+ mNextWallpaperComponent, 0);
+ } catch (NameNotFoundException e) {
+ mNextWallpaperComponent = null;
+ }
+ }
+ }
+ return changed;
+ }
+ }
+
public WallpaperManagerService(Context context) {
if (DEBUG) Log.v(TAG, "WallpaperService startup");
mContext = context;
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
+ mMonitor = new MyPackageMonitor();
+ mMonitor.register(context, true);
WALLPAPER_DIR.mkdirs();
loadSettingsLocked();
mWallpaperObserver.startWatching();
@@ -241,16 +328,20 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
public void clearWallpaper() {
if (DEBUG) Log.v(TAG, "clearWallpaper");
synchronized (mLock) {
- File f = WALLPAPER_FILE;
- if (f.exists()) {
- f.delete();
- }
- final long ident = Binder.clearCallingIdentity();
- try {
- bindWallpaperComponentLocked(null);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ clearWallpaperLocked();
+ }
+ }
+
+ public void clearWallpaperLocked() {
+ File f = WALLPAPER_FILE;
+ if (f.exists()) {
+ f.delete();
+ }
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ bindWallpaperComponentLocked(null);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
@@ -499,7 +590,9 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
mWidth, mHeight);
} catch (RemoteException e) {
Log.w(TAG, "Failed attaching wallpaper; clearing", e);
- bindWallpaperComponentLocked(null);
+ if (!mWallpaperUpdating) {
+ bindWallpaperComponentLocked(null);
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 45c3f00..5b37f47 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -47,6 +47,7 @@ import android.app.ResultInfo;
import android.app.Service;
import android.backup.IBackupManager;
import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -93,7 +94,6 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
-import android.text.TextUtils;
import android.util.Config;
import android.util.EventLog;
import android.util.Log;
@@ -107,7 +107,6 @@ import android.view.WindowManagerPolicy;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
@@ -296,12 +295,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
// Memory pages are 4K.
static final int PAGE_SIZE = 4*1024;
- // System property defining error report receiver for system apps
- static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
-
- // System property defining default error report receiver
- static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
-
// Corresponding memory levels for above adjustments.
static final int EMPTY_APP_MEM;
static final int HIDDEN_APP_MEM;
@@ -1193,7 +1186,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
int uid = msg.arg1;
boolean restart = (msg.arg2 == 1);
String pkg = (String) msg.obj;
- forceStopPackageLocked(pkg, uid, restart, false);
+ forceStopPackageLocked(pkg, uid, restart, false, true);
}
} break;
}
@@ -1396,7 +1389,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
- mConfiguration.makeDefault();
+ mConfiguration.setToDefaults();
+ mConfiguration.locale = Locale.getDefault();
mProcessStats.init();
// Add ourself to the Watchdog monitors.
@@ -4846,7 +4840,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return;
}
killPackageProcessesLocked(packageName, pkgUid,
- SECONDARY_SERVER_ADJ, false);
+ SECONDARY_SERVER_ADJ, false, true);
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -4988,7 +4982,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
private void forceStopPackageLocked(final String packageName, int uid) {
- forceStopPackageLocked(packageName, uid, false, false);
+ forceStopPackageLocked(packageName, uid, false, false, true);
Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
Uri.fromParts("package", packageName, null));
intent.putExtra(Intent.EXTRA_UID, uid);
@@ -4997,8 +4991,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
false, false, MY_PID, Process.SYSTEM_UID);
}
- private final void killPackageProcessesLocked(String packageName, int uid,
- int minOomAdj, boolean callerWillRestart) {
+ private final boolean killPackageProcessesLocked(String packageName, int uid,
+ int minOomAdj, boolean callerWillRestart, boolean doit) {
ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
// Remove all processes this package may have touched: all with the
@@ -5010,11 +5004,16 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
for (int ia=0; ia<NA; ia++) {
ProcessRecord app = apps.valueAt(ia);
if (app.removed) {
- procs.add(app);
+ if (doit) {
+ procs.add(app);
+ }
} else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
|| app.processName.equals(packageName)
|| app.processName.startsWith(procNamePrefix)) {
if (app.setAdj >= minOomAdj) {
+ if (!doit) {
+ return true;
+ }
app.removed = true;
procs.add(app);
}
@@ -5026,10 +5025,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
for (int i=0; i<N; i++) {
removeProcessLocked(procs.get(i), callerWillRestart);
}
+ return N > 0;
}
- private final void forceStopPackageLocked(String name, int uid,
- boolean callerWillRestart, boolean purgeCache) {
+ private final boolean forceStopPackageLocked(String name, int uid,
+ boolean callerWillRestart, boolean purgeCache, boolean doit) {
int i, N;
if (uid < 0) {
@@ -5039,21 +5039,28 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
- Log.i(TAG, "Force stopping package " + name + " uid=" + uid);
+ if (doit) {
+ Log.i(TAG, "Force stopping package " + name + " uid=" + uid);
- Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
- while (badApps.hasNext()) {
- SparseArray<Long> ba = badApps.next();
- if (ba.get(uid) != null) {
- badApps.remove();
+ Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
+ while (badApps.hasNext()) {
+ SparseArray<Long> ba = badApps.next();
+ if (ba.get(uid) != null) {
+ badApps.remove();
+ }
}
}
-
- killPackageProcessesLocked(name, uid, -100, callerWillRestart);
+
+ boolean didSomething = killPackageProcessesLocked(name, uid, -100,
+ callerWillRestart, doit);
for (i=mHistory.size()-1; i>=0; i--) {
HistoryRecord r = (HistoryRecord)mHistory.get(i);
if (r.packageName.equals(name)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
Log.i(TAG, " Force finishing activity " + r);
if (r.app != null) {
r.app.removed = true;
@@ -5066,6 +5073,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
for (ServiceRecord service : mServices.values()) {
if (service.packageName.equals(name)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
Log.i(TAG, " Force stopping service " + service);
if (service.app != null) {
service.app.removed = true;
@@ -5080,13 +5091,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
bringDownServiceLocked(services.get(i), true);
}
- resumeTopActivityLocked(null);
- if (purgeCache) {
- AttributeCache ac = AttributeCache.instance();
- if (ac != null) {
- ac.removePackage(name);
+ if (doit) {
+ if (purgeCache) {
+ AttributeCache ac = AttributeCache.instance();
+ if (ac != null) {
+ ac.removePackage(name);
+ }
}
+ resumeTopActivityLocked(null);
}
+
+ return didSomething;
}
private final boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart) {
@@ -5583,19 +5598,38 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
final void finishBooting() {
- // Ensure that any processes we had put on hold are now started
- // up.
- final int NP = mProcessesOnHold.size();
- if (NP > 0) {
- ArrayList<ProcessRecord> procs =
- new ArrayList<ProcessRecord>(mProcessesOnHold);
- for (int ip=0; ip<NP; ip++) {
- this.startProcessLocked(procs.get(ip), "on-hold", null);
+ IntentFilter pkgFilter = new IntentFilter();
+ pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
+ pkgFilter.addDataScheme("package");
+ mContext.registerReceiver(new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+ if (pkgs != null) {
+ for (String pkg : pkgs) {
+ if (forceStopPackageLocked(pkg, -1, false, false, false)) {
+ setResultCode(Activity.RESULT_OK);
+ return;
+ }
+ }
+ }
}
- }
- if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
- // Tell anyone interested that we are done booting!
- synchronized (this) {
+ }, pkgFilter);
+
+ synchronized (this) {
+ // Ensure that any processes we had put on hold are now started
+ // up.
+ final int NP = mProcessesOnHold.size();
+ if (NP > 0) {
+ ArrayList<ProcessRecord> procs =
+ new ArrayList<ProcessRecord>(mProcessesOnHold);
+ for (int ip=0; ip<NP; ip++) {
+ this.startProcessLocked(procs.get(ip), "on-hold", null);
+ }
+ }
+
+ if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
+ // Tell anyone interested that we are done booting!
broadcastIntentLocked(null, null,
new Intent(Intent.ACTION_BOOT_COMPLETED, null),
null, null, 0, null, null,
@@ -8050,7 +8084,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mDebugTransient = !persistent;
if (packageName != null) {
final long origId = Binder.clearCallingIdentity();
- forceStopPackageLocked(packageName, -1, false, false);
+ forceStopPackageLocked(packageName, -1, false, false, true);
Binder.restoreCallingIdentity(origId);
}
}
@@ -8339,7 +8373,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
mAlwaysFinishActivities = alwaysFinishActivities;
// This happens before any activities are started, so we can
// change mConfiguration in-place.
- mConfiguration.locale = Locale.getDefault();
mConfiguration.updateFrom(configuration);
mConfigurationSeq = mConfiguration.seq = 1;
if (DEBUG_CONFIGURATION) Log.v(TAG, "Initial config: " + mConfiguration);
@@ -8537,73 +8570,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
return handleAppCrashLocked(app);
}
- private ComponentName getErrorReportReceiver(ProcessRecord app) {
- // check if error reporting is enabled in secure settings
- int enabled = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SEND_ACTION_APP_ERROR, 0);
- if (enabled == 0) {
- return null;
- }
-
- IPackageManager pm = ActivityThread.getPackageManager();
-
- try {
- // look for receiver in the installer package
- String candidate = pm.getInstallerPackageName(app.info.packageName);
- ComponentName result = getErrorReportReceiver(pm, app.info.packageName, candidate);
- if (result != null) {
- return result;
- }
-
- // if the error app is on the system image, look for system apps
- // error receiver
- if ((app.info.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
- candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
- result = getErrorReportReceiver(pm, app.info.packageName, candidate);
- if (result != null) {
- return result;
- }
- }
-
- // if there is a default receiver, try that
- candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
- return getErrorReportReceiver(pm, app.info.packageName, candidate);
- } catch (RemoteException e) {
- // should not happen
- Log.e(TAG, "error talking to PackageManager", e);
- return null;
- }
- }
-
- /**
- * Return activity in receiverPackage that handles ACTION_APP_ERROR.
- *
- * @param pm PackageManager isntance
- * @param errorPackage package which caused the error
- * @param receiverPackage candidate package to receive the error
- * @return activity component within receiverPackage which handles
- * ACTION_APP_ERROR, or null if not found
- */
- private ComponentName getErrorReportReceiver(IPackageManager pm, String errorPackage,
- String receiverPackage) throws RemoteException {
- if (receiverPackage == null || receiverPackage.length() == 0) {
- return null;
- }
-
- // break the loop if it's the error report receiver package that crashed
- if (receiverPackage.equals(errorPackage)) {
- return null;
- }
-
- Intent intent = new Intent(Intent.ACTION_APP_ERROR);
- intent.setPackage(receiverPackage);
- ResolveInfo info = pm.resolveIntent(intent, null, 0);
- if (info == null || info.activityInfo == null) {
- return null;
- }
- return new ComponentName(receiverPackage, info.activityInfo.name);
- }
-
private void makeAppNotRespondingLocked(ProcessRecord app,
String activity, String shortMsg, String longMsg) {
app.notResponding = true;
@@ -8717,7 +8683,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
void startAppProblemLocked(ProcessRecord app) {
- app.errorReportReceiver = getErrorReportReceiver(app);
+ app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
+ mContext, app.info.packageName, app.info.flags);
skipCurrentReceiverLocked(app);
}
@@ -11951,7 +11918,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
if (list != null && (list.length > 0)) {
for (String pkg : list) {
- forceStopPackageLocked(pkg, -1, false, true);
+ forceStopPackageLocked(pkg, -1, false, true, true);
}
}
} else {
@@ -11960,7 +11927,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
forceStopPackageLocked(ssp,
- intent.getIntExtra(Intent.EXTRA_UID, -1), false, true);
+ intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
}
}
}
@@ -12931,7 +12898,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
final long origId = Binder.clearCallingIdentity();
- forceStopPackageLocked(ii.targetPackage, -1, true, false);
+ forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
ProcessRecord app = addAppLocked(ai);
app.instrumentationClass = className;
app.instrumentationInfo = ai;
@@ -12986,7 +12953,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
app.instrumentationProfileFile = null;
app.instrumentationArguments = null;
- forceStopPackageLocked(app.processName, -1, false, false);
+ forceStopPackageLocked(app.processName, -1, false, false, true);
}
public void finishInstrumentation(IApplicationThread target,