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

Commit 7d44d327 authored by Rambo Wang's avatar Rambo Wang
Browse files

Fix Settings app ANR due to blocking IDumpstateDevice IPC call

This CL fixes the ANR by moving possible blocking IDumpstateDevice
IPC call from main thread to background thread.

Settings develop options depends on IDumpstateDevice IPC call to
set and get Vendor Verbose Logging feature. The IPC may occasionally
get blocked in system_server which is extremely busy (e.g. during
bugreport generating). This may cause Settings app crashing with ANR.

Bug: 287126040
Bug: 280015761
Test: atest EnableVerboseVendorLoggingPreferenceControllerTest
Test: Verbose Vendor Logging regression
Test: Stress test (heavily trigger on/off during BR generating)
Merged-In: I0b88ef089097930b62dcb1cb7d6fe9990356ab5d
Change-Id: I0b88ef089097930b62dcb1cb7d6fe9990356ab5d
(cherry picked from commit f7b8d687)
parent 542ef9e5
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.preference.SwitchPreference;

import com.android.settings.core.PreferenceControllerMixin;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import com.android.settingslib.utils.ThreadUtils;

import java.util.NoSuchElementException;

@@ -66,23 +67,34 @@ public class EnableVerboseVendorLoggingPreferenceController
        return isIDumpstateDeviceAidlServiceAvailable() || isIDumpstateDeviceV1_1ServiceAvailable();
    }

    @SuppressWarnings("FutureReturnValueIgnored")
    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final boolean isEnabled = (Boolean) newValue;
        setVerboseLoggingEnabled(isEnabled);
        // IDumpstateDevice IPC may be blocking when system is extremely heavily-loaded.
        // Post to background thread to avoid ANR. Ignore the returned Future.
        ThreadUtils.postOnBackgroundThread(() ->
                setVerboseLoggingEnabled(isEnabled));
        return true;
    }

    @SuppressWarnings("FutureReturnValueIgnored")
    @Override
    public void updateState(Preference preference) {
        ThreadUtils.postOnBackgroundThread(() -> {
                    final boolean enabled = getVerboseLoggingEnabled();
        ((SwitchPreference) mPreference).setChecked(enabled);
                    ThreadUtils.getUiThreadHandler().post(() ->
                            ((SwitchPreference) mPreference).setChecked(enabled));
                }
        );
    }

    @SuppressWarnings("FutureReturnValueIgnored")
    @Override
    protected void onDeveloperOptionsSwitchDisabled() {
        super.onDeveloperOptionsSwitchDisabled();
        setVerboseLoggingEnabled(false);
        ThreadUtils.postOnBackgroundThread(() ->
                setVerboseLoggingEnabled(false));
        ((SwitchPreference) mPreference).setChecked(false);
    }