Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 484e6dbb authored by Hongyi Zhang's avatar Hongyi Zhang
Browse files

Start rebootPromptAndWipeUserData from a separate thread in RescueParty

Call rebootPromptAndWipeUserData from currently thread in RescueParty
will cause a deadlock in PackageWatchdog when shutting down device, if the reset is triggerred by PackageWatchdog.
Forking a separate thread to execute it to release the lock.

Test: Trigger final level of rescue on a local device, and now can
successfully shutdown and boot into recovery mode.
Bug: 155780451

Change-Id: I3a901a469e172252deac9f6e4f1f2ab7a455fa58
parent cf256243
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -253,10 +253,7 @@ public class RescueParty {
            logCriticalInfo(Log.DEBUG,
                    "Finished rescue level " + levelToString(level));
        } catch (Throwable t) {
            final String msg = ExceptionUtils.getCompleteMessage(t);
            EventLogTags.writeRescueFailure(level, msg);
            logCriticalInfo(Log.ERROR,
                    "Failed rescue level " + levelToString(level) + ": " + msg);
            logRescueException(level, t);
        }
    }

@@ -274,11 +271,31 @@ public class RescueParty {
                resetAllSettings(context, Settings.RESET_MODE_TRUSTED_DEFAULTS, failedPackage);
                break;
            case LEVEL_FACTORY_RESET:
                // Request the reboot from a separate thread to avoid deadlock on PackageWatchdog
                // when device shutting down.
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        try {
                            RecoverySystem.rebootPromptAndWipeUserData(context, TAG);
                        } catch (Throwable t) {
                            logRescueException(level, t);
                        }
                    }
                };
                Thread thread = new Thread(runnable);
                thread.start();
                break;
        }
    }

    private static void logRescueException(int level, Throwable t) {
        final String msg = ExceptionUtils.getCompleteMessage(t);
        EventLogTags.writeRescueFailure(level, msg);
        logCriticalInfo(Log.ERROR,
                "Failed rescue level " + levelToString(level) + ": " + msg);
    }

    private static int mapRescueLevelToUserImpact(int rescueLevel) {
        switch(rescueLevel) {
            case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS: