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

Commit 249283ff authored by Jing Ji's avatar Jing Ji
Browse files

Add a developer option to disable app child process restrictions

Bug: 205156966
Test: atest PhantomProcessPreferenceControllerTest
Change-Id: I87fd78b3dc7dea069823de6bef0bd7fe20d985ad
parent 0514e9a9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -11267,6 +11267,11 @@
    <!-- Developer Settings: Dialog ListPreference option to disable network bandwidth ingress rate limit [CHAR LIMIT=none] -->
    <string name="ingress_rate_limit_no_limit_entry">No limit</string>
    <!-- Developer settings: Title for disabling phantom process monitoring. [CHAR LIMIT=50]-->
    <string name="disable_phantom_process_monitor_title">Disable child process restrictions</string>
    <!-- Developer settings: Summary for disabling phantom process monitoring. [CHAR LIMIT=NONE]-->
    <string name="disable_phantom_process_monitor_summary">Disable restrictions on the system resource usage of the app child processes</string>
    <!-- BT LE Audio Device: Media Broadcast -->
    <!-- The title of the Media Broadcast Dialog [CHAR LIMIT=none] -->
    <string name="bluetooth_broadcast_dialog_title">Broadcast</string>
+6 −0
Original line number Diff line number Diff line
@@ -672,6 +672,12 @@
        <Preference
            android:key="reset_shortcut_manager_throttling"
            android:title="@string/reset_shortcut_manager_throttling" />

        <SwitchPreference
            android:key="disable_phantom_process_monitor"
            android:title="@string/disable_phantom_process_monitor_title"
            android:summary="@string/disable_phantom_process_monitor_summary" />

    </PreferenceCategory>

    <PreferenceCategory
+1 −0
Original line number Diff line number Diff line
@@ -656,6 +656,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
        controllers.add(new StylusHandwritingPreferenceController(context));
        controllers.add(new IngressRateLimitPreferenceController((context)));
        controllers.add(new BackAnimationPreferenceController(context, fragment));
        controllers.add(new PhantomProcessPreferenceController(context));

        return controllers;
    }
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.development;

import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;

import android.content.Context;
import android.util.FeatureFlagUtils;
import android.util.Log;

import androidx.preference.Preference;
import androidx.preference.SwitchPreference;

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

/**
 * PreferenceController for MockModem
 */
public class PhantomProcessPreferenceController extends
        DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
        PreferenceControllerMixin {

    private static final String TAG = "PhantomProcessPreferenceController";
    private static final String DISABLE_PHANTOM_PROCESS_MONITOR_KEY =
            "disable_phantom_process_monitor";

    public PhantomProcessPreferenceController(Context context) {
        super(context);
    }

    @Override
    public String getPreferenceKey() {
        return DISABLE_PHANTOM_PROCESS_MONITOR_KEY;
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        final boolean isEnabled = (Boolean) newValue; // true means we're disabling this flag.
        try {
            FeatureFlagUtils.setEnabled(mContext,
                    SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS,
                    !isEnabled);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to set feature flag: " + e.getMessage());
        }
        return true;
    }

    @Override
    public void updateState(Preference preference) {
        try {
            final boolean isEnabled = !FeatureFlagUtils.isEnabled(mContext,
                    SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);
            ((SwitchPreference) mPreference).setChecked(isEnabled);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to get feature flag: " + e.getMessage());
        }
    }

    @Override
    protected void onDeveloperOptionsSwitchDisabled() {
        super.onDeveloperOptionsSwitchDisabled();
        try {
            FeatureFlagUtils.setEnabled(mContext,
                    SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS,
                    true /* Enable the monitoring */);
            ((SwitchPreference) mPreference).setChecked(false);
        } catch (RuntimeException e) {
            Log.e(TAG, "Fail to set feature flag: " + e.getMessage());
        }
    }
}
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.development;

import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;

import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
import android.os.Looper;
import android.util.FeatureFlagUtils;

import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
public class PhantomProcessPreferenceControllerTest {

    private Context mContext;
    private PhantomProcessPreferenceController mController;
    private SwitchPreference mPreference;

    @Before
    public void setUp() {
        mContext = ApplicationProvider.getApplicationContext();
        mController = new PhantomProcessPreferenceController(mContext);
        if (Looper.myLooper() == null) {
            Looper.prepare();
        }

        final PreferenceManager preferenceManager = new PreferenceManager(mContext);
        final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
        mPreference = new SwitchPreference(mContext);
        mPreference.setKey(mController.getPreferenceKey());
        screen.addPreference(mPreference);
        mController.displayPreference(screen);
    }

    @Test
    public void onPreferenceChanged_settingDisabled_shouldNotDisablePhantomProcessMonitor() {
        mController.onPreferenceChange(mPreference, false /* new value */);

        final boolean mode = !FeatureFlagUtils.isEnabled(mContext,
                SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);

        assertThat(mode).isFalse();
    }

    @Test
    public void onPreferenceChanged_settingEnabled_shouldDisablePhantomProcessMonitor() {
        mController.onPreferenceChange(mPreference, true /* new value */);

        final boolean mode = !FeatureFlagUtils.isEnabled(mContext,
                SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);

        assertThat(mode).isTrue();
    }

    @Test
    public void updateState_settingEnabled_preferenceShouldBeChecked() {
        FeatureFlagUtils.setEnabled(mContext, SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, false);

        mController.updateState(mPreference);
        assertThat(mPreference.isChecked()).isTrue();
    }

    @Test
    public void updateState_settingDisabled_preferenceShouldNotBeChecked() {
        FeatureFlagUtils.setEnabled(mContext, SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, true);

        mController.updateState(mPreference);
        assertThat(mPreference.isChecked()).isFalse();
    }

    @Test
    public void onDeveloperOptionsDisabled_shouldDisablePreference() {
        mController.onDeveloperOptionsSwitchDisabled();
        final boolean mode = !FeatureFlagUtils.isEnabled(mContext,
                SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS);

        mController.updateState(mPreference);

        assertThat(mode).isFalse();
        assertThat(mPreference.isChecked()).isFalse();
    }
}