From 1c310ef44b405fa92fb50bcdd1be9162e4fd97a1 Mon Sep 17 00:00:00 2001 From: Jason Chang Date: Wed, 2 Jun 2021 20:01:51 +0800 Subject: [PATCH 1/5] Remove redundant swipe down notification and one handed sub settings 1. Remove "Swipe down for notification" item code. 2. Remove "Exit when switching apps & "Timeout" items code. Bug: 175851783 Test: build & verify Settings > System > Gestures Test: make RunSettingsRoboTests ROBOTEST_FILTER= "com.android.settings.gestures .OneHandedEnablePreferenceControllerTest" Change-Id: I77be5ff5542f6310fa0b9649ddfc1d3c16fa4261 --- res/xml/gestures.xml | 7 - .../swipe_bottom_to_notification_settings.xml | 38 ----- ...HandedAppTapsExitPreferenceController.java | 94 ------------ .../OneHandedEnablePreferenceController.java | 3 +- .../gestures/OneHandedSettingsUtils.java | 9 -- .../OneHandedTimeoutPreferenceController.java | 138 ------------------ ...tomToNotificationPreferenceController.java | 71 --------- .../SwipeBottomToNotificationSettings.java | 59 -------- ...HandedTimeoutPreferenceControllerTest.java | 111 -------------- ...oNotificationPreferenceControllerTest.java | 134 ----------------- ...SwipeBottomToNotificationSettingsTest.java | 102 ------------- ...edAppTapsExitPreferenceControllerTest.java | 94 ------------ 12 files changed, 1 insertion(+), 859 deletions(-) delete mode 100644 res/xml/swipe_bottom_to_notification_settings.xml delete mode 100644 src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceController.java delete mode 100644 src/com/android/settings/gestures/OneHandedTimeoutPreferenceController.java delete mode 100644 src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java delete mode 100644 src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java delete mode 100644 tests/robotests/src/com/android/settings/gestures/OneHandedTimeoutPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java delete mode 100644 tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index 1f4895eff76..6de9c1ac4a3 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -33,13 +33,6 @@ settings:searchable="false" settings:controller="com.android.settings.gestures.SwipeToNotificationPreferenceController" /> - - - - - - - - - - - diff --git a/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceController.java b/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceController.java deleted file mode 100644 index 1cc7911c027..00000000000 --- a/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceController.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import android.content.Context; -import android.net.Uri; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.core.TogglePreferenceController; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnStart; -import com.android.settingslib.core.lifecycle.events.OnStop; - -/** - * The Controller to handle app taps to exit of one-handed mode - */ -public class OneHandedAppTapsExitPreferenceController extends TogglePreferenceController implements - LifecycleObserver, OnStart, OnStop, OneHandedSettingsUtils.TogglesCallback { - - private final OneHandedSettingsUtils mUtils; - - private Preference mPreference; - - public OneHandedAppTapsExitPreferenceController(Context context, String key) { - super(context, key); - - mUtils = new OneHandedSettingsUtils(context); - - // By default, app taps to stop one-handed is enabled, this will get default value once. - OneHandedSettingsUtils.setTapsAppToExitEnabled(mContext, isChecked()); - } - - @Override - public int getAvailabilityStatus() { - return OneHandedSettingsUtils.isOneHandedModeEnabled(mContext) - ? AVAILABLE : DISABLED_DEPENDENT_SETTING; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(getPreferenceKey()); - } - - @Override - public void updateState(Preference preference) { - super.updateState(preference); - - final int availabilityStatus = getAvailabilityStatus(); - preference.setEnabled( - availabilityStatus == AVAILABLE || availabilityStatus == AVAILABLE_UNSEARCHABLE); - } - - @Override - public boolean setChecked(boolean isChecked) { - return OneHandedSettingsUtils.setTapsAppToExitEnabled(mContext, isChecked); - } - - @Override - public boolean isChecked() { - return OneHandedSettingsUtils.isTapsAppToExitEnabled(mContext); - } - - @Override - public void onStart() { - mUtils.registerToggleAwareObserver(this); - } - - @Override - public void onStop() { - mUtils.unregisterToggleAwareObserver(); - } - - @Override - public void onChange(Uri uri) { - updateState(mPreference); - } -} diff --git a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java index 1e9c240115b..d7bf7b041da 100644 --- a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java +++ b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java @@ -32,8 +32,7 @@ public class OneHandedEnablePreferenceController extends SettingsMainSwitchPrefe @Override public int getAvailabilityStatus() { - return OneHandedSettingsUtils.isFeatureAvailable(mContext) - ? AVAILABLE : UNSUPPORTED_ON_DEVICE; + return AVAILABLE; } @Override diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java index 21998a6e215..fc784e0f75a 100644 --- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java +++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java @@ -189,15 +189,6 @@ public class OneHandedSettingsUtils { Settings.Secure.NAVIGATION_MODE, 2 /* fully gestural */, sCurrentUserId); } - /** - * - * @param context App context - * @return Support One-Handed mode feature or not. - */ - public static boolean isFeatureAvailable(Context context) { - return isSupportOneHandedMode() && getNavigationBarMode(context) != 0; - } - /** * Registers callback for observing Settings.Secure.ONE_HANDED_MODE_ENABLED state. * @param callback for state changes diff --git a/src/com/android/settings/gestures/OneHandedTimeoutPreferenceController.java b/src/com/android/settings/gestures/OneHandedTimeoutPreferenceController.java deleted file mode 100644 index 8ce0e86ffd4..00000000000 --- a/src/com/android/settings/gestures/OneHandedTimeoutPreferenceController.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import android.content.Context; -import android.net.Uri; - -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnStart; -import com.android.settingslib.core.lifecycle.events.OnStop; - -import java.util.HashMap; -import java.util.Map; - -/** - * The Controller to handle one-handed mode timeout state. - **/ -public class OneHandedTimeoutPreferenceController extends BasePreferenceController implements - Preference.OnPreferenceChangeListener, LifecycleObserver, OnStart, OnStop, - OneHandedSettingsUtils.TogglesCallback { - - private final Map mTimeoutMap; - private final OneHandedSettingsUtils mUtils; - - private Preference mTimeoutPreference; - - public OneHandedTimeoutPreferenceController(Context context, String preferenceKey) { - super(context, preferenceKey); - - mTimeoutMap = new HashMap<>(); - initTimeoutMap(); - mUtils = new OneHandedSettingsUtils(context); - } - - @Override - public int getAvailabilityStatus() { - return OneHandedSettingsUtils.isOneHandedModeEnabled(mContext) - ? AVAILABLE : DISABLED_DEPENDENT_SETTING; - } - - @Override - public boolean onPreferenceChange(Preference preference, Object object) { - if (!(preference instanceof ListPreference)) { - return false; - } - final int newValue = Integer.parseInt((String) object); - OneHandedSettingsUtils.setTimeoutValue(mContext, newValue); - updateState(preference); - return true; - } - - @Override - public void updateState(Preference preference) { - super.updateState(preference); - if (!(preference instanceof ListPreference)) { - return; - } - final ListPreference listPreference = (ListPreference) preference; - listPreference.setValue(getTimeoutValue()); - - final int availabilityStatus = getAvailabilityStatus(); - preference.setEnabled( - availabilityStatus == AVAILABLE || availabilityStatus == AVAILABLE_UNSEARCHABLE); - } - - @Override - public CharSequence getSummary() { - if (OneHandedSettingsUtils.getTimeoutValue(mContext) == 0) { - return mContext.getResources().getString(R.string.screensaver_settings_summary_never); - } - return String.format(mContext.getResources().getString( - R.string.screen_timeout_summary), mTimeoutMap.get(getTimeoutValue())); - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mTimeoutPreference = screen.findPreference(mPreferenceKey); - } - - @Override - public void onStart() { - mUtils.registerToggleAwareObserver(this); - } - - @Override - public void onStop() { - mUtils.unregisterToggleAwareObserver(); - } - - @Override - public void onChange(Uri uri) { - updateState(mTimeoutPreference); - } - - private String getTimeoutValue() { - return String.valueOf(OneHandedSettingsUtils.getTimeoutValue(mContext)); - } - - private void initTimeoutMap() { - if (mTimeoutMap.size() != 0) { - return; - } - - final String[] timeoutValues = mContext.getResources().getStringArray( - R.array.one_handed_timeout_values); - final String[] timeoutTitles = mContext.getResources().getStringArray( - R.array.one_handed_timeout_title); - - if (timeoutValues.length != timeoutTitles.length) { - return; - } - - for (int i = 0; i < timeoutValues.length; i++) { - mTimeoutMap.put(timeoutValues[i], timeoutTitles[i]); - } - } -} diff --git a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java b/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java deleted file mode 100644 index ec81482dd68..00000000000 --- a/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceController.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - - -import android.content.Context; - -import com.android.settings.R; -import com.android.settings.core.TogglePreferenceController; - -/** - * Handles swipe bottom to expand notification panel gesture. - **/ -public class SwipeBottomToNotificationPreferenceController extends TogglePreferenceController { - - public SwipeBottomToNotificationPreferenceController(Context context, String key) { - super(context, key); - } - - @Override - public int getAvailabilityStatus() { - return OneHandedSettingsUtils.isFeatureAvailable(mContext) - ? AVAILABLE : UNSUPPORTED_ON_DEVICE; - } - - @Override - public boolean isSliceable() { - return true; - } - - @Override - public boolean isPublicSlice() { - return true; - } - - @Override - public boolean setChecked(boolean isChecked) { - if (isChecked) { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - } - OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, isChecked); - return true; - } - - @Override - public boolean isChecked() { - return OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext); - } - - @Override - public CharSequence getSummary() { - // This toggle preference summary will be updated in gesture preference page since we bound - // it with entry preference in gesture.xml - return mContext.getText( - isChecked() ? R.string.gesture_setting_on : R.string.gesture_setting_off); - } -} diff --git a/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java b/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java deleted file mode 100644 index 9d85f1123ac..00000000000 --- a/src/com/android/settings/gestures/SwipeBottomToNotificationSettings.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import android.app.settings.SettingsEnums; -import android.content.Context; - -import com.android.settings.R; -import com.android.settings.dashboard.DashboardFragment; -import com.android.settings.search.BaseSearchIndexProvider; - -/** - * The Fragment for swipe bottom to notification gesture settings. - */ -public class SwipeBottomToNotificationSettings extends DashboardFragment { - - private static final String TAG = "SwipeBottomToNotificationSettings"; - - @Override - public int getMetricsCategory() { - return SettingsEnums.SETTINGS_SWIPE_BOTTOM_TO_NOTIFICATION; - } - - @Override - protected String getLogTag() { - return TAG; - } - - @Override - protected int getPreferenceScreenResId() { - return R.xml.swipe_bottom_to_notification_settings; - } - - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.swipe_bottom_to_notification_settings) { - - @Override - protected boolean isPageSearchEnabled(Context context) { - if (!OneHandedSettingsUtils.isSupportOneHandedMode()) { - return false; - } - return !OneHandedSettingsUtils.isOneHandedModeEnabled(context); - } - }; -} diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedTimeoutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedTimeoutPreferenceControllerTest.java deleted file mode 100644 index d278945fd86..00000000000 --- a/tests/robotests/src/com/android/settings/gestures/OneHandedTimeoutPreferenceControllerTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.os.UserHandle; - -import androidx.preference.ListPreference; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class OneHandedTimeoutPreferenceControllerTest { - - private static final String KEY = "gesture_one_handed_timeout"; - - private Context mContext; - private OneHandedTimeoutPreferenceController mController; - private ListPreference mPreference; - - @Before - public void setUp() { - mContext = RuntimeEnvironment.application; - mController = new OneHandedTimeoutPreferenceController(mContext, KEY); - mPreference = new ListPreference(mContext); - mPreference.setKey(KEY); - OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); - } - - @Test - public void getAvailabilityStatus_enabledOneHanded_shouldAvailable() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.AVAILABLE); - } - - @Test - public void getAvailabilityStatus_disableOneHanded_shouldUnavailable() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); - } - - @Test - public void updateState_enableOneHanded_switchShouldEnabled() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isTrue(); - } - - @Test - public void updateState_disableOneHanded_switchShouldDisabled() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - - mController.updateState(mPreference); - - assertThat(mPreference.isEnabled()).isFalse(); - } - - @Test - public void getSummary_setTimeoutNever_shouldReturnNeverSummary() { - final String[] timeoutTitles = mContext.getResources().getStringArray( - R.array.one_handed_timeout_title); - - OneHandedSettingsUtils.setTimeoutValue(mContext, - OneHandedSettingsUtils.OneHandedTimeout.NEVER.getValue()); - - assertThat(mController.getSummary()).isEqualTo( - timeoutTitles[OneHandedSettingsUtils.OneHandedTimeout.NEVER.ordinal()]); - } - - @Test - public void getSummary_setTimeoutShort_shouldReturnShortSummary() { - final String[] timeoutTitles = mContext.getResources().getStringArray( - R.array.one_handed_timeout_title); - - OneHandedSettingsUtils.setTimeoutValue(mContext, - OneHandedSettingsUtils.OneHandedTimeout.SHORT.getValue()); - - assertThat(mController.getSummary()).isEqualTo(String.format( - mContext.getResources().getString(R.string.screen_timeout_summary), - timeoutTitles[OneHandedSettingsUtils.OneHandedTimeout.SHORT.ordinal()])); - } -} diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java deleted file mode 100644 index 8f50006674c..00000000000 --- a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationPreferenceControllerTest.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import static com.android.settings.core.BasePreferenceController.AVAILABLE; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.os.SystemProperties; -import android.os.UserHandle; -import android.provider.Settings; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; - -@RunWith(RobolectricTestRunner.class) -public class SwipeBottomToNotificationPreferenceControllerTest { - - private static final String KEY = "gesture_swipe_bottom_to_notification"; - - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Context mContext; - - private SwipeBottomToNotificationPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mController = new SwipeBottomToNotificationPreferenceController(mContext, KEY); - } - - @Test - public void setChecked_toggledOn_enablesSwipeBottomToNotification() { - mController.setChecked(true); - - assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isTrue(); - assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isFalse(); - } - - @Test - public void setChecked_toggledOff_disablesSwipeBottomToNotification() { - mController.setChecked(false); - - assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isFalse(); - } - - @Test - public void getAvailabilityStatus_oneHandedUnsupported_returnsUnsupport() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); - setNavigationBarMode(mContext, "2" /* fully gestural */); - - assertThat(mController.getAvailabilityStatus()).isEqualTo( - BasePreferenceController.UNSUPPORTED_ON_DEVICE); - } - - @Test - public void getAvailabilityStatus_oneHandedSupported_returnsAvailable() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - setNavigationBarMode(mContext, "2" /* fully gestural */); - - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); - } - - @Test - public void getAvailabilityStatus_set3ButtonModeProperty_returnsUnsupport() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - setNavigationBarMode(mContext, "0" /* 3-button */); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); - } - - @Test - public void getSummary_gestureEnabled_returnsOnSummary() { - mController.setChecked(true); - - assertThat(mController.getSummary()).isEqualTo( - mContext.getText(R.string.gesture_setting_on)); - } - - @Test - public void getSummary_gestureDisabled_returnsOffSummary() { - mController.setChecked(false); - - assertThat(mController.getSummary()).isEqualTo( - mContext.getText(R.string.gesture_setting_off)); - } - - @Test - public void isChecked_getDefaultConfig_returnFalse() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); - Settings.Secure.resetToDefaults(mContext.getContentResolver(), - Settings.Secure.ONE_HANDED_MODE_ENABLED); - - assertThat(mController.isChecked()).isFalse(); - } - - /** - * Set NavigationBar mode flag to Settings provider. - * @param context App context - * @param value Navigation bar mode: - * 0 = 3 button - * 1 = 2 button - * 2 = fully gestural - * @return true if the value was set, false on database errors. - */ - private boolean setNavigationBarMode(Context context, String value) { - return Settings.Secure.putStringForUser(context.getContentResolver(), - Settings.Secure.NAVIGATION_MODE, value, UserHandle.myUserId()); - } -} diff --git a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java deleted file mode 100644 index a3c8a1ebd0b..00000000000 --- a/tests/robotests/src/com/android/settings/gestures/SwipeBottomToNotificationSettingsTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.os.SystemProperties; -import android.provider.SearchIndexableResource; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Answers; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.util.ReflectionHelpers; - -import java.util.List; - -@RunWith(RobolectricTestRunner.class) -public class SwipeBottomToNotificationSettingsTest { - @Mock(answer = Answers.RETURNS_DEEP_STUBS) - private Context mContext; - - private SwipeBottomToNotificationSettings mSettings = new SwipeBottomToNotificationSettings(); - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void getPreferenceScreenResId_shouldReturnsXml() { - assertThat(mSettings.getPreferenceScreenResId()) - .isEqualTo(R.xml.swipe_bottom_to_notification_settings); - } - - @Test - public void searchIndexProvider_shouldIndexResource() { - final List indexRes = - SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( - mContext, true /* enabled */); - - assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId()); - } - - @Test - public void isPageSearchEnabled_oneHandedUnsupported_shouldReturnFalse() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); - - final Object obj = ReflectionHelpers.callInstanceMethod( - SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled", - ReflectionHelpers.ClassParameter.from(Context.class, mContext)); - - final boolean isEnabled = (Boolean) obj; - assertThat(isEnabled).isFalse(); - } - - @Test - public void isPageSearchEnabled_oneHandedDisabled_shouldReturnTrue() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - - final Object obj = ReflectionHelpers.callInstanceMethod( - SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled", - ReflectionHelpers.ClassParameter.from(Context.class, mContext)); - - final boolean isEnabled = (Boolean) obj; - assertThat(isEnabled).isTrue(); - } - - @Test - public void isPageSearchEnabled_oneHandedEnabled_shouldReturnFalse() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); - - final Object obj = ReflectionHelpers.callInstanceMethod( - SwipeBottomToNotificationSettings.SEARCH_INDEX_DATA_PROVIDER, "isPageSearchEnabled", - ReflectionHelpers.ClassParameter.from(Context.class, mContext)); - - final boolean isEnabled = (Boolean) obj; - assertThat(isEnabled).isFalse(); - } -} diff --git a/tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java b/tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java deleted file mode 100644 index 980ca6e84ee..00000000000 --- a/tests/unit/src/com/android/settings/gestures/OneHandedAppTapsExitPreferenceControllerTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2020 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.gestures; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.os.UserHandle; - -import androidx.preference.SwitchPreference; -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.android.settings.core.TogglePreferenceController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -public class OneHandedAppTapsExitPreferenceControllerTest { - - private static final String KEY = "gesture_app_taps_to_exit"; - - private Context mContext; - private SwitchPreference mSwitchPreference; - private OneHandedAppTapsExitPreferenceController mController; - - @Before - public void setUp() { - mContext = ApplicationProvider.getApplicationContext(); - mController = new OneHandedAppTapsExitPreferenceController(mContext, KEY); - mSwitchPreference = new SwitchPreference(mContext); - mSwitchPreference.setKey(KEY); - OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); - } - - @Test - public void setChecked_setBoolean_checkIsTrueOrFalse() { - mController.setChecked(false); - assertThat(mController.isChecked()).isFalse(); - - mController.setChecked(true); - assertThat(mController.isChecked()).isTrue(); - } - - @Test - public void getAvailabilityStatus_enabledOneHanded_shouldAvailable() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(TogglePreferenceController.AVAILABLE); - } - - @Test - public void getAvailabilityStatus_disabledOneHanded_shouldUnavailable() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(TogglePreferenceController.DISABLED_DEPENDENT_SETTING); - } - - @Test - public void updateState_enableOneHanded_switchShouldEnabled() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); - - mController.updateState(mSwitchPreference); - - assertThat(mSwitchPreference.isEnabled()).isTrue(); - } - - @Test - public void updateState_disableOneHanded_switchShouldDisabled() { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); - - mController.updateState(mSwitchPreference); - - assertThat(mSwitchPreference.isEnabled()).isFalse(); - } -} From 76d6d66353afd6623463c740f1fe748882a8ad36 Mon Sep 17 00:00:00 2001 From: Jason Chang Date: Thu, 3 Jun 2021 03:10:26 +0800 Subject: [PATCH 2/5] Update key visual changes for one handed mode settings Follow new visual UI to change the design. Bug: 175851783 Bug: 188868459 Bug: 189001678 Test: manual verified on Settings > System > Gesture page > System controls page Test: make RunSettingsRoboTests ROBOTEST_FILTER= "com.android.settings.gestures .OneHandedEnablePreferenceControllerTest" Test: make RunSettingsRoboTests ROBOTEST_FILTER= "com.android.settings.gestures .OneHandedMainSwitchPreferenceControllerTest" Test: make RunSettingsRoboTests ROBOTEST_FILTER= "com.android.settings.gestures .OneHandedActionPullDownPrefControllerTest" Test: make RunSettingsRoboTests ROBOTEST_FILTER= "com.android.settings.gestures .OneHandedActionShowNotificationPrefControllerTest" Change-Id: I86535fd9f49726c7234353032b950640346a02c5 --- res/values/strings.xml | 15 ++- res/xml/one_handed_settings.xml | 43 ++++--- ...OneHandedActionPullDownPrefController.java | 101 ++++++++++++++++ ...dActionShowNotificationPrefController.java | 101 ++++++++++++++++ .../OneHandedEnablePreferenceController.java | 26 ++--- ...eHandedMainSwitchPreferenceController.java | 56 +++++++++ .../gestures/OneHandedSettingsUtils.java | 41 ++++++- ...andedActionPullDownPrefControllerTest.java | 108 ++++++++++++++++++ ...ionShowNotificationPrefControllerTest.java | 107 +++++++++++++++++ ...eHandedEnablePreferenceControllerTest.java | 37 ------ ...dedMainSwitchPreferenceControllerTest.java | 85 ++++++++++++++ 11 files changed, 642 insertions(+), 78 deletions(-) create mode 100644 src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java create mode 100644 src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java create mode 100644 src/com/android/settings/gestures/OneHandedMainSwitchPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/gestures/OneHandedActionPullDownPrefControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceControllerTest.java diff --git a/res/values/strings.xml b/res/values/strings.xml index 90708da8871..a21d9ef355b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11676,7 +11676,7 @@ Swipe down on the bottom edge of the screen to show your notifications.\nYou can\'t use one-handed mode when this feature is turned on. - One-Handed mode + One-handed mode Use one-handed mode @@ -11691,6 +11691,19 @@ 12 seconds reachability + + Swipe down to + + To use one handed mode, swipe down from the bottom edge of the screen. To use this feature, make sure gesture navigation is turned on in system navigation settings. + + Pull screen into reach + + The top of the screen will move into reach of your thumb. + + Show notifications + + Notification and settings will appear. + To check time, notifications, and other info, double-tap your screen. diff --git a/res/xml/one_handed_settings.xml b/res/xml/one_handed_settings.xml index b2c7de9788d..f46b7eae186 100644 --- a/res/xml/one_handed_settings.xml +++ b/res/xml/one_handed_settings.xml @@ -21,12 +21,6 @@ android:persistent="false" android:title="@string/one_handed_title"> - - - + - + + + + + + + + + diff --git a/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java b/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java new file mode 100644 index 00000000000..84ea8b6c457 --- /dev/null +++ b/src/com/android/settings/gestures/OneHandedActionPullDownPrefController.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2021 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.gestures; + +import android.content.Context; +import android.net.Uri; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.widget.RadioButtonPreference; + +/** + * The controller to handle one-handed mode pull screen into reach preference. + **/ +public class OneHandedActionPullDownPrefController extends BasePreferenceController + implements OneHandedSettingsUtils.TogglesCallback, LifecycleObserver, OnStart, OnStop { + + private final OneHandedSettingsUtils mUtils; + + private Preference mPreference; + + public OneHandedActionPullDownPrefController(Context context, String key) { + super(context, key); + mUtils = new OneHandedSettingsUtils(context); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (preference instanceof RadioButtonPreference) { + ((RadioButtonPreference) preference).setChecked( + !OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)); + } + } + + @Override + public int getAvailabilityStatus() { + return (OneHandedSettingsUtils.isSupportOneHandedMode() + && OneHandedSettingsUtils.canEnableController(mContext)) + ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (!getPreferenceKey().equals(preference.getKey())) { + return false; + } + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, false); + if (preference instanceof RadioButtonPreference) { + ((RadioButtonPreference) preference).setChecked(true); + } + return true; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void onStart() { + mUtils.registerToggleAwareObserver(this); + } + + @Override + public void onStop() { + mUtils.unregisterToggleAwareObserver(); + } + + @Override + public void onChange(Uri uri) { + if (mPreference == null) { + return; + } + if (uri.equals(OneHandedSettingsUtils.ONE_HANDED_MODE_ENABLED_URI)) { + mPreference.setEnabled(OneHandedSettingsUtils.canEnableController(mContext)); + } else if (uri.equals(OneHandedSettingsUtils.SHOW_NOTIFICATION_ENABLED_URI)) { + updateState(mPreference); + } + } +} diff --git a/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java b/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java new file mode 100644 index 00000000000..564429986e1 --- /dev/null +++ b/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefController.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2021 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.gestures; + +import android.content.Context; +import android.net.Uri; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.widget.RadioButtonPreference; + +/** + * The controller to handle one-handed mode show notification preference. + **/ +public class OneHandedActionShowNotificationPrefController extends BasePreferenceController + implements OneHandedSettingsUtils.TogglesCallback, LifecycleObserver, OnStart, OnStop { + + private final OneHandedSettingsUtils mUtils; + + private Preference mPreference; + + public OneHandedActionShowNotificationPrefController(Context context, String key) { + super(context, key); + mUtils = new OneHandedSettingsUtils(context); + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + if (preference instanceof RadioButtonPreference) { + ((RadioButtonPreference) preference).setChecked( + OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)); + } + } + + @Override + public int getAvailabilityStatus() { + return (OneHandedSettingsUtils.isSupportOneHandedMode() + && OneHandedSettingsUtils.canEnableController(mContext)) + ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (!getPreferenceKey().equals(preference.getKey())) { + return false; + } + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, true); + if (preference instanceof RadioButtonPreference) { + ((RadioButtonPreference) preference).setChecked(true); + } + return true; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = screen.findPreference(getPreferenceKey()); + } + + @Override + public void onStart() { + mUtils.registerToggleAwareObserver(this); + } + + @Override + public void onStop() { + mUtils.unregisterToggleAwareObserver(); + } + + @Override + public void onChange(Uri uri) { + if (mPreference == null) { + return; + } + if (uri.equals(OneHandedSettingsUtils.ONE_HANDED_MODE_ENABLED_URI)) { + mPreference.setEnabled(OneHandedSettingsUtils.canEnableController(mContext)); + } else if (uri.equals(OneHandedSettingsUtils.SHOW_NOTIFICATION_ENABLED_URI)) { + updateState(mPreference); + } + } +} diff --git a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java index d7bf7b041da..e388585e5f4 100644 --- a/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java +++ b/src/com/android/settings/gestures/OneHandedEnablePreferenceController.java @@ -19,37 +19,25 @@ package com.android.settings.gestures; import android.content.Context; import com.android.settings.R; -import com.android.settings.widget.SettingsMainSwitchPreferenceController; +import com.android.settings.core.BasePreferenceController; /** * The controller to handle one-handed mode enable or disable state. **/ -public class OneHandedEnablePreferenceController extends SettingsMainSwitchPreferenceController { +public class OneHandedEnablePreferenceController extends BasePreferenceController { - public OneHandedEnablePreferenceController(Context context, String key) { - super(context, key); + public OneHandedEnablePreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); } - @Override public int getAvailabilityStatus() { - return AVAILABLE; - } - - @Override - public boolean setChecked(boolean isChecked) { - OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, isChecked); - OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, !isChecked); - return true; - } - - @Override - public boolean isChecked() { - return OneHandedSettingsUtils.isOneHandedModeEnabled(mContext); + return OneHandedSettingsUtils.isSupportOneHandedMode() ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } @Override public CharSequence getSummary() { return mContext.getText( - isChecked() ? R.string.gesture_setting_on : R.string.gesture_setting_off); + OneHandedSettingsUtils.isOneHandedModeEnabled(mContext) + ? R.string.gesture_setting_on : R.string.gesture_setting_off); } } diff --git a/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceController.java b/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceController.java new file mode 100644 index 00000000000..043588e8a39 --- /dev/null +++ b/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceController.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021 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.gestures; + +import android.content.Context; + +import com.android.settings.widget.SettingsMainSwitchPreferenceController; + +/** + * The controller to handle one-handed mode main switch enable or disable state. + **/ +public class OneHandedMainSwitchPreferenceController extends + SettingsMainSwitchPreferenceController { + + public OneHandedMainSwitchPreferenceController(Context context, String preferenceKey) { + super(context, preferenceKey); + } + + @Override + public int getAvailabilityStatus() { + return (OneHandedSettingsUtils.isSupportOneHandedMode() + && OneHandedSettingsUtils.getNavigationBarMode(mContext) != 0 /* 3-button mode */) + ? AVAILABLE : DISABLED_DEPENDENT_SETTING; + } + + @Override + public boolean isChecked() { + return OneHandedSettingsUtils.isOneHandedModeEnabled(mContext); + } + + @Override + public boolean setChecked(boolean isChecked) { + if (isChecked) { + // Set default value for TapsAppToExit and Timeout + OneHandedSettingsUtils.setTapsAppToExitEnabled(mContext, true); + OneHandedSettingsUtils.setTimeoutValue(mContext, + OneHandedSettingsUtils.OneHandedTimeout.MEDIUM.getValue()); + } + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, isChecked); + return true; + } +} diff --git a/src/com/android/settings/gestures/OneHandedSettingsUtils.java b/src/com/android/settings/gestures/OneHandedSettingsUtils.java index fc784e0f75a..a9311296b43 100644 --- a/src/com/android/settings/gestures/OneHandedSettingsUtils.java +++ b/src/com/android/settings/gestures/OneHandedSettingsUtils.java @@ -26,6 +26,8 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; +import androidx.annotation.VisibleForTesting; + /** * The Util to query one-handed mode settings config */ @@ -34,6 +36,10 @@ public class OneHandedSettingsUtils { static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode"; static final int OFF = 0; static final int ON = 1; + static final Uri ONE_HANDED_MODE_ENABLED_URI = + Settings.Secure.getUriFor(Settings.Secure.ONE_HANDED_MODE_ENABLED); + static final Uri SHOW_NOTIFICATION_ENABLED_URI = + Settings.Secure.getUriFor(Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED); public enum OneHandedTimeout { NEVER(0), SHORT(4), MEDIUM(8), LONG(12); @@ -176,6 +182,21 @@ public class OneHandedSettingsUtils { sCurrentUserId); } + /** + * Set NavigationBar mode flag to Settings provider. + * @param context App context + * @param value Navigation bar mode: + * 0 = 3 button + * 1 = 2 button + * 2 = fully gestural + * @return true if the value was set, false on database errors. + */ + @VisibleForTesting + public boolean setNavigationBarMode(Context context, String value) { + return Settings.Secure.putStringForUser(context.getContentResolver(), + Settings.Secure.NAVIGATION_MODE, value, UserHandle.myUserId()); + } + /** * Get NavigationBar mode flag from Settings provider. * @param context App context @@ -189,6 +210,20 @@ public class OneHandedSettingsUtils { Settings.Secure.NAVIGATION_MODE, 2 /* fully gestural */, sCurrentUserId); } + /** + * Check if One-handed mode settings controllers can enabled or disabled. + * @param context App context + * @return true if controllers are able to enabled, false otherwise. + * + * Note: For better UX experience, just disabled controls that let users know to use + * this feature, they need to make sure gesture navigation is turned on in system + * navigation settings. + */ + public static boolean canEnableController(Context context) { + return (OneHandedSettingsUtils.isOneHandedModeEnabled(context) + && OneHandedSettingsUtils.getNavigationBarMode(context) != 0 /* 3-button mode */); + } + /** * Registers callback for observing Settings.Secure.ONE_HANDED_MODE_ENABLED state. * @param callback for state changes @@ -209,9 +244,6 @@ public class OneHandedSettingsUtils { private final class SettingsObserver extends ContentObserver { private TogglesCallback mCallback; - private final Uri mOneHandedEnabledAware = Settings.Secure.getUriFor( - Settings.Secure.ONE_HANDED_MODE_ENABLED); - SettingsObserver(Handler handler) { super(handler); } @@ -222,7 +254,8 @@ public class OneHandedSettingsUtils { public void observe() { final ContentResolver resolver = mContext.getContentResolver(); - resolver.registerContentObserver(mOneHandedEnabledAware, true, this); + resolver.registerContentObserver(ONE_HANDED_MODE_ENABLED_URI, true, this); + resolver.registerContentObserver(SHOW_NOTIFICATION_ENABLED_URI, true, this); } @Override diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedActionPullDownPrefControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedActionPullDownPrefControllerTest.java new file mode 100644 index 00000000000..60398de9937 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedActionPullDownPrefControllerTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2021 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.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.SystemProperties; +import android.os.UserHandle; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.widget.RadioButtonPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class OneHandedActionPullDownPrefControllerTest { + + private static final String KEY = "gesture_one_handed_action_pull_screen_down"; + + private Context mContext; + private OneHandedSettingsUtils mUtils; + private OneHandedActionPullDownPrefController mController; + private RadioButtonPreference mPreference; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mUtils = new OneHandedSettingsUtils(mContext); + mController = new OneHandedActionPullDownPrefController(mContext, KEY); + mPreference = new RadioButtonPreference(mContext); + OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); + } + + @Test + public void updateState_showNotificationEnabled_shouldUnchecked() { + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, true); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void updateState_showNotificationDisabled_shouldChecked() { + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, false); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void getAvailabilityStatus_setOneHandedModeDisabled_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_setNavi3ButtonMode_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "0" /* 3 button */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_setNaviGesturalMode_shouldEnabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefControllerTest.java new file mode 100644 index 00000000000..b56a4f78f16 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedActionShowNotificationPrefControllerTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2021 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.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.SystemProperties; +import android.os.UserHandle; + +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.widget.RadioButtonPreference; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class OneHandedActionShowNotificationPrefControllerTest { + + private static final String KEY = "gesture_one_handed_action_show_notification"; + + private Context mContext; + private OneHandedSettingsUtils mUtils; + private OneHandedActionShowNotificationPrefController mController; + private RadioButtonPreference mPreference; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mUtils = new OneHandedSettingsUtils(mContext); + mController = new OneHandedActionShowNotificationPrefController(mContext, KEY); + mPreference = new RadioButtonPreference(mContext); + OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); + } + + @Test + public void updateState_setGesturalMode_shouldEnabled() { + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + mController.updateState(mPreference); + assertThat(mPreference.isEnabled()).isTrue(); + } + + @Test + public void updateState_ShowNotificationEnabled_shouldChecked() { + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, true); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isTrue(); + } + + @Test + public void updateState_showNotificationDisabled_shouldUnchecked() { + OneHandedSettingsUtils.setSwipeDownNotificationEnabled(mContext, false); + + mController.updateState(mPreference); + assertThat(mPreference.isChecked()).isFalse(); + } + + @Test + public void getAvailabilityStatus_setOneHandedModeDisabled_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, false); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_setNavi3ButtonMode_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "0" /* 3 button */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); + OneHandedSettingsUtils.setOneHandedModeEnabled(mContext, true); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java index e5b86880faa..d0f64854ebc 100644 --- a/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedEnablePreferenceControllerTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.SystemProperties; import android.os.UserHandle; -import android.provider.Settings; import com.android.settings.R; import com.android.settings.core.BasePreferenceController; @@ -47,21 +46,9 @@ public class OneHandedEnablePreferenceControllerTest { OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); } - @Test - public void setChecked_setBoolean_checkIsTrueOrFalse() { - mController.setChecked(false); - assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isFalse(); - assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isTrue(); - - mController.setChecked(true); - assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isTrue(); - assertThat(OneHandedSettingsUtils.isSwipeDownNotificationEnabled(mContext)).isFalse(); - } - @Test public void getAvailabilityStatus_setSupportOneHandedModeProperty_shouldAvailable() { SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - setNavigationBarMode(mContext, "2" /* fully gestural */); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.AVAILABLE); @@ -70,16 +57,6 @@ public class OneHandedEnablePreferenceControllerTest { @Test public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldUnsupported() { SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); - setNavigationBarMode(mContext, "2" /* fully gestural */); - - assertThat(mController.getAvailabilityStatus()) - .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); - } - - @Test - public void getAvailabilityStatus_set3ButtonModeProperty_shouldUnsupported() { - SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); - setNavigationBarMode(mContext, "0" /* 3-button */); assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); @@ -100,18 +77,4 @@ public class OneHandedEnablePreferenceControllerTest { assertThat(mController.getSummary()) .isEqualTo(mContext.getText(R.string.switch_off_text)); } - - /** - * Set NavigationBar mode flag to Settings provider. - * @param context App context - * @param value Navigation bar mode: - * 0 = 3 button - * 1 = 2 button - * 2 = fully gestural - * @return true if the value was set, false on database errors. - */ - private boolean setNavigationBarMode(Context context, String value) { - return Settings.Secure.putStringForUser(context.getContentResolver(), - Settings.Secure.NAVIGATION_MODE, value, UserHandle.myUserId()); - } } diff --git a/tests/robotests/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceControllerTest.java new file mode 100644 index 00000000000..40cf795acd4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/OneHandedMainSwitchPreferenceControllerTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2021 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.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.os.SystemProperties; +import android.os.UserHandle; + +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class OneHandedMainSwitchPreferenceControllerTest { + + private static final String KEY = "gesture_one_handed_mode_enabled_main_switch"; + + private Context mContext; + private OneHandedSettingsUtils mUtils; + private OneHandedMainSwitchPreferenceController mController; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mUtils = new OneHandedSettingsUtils(mContext); + mController = new OneHandedMainSwitchPreferenceController(mContext, KEY); + OneHandedSettingsUtils.setUserId(UserHandle.myUserId()); + } + + @Test + public void setChecked_setBoolean_checkIsTrueOrFalse() { + mController.setChecked(false); + assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isFalse(); + + mController.setChecked(true); + assertThat(OneHandedSettingsUtils.isOneHandedModeEnabled(mContext)).isTrue(); + } + + @Test + public void getAvailabilityStatus_setSupportOneHandedModeProperty_shouldAvailable() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_unsetSupportOneHandedModeProperty_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "false"); + mUtils.setNavigationBarMode(mContext, "2" /* fully gestural */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } + + @Test + public void getAvailabilityStatus_set3ButtonMode_shouldDisabled() { + SystemProperties.set(OneHandedSettingsUtils.SUPPORT_ONE_HANDED_MODE, "true"); + mUtils.setNavigationBarMode(mContext, "0" /* 3-button mode */); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.DISABLED_DEPENDENT_SETTING); + } +} From 652c425acb24bd5fc68e82985edde9d6ae4dfa76 Mon Sep 17 00:00:00 2001 From: Peter_Liang Date: Fri, 11 Jun 2021 10:21:12 +0800 Subject: [PATCH 3/5] Fixing the crash when tapping the "Downloaded apps" in Accessibility page. Root cause: When Accessibility settings parse the application which is from google play store, the settings have no check if the resource is valid before delivery the parameter into the corresponding fragment. Solution: Check if the resource is valid before creating the image uri. Bug: 190716289 Test: manual test Change-Id: I56eba2232ddf6ed5b2e526d4698479465a012e52 --- .../LaunchAccessibilityActivityPreferenceFragment.java | 10 ++++++---- .../ToggleAccessibilityServicePreferenceFragment.java | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java index fe08d6b5bde..98090ac1dba 100644 --- a/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java +++ b/src/com/android/settings/accessibility/LaunchAccessibilityActivityPreferenceFragment.java @@ -78,10 +78,12 @@ public class LaunchAccessibilityActivityPreferenceFragment extends ToggleFeature // Settings animated image. final int animatedImageRes = arguments.getInt( AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES); - mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) - .authority(mComponentName.getPackageName()) - .appendPath(String.valueOf(animatedImageRes)) - .build(); + if (animatedImageRes > 0) { + mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(mComponentName.getPackageName()) + .appendPath(String.valueOf(animatedImageRes)) + .build(); + } // Settings html description. mHtmlDescription = arguments.getCharSequence(AccessibilitySettings.EXTRA_HTML_DESCRIPTION); diff --git a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java index 9d948583fd4..934907181a7 100644 --- a/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java +++ b/src/com/android/settings/accessibility/ToggleAccessibilityServicePreferenceFragment.java @@ -396,10 +396,12 @@ public class ToggleAccessibilityServicePreferenceFragment extends // Settings animated image. final int animatedImageRes = arguments.getInt( AccessibilitySettings.EXTRA_ANIMATED_IMAGE_RES); - mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) - .authority(mComponentName.getPackageName()) - .appendPath(String.valueOf(animatedImageRes)) - .build(); + if (animatedImageRes > 0) { + mImageUri = new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE) + .authority(mComponentName.getPackageName()) + .appendPath(String.valueOf(animatedImageRes)) + .build(); + } // Get Accessibility service name. mPackageName = getAccessibilityServiceInfo().getResolveInfo().loadLabel( From 7d7be0bd7d77a80366d644b8a270b4437683e410 Mon Sep 17 00:00:00 2001 From: Yanting Yang Date: Fri, 11 Jun 2021 14:31:47 +0800 Subject: [PATCH 4/5] Update wallpaper summary of homepage for AOSP Fixes: 190585430 Test: robotests & visual Change-Id: Idd51d7988dc6664b7a8936bcbb9c7174c20580eb --- res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 90708da8871..fe90b863458 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3166,8 +3166,8 @@ Wallpaper Wallpaper & style - - Colors, themed icons, app grid + + Home, lock screen Default From 04a40602256d909f551f9166078cb5850a92db1e Mon Sep 17 00:00:00 2001 From: Weng Su Date: Tue, 8 Jun 2021 04:43:24 +0800 Subject: [PATCH 5/5] [Provider Model] Add WiFi toggle in internet panel - Move Wi-Fi toggle from menu button to slice row - Remove Wi-Fi disconnect action - Show scanning sub-title once only Bug: 189912933 Test: manual test atest -c InternetConnectivityPanelTest \ ProviderModelSliceTest Change-Id: I2baf05362f5cd0a8ce94c7b3b2b112a7e9fe6894 --- .../settings/network/ProviderModelSlice.java | 142 +++++++++--------- .../telephony/NetworkProviderWorker.java | 2 +- .../panel/InternetConnectivityPanel.java | 80 ++++++---- .../network/ProviderModelSliceTest.java | 75 +++++---- .../panel/InternetConnectivityPanelTest.java | 99 +++++------- 5 files changed, 191 insertions(+), 207 deletions(-) diff --git a/src/com/android/settings/network/ProviderModelSlice.java b/src/com/android/settings/network/ProviderModelSlice.java index cfaef53ac60..1df77bc28f5 100644 --- a/src/com/android/settings/network/ProviderModelSlice.java +++ b/src/com/android/settings/network/ProviderModelSlice.java @@ -20,6 +20,7 @@ package com.android.settings.network; import static android.app.slice.Slice.EXTRA_TOGGLE_STATE; import static com.android.settings.slices.CustomSliceRegistry.PROVIDER_MODEL_SLICE_URI; +import static com.android.settings.slices.CustomSliceRegistry.WIFI_SLICE_URI; import android.annotation.ColorInt; import android.app.PendingIntent; @@ -64,7 +65,6 @@ import java.util.stream.Collectors; public class ProviderModelSlice extends WifiSlice { private static final String TAG = "ProviderModelSlice"; - protected static final String ACTION_TITLE_CONNECT_TO_CARRIER = "Connect_To_Carrier"; private final ProviderModelSliceHelper mHelper; @@ -89,78 +89,77 @@ public class ProviderModelSlice extends WifiSlice { @Override public Slice getSlice() { // The provider model slice step: - // First section: Add a Wi-Fi item which state is connected. - // Second section: Add a carrier item. - // Third section: Add the Wi-Fi items which are not connected. - // Fourth section: If device has connection problem, this row show the message for user. - @InternetUpdater.InternetType int internetType = getInternetType(); + // First section: Add the Ethernet item. + // Second section: Add the carrier item. + // Third section: Add the Wi-Fi toggle item. + // Fourth section: Add the connected Wi-Fi item. + // Fifth section: Add the Wi-Fi items which are not connected. + // Sixth section: Add the See All item. final ListBuilder listBuilder = mHelper.createListBuilder(getUri()); - if (mHelper.isAirplaneModeEnabled() && !mWifiManager.isWifiEnabled() - && internetType != InternetUpdater.INTERNET_ETHERNET) { - log("Airplane mode is enabled."); - return listBuilder.build(); - } - int maxListSize = 0; - List wifiList = null; final NetworkProviderWorker worker = getWorker(); if (worker != null) { - // get Wi-Fi list. - wifiList = worker.getResults(); maxListSize = worker.getApRowCount(); } else { log("network provider worker is null."); } - final boolean hasCarrier = mHelper.hasCarrier(); - log("hasCarrier: " + hasCarrier); - - // First section: Add a Ethernet or Wi-Fi item which state is connected. - boolean isConnectedWifiAddedTop = false; - final WifiSliceItem connectedWifiItem = mHelper.getConnectedWifiItem(wifiList); - if (internetType == InternetUpdater.INTERNET_ETHERNET) { + // First section: Add the Ethernet item. + if (getInternetType() == InternetUpdater.INTERNET_ETHERNET) { log("get Ethernet item which is connected"); listBuilder.addRow(createEthernetRow()); maxListSize--; - } else { - if (connectedWifiItem != null && internetType == InternetUpdater.INTERNET_WIFI) { - log("get Wi-Fi item which is connected to internet"); - listBuilder.addRow(getWifiSliceItemRow(connectedWifiItem)); - isConnectedWifiAddedTop = true; + } + + // Second section: Add the carrier item. + if (!mHelper.isAirplaneModeEnabled()) { + final boolean hasCarrier = mHelper.hasCarrier(); + log("hasCarrier: " + hasCarrier); + if (hasCarrier) { + mHelper.updateTelephony(); + listBuilder.addRow( + mHelper.createCarrierRow( + worker != null ? worker.getNetworkTypeDescription() : "")); maxListSize--; } } - // Second section: Add a carrier item. - if (hasCarrier) { - mHelper.updateTelephony(); - listBuilder.addRow( - mHelper.createCarrierRow( - worker != null ? worker.getNetworkTypeDescription() : "")); - maxListSize--; + // Third section: Add the Wi-Fi toggle item. + final boolean isWifiEnabled = mWifiManager.isWifiEnabled(); + listBuilder.addRow(createWifiToggleRow(mContext, isWifiEnabled)); + maxListSize--; + if (!isWifiEnabled) { + log("Wi-Fi is disabled"); + return listBuilder.build(); + } + List wifiList = (worker != null) ? worker.getResults() : null; + if (wifiList == null || wifiList.size() <= 0) { + log("Wi-Fi list is empty"); + return listBuilder.build(); } - // Third section: Add the connected Wi-Fi item to Wi-Fi list if the Ethernet is connected. - if (connectedWifiItem != null && !isConnectedWifiAddedTop) { + // Fourth section: Add the connected Wi-Fi item. + final WifiSliceItem connectedWifiItem = mHelper.getConnectedWifiItem(wifiList); + if (connectedWifiItem != null) { log("get Wi-Fi item which is connected"); listBuilder.addRow(getWifiSliceItemRow(connectedWifiItem)); maxListSize--; } - // Fourth section: Add the Wi-Fi items which are not connected. - if (wifiList != null && wifiList.size() > 0) { - log("get Wi-Fi items which are not connected. Wi-Fi items : " + wifiList.size()); - - final List disconnectedWifiList = wifiList.stream() - .filter(wifiSliceItem -> wifiSliceItem.getConnectedState() - != WifiEntry.CONNECTED_STATE_CONNECTED) - .limit(maxListSize - 1) - .collect(Collectors.toList()); - for (WifiSliceItem item : disconnectedWifiList) { - listBuilder.addRow(getWifiSliceItemRow(item)); - } - listBuilder.addRow(getSeeAllRow()); + // Fifth section: Add the Wi-Fi items which are not connected. + log("get Wi-Fi items which are not connected. Wi-Fi items : " + wifiList.size()); + final List disconnectedWifiList = wifiList.stream() + .filter(item -> item.getConnectedState() != WifiEntry.CONNECTED_STATE_CONNECTED) + .limit(maxListSize - 1) + .collect(Collectors.toList()); + for (WifiSliceItem item : disconnectedWifiList) { + listBuilder.addRow(getWifiSliceItemRow(item)); } + + // Sixth section: Add the See All item. + log("add See-All"); + listBuilder.addRow(getSeeAllRow()); + return listBuilder.build(); } @@ -269,6 +268,26 @@ public class ProviderModelSlice extends WifiSlice { .setSubtitle(mContext.getText(R.string.to_switch_networks_disconnect_ethernet)); } + /** + * @return a {@link ListBuilder.RowBuilder} of the Wi-Fi toggle. + */ + protected ListBuilder.RowBuilder createWifiToggleRow(Context context, boolean isWifiEnabled) { + final Intent intent = new Intent(WIFI_SLICE_URI.toString()) + .setData(WIFI_SLICE_URI) + .setClass(context, SliceBroadcastReceiver.class) + .putExtra(EXTRA_TOGGLE_STATE, !isWifiEnabled) + // The FLAG_RECEIVER_FOREGROUND flag is necessary to avoid the intent delay of + // the first sending after the device restarts + .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); + final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); + final SliceAction toggleSliceAction = SliceAction.createToggle(pendingIntent, + null /* actionTitle */, isWifiEnabled); + return new ListBuilder.RowBuilder() + .setTitle(context.getString(R.string.wifi_settings)) + .setPrimaryAction(toggleSliceAction); + } + protected ListBuilder.RowBuilder getSeeAllRow() { final CharSequence title = mContext.getText(R.string.previous_connected_see_all); final IconCompat icon = getSeeAllIcon(); @@ -294,31 +313,6 @@ public class ProviderModelSlice extends WifiSlice { return SliceAction.createDeeplink(intent, icon, ListBuilder.ICON_IMAGE, title); } - @Override - protected ListBuilder.RowBuilder getWifiSliceItemRow(WifiSliceItem wifiSliceItem) { - final CharSequence title = wifiSliceItem.getTitle(); - final IconCompat levelIcon = getWifiSliceItemLevelIcon(wifiSliceItem); - final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() - .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE) - .setTitle(title) - .setSubtitle(wifiSliceItem.getSummary()) - .setContentDescription(wifiSliceItem.getContentDescription()); - - final IconCompat endIcon; - if (wifiSliceItem.hasInternetAccess()) { - rowBuilder.setPrimaryAction(SliceAction.create(getBroadcastIntent(mContext), - levelIcon, ListBuilder.ICON_IMAGE, ACTION_TITLE_CONNECT_TO_CARRIER)); - endIcon = IconCompat.createWithResource(mContext, R.drawable.ic_settings_close); - } else { - rowBuilder.setPrimaryAction(getWifiEntryAction(wifiSliceItem, levelIcon, title)); - endIcon = getEndIcon(wifiSliceItem); - } - if (endIcon != null) { - rowBuilder.addEndItem(endIcon, ListBuilder.ICON_IMAGE); - } - return rowBuilder; - } - @Override protected IconCompat getWifiSliceItemLevelIcon(WifiSliceItem wifiSliceItem) { if (wifiSliceItem.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED diff --git a/src/com/android/settings/network/telephony/NetworkProviderWorker.java b/src/com/android/settings/network/telephony/NetworkProviderWorker.java index 369218b86ad..d4f05510318 100644 --- a/src/com/android/settings/network/telephony/NetworkProviderWorker.java +++ b/src/com/android/settings/network/telephony/NetworkProviderWorker.java @@ -54,7 +54,7 @@ public class NetworkProviderWorker extends WifiScanWorker implements DataConnectivityListener.Client, InternetUpdater.InternetChangeListener, SubscriptionsChangeListener.SubscriptionsChangeListenerClient { private static final String TAG = "NetworkProviderWorker"; - private static final int PROVIDER_MODEL_DEFAULT_EXPANDED_ROW_COUNT = 5; + private static final int PROVIDER_MODEL_DEFAULT_EXPANDED_ROW_COUNT = 6; private DataContentObserver mMobileDataObserver; private SignalStrengthListener mSignalStrengthListener; private SubscriptionsChangeListener mSubscriptionsListener; diff --git a/src/com/android/settings/panel/InternetConnectivityPanel.java b/src/com/android/settings/panel/InternetConnectivityPanel.java index e6344d806c2..c735780b1f0 100644 --- a/src/com/android/settings/panel/InternetConnectivityPanel.java +++ b/src/com/android/settings/panel/InternetConnectivityPanel.java @@ -38,7 +38,6 @@ import android.text.TextUtils; import android.util.Log; import androidx.annotation.VisibleForTesting; -import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.OnLifecycleEvent; @@ -84,12 +83,13 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve } if (TextUtils.equals(intent.getAction(), WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { - showProgressBar(); + updateProgressBar(); updatePanelTitle(); return; } if (TextUtils.equals(intent.getAction(), WifiManager.NETWORK_STATE_CHANGED_ACTION)) { + updateProgressBar(); updatePanelTitle(); } } @@ -110,13 +110,40 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve private int mDefaultDataSubid = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Wi-Fi scanning progress bar + protected HandlerInjector mHandlerInjector; protected boolean mIsProgressBarVisible; - protected final Runnable mHideProgressBarRunnable = () -> { + protected boolean mIsScanningSubTitleShownOnce; + protected Runnable mHideProgressBarRunnable = () -> { setProgressBarVisible(false); }; + protected Runnable mHideScanningSubTitleRunnable = () -> { + mIsScanningSubTitleShownOnce = true; + updatePanelTitle(); + }; + + /** + * Wrapper for testing compatibility. + */ + @VisibleForTesting + static class HandlerInjector { + protected final Handler mHandler; + + HandlerInjector(Context context) { + mHandler = context.getMainThreadHandler(); + } + + public void postDelay(Runnable runnable) { + mHandler.postDelayed(runnable, 2000 /* delay millis */); + } + + public void removeCallbacks(Runnable runnable) { + mHandler.removeCallbacks(runnable); + } + } private InternetConnectivityPanel(Context context) { mContext = context.getApplicationContext(); + mHandlerInjector = new HandlerInjector(context); mIsProviderModelEnabled = Utils.isProviderModelEnabled(mContext); mInternetUpdater = new InternetUpdater(context, null /* Lifecycle */, this); @@ -150,7 +177,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mTelephonyManager.registerTelephonyCallback( new HandlerExecutor(new Handler(Looper.getMainLooper())), mTelephonyCallback); mContext.registerReceiver(mWifiStateReceiver, mWifiStateFilter); - showProgressBar(); + updateProgressBar(); updatePanelTitle(); } @@ -165,7 +192,8 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mConnectivityListener.stop(); mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback); mContext.unregisterReceiver(mWifiStateReceiver); - mContext.getMainThreadHandler().removeCallbacks(mHideProgressBarRunnable); + mHandlerInjector.removeCallbacks(mHideProgressBarRunnable); + mHandlerInjector.removeCallbacks(mHideScanningSubTitleRunnable); } /** @@ -209,23 +237,6 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve return null; } - @Override - public boolean isCustomizedButtonUsed() { - return mIsProviderModelEnabled; - } - - @Override - public CharSequence getCustomizedButtonTitle() { - return mContext.getText( - mInternetUpdater.isWifiEnabled() ? R.string.turn_off_wifi : R.string.turn_on_wifi); - } - - @Override - public void onClickCustomizedButton(FragmentActivity panelActivity) { - // Don't finish the panel activity - mWifiManager.setWifiEnabled(!mInternetUpdater.isWifiEnabled()); - } - @Override public boolean isProgressBarVisible() { return mIsProgressBarVisible; @@ -246,6 +257,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve */ @Override public void onAirplaneModeChanged(boolean isAirplaneModeOn) { + log("onAirplaneModeChanged: isAirplaneModeOn:" + isAirplaneModeOn); updatePanelTitle(); } @@ -254,6 +266,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve */ @Override public void onWifiEnabledChanged(boolean enabled) { + log("onWifiEnabledChanged: enabled:" + enabled); updatePanelTitle(); } @@ -305,13 +318,6 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve return; } - if (mIsProgressBarVisible) { - // When the Wi-Fi scan result callback is received - // Sub-Title: Searching for networks... - mSubtitle = SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS; - return; - } - if (mInternetUpdater.isAirplaneModeOn()) { return; } @@ -319,11 +325,18 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve final List wifiList = mWifiManager.getScanResults(); if (wifiList != null && wifiList.size() != 0) { // When the Wi-Fi scan result is not empty - // Sub-Title: Select the network you want to use for data + // Sub-Title: Tap a network to connect mSubtitle = SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT; return; } + if (!mIsScanningSubTitleShownOnce && mIsProgressBarVisible) { + // When the Wi-Fi scan result callback is received + // Sub-Title: Searching for networks... + mSubtitle = SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS; + return; + } + // Sub-Title: // show non_carrier_network_unavailable // - while Wi-Fi on + no Wi-Fi item @@ -353,7 +366,7 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve mSubtitle = SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE; } - protected void showProgressBar() { + protected void updateProgressBar() { if (mWifiManager == null || !mInternetUpdater.isWifiEnabled()) { setProgressBarVisible(false); return; @@ -362,8 +375,9 @@ public class InternetConnectivityPanel implements PanelContent, LifecycleObserve setProgressBarVisible(true); List wifiScanResults = mWifiManager.getScanResults(); if (wifiScanResults != null && wifiScanResults.size() > 0) { - mContext.getMainThreadHandler().postDelayed(mHideProgressBarRunnable, - 2000 /* delay millis */); + mHandlerInjector.postDelay(mHideProgressBarRunnable); + } else if (!mIsScanningSubTitleShownOnce) { + mHandlerInjector.postDelay(mHideScanningSubTitleRunnable); } } diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java index a96e7cf21b4..85129f8b3f3 100644 --- a/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java +++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceTest.java @@ -16,8 +16,6 @@ package com.android.settings.network; -import static com.android.settings.network.ProviderModelSlice.ACTION_TITLE_CONNECT_TO_CARRIER; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -42,6 +40,8 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import androidx.slice.Slice; +import androidx.slice.SliceItem; +import androidx.slice.SliceMetadata; import androidx.slice.SliceProvider; import androidx.slice.builders.ListBuilder; import androidx.slice.builders.SliceAction; @@ -100,8 +100,6 @@ public class ProviderModelSliceTest { ListBuilder.RowBuilder mMockCarrierRowBuild; @Mock WifiPickerTracker mWifiPickerTracker; - @Mock - WifiSliceItem mWifiSliceItem; private FakeFeatureFactory mFeatureFactory; @@ -122,7 +120,7 @@ public class ProviderModelSliceTest { when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager); - + when(mWifiManager.isWifiEnabled()).thenReturn(true); // Set-up specs for SliceMetadata. SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); @@ -182,7 +180,24 @@ public class ProviderModelSliceTest { @Test @UiThreadTest - public void getSlice_haveTwoWifiAndOneCarrier_getCarrierAndTwoWiFiAndSeeAll() { + public void getSlice_airplaneModeIsOn_oneWifiToggle() { + mWifiList.clear(); + mMockNetworkProviderWorker.updateSelfResults(null); + mockHelperCondition(true, false, false, null); + + final Slice slice = mMockProviderModelSlice.getSlice(); + + assertThat(slice).isNotNull(); + verify(mListBuilder, times(1)).addRow(any(ListBuilder.RowBuilder.class)); + final SliceItem sliceTitle = + SliceMetadata.from(mContext, slice).getListContent().getHeader().getTitleItem(); + assertThat(sliceTitle.getText()).isEqualTo( + ResourcesUtils.getResourcesString(mContext, "wifi_settings")); + } + + @Test + @UiThreadTest + public void getSlice_haveTwoWifiAndOneCarrier_getFiveRow() { mWifiList.clear(); mockWifiItemCondition(mMockWifiSliceItem1, "wifi1", "wifi1", WifiEntry.CONNECTED_STATE_CONNECTED, "wifi1_key", true); @@ -197,13 +212,13 @@ public class ProviderModelSliceTest { assertThat(slice).isNotNull(); verify(mListBuilder, times(1)).addRow(mMockCarrierRowBuild); - verify(mListBuilder, times(4)).addRow(any(ListBuilder.RowBuilder.class)); + verify(mListBuilder, times(5)).addRow(any(ListBuilder.RowBuilder.class)); assertThat(mMockProviderModelSlice.hasSeeAllRow()).isTrue(); } @Test @UiThreadTest - public void getSlice_haveOneConnectedWifiAndTwoDisconnectedWifiAndNoCarrier_getFourRow() { + public void getSlice_haveOneConnectedWifiAndTwoDisconnectedWifiAndNoCarrier_getFiveRow() { mWifiList.clear(); mockWifiItemCondition(mMockWifiSliceItem1, "wifi1", "wifi1", WifiEntry.CONNECTED_STATE_CONNECTED, "wifi1_key", true); @@ -220,13 +235,13 @@ public class ProviderModelSliceTest { final Slice slice = mMockProviderModelSlice.getSlice(); assertThat(slice).isNotNull(); - verify(mListBuilder, times(4)).addRow(any(ListBuilder.RowBuilder.class)); + verify(mListBuilder, times(5)).addRow(any(ListBuilder.RowBuilder.class)); assertThat(mMockProviderModelSlice.hasSeeAllRow()).isTrue(); } @Test @UiThreadTest - public void getSlice_haveTwoDisconnectedWifiAndNoCarrier_getThreeRow() { + public void getSlice_haveTwoDisconnectedWifiAndNoCarrier_getFourRow() { mWifiList.clear(); mockWifiItemCondition(mMockWifiSliceItem1, "wifi1", "wifi1", WifiEntry.CONNECTED_STATE_DISCONNECTED, "wifi1_key", true); @@ -240,13 +255,13 @@ public class ProviderModelSliceTest { final Slice slice = mMockProviderModelSlice.getSlice(); assertThat(slice).isNotNull(); - verify(mListBuilder, times(3)).addRow(any(ListBuilder.RowBuilder.class)); + verify(mListBuilder, times(4)).addRow(any(ListBuilder.RowBuilder.class)); assertThat(mMockProviderModelSlice.hasSeeAllRow()).isTrue(); } @Test @UiThreadTest - public void getSlice_haveEthernetAndCarrierAndTwoDisconnectedWifi_getFiveRow() { + public void getSlice_haveEthernetAndCarrierAndTwoDisconnectedWifi_getSixRow() { mWifiList.clear(); mockWifiItemCondition(mMockWifiSliceItem1, "wifi1", "wifi1", WifiEntry.CONNECTED_STATE_DISCONNECTED, "wifi1_key", true); @@ -264,13 +279,13 @@ public class ProviderModelSliceTest { assertThat(slice).isNotNull(); assertThat(mMockProviderModelSlice.hasCreateEthernetRow()).isTrue(); verify(mListBuilder, times(1)).addRow(mMockCarrierRowBuild); - verify(mListBuilder, times(5)).addRow(any(ListBuilder.RowBuilder.class)); + verify(mListBuilder, times(6)).addRow(any(ListBuilder.RowBuilder.class)); assertThat(mMockProviderModelSlice.hasSeeAllRow()).isTrue(); } @Test @UiThreadTest - public void getSlice_haveEthernetAndCarrierAndConnectedWifiAndDisconnectedWifi_getFiveRow() { + public void getSlice_haveEthernetAndCarrierAndConnectedWifiAndDisconnectedWifi_getSixRow() { mWifiList.clear(); mockWifiItemCondition(mMockWifiSliceItem1, "wifi1", "wifi1", WifiEntry.CONNECTED_STATE_CONNECTED, "wifi1_key", true); @@ -288,7 +303,7 @@ public class ProviderModelSliceTest { assertThat(slice).isNotNull(); assertThat(mMockProviderModelSlice.hasCreateEthernetRow()).isTrue(); verify(mListBuilder, times(1)).addRow(mMockCarrierRowBuild); - verify(mListBuilder, times(5)).addRow(any(ListBuilder.RowBuilder.class)); + verify(mListBuilder, times(6)).addRow(any(ListBuilder.RowBuilder.class)); assertThat(mMockProviderModelSlice.hasSeeAllRow()).isTrue(); } @@ -380,6 +395,11 @@ public class ProviderModelSliceTest { return super.getSeeAllRow(); } + @Override + public ListBuilder.RowBuilder getWifiSliceItemRow(WifiSliceItem wifiSliceItem) { + return super.getWifiSliceItemRow(wifiSliceItem); + } + public boolean hasCreateEthernetRow() { return mHasCreateEthernetRow; } @@ -420,29 +440,4 @@ public class ProviderModelSliceTest { verify(mMockNetworkProviderWorker, never()).connectCarrierNetwork(); } - - @Test - public void getWifiSliceItemRow_wifiNoInternetAccess_actionConnectToWifiSsid() { - when(mWifiSliceItem.getKey()).thenReturn("wifi_key"); - when(mWifiSliceItem.getTitle()).thenReturn("wifi_ssid"); - when(mWifiSliceItem.hasInternetAccess()).thenReturn(false); - - ListBuilder.RowBuilder rowBuilder = - mMockProviderModelSlice.getWifiSliceItemRow(mWifiSliceItem); - - assertThat(rowBuilder.getPrimaryAction().getTitle()) - .isEqualTo("wifi_ssid"); - } - - @Test - public void getWifiSliceItemRow_wifiHasInternetAccess_actionConnectToCarrier() { - when(mWifiSliceItem.getTitle()).thenReturn("wifi_ssid"); - when(mWifiSliceItem.hasInternetAccess()).thenReturn(true); - - ListBuilder.RowBuilder rowBuilder = - mMockProviderModelSlice.getWifiSliceItemRow(mWifiSliceItem); - - assertThat(rowBuilder.getPrimaryAction().getTitle()) - .isEqualTo(ACTION_TITLE_CONNECT_TO_CARRIER); - } } diff --git a/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java index e475e6fe1db..9ad4a378b83 100644 --- a/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java +++ b/tests/unit/src/com/android/settings/panel/InternetConnectivityPanelTest.java @@ -18,12 +18,9 @@ package com.android.settings.panel; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -32,9 +29,7 @@ import android.content.Context; import android.net.Uri; import android.net.wifi.ScanResult; import android.net.wifi.WifiManager; -import android.os.Handler; -import androidx.fragment.app.FragmentActivity; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -82,8 +77,6 @@ public class InternetConnectivityPanelTest { @Rule public final MockitoRule mMocks = MockitoJUnit.rule(); @Mock - Handler mMainThreadHandler; - @Mock PanelContentCallback mPanelContentCallback; @Mock InternetUpdater mInternetUpdater; @@ -91,17 +84,34 @@ public class InternetConnectivityPanelTest { private WifiManager mWifiManager; @Mock private ProviderModelSliceHelper mProviderModelSliceHelper; - @Mock - private FragmentActivity mPanelActivity; private Context mContext; + private FakeHandlerInjector mFakeHandlerInjector; private InternetConnectivityPanel mPanel; + private class FakeHandlerInjector extends InternetConnectivityPanel.HandlerInjector { + + private Runnable mRunnable; + + FakeHandlerInjector(Context context) { + super(context); + } + + @Override + public void postDelay(Runnable runnable) { + mRunnable = runnable; + } + + public Runnable getRunnable() { + return mRunnable; + } + } + @Before public void setUp() { mContext = spy(ApplicationProvider.getApplicationContext()); + mFakeHandlerInjector = new FakeHandlerInjector(mContext); when(mContext.getApplicationContext()).thenReturn(mContext); - when(mContext.getMainThreadHandler()).thenReturn(mMainThreadHandler); when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager); mPanel = InternetConnectivityPanel.create(mContext); @@ -109,6 +119,7 @@ public class InternetConnectivityPanelTest { mPanel.mIsProviderModelEnabled = true; mPanel.mInternetUpdater = mInternetUpdater; mPanel.mProviderModelSliceHelper = mProviderModelSliceHelper; + mPanel.mHandlerInjector = mFakeHandlerInjector; } @Test @@ -203,20 +214,6 @@ public class InternetConnectivityPanelTest { assertThat(mPanel.getSubTitle()).isEqualTo(SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT); } - @Test - public void getCustomizedButtonTitle_wifiOff_turnOnWifi() { - doReturn(false).when(mInternetUpdater).isWifiEnabled(); - - assertThat(mPanel.getCustomizedButtonTitle()).isEqualTo(BUTTON_TURN_ON_WIFI); - } - - @Test - public void getCustomizedButtonTitle_wifiOn_turnOffWifi() { - doReturn(true).when(mInternetUpdater).isWifiEnabled(); - - assertThat(mPanel.getCustomizedButtonTitle()).isEqualTo(BUTTON_TURN_OFF_WIFI); - } - @Test public void getSlices_providerModelDisabled_containsNecessarySlices() { mPanel.mIsProviderModelEnabled = false; @@ -240,31 +237,6 @@ public class InternetConnectivityPanelTest { assertThat(mPanel.getSeeMoreIntent()).isNull(); } - @Test - public void onClickCustomizedButton_wifiOn_setWifiOff() { - doReturn(true).when(mInternetUpdater).isWifiEnabled(); - - mPanel.onClickCustomizedButton(mPanelActivity); - - verify(mWifiManager).setWifiEnabled(false); - } - - @Test - public void onClickCustomizedButton_wifiOff_setWifiOn() { - doReturn(false).when(mInternetUpdater).isWifiEnabled(); - - mPanel.onClickCustomizedButton(mPanelActivity); - - verify(mWifiManager).setWifiEnabled(true); - } - - @Test - public void onClickCustomizedButton_shouldNotFinishActivity() { - mPanel.onClickCustomizedButton(mPanelActivity); - - verify(mPanelActivity, never()).finish(); - } - @Test public void updatePanelTitle_onHeaderChanged() { clearInvocations(mPanelContentCallback); @@ -295,36 +267,41 @@ public class InternetConnectivityPanelTest { } @Test - public void showProgressBar_wifiDisabled_hideProgress() { + public void updateProgressBar_wifiDisabled_hideProgress() { mPanel.mIsProgressBarVisible = true; doReturn(false).when(mInternetUpdater).isWifiEnabled(); clearInvocations(mPanelContentCallback); - mPanel.showProgressBar(); + mPanel.updateProgressBar(); assertThat(mPanel.isProgressBarVisible()).isFalse(); verify(mPanelContentCallback).onProgressBarVisibleChanged(); } @Test - public void showProgressBar_noWifiScanResults_showProgressForever() { + public void updateProgressBar_noWifiScanResults_showProgressForever() { + mPanel.mIsScanningSubTitleShownOnce = false; mPanel.mIsProgressBarVisible = false; doReturn(true).when(mInternetUpdater).isWifiEnabled(); List noWifiScanResults = new ArrayList<>(); doReturn(noWifiScanResults).when(mWifiManager).getScanResults(); clearInvocations(mPanelContentCallback); - mPanel.showProgressBar(); + mPanel.updateProgressBar(); - assertThat(mPanel.isProgressBarVisible()).isTrue(); + assertThat(mPanel.mIsProgressBarVisible).isTrue(); verify(mPanelContentCallback).onProgressBarVisibleChanged(); verify(mPanelContentCallback).onHeaderChanged(); - verify(mMainThreadHandler, never()) - .postDelayed(any() /* mHideProgressBarRunnable */, anyLong()); + + assertThat(mFakeHandlerInjector.getRunnable()) + .isEqualTo(mPanel.mHideScanningSubTitleRunnable); + mFakeHandlerInjector.getRunnable().run(); + assertThat(mPanel.mIsScanningSubTitleShownOnce).isTrue(); + assertThat(mPanel.mIsProgressBarVisible).isTrue(); } @Test - public void showProgressBar_hasWifiScanResults_showProgressDelayedHide() { + public void updateProgressBar_hasWifiScanResults_showProgressDelayedHide() { mPanel.mIsProgressBarVisible = false; doReturn(true).when(mInternetUpdater).isWifiEnabled(); List hasWifiScanResults = mock(ArrayList.class); @@ -332,11 +309,15 @@ public class InternetConnectivityPanelTest { doReturn(hasWifiScanResults).when(mWifiManager).getScanResults(); clearInvocations(mPanelContentCallback); - mPanel.showProgressBar(); + mPanel.updateProgressBar(); assertThat(mPanel.isProgressBarVisible()).isTrue(); verify(mPanelContentCallback).onProgressBarVisibleChanged(); - verify(mMainThreadHandler).postDelayed(any() /* mHideProgressBarRunnable */, anyLong()); + + assertThat(mFakeHandlerInjector.getRunnable()) + .isEqualTo(mPanel.mHideProgressBarRunnable); + mFakeHandlerInjector.getRunnable().run(); + assertThat(mPanel.mIsProgressBarVisible).isFalse(); } @Test