From e5a2816656cbe9ab4cc9bcc5a0fc49d6bc627c07 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 6 Sep 2017 15:43:00 -0700 Subject: [PATCH 01/25] Add OWNERS for folder inputmethod Bug: 65294119 Test: Manual Change-Id: Icdcfaaf6cc7a1e1cf77e89a79d0425cab4405ffc --- src/com/android/settings/inputmethod/OWNERS | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/com/android/settings/inputmethod/OWNERS diff --git a/src/com/android/settings/inputmethod/OWNERS b/src/com/android/settings/inputmethod/OWNERS new file mode 100644 index 00000000000..9f333949ff1 --- /dev/null +++ b/src/com/android/settings/inputmethod/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +yukawa@google.com +michaelwr@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 6530b21cc56abdd869cd7ba48357f63883c4a218 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Wed, 6 Sep 2017 16:47:08 +0100 Subject: [PATCH 02/25] Settings: Add laser sensor preference Add a switch for enabling/disabling the laser sensor within developer options. Test: Manual using setting app, RunSettingsRoboTests Bug: 64423712 Change-Id: I89a32dfa062fc62c4be096d2e026a32ce9b784ca --- res/values/config.xml | 3 + res/values/strings.xml | 3 + res/xml/development_prefs.xml | 4 + ...CameraLaserSensorPreferenceController.java | 104 +++++++++++ .../development/DevelopmentSettings.java | 10 + ...raLaserSensorPreferenceControllerTest.java | 175 ++++++++++++++++++ 6 files changed, 299 insertions(+) create mode 100644 src/com/android/settings/development/CameraLaserSensorPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java diff --git a/res/values/config.xml b/res/values/config.xml index 92c11f6c27e..f964d5ee241 100755 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -44,6 +44,9 @@ false + + false + com.android.settings.overlay.FeatureFactoryImpl diff --git a/res/values/strings.xml b/res/values/strings.xml index b53dbde40c6..c778b685ddb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8236,6 +8236,9 @@ To apply Camera HAL HDR+ change, reboot device + + Camera Laser Sensor + Automatic system updates diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml index 1846a8c43e0..147c5bcce7c 100644 --- a/res/xml/development_prefs.xml +++ b/res/xml/development_prefs.xml @@ -163,6 +163,10 @@ android:title="@string/telephony_monitor_switch" android:summary="@string/telephony_monitor_switch_summary"/> + + diff --git a/src/com/android/settings/development/CameraLaserSensorPreferenceController.java b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java new file mode 100644 index 00000000000..26bfc805227 --- /dev/null +++ b/src/com/android/settings/development/CameraLaserSensorPreferenceController.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import android.content.Context; +import android.os.SystemProperties; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceScreen; +import android.widget.Toast; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settings.R; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.AbstractPreferenceController; + +public class CameraLaserSensorPreferenceController extends AbstractPreferenceController + implements PreferenceControllerMixin { + + private static final String KEY_CAMERA_LASER_SENSOR_SWITCH = "camera_laser_sensor_switch"; + @VisibleForTesting + static final String BUILD_TYPE = "ro.build.type"; + @VisibleForTesting + static final String PROPERTY_CAMERA_LASER_SENSOR = "persist.camera.stats.disablehaf"; + @VisibleForTesting + static final int ENABLED = 0; + @VisibleForTesting + static final int DISABLED = 2; + + private SwitchPreference mPreference; + + public CameraLaserSensorPreferenceController(Context context) { + super(context); + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (SwitchPreference) screen.findPreference(KEY_CAMERA_LASER_SENSOR_SWITCH); + updatePreference(); + } + + @Override + public String getPreferenceKey() { + return KEY_CAMERA_LASER_SENSOR_SWITCH; + } + + @Override + public boolean isAvailable() { + String buildType = SystemProperties.get(BUILD_TYPE); + return mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor) && + (buildType.equals("userdebug") || buildType.equals("eng")); + } + + @Override + public void updateState(Preference preference) { + updatePreference(); + } + + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (KEY_CAMERA_LASER_SENSOR_SWITCH.equals(preference.getKey())) { + final SwitchPreference switchPreference = (SwitchPreference)preference; + String value = Integer.toString(switchPreference.isChecked() ? ENABLED : DISABLED); + SystemProperties.set(PROPERTY_CAMERA_LASER_SENSOR, value); + return true; + } + return false; + } + + public void enablePreference(boolean enabled) { + if (isAvailable()) { + mPreference.setEnabled(enabled); + } + } + + public boolean updatePreference() { + if (!isAvailable()) { + return false; + } + final boolean enabled = isLaserSensorEnabled(); + mPreference.setChecked(enabled); + return enabled; + } + + private boolean isLaserSensorEnabled() { + String prop = SystemProperties.get(PROPERTY_CAMERA_LASER_SENSOR, Integer.toString(ENABLED)); + return prop.equals(Integer.toString(ENABLED)); + } +} diff --git a/src/com/android/settings/development/DevelopmentSettings.java b/src/com/android/settings/development/DevelopmentSettings.java index c2571ee8856..fdf0d5c74f9 100644 --- a/src/com/android/settings/development/DevelopmentSettings.java +++ b/src/com/android/settings/development/DevelopmentSettings.java @@ -364,6 +364,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment private BugReportInPowerPreferenceController mBugReportInPowerController; private TelephonyMonitorPreferenceController mTelephonyMonitorController; private CameraHalHdrplusPreferenceController mCameraHalHdrplusController; + private CameraLaserSensorPreferenceController mCameraLaserSensorController; private BroadcastReceiver mEnableAdbReceiver; @@ -405,6 +406,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mWebViewAppPrefController = new WebViewAppPreferenceController(getActivity()); mVerifyAppsOverUsbController = new VerifyAppsOverUsbPreferenceController(getActivity()); mCameraHalHdrplusController = new CameraHalHdrplusPreferenceController(getActivity()); + mCameraLaserSensorController = new CameraLaserSensorPreferenceController(getActivity()); setIfOnlyAvailableForAdmins(true); if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) { @@ -440,6 +442,8 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mCameraHalHdrplusController.displayPreference(getPreferenceScreen()); mEnableAdbController.displayPreference(getPreferenceScreen()); + mCameraLaserSensorController.displayPreference(getPreferenceScreen()); + mKeepScreenOn = (RestrictedSwitchPreference) findAndInitSwitchPref(KEEP_SCREEN_ON); mBtHciSnoopLog = findAndInitSwitchPref(BT_HCI_SNOOP_LOG); mEnableOemUnlock = (RestrictedSwitchPreference) findAndInitSwitchPref(ENABLE_OEM_UNLOCK); @@ -659,6 +663,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mTelephonyMonitorController.enablePreference(enabled); mWebViewAppPrefController.enablePreference(enabled); mCameraHalHdrplusController.enablePreference(enabled); + mCameraLaserSensorController.enablePreference(enabled); updateAllOptions(); } @@ -793,6 +798,7 @@ public class DevelopmentSettings extends RestrictedSettingsFragment mHaveDebugSettings |= mBugReportInPowerController.updatePreference(); mHaveDebugSettings |= mTelephonyMonitorController.updatePreference(); mHaveDebugSettings |= mCameraHalHdrplusController.updatePreference(); + mHaveDebugSettings |= mCameraLaserSensorController.updatePreference(); updateSwitchPreference(mKeepScreenOn, Settings.Global.getInt(cr, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0) != 0); updateSwitchPreference(mBtHciSnoopLog, SystemProperties.getBoolean( @@ -2459,6 +2465,10 @@ public class DevelopmentSettings extends RestrictedSettingsFragment return true; } + if (mCameraLaserSensorController.handlePreferenceTreeClick(preference)) { + return true; + } + if (preference == mClearAdbKeys) { if (mAdbKeysDialog != null) dismissDialogs(); mAdbKeysDialog = new AlertDialog.Builder(getActivity()) diff --git a/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java new file mode 100644 index 00000000000..7aab99d7c87 --- /dev/null +++ b/tests/robotests/src/com/android/settings/development/CameraLaserSensorPreferenceControllerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import android.content.Context; +import android.os.SystemProperties; +import android.support.v14.preference.SwitchPreference; +import android.support.v7.preference.PreferenceScreen; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.TestConfig; +import com.android.settings.testutils.shadow.SettingsShadowSystemProperties; + +import org.junit.After; +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.annotation.Config; +import org.robolectric.RuntimeEnvironment; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, + shadows = {SettingsShadowSystemProperties.class}) +public class CameraLaserSensorPreferenceControllerTest { + + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private Context mContext; + @Mock + private PreferenceScreen mScreen; + @Mock + private SwitchPreference mPreference; + + static final String USERDEBUG_BUILD = "userdebug"; + static final String ENG_BUILD = "eng"; + static final String USER_BUILD = "user"; + + private CameraLaserSensorPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mController = new CameraLaserSensorPreferenceController(mContext); + when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + when(mPreference.getKey()).thenReturn(mController.getPreferenceKey()); + } + + @After + public void tearDown() { + SettingsShadowSystemProperties.clear(); + } + + @Test + public void isAvailable_withConfigNoShow_shouldReturnFalse() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(false); + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void isAvailable_withUserdebugBuild_shouldReturnTrue() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_withEngBuild_shouldReturnTrue() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, ENG_BUILD); + + assertThat(mController.isAvailable()).isTrue(); + } + + @Test + public void isAvailable_withUserBuild_shouldReturnFalse() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USER_BUILD); + + assertThat(mController.isAvailable()).isFalse(); + } + + @Test + public void displayPreference_cameraLaserSensorEnabled_shouldCheckedPreference() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)); + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(true); + } + + @Test + public void displayPreference_cameraLaserSensorEnabled_shouldUncheckedPreference() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.DISABLED)); + SettingsShadowSystemProperties.set( + CameraLaserSensorPreferenceController.BUILD_TYPE, USERDEBUG_BUILD); + + mController.displayPreference(mScreen); + + verify(mPreference).setChecked(false); + } + + @Test + public void handlePreferenceTreeClick_preferenceChecked_shouldEnableCameraLaserSensor() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + when(mPreference.isChecked()).thenReturn(true); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(Integer.toString(CameraLaserSensorPreferenceController.ENABLED).equals( + SystemProperties.get( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)))).isTrue(); + } + + @Test + public void handlePreferenceTreeClick_preferenceUnchecked_shouldDisableCameraLaserSensor() { + when(mContext.getResources().getBoolean(R.bool.config_show_camera_laser_sensor)) + .thenReturn(true); + + when(mPreference.isChecked()).thenReturn(false); + + mController.handlePreferenceTreeClick(mPreference); + + assertThat(Integer.toString(CameraLaserSensorPreferenceController.DISABLED).equals( + SystemProperties.get( + CameraLaserSensorPreferenceController.PROPERTY_CAMERA_LASER_SENSOR, + Integer.toString(CameraLaserSensorPreferenceController.ENABLED)))).isTrue(); + } +} From 5f21c6913b78ab8d3a5ab1f801f93fec73bd1eed Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 1 Sep 2017 13:33:23 -0700 Subject: [PATCH 03/25] Add OWNERS for package backup Bug: 65294119 Test: Manual Change-Id: I804b50a38c877da80b5ef3251e16029259014152 --- src/com/android/settings/backup/OWNERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/com/android/settings/backup/OWNERS diff --git a/src/com/android/settings/backup/OWNERS b/src/com/android/settings/backup/OWNERS new file mode 100644 index 00000000000..c026a350e75 --- /dev/null +++ b/src/com/android/settings/backup/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +bryanmawhinney@google.com +cprins@google.com +jorlow@google.com +philippov@google.com +stefanot@google.com \ No newline at end of file From 39af82fbac17713b97696b8cada7495b4aedf562 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 11:21:49 -0700 Subject: [PATCH 04/25] Add OWNERS for folder location Bug: 65294119 Test: Build Change-Id: I2fd0249fd8b555e5ca93c3aec13857e6c74e157c --- src/com/android/settings/location/OWNERS | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/com/android/settings/location/OWNERS diff --git a/src/com/android/settings/location/OWNERS b/src/com/android/settings/location/OWNERS new file mode 100644 index 00000000000..5feda773f3a --- /dev/null +++ b/src/com/android/settings/location/OWNERS @@ -0,0 +1,10 @@ +# Default reviewers for this and subdirectories. +asalo@google.com +lifu@google.com +mstogaitis@google.com +palanki@google.com +sooniln@google.com +weiwa@google.com +wyattriley@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From a230cf2a84d1cd56eee18bed8c6b19127b645fe5 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 6 Sep 2017 15:15:40 -0700 Subject: [PATCH 05/25] Add OWNERS for package enterprise Bug: 65294119 Test: Manual Change-Id: I697528ff260a0f8e54aa1188e35143e668800e7d --- src/com/android/settings/enterprise/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/com/android/settings/enterprise/OWNERS diff --git a/src/com/android/settings/enterprise/OWNERS b/src/com/android/settings/enterprise/OWNERS new file mode 100644 index 00000000000..bab2fe2d1b9 --- /dev/null +++ b/src/com/android/settings/enterprise/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +sandness@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From bd3c83b4c21535a101dc567e16f4f39122616e43 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 1 Sep 2017 13:19:58 -0700 Subject: [PATCH 06/25] Add OWNER for accessibility package. Bug: 65294119 Test: Manual Change-Id: I39eec9ebc1db2dc14669f27b17624394e25eb47f --- src/com/android/settings/accessibility/OWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/com/android/settings/accessibility/OWNERS diff --git a/src/com/android/settings/accessibility/OWNERS b/src/com/android/settings/accessibility/OWNERS new file mode 100644 index 00000000000..28dfdefabef --- /dev/null +++ b/src/com/android/settings/accessibility/OWNERS @@ -0,0 +1,3 @@ +# Default reviewers for this and subdirectories. +pweaver@google.com +zork@google.com \ No newline at end of file From d44a993b871cca32706d31095f6bdb54e6ab7042 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 15:28:17 -0700 Subject: [PATCH 07/25] Add OWNERS for folder users Bug: 65294119 Test: Manual Change-Id: I24ec103ff5013ad416e3dfb1c548acd387b4ba64 --- src/com/android/settings/users/OWNERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/com/android/settings/users/OWNERS diff --git a/src/com/android/settings/users/OWNERS b/src/com/android/settings/users/OWNERS new file mode 100644 index 00000000000..59096bec798 --- /dev/null +++ b/src/com/android/settings/users/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +dling@google.com +yamasani@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 3b3d52ff3682f39e3c5f2f7c705914b22484404d Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 15:11:20 -0700 Subject: [PATCH 08/25] Add OWNERS for folder notification Bug: 65294119 Test: Manual Change-Id: If9fddc8b4e2e6d4d7db185ab16063e824323b9a7 --- src/com/android/settings/notification/OWNERS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/com/android/settings/notification/OWNERS diff --git a/src/com/android/settings/notification/OWNERS b/src/com/android/settings/notification/OWNERS new file mode 100644 index 00000000000..0d73685a875 --- /dev/null +++ b/src/com/android/settings/notification/OWNERS @@ -0,0 +1,4 @@ +# Default reviewers for this and subdirectories. +asc@google.com +dsandler@google.com +juliacr@google.com \ No newline at end of file From 1caec026dac35545caa28646275e901a778b1402 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 13:08:54 -0700 Subject: [PATCH 09/25] Add OWNERS for folder password Bug: 65294119 Test: Build Change-Id: Id1c2d9233643a18c1e104255a9e2b8b1aaefc44e --- src/com/android/settings/password/OWNERS | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/com/android/settings/password/OWNERS diff --git a/src/com/android/settings/password/OWNERS b/src/com/android/settings/password/OWNERS new file mode 100644 index 00000000000..cac6e3f3df7 --- /dev/null +++ b/src/com/android/settings/password/OWNERS @@ -0,0 +1,7 @@ +# Default reviewers for this and subdirectories. +jaggies@google.com +kchyn@google.com +paulcrowley@google.com +rubinxu@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 5a7e46dd800dac5ce863b5b337592bca21dc0c2b Mon Sep 17 00:00:00 2001 From: Eric Schwarzenbach Date: Mon, 17 Jul 2017 14:13:02 -0700 Subject: [PATCH 10/25] Add modify button to WifiNetworkDetailsFragment. Adds pencil icon to Wifi Detail action bar to modify the network. Modifies package/public visibility to allow the detail package to use the WifiDialog. Listens for changes in WifiConfigurations to propagate changes to the UI in WifiNetworkDetailsFragment. Changes WifiNetworkDetail preference launch to conform to pattern of other Settings apps. Removes unused WifiDetailActionBarObserver. Bug: 36483704, 37082355 Test: make -j40 RunSettingsRoboTests Change-Id: Ie9dc1892eaefdfad4a6bd7040bfc5dbf6236cfb4 --- res/xml/wifi_network_details_fragment.xml | 11 ++- .../settings/wifi/WifiConfigController.java | 2 +- src/com/android/settings/wifi/WifiDialog.java | 3 +- .../android/settings/wifi/WifiSettings.java | 26 +++++-- .../details/WifiDetailActionBarObserver.java | 45 ------------ .../WifiDetailPreferenceController.java | 54 +++++++++++++-- .../details/WifiNetworkDetailsFragment.java | 52 ++++++++++++-- .../WifiDetailActionBarObserverTest.java | 69 ------------------- 8 files changed, 122 insertions(+), 140 deletions(-) delete mode 100644 src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 550ab36ac0a..5407947f8ec 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -22,14 +22,14 @@ android:selectable="false" android:order="-10000"/> + + + - - - - diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 5a3d426d125..3cf7f930bda 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -492,7 +492,7 @@ public class WifiConfigController implements TextWatcher, } } - /* package */ WifiConfiguration getConfig() { + public WifiConfiguration getConfig() { if (mMode == WifiConfigUiBase.MODE_VIEW) { return null; } diff --git a/src/com/android/settings/wifi/WifiDialog.java b/src/com/android/settings/wifi/WifiDialog.java index 81f2a14ee62..cb3f8df1e77 100644 --- a/src/com/android/settings/wifi/WifiDialog.java +++ b/src/com/android/settings/wifi/WifiDialog.java @@ -27,8 +27,7 @@ import com.android.settings.R; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.wifi.AccessPoint; -// TODO(b/64069122) Have this extend a dialogfragment to handle the fullscreen launch case. -class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { +public class WifiDialog extends AlertDialog implements WifiConfigUiBase, DialogInterface.OnClickListener { public interface WifiDialogListener { void onForget(WifiDialog dialog); diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index ef6a650a8b0..f3b08bf1dac 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -884,17 +884,20 @@ public class WifiSettings extends RestrictedSettingsFragment * {@link #mConnectedAccessPointPreferenceCategory}. */ private void addConnectedAccessPointPreference(AccessPoint connectedAp) { - String key = connectedAp.getBssid(); - LongPressAccessPointPreference pref = (LongPressAccessPointPreference) - getCachedPreference(key); - if (pref == null) { - pref = createLongPressActionPointPreference(connectedAp); - } + final LongPressAccessPointPreference pref = getOrCreatePreference(connectedAp); // Save the state of the current access point in the bundle so that we can restore it // in the Wifi Network Details Fragment pref.getAccessPoint().saveWifiState(pref.getExtras()); - pref.setFragment(WifiNetworkDetailsFragment.class.getName()); + + // Launch details page on click. + pref.setOnPreferenceClickListener(preference -> { + SettingsActivity activity = (SettingsActivity) WifiSettings.this.getActivity(); + activity.startPreferencePanel(this, + WifiNetworkDetailsFragment.class.getName(), pref.getExtras(), + R.string.wifi_details_title, null, null, 0); + return true; + }); pref.refresh(); mConnectedAccessPointPreferenceCategory.addPreference(pref); @@ -905,6 +908,15 @@ public class WifiSettings extends RestrictedSettingsFragment } } + private LongPressAccessPointPreference getOrCreatePreference(AccessPoint ap) { + LongPressAccessPointPreference pref = (LongPressAccessPointPreference) + getCachedPreference(AccessPointPreference.generatePreferenceKey(ap)); + if (pref == null) { + pref = createLongPressActionPointPreference(ap); + } + return pref; + } + /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */ private void removeConnectedAccessPointPreference() { mConnectedAccessPointPreferenceCategory.removeAll(); diff --git a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java b/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java deleted file mode 100644 index 81413d29b85..00000000000 --- a/src/com/android/settings/wifi/details/WifiDetailActionBarObserver.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.details; - -import android.app.Fragment; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnCreate; - -/** - * ActionBar lifecycle observer for {@link WifiNetworkDetailsFragment}. - */ -public class WifiDetailActionBarObserver implements LifecycleObserver, OnCreate { - - private final Fragment mFragment; - private final Context mContext; - - public WifiDetailActionBarObserver(Context context, Fragment fragment) { - mContext = context; - mFragment = fragment; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - if (mFragment.getActivity() != null) { - mFragment.getActivity().getActionBar() - .setTitle(mContext.getString(R.string.wifi_details_title)); - } - } -} diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index aa23419e692..fcdd0d26169 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static com.android.settings.wifi.WifiSettings.isEditabilityLockedDown; +import android.app.Activity; import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; @@ -48,7 +49,7 @@ import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; import android.util.Log; import android.widget.ImageView; - +import android.widget.Toast; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -60,13 +61,14 @@ import com.android.settings.vpn2.ConnectivityManagerWrapper; import com.android.settings.widget.ActionButtonPreference; import com.android.settings.widget.EntityHeaderController; import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiDialog; +import com.android.settings.wifi.WifiDialog.WifiDialogListener; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; import com.android.settingslib.wifi.AccessPoint; - import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; @@ -79,7 +81,9 @@ import java.util.stream.Collectors; * {@link WifiNetworkDetailsFragment}. */ public class WifiDetailPreferenceController extends AbstractPreferenceController - implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnResume { + implements PreferenceControllerMixin, WifiDialogListener, LifecycleObserver, OnPause, + OnResume { + private static final String TAG = "WifiDetailsPrefCtrl"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @@ -121,7 +125,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController private NetworkCapabilities mNetworkCapabilities; private int mRssiSignalLevel = -1; private String[] mSignalStr; - private final WifiConfiguration mWifiConfig; + private WifiConfiguration mWifiConfig; private WifiInfo mWifiInfo; private final WifiManager mWifiManager; private final MetricsFeatureProvider mMetricsFeatureProvider; @@ -147,9 +151,21 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController @Override public void onReceive(Context context, Intent intent) { switch (intent.getAction()) { + case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION: + if (!intent.getBooleanExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, + false /* defaultValue */)) { + // only one network changed + WifiConfiguration wifiConfiguration = intent + .getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION); + if (mAccessPoint.matches(wifiConfiguration)) { + mWifiConfig = wifiConfiguration; + } + } + // fall through case WifiManager.NETWORK_STATE_CHANGED_ACTION: case WifiManager.RSSI_CHANGED_ACTION: updateInfo(); + break; } } }; @@ -239,6 +255,8 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mFilter = new IntentFilter(); mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); + mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); + lifecycle.addObserver(this); } @@ -334,7 +352,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController return; } - // Update whether the forgot button should be displayed. + // Update whether the forget button should be displayed. mButtonsPref.setButton1Visible(canForgetNetwork()); refreshNetworkState(); @@ -521,6 +539,32 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController mConnectivityManagerWrapper.startCaptivePortalApp(mNetwork); } + @Override + public void onForget(WifiDialog dialog) { + // can't forget network from a 'modify' dialog + } + + @Override + public void onSubmit(WifiDialog dialog) { + if (dialog.getController() != null) { + mWifiManager.save(dialog.getController().getConfig(), new WifiManager.ActionListener() { + @Override + public void onSuccess() { + } + + @Override + public void onFailure(int reason) { + Activity activity = mFragment.getActivity(); + if (activity != null) { + Toast.makeText(activity, + R.string.wifi_failed_save_message, + Toast.LENGTH_SHORT).show(); + } + } + }); + } + } + /** * Wrapper for testing compatibility. */ diff --git a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java index 4918889ff9d..765bebccb2b 100644 --- a/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java +++ b/src/com/android/settings/wifi/details/WifiNetworkDetailsFragment.java @@ -15,17 +15,25 @@ */ package com.android.settings.wifi.details; +import static com.android.settings.wifi.WifiSettings.WIFI_DIALOG_ID; + +import android.app.Dialog; import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import com.android.internal.logging.nano.MetricsProto; +import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.vpn2.ConnectivityManagerWrapperImpl; -import com.android.settings.wifi.WifiDetailPreference; +import com.android.settings.wifi.WifiConfigUiBase; +import com.android.settings.wifi.WifiDialog; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.wifi.AccessPoint; import java.util.ArrayList; @@ -44,13 +52,9 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { private AccessPoint mAccessPoint; private WifiDetailPreferenceController mWifiDetailPreferenceController; - private WifiDetailActionBarObserver mWifiDetailActionBarObserver; @Override public void onAttach(Context context) { - mWifiDetailActionBarObserver = new WifiDetailActionBarObserver(context, this); - getLifecycle().addObserver(mWifiDetailActionBarObserver); - mAccessPoint = new AccessPoint(context, getArguments()); super.onAttach(context); } @@ -70,6 +74,44 @@ public class WifiNetworkDetailsFragment extends DashboardFragment { return R.xml.wifi_network_details_fragment; } + @Override + public int getDialogMetricsCategory(int dialogId) { + if (dialogId == WIFI_DIALOG_ID) { + return MetricsEvent.DIALOG_WIFI_AP_EDIT; + } + return 0; + } + + @Override + public Dialog onCreateDialog(int dialogId) { + if (getActivity() == null || mWifiDetailPreferenceController == null + || mAccessPoint == null) { + return null; + } + return WifiDialog.createModal(getActivity(), mWifiDetailPreferenceController, mAccessPoint, + WifiConfigUiBase.MODE_MODIFY); + } + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + MenuItem item = menu.add(0, Menu.FIRST, 0, R.string.wifi_modify); + item.setIcon(R.drawable.ic_mode_edit); + item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + switch (menuItem.getItemId()) { + case Menu.FIRST: + showDialog(WIFI_DIALOG_ID); + return true; + default: + return super.onOptionsItemSelected(menuItem); + } + } + @Override protected List getPreferenceControllers(Context context) { ConnectivityManager cm = context.getSystemService(ConnectivityManager.class); diff --git a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java b/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java deleted file mode 100644 index c573d3cb658..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/details/WifiDetailActionBarObserverTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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.wifi.details; - -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.ActionBar; -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import com.android.settings.R; -import com.android.settings.TestConfig; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settingslib.core.lifecycle.Lifecycle; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class WifiDetailActionBarObserverTest { - - @Mock private Bundle mockBundle; - @Mock private Activity mockActivity; - @Mock private ActionBar mockActionBar; - @Mock private WifiNetworkDetailsFragment mockFragment; - - private Context mContext = RuntimeEnvironment.application; - private Lifecycle mLifecycle; - private WifiDetailActionBarObserver mObserver; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mLifecycle = new Lifecycle(); - - when(mockFragment.getActivity()).thenReturn(mockActivity); - when(mockActivity.getActionBar()).thenReturn(mockActionBar); - - mObserver = new WifiDetailActionBarObserver(mContext, mockFragment); - mLifecycle.addObserver(mObserver); - } - - @Test - public void actionBarIsSetToNetworkInfo() { - mLifecycle.onCreate(mockBundle); - - verify(mockActionBar).setTitle(mContext.getString(R.string.wifi_details_title)); - } -} From d8964a5735165a7d03e5928a5832570331006053 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 14:16:17 -0700 Subject: [PATCH 11/25] Add OWNERS for folder nfc Bug: 65294119 Test: Manual Change-Id: I69af58183c5b89af96c1a8808665fa506a620012 --- src/com/android/settings/nfc/OWNERS | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/com/android/settings/nfc/OWNERS diff --git a/src/com/android/settings/nfc/OWNERS b/src/com/android/settings/nfc/OWNERS new file mode 100644 index 00000000000..f11f74f19db --- /dev/null +++ b/src/com/android/settings/nfc/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +eisenbach@google.com +kandoiruchi@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From a50a5e529b9ea64935f1444bd6288f378f86f87f Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 11 Sep 2017 12:54:31 -0700 Subject: [PATCH 12/25] Add OWNERS for folder fuelgauge Bug: 65294119 Test: Manual Change-Id: Ia1eb8155f2d4359d56b0babd474083295ba38a0b --- src/com/android/settings/fuelgauge/OWNERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/com/android/settings/fuelgauge/OWNERS diff --git a/src/com/android/settings/fuelgauge/OWNERS b/src/com/android/settings/fuelgauge/OWNERS new file mode 100644 index 00000000000..5b26c46d340 --- /dev/null +++ b/src/com/android/settings/fuelgauge/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +dehboxturtle@google.com +jackqdyulei@google.com + +# Emergency approvers in case the above are not available +asapperstein@google.com \ No newline at end of file From 12701a4c5b4919eccd27114ee075de136603d9e8 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 6 Sep 2017 15:28:21 -0700 Subject: [PATCH 13/25] Add OWNERS for folder fingerprint Bug: 65294119 Test: Manual Change-Id: I1486782f476acaf1e2e4b66df57869409239986f --- src/com/android/settings/fingerprint/OWNERS | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/com/android/settings/fingerprint/OWNERS diff --git a/src/com/android/settings/fingerprint/OWNERS b/src/com/android/settings/fingerprint/OWNERS new file mode 100644 index 00000000000..937b3030fd6 --- /dev/null +++ b/src/com/android/settings/fingerprint/OWNERS @@ -0,0 +1,5 @@ +# Default reviewers for this and subdirectories. +jaggies@google.com +yukl@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 054064d40dccb96b2be4a5bcbf1c651701dc1afe Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 11 Sep 2017 12:44:27 -0700 Subject: [PATCH 14/25] Add OWNERS for folder bluetooth Bug: 65294119 Test: Build Change-Id: I927052a73f639d0894600611cd5c79293f43ff5e --- src/com/android/settings/bluetooth/OWNERS | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/com/android/settings/bluetooth/OWNERS diff --git a/src/com/android/settings/bluetooth/OWNERS b/src/com/android/settings/bluetooth/OWNERS new file mode 100644 index 00000000000..2b829785e51 --- /dev/null +++ b/src/com/android/settings/bluetooth/OWNERS @@ -0,0 +1,7 @@ +# Default reviewers for this and subdirectories. +asargent@google.com +eisenbach@google.com +jackqdyulei@google.com +siyuanh@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 35066bbcd733826e480164b807748e5cd9b794ef Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 13:19:35 -0700 Subject: [PATCH 15/25] Add OWNERS for folder tts Bug: 65294119 Test: Manual Change-Id: Ie9492f497824cd2b2727dde9d3a48452c72f1084 --- src/com/android/settings/tts/OWNERS | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/com/android/settings/tts/OWNERS diff --git a/src/com/android/settings/tts/OWNERS b/src/com/android/settings/tts/OWNERS new file mode 100644 index 00000000000..01068dcf299 --- /dev/null +++ b/src/com/android/settings/tts/OWNERS @@ -0,0 +1,6 @@ +# Default reviewers for this and subdirectories. +fergus@google.com +nielse@google.com +ssancho@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From 65dea0a7b2f44422aa3778b6565f1c4b7e5d9eb1 Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 11 Sep 2017 14:33:28 -0700 Subject: [PATCH 16/25] Init the pref summary in onCreate() The visibility of bottom summary in BatteryHistoryPrefence will be changed dynamically(charging status + flags). Before this cl, we only update it in a callback, which makes other preference may have unnecessary moves. This cl add init method in onCreate(), which removes the uncessary preference position moves. Bug: 65529494 Test: RoboTest still pass Change-Id: I09d2e26fc3caaeb272422997c16957770cdc1d3f --- .../settings/fuelgauge/PowerUsageAdvanced.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index fe002b0fc37..d29364dfcc6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -124,6 +124,9 @@ public class PowerUsageAdvanced extends PowerUsageBase { mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mBatteryUtils = BatteryUtils.getInstance(context); + + // init the summary so other preferences won't have unnecessary move + updateHistPrefSummary(context); } @Override @@ -175,7 +178,13 @@ public class PowerUsageAdvanced extends PowerUsageBase { } updatePreference(mHistPref); refreshPowerUsageDataList(mStatsHelper, mUsageListGroup); + updateHistPrefSummary(context); + BatteryEntry.startRequestQueue(); + BatteryUtils.logRuntime(TAG, "refreshUI", startTime); + } + + private void updateHistPrefSummary(Context context) { Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0; @@ -186,9 +195,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { } else { mHistPref.hideBottomSummary(); } - - BatteryEntry.startRequestQueue(); - BatteryUtils.logRuntime(TAG, "refreshUI", startTime); } @VisibleForTesting From 5152bf87b0883df86fe4c10221ae3dfba544f1ef Mon Sep 17 00:00:00 2001 From: jeffreyhuang Date: Mon, 11 Sep 2017 14:42:11 -0700 Subject: [PATCH 17/25] Do not dim icons when Preference is Disabled Change DimmableIconPreference into RestrictedPreference so that the app icon background no longer turns darker Fixes: 65207948 Test: Manual using settings app, Run SettingsRoboTests Change-Id: I1c458439006c9d07642b9ef35455e845cb5545e6 --- src/com/android/settings/location/LocationSettings.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/location/LocationSettings.java b/src/com/android/settings/location/LocationSettings.java index 34e8cc39f47..d66b3105d2d 100644 --- a/src/com/android/settings/location/LocationSettings.java +++ b/src/com/android/settings/location/LocationSettings.java @@ -35,7 +35,6 @@ import android.util.Log; import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; -import com.android.settings.DimmableIconPreference; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.Utils; @@ -43,6 +42,7 @@ import com.android.settings.applications.InstalledAppDetails; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.widget.SwitchBar; import com.android.settingslib.RestrictedLockUtils; +import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedSwitchPreference; import com.android.settingslib.location.RecentLocationApps; @@ -207,8 +207,8 @@ public class LocationSettings extends LocationSettingsBase List recentLocationPrefs = new ArrayList<>(recentLocationRequests.size()); for (final RecentLocationApps.Request request : recentLocationRequests) { - DimmableIconPreference pref = new DimmableIconPreference(getPrefContext(), - request.contentDescription); + RestrictedPreference pref = new RestrictedPreference(getPrefContext()); + pref.setSummary(request.contentDescription); pref.setIcon(request.icon); pref.setTitle(request.label); pref.setOnPreferenceClickListener( From 26938b36ee55aa23fff19fc7c9569191c5d49bf7 Mon Sep 17 00:00:00 2001 From: Malcolm Chen Date: Mon, 11 Sep 2017 17:48:14 -0700 Subject: [PATCH 18/25] In ApnEditor, restore preference values after re-creating. After destroying and re-creating, the preference values in ApnEditor are not restored. This results in incorrect behavior if it enters two window mode where it's destroyed and re-created. The fix is to have them restored and shown correctly. Bug: 65338066 Test: Manual Change-Id: I5ea16ce01c72061ab116f9c15bfc5cc39bb7a095 --- res/xml/apn_editor.xml | 20 ++++++++++++++++++++ src/com/android/settings/ApnEditor.java | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/res/xml/apn_editor.xml b/res/xml/apn_editor.xml index eac78e97f62..b1e332bd7c4 100644 --- a/res/xml/apn_editor.xml +++ b/res/xml/apn_editor.xml @@ -22,6 +22,7 @@ android:key="apn_name" android:singleLine="true" android:inputType="text" + android:persistent="false" /> diff --git a/src/com/android/settings/ApnEditor.java b/src/com/android/settings/ApnEditor.java index e61f9594dac..50a7a77309a 100644 --- a/src/com/android/settings/ApnEditor.java +++ b/src/com/android/settings/ApnEditor.java @@ -297,6 +297,11 @@ public class ApnEditor extends SettingsPreferenceFragment getPreferenceScreen().getPreference(i).setOnPreferenceChangeListener(this); } + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); fillUi(); } From d77881f88d0ef73a4492c214fceb505c2e555c95 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Fri, 8 Sep 2017 15:29:54 -0700 Subject: [PATCH 19/25] Add switch bar to enable/disable dev settings in new page. Bug: 65522852 Test: make RunSettingsRoboTests -j40 ROBOTEST_FILTER=Development Change-Id: I0958950dc6aaee24d8d5e0be58d7564d108bc72e --- .../DevelopmentSettingsDashboardFragment.java | 62 +++++++++++++- .../DevelopmentSwitchBarController.java | 38 ++++++++- ...EnableDevelopmentSettingWarningDialog.java | 70 ++++++++++++++++ ...elopmentSettingsDashboardFragmentTest.java | 83 ++++++++++++++++++- .../DevelopmentSwitchBarControllerTest.java | 34 ++++++++ 5 files changed, 283 insertions(+), 4 deletions(-) create mode 100644 src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 30be65483f5..919dc3a4bef 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -17,12 +17,16 @@ package com.android.settings.development; import android.content.Context; +import android.os.Bundle; import android.os.UserManager; import android.provider.SearchIndexableResource; import android.util.Log; +import android.widget.Switch; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; +import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; @@ -33,21 +37,67 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler; import java.util.Arrays; import java.util.List; -public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment { +public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFragment + implements SwitchBar.OnSwitchChangeListener { private static final String TAG = "DevSettingsDashboard"; + private boolean mIsAvailable = true; private SwitchBar mSwitchBar; + private DevelopmentSwitchBarController mSwitchBarController; public DevelopmentSettingsDashboardFragment() { super(UserManager.DISALLOW_DEBUGGING_FEATURES); } + @Override + public void onActivityCreated(Bundle icicle) { + super.onActivityCreated(icicle); + // Apply page-level restrictions + setIfOnlyAvailableForAdmins(true); + if (isUiRestricted() || !Utils.isDeviceProvisioned(getActivity())) { + // Block access to developer options if the user is not the owner, if user policy + // restricts it, or if the device has not been provisioned + mIsAvailable = false; + // Show error message + if (!isUiRestrictedByOnlyAdmin()) { + getEmptyTextView().setText(R.string.development_settings_not_available); + } + getPreferenceScreen().removeAll(); + return; + } + // Set up master switch + mSwitchBar = ((SettingsActivity) getActivity()).getSwitchBar(); + mSwitchBarController = new DevelopmentSwitchBarController( + this /* DevelopmentSettings */, mSwitchBar, mIsAvailable, getLifecycle()); + mSwitchBar.show(); + } + @Override public int getMetricsCategory() { return MetricsProto.MetricsEvent.DEVELOPMENT; } + @Override + public void onSwitchChanged(Switch switchView, boolean isChecked) { + if (switchView != mSwitchBar.getSwitch()) { + return; + } + final boolean developmentEnabledState = + DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(getContext()); + if (isChecked != developmentEnabledState) { + if (isChecked) { + EnableDevelopmentSettingWarningDialog.show(this /* host */); + } else { + // TODO: Reset dangerous options (move logic from DevelopmentSettings). + // resetDangerousOptions(); + DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), false); + // TODO: Refresh all prefs' enabled state (move logic from DevelopmentSettings). + // setPrefsEnabledState(false); + } + } + } + @Override protected String getLogTag() { return TAG; @@ -69,6 +119,16 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra return buildPreferenceControllers(context); } + void onEnableDevelopmentOptionsConfirmed() { + DevelopmentSettingsEnabler.setDevelopmentSettingsEnabled(getContext(), true); + // TODO: Refresh all prefs' enabled state (move logic from DevelopmentSettings). + } + + void onEnableDevelopmentOptionsRejected() { + // Reset the toggle + mSwitchBar.setChecked(false); + } + private static List buildPreferenceControllers(Context context) { return null; } diff --git a/src/com/android/settings/development/DevelopmentSwitchBarController.java b/src/com/android/settings/development/DevelopmentSwitchBarController.java index 168f7c062b3..ae875b39961 100644 --- a/src/com/android/settings/development/DevelopmentSwitchBarController.java +++ b/src/com/android/settings/development/DevelopmentSwitchBarController.java @@ -22,18 +22,39 @@ import com.android.settingslib.core.lifecycle.Lifecycle; 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.development.DevelopmentSettingsEnabler; public class DevelopmentSwitchBarController implements LifecycleObserver, OnStart, OnStop { private final SwitchBar mSwitchBar; private final boolean mIsAvailable; private final DevelopmentSettings mSettings; + private final DevelopmentSettingsDashboardFragment mNewSettings; + /** + * @deprecated in favor of the other constructor. + */ + @Deprecated public DevelopmentSwitchBarController(DevelopmentSettings settings, SwitchBar switchBar, boolean isAvailable, Lifecycle lifecycle) { mSwitchBar = switchBar; mIsAvailable = isAvailable && !Utils.isMonkeyRunning(); mSettings = settings; + mNewSettings = null; + + if (mIsAvailable) { + lifecycle.addObserver(this); + } else { + mSwitchBar.setEnabled(false); + } + } + + public DevelopmentSwitchBarController(DevelopmentSettingsDashboardFragment settings, + SwitchBar switchBar, boolean isAvailable, Lifecycle lifecycle) { + mSwitchBar = switchBar; + mIsAvailable = isAvailable && !Utils.isMonkeyRunning(); + mSettings = null; + mNewSettings = settings; if (mIsAvailable) { lifecycle.addObserver(this); @@ -44,11 +65,24 @@ public class DevelopmentSwitchBarController implements LifecycleObserver, OnStar @Override public void onStart() { - mSwitchBar.addOnSwitchChangeListener(mSettings); + if (mSettings != null) { + mSwitchBar.addOnSwitchChangeListener(mSettings); + } + if (mNewSettings != null) { + final boolean developmentEnabledState = DevelopmentSettingsEnabler + .isDevelopmentSettingsEnabled(mNewSettings.getContext()); + mSwitchBar.setChecked(developmentEnabledState); + mSwitchBar.addOnSwitchChangeListener(mNewSettings); + } } @Override public void onStop() { - mSwitchBar.removeOnSwitchChangeListener(mSettings); + if (mSettings != null) { + mSwitchBar.removeOnSwitchChangeListener(mSettings); + } + if (mNewSettings != null) { + mSwitchBar.removeOnSwitchChangeListener(mNewSettings); + } } } diff --git a/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java b/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java new file mode 100644 index 00000000000..3c3d645911f --- /dev/null +++ b/src/com/android/settings/development/EnableDevelopmentSettingWarningDialog.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.development; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.FragmentManager; +import android.content.DialogInterface; +import android.os.Bundle; + +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; + +public class EnableDevelopmentSettingWarningDialog extends InstrumentedDialogFragment + implements DialogInterface.OnClickListener { + + public static final String TAG = "EnableDevSettingDlg"; + + public static void show( + DevelopmentSettingsDashboardFragment host) { + final EnableDevelopmentSettingWarningDialog dialog = + new EnableDevelopmentSettingWarningDialog(); + dialog.setTargetFragment(host, 0 /* requestCode */); + final FragmentManager manager = host.getActivity().getFragmentManager(); + if (manager.findFragmentByTag(TAG) == null) { + dialog.show(manager, TAG); + } + } + + @Override + public int getMetricsCategory() { + return MetricsProto.MetricsEvent.DIALOG_ENABLE_DEVELOPMENT_OPTIONS; + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return new AlertDialog.Builder(getActivity()) + .setMessage(R.string.dev_settings_warning_message) + .setTitle(R.string.dev_settings_warning_title) + .setPositiveButton(android.R.string.yes, this) + .setNegativeButton(android.R.string.no, this) + .create(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + final DevelopmentSettingsDashboardFragment host = + (DevelopmentSettingsDashboardFragment) getTargetFragment(); + if (which == DialogInterface.BUTTON_POSITIVE) { + host.onEnableDevelopmentOptionsConfirmed(); + } else { + host.onEnableDevelopmentOptionsRejected(); + } + } +} diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java index 04ff721167f..a001aafcdb1 100644 --- a/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/development/DevelopmentSettingsDashboardFragmentTest.java @@ -17,22 +17,32 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.content.Context; import android.provider.SearchIndexableResource; +import android.provider.Settings; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.widget.SwitchBar; +import com.android.settings.widget.ToggleSwitch; import com.android.settingslib.development.DevelopmentSettingsEnabler; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.util.ReflectionHelpers; import java.util.List; @@ -44,11 +54,24 @@ import java.util.List; }) public class DevelopmentSettingsDashboardFragmentTest { + private SwitchBar mSwitchBar; + private ToggleSwitch mSwitch; + private Context mContext; private DevelopmentSettingsDashboardFragment mDashboard; @Before public void setUp() { - mDashboard = new DevelopmentSettingsDashboardFragment(); + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mSwitchBar = new SwitchBar(mContext); + mSwitch = mSwitchBar.getSwitch(); + mDashboard = spy(new DevelopmentSettingsDashboardFragment()); + ReflectionHelpers.setField(mDashboard, "mSwitchBar", mSwitchBar); + } + + @After + public void tearDown() { + ShadowEnableDevelopmentSettingWarningDialog.reset(); } @Test @@ -95,4 +118,62 @@ public class DevelopmentSettingsDashboardFragmentTest { assertThat(nonIndexableKeys).doesNotContain("development_prefs_screen"); } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_sameState_shouldDoNothing() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + + mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); + } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_turnOn_shouldShowWarningDialog() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0); + + mDashboard.onSwitchChanged(mSwitch, true /* isChecked */); + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isTrue(); + } + + @Test + @Config(shadows = { + ShadowEnableDevelopmentSettingWarningDialog.class + }) + public void onSwitchChanged_turnOff_shouldTurnOff() { + when(mDashboard.getContext()).thenReturn(mContext); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1); + + mDashboard.onSwitchChanged(mSwitch, false /* isChecked */); + + assertThat(ShadowEnableDevelopmentSettingWarningDialog.mShown).isFalse(); + assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) + .isFalse(); + } + + @Implements(EnableDevelopmentSettingWarningDialog.class) + public static class ShadowEnableDevelopmentSettingWarningDialog { + + static boolean mShown; + + public static void reset() { + mShown = false; + } + + @Implementation + public static void show( + DevelopmentSettingsDashboardFragment host) { + mShown = true; + } + } } diff --git a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java index a53b83662cb..6f79fafc98f 100644 --- a/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/DevelopmentSwitchBarControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.development; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.when; import com.android.settings.TestConfig; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -45,6 +46,8 @@ public class DevelopmentSwitchBarControllerTest { @Mock private DevelopmentSettings mSettings; + @Mock + private DevelopmentSettingsDashboardFragment mNewSettings; private Lifecycle mLifecycle; private SwitchBar mSwitchBar; private DevelopmentSwitchBarController mController; @@ -76,6 +79,21 @@ public class DevelopmentSwitchBarControllerTest { assertThat(listeners).doesNotContain(mSettings); } + @Test + public void runThroughLifecycle_v2_isMonkeyRun_shouldNotRegisterListener() { + ShadowUtils.setIsUserAMonkey(true); + mController = new DevelopmentSwitchBarController(mNewSettings, mSwitchBar, + true /* isAvailable */, mLifecycle); + final ArrayList listeners = + ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners"); + + mLifecycle.onStart(); + assertThat(listeners).doesNotContain(mNewSettings); + + mLifecycle.onStop(); + assertThat(listeners).doesNotContain(mNewSettings); + } + @Test public void runThroughLifecycle_isNotMonkeyRun_shouldRegisterAndRemoveListener() { ShadowUtils.setIsUserAMonkey(false); @@ -91,6 +109,22 @@ public class DevelopmentSwitchBarControllerTest { assertThat(listeners).doesNotContain(mSettings); } + @Test + public void runThroughLifecycle_v2_isNotMonkeyRun_shouldRegisterAndRemoveListener() { + when(mNewSettings.getContext()).thenReturn(RuntimeEnvironment.application); + ShadowUtils.setIsUserAMonkey(false); + mController = new DevelopmentSwitchBarController(mNewSettings, mSwitchBar, + true /* isAvailable */, mLifecycle); + final ArrayList listeners = + ReflectionHelpers.getField(mSwitchBar, "mSwitchChangeListeners"); + + mLifecycle.onStart(); + assertThat(listeners).contains(mNewSettings); + + mLifecycle.onStop(); + assertThat(listeners).doesNotContain(mNewSettings); + } + @Test public void buildController_unavailable_shouldDisableSwitchBar() { ShadowUtils.setIsUserAMonkey(false); From ed3fab65e837648095e956ea7716279cf0c6623d Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 7 Sep 2017 15:33:08 -0700 Subject: [PATCH 20/25] Add OWNERS for folder wifi Bug: 65294119 Test: Manual Change-Id: I49159950521a013422b1087ea2c3e6cd5151457c --- src/com/android/settings/wifi/OWNERS | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/com/android/settings/wifi/OWNERS diff --git a/src/com/android/settings/wifi/OWNERS b/src/com/android/settings/wifi/OWNERS new file mode 100644 index 00000000000..3090f13bd3c --- /dev/null +++ b/src/com/android/settings/wifi/OWNERS @@ -0,0 +1,9 @@ +# Default reviewers for this and subdirectories. +asargent@google.com +easchwar@google.com +dling@google.com +jlapenna@google.com +sghuman@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available \ No newline at end of file From d52c17c7658bfd09965b5a21aacf9595714feca6 Mon Sep 17 00:00:00 2001 From: Rebecca Silberstein Date: Fri, 8 Sep 2017 01:02:23 -0700 Subject: [PATCH 21/25] Revert back to isDualBandSupported() for Wifi tethering. This is needed to maintain OEM compatibility Bug: 33160120 Test: robotests Change-Id: Ic302969d33f32da72aee47d29615a250d3d924e2 --- .../WifiTetherApBandPreferenceController.java | 21 ++++++++----- ...iTetherApBandPreferenceControllerTest.java | 30 ++++++++++++++----- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java index 37da38ec3c7..5a08c58d1f7 100644 --- a/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java +++ b/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceController.java @@ -16,6 +16,9 @@ package com.android.settings.wifi.tether; +import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ; +import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ; + import android.content.Context; import android.net.wifi.WifiConfiguration; import android.support.v7.preference.ListPreference; @@ -24,9 +27,6 @@ import android.support.v7.preference.PreferenceScreen; import com.android.settings.R; -import static android.net.wifi.WifiConfiguration.AP_BAND_2GHZ; -import static android.net.wifi.WifiConfiguration.AP_BAND_5GHZ; - public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferenceController { private static final String PREF_KEY = "wifi_tether_network_ap_band"; @@ -41,10 +41,14 @@ public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferen super(context, listener); mBandEntries = mContext.getResources().getStringArray(R.array.wifi_ap_band_config_full); final WifiConfiguration config = mWifiManager.getWifiApConfiguration(); - if (config != null) { + if (config == null) { + mBandIndex = 0; + } else if (is5GhzBandSupported()) { mBandIndex = config.apBand; } else { - mBandIndex = 0; + config.apBand = 0; + mWifiManager.setWifiApConfiguration(config); + mBandIndex = config.apBand; } } @@ -77,10 +81,11 @@ public class WifiTetherApBandPreferenceController extends WifiTetherBasePreferen } private boolean is5GhzBandSupported() { - if (mBandIndex > 0) { - return true; + final String countryCode = mWifiManager.getCountryCode(); + if (!mWifiManager.isDualBandSupported() || countryCode == null) { + return false; } - return mWifiManager.is5GHzBandSupported(); + return true; } public int getBandIndex() { diff --git a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java index a7e00ab544e..8f0b143ae02 100644 --- a/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/wifi/tether/WifiTetherApBandPreferenceControllerTest.java @@ -16,6 +16,12 @@ package com.android.settings.wifi.tether; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.content.Context; import android.net.ConnectivityManager; import android.net.wifi.WifiManager; @@ -35,12 +41,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class WifiTetherApBandPreferenceControllerTest { @@ -75,16 +75,30 @@ public class WifiTetherApBandPreferenceControllerTest { @Test public void display_5GhzSupported_shouldDisplayFullList() { - when(mWifiManager.is5GHzBandSupported()).thenReturn(true); + when(mWifiManager.getCountryCode()).thenReturn("US"); + when(mWifiManager.isDualBandSupported()).thenReturn(true); mController.displayPreference(mScreen); assertThat(mListPreference.getEntries().length).isEqualTo(2); } + @Test + public void display_noCountryCode_shouldDisable() { + when(mWifiManager.getCountryCode()).thenReturn(null); + when(mWifiManager.isDualBandSupported()).thenReturn(true); + + mController.displayPreference(mScreen); + + assertThat(mListPreference.getEntries()).isNull(); + assertThat(mListPreference.isEnabled()).isFalse(); + assertThat(mListPreference.getSummary()) + .isEqualTo(RuntimeEnvironment.application.getString(R.string.wifi_ap_choose_2G)); + } + @Test public void display_5GhzNotSupported_shouldDisable() { - when(mWifiManager.is5GHzBandSupported()).thenReturn(false); + when(mWifiManager.isDualBandSupported()).thenReturn(false); mController.displayPreference(mScreen); From be137eb7c5cdde287195b494b1d83c8e6eee65ae Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Fri, 1 Sep 2017 11:21:52 -0700 Subject: [PATCH 22/25] Add OWNERS file for settings Bug: 65294119 Test: manual Change-Id: I054a6df08046cda1c2f202390ed24839a6b10349 --- OWNERS | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 OWNERS diff --git a/OWNERS b/OWNERS new file mode 100644 index 00000000000..e19e56fdbf0 --- /dev/null +++ b/OWNERS @@ -0,0 +1,15 @@ +# Use this reviewer by default. +pixel-sw-exp-reviews+gerrit@google.com + +# People who can approve changes for submission +asapperstein@google.com +asargent@google.com +dehboxturtle@google.com +dhnishi@google.com +dling@google.com +jackqdyulei@google.com +mfritze@google.com +zhfan@google.com + +# Emergency approvers in case the above are not available +miket@google.com From 4de9df2943cbe047b83c8d428d8572ee0066d771 Mon Sep 17 00:00:00 2001 From: Roozbeh Pournader Date: Sat, 26 Aug 2017 14:05:15 -0700 Subject: [PATCH 23/25] Define Utils.formatRelativeTime() and use it Previously, relative times were formatted using formatElapsedTime() (appending translations of "ago" to them), sometimes resulting in grammatically hard-to-understand or unnatural localizations. Now we use ICU's RelativeDateTimeFormatter, which uses grammatically correct and natural localizations from CLDR data. Bug: 64507689 Bug: 64605781 Bug: 64556849 Bug: 64550172 Test: make -j RunSettingsRoboTests Change-Id: Ia2d098b190ab99e7748ef6f03b919f5c6174ba7d --- res/values/strings.xml | 8 +- src/com/android/settings/Utils.java | 45 +++++++++ .../RecentAppsPreferenceController.java | 6 +- .../settings/fuelgauge/PowerUsageSummary.java | 8 +- .../src/com/android/settings/UtilsTest.java | 99 +++++++++++++++++++ .../RecentAppsPreferenceControllerTest.java | 4 +- .../fuelgauge/PowerUsageSummaryTest.java | 9 +- 7 files changed, 153 insertions(+), 26 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index c58f6bb3b30..51305b52c9b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3633,8 +3633,6 @@ Recently opened apps See all %1$d apps - - ^1 ago @@ -4644,12 +4642,10 @@ Mobile network scanning - - ^1 ago - App usage since full charge (^1 ago) + App usage since full charge (^1) - Device usage since full charge (^1 ago) + Device usage since full charge (^1) Amount of time screen has been on since full charge diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 417ac0faeb5..fa61cecdf2f 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -52,8 +52,11 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.hardware.fingerprint.FingerprintManager; import android.icu.text.MeasureFormat; +import android.icu.text.RelativeDateTimeFormatter; +import android.icu.text.RelativeDateTimeFormatter.RelativeUnit; import android.icu.util.Measure; import android.icu.util.MeasureUnit; +import android.icu.util.ULocale; import android.net.ConnectivityManager; import android.net.LinkProperties; import android.net.Network; @@ -860,6 +863,48 @@ public final class Utils extends com.android.settingslib.Utils { return sb; } + /** + * Returns relative time for the given millis in the past, in a short format such as "2 days + * ago", "5 hr. ago", "40 min. ago", or "29 sec. ago". + * + *

