summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityThread.java9
-rw-r--r--core/java/android/content/Intent.java6
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/values/cm_strings.xml2
-rw-r--r--core/res/res/values/cm_symbols.xml3
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java26
-rw-r--r--services/java/com/android/server/AppsFailureReceiver.java (renamed from services/java/com/android/server/AppsLaunchFailureReceiver.java)38
-rw-r--r--services/java/com/android/server/SystemServer.java6
8 files changed, 76 insertions, 20 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6c88563..cd27d76 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2428,13 +2428,6 @@ public final class ActivityThread {
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
- if (e instanceof InflateException) {
- Log.e(TAG, "Failed to inflate", e);
- sendAppLaunchFailureBroadcast(r);
- } else if (e instanceof Resources.NotFoundException) {
- Log.e(TAG, "Failed to find resource", e);
- sendAppLaunchFailureBroadcast(r);
- }
throw new RuntimeException(
"Unable to start activity " + component
+ ": " + e.toString(), e);
@@ -2449,7 +2442,7 @@ public final class ActivityThread {
if (r.packageInfo != null && !TextUtils.isEmpty(r.packageInfo.getPackageName())) {
pkg = r.packageInfo.getPackageName();
}
- Intent intent = new Intent(Intent.ACTION_APP_LAUNCH_FAILURE,
+ Intent intent = new Intent(Intent.ACTION_APP_FAILURE,
(pkg != null)? Uri.fromParts("package", pkg, null) : null);
getSystemContext().sendBroadcast(intent);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 052c6d3..a1a0867 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2846,13 +2846,15 @@ public class Intent implements Parcelable, Cloneable {
* Could indicate that curently applied theme is malicious.
* @hide
*/
- public static final String ACTION_APP_LAUNCH_FAILURE = "com.tmobile.intent.action.APP_LAUNCH_FAILURE";
+ public static final String ACTION_APP_FAILURE =
+ "com.tmobile.intent.action.APP_FAILURE";
/**
* Broadcast Action: Request to reset the unrecoverable errors count to 0.
* @hide
*/
- public static final String ACTION_APP_LAUNCH_FAILURE_RESET = "com.tmobile.intent.action.APP_LAUNCH_FAILURE_RESET";
+ public static final String ACTION_APP_FAILURE_RESET =
+ "com.tmobile.intent.action.APP_FAILURE_RESET";
/**
* Activity Action: Shows the brightness setting dialog.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 863b9ea..540a74b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2954,10 +2954,10 @@
</intent-filter>
</receiver>
- <receiver android:name="com.android.server.AppsLaunchFailureReceiver" >
+ <receiver android:name="com.android.server.AppsFailureReceiver" >
<intent-filter>
- <action android:name="com.tmobile.intent.action.APP_LAUNCH_FAILURE" />
- <action android:name="com.tmobile.intent.action.APP_LAUNCH_FAILURE_RESET" />
+ <action android:name="com.tmobile.intent.action.APP_FAILURE" />
+ <action android:name="com.tmobile.intent.action.APP_FAILURE_RESET" />
<action android:name="android.intent.action.PACKAGE_ADDED" />
<action android:name="android.intent.action.PACKAGE_REMOVED" />
<action android:name="org.cyanogenmod.intent.action.THEME_CHANGED" />
diff --git a/core/res/res/values/cm_strings.xml b/core/res/res/values/cm_strings.xml
index 98e0539..b5da286 100644
--- a/core/res/res/values/cm_strings.xml
+++ b/core/res/res/values/cm_strings.xml
@@ -133,4 +133,6 @@
<!-- stylus gestures support -->
<string name="stylus_app_not_installed">%s is not installed</string>
+ <string name="theme_reset_notification_title">Theme reset</string>
+ <string name="theme_reset_notification_body">System theme restored due to multiple app crashes.</string>
</resources>
diff --git a/core/res/res/values/cm_symbols.xml b/core/res/res/values/cm_symbols.xml
index d2ad24d..a5d780e 100644
--- a/core/res/res/values/cm_symbols.xml
+++ b/core/res/res/values/cm_symbols.xml
@@ -71,4 +71,7 @@
<java-symbol type="bool" name="config_stylusGestures" />
<java-symbol type="string" name="stylus_app_not_installed" />
+ <!-- Theme reset notification -->
+ <java-symbol type="string" name="theme_reset_notification_title" />
+ <java-symbol type="string" name="theme_reset_notification_body" />
</resources>
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6c450c6..9da1a95 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -76,6 +76,7 @@ import android.util.SparseIntArray;
import android.view.Display;
import android.util.BoostFramework;
+import android.view.InflateException;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.AssistUtils;
@@ -12024,6 +12025,28 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ private void sendAppFailureBroadcast(String pkgName) {
+ Intent intent = new Intent(Intent.ACTION_APP_FAILURE,
+ (pkgName != null)? Uri.fromParts("package", pkgName, null) : null);
+ mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT_OR_SELF);
+ }
+
+ /**
+ * A possible theme crash is one that throws one of the following exceptions
+ * {@link android.content.res.Resources.NotFoundException}
+ * {@link android.view.InflateException}
+ *
+ * @param exceptionClassName
+ * @return True if exceptionClassName is one of the above exceptions
+ */
+ private boolean isPossibleThemeCrash(String exceptionClassName) {
+ if (Resources.NotFoundException.class.getName().equals(exceptionClassName) ||
+ InflateException.class.getName().equals(exceptionClassName)) {
+ return true;
+ }
+ return false;
+ }
+
private boolean handleAppCrashLocked(ProcessRecord app, String reason,
String shortMsg, String longMsg, String stackTrace) {
long now = SystemClock.uptimeMillis();
@@ -12034,6 +12057,9 @@ public final class ActivityManagerService extends ActivityManagerNative
} else {
crashTime = null;
}
+
+ if (isPossibleThemeCrash(shortMsg)) sendAppFailureBroadcast(app.info.packageName);
+
if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
// This process loses!
Slog.w(TAG, "Process " + app.info.processName
diff --git a/services/java/com/android/server/AppsLaunchFailureReceiver.java b/services/java/com/android/server/AppsFailureReceiver.java
index 81b23ec..bebef9b 100644
--- a/services/java/com/android/server/AppsLaunchFailureReceiver.java
+++ b/services/java/com/android/server/AppsFailureReceiver.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010, T-Mobile USA, Inc.
+ * Copyright (C) 2015 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,9 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.android.server;
+import android.app.Notification;
+import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -28,11 +30,15 @@ import android.provider.ThemesContract;
import java.util.ArrayList;
import java.util.List;
-public class AppsLaunchFailureReceiver extends BroadcastReceiver {
+import com.android.internal.R;
+
+public class AppsFailureReceiver extends BroadcastReceiver {
private static final int FAILURES_THRESHOLD = 3;
private static final int EXPIRATION_TIME_IN_MILLISECONDS = 30000; // 30 seconds
+ private static final int THEME_RESET_NOTIFICATION_ID = 0x4641494C;
+
private int mFailuresCount = 0;
private long mStartTime = 0;
@@ -44,8 +50,9 @@ public class AppsLaunchFailureReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(Intent.ACTION_APP_LAUNCH_FAILURE)) {
+ if (action.equals(Intent.ACTION_APP_FAILURE)) {
long currentTime = SystemClock.uptimeMillis();
+ String pkgName = intent.getStringExtra("package");
if (currentTime - mStartTime > EXPIRATION_TIME_IN_MILLISECONDS) {
// reset both the count and the timer
mStartTime = currentTime;
@@ -70,9 +77,10 @@ public class AppsLaunchFailureReceiver extends BroadcastReceiver {
components.add(ThemesContract.ThemesColumns.MODIFIES_STATUS_BAR);
components.add(ThemesContract.ThemesColumns.MODIFIES_NAVIGATION_BAR);
tm.requestThemeChange(ThemeConfig.SYSTEM_DEFAULT, components);
+ postThemeResetNotification(context);
}
}
- } else if (action.equals(Intent.ACTION_APP_LAUNCH_FAILURE_RESET)
+ } else if (action.equals(Intent.ACTION_APP_FAILURE_RESET)
|| action.equals(ThemeUtils.ACTION_THEME_CHANGED)) {
mFailuresCount = 0;
mStartTime = SystemClock.uptimeMillis();
@@ -83,4 +91,26 @@ public class AppsLaunchFailureReceiver extends BroadcastReceiver {
}
}
+ /**
+ * Posts a notification to let the user know their theme was reset
+ * @param context
+ */
+ private void postThemeResetNotification(Context context) {
+ NotificationManager nm =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ String title = context.getString(R.string.theme_reset_notification_title);
+ String body = context.getString(R.string.theme_reset_notification_body);
+ Notification notice = new Notification.Builder(context)
+ .setAutoCancel(true)
+ .setOngoing(false)
+ .setContentTitle(title)
+ .setContentText(body)
+ .setStyle(new Notification.BigTextStyle().bigText(body))
+ .setSmallIcon(android.R.drawable.stat_notify_error)
+ .setWhen(System.currentTimeMillis())
+ .setCategory(Notification.CATEGORY_SYSTEM)
+ .setPriority(Notification.PRIORITY_MAX)
+ .build();
+ nm.notify(THEME_RESET_NOTIFICATION_ID, notice);
+ }
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b4427ec..48deb68 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1152,14 +1152,14 @@ public final class SystemServer {
}
IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_APP_LAUNCH_FAILURE);
- filter.addAction(Intent.ACTION_APP_LAUNCH_FAILURE_RESET);
+ filter.addAction(Intent.ACTION_APP_FAILURE);
+ filter.addAction(Intent.ACTION_APP_FAILURE_RESET);
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(ThemeUtils.ACTION_THEME_CHANGED);
filter.addCategory(Intent.CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE);
filter.addDataScheme("package");
- context.registerReceiver(new AppsLaunchFailureReceiver(), filter);
+ context.registerReceiver(new AppsFailureReceiver(), filter);
// These are needed to propagate to the runnable below.
final NetworkManagementService networkManagementF = networkManagement;