From d9ecc3ae9a982ae70a27b866734b127c8e2c72c5 Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Mon, 29 Apr 2019 17:50:35 -0700 Subject: [PATCH 01/27] Update dialog text for untethered BT device Fixes: 122672631 Test: RunSettingsRoboTests Change-Id: I380308acbb7025461ef34aeec68e535189714bf3 --- res/values/strings.xml | 3 + .../bluetooth/ForgetDeviceDialogFragment.java | 8 ++- .../ForgetDeviceDialogFragmentTest.java | 57 ++++++++++++++++++- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 959a72f1e31..ee3c5d34a70 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1786,6 +1786,9 @@ Your device will no longer be paired with %1$s + + %1$s will no longer be paired with any device linked to this account + Forget device diff --git a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java index db6b8325a29..6d8fb3380e1 100644 --- a/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java +++ b/src/com/android/settings/bluetooth/ForgetDeviceDialogFragment.java @@ -29,6 +29,7 @@ import androidx.appcompat.app.AlertDialog; import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; @@ -72,13 +73,18 @@ public class ForgetDeviceDialogFragment extends InstrumentedDialogFragment { }; Context context = getContext(); mDevice = getDevice(context); + final boolean untetheredHeadset = BluetoothUtils.getBooleanMetaData( + mDevice.getDevice(), BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET); + AlertDialog dialog = new AlertDialog.Builder(context) .setPositiveButton(R.string.bluetooth_unpair_dialog_forget_confirm_button, onConfirm) .setNegativeButton(android.R.string.cancel, null) .create(); dialog.setTitle(R.string.bluetooth_unpair_dialog_title); - dialog.setMessage(context.getString(R.string.bluetooth_unpair_dialog_body, + dialog.setMessage(context.getString(untetheredHeadset + ? R.string.bluetooth_untethered_unpair_dialog_body + : R.string.bluetooth_unpair_dialog_body, mDevice.getName())); return dialog; } diff --git a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java index 44ffa5494a2..b4f4f97f228 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/ForgetDeviceDialogFragmentTest.java @@ -25,10 +25,15 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothDevice; +import android.content.Context; + import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentActivity; +import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import org.junit.Before; @@ -39,33 +44,46 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowDialog; +import org.robolectric.shadows.androidx.fragment.FragmentController; @RunWith(RobolectricTestRunner.class) +@Config(shadows = {ShadowAlertDialogCompat.class}) public class ForgetDeviceDialogFragmentTest { + private static final String DEVICE_NAME = "Nightshade"; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) private CachedBluetoothDevice mCachedDevice; + @Mock + private BluetoothDevice mBluetoothDevice; private ForgetDeviceDialogFragment mFragment; private FragmentActivity mActivity; private AlertDialog mDialog; + private Context mContext; @Before public void setUp() { MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; FakeFeatureFactory.setupForTest(); String deviceAddress = "55:66:77:88:99:AA"; when(mCachedDevice.getAddress()).thenReturn(deviceAddress); + when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); + when(mCachedDevice.getName()).thenReturn(DEVICE_NAME); mFragment = spy(ForgetDeviceDialogFragment.newInstance(deviceAddress)); doReturn(mCachedDevice).when(mFragment).getDevice(any()); mActivity = Robolectric.setupActivity(FragmentActivity.class); - mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commit(); - mDialog = (AlertDialog) ShadowDialog.getLatestDialog(); } @Test public void cancelDialog() { + initDialog(); + mDialog.getButton(AlertDialog.BUTTON_NEGATIVE).performClick(); verify(mCachedDevice, never()).unpair(); assertThat(mActivity.isFinishing()).isFalse(); @@ -73,8 +91,43 @@ public class ForgetDeviceDialogFragmentTest { @Test public void confirmDialog() { + initDialog(); + mDialog.getButton(AlertDialog.BUTTON_POSITIVE).performClick(); verify(mCachedDevice).unpair(); assertThat(mActivity.isFinishing()).isTrue(); } + + @Test + public void createDialog_untetheredDevice_showUntetheredMessage() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) + .thenReturn("true".getBytes()); + + FragmentController.setupFragment(mFragment, FragmentActivity.class, + 0 /* containerViewId */, null /* bundle */); + final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog); + + assertThat(shadowDialog.getMessage()).isEqualTo( + mContext.getString(R.string.bluetooth_untethered_unpair_dialog_body, DEVICE_NAME)); + } + + @Test + public void createDialog_normalDevice_showNormalMessage() { + when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET)) + .thenReturn("false".getBytes()); + + FragmentController.setupFragment(mFragment, FragmentActivity.class, + 0 /* containerViewId */, null /* bundle */); + final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog(); + ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog); + + assertThat(shadowDialog.getMessage()).isEqualTo( + mContext.getString(R.string.bluetooth_unpair_dialog_body, DEVICE_NAME)); + } + + private void initDialog() { + mActivity.getSupportFragmentManager().beginTransaction().add(mFragment, null).commit(); + mDialog = (AlertDialog) ShadowDialog.getLatestDialog(); + } } From fe488a9ea404cd01faa973bd67ed1590a30782fb Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Wed, 1 May 2019 16:08:06 -0400 Subject: [PATCH 02/27] Adding strings for themepicker suggestion Bug: 126230901 Test: mp settingsg Change-Id: I2c94c455fedb0503f3f8a3e93dcdbbedb927c69b --- res/values/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index 938c72f4de0..373da53330d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2888,6 +2888,10 @@ Personalize your screen Choose wallpaper from + + Customize your Pixel + + Try different styles, wallpapers, clocks, and more Screen saver From 5eaa4a84bd0c77fb96beef2dbe6bc4c3dedf80a1 Mon Sep 17 00:00:00 2001 From: lindatseng Date: Wed, 1 May 2019 15:20:38 -0700 Subject: [PATCH 03/27] Update Settings owners Test: rebuild Fixes: 131782410 Change-Id: I9f2b399efcd6b784325fcef66bde45a01417e5e8 --- OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OWNERS b/OWNERS index bed20a966af..ccf8e813739 100644 --- a/OWNERS +++ b/OWNERS @@ -6,10 +6,10 @@ asapperstein@google.com asargent@google.com dehboxturtle@google.com dhnishi@google.com -dling@google.com edgarwang@google.com emilychuang@google.com jackqdyulei@google.com +lindatseng@google.com mfritze@google.com rafftsai@google.com tmfang@google.com From 95176da5d2eed859251a4fd1c5f0aa18e0b293ba Mon Sep 17 00:00:00 2001 From: cosmohsieh Date: Thu, 2 May 2019 09:51:42 +0800 Subject: [PATCH 04/27] [PasspointV2] Fix lint error Lint error ... "Missing mandatory plural message forms: =1." Add case one for plural string to prevent lint error, even though this case should not happened. Bug: 131688045 Test: manual Change-Id: I1087b26495c71a6d167d7eaee1359d39c81cc59f --- res/values/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 83b622ffc78..cf624726983 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2317,8 +2317,9 @@ 1 subscription %d subscriptions - + + 1 network & subscription %d networks & subscriptions From 0dde3a3b345509a9c031c0981dd3705a03049d18 Mon Sep 17 00:00:00 2001 From: timpeng Date: Fri, 12 Apr 2019 16:53:56 +0800 Subject: [PATCH 05/27] [Fix] prevent Talkback from reading out Bluetooth ImageView ContentDescription - set View.IMPORTANT_FOR_ACCESSIBILITY_NO to ImageView Bug: 128396030 Test: RunSettingsRoboTests Change-Id: I267921057ede734a3c9be7087f34c96631e04859 --- .../android/settings/bluetooth/BluetoothDevicePreference.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java index ec5381c1c9f..74d3b6a0594 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePreference.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePreference.java @@ -29,6 +29,7 @@ import android.text.Html; import android.text.TextUtils; import android.util.Pair; import android.util.TypedValue; +import android.view.View; import android.widget.ImageView; import androidx.annotation.VisibleForTesting; @@ -170,6 +171,8 @@ public final class BluetoothDevicePreference extends GearPreference implements final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); if (imageView != null) { imageView.setContentDescription(contentDescription); + // Set property to prevent Talkback from reading out. + imageView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); imageView.setElevation( getContext().getResources().getDimension(R.dimen.bt_icon_elevation)); } From 35eef604a351215ccc35c301e010f546dfb306b9 Mon Sep 17 00:00:00 2001 From: Michael Wachenschwanz Date: Thu, 25 Apr 2019 16:07:39 -0700 Subject: [PATCH 06/27] Simplify user flow for setting default supervisor as PO A follow up CL will clean up and separate the DeviceAdminAdd and ProfileOwnerAdd logic (see b/131713071) Bug: 124066840 Test: manual (overlay config_defaultSupervisionProfileOwnerComponent and confirm only that component can be set as profile owner after setup is complete) Test: manual (install CtsVerifier, adb shell am start -n "com.android.cts.verifier/.admin.tapjacking.OverlayingActivity", user should not be able to click the "Allow" button) Change-Id: Iccd931801145719110ce75421c35db80ea651779 --- AndroidManifest.xml | 13 ++-- res/layout/profile_owner_add.xml | 38 ++++++++++ res/values/strings.xml | 5 ++ .../deviceadmin/DeviceAdminAdd.java | 76 +++++++++++++++---- .../deviceadmin/ProfileOwnerAdd.java | 31 ++++++++ 5 files changed, 141 insertions(+), 22 deletions(-) create mode 100644 res/layout/profile_owner_add.xml create mode 100644 src/com/android/settings/applications/specialaccess/deviceadmin/ProfileOwnerAdd.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9dd4732072f..ef8e76160e4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1333,22 +1333,23 @@ + android:label="@string/device_admin_add_title" + android:clearTaskOnLaunch="true"> - + - + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 615077c6c13..85cde7b7d1b 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6019,6 +6019,9 @@ Activating this admin app will allow the app %1$s to perform the following operations: + + This device will be managed and monitored by + %1$s. This admin app is active and allows the app %1$s to perform the @@ -6026,6 +6029,8 @@ Activate Profile Manager? + + Allow supervision? By proceeding, your user will be managed by your admin which may also be able to store associated data, in addition to your personal diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java index 7e0ca242b36..0d0bd2016c5 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java @@ -46,6 +46,7 @@ import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; import android.text.TextUtils.TruncateAt; +import android.text.method.ScrollingMovementMethod; import android.util.EventLog; import android.util.Log; import android.view.Display; @@ -273,15 +274,63 @@ public class DeviceAdminAdd extends Activity { } } - // If we're trying to add a profile owner and user setup hasn't completed yet, no - // need to prompt for permission. Just add and finish. - if (mAddingProfileOwner && !mDPM.hasUserSetupCompleted()) { - addAndFinish(); - return; - } - mAddMsgText = getIntent().getCharSequenceExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION); + if (mAddingProfileOwner) { + // If we're trying to add a profile owner and user setup hasn't completed yet, no + // need to prompt for permission. Just add and finish + if (!mDPM.hasUserSetupCompleted()) { + addAndFinish(); + return; + } + + // othewise, only the defined default supervision profile owner can be set after user + // setup. + final String supervisor = getString( + com.android.internal.R.string.config_defaultSupervisionProfileOwnerComponent); + if (supervisor == null) { + Log.w(TAG, "Unable to set profile owner post-setup, no default supervisor" + + "profile owner defined"); + finish(); + return; + } + + final ComponentName supervisorComponent = ComponentName.unflattenFromString( + supervisor); + if (who.compareTo(supervisorComponent) != 0) { + Log.w(TAG, "Unable to set non-default profile owner post-setup " + who); + finish(); + return; + } + + // Build and show the simplified dialog + final Dialog dialog = new AlertDialog.Builder(this) + .setTitle(getText(R.string.profile_owner_add_title_simplified)) + .setView(R.layout.profile_owner_add) + .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + addAndFinish(); + } + }) + .setNeutralButton(R.string.cancel, null) + .setOnDismissListener(new DialogInterface.OnDismissListener() { + public void onDismiss(DialogInterface dialogInterface) { + finish(); + } + }) + .create(); + dialog.show(); + + mActionButton = ((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE); + mActionButton.setFilterTouchesWhenObscured(true); + mAddMsg = dialog.findViewById(R.id.add_msg_simplified); + mAddMsg.setMovementMethod(new ScrollingMovementMethod()); + mAddMsg.setText(mAddMsgText); + mAdminWarning = dialog.findViewById(R.id.admin_warning_simplified); + mAdminWarning.setText(getString(R.string.device_admin_warning_simplified, + mProfileOwnerName)); + return; + } setContentView(R.layout.device_admin_add); mAdminIcon = (ImageView)findViewById(R.id.admin_icon); @@ -501,7 +550,9 @@ public class DeviceAdminAdd extends Activity { protected void onResume() { super.onResume(); mActionButton.setEnabled(true); - updateInterface(); + if (!mAddingProfileOwner) { + updateInterface(); + } // As long as we are running, don't let anyone overlay stuff on top of the screen. mAppOps.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, true, mToken); mAppOps.setUserRestriction(AppOpsManager.OP_TOAST_WINDOW, true, mToken); @@ -571,9 +622,6 @@ public class DeviceAdminAdd extends Activity { } catch (Resources.NotFoundException e) { mAdminDescription.setVisibility(View.GONE); } - if (mAddingProfileOwner) { - mProfileOwnerWarning.setVisibility(View.VISIBLE); - } if (mAddMsgText != null) { mAddMsg.setText(mAddMsgText); mAddMsg.setVisibility(View.VISIBLE); @@ -634,11 +682,7 @@ public class DeviceAdminAdd extends Activity { addDeviceAdminPolicies(true /* showDescription */); mAdminWarning.setText(getString(R.string.device_admin_warning, mDeviceAdmin.getActivityInfo().applicationInfo.loadLabel(getPackageManager()))); - if (mAddingProfileOwner) { - setTitle(getText(R.string.profile_owner_add_title)); - } else { - setTitle(getText(R.string.add_device_admin_msg)); - } + setTitle(getText(R.string.add_device_admin_msg)); mActionButton.setText(getText(R.string.add_device_admin)); if (isAdminUninstallable()) { mUninstallButton.setVisibility(View.VISIBLE); diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/ProfileOwnerAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/ProfileOwnerAdd.java new file mode 100644 index 00000000000..6841ea491fa --- /dev/null +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/ProfileOwnerAdd.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.applications.specialaccess.deviceadmin; + +import android.os.Bundle; + +/** + * ProfileOwnerAdd uses the DeviceAdminAdd logic to handle SET_PROFILE_OWNER intents + * + * TODO(b/131713071): Move profile owner add logic from DeviceAdminAdd to here + */ +public class ProfileOwnerAdd extends DeviceAdminAdd { + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + } +} From 1da7fbb09dbfc9546d59cb7e38b0429fb868d9a2 Mon Sep 17 00:00:00 2001 From: yuanjiahsu Date: Tue, 30 Apr 2019 18:44:15 +0800 Subject: [PATCH 07/27] Clean Safetyhub feature flag from Settings. Clean all related code, need submit together. Test: Manually Bug: 118848485 Change-Id: Icaa0c0736dfa4a7d96aba396a884c9d3383a0f22 --- .../EmergencyInfoPreferenceController.java | 21 ++++--------------- .../deviceinfo/EmergencyInfoSlice.java | 5 ++--- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java index 7dc80d025c2..5be829b8370 100644 --- a/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java +++ b/src/com/android/settings/accounts/EmergencyInfoPreferenceController.java @@ -23,7 +23,6 @@ import android.content.res.Resources; import android.os.UserHandle; import android.os.UserManager; import android.text.TextUtils; -import android.util.FeatureFlagUtils; import androidx.preference.Preference; @@ -35,9 +34,9 @@ import java.util.List; public class EmergencyInfoPreferenceController extends BasePreferenceController { - public static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO"; - - private static final String PACKAGE_NAME_EMERGENCY = "com.android.emergency"; + public static String getIntentAction(Context context) { + return context.getResources().getString(R.string.config_emergency_intent_action); + } public EmergencyInfoPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); @@ -85,19 +84,7 @@ public class EmergencyInfoPreferenceController extends BasePreferenceController ? AVAILABLE : UNSUPPORTED_ON_DEVICE; } - private static String getIntentAction(Context context) { - if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SAFETY_HUB)) { - return context.getResources().getString(R.string.config_emergency_intent_action); - } - - return ACTION_EDIT_EMERGENCY_INFO; - } - private static String getPackageName(Context context) { - if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SAFETY_HUB)) { - return context.getResources().getString(R.string.config_emergency_package_name); - } - - return PACKAGE_NAME_EMERGENCY; + return context.getResources().getString(R.string.config_emergency_package_name); } } diff --git a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java index f8be2d656aa..10e87ff8366 100644 --- a/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java +++ b/src/com/android/settings/homepage/contextualcards/deviceinfo/EmergencyInfoSlice.java @@ -16,8 +16,6 @@ package com.android.settings.homepage.contextualcards.deviceinfo; -import static com.android.settings.accounts.EmergencyInfoPreferenceController.ACTION_EDIT_EMERGENCY_INFO; - import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -29,6 +27,7 @@ import androidx.slice.builders.ListBuilder; import androidx.slice.builders.SliceAction; import com.android.settings.R; +import com.android.settings.accounts.EmergencyInfoPreferenceController; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.CustomSliceable; @@ -62,7 +61,7 @@ public class EmergencyInfoSlice implements CustomSliceable { @Override public Intent getIntent() { - return new Intent(ACTION_EDIT_EMERGENCY_INFO); + return new Intent(EmergencyInfoPreferenceController.getIntentAction(mContext)); } @Override From 8f205a66c0e5059ae84cd95d74996bd5058696ac Mon Sep 17 00:00:00 2001 From: Raff Tsai Date: Thu, 2 May 2019 14:34:45 +0800 Subject: [PATCH 08/27] Can't switch navigation mode from search results 3 Navigation modes are mutually exclusive, we can't set all often them on. Therefore we will now show them as slices. Fixes: 131713601 Test: robolectric, manual Change-Id: I52e94dffe15ed20a23a5e4cea68a40b66158b3dd --- .../SystemNavigationEdgeToEdgePreferenceController.java | 5 ----- .../gestures/SystemNavigationLegacyPreferenceController.java | 5 ----- .../SystemNavigationSwipeUpPreferenceController.java | 5 ----- .../SystemNavigationEdgeToEdgePreferenceControllerTest.java | 4 ++-- .../SystemNavigationLegacyPreferenceControllerTest.java | 4 ++-- .../SystemNavigationSwipeUpPreferenceControllerTest.java | 4 ++-- 6 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java b/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java index 11ff0949b05..337ad2ea2a3 100644 --- a/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java +++ b/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceController.java @@ -42,11 +42,6 @@ public class SystemNavigationEdgeToEdgePreferenceController extends super(context, overlayManager, key); } - @Override - public boolean isSliceable() { - return TextUtils.equals(PREF_KEY_EDGE_TO_EDGE, getPreferenceKey()); - } - @Override public void onRadioButtonClicked(RadioButtonPreference preference) { setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_GESTURAL_OVERLAY); diff --git a/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java index 0b197845599..728c5df0342 100644 --- a/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java +++ b/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceController.java @@ -42,11 +42,6 @@ public class SystemNavigationLegacyPreferenceController extends super(context, overlayManager, key); } - @Override - public boolean isSliceable() { - return TextUtils.equals(PREF_KEY_LEGACY, getPreferenceKey()); - } - @Override public void onRadioButtonClicked(RadioButtonPreference preference) { setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_3BUTTON_OVERLAY); diff --git a/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java b/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java index 26c2201a1e5..cf2886f88a6 100644 --- a/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java +++ b/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceController.java @@ -42,11 +42,6 @@ public class SystemNavigationSwipeUpPreferenceController extends super(context, overlayManager, key); } - @Override - public boolean isSliceable() { - return TextUtils.equals(PREF_KEY_SWIPE_UP, getPreferenceKey()); - } - @Override public void onRadioButtonClicked(RadioButtonPreference preference) { setNavBarInteractionMode(mOverlayManager, NAV_BAR_MODE_2BUTTON_OVERLAY); diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java index 740ff2cae29..a23f8dac26f 100644 --- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationEdgeToEdgePreferenceControllerTest.java @@ -180,8 +180,8 @@ public class SystemNavigationEdgeToEdgePreferenceControllerTest { } @Test - public void isSliceableCorrectKey_returnsTrue() { - assertThat(mController.isSliceable()).isTrue(); + public void isSliceable_returnsFalse() { + assertThat(mController.isSliceable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java index 2c4f88a09ad..dc9e3d9ae9a 100644 --- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationLegacyPreferenceControllerTest.java @@ -182,8 +182,8 @@ public class SystemNavigationLegacyPreferenceControllerTest { } @Test - public void isSliceableCorrectKey_returnsTrue() { - assertThat(mController.isSliceable()).isTrue(); + public void isSliceable_returnsFalse() { + assertThat(mController.isSliceable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java index 177d4987d1d..955ea0c631f 100644 --- a/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/gestures/SystemNavigationSwipeUpPreferenceControllerTest.java @@ -180,8 +180,8 @@ public class SystemNavigationSwipeUpPreferenceControllerTest { } @Test - public void isSliceableCorrectKey_returnsTrue() { - assertThat(mController.isSliceable()).isTrue(); + public void isSliceable_returnsFalse() { + assertThat(mController.isSliceable()).isFalse(); } @Test From de6ab19391cde923413e21685d363cbd368135d4 Mon Sep 17 00:00:00 2001 From: pastychang Date: Thu, 2 May 2019 16:19:44 +0800 Subject: [PATCH 09/27] Update sub-text in skip lock screen dialog Bug: 131634814 Test: Manual Change-Id: Iaae7c6c6616bfb8448539e5e18dda68a4754d9be --- res/values/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 938c72f4de0..f7e1a2c5a21 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1052,17 +1052,17 @@ You\u2019ve chosen to use your fingerprint as one way to unlock your phone. If you skip now, you\u2019ll need to set this up later. Setup takes only a minute or so. - Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password. - Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password. - Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up fingerprint. Tap Cancel, then set a PIN, pattern, or password. - Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your tablet with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. - Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your device with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. - Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN or choose another screen lock option. + Protect your phone with a screen lock option so no one will be able to use it if it is lost or stolen. You also need a screen lock option to set up face authentication. Tap Cancel, then set a PIN, pattern, or password. Skip PIN setup? From 1789d9ee6a3c81b46f7b193fe9bc5002a24f07d0 Mon Sep 17 00:00:00 2001 From: Jason Chiu Date: Thu, 2 May 2019 18:28:42 +0800 Subject: [PATCH 10/27] Update strings for Vibration Fixes: 131345468 Test: visual Change-Id: I7670ba96cf9b66e241a0003800a30c00f2585fc9 --- res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 615077c6c13..d69ee564df5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4885,13 +4885,13 @@ Delay before click - Vibration + Vibration & haptic strength Notification vibration Ring vibration - Touch vibration + Touch feedback Use service From bf63dde205d6b9991409bc4e74d28621cd1ebbe9 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Mon, 29 Apr 2019 17:59:54 -0400 Subject: [PATCH 11/27] Add setting suggestion for style Also added extra to the existing wallpaper suggestion so it opens directly to that tab instead of the style tab Test: atest com.android.settings.wallpaper.StyleSuggestionActivityTest Fixes: 126230901 Change-Id: I50ca588627063194900dca8a9273baff4a44ca67 --- AndroidManifest.xml | 17 ++++ res/drawable/ic_theme.xml | 26 ++++++ .../SuggestionFeatureProviderImpl.java | 3 + .../wallpaper/StyleSuggestionActivity.java | 41 +++++++++ .../StyleSuggestionActivityBase.java | 80 ++++++++++++++++++ .../WallpaperSuggestionActivity.java | 49 ++--------- .../StyleSuggestionActivityTest.java | 83 +++++++++++++++++++ 7 files changed, 256 insertions(+), 43 deletions(-) create mode 100644 res/drawable/ic_theme.xml create mode 100644 src/com/android/settings/wallpaper/StyleSuggestionActivity.java create mode 100644 src/com/android/settings/wallpaper/StyleSuggestionActivityBase.java create mode 100644 tests/robotests/src/com/android/settings/wallpaper/StyleSuggestionActivityTest.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 9dd4732072f..20742885742 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -848,6 +848,23 @@ + + + + + + + + + + + + + + + diff --git a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java index bfa44e5216e..35905546a03 100644 --- a/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java +++ b/src/com/android/settings/dashboard/suggestions/SuggestionFeatureProviderImpl.java @@ -31,6 +31,7 @@ import com.android.settings.notification.ZenOnboardingActivity; import com.android.settings.notification.ZenSuggestionActivity; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.ScreenLockSuggestionActivity; +import com.android.settings.wallpaper.StyleSuggestionActivity; import com.android.settings.wallpaper.WallpaperSuggestionActivity; import com.android.settings.wifi.calling.WifiCallingSuggestionActivity; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -62,6 +63,8 @@ public class SuggestionFeatureProviderImpl implements SuggestionFeatureProvider final String className = component.getClassName(); if (className.equals(WallpaperSuggestionActivity.class.getName())) { return WallpaperSuggestionActivity.isSuggestionComplete(context); + } else if (className.equals(StyleSuggestionActivity.class.getName())) { + return StyleSuggestionActivity.isSuggestionComplete(context); } else if (className.equals(FingerprintSuggestionActivity.class.getName())) { return FingerprintSuggestionActivity.isSuggestionComplete(context); } else if (className.equals(FingerprintEnrollSuggestionActivity.class.getName())) { diff --git a/src/com/android/settings/wallpaper/StyleSuggestionActivity.java b/src/com/android/settings/wallpaper/StyleSuggestionActivity.java new file mode 100644 index 00000000000..376724b0cae --- /dev/null +++ b/src/com/android/settings/wallpaper/StyleSuggestionActivity.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 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.wallpaper; + +import android.content.Context; +import android.provider.Settings; +import android.text.TextUtils; + +import com.android.internal.annotations.VisibleForTesting; + +public class StyleSuggestionActivity extends StyleSuggestionActivityBase { + + @VisibleForTesting + public static boolean isSuggestionComplete(Context context) { + if (!isWallpaperServiceEnabled(context)) { + return true; + } + + final String currentTheme = Settings.Secure.getStringForUser(context.getContentResolver(), + Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, context.getUserId()); + if (TextUtils.isEmpty(currentTheme)) { + // Empty value means the user has not visited the styles tab yet + return false; + } + return true; + } +} diff --git a/src/com/android/settings/wallpaper/StyleSuggestionActivityBase.java b/src/com/android/settings/wallpaper/StyleSuggestionActivityBase.java new file mode 100644 index 00000000000..abbf3dc8146 --- /dev/null +++ b/src/com/android/settings/wallpaper/StyleSuggestionActivityBase.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 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.wallpaper; + +import android.app.Activity; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; + +import androidx.annotation.VisibleForTesting; + +import com.android.settings.R; +import com.android.settings.core.SubSettingLauncher; +import com.android.settings.display.WallpaperPreferenceController; + +import com.google.android.setupcompat.util.WizardManagerHelper; + +public abstract class StyleSuggestionActivityBase extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final PackageManager pm = getPackageManager(); + final Intent intent = new Intent() + .setComponent(new WallpaperPreferenceController(this, "dummy key") + .getComponentName()) + .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); + + // passing the necessary extra to next page + WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent); + + addExtras(intent); + + if (pm.resolveActivity(intent, 0) != null) { + startActivity(intent); + } else { + startFallbackSuggestion(); + } + + finish(); + } + + /** + * Add any extras to the intent before launching the wallpaper activity + * @param intent + */ + protected void addExtras(Intent intent) { } + + @VisibleForTesting + void startFallbackSuggestion() { + // fall back to default wallpaper picker + new SubSettingLauncher(this) + .setDestination(WallpaperTypeSettings.class.getName()) + .setTitleRes(R.string.wallpaper_suggestion_title) + .setSourceMetricsCategory(SettingsEnums.DASHBOARD_SUMMARY) + .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) + .launch(); + } + + protected static boolean isWallpaperServiceEnabled(Context context) { + return context.getResources().getBoolean( + com.android.internal.R.bool.config_enableWallpaperService); + } +} diff --git a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java index fe23d742770..57222f1a41d 100644 --- a/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java +++ b/src/com/android/settings/wallpaper/WallpaperSuggestionActivity.java @@ -16,63 +16,31 @@ package com.android.settings.wallpaper; -import android.app.Activity; import android.app.WallpaperManager; -import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Bundle; import androidx.annotation.VisibleForTesting; -import com.android.settings.R; -import com.android.settings.core.SubSettingLauncher; import com.android.settings.display.WallpaperPreferenceController; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; import com.android.settings.search.SearchIndexableRaw; import com.android.settingslib.search.SearchIndexable; -import com.google.android.setupcompat.util.WizardManagerHelper; - import java.util.ArrayList; import java.util.List; @SearchIndexable -public class WallpaperSuggestionActivity extends Activity implements Indexable { +public class WallpaperSuggestionActivity extends StyleSuggestionActivityBase implements Indexable { + + private static final String WALLPAPER_FLAVOR_EXTRA = "com.android.launcher3.WALLPAPER_FLAVOR"; + private static final String WALLPAPER_FOCUS = "focus_wallpaper"; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - final PackageManager pm = getPackageManager(); - final Intent intent = new Intent() - .setComponent(new WallpaperPreferenceController(this, "dummy key") - .getComponentName()) - .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT); - - // passing the necessary extra to next page - WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent); - - if (pm.resolveActivity(intent, 0) != null) { - startActivity(intent); - } else { - startFallbackSuggestion(); - } - - finish(); - } - - @VisibleForTesting - void startFallbackSuggestion() { - // fall back to default wallpaper picker - new SubSettingLauncher(this) - .setDestination(WallpaperTypeSettings.class.getName()) - .setTitleRes(R.string.wallpaper_suggestion_title) - .setSourceMetricsCategory(SettingsEnums.DASHBOARD_SUMMARY) - .addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT) - .launch(); + protected void addExtras(Intent intent) { + intent.putExtra(WALLPAPER_FLAVOR_EXTRA, WALLPAPER_FOCUS); } @VisibleForTesting @@ -85,11 +53,6 @@ public class WallpaperSuggestionActivity extends Activity implements Indexable { return manager.getWallpaperId(WallpaperManager.FLAG_SYSTEM) > 0; } - private static boolean isWallpaperServiceEnabled(Context context) { - return context.getResources().getBoolean( - com.android.internal.R.bool.config_enableWallpaperService); - } - public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider() { private static final String SUPPORT_SEARCH_INDEX_KEY = "wallpaper_type"; diff --git a/tests/robotests/src/com/android/settings/wallpaper/StyleSuggestionActivityTest.java b/tests/robotests/src/com/android/settings/wallpaper/StyleSuggestionActivityTest.java new file mode 100644 index 00000000000..120c780ab9d --- /dev/null +++ b/tests/robotests/src/com/android/settings/wallpaper/StyleSuggestionActivityTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2019 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.wallpaper; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.ContentResolver; +import android.content.Context; +import android.content.res.Resources; +import android.provider.Settings; + +import com.android.settings.testutils.shadow.ShadowSecureSettings; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +public class StyleSuggestionActivityTest { + + @Mock + private Context mContext; + @Mock + private Resources mResources; + @Mock + private ContentResolver mContentResolver; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mContext.getResources()).thenReturn(mResources); + when(mContext.getContentResolver()).thenReturn(mContentResolver); + } + + @Test + public void wallpaperServiceEnabled_no_shouldReturnTrue() { + when(mResources.getBoolean(com.android.internal.R.bool.config_enableWallpaperService)) + .thenReturn(false); + assertThat(StyleSuggestionActivity.isSuggestionComplete(mContext)).isTrue(); + } + + @Test + @Config(shadows = ShadowSecureSettings.class) + public void hasStyleSet_yes_shouldReturnTrue() { + when(mResources.getBoolean(com.android.internal.R.bool.config_enableWallpaperService)) + .thenReturn(true); + + Settings.Secure.putString(mContentResolver, + Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, "test"); + assertThat(StyleSuggestionActivity.isSuggestionComplete(mContext)).isTrue(); + } + + @Test + @Config(shadows = ShadowSecureSettings.class) + public void hasStyleSet_no_shouldReturnFalse() { + when(mResources.getBoolean(com.android.internal.R.bool.config_enableWallpaperService)) + .thenReturn(true); + + Settings.Secure.putString(mContentResolver, + Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES, null); + assertThat(StyleSuggestionActivity.isSuggestionComplete(mContext)).isFalse(); + } +} From f580032adaee3a4e327fc26cdd7742effb1e401a Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Thu, 2 May 2019 08:38:04 -0700 Subject: [PATCH 12/27] Changed Content Capture title. Fixes: 131169650 Test: m SettingsGoogle && adb sync && adb shell kill `pid com.android.settings` && \ adb shell am start-activity -a android.settings.REQUEST_ENABLE_CONTENT_CAPTURE Change-Id: I63a032a27f40e9f413121ba6cd5fc4b2e10da637 --- res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 615077c6c13..8ad030294bd 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11068,9 +11068,9 @@ You may lose access to any remaining time or data. Check with your provider before removing. - content capture + content capture, app content - Content Capture + App content Allow apps to send content to the Android system From b056b7dec41e64e2101552d0bd1d43596b70fad8 Mon Sep 17 00:00:00 2001 From: Salvador Martinez Date: Fri, 26 Apr 2019 16:25:38 -0700 Subject: [PATCH 13/27] Update battery saver footer to have learn more link This will allow tapping on the Learn More text to take a user to the support page for battery saver. Bug: 129010739 Test: atest BatterySaverSettingsTest Change-Id: Ifb758ea8c608a4051c093b5d1d43f9a039ab1294 --- .../batterysaver/BatterySaverSettings.java | 99 ++++++++++++++++++- .../BatterySaverSettingsTest.java | 62 ++++++++++++ 2 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java index 64354687044..be23f720279 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettings.java @@ -20,12 +20,25 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.os.Bundle; import android.provider.SearchIndexableResource; +import android.text.Annotation; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.TextUtils; +import android.text.style.URLSpan; +import android.view.View; + +import androidx.annotation.VisibleForTesting; +import androidx.fragment.app.Fragment; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.Indexable; +import com.android.settingslib.HelpUtils; import com.android.settingslib.search.SearchIndexable; +import com.android.settingslib.widget.FooterPreference; import java.util.Arrays; import java.util.List; @@ -36,10 +49,14 @@ import java.util.List; @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) public class BatterySaverSettings extends DashboardFragment { private static final String TAG = "BatterySaverSettings"; + public static final String KEY_FOOTER_PREFERENCE = "footer_preference"; + private SpannableStringBuilder mFooterText; + private String mHelpUri; @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onStart() { + super.onStart(); + setupFooter(); } @Override @@ -75,4 +92,82 @@ public class BatterySaverSettings extends DashboardFragment { return Arrays.asList(sir); } }; + + // Updates the footer for this page. + @VisibleForTesting + void setupFooter() { + mFooterText = new SpannableStringBuilder(getText( + com.android.internal.R.string.battery_saver_description_with_learn_more)); + mHelpUri = getString(R.string.help_url_battery_saver_settings); + if (!TextUtils.isEmpty(mHelpUri)) { + addHelpLink(); + } + } + + // Changes the text to include a learn more link if possible. + @VisibleForTesting + void addHelpLink() { + FooterPreference pref = getPreferenceScreen().findPreference(KEY_FOOTER_PREFERENCE); + if (pref != null) { + SupportPageLearnMoreSpan.linkify(mFooterText, this, mHelpUri); + pref.setTitle(mFooterText); + } + } + + /** + * A {@link URLSpan} that opens a support page when clicked + */ + public static class SupportPageLearnMoreSpan extends URLSpan { + + + private static final String ANNOTATION_URL = "url"; + private final Fragment mFragment; + private final String mUriString; + + public SupportPageLearnMoreSpan(Fragment fragment, String uriString) { + // sets the url to empty string so we can prevent any other span processing from + // from clearing things we need in this string. + super(""); + mFragment = fragment; + mUriString = uriString; + } + + @Override + public void onClick(View widget) { + if (mFragment != null) { + // launch the support page + mFragment.startActivityForResult(HelpUtils.getHelpIntent(mFragment.getContext(), + mUriString, ""), 0); + } + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + // remove underline + ds.setUnderlineText(false); + } + + /** + * This method takes a string and turns it into a url span that will launch a support page + * @param msg The text to turn into a link + * @param fragment The fragment which contains this span + * @param uriString The URI string of the help article to open when clicked + * @return A CharSequence containing the original text content as a url + */ + public static CharSequence linkify(Spannable msg, Fragment fragment, String uriString) { + Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class); + for (Annotation annotation : spans) { + int start = msg.getSpanStart(annotation); + int end = msg.getSpanEnd(annotation); + if (ANNOTATION_URL.equals(annotation.getValue())) { + SupportPageLearnMoreSpan link = + new SupportPageLearnMoreSpan(fragment, uriString); + msg.removeSpan(annotation); + msg.setSpan(link, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + return msg; + } + } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java new file mode 100644 index 00000000000..7cb57a33370 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverSettingsTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2019 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.fuelgauge.batterysaver; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import androidx.preference.PreferenceScreen; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class BatterySaverSettingsTest { + BatterySaverSettings mFragment; + @Mock + PreferenceScreen mScreen; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mFragment = spy(new BatterySaverSettings()); + doReturn(mScreen).when(mFragment).getPreferenceScreen(); + } + + + @Test + public void setupFooter_linkAddedWhenAppropriate() { + doReturn("").when(mFragment).getText(anyInt()); + doReturn("").when(mFragment).getString(anyInt()); + mFragment.setupFooter(); + verify(mFragment, never()).addHelpLink(); + + doReturn("testString").when(mFragment).getText(anyInt()); + doReturn("testString").when(mFragment).getString(anyInt()); + mFragment.setupFooter(); + verify(mFragment, atLeastOnce()).addHelpLink(); + } +} From 52f7903d2f5236b4bf32904a763c919c8ca239fc Mon Sep 17 00:00:00 2001 From: Andrew Sapperstein Date: Thu, 2 May 2019 13:32:45 -0700 Subject: [PATCH 14/27] Tint plus icon in mobile networks list. Fixes: 131723134 Test: visual inspection Change-Id: Ia6e85b99941604904e536735fadfd5c3e6ef0eba --- res/drawable/ic_menu_add_activated_tint.xml | 28 +++++++++++++++++++++ res/xml/mobile_network_list.xml | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 res/drawable/ic_menu_add_activated_tint.xml diff --git a/res/drawable/ic_menu_add_activated_tint.xml b/res/drawable/ic_menu_add_activated_tint.xml new file mode 100644 index 00000000000..e5d138483d2 --- /dev/null +++ b/res/drawable/ic_menu_add_activated_tint.xml @@ -0,0 +1,28 @@ + + + + + + diff --git a/res/xml/mobile_network_list.xml b/res/xml/mobile_network_list.xml index c2baf460401..13f9a597132 100644 --- a/res/xml/mobile_network_list.xml +++ b/res/xml/mobile_network_list.xml @@ -24,7 +24,7 @@ android:key="add_more" settings:isPreferenceVisible="false" android:title="@string/mobile_network_list_add_more" - android:icon="@drawable/ic_menu_add" + android:icon="@drawable/ic_menu_add_activated_tint" android:order="100" > Date: Thu, 2 May 2019 14:03:24 -0700 Subject: [PATCH 15/27] Add metrics categories for delete sims dialogs. Fixes: 131519375 Test: is metrics Change-Id: I020e3d887fb0408617428d00386bb57318b6b175 --- .../network/telephony/DeleteSimProfileConfirmationDialog.java | 4 ++-- .../network/telephony/DeleteSimProfileProgressDialog.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java index 52c5cc10b4d..13bfa9230cf 100644 --- a/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java +++ b/src/com/android/settings/network/telephony/DeleteSimProfileConfirmationDialog.java @@ -17,6 +17,7 @@ package com.android.settings.network.telephony; import android.app.Dialog; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; @@ -77,7 +78,6 @@ public class DeleteSimProfileConfirmationDialog extends InstrumentedDialogFragme @Override public int getMetricsCategory() { - // TODO(b/131519375) - use a real id here once it's been created in the metrics proto - return 0; + return SettingsEnums.DIALOG_DELETE_SIM_CONFIRMATION; } } diff --git a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java index 15f4b2223db..c176f3cc911 100644 --- a/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java +++ b/src/com/android/settings/network/telephony/DeleteSimProfileProgressDialog.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.Dialog; import android.app.PendingIntent; import android.app.ProgressDialog; +import android.app.settings.SettingsEnums; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; @@ -114,7 +115,6 @@ public class DeleteSimProfileProgressDialog extends InstrumentedDialogFragment { @Override public int getMetricsCategory() { - // TODO(b/131519375) - use a real id here once it's been created in the metrics proto - return 0; + return SettingsEnums.DIALOG_DELETE_SIM_PROGRESS; } } From 06a309cf1c40c55ca5eeb742587952106a0c0e06 Mon Sep 17 00:00:00 2001 From: Lei Yu Date: Thu, 2 May 2019 13:01:38 -0700 Subject: [PATCH 16/27] Update title for metered preference Fixes: 111859056 Test: Manual Change-Id: I7cecb6fee3963607e33a8fd24d53e98c209f1495 --- res/values/strings.xml | 2 ++ res/xml/wifi_network_details_fragment.xml | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 959a72f1e31..d8881b8baa9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -6376,6 +6376,8 @@ Automatic + + Network usage Metered diff --git a/res/xml/wifi_network_details_fragment.xml b/res/xml/wifi_network_details_fragment.xml index 3218e0de25e..d45f9bc1796 100644 --- a/res/xml/wifi_network_details_fragment.xml +++ b/res/xml/wifi_network_details_fragment.xml @@ -58,7 +58,7 @@ From 094c238ba1120afdf673c001a4f7ef446131d007 Mon Sep 17 00:00:00 2001 From: Fan Zhang Date: Thu, 2 May 2019 16:24:05 -0700 Subject: [PATCH 17/27] Delete dead tests. These tests are broken for a while and we don't have owners to maintain these tests. New tests will be written in robolectric. Fixes: 131857690 Test: rebuild Change-Id: I6ad2d7f1aa6bc904df5746b82cd8d9db3e93bd8f --- .../ui/AccessibilitySettingsTests.java | 277 ------------------ .../ui/BluetoothNetworkSettingsTests.java | 163 ----------- .../settings/ui/DisplaySettingsTest.java | 268 ----------------- 3 files changed, 708 deletions(-) delete mode 100644 tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java delete mode 100644 tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java delete mode 100644 tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java diff --git a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java b/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java deleted file mode 100644 index 2fdee5cfee4..00000000000 --- a/tests/uitests/src/com/android/settings/ui/AccessibilitySettingsTests.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2018 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.ui; - -import android.metrics.MetricsReader; -import android.os.RemoteException; -import android.platform.test.annotations.Presubmit; -import android.provider.Settings; -import android.support.test.metricshelper.MetricsAsserts; -import android.support.test.uiautomator.By; -import android.support.test.uiautomator.Direction; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject2; -import android.support.test.uiautomator.Until; -import android.system.helpers.SettingsHelper; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - -public class AccessibilitySettingsTests extends InstrumentationTestCase { - - private static final String SETTINGS_PACKAGE = "com.android.settings"; - private static final int TIMEOUT = 2000; - private UiDevice mDevice; - private MetricsReader mMetricsReader; - - @Override - public void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - try { - mDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException("failed to freeze device orientaion", e); - } - mMetricsReader = new MetricsReader(); - // Clear out old logs - mMetricsReader.checkpoint(); - } - - @Override - protected void tearDown() throws Exception { - // Need to finish settings activity - mDevice.pressBack(); - mDevice.pressHome(); - mDevice.waitForIdle(); - super.tearDown(); - } - - @Presubmit - @MediumTest - public void testHighContrastTextOn() throws Exception { - verifyAccessibilitySettingOnOrOff("High contrast text", - Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 0, 1); - } - - @Presubmit - @MediumTest - public void testHighContrastTextOff() throws Exception { - verifyAccessibilitySettingOnOrOff("High contrast text", - Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, 1, 0); - } - - @Presubmit - @MediumTest - public void testPowerButtonEndsCallOn() throws Exception { - verifyAccessibilitySettingOnOrOff("Power button ends call", - Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 1, 2); - } - - @Presubmit - @MediumTest - public void testPowerButtonEndsCallOff() throws Exception { - verifyAccessibilitySettingOnOrOff("Power button ends call", - Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, 2, 1); - } - - /* Suppressing these four tests. The settings don't play - * nice with Settings.System.putInt or Settings.Secure.putInt. - * Need further clarification. Filed bug b/27792029 - */ - @Suppress - @MediumTest - public void testAutoRotateScreenOn() throws Exception { - verifyAccessibilitySettingOnOrOff("Auto-rotate screen", - Settings.System.ACCELEROMETER_ROTATION, 0, 1); - } - - @Suppress - @MediumTest - public void testAutoRotateScreenOff() throws Exception { - verifyAccessibilitySettingOnOrOff("Auto-rotate screen", - Settings.System.ACCELEROMETER_ROTATION, 1, 0); - } - - @Suppress - @MediumTest - public void testMonoAudioOn() throws Exception { - verifyAccessibilitySettingOnOrOff("Mono audio", - Settings.System.MASTER_MONO, 0, 1); - } - - @Suppress - @MediumTest - public void testMonoAudioOff() throws Exception { - verifyAccessibilitySettingOnOrOff("Mono audio", - Settings.System.MASTER_MONO, 1, 0); - } - - @Presubmit - @MediumTest - public void testLargeMousePointerOn() throws Exception { - verifyAccessibilitySettingOnOrOff("Large mouse pointer", - Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 0, 1); - } - - @Presubmit - @MediumTest - public void testLargeMousePointerOff() throws Exception { - verifyAccessibilitySettingOnOrOff("Large mouse pointer", - Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON, 1, 0); - } - - @Presubmit - @MediumTest - public void testColorCorrection() throws Exception { - verifySettingToggleAfterScreenLoad("Color correction", - Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED); - MetricsAsserts.assertHasVisibilityLog("Missing color correction log", - mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER, true); - } - - // Suppressing this test, since UiAutomator + talkback don't play nice - @Suppress - @MediumTest - public void testTalkback() throws Exception { - verifySettingToggleAfterScreenLoad("TalkBack", - Settings.Secure.ACCESSIBILITY_ENABLED); - } - - @Presubmit - @MediumTest - public void testCaptions() throws Exception { - verifySettingToggleAfterScreenLoad("Captions", - Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED); - MetricsAsserts.assertHasVisibilityLog("Missing captions log", - mMetricsReader, MetricsEvent.ACCESSIBILITY_CAPTION_PROPERTIES, true); - } - - @Presubmit - @MediumTest - public void testMagnificationGesture() throws Exception { - verifySettingToggleAfterScreenLoad("Magnification", "Magnify with triple-tap", - Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED); - MetricsAsserts.assertHasVisibilityLog("Missing magnification log", - mMetricsReader, MetricsEvent.ACCESSIBILITY_TOGGLE_SCREEN_MAGNIFICATION, true); - } - - @MediumTest - public void testClickAfterPointerStopsMoving() throws Exception { - verifySettingToggleAfterScreenLoad("Click after pointer stops moving", - Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED); - } - - @MediumTest - public void testAccessibilitySettingsLoadLog() throws Exception { - launchAccessibilitySettings(); - MetricsAsserts.assertHasVisibilityLog("Missing accessibility settings load log", - mMetricsReader, MetricsEvent.ACCESSIBILITY, true); - } - - public void launchAccessibilitySettings() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), - Settings.ACTION_ACCESSIBILITY_SETTINGS); - } - - private void verifyAccessibilitySettingOnOrOff(String settingText, - String settingFlag, int initialFlagValue, int expectedFlagValue) - throws Exception { - Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), - settingFlag, initialFlagValue); - launchAccessibilitySettings(); - UiObject2 settingsTitle = findItemOnScreen(settingText); - settingsTitle.click(); - Thread.sleep(TIMEOUT); - int settingValue = Settings.Secure - .getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); - assertEquals(settingText + " not correctly set after toggle", - expectedFlagValue, settingValue); - } - - private void verifySettingToggleAfterScreenLoad(String settingText, String settingFlag) - throws Exception { - verifySettingToggleAfterScreenLoad(settingText, null, settingFlag); - } - - private void verifySettingToggleAfterScreenLoad - (String settingText, String subSetting, String settingFlag) throws Exception { - // Load accessibility settings - launchAccessibilitySettings(); - Settings.Secure.putInt(getInstrumentation().getContext().getContentResolver(), - settingFlag, 0); - Thread.sleep(TIMEOUT); - // Tap on setting required - UiObject2 settingTitle = findItemOnScreen(settingText); - // Load screen - settingTitle.click(); - Thread.sleep(TIMEOUT); - if (subSetting != null) { - UiObject2 subSettingObject = findItemOnScreen(subSetting); - subSettingObject.click(); - Thread.sleep(TIMEOUT); - } - // Toggle value - UiObject2 settingToggle = mDevice.wait(Until.findObject(By.text("Off")), - TIMEOUT); - settingToggle.click(); - dismissOpenDialog(); - Thread.sleep(TIMEOUT); - // Assert new value - int settingValue = Settings.Secure. - getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); - assertEquals(settingText + " value not set correctly", 1, settingValue); - // Toogle value - settingToggle.click(); - dismissOpenDialog(); - mDevice.pressBack(); - Thread.sleep(TIMEOUT); - // Assert reset to old value - settingValue = Settings.Secure. - getInt(getInstrumentation().getContext().getContentResolver(), settingFlag); - assertEquals(settingText + " value not set correctly", 0, settingValue); - } - - private UiObject2 findItemOnScreen(String item) throws Exception { - int count = 0; - UiObject2 settingsPanel = mDevice.wait(Until.findObject - (By.res(SETTINGS_PACKAGE, "list")), TIMEOUT); - while (settingsPanel.fling(Direction.UP) && count < 3) { - count++; - } - count = 0; - UiObject2 setting = null; - while(count < 3 && setting == null) { - setting = mDevice.wait(Until.findObject(By.text(item)), TIMEOUT); - if (setting == null) { - settingsPanel.scroll(Direction.DOWN, 1.0f); - } - count++; - } - return setting; - } - - private void dismissOpenDialog() throws Exception { - UiObject2 okButton = mDevice.wait(Until.findObject - (By.res("android:id/button1")), TIMEOUT*2); - if (okButton != null) { - okButton.click(); - } - } -} diff --git a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java b/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java deleted file mode 100644 index d41be9cd352..00000000000 --- a/tests/uitests/src/com/android/settings/ui/BluetoothNetworkSettingsTests.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2018 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.ui; - -import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothManager; -import android.content.Context; -import android.content.Intent; -import android.metrics.MetricsReader; -import android.os.RemoteException; -import android.platform.test.annotations.Presubmit; -import android.provider.Settings; -import android.support.test.metricshelper.MetricsAsserts; -import android.support.test.uiautomator.By; -import android.support.test.uiautomator.BySelector; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject2; -import android.support.test.uiautomator.Until; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import com.android.internal.logging.nano.MetricsProto.MetricsEvent; - -public class BluetoothNetworkSettingsTests extends InstrumentationTestCase { - - private static final String SETTINGS_PACKAGE = "com.android.settings"; - private static final int TIMEOUT = 2000; - private static final int LONG_TIMEOUT = 40000; - private UiDevice mDevice; - private MetricsReader mMetricsReader; - - @Override - public void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - try { - mDevice.setOrientationNatural(); - } catch (RemoteException e) { - throw new RuntimeException("failed to freeze device orientaion", e); - } - mMetricsReader = new MetricsReader(); - // Clear out old logs - mMetricsReader.checkpoint(); - } - - @Override - protected void tearDown() throws Exception { - mDevice.pressBack(); - mDevice.pressHome(); - mDevice.waitForIdle(); - super.tearDown(); - } - - @Presubmit - @MediumTest - public void testBluetoothEnabled() throws Exception { - verifyBluetoothOnOrOff(true); - MetricsAsserts.assertHasActionLog("missing bluetooth toggle log", - mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE); - } - - @Presubmit - @MediumTest - public void testBluetoothDisabled() throws Exception { - verifyBluetoothOnOrOff(false); - MetricsAsserts.assertHasActionLog("missing bluetooth toggle log", - mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_TOGGLE); - } - - @MediumTest - public void testRenameOption() throws Exception { - launchBluetoothSettings(); - verifyUiObjectClicked(By.text("Device name"), "Rename preference"); - verifyUiObjectClicked(By.text("CANCEL"), "CANCEL button"); - - MetricsAsserts.assertHasActionLog("missing bluetooth rename device log", - mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_RENAME); - MetricsAsserts.assertHasVisibilityLog("missing bluetooth rename dialog log", - mMetricsReader, MetricsEvent.DIALOG_BLUETOOTH_RENAME, true); - } - - @MediumTest - public void testReceivedFilesOption() throws Exception { - launchBluetoothSettings(); - verifyUiObjectClicked(By.text("Received files"), "Received files preference"); - - MetricsAsserts.assertHasActionLog("missing bluetooth received files log", - mMetricsReader, MetricsEvent.ACTION_BLUETOOTH_FILES); - } - - @MediumTest - public void testHelpFeedbackOverflowOption() throws Exception { - launchBluetoothSettings(); - - // Verify help & feedback - assertNotNull("Help & feedback item not found under Bluetooth Settings", - mDevice.wait(Until.findObject(By.desc("Help & feedback")), TIMEOUT)); - } - - public void launchBluetoothSettings() throws Exception { - Intent btIntent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); - btIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getInstrumentation().getContext().startActivity(btIntent); - Thread.sleep(TIMEOUT * 2); - } - - /** - * Find the {@link UiObject2} by {@code itemSelector} and try to click it if possible. - * - * If not find, throw assertion error - * @param itemSelector used to find the {@link UiObject2} - * @param text the description of the {@link UiObject2} - */ - private void verifyUiObjectClicked(BySelector itemSelector, String text) throws Exception { - UiObject2 uiObject2 = mDevice.wait(Until.findObject(itemSelector), TIMEOUT); - assertNotNull(text + "is not present in bluetooth settings page", uiObject2); - uiObject2.click(); - } - - /** - * Toggles the Bluetooth switch and verifies that the change is reflected in Settings - * - * @param verifyOn set to whether you want the setting turned On or Off - */ - private void verifyBluetoothOnOrOff(boolean verifyOn) throws Exception { - String switchText = "ON"; - BluetoothAdapter bluetoothAdapter = ((BluetoothManager) getInstrumentation().getContext() - .getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); - if (verifyOn) { - switchText = "OFF"; - bluetoothAdapter.disable(); - } else { - bluetoothAdapter.enable(); - } - launchBluetoothSettings(); - mDevice.wait(Until - .findObject(By.res(SETTINGS_PACKAGE, "switch_widget").text(switchText)), TIMEOUT) - .click(); - Thread.sleep(TIMEOUT); - String bluetoothValue = - Settings.Global.getString(getInstrumentation().getContext().getContentResolver(), - Settings.Global.BLUETOOTH_ON); - if (verifyOn) { - assertEquals("1", bluetoothValue); - } else { - assertEquals("0", bluetoothValue); - } - } -} diff --git a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java b/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java deleted file mode 100644 index 0b7402d76f2..00000000000 --- a/tests/uitests/src/com/android/settings/ui/DisplaySettingsTest.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2018 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.ui; - -import android.content.ContentResolver; -import android.platform.test.annotations.Presubmit; -import android.provider.Settings; -import android.support.test.uiautomator.By; -import android.support.test.uiautomator.UiDevice; -import android.support.test.uiautomator.UiObject2; -import android.support.test.uiautomator.Until; -import android.system.helpers.SettingsHelper; -import android.system.helpers.SettingsHelper.SettingsType; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.Suppress; - -import java.util.regex.Pattern; - -public class DisplaySettingsTest extends InstrumentationTestCase { - - private static final String PAGE = Settings.ACTION_DISPLAY_SETTINGS; - private static final int TIMEOUT = 2000; - private static final FontSetting FONT_SMALL = new FontSetting("Small", 0.85f); - private static final FontSetting FONT_NORMAL = new FontSetting("Default", 1.00f); - private static final FontSetting FONT_LARGE = new FontSetting("Large", 1.15f); - private static final FontSetting FONT_HUGE = new FontSetting("Largest", 1.30f); - - private UiDevice mDevice; - private ContentResolver mResolver; - private SettingsHelper mHelper; - - @Override - public void setUp() throws Exception { - super.setUp(); - mDevice = UiDevice.getInstance(getInstrumentation()); - mDevice.setOrientationNatural(); - mResolver = getInstrumentation().getContext().getContentResolver(); - mHelper = new SettingsHelper(); - } - - @Override - public void tearDown() throws Exception { - // reset settings we touched that may impact others - Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); - mDevice.waitForIdle(); - super.tearDown(); - } - - @Presubmit - @MediumTest - public void testAdaptiveBrightness() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - Thread.sleep(1000); - - assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness", - Settings.System.SCREEN_BRIGHTNESS_MODE)); - assertTrue(mHelper.verifyToggleSetting(SettingsType.SYSTEM, PAGE, "Adaptive brightness", - Settings.System.SCREEN_BRIGHTNESS_MODE)); - } - - - // blocked on b/27487224 - @MediumTest - @Suppress - public void testDaydreamToggle() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - clickMore(); - Pattern p = Pattern.compile("On|Off"); - mHelper.clickSetting("Screen saver"); - Thread.sleep(1000); - try { - assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p, - Settings.Secure.SCREENSAVER_ENABLED, false)); - assertTrue(mHelper.verifyToggleSetting(SettingsType.SECURE, PAGE, p, - Settings.Secure.SCREENSAVER_ENABLED, false)); - } finally { - mDevice.pressBack(); - } - } - - @MediumTest - public void testAccelRotation() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - clickMore(); - Thread.sleep(4000); - int currentAccelSetting = Settings.System.getInt( - mResolver, Settings.System.ACCELEROMETER_ROTATION); - mHelper.clickSetting("Auto-rotate screen"); - int newAccelSetting = Settings.System.getInt( - mResolver, Settings.System.ACCELEROMETER_ROTATION); - assertTrue("Accelorometer setting unchanged after toggle", currentAccelSetting != newAccelSetting); - mHelper.clickSetting("Auto-rotate screen"); - int revertedAccelSetting = Settings.System.getInt( - mResolver, Settings.System.ACCELEROMETER_ROTATION); - assertTrue("Accelorometer setting unchanged after toggle", revertedAccelSetting != newAccelSetting); - } - - @MediumTest - public void testDaydream() throws Exception { - Settings.Secure.putInt(mResolver, Settings.Secure.SCREENSAVER_ENABLED, 1); - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - clickMore(); - mHelper.scrollVert(false); - mDevice.wait(Until.findObject(By.text("Screen saver")), TIMEOUT).click(); - try { - assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, - "Current screen saver", "Clock", Settings.Secure.SCREENSAVER_COMPONENTS, - "com.google.android.deskclock/com.android.deskclock.Screensaver")); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, - "Current screen saver", "Colors", Settings.Secure.SCREENSAVER_COMPONENTS, - "com.android.dreams.basic/com.android.dreams.basic.Colors")); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SECURE, PAGE, - "Current screen saver", "Photos", Settings.Secure.SCREENSAVER_COMPONENTS, - "com.google.android.apps.photos/com.google.android.apps.photos.daydream" - + ".PhotosDreamService")); - } finally { - mDevice.pressBack(); - Thread.sleep(2000); - } - } - - @Presubmit - @MediumTest - public void testSleep15Seconds() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "15 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "15000")); - } - - @MediumTest - public void testSleep30Seconds() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "30 seconds", Settings.System.SCREEN_OFF_TIMEOUT, "30000")); - } - - @MediumTest - public void testSleep1Minute() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "1 minute", Settings.System.SCREEN_OFF_TIMEOUT, "60000")); - } - - @MediumTest - public void testSleep2Minutes() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "2 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "120000")); - } - - @MediumTest - public void testSleep5Minutes() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "5 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "300000")); - } - - @MediumTest - public void testSleep10Minutes() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "10 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "600000")); - } - - @MediumTest - public void testSleep30Minutes() throws Exception { - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - mHelper.scrollVert(true); - assertTrue(mHelper.verifyRadioSetting(SettingsType.SYSTEM, PAGE, - "Sleep", "30 minutes", Settings.System.SCREEN_OFF_TIMEOUT, "1800000")); - } - - @Presubmit - @MediumTest - public void testFontSizeLarge() throws Exception { - verifyFontSizeSetting(1.00f, FONT_LARGE); - // Leaving the font size at large can make later tests fail, so reset it - Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); - // It takes a second for the new font size to be picked up - Thread.sleep(2000); - } - - @MediumTest - public void testFontSizeDefault() throws Exception { - verifyFontSizeSetting(1.15f, FONT_NORMAL); - } - - @MediumTest - public void testFontSizeLargest() throws Exception { - verifyFontSizeSetting(1.00f, FONT_HUGE); - // Leaving the font size at huge can make later tests fail, so reset it - Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, 1.00f); - // It takes a second for the new font size to be picked up - Thread.sleep(2000); - } - - @MediumTest - public void testFontSizeSmall() throws Exception { - verifyFontSizeSetting(1.00f, FONT_SMALL); - } - - private void verifyFontSizeSetting(float resetValue, FontSetting setting) - throws Exception { - Settings.System.putFloat(mResolver, Settings.System.FONT_SCALE, resetValue); - SettingsHelper.launchSettingsPage(getInstrumentation().getContext(), PAGE); - clickMore(); - mHelper.clickSetting("Font size"); - try { - mDevice.wait(Until.findObject(By.desc(setting.getName())), TIMEOUT).click(); - Thread.sleep(1000); - float changedValue = Settings.System.getFloat( - mResolver, Settings.System.FONT_SCALE); - assertEquals(setting.getSize(), changedValue, 0.0001); - } finally { - // Make sure to back out of the font menu - mDevice.pressBack(); - } - } - - private void clickMore() throws InterruptedException { - UiObject2 more = mDevice.wait(Until.findObject(By.text("Advanced")), TIMEOUT); - if (more != null) { - more.click(); - Thread.sleep(TIMEOUT); - } - } - - private static class FontSetting { - private final String mSizeName; - private final float mSizeVal; - - public FontSetting(String sizeName, float sizeVal) { - mSizeName = sizeName; - mSizeVal = sizeVal; - } - - public String getName() { - return mSizeName; - } - - public float getSize() { - return mSizeVal; - } - } -} From 0c4bf9b2bc2e8b982ffc88241c1b5ca562991888 Mon Sep 17 00:00:00 2001 From: Kevin Chyn Date: Thu, 2 May 2019 16:59:12 -0700 Subject: [PATCH 18/27] Update face settings to match mocks Test: Builds Fixes: 131660440 Change-Id: Ie75b67428be1e0504e3121bccb68f61e1fdbdb44 --- res/values/strings.xml | 21 +++++++++++---------- res/xml/security_settings_face.xml | 3 ++- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4cb495dc02d..e770d3c4bfb 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -933,26 +933,27 @@ Done - Use your face for + Use face unlock for - Unlocking your device + Unlocking your phone App sign-in \u0026 payments + + Require for face unlock - Eyes open to unlock + Open eyes looking at screen - When using face authentication, your eyes must be open + To unlock the phone, always require looking at the screen with your eyes open - Always require confirmation + Confirm button - When authenticating in apps, always require confirmation + When authenticating for apps, always require confirmation - Remove face data + Delete face data - Set up face authentication + Set up new face unlock - Your face can be used to unlock your device and access apps. - Learn more + Use Face unlock to unlock your device, sign in to apps, and confirm payments.\n\nKeep in mind:\nLooking at the phone can unlock it when you don\u2019t intend to.\n\nYour phone can be unlocked by someone else if it\u2019s held up to your face while your eyes are open.\n\nYour phone can be unlocked by someone who looks a lot like you, say, your child or an identical sibling. Delete face data? diff --git a/res/xml/security_settings_face.xml b/res/xml/security_settings_face.xml index 39bf73b5e66..fc812f465f4 100644 --- a/res/xml/security_settings_face.xml +++ b/res/xml/security_settings_face.xml @@ -42,7 +42,8 @@ + android:key="security_settings_face_manage_category" + android:title="@string/security_settings_face_settings_require_category"> Date: Fri, 3 May 2019 17:33:09 +0800 Subject: [PATCH 19/27] Update the deprecated Slice APIs to the new ones Fixes: 131880868 Test: build, visual, robotest Change-Id: I2cbb8fe131ebb284dabc5a5d65e70db254691688 --- .../contextualcards/slices/SliceFullCardRendererHelper.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java index f7b2bf5504f..cbe5ede4ece 100644 --- a/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java +++ b/src/com/android/settings/homepage/contextualcards/slices/SliceFullCardRendererHelper.java @@ -74,10 +74,10 @@ class SliceFullCardRendererHelper { }); // Customize slice view for Settings - cardHolder.sliceView.showTitleItems(true); + cardHolder.sliceView.setShowTitleItems(true); if (card.isLargeCard()) { - cardHolder.sliceView.showHeaderDivider(true); - cardHolder.sliceView.showActionDividers(true); + cardHolder.sliceView.setShowHeaderDivider(true); + cardHolder.sliceView.setShowActionDividers(true); } } From fc5f111bb9feae59478f948d0fb2860ffc5ca9f7 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 2 May 2019 17:36:40 -0400 Subject: [PATCH 20/27] Update colors For night mode and a11y Test: manual Fixes: 129507563 Change-Id: Ic675cbe0aaf0ccbb18d57729c26b5b55ca907910 --- color-check-baseline.xml | 16 ++++++++++++++++ res/drawable/button_border_selected.xml | 4 +++- res/drawable/button_border_unselected.xml | 2 +- res/values-night/colors.xml | 1 + res/values/colors.xml | 1 + 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/color-check-baseline.xml b/color-check-baseline.xml index e0a02067223..e90d9e41745 100644 --- a/color-check-baseline.xml +++ b/color-check-baseline.xml @@ -3373,4 +3373,20 @@ column="10"/> + + + + diff --git a/res/drawable/button_border_selected.xml b/res/drawable/button_border_selected.xml index 9701b382540..d96128b1c99 100644 --- a/res/drawable/button_border_selected.xml +++ b/res/drawable/button_border_selected.xml @@ -16,8 +16,10 @@ --> + diff --git a/res/drawable/button_border_unselected.xml b/res/drawable/button_border_unselected.xml index 4153303667d..092b1246f82 100644 --- a/res/drawable/button_border_unselected.xml +++ b/res/drawable/button_border_unselected.xml @@ -17,7 +17,7 @@ diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index b7b30f5836a..ae81762fdc7 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -26,5 +26,6 @@ @*android:color/material_grey_800 @*android:color/material_grey_800 + @*android:color/material_grey_800 diff --git a/res/values/colors.xml b/res/values/colors.xml index 1245b37ff2c..77f02d5ac1b 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -127,6 +127,7 @@ #FF32c1de #FFF87B2B #FFDADCE0 + #FFFFFF @*android:color/accent_device_default_light From bd6045bea92453d80ae2d878cd71ab63cfbb7a3e Mon Sep 17 00:00:00 2001 From: Salvador Martinez Date: Wed, 1 May 2019 13:18:43 -0700 Subject: [PATCH 21/27] Update Battery Saver schedule to add order to seekbar If the first time battery saver warning was the one causing a change in settings global the radio button picker doesn't update the preferences correctly and would put the seekbar at the top. This explicitly adds an order to the seekbar so that if it gets updated for some reason it will show up at the end again. Test: atest BatterySaverScheduleSettingsTest Bug: 131434758 Change-Id: Iebab5d176c8fbdaea078e13a71eff7e21408353b --- ...BatterySaverScheduleSeekBarController.java | 3 ++ .../BatterySaverScheduleSettings.java | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java index b704fde5096..a936e99f751 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSeekBarController.java @@ -100,6 +100,9 @@ public class BatterySaverScheduleSeekBarController implements } public void addToScreen(PreferenceScreen screen) { + // makes sure it gets added after the preferences if called due to first time battery + // saver message + mSeekBarPreference.setOrder(5); screen.addPreference(mSeekBarPreference); } } diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java index 3f8716dcdc8..6553c609a1b 100644 --- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java +++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverScheduleSettings.java @@ -17,15 +17,20 @@ package com.android.settings.fuelgauge.batterysaver; import android.content.Context; +import android.database.ContentObserver; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.os.Bundle; +import android.os.Handler; +import android.provider.Settings; import android.text.TextUtils; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.preference.PreferenceScreen; import com.android.settings.R; @@ -51,8 +56,18 @@ import java.util.List; public class BatterySaverScheduleSettings extends RadioButtonPickerFragment { public BatterySaverScheduleRadioButtonsController mRadioButtonController; + @VisibleForTesting + Context mContext; private BatterySaverScheduleSeekBarController mSeekBarController; + @VisibleForTesting + final ContentObserver mSettingsObserver = new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange, Uri uri) { + updateCandidates(); + } + }; + @Override protected int getPreferenceScreenResId() { return R.xml.battery_saver_schedule_settings; @@ -64,6 +79,16 @@ public class BatterySaverScheduleSettings extends RadioButtonPickerFragment { mSeekBarController = new BatterySaverScheduleSeekBarController(context); mRadioButtonController = new BatterySaverScheduleRadioButtonsController( context, mSeekBarController); + mContext = context; + } + + @Override + public void onResume() { + super.onResume(); + mContext.getContentResolver().registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED), + false, + mSettingsObserver); } @Override @@ -78,6 +103,12 @@ public class BatterySaverScheduleSettings extends RadioButtonPickerFragment { super.onCreate(savedInstanceState); } + @Override + public void onPause() { + mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); + super.onPause(); + } + @Override protected List getCandidates() { Context context = getContext(); From 3f1de20c7e6743205f20b134fe9fa123b8f6cd09 Mon Sep 17 00:00:00 2001 From: Amin Shaikh Date: Wed, 1 May 2019 17:29:02 -0400 Subject: [PATCH 22/27] Fix themed settings icons. - Added android prefix for homeAsUpIndicator attribute - Override ic_arrow_down_24dp from androidx - Remove ic_lock drawable overlay - Update date and time icon - Dedupe ic_menu_add and ic_add_24dp Bug: 131346125 Test: mp settings; Change-Id: I7223249f2adccc5569a37e8b68cae5499e7c7620 --- ...{ic_menu_add.xml => ic_arrow_down_24dp.xml} | 18 +++++++----------- res/drawable/ic_menu_add_activated_tint.xml | 16 ++++------------ res/drawable/ic_settings_date_time.xml | 7 +++++-- res/menu/vpn.xml | 2 +- res/values/themes.xml | 2 +- res/xml/bluetooth_screen.xml | 2 +- res/xml/connected_devices.xml | 2 +- res/xml/user_settings.xml | 2 +- res/xml/zen_mode_automation_settings.xml | 2 +- .../accounts/AccountPreferenceController.java | 2 +- .../defaultapps/DefaultAutofillPicker.java | 2 +- .../fingerprint/FingerprintSettings.java | 2 +- .../BluetoothPairingPreferenceController.java | 2 +- .../inputmethod/UserDictionarySettings.java | 2 +- .../android/settings/network/ApnSettings.java | 2 +- .../settings/print/PrintSettingsFragment.java | 2 +- .../wifi/AddWifiNetworkPreference.java | 2 +- .../wifi/dpp/WifiNetworkListFragment.java | 2 +- .../res/values/overlayable_icons_test.xml | 12 ++++++++++-- ...uetoothPairingPreferenceControllerTest.java | 2 +- 20 files changed, 42 insertions(+), 43 deletions(-) rename res/drawable/{ic_menu_add.xml => ic_arrow_down_24dp.xml} (59%) diff --git a/res/drawable/ic_menu_add.xml b/res/drawable/ic_arrow_down_24dp.xml similarity index 59% rename from res/drawable/ic_menu_add.xml rename to res/drawable/ic_arrow_down_24dp.xml index 0313d623176..85035118160 100644 --- a/res/drawable/ic_menu_add.xml +++ b/res/drawable/ic_arrow_down_24dp.xml @@ -1,6 +1,5 @@ - - + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:fillColor="?android:attr/colorControlNormal" + android:pathData="M12,16.41l-6.71,-6.7l1.42,-1.42l5.29,5.3l5.29,-5.3l1.42,1.42z"/> diff --git a/res/drawable/ic_menu_add_activated_tint.xml b/res/drawable/ic_menu_add_activated_tint.xml index e5d138483d2..afe6e1093b1 100644 --- a/res/drawable/ic_menu_add_activated_tint.xml +++ b/res/drawable/ic_menu_add_activated_tint.xml @@ -14,15 +14,7 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> - - - - + \ No newline at end of file diff --git a/res/drawable/ic_settings_date_time.xml b/res/drawable/ic_settings_date_time.xml index 1d2f3d336bb..c6fbbf95328 100644 --- a/res/drawable/ic_settings_date_time.xml +++ b/res/drawable/ic_settings_date_time.xml @@ -20,6 +20,9 @@ android:viewportHeight="24.0" android:tint="?android:attr/colorControlNormal"> + android:fillColor="@android:color/white" + android:pathData="M11.99,2.0C6.47,2.0 2.0,6.48 2.0,12.0s4.47,10.0 9.99,10.0C17.52,22.0 22.0,17.52 22.0,12.0S17.52,2.0 11.99,2.0zM12.0,20.0c-4.42,0.0 -8.0,-3.58 -8.0,-8.0s3.58,-8.0 8.0,-8.0 8.0,3.58 8.0,8.0 -3.58,8.0 -8.0,8.0z"/> + diff --git a/res/menu/vpn.xml b/res/menu/vpn.xml index a3b8090f8d9..cb11cad61a6 100644 --- a/res/menu/vpn.xml +++ b/res/menu/vpn.xml @@ -18,6 +18,6 @@ diff --git a/res/values/themes.xml b/res/values/themes.xml index 26d4aa892c2..951bb048960 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -28,7 +28,7 @@