The unit is chosen to have good information value while only using one unit. So 27 hours + * and 50 minutes would be formatted as "28 hr. ago", while 50 hours would be formatted as + * "2 days ago". + * + * @param context the application context + * @param millis the elapsed time in milli seconds + * @param withSeconds include seconds? + * @return the formatted elapsed time + */ + public static CharSequence formatRelativeTime(Context context, double millis, + boolean withSeconds) { + final int seconds = (int) Math.floor(millis / 1000); + final RelativeUnit unit; + final int value; + if (withSeconds && seconds < 2 * SECONDS_PER_MINUTE) { + unit = RelativeUnit.SECONDS; + value = seconds; + } else if (seconds < 2 * SECONDS_PER_HOUR) { + unit = RelativeUnit.MINUTES; + value = (seconds + SECONDS_PER_MINUTE / 2) / SECONDS_PER_MINUTE; + } else if (seconds < 2 * SECONDS_PER_DAY) { + unit = RelativeUnit.HOURS; + value = (seconds + SECONDS_PER_HOUR / 2) / SECONDS_PER_HOUR; + } else { + unit = RelativeUnit.DAYS; + value = (seconds + SECONDS_PER_DAY / 2) / SECONDS_PER_DAY; + } + + final Locale locale = context.getResources().getConfiguration().locale; + final RelativeDateTimeFormatter formatter = RelativeDateTimeFormatter.getInstance( + ULocale.forLocale(locale), + null /* default NumberFormat */, + RelativeDateTimeFormatter.Style.SHORT, + android.icu.text.DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE); + + return formatter.format(value, RelativeDateTimeFormatter.Direction.LAST, unit); + } + /** * Queries for the UserInfo of a user. Returns null if the user doesn't exist (was removed). * @param userManager Instance of UserManager diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java index d0f7584eaed..69a36f67a53 100644 --- a/src/com/android/settings/applications/RecentAppsPreferenceController.java +++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java @@ -235,10 +235,8 @@ public class RecentAppsPreferenceController extends AbstractPreferenceController pref.setKey(pkgName); pref.setTitle(appEntry.label); pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info)); - pref.setSummary(TextUtils.expandTemplate( - mContext.getResources().getText(R.string.recent_app_summary), - Utils.formatElapsedTime(mContext, - System.currentTimeMillis() - stat.getLastTimeUsed(), false))); + pref.setSummary(Utils.formatRelativeTime(mContext, + System.currentTimeMillis() - stat.getLastTimeUsed(), false)); pref.setOrder(i); pref.setOnPreferenceClickListener(preference -> { AppInfoBase.startAppInfoFragment(InstalledAppDetails.class, diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java index 1596aca70b8..9798749ebad 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java +++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java @@ -533,7 +533,7 @@ public class PowerUsageSummary extends PowerUsageBase implements updateScreenPreference(); updateLastFullChargePreference(lastFullChargeTime); - final CharSequence timeSequence = Utils.formatElapsedTime(context, lastFullChargeTime, + final CharSequence timeSequence = Utils.formatRelativeTime(context, lastFullChargeTime, false); final int resId = mShowAllApps ? R.string.power_usage_list_summary_device : R.string.power_usage_list_summary; @@ -682,10 +682,8 @@ public class PowerUsageSummary extends PowerUsageBase implements @VisibleForTesting void updateLastFullChargePreference(long timeMs) { - final CharSequence timeSequence = Utils.formatElapsedTime(getContext(), timeMs, false); - mLastFullChargePref.setSubtitle( - TextUtils.expandTemplate(getText(R.string.power_last_full_charge_summary), - timeSequence)); + final CharSequence timeSequence = Utils.formatRelativeTime(getContext(), timeMs, false); + mLastFullChargePref.setSubtitle(timeSequence); } @VisibleForTesting diff --git a/tests/robotests/src/com/android/settings/UtilsTest.java b/tests/robotests/src/com/android/settings/UtilsTest.java index 33ead1fd4d0..19b87a1b1fa 100644 --- a/tests/robotests/src/com/android/settings/UtilsTest.java +++ b/tests/robotests/src/com/android/settings/UtilsTest.java @@ -173,6 +173,105 @@ public class UtilsTest { assertThat(ttsSpans[0].getType()).isEqualTo(TtsSpan.TYPE_MEASURE); } + @Test + public void testFormatRelativeTime_WithSeconds_ShowSeconds() { + final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "40 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_NoSeconds_DoNotShowSeconds() { + final double testMillis = 40 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "1 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoMinutes_withSeconds() { + final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "119 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoMinutes_NoSeconds() { + final double testMillis = 119 * DateUtils.SECOND_IN_MILLIS; + final String expectedTime = "2 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoMinutes_withSeconds() { + final double testMillis = 2 * DateUtils.MINUTE_IN_MILLIS; + final String expectedTime = "2 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoHours_withSeconds() { + final double testMillis = 119 * DateUtils.MINUTE_IN_MILLIS; + final String expectedTime = "119 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoHours_withSeconds() { + final double testMillis = 2 * DateUtils.HOUR_IN_MILLIS; + final String expectedTime = "2 hr. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_LessThanTwoDays_withSeconds() { + final double testMillis = 47 * DateUtils.HOUR_IN_MILLIS; + final String expectedTime = "47 hr. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_TwoDays_withSeconds() { + final double testMillis = 2 * DateUtils.DAY_IN_MILLIS; + final String expectedTime = "2 days ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_FormatZero_WithSeconds() { + final double testMillis = 0; + final String expectedTime = "0 sec. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, true).toString()).isEqualTo( + expectedTime); + } + + @Test + public void testFormatRelativeTime_FormatZero_NoSeconds() { + final double testMillis = 0; + final String expectedTime = "0 min. ago"; + + assertThat(Utils.formatRelativeTime(mContext, testMillis, false).toString()).isEqualTo( + expectedTime); + } + @Test public void testInitializeVolumeDoesntBreakOnNullVolume() { VolumeInfo info = new VolumeInfo("id", 0, new DiskInfo("id", 0), ""); diff --git a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java index 2510f201faa..5e85f9b7e48 100644 --- a/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/RecentAppsPreferenceControllerTest.java @@ -249,8 +249,6 @@ public class RecentAppsPreferenceControllerTest { when(mUsageStatsManager.queryUsageStats(anyInt(), anyLong(), anyLong())) .thenReturn(stats); - when(mMockContext.getResources().getText(eq(R.string.recent_app_summary))) - .thenReturn(mContext.getResources().getText(R.string.recent_app_summary)); final Configuration configuration = new Configuration(); configuration.locale = Locale.US; when(mMockContext.getResources().getConfiguration()).thenReturn(configuration); @@ -258,7 +256,7 @@ public class RecentAppsPreferenceControllerTest { mController = new RecentAppsPreferenceController(mMockContext, mAppState, null); mController.displayPreference(mScreen); - verify(mCategory).addPreference(argThat(summaryMatches("0m ago"))); + verify(mCategory).addPreference(argThat(summaryMatches("0 min. ago"))); } private static ArgumentMatcher summaryMatches(String expected) { diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java index db4fb6daa82..89a4208d84e 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java @@ -411,18 +411,11 @@ public class PowerUsageSummaryTest { @Test public void testUpdateLastFullChargePreference_showCorrectSummary() { - final CharSequence formattedString = mRealContext.getText( - R.string.power_last_full_charge_summary); - final CharSequence timeSequence = Utils.formatElapsedTime(mRealContext, - TIME_SINCE_LAST_FULL_CHARGE_MS, false); - final CharSequence expectedSummary = TextUtils.expandTemplate( - formattedString, timeSequence); - doReturn(formattedString).when(mFragment).getText(R.string.power_last_full_charge_summary); doReturn(mRealContext).when(mFragment).getContext(); mFragment.updateLastFullChargePreference(TIME_SINCE_LAST_FULL_CHARGE_MS); - assertThat(mLastFullChargePref.getSubtitle()).isEqualTo(expectedSummary); + assertThat(mLastFullChargePref.getSubtitle()).isEqualTo("2 hr. ago"); } @Test From 4b0677a2a45e2542b44e906c91e4bf57ed00f44e Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Fri, 8 Sep 2017 14:05:15 -0700 Subject: [PATCH 24/25] Index the System status page - Page is found in System > About Phone > Status The page was simply never indexed. - Remove the unavailable summary text. - Suppress IP address because it appears in wifi settings as well. Test: make RunSettingsRoboTests Change-Id: I0c5eb5222fc356dd3686fb84ca47da8e2d3274f5 Fixes: 65443327 --- res/xml/device_info_status.xml | 16 ++-- .../android/settings/deviceinfo/Status.java | 22 ++++- .../search/SearchIndexableResources.java | 2 + .../settings/wifi/ConfigureWifiSettings.java | 21 +++++ .../grandfather_not_implementing_indexable | 1 - .../wifi/ConfigureWifiSettingsTest.java | 83 +++++++++++++++++++ 6 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java diff --git a/res/xml/device_info_status.xml b/res/xml/device_info_status.xml index 9a57af987bf..b381d04242d 100644 --- a/res/xml/device_info_status.xml +++ b/res/xml/device_info_status.xml @@ -23,13 +23,13 @@ android:enabled="false" android:shouldDisableView="false" android:title="@string/battery_status_title" - android:summary="@string/device_info_not_available" /> + android:summary="@string/summary_placeholder" /> diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java index baddc6cac2b..624103a179f 100644 --- a/src/com/android/settings/deviceinfo/Status.java +++ b/src/com/android/settings/deviceinfo/Status.java @@ -31,6 +31,7 @@ import android.os.Message; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserManager; +import android.provider.SearchIndexableResource; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceScreen; import android.text.TextUtils; @@ -40,13 +41,17 @@ import com.android.internal.util.ArrayUtils; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.Utils; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settings.search.Indexable; import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.List; import static android.content.Context.CONNECTIVITY_SERVICE; import static android.content.Context.WIFI_SERVICE; -public class Status extends SettingsPreferenceFragment { +public class Status extends SettingsPreferenceFragment implements Indexable { private static final String KEY_BATTERY_STATUS = "battery_status"; private static final String KEY_BATTERY_LEVEL = "battery_level"; @@ -302,4 +307,19 @@ public class Status extends SettingsPreferenceFragment { return h + ":" + pad(m) + ":" + pad(s); } + + /** + * For Search. + */ + public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider() { + + @Override + public List getXmlResourcesToIndex( + Context context, boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.device_info_status; + return Arrays.asList(sir); + } + }; } diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index c20d2a03007..b657d80b31f 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -45,6 +45,7 @@ import com.android.settings.datausage.DataPlanUsageSummary; import com.android.settings.datausage.DataUsageMeteredSettings; import com.android.settings.datausage.DataUsageSummary; import com.android.settings.development.DevelopmentSettings; +import com.android.settings.deviceinfo.Status; import com.android.settings.deviceinfo.StorageDashboardFragment; import com.android.settings.deviceinfo.StorageSettings; import com.android.settings.display.AmbientDisplaySettings; @@ -188,6 +189,7 @@ public final class SearchIndexableResources { addIndex(PrintSettingsFragment.class, NO_DATA_RES_ID, R.drawable.ic_settings_print); addIndex(DevelopmentSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_development); addIndex(DeviceInfoSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about); + addIndex(Status.class, NO_DATA_RES_ID, 0 /* icon */); addIndex(LegalSettings.class, NO_DATA_RES_ID, R.drawable.ic_settings_about); addIndex(ZenModeVisualInterruptionSettings.class, R.xml.zen_mode_visual_interruptions_settings, diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java index aeee6ffa011..53b2619fc99 100644 --- a/src/com/android/settings/wifi/ConfigureWifiSettings.java +++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java @@ -19,6 +19,8 @@ import static android.content.Context.WIFI_SERVICE; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.net.NetworkScoreManager; import android.net.wifi.WifiManager; import android.provider.SearchIndexableResource; @@ -42,6 +44,8 @@ public class ConfigureWifiSettings extends DashboardFragment { private static final String TAG = "ConfigureWifiSettings"; + public static final String KEY_IP_ADDRESS = "current_ip_address"; + private WifiWakeupPreferenceController mWifiWakeupPreferenceController; private UseOpenWifiPreferenceController mUseOpenWifiPreferenceController; @@ -114,5 +118,22 @@ public class ConfigureWifiSettings extends DashboardFragment { sir.xmlResId = R.xml.wifi_configure_settings; return Arrays.asList(sir); } + + @Override + public List getNonIndexableKeys(Context context) { + List keys = super.getNonIndexableKeys(context); + + // If connected to WiFi, this IP address will be the same as the Status IP. + // Or, if there is no connection they will say unavailable. + ConnectivityManager cm = (ConnectivityManager) + context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo info = cm.getActiveNetworkInfo(); + if (info == null + || info.getType() == ConnectivityManager.TYPE_WIFI) { + keys.add(KEY_IP_ADDRESS); + } + + return keys; + } }; } diff --git a/tests/robotests/assets/grandfather_not_implementing_indexable b/tests/robotests/assets/grandfather_not_implementing_indexable index be5a99b2c65..d961fd6eb86 100644 --- a/tests/robotests/assets/grandfather_not_implementing_indexable +++ b/tests/robotests/assets/grandfather_not_implementing_indexable @@ -20,7 +20,6 @@ com.android.settings.applications.ProcessStatsDetail com.android.settings.wifi.WifiInfo com.android.settings.applications.VrListenerSettings com.android.settings.inputmethod.UserDictionaryList -com.android.settings.deviceinfo.Status com.android.settings.datausage.DataSaverSummary com.android.settings.notification.ChannelNotificationSettings com.android.settings.datausage.AppDataUsage diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java new file mode 100644 index 00000000000..687287be8a4 --- /dev/null +++ b/tests/robotests/src/com/android/settings/wifi/ConfigureWifiSettingsTest.java @@ -0,0 +1,83 @@ +package com.android.settings.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.XmlTestUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class ConfigureWifiSettingsTest { + + private Context mContext; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + } + + @Test + public void testNonIndexableKeys_existInXmlLayout() { + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + final int xmlId = new ConfigureWifiSettings().getPreferenceScreenResId(); + + final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, xmlId); + + assertThat(keys).containsAllIn(niks); + } + + @Test + public void testNonIndexableKeys_noConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + when(manager.getActiveNetworkInfo()).thenReturn(null); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).contains(ConfigureWifiSettings.KEY_IP_ADDRESS); + } + + @Test + public void testNonIndexableKeys_wifiConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + NetworkInfo info = mock(NetworkInfo.class); + when(info.getType()).thenReturn(ConnectivityManager.TYPE_WIFI); + when(manager.getActiveNetworkInfo()).thenReturn(info); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).contains(ConfigureWifiSettings.KEY_IP_ADDRESS); + } + + @Test + public void testNonIndexableKeys_mobileConnection_blocksIP() { + ConnectivityManager manager = mock(ConnectivityManager.class); + NetworkInfo info = mock(NetworkInfo.class); + when(info.getType()).thenReturn(ConnectivityManager.TYPE_MOBILE); + when(manager.getActiveNetworkInfo()).thenReturn(info); + doReturn(manager).when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE); + + final List niks = ConfigureWifiSettings.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + assertThat(niks).doesNotContain(ConfigureWifiSettings.KEY_IP_ADDRESS); + } +} From 1c5d663ed72ddb164302f3dde5999dc3d96d3b0e Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Mon, 11 Sep 2017 14:33:28 -0700 Subject: [PATCH 25/25] Init the pref summary in onCreate() The visibility of bottom summary in BatteryHistoryPrefence will be changed dynamically(charging status + flags). Before this cl, we only update it in a callback, which makes other preference may have unnecessary moves. This cl add init method in onCreate(), which removes the uncessary preference position moves. Bug: 65529494 Test: RoboTest still pass Change-Id: I09d2e26fc3caaeb272422997c16957770cdc1d3f (cherry picked from commit 65dea0a7b2f44422aa3778b6565f1c4b7e5d9eb1) --- .../settings/fuelgauge/PowerUsageAdvanced.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java index fe002b0fc37..d29364dfcc6 100644 --- a/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/PowerUsageAdvanced.java @@ -124,6 +124,9 @@ public class PowerUsageAdvanced extends PowerUsageBase { mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mBatteryUtils = BatteryUtils.getInstance(context); + + // init the summary so other preferences won't have unnecessary move + updateHistPrefSummary(context); } @Override @@ -175,7 +178,13 @@ public class PowerUsageAdvanced extends PowerUsageBase { } updatePreference(mHistPref); refreshPowerUsageDataList(mStatsHelper, mUsageListGroup); + updateHistPrefSummary(context); + BatteryEntry.startRequestQueue(); + BatteryUtils.logRuntime(TAG, "refreshUI", startTime); + } + + private void updateHistPrefSummary(Context context) { Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); final boolean plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) != 0; @@ -186,9 +195,6 @@ public class PowerUsageAdvanced extends PowerUsageBase { } else { mHistPref.hideBottomSummary(); } - - BatteryEntry.startRequestQueue(); - BatteryUtils.logRuntime(TAG, "refreshUI", startTime); } @VisibleForTesting