Loading services/core/java/com/android/server/RescueParty.java +6 −6 Original line number Diff line number Diff line Loading @@ -131,10 +131,10 @@ public class RescueParty { } /** * Take note of a persistent app crash. If we notice too many of these * Take note of a persistent app or apex module crash. If we notice too many of these * events happening in rapid succession, we'll send out a rescue party. */ public static void notePersistentAppCrash(Context context, int uid) { public static void noteAppCrash(Context context, int uid) { if (isDisabled()) return; Threshold t = sApps.get(uid); if (t == null) { Loading Loading @@ -245,14 +245,14 @@ public class RescueParty { Exception res = null; final ContentResolver resolver = context.getContentResolver(); try { Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM); FlagNamespaceUtils.resetDeviceConfig(mode); } catch (Exception e) { res = new RuntimeException("Failed to reset global settings", e); res = new RuntimeException("Failed to reset config settings", e); } try { FlagNamespaceUtils.resetDeviceConfig(mode); Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM); } catch (Exception e) { res = new RuntimeException("Failed to reset config settings", e); res = new RuntimeException("Failed to reset global settings", e); } for (int userId : getAllUserIds()) { try { Loading services/core/java/com/android/server/am/AppErrors.java +24 −8 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.net.Uri; import android.os.Binder; Loading Loading @@ -406,15 +408,29 @@ class AppErrors { } if (r != null) { if (r.isPersistent()) { // If a persistent app is stuck in a crash loop, the device isn't very // usable, so we want to consider sending out a rescue party. RescueParty.notePersistentAppCrash(mContext, r.uid); } else { // If a non-persistent app is stuck in crash loop, we want to inform // the package watchdog, maybe an update or experiment can be rolled back. mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode()); boolean isApexModule = false; try { for (String androidPackage : r.getPackageList()) { ModuleInfo moduleInfo = mContext.getPackageManager().getModuleInfo( androidPackage, /*flags=*/ 0); if (moduleInfo != null) { isApexModule = true; break; } } } catch (IllegalStateException | PackageManager.NameNotFoundException e) { // Call to PackageManager#getModuleInfo() can result in NameNotFoundException or // IllegalStateException. In case they are thrown, there isn't much we can do // other than proceed with app crash handling. } if (r.isPersistent() || isApexModule) { // If a persistent app or apex module is stuck in a crash loop, the device isn't // very usable, so we want to consider sending out a rescue party. RescueParty.noteAppCrash(mContext, r.uid); } mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode()); } final int relaunchReason = r != null Loading services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -334,7 +334,7 @@ public class RescuePartyTest { private void notePersistentAppCrash(int numTimes) { for (int i = 0; i < numTimes; i++) { RescueParty.notePersistentAppCrash(mMockContext, PERSISTENT_APP_UID); RescueParty.noteAppCrash(mMockContext, PERSISTENT_APP_UID); } } } Loading
services/core/java/com/android/server/RescueParty.java +6 −6 Original line number Diff line number Diff line Loading @@ -131,10 +131,10 @@ public class RescueParty { } /** * Take note of a persistent app crash. If we notice too many of these * Take note of a persistent app or apex module crash. If we notice too many of these * events happening in rapid succession, we'll send out a rescue party. */ public static void notePersistentAppCrash(Context context, int uid) { public static void noteAppCrash(Context context, int uid) { if (isDisabled()) return; Threshold t = sApps.get(uid); if (t == null) { Loading Loading @@ -245,14 +245,14 @@ public class RescueParty { Exception res = null; final ContentResolver resolver = context.getContentResolver(); try { Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM); FlagNamespaceUtils.resetDeviceConfig(mode); } catch (Exception e) { res = new RuntimeException("Failed to reset global settings", e); res = new RuntimeException("Failed to reset config settings", e); } try { FlagNamespaceUtils.resetDeviceConfig(mode); Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM); } catch (Exception e) { res = new RuntimeException("Failed to reset config settings", e); res = new RuntimeException("Failed to reset global settings", e); } for (int userId : getAllUserIds()) { try { Loading
services/core/java/com/android/server/am/AppErrors.java +24 −8 Original line number Diff line number Diff line Loading @@ -34,6 +34,8 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.ModuleInfo; import android.content.pm.PackageManager; import android.content.pm.VersionedPackage; import android.net.Uri; import android.os.Binder; Loading Loading @@ -406,15 +408,29 @@ class AppErrors { } if (r != null) { if (r.isPersistent()) { // If a persistent app is stuck in a crash loop, the device isn't very // usable, so we want to consider sending out a rescue party. RescueParty.notePersistentAppCrash(mContext, r.uid); } else { // If a non-persistent app is stuck in crash loop, we want to inform // the package watchdog, maybe an update or experiment can be rolled back. mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode()); boolean isApexModule = false; try { for (String androidPackage : r.getPackageList()) { ModuleInfo moduleInfo = mContext.getPackageManager().getModuleInfo( androidPackage, /*flags=*/ 0); if (moduleInfo != null) { isApexModule = true; break; } } } catch (IllegalStateException | PackageManager.NameNotFoundException e) { // Call to PackageManager#getModuleInfo() can result in NameNotFoundException or // IllegalStateException. In case they are thrown, there isn't much we can do // other than proceed with app crash handling. } if (r.isPersistent() || isApexModule) { // If a persistent app or apex module is stuck in a crash loop, the device isn't // very usable, so we want to consider sending out a rescue party. RescueParty.noteAppCrash(mContext, r.uid); } mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode()); } final int relaunchReason = r != null Loading
services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -334,7 +334,7 @@ public class RescuePartyTest { private void notePersistentAppCrash(int numTimes) { for (int i = 0; i < numTimes; i++) { RescueParty.notePersistentAppCrash(mMockContext, PERSISTENT_APP_UID); RescueParty.noteAppCrash(mMockContext, PERSISTENT_APP_UID); } } }