diff --git a/res/values/strings.xml b/res/values/strings.xml index 0ae67e5f566..2d3532cc72b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10467,8 +10467,14 @@ %d unused apps - - Remove permissions and free up space + + Unused app settings + + + Pause app activity + + + Remove permissions, delete temporary files, and stop notifications if unused All apps @@ -13514,6 +13520,11 @@ Allow apps that can display over other apps to overlay Settings screens + + Allow Mock Modem + + Allow this device to run Mock Modem service for instrumentation testing. Do not enable this during normal usage of the phone + Media @@ -14094,7 +14105,7 @@ *This is a temporary placeholder fallback activity. - Spatial audio + Spatial Audio Audio from compatible media becomes more immersive diff --git a/res/xml/app_info_settings.xml b/res/xml/app_info_settings.xml index bb5fbae7564..95fefb63a12 100644 --- a/res/xml/app_info_settings.xml +++ b/res/xml/app_info_settings.xml @@ -148,6 +148,7 @@ diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 98674196d93..89e5167a11b 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -250,6 +250,11 @@ android:title="@string/force_high_refresh_rate_toggle" android:summary="@string/force_high_refresh_rate_desc" /> + + { + if (controller instanceof BasePreferenceController.UiBlocker) { + ((BasePreferenceController) controller).revokeFirstLaunch(); + } + }); } @Override @@ -424,7 +429,14 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment for (AbstractPreferenceController controller : controllerList) { final String key = controller.getPreferenceKey(); final Preference preference = findPreference(key); - if (preference != null) { + if (preference == null) { + continue; + } + if (controller instanceof BasePreferenceController.UiBlocker) { + final boolean prefVisible = + ((BasePreferenceController) controller).getSavedPrefVisibility(); + preference.setVisible(visible && controller.isAvailable() && prefVisible); + } else { preference.setVisible(visible && controller.isAvailable()); } } @@ -496,6 +508,7 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment @Override public void onBlockerWorkFinished(BasePreferenceController controller) { mBlockerController.countDown(controller.getPreferenceKey()); + controller.setUiBlockerFinished(mBlockerController.isBlockerFinished()); } protected Preference createPreference(Tile tile) { diff --git a/src/com/android/settings/dashboard/UiBlockerController.java b/src/com/android/settings/dashboard/UiBlockerController.java index 710175b112b..b3729f13e1e 100644 --- a/src/com/android/settings/dashboard/UiBlockerController.java +++ b/src/com/android/settings/dashboard/UiBlockerController.java @@ -37,7 +37,7 @@ import java.util.concurrent.TimeUnit; */ public class UiBlockerController { private static final String TAG = "UiBlockerController"; - private static final int TIMEOUT_MILLIS = 500; + private static final int TIMEOUT_MILLIS = 300; private CountDownLatch mCountDownLatch; private boolean mBlockerFinished; diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 085a372c0ea..722e94e409b 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -518,6 +518,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra controllers.add(new BugReportInPowerPreferenceController(context)); controllers.add(new AutomaticSystemServerHeapDumpPreferenceController(context)); controllers.add(new MockLocationAppPreferenceController(context, fragment)); + controllers.add(new MockModemPreferenceController(context)); controllers.add(new DebugViewAttributesPreferenceController(context)); controllers.add(new SelectDebugAppPreferenceController(context, fragment)); controllers.add(new WaitForDebuggerPreferenceController(context)); diff --git a/src/com/android/settings/development/MockModemPreferenceController.java b/src/com/android/settings/development/MockModemPreferenceController.java new file mode 100644 index 00000000000..655f15767c5 --- /dev/null +++ b/src/com/android/settings/development/MockModemPreferenceController.java @@ -0,0 +1,86 @@ +/* + * 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 android.content.Context; +import android.os.SystemProperties; +import android.util.Log; + +import androidx.annotation.VisibleForTesting; +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 MockModemPreferenceController extends + DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener, + PreferenceControllerMixin { + + private static final String TAG = "MockModemPreferenceController"; + private static final String ALLOW_MOCK_MODEM_KEY = + "allow_mock_modem"; + @VisibleForTesting + static final String ALLOW_MOCK_MODEM_PROPERTY = + "persist.radio.allow_mock_modem"; + + public MockModemPreferenceController(Context context) { + super(context); + } + + @Override + public String getPreferenceKey() { + return ALLOW_MOCK_MODEM_KEY; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + final boolean isEnabled = (Boolean) newValue; + try { + SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY, + isEnabled ? "true" : "false"); + } catch (RuntimeException e) { + Log.e(TAG, "Fail to set radio system property: " + e.getMessage()); + } + return true; + } + + @Override + public void updateState(Preference preference) { + try { + final boolean isEnabled = SystemProperties.getBoolean( + ALLOW_MOCK_MODEM_PROPERTY, false /* default */); + ((SwitchPreference) mPreference).setChecked(isEnabled); + } catch (RuntimeException e) { + Log.e(TAG, "Fail to get radio system property: " + e.getMessage()); + } + } + + @Override + protected void onDeveloperOptionsSwitchDisabled() { + super.onDeveloperOptionsSwitchDisabled(); + try { + SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY, "false"); + ((SwitchPreference) mPreference).setChecked(false); + } catch (RuntimeException e) { + Log.e(TAG, "Fail to set radio system property: " + e.getMessage()); + } + } +} diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java index b160d904293..30f38d299e5 100644 --- a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java +++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java @@ -58,12 +58,17 @@ public class NetworkRequestDialogActivity extends FragmentActivity implements final static String EXTRA_IS_SPECIFIED_SSID = "com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK"; - @VisibleForTesting NetworkRequestDialogBaseFragment mDialogFragment; + @VisibleForTesting + NetworkRequestDialogBaseFragment mDialogFragment; + @VisibleForTesting + boolean mIsSpecifiedSsid; + @VisibleForTesting + boolean mShowingErrorDialog; + @VisibleForTesting + ProgressDialog mProgressDialog; + private NetworkRequestUserSelectionCallback mUserSelectionCallback; - private boolean mIsSpecifiedSsid; - private boolean mShowingErrorDialog; private WifiConfiguration mMatchedConfig; - @VisibleForTesting ProgressDialog mProgressDialog; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -103,7 +108,8 @@ public class NetworkRequestDialogActivity extends FragmentActivity implements mDialogFragment.show(getSupportFragmentManager(), TAG); } - private void dismissDialogs() { + @VisibleForTesting + void dismissDialogs() { if (mDialogFragment != null) { mDialogFragment.dismiss(); mDialogFragment = null; @@ -174,7 +180,9 @@ public class NetworkRequestDialogActivity extends FragmentActivity implements return; } - mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback); + if (mDialogFragment != null) { + mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback); + } } @Override @@ -201,7 +209,9 @@ public class NetworkRequestDialogActivity extends FragmentActivity implements return; } - mDialogFragment.onMatch(scanResults); + if (mDialogFragment != null) { + mDialogFragment.onMatch(scanResults); + } } @Override diff --git a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java index f1e656851d5..169bcb3d838 100644 --- a/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java +++ b/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivity.java @@ -56,8 +56,6 @@ public class AddAppNetworksActivity extends FragmentActivity { final Bundle mBundle = new Bundle(); @VisibleForTesting IActivityManager mActivityManager = ActivityManager.getService(); - @VisibleForTesting - boolean mIsAddWifiConfigAllow; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -74,8 +72,6 @@ public class AddAppNetworksActivity extends FragmentActivity { window.setGravity(Gravity.BOTTOM); window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT); - - mIsAddWifiConfigAllow = WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this); } @Override @@ -90,7 +86,7 @@ public class AddAppNetworksActivity extends FragmentActivity { @VisibleForTesting protected boolean showAddNetworksFragment() { - if (!mIsAddWifiConfigAllow) { + if (!isAddWifiConfigAllow()) { Log.d(TAG, "Not allowed by Enterprise Restriction"); return false; } @@ -129,4 +125,9 @@ public class AddAppNetworksActivity extends FragmentActivity { } return packageName; } + + @VisibleForTesting + boolean isAddWifiConfigAllow() { + return WifiEnterpriseRestrictionUtils.isAddWifiConfigAllowed(this); + } } diff --git a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java index 2678aff7bde..a1b844b1b49 100644 --- a/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java +++ b/tests/robotests/src/com/android/settings/password/SetupChooseLockPasswordTest.java @@ -46,7 +46,6 @@ import com.google.android.setupcompat.template.FooterBarMixin; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -106,7 +105,6 @@ public class SetupChooseLockPasswordTest { @Test @Config(shadows = ShadowChooseLockGenericController.class) - @Ignore public void createActivity_withShowOptionsButtonExtra_buttonNotVisibleIfNoVisibleLockTypes() { SetupChooseLockPassword activity = createSetupChooseLockPassword(); Button optionsButton = activity.findViewById(R.id.screen_lock_options); @@ -206,7 +204,7 @@ public class SetupChooseLockPasswordTest { @Implements(ChooseLockGenericController.class) public static class ShadowChooseLockGenericController { @Implementation - protected List getVisibleScreenLockTypes() { + protected List getVisibleAndEnabledScreenLockTypes() { return Collections.emptyList(); } } diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java index fb200453d4d..616cb0bde39 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java @@ -25,7 +25,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.content.Context; import android.content.Intent; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; @@ -42,9 +41,12 @@ import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_ import com.android.wifitrackerlib.WifiPickerTracker; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; @@ -61,25 +63,26 @@ public class NetworkRequestDialogActivityTest { private static final String TEST_SSID = "testssid"; private static final String TEST_CAPABILITY = "wep"; - NetworkRequestDialogActivity mActivity; + @Rule + public MockitoRule mRule = MockitoJUnit.rule(); + @Mock WifiManager mWifiManager; - Context mContext; + @Mock + NetworkRequestUserSelectionCallback mNetworkRequestUserSelectionCallback; + + NetworkRequestDialogActivity mActivity; + List mScanResults = new ArrayList<>(); @Before public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); FakeFeatureFactory fakeFeatureFactory = FakeFeatureFactory.setupForTest(); when(fakeFeatureFactory.wifiTrackerLibProvider.createWifiPickerTracker( any(), any(), any(), any(), any(), anyLong(), anyLong(), any())) .thenReturn(mock(WifiPickerTracker.class)); + mScanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY)); - NetworkRequestDialogActivity activity = - Robolectric.setupActivity(NetworkRequestDialogActivity.class); - mActivity = spy(activity); - - mWifiManager = mock(WifiManager.class); - when(mActivity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); + mActivity = spy(Robolectric.setupActivity(NetworkRequestDialogActivity.class)); + when(mActivity.getSystemService(WifiManager.class)).thenReturn(mWifiManager); } @Test @@ -169,10 +172,7 @@ public class NetworkRequestDialogActivityTest { public void specifiedSsid_onMatch_shouldShowDialogFragment() { startSpecifiedActivity(); - final List scanResults = new ArrayList<>(); - scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY)); - - mActivity.onMatch(scanResults); + mActivity.onMatch(mScanResults); assertThat(mActivity.mProgressDialog).isNull(); assertThat(mActivity.mDialogFragment).isNotNull(); @@ -193,9 +193,7 @@ public class NetworkRequestDialogActivityTest { public void onUserSelectionConnectFailure_shouldShowDialogFragment() { WifiConfiguration wifiConfiguration = mock(WifiConfiguration.class); startSpecifiedActivity(); - final List scanResults = new ArrayList<>(); - scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY)); - mActivity.onMatch(scanResults); + mActivity.onMatch(mScanResults); mActivity.onUserSelectionConnectFailure(wifiConfiguration); @@ -205,13 +203,9 @@ public class NetworkRequestDialogActivityTest { @Test public void onClickConnectButton_shouldShowProgressDialog() { - NetworkRequestUserSelectionCallback networkRequestUserSelectionCallback = mock( - NetworkRequestUserSelectionCallback.class); startSpecifiedActivity(); - final List scanResults = new ArrayList<>(); - scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY)); - mActivity.onMatch(scanResults); - mActivity.onUserSelectionCallbackRegistration(networkRequestUserSelectionCallback); + mActivity.onMatch(mScanResults); + mActivity.onUserSelectionCallbackRegistration(mNetworkRequestUserSelectionCallback); mActivity.onClickConnectButton(); @@ -222,9 +216,7 @@ public class NetworkRequestDialogActivityTest { @Test public void onCancel_shouldCloseAllUI() { startSpecifiedActivity(); - final List scanResults = new ArrayList<>(); - scanResults.add(getScanResult(TEST_SSID, TEST_CAPABILITY)); - mActivity.onMatch(scanResults); + mActivity.onMatch(mScanResults); mActivity.onCancel(); @@ -240,4 +232,20 @@ public class NetworkRequestDialogActivityTest { verify(mActivity).finish(); } + + @Test + public void onUserSelectionCallbackRegistration_dismissDialogsAndDialogIsNull_shouldNotCrash() { + mActivity.dismissDialogs(); + + mActivity.onUserSelectionCallbackRegistration(mNetworkRequestUserSelectionCallback); + } + + @Test + public void onMatch_dismissDialogsAndDialogIsNull_shouldNotCrash() { + mActivity.mIsSpecifiedSsid = false; + mActivity.mShowingErrorDialog = false; + mActivity.dismissDialogs(); + + mActivity.onMatch(mScanResults); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java index 6cd20fc26fb..8391b8aa8dd 100644 --- a/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/addappnetworks/AddAppNetworksActivityTest.java @@ -39,15 +39,14 @@ public class AddAppNetworksActivityTest { @Mock private IActivityManager mIActivityManager; - private AddAppNetworksActivity mActivity; + private FakeAddAppNetworksActivity mActivity; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mActivity = Robolectric.buildActivity(AddAppNetworksActivity.class).create().get(); + mActivity = Robolectric.buildActivity(FakeAddAppNetworksActivity.class).create().get(); mActivity.mActivityManager = mIActivityManager; - mActivity.mIsAddWifiConfigAllow = true; } @Test @@ -92,4 +91,13 @@ public class AddAppNetworksActivityTest { // Do nothing. } } + + private static class FakeAddAppNetworksActivity extends AddAppNetworksActivity { + boolean mIsAddWifiConfigAllow = true; + + @Override + boolean isAddWifiConfigAllow() { + return mIsAddWifiConfigAllow; + } + } } diff --git a/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java b/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java new file mode 100644 index 00000000000..f811ac4ba72 --- /dev/null +++ b/tests/unit/src/com/android/settings/development/MockModemPreferenceControllerTest.java @@ -0,0 +1,111 @@ +/* + * 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 com.android.settings.development.MockModemPreferenceController + .ALLOW_MOCK_MODEM_PROPERTY; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.Looper; +import android.os.SystemProperties; + +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 MockModemPreferenceControllerTest { + + private Context mContext; + private MockModemPreferenceController mController; + private SwitchPreference mPreference; + + @Before + public void setUp() { + mContext = ApplicationProvider.getApplicationContext(); + mController = new MockModemPreferenceController(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_shouldNotAllowedMockModem() { + mController.onPreferenceChange(mPreference, false /* new value */); + + final boolean mode = SystemProperties.getBoolean( + ALLOW_MOCK_MODEM_PROPERTY, false /* default */); + + assertThat(mode).isFalse(); + } + + @Test + public void onPreferenceChanged_settingEnabled_shouldAllowMockModem() { + mController.onPreferenceChange(mPreference, true /* new value */); + + final boolean mode = SystemProperties.getBoolean( + ALLOW_MOCK_MODEM_PROPERTY, false /* default */); + + assertThat(mode).isTrue(); + } + + @Test + public void updateState_settingEnabled_preferenceShouldBeChecked() { + SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY, + Boolean.toString(true)); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_settingDisabled_preferenceShouldNotBeChecked() { + SystemProperties.set(ALLOW_MOCK_MODEM_PROPERTY, + Boolean.toString(false)); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void onDeveloperOptionsDisabled_shouldDisablePreference() { + mController.onDeveloperOptionsSwitchDisabled(); + final boolean mode = SystemProperties.getBoolean( + ALLOW_MOCK_MODEM_PROPERTY, + false /* default */); + + mController.updateState(mPreference); + + assertThat(mode).isFalse(); + assertThat(mPreference.isChecked()).isFalse(); + } +}