From d6506e8540b2da4f16e84a8ec8abf1f5cb8dc42d Mon Sep 17 00:00:00 2001 From: xshu Date: Tue, 24 Mar 2020 18:11:55 -0700 Subject: [PATCH 01/10] Add dev option for enhanced mac randomization This toggle will affect client mode mac randomization only. When toggled on, during association to networks that have MAC randomization turned on, a more random MAC (as opposed to persistent MAC per-network) would be used. Bug: 151983183 Test: Manual Change-Id: I4affade362644037e649ac6cf93e6871a81058bc --- res/xml/development_settings.xml | 5 + .../DevelopmentSettingsDashboardFragment.java | 1 + ...dMacRandomizationPreferenceController.java | 73 ++++++++++++ ...RandomizationPreferenceControllerTest.java | 105 ++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 src/com/android/settings/development/WifiEnhancedMacRandomizationPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/development/WifiEnhancedMacRandomizationPreferenceControllerTest.java diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml index 48a0850c7ba..7327d219a74 100644 --- a/res/xml/development_settings.xml +++ b/res/xml/development_settings.xml @@ -275,6 +275,11 @@ android:title="@string/wifi_scan_throttling" android:summary="@string/wifi_scan_throttling_summary" /> + + Date: Wed, 1 Apr 2020 11:18:27 +0100 Subject: [PATCH 02/10] Add metrics for the cross profile settings page Also changed the install banner to not say "Tap to install" if the intent to redirect to Play is missing. Bug: 149774826 Test: tested manually that the metrics are being reported by running ./out/host/linux-x86/bin/statsd_testdrive 103 Change-Id: Ieebda237748b5dbff8e974465c5d67b147d92077 --- .../InteractAcrossProfilesDetails.java | 71 +++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java index af055f3392d..ad47c03a90b 100644 --- a/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java +++ b/src/com/android/settings/applications/specialaccess/interactacrossprofiles/InteractAcrossProfilesDetails.java @@ -17,11 +17,13 @@ package com.android.settings.applications.specialaccess.interactacrossprofiles; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE; +import static android.provider.Settings.ACTION_MANAGE_CROSS_PROFILE_ACCESS; import android.Manifest; import android.annotation.UserIdInt; import android.app.ActionBar; import android.app.AppOpsManager; +import android.app.admin.DevicePolicyEventLogger; import android.app.admin.DevicePolicyManager; import android.app.settings.SettingsEnums; import android.content.Context; @@ -37,6 +39,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; import android.os.UserManager; +import android.stats.devicepolicy.DevicePolicyEnums; import android.util.IconDrawableFactory; import android.view.View; import android.widget.ImageView; @@ -60,6 +63,8 @@ public class InteractAcrossProfilesDetails extends AppInfoBase "interact_across_profiles_settings_switch"; private static final String INTERACT_ACROSS_PROFILES_HEADER = "interact_across_profiles_header"; public static final String INSTALL_APP_BANNER_KEY = "install_app_banner"; + public static final String EXTRA_SHOW_FRAGMENT_ARGS = ":settings:show_fragment_args"; + public static final String INTENT_KEY = "intent"; private Context mContext; private CrossProfileApps mCrossProfileApps; @@ -108,6 +113,52 @@ public class InteractAcrossProfilesDetails extends AppInfoBase } addAppTitleAndIcons(mPersonalProfile, mWorkProfile); styleActionBar(); + logPageLaunchMetrics(); + } + + private void logPageLaunchMetrics() { + if (!mCrossProfileApps.canConfigureInteractAcrossProfiles(mPackageName)) { + logNonConfigurableAppMetrics(); + } + Bundle bundle = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGS); + if (bundle == null) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS); + return; + } + Intent intent = (Intent) bundle.get(INTENT_KEY); + if (intent == null) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_SETTINGS); + return; + } + if (ACTION_MANAGE_CROSS_PROFILE_ACCESS.equals(intent.getAction())) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_LAUNCHED_FROM_APP); + } + } + + private void logNonConfigurableAppMetrics() { + if (!isCrossProfilePackageWhitelisted(mPackageName)) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_ADMIN_RESTRICTED); + return; + } + if (mInstallBanner == null) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_INSTALL_BANNER_INTENT); + } + if (!mInstalledInPersonal) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_PERSONAL_APP); + return; + } + if (!mInstalledInWork) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_MISSING_WORK_APP); + } + } + + private void logEvent(int eventId) { + DevicePolicyEventLogger.createEvent(eventId) + .setStrings(mPackageName) + .setInt(UserHandle.myUserId()) + .setAdmin(RestrictedLockUtils.getProfileOrDeviceOwner( + mContext, mWorkProfile).component) + .write(); } private void addAppTitleAndIcons(UserHandle personalProfile, UserHandle workProfile) { @@ -187,6 +238,7 @@ public class InteractAcrossProfilesDetails extends AppInfoBase private void handleSwitchPreferenceClick() { if (isInteractAcrossProfilesEnabled()) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_PERMISSION_REVOKED); enableInteractAcrossProfiles(false); refreshUi(); } else { @@ -220,12 +272,15 @@ public class InteractAcrossProfilesDetails extends AppInfoBase builder.setView(dialogView) .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_USER_CONSENTED); enableInteractAcrossProfiles(true); refreshUi(); } }) .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { + logEvent( + DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_USER_DECLINED_CONSENT); refreshUi(); } }) @@ -277,13 +332,17 @@ public class InteractAcrossProfilesDetails extends AppInfoBase private void handleInstallBannerClick() { if (mInstallAppIntent == null) { + logEvent( + DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_NO_INTENT_CLICKED); return; } if (!mInstalledInWork) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED); mContext.startActivityAsUser(mInstallAppIntent, mWorkProfile); return; } if (!mInstalledInPersonal) { + logEvent(DevicePolicyEnums.CROSS_PROFILE_SETTINGS_PAGE_INSTALL_BANNER_CLICKED); mContext.startActivityAsUser(mInstallAppIntent, mPersonalProfile); } } @@ -333,8 +392,10 @@ public class InteractAcrossProfilesDetails extends AppInfoBase mInstallBanner.setTitle(getString( R.string.interact_across_profiles_install_personal_app_title, mAppLabel)); - mInstallBanner.setSummary( - R.string.interact_across_profiles_install_app_summary); + if (mInstallAppIntent != null) { + mInstallBanner.setSummary( + R.string.interact_across_profiles_install_app_summary); + } mInstallBanner.setVisible(true); return true; } @@ -342,8 +403,10 @@ public class InteractAcrossProfilesDetails extends AppInfoBase mInstallBanner.setTitle(getString( R.string.interact_across_profiles_install_work_app_title, mAppLabel)); - mInstallBanner.setSummary( - R.string.interact_across_profiles_install_app_summary); + if (mInstallAppIntent != null) { + mInstallBanner.setSummary( + R.string.interact_across_profiles_install_app_summary); + } mInstallBanner.setVisible(true); return true; } From 83df54b0072debd0ffa3ec624e4a18267c85e8fe Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Tue, 24 Mar 2020 16:37:57 -0400 Subject: [PATCH 03/10] Added settings screens for Power Menu This CL adds a new Preference in Gestures (Power Menu), moves Global Actions to it (now renamed Cards & passes) and adds a new Preference for Device controls. Missing: * Explanation video for Device controls * Privacy settings Test: robotests Test: manual change settings Bug: 152212779 Bug: 152329723 Change-Id: Ia8f69565307a5961c8435bc1f441abeb389acf8b --- AndroidManifest.xml | 22 ++- res/values/strings.xml | 41 +++--- res/xml/device_controls_settings.xml | 34 +++++ res/xml/gestures.xml | 9 +- res/xml/global_actions_panel_settings.xml | 8 +- res/xml/power_menu_settings.xml | 34 +++++ src/com/android/settings/Settings.java | 2 + .../core/gateway/SettingsGateway.java | 4 + .../DeviceControlsPreferenceController.java | 69 +++++++++ .../gestures/DeviceControlsSettings.java | 48 +++++++ .../PowerMenuPreferenceController.java | 61 ++++++++ .../settings/gestures/PowerMenuSettings.java | 46 ++++++ ...eviceControlsPreferenceControllerTest.java | 87 +++++++++++ .../gestures/DeviceControlsSettingsTest.java | 50 +++++++ .../PowerMenuPreferenceControllerTest.java | 136 ++++++++++++++++++ .../gestures/PowerMenuSettingsTest.java | 50 +++++++ 16 files changed, 670 insertions(+), 31 deletions(-) create mode 100644 res/xml/device_controls_settings.xml create mode 100644 res/xml/power_menu_settings.xml create mode 100644 src/com/android/settings/gestures/DeviceControlsPreferenceController.java create mode 100644 src/com/android/settings/gestures/DeviceControlsSettings.java create mode 100644 src/com/android/settings/gestures/PowerMenuPreferenceController.java create mode 100644 src/com/android/settings/gestures/PowerMenuSettings.java create mode 100644 tests/robotests/src/com/android/settings/gestures/DeviceControlsPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/gestures/DeviceControlsSettingsTest.java create mode 100644 tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java create mode 100644 tests/robotests/src/com/android/settings/gestures/PowerMenuSettingsTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 98789bdc86c..07bc06cf354 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3314,7 +3314,7 @@ + android:label="@string/cards_passes_sentence"> @@ -3323,6 +3323,26 @@ android:value="com.android.settings.gestures.GlobalActionsPanelSettings" /> + + + + + + + + + + + + + + + + work challenge, work, profile work profile, managed profile, unify, unification, work, profile gestures - - global actions + cards, passes + device controls, controls pay, tap, payments backup, back up gesture @@ -10737,13 +10737,6 @@ To check time, notifications, and other info, tap your screen. - - To show the global actions panel, press & hold Power button - - Show global actions - - Global actions - Swipe fingerprint for notifications @@ -11866,11 +11859,11 @@ This choice is no longer valid. Try again. - - Quick controls + + Device controls - - quick controls + + device controls Cards & passes @@ -11887,11 +11880,11 @@ Show cards & passes - - Show quick controls + + Show device controls - - Show cards, passes, and quick controls + + Show cards, passes, and device controls Don\u2019t show any content @@ -11905,11 +11898,17 @@ Hide cards and controls when locked - - Show quick controls + + Show device controls - - To access controls for connected devices, hold the Power button + + Show cards & passes + + + To access controls for connected devices, hold the Power button + + + To access things like your payment methods and boarding passes, press and hold the Power button. diff --git a/res/xml/device_controls_settings.xml b/res/xml/device_controls_settings.xml new file mode 100644 index 00000000000..998b98202c6 --- /dev/null +++ b/res/xml/device_controls_settings.xml @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/res/xml/gestures.xml b/res/xml/gestures.xml index a523ec629b5..ed191ce5282 100644 --- a/res/xml/gestures.xml +++ b/res/xml/gestures.xml @@ -81,9 +81,8 @@ settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" /> - + android:key="gesture_power_menu_summary" + android:title="@string/power_menu_setting_name" + android:fragment="com.android.settings.gestures.PowerMenuSettings" + settings:controller="com.android.settings.gestures.PowerMenuPreferenceController" /> diff --git a/res/xml/global_actions_panel_settings.xml b/res/xml/global_actions_panel_settings.xml index 3b7bef3f57e..980c75681d9 100644 --- a/res/xml/global_actions_panel_settings.xml +++ b/res/xml/global_actions_panel_settings.xml @@ -18,7 +18,7 @@ + android:title="@string/cards_passes_sentence"> diff --git a/res/xml/power_menu_settings.xml b/res/xml/power_menu_settings.xml new file mode 100644 index 00000000000..453a7e6a1f8 --- /dev/null +++ b/res/xml/power_menu_settings.xml @@ -0,0 +1,34 @@ + + + + + + + + + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index d25d7e9dd24..f5494faa8ee 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -218,6 +218,8 @@ public class Settings extends SettingsActivity { public static class WifiCallingDisclaimerActivity extends SettingsActivity { /* empty */ } public static class MobileNetworkListActivity extends SettingsActivity {} public static class GlobalActionsPanelSettingsActivity extends SettingsActivity {} + public static class PowerMenuSettingsActivity extends SettingsActivity {} + public static class QuickControlsSettingsActivity extends SettingsActivity {} /** * Activity for BugReportHandlerPicker. */ diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index 8c49e580c06..fea32cf8512 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -88,12 +88,14 @@ import com.android.settings.fuelgauge.PowerUsageSummary; import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleSettings; import com.android.settings.fuelgauge.batterysaver.BatterySaverSettings; import com.android.settings.gestures.AssistGestureSettings; +import com.android.settings.gestures.DeviceControlsSettings; import com.android.settings.gestures.DoubleTapPowerSettings; import com.android.settings.gestures.DoubleTapScreenSettings; import com.android.settings.gestures.DoubleTwistGestureSettings; import com.android.settings.gestures.GestureNavigationSettingsFragment; import com.android.settings.gestures.GlobalActionsPanelSettings; import com.android.settings.gestures.PickupGestureSettings; +import com.android.settings.gestures.PowerMenuSettings; import com.android.settings.gestures.SwipeToNotificationSettings; import com.android.settings.gestures.SystemNavigationGestureSettings; import com.android.settings.inputmethod.AvailableVirtualKeyboardFragment; @@ -294,7 +296,9 @@ public class SettingsGateway { PreviouslyConnectedDeviceDashboardFragment.class.getName(), BatterySaverScheduleSettings.class.getName(), MobileNetworkListFragment.class.getName(), + PowerMenuSettings.class.getName(), GlobalActionsPanelSettings.class.getName(), + DeviceControlsSettings.class.getName(), DarkModeSettingsFragment.class.getName(), BugReportHandlerPicker.class.getName(), GestureNavigationSettingsFragment.class.getName(), diff --git a/src/com/android/settings/gestures/DeviceControlsPreferenceController.java b/src/com/android/settings/gestures/DeviceControlsPreferenceController.java new file mode 100644 index 00000000000..e588e86354d --- /dev/null +++ b/src/com/android/settings/gestures/DeviceControlsPreferenceController.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import android.content.Context; +import android.provider.Settings; +import android.text.TextUtils; + +import com.android.internal.annotations.VisibleForTesting; + +public class DeviceControlsPreferenceController extends GesturePreferenceController { + private static final String PREF_KEY_VIDEO = "device_controls_video"; + + @VisibleForTesting + protected static final String ENABLED_SETTING = Settings.Secure.CONTROLS_ENABLED; + + @VisibleForTesting + protected static final String TOGGLE_KEY = "gesture_device_controls_switch"; + + public DeviceControlsPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public boolean setChecked(boolean isChecked) { + return Settings.Secure.putInt(mContext.getContentResolver(), ENABLED_SETTING, + isChecked ? 1 : 0); + } + + @Override + protected String getVideoPrefKey() { + return PREF_KEY_VIDEO; + } + + @Override + public boolean isSliceable() { + return TextUtils.equals(getPreferenceKey(), TOGGLE_KEY); + } + + @Override + public boolean isPublicSlice() { + return true; + } + + @Override + public boolean isChecked() { + int enabled = Settings.Secure.getInt(mContext.getContentResolver(), ENABLED_SETTING, 1); + return enabled == 1; + } +} diff --git a/src/com/android/settings/gestures/DeviceControlsSettings.java b/src/com/android/settings/gestures/DeviceControlsSettings.java new file mode 100644 index 00000000000..df36717cb0b --- /dev/null +++ b/src/com/android/settings/gestures/DeviceControlsSettings.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import android.app.settings.SettingsEnums; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; +import com.android.settingslib.search.SearchIndexable; + +@SearchIndexable +public class DeviceControlsSettings extends DashboardFragment { + + private static final String TAG = "QuickControlsSettings"; + + @Override + public int getMetricsCategory() { + return SettingsEnums.DEVICE_CONTROLS_SETTINGS; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + protected int getPreferenceScreenResId() { + return R.xml.device_controls_settings; + } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.device_controls_settings); +} diff --git a/src/com/android/settings/gestures/PowerMenuPreferenceController.java b/src/com/android/settings/gestures/PowerMenuPreferenceController.java new file mode 100644 index 00000000000..e65d140dbdb --- /dev/null +++ b/src/com/android/settings/gestures/PowerMenuPreferenceController.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +public class PowerMenuPreferenceController extends BasePreferenceController { + + private static final String KEY = "gesture_power_menu_summary"; + private static final String CONTROLS_ENABLED_SETTING = Settings.Secure.CONTROLS_ENABLED; + private static final String CARDS_ENABLED_SETTING = + Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED; + private static final String CARDS_AVAILABLE_SETTING = + Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE; + + public PowerMenuPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + public CharSequence getSummary() { + boolean controlsEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + CONTROLS_ENABLED_SETTING, 1) == 1; + boolean cardsEnabled = Settings.Secure.getInt(mContext.getContentResolver(), + CARDS_ENABLED_SETTING, 0) == 1; + boolean cardsVisible = cardsEnabled && Settings.Secure.getInt(mContext.getContentResolver(), + CARDS_AVAILABLE_SETTING, 0) == 1; + if (controlsEnabled && cardsVisible) { + return mContext.getText(R.string.power_menu_cards_passes_device_controls); + } else if (controlsEnabled) { + return mContext.getText(R.string.power_menu_device_controls); + } else if (cardsVisible) { + return mContext.getText(R.string.power_menu_cards_passes); + } else { + return mContext.getText(R.string.power_menu_none); + } + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } +} diff --git a/src/com/android/settings/gestures/PowerMenuSettings.java b/src/com/android/settings/gestures/PowerMenuSettings.java new file mode 100644 index 00000000000..3b4c5c31f74 --- /dev/null +++ b/src/com/android/settings/gestures/PowerMenuSettings.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import android.app.settings.SettingsEnums; + +import com.android.settings.R; +import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.search.BaseSearchIndexProvider; + +public class PowerMenuSettings extends DashboardFragment { + + private static final String TAG = "PowerMenuSettings"; + + @Override + protected int getPreferenceScreenResId() { + return R.xml.power_menu_settings; + } + + @Override + protected String getLogTag() { + return TAG; + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.POWER_MENU_SETTINGS; + } + + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = + new BaseSearchIndexProvider(R.xml.power_menu_settings); +} diff --git a/tests/robotests/src/com/android/settings/gestures/DeviceControlsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/DeviceControlsPreferenceControllerTest.java new file mode 100644 index 00000000000..c31971a991b --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DeviceControlsPreferenceControllerTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class DeviceControlsPreferenceControllerTest { + + private Context mContext; + private DeviceControlsPreferenceController mController; + + private static final String KEY_GESTURE_PANEL = "gesture_device_controls"; + private static final String ENABLED_SETTING = + DeviceControlsPreferenceController.ENABLED_SETTING; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mController = new DeviceControlsPreferenceController(mContext, KEY_GESTURE_PANEL); + } + + @Test + public void testIsChecked_panelEnabled() { + Settings.Secure.putInt( + mContext.getContentResolver(), ENABLED_SETTING, 1); + assertThat(mController.isChecked()).isTrue(); + } + + @Test + public void testIsChecked_panelDisabled() { + Settings.Secure.putInt( + mContext.getContentResolver(), ENABLED_SETTING, 0); + assertThat(mController.isChecked()).isFalse(); + } + + @Test + public void getAvailabilityStatus_panelAvailable() { + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(BasePreferenceController.AVAILABLE); + } + + @Test + public void isSliceable_correctKey() { + final DeviceControlsPreferenceController controller = + new DeviceControlsPreferenceController(mContext, + DeviceControlsPreferenceController.TOGGLE_KEY); + assertThat(controller.isSliceable()).isTrue(); + } + + @Test + public void isSliceable_incorrectKey() { + final DeviceControlsPreferenceController controller = + new DeviceControlsPreferenceController(mContext, "bad_key"); + assertThat(controller.isSliceable()).isFalse(); + } + + @Test + public void isPublicSlice_returnTrue() { + assertThat(mController.isPublicSlice()).isTrue(); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/DeviceControlsSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/DeviceControlsSettingsTest.java new file mode 100644 index 00000000000..2ec0f1d1602 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/DeviceControlsSettingsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.provider.SearchIndexableResource; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +public class DeviceControlsSettingsTest { + + private DeviceControlsSettings mSettings; + + @Before + public void setUp() { + mSettings = new DeviceControlsSettings(); + } + + @Test + public void testSearchIndexProvider_shouldIndexResource() { + final List indexRes = + DeviceControlsSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( + RuntimeEnvironment.application, true /* enabled */); + + assertThat(indexRes).isNotNull(); + assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId()); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java new file mode 100644 index 00000000000..e14293eb82a --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/PowerMenuPreferenceControllerTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public class PowerMenuPreferenceControllerTest { + private Context mContext; + private PowerMenuPreferenceController mController; + + private static final String KEY_GESTURE_POWER_MENU = "gesture_power_menu"; + private static final String CONTROLS_ENABLED = Settings.Secure.CONTROLS_ENABLED; + private static final String CARDS_ENABLED = Settings.Secure.GLOBAL_ACTIONS_PANEL_ENABLED; + private static final String CARDS_AVAILABLE = Settings.Secure.GLOBAL_ACTIONS_PANEL_AVAILABLE; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + mController = new PowerMenuPreferenceController(mContext, KEY_GESTURE_POWER_MENU); + } + + @Test + public void getAvailabilityStatus_available() { + assertThat(mController.getAvailabilityStatus()).isEqualTo( + BasePreferenceController.AVAILABLE); + } + + @Test + public void getSummary_allDisabled() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_none)); + } + + @Test + public void getSummary_onlyControlsEnabled() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_device_controls)); + } + + @Test + public void getSummary_onlyCardsEnabled_notAvailable() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_none)); + } + + @Test + public void getSummary_cardsAvailable_notEnabled() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_none)); + } + + @Test + public void getSummary_allEnabled_cardsNotAvailable() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 0); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_device_controls)); + } + + @Test + public void getSummary_controlsEnabled_cardsDisabledAvailable() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_device_controls)); + } + + @Test + public void getSummary_controlsDisabled() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 0); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_cards_passes)); + } + + @Test + public void getSummary_allEnabled() { + Settings.Secure.putInt(mContext.getContentResolver(), CONTROLS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_ENABLED, 1); + Settings.Secure.putInt(mContext.getContentResolver(), CARDS_AVAILABLE, 1); + + assertThat(mController.getSummary()) + .isEqualTo(mContext.getText(R.string.power_menu_cards_passes_device_controls)); + } +} diff --git a/tests/robotests/src/com/android/settings/gestures/PowerMenuSettingsTest.java b/tests/robotests/src/com/android/settings/gestures/PowerMenuSettingsTest.java new file mode 100644 index 00000000000..4448ee38e12 --- /dev/null +++ b/tests/robotests/src/com/android/settings/gestures/PowerMenuSettingsTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.gestures; + +import static com.google.common.truth.Truth.assertThat; + +import android.provider.SearchIndexableResource; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +import java.util.List; + +@RunWith(RobolectricTestRunner.class) +public class PowerMenuSettingsTest { + + private PowerMenuSettings mSettings; + + @Before + public void setUp() { + mSettings = new PowerMenuSettings(); + } + + @Test + public void testSearchIndexProvider_shouldIndexResource() { + final List indexRes = + PowerMenuSettings.SEARCH_INDEX_DATA_PROVIDER.getXmlResourcesToIndex( + RuntimeEnvironment.application, true /* enabled */); + + assertThat(indexRes).isNotNull(); + assertThat(indexRes.get(0).xmlResId).isEqualTo(mSettings.getPreferenceScreenResId()); + } +} From a971c458badcdafa5db85cdfc35c3b2aa5215d9d Mon Sep 17 00:00:00 2001 From: calvinpan Date: Wed, 8 Apr 2020 16:58:56 +0800 Subject: [PATCH 04/10] Check is5gEntryDisplayed in NETWORK_MODE_LTE_GSM_WCDMA mode Add is5gEntryDisplayed() check in in NETWORK_MODE_LTE_GSM_WCDMA mode to prevent that show "LTE(recommand)" everytime. Bug: 153301072 Test: By manual 1. Reproduce issue 2. Verify the patch Change-Id: I96311a1e399efd160a3f7290f85df778b2d6f0c4 --- .../EnabledNetworkModePreferenceController.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java index 948eecaa5c2..d2ff6e8e4ae 100644 --- a/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java +++ b/src/com/android/settings/network/telephony/EnabledNetworkModePreferenceController.java @@ -398,8 +398,13 @@ public class EnabledNetworkModePreferenceController extends if (!mIsGlobalCdma) { setSelectedEntry( TelephonyManagerConstants.NETWORK_MODE_LTE_GSM_WCDMA); - setSummary( - mShow4gForLTE ? R.string.network_4G : R.string.network_lte); + if (is5gEntryDisplayed()) { + setSummary(mShow4gForLTE + ? R.string.network_4G_pure : R.string.network_lte_pure); + } else { + setSummary(mShow4gForLTE + ? R.string.network_4G : R.string.network_lte); + } } else { setSelectedEntry( TelephonyManagerConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA); @@ -542,6 +547,7 @@ public class EnabledNetworkModePreferenceController extends mEntriesValue.add(value); mIs5gEntryDisplayed = true; } else { + mIs5gEntryDisplayed = false; Log.d(LOG_TAG, "Hide 5G option. " + " supported5GRadioAccessFamily: " + mSupported5gRadioAccessFamily + " allowed5GNetworkType: " + mAllowed5gNetworkType From 3bd20b6bc9a8d399b8903e11c752f24cecaa87f0 Mon Sep 17 00:00:00 2001 From: Benedict Wong Date: Wed, 8 Apr 2020 19:41:56 +0000 Subject: [PATCH 05/10] Fix VPN settings UI to validate IPsec Identifier This change ensures that the updateUiControls() (and validate() transitively) is called whenever the IPsec identifier is updated. Bug: 152811464 Test: Manual testing with settings UI Change-Id: I6536652a60244c3fde3f65211f9d0709145c6cd9 Merged-In: I6536652a60244c3fde3f65211f9d0709145c6cd9 (cherry picked from commit e56ae928c301be6b5a21ef03a8d8cce72f3ec2de) --- src/com/android/settings/vpn2/ConfigDialog.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java index a0aac19794d..4e6cc893b8e 100644 --- a/src/com/android/settings/vpn2/ConfigDialog.java +++ b/src/com/android/settings/vpn2/ConfigDialog.java @@ -173,6 +173,7 @@ class ConfigDialog extends AlertDialog implements TextWatcher, mProxySettings.setOnItemSelectedListener(this); mProxyHost.addTextChangedListener(this); mProxyPort.addTextChangedListener(this); + mIpsecIdentifier.addTextChangedListener(this); mIpsecSecret.addTextChangedListener(this); mIpsecUserCert.setOnItemSelectedListener(this); mShowOptions.setOnClickListener(this); From 98c17ee49ffe9a8941075eb52f4ca09e7147e322 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 9 Apr 2020 15:22:26 +0800 Subject: [PATCH 06/10] [A11Y][Wi-Fi] Fix multiple Spinner selected speak out at once. When users select edit a Wi-Fi and select enterprise security, there are multiple spinner shows with a default value. This change does not allow TalkBack to speak out for multiple Spinner text at one user selection. Bug: 153272108 Test: manual Wi-Fi Settings -> Add network -> Security spinner -> WPA/WPA2/WPA3-Enterprise TalkBack should only speak out for the Security spinner. Change-Id: Id9ab44e4da6d7abb5168e0ab7441ee1e226f5f68 --- .../settings/wifi/WifiConfigController.java | 23 +++++++++++++++++++ .../settings/wifi/WifiConfigController2.java | 23 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java index 54026a5671c..66b9a230ba2 100644 --- a/src/com/android/settings/wifi/WifiConfigController.java +++ b/src/com/android/settings/wifi/WifiConfigController.java @@ -48,6 +48,7 @@ import android.view.KeyEvent; import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.inputmethod.EditorInfo; @@ -1020,6 +1021,8 @@ public class WifiConfigController implements TextWatcher, mEapUserCertSpinner.setOnItemSelectedListener(this); mEapIdentityView = (TextView) mView.findViewById(R.id.identity); mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous); + + setAccessibilityDelegateForSecuritySpinners(); } if (refreshEapMethods) { @@ -1148,6 +1151,26 @@ public class WifiConfigController implements TextWatcher, } } + private void setAccessibilityDelegateForSecuritySpinners() { + final AccessibilityDelegate selectedEventBlocker = new AccessibilityDelegate() { + @Override + public void sendAccessibilityEvent(View host, int eventType) { + if (eventType == AccessibilityEvent.TYPE_VIEW_SELECTED) { + // Ignore TYPE_VIEW_SELECTED or there will be multiple Spinner selected + // information for WifiController#showSecurityFields. + return; + } + super.sendAccessibilityEvent(host, eventType); + } + }; + + mEapMethodSpinner.setAccessibilityDelegate(selectedEventBlocker); + mPhase2Spinner.setAccessibilityDelegate(selectedEventBlocker); + mEapCaCertSpinner.setAccessibilityDelegate(selectedEventBlocker); + mEapOcspSpinner.setAccessibilityDelegate(selectedEventBlocker); + mEapUserCertSpinner.setAccessibilityDelegate(selectedEventBlocker); + } + /** * EAP-PWD valid fields include * identity diff --git a/src/com/android/settings/wifi/WifiConfigController2.java b/src/com/android/settings/wifi/WifiConfigController2.java index 4df0dfdc84e..ce0516d6f4d 100644 --- a/src/com/android/settings/wifi/WifiConfigController2.java +++ b/src/com/android/settings/wifi/WifiConfigController2.java @@ -46,6 +46,7 @@ import android.view.KeyEvent; import android.view.View; import android.view.View.AccessibilityDelegate; import android.view.ViewGroup; +import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.inputmethod.EditorInfo; @@ -1014,6 +1015,8 @@ public class WifiConfigController2 implements TextWatcher, mEapUserCertSpinner.setOnItemSelectedListener(this); mEapIdentityView = (TextView) mView.findViewById(R.id.identity); mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous); + + setAccessibilityDelegateForSecuritySpinners(); } if (refreshEapMethods) { @@ -1144,6 +1147,26 @@ public class WifiConfigController2 implements TextWatcher, } } + private void setAccessibilityDelegateForSecuritySpinners() { + final AccessibilityDelegate selectedEventBlocker = new AccessibilityDelegate() { + @Override + public void sendAccessibilityEvent(View host, int eventType) { + if (eventType == AccessibilityEvent.TYPE_VIEW_SELECTED) { + // Ignore TYPE_VIEW_SELECTED or there will be multiple Spinner selected + // information for WifiController2#showSecurityFields. + return; + } + super.sendAccessibilityEvent(host, eventType); + } + }; + + mEapMethodSpinner.setAccessibilityDelegate(selectedEventBlocker); + mPhase2Spinner.setAccessibilityDelegate(selectedEventBlocker); + mEapCaCertSpinner.setAccessibilityDelegate(selectedEventBlocker); + mEapOcspSpinner.setAccessibilityDelegate(selectedEventBlocker); + mEapUserCertSpinner.setAccessibilityDelegate(selectedEventBlocker); + } + /** * EAP-PWD valid fields include * identity From aa6b25e1379cbbfd75e1da326ba2504f3271f8d0 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Thu, 9 Apr 2020 16:51:10 +0800 Subject: [PATCH 07/10] [A11Y][Wi-Fi] Prevent data usage header spinner speak at onResume Ignore AccessibilityEvent.TYPE_VIEW_SELECTED for the Spinner. Bug: 146818854 Test: manual Should not speak for header spinner right after entering 'Wi-Fi data usage' Change-Id: I289d9a781242f8bfec56c59b7be2ac0688c5e485 --- .../android/settings/datausage/DataUsageList.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/com/android/settings/datausage/DataUsageList.java b/src/com/android/settings/datausage/DataUsageList.java index 8db32e9eb19..7f1a0d8252d 100644 --- a/src/com/android/settings/datausage/DataUsageList.java +++ b/src/com/android/settings/datausage/DataUsageList.java @@ -42,6 +42,8 @@ import android.telephony.SubscriptionManager; import android.util.Log; import android.util.SparseArray; import android.view.View; +import android.view.View.AccessibilityDelegate; +import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ImageView; @@ -180,6 +182,16 @@ public class DataUsageList extends DataUsageBaseFragment mCycleSpinner.setSelection(position); } }, mCycleListener); + mCycleSpinner.setAccessibilityDelegate(new AccessibilityDelegate() { + @Override + public void sendAccessibilityEvent(View host, int eventType) { + if (eventType == AccessibilityEvent.TYPE_VIEW_SELECTED) { + // Ignore TYPE_VIEW_SELECTED or TalkBack will speak for it at onResume. + return; + } + super.sendAccessibilityEvent(host, eventType); + } + }); mLoadingViewController = new LoadingViewController( getView().findViewById(R.id.loading_container), getListView()); From 6684c5c4f82b2936c598fffc163d5098a222ae8b Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Thu, 9 Apr 2020 12:22:01 +0100 Subject: [PATCH 08/10] Remove unused file. Bug: 149075700 Test: compiles Change-Id: Iaa50a96107ca9cb4419875e4067e61a8f5d093e5 --- res/layout/user_limits.xml | 55 -------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 res/layout/user_limits.xml diff --git a/res/layout/user_limits.xml b/res/layout/user_limits.xml deleted file mode 100644 index b242f0e9c1c..00000000000 --- a/res/layout/user_limits.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - -