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

Commit de0880a5 authored by William Hester's avatar William Hester
Browse files

Ensure that THM sets up even when system dies

Sometimes, something crashes unrelated to Test Harness Mode on the first
boot. When this happens, if Test Harness Mode is partially set up, it
leaves the device in a state without ADB access. This change keeps the
persistent data around until after the device is set up entirely, so
that if the system crashes, it will still apply everything correctly.

Test: make, then run cmd testharness enable 100x to check for robustness
Change-Id: I4daa112f85e3234ab18a3aa1dae883cff61497df
Bug: 129769105
parent 8cbcfdae
Loading
Loading
Loading
Loading
+26 −30
Original line number Original line Diff line number Diff line
@@ -71,7 +71,6 @@ public class TestHarnessModeService extends SystemService {
    private static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness";
    private static final String TEST_HARNESS_MODE_PROPERTY = "persist.sys.test_harness";


    private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
    private PersistentDataBlockManagerInternal mPersistentDataBlockManagerInternal;
    private boolean mShouldSetUpTestHarnessMode;


    public TestHarnessModeService(Context context) {
    public TestHarnessModeService(Context context) {
        super(context);
        super(context);
@@ -89,9 +88,8 @@ public class TestHarnessModeService extends SystemService {
                setUpTestHarnessMode();
                setUpTestHarnessMode();
                break;
                break;
            case PHASE_BOOT_COMPLETED:
            case PHASE_BOOT_COMPLETED:
                disableAutoSync();
                completeTestHarnessModeSetup();
                configureSettings();
                showNotificationIfEnabled();
                showNotification();
                break;
                break;
        }
        }
        super.onBootPhase(phase);
        super.onBootPhase(phase);
@@ -104,47 +102,45 @@ public class TestHarnessModeService extends SystemService {
            // There's no data to apply, so leave it as-is.
            // There's no data to apply, so leave it as-is.
            return;
            return;
        }
        }
        PersistentData persistentData;
        // If there is data, we should set the device as provisioned, so that we skip the setup
        // wizard.
        setDeviceProvisioned();
        SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, "1");
    }

    private void completeTestHarnessModeSetup() {
        Slog.d(TAG, "Completing Test Harness Mode setup.");
        byte[] testHarnessModeData = getPersistentDataBlock().getTestHarnessModeData();
        if (testHarnessModeData == null || testHarnessModeData.length == 0) {
            // There's no data to apply, so leave it as-is.
            return;
        }
        try {
        try {
            persistentData = PersistentData.fromBytes(testHarnessModeData);
            setUpAdbFiles(PersistentData.fromBytes(testHarnessModeData));
            disableAutoSync();
            configureSettings();
        } catch (SetUpTestHarnessModeException e) {
        } catch (SetUpTestHarnessModeException e) {
            Slog.e(TAG, "Failed to set up Test Harness Mode. Bad data.", e);
            Slog.e(TAG, "Failed to set up Test Harness Mode. Bad data.", e);
            return;
        } finally {
        } finally {
            // Clear out the Test Harness Mode data. It's now in memory if successful or we should
            // Clear out the Test Harness Mode data so that we don't repeat the setup. If it failed
            // skip setting up.
            // to set up, then retrying without enabling Test Harness Mode should allow it to boot.
            // If we succeeded setting up, we shouldn't be re-applying the THM steps every boot
            // anyway.
            getPersistentDataBlock().clearTestHarnessModeData();
            getPersistentDataBlock().clearTestHarnessModeData();
        }
        }
        mShouldSetUpTestHarnessMode = true;
        setUpAdb(persistentData);
        setDeviceProvisioned();
    }

    private void setUpAdb(PersistentData persistentData) {
        ContentResolver cr = getContext().getContentResolver();

        // Disable the TTL for ADB keys before enabling ADB
        Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0);

        SystemProperties.set(TEST_HARNESS_MODE_PROPERTY, "1");
        writeAdbKeysFile(persistentData);
    }
    }


    private void disableAutoSync() {
    private void disableAutoSync() {
        if (!mShouldSetUpTestHarnessMode) {
            return;
        }
        UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser();
        UserInfo primaryUser = UserManager.get(getContext()).getPrimaryUser();
        ContentResolver
        ContentResolver
            .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier());
            .setMasterSyncAutomaticallyAsUser(false, primaryUser.getUserHandle().getIdentifier());
    }
    }


    private void configureSettings() {
    private void configureSettings() {
        if (!mShouldSetUpTestHarnessMode) {
            return;
        }
        ContentResolver cr = getContext().getContentResolver();
        ContentResolver cr = getContext().getContentResolver();


        // Disable the TTL for ADB keys before enabling ADB
        Settings.Global.putLong(cr, Settings.Global.ADB_ALLOWED_CONNECTION_TIME, 0);
        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
        Settings.Global.putInt(cr, Settings.Global.ADB_ENABLED, 1);
        Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
        Settings.Global.putInt(cr, Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
        Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
        Settings.Global.putInt(cr, Settings.Global.PACKAGE_VERIFIER_ENABLE, 0);
@@ -155,7 +151,7 @@ public class TestHarnessModeService extends SystemService {
        Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1);
        Settings.Global.putInt(cr, Settings.Global.OTA_DISABLE_AUTOMATIC_UPDATE, 1);
    }
    }


    private void writeAdbKeysFile(PersistentData persistentData) {
    private void setUpAdbFiles(PersistentData persistentData) {
        AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class);
        AdbManagerInternal adbManager = LocalServices.getService(AdbManagerInternal.class);


        writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath());
        writeBytesToFile(persistentData.mAdbKeys, adbManager.getAdbKeysFile().toPath());
@@ -189,7 +185,7 @@ public class TestHarnessModeService extends SystemService {
                UserHandle.USER_CURRENT);
                UserHandle.USER_CURRENT);
    }
    }


    private void showNotification() {
    private void showNotificationIfEnabled() {
        if (!SystemProperties.getBoolean(TEST_HARNESS_MODE_PROPERTY, false)) {
        if (!SystemProperties.getBoolean(TEST_HARNESS_MODE_PROPERTY, false)) {
            return;
            return;
        }
        }