diff options
author | d34d <clark@cyngn.com> | 2015-01-22 17:48:59 -0800 |
---|---|---|
committer | Clark Scheff <clark@cyngn.com> | 2015-10-27 10:39:14 -0700 |
commit | c26aa7cf406401e4e90fd8e8a3f4ad1e9284d5d5 (patch) | |
tree | 629402cefe5a6134aa0fa629c6b28975964c633a /services | |
parent | a4ee56970265e780813c5e19da68a3f49b79a3a8 (diff) | |
download | frameworks_base-c26aa7cf406401e4e90fd8e8a3f4ad1e9284d5d5.zip frameworks_base-c26aa7cf406401e4e90fd8e8a3f4ad1e9284d5d5.tar.gz frameworks_base-c26aa7cf406401e4e90fd8e8a3f4ad1e9284d5d5.tar.bz2 |
Themes: Watch all app crashes for problematic themes
Only watching for exceptions that occur during an apps launch may
not be sufficient to catch possible bad themes causing issues.
This patch monitors all app crashes and broadcasts that there was
a crash if either Resources.NotFoundException or InflateException
are thrown. The remaining logic is the same as when an app launch
failure occurred.
We also display a notification to the user so that they know why
their theme was reset to the system theme.
Change-Id: I0761d02587b5b81deee4a31a89f515dbc7cc5fe6
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 26 | ||||
-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.java | 6 |
3 files changed, 63 insertions, 7 deletions
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; |