From abb4fbd59612238d5c587ce26b96c8cb183bb0e9 Mon Sep 17 00:00:00 2001 From: Oli Thompson Date: Mon, 26 Jun 2023 12:31:31 +0000 Subject: [PATCH 1/6] Fix theming on Forgot your password work challegne screen Test: manually tested, screenshots in bug Bug: 286397998 Change-Id: Iaa9d83fb5c8a2f7df7bf43d224420b767e6c75fc --- src/com/android/settings/password/ForgotPasswordActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/android/settings/password/ForgotPasswordActivity.java b/src/com/android/settings/password/ForgotPasswordActivity.java index 9afda1867fd..92dc336d49f 100644 --- a/src/com/android/settings/password/ForgotPasswordActivity.java +++ b/src/com/android/settings/password/ForgotPasswordActivity.java @@ -50,6 +50,7 @@ public class ForgotPasswordActivity extends Activity { finish(); return; } + ThemeHelper.trySetDynamicColor(this); setContentView(R.layout.forgot_password_activity); DevicePolicyManager devicePolicyManager = getSystemService(DevicePolicyManager.class); From 83e5cd004f542ac80bd1c4ca1ee289d050c21be4 Mon Sep 17 00:00:00 2001 From: Yuyang Huang Date: Fri, 16 Jun 2023 06:22:42 +0000 Subject: [PATCH 2/6] Enable/Disable ASHA profile with LE audio toggle LE audio has more capability and better quality than ASHA has. When LE audio turned on, ASHA should be off to avoid media streaming profile conflict. Bug: 287525854 Test: manual (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f79e084bd0a3f9cd332d8218ac040d8c6c60f658) Merged-In: I3c5c9012c167b920e484b39374fe8174191b094d Change-Id: I3c5c9012c167b920e484b39374fe8174191b094d --- .../BluetoothDetailsProfilesController.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java index 00f18e8a87a..d2446f15ea5 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java @@ -319,11 +319,16 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll return; } + LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile(); + for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { Log.d(TAG, "device:" + leAudioDevice.getDevice().getAnonymizedAddress() + "disable LE profile"); profile.setEnabled(leAudioDevice.getDevice(), false); + if (asha != null) { + asha.setEnabled(leAudioDevice.getDevice(), true); + } } if (!SystemProperties.getBoolean(ENABLE_DUAL_MODE_AUDIO, false)) { @@ -349,12 +354,16 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll disableProfileBeforeUserEnablesLeAudio(mProfileManager.getA2dpProfile()); disableProfileBeforeUserEnablesLeAudio(mProfileManager.getHeadsetProfile()); } + LocalBluetoothProfile asha = mProfileManager.getHearingAidProfile(); for (CachedBluetoothDevice leAudioDevice : mProfileDeviceMap.get(profile.toString())) { Log.d(TAG, "device:" + leAudioDevice.getDevice().getAnonymizedAddress() + "enable LE profile"); profile.setEnabled(leAudioDevice.getDevice(), true); + if (asha != null) { + asha.setEnabled(leAudioDevice.getDevice(), false); + } } } @@ -371,6 +380,12 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll + profile.toString() + " profile is disabled. Do nothing."); } } + } else { + if (profile == null) { + Log.w(TAG, "profile is null"); + } else { + Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap); + } } } @@ -387,6 +402,12 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll + profile.toString() + " profile is enabled. Do nothing."); } } + } else { + if (profile == null) { + Log.w(TAG, "profile is null"); + } else { + Log.w(TAG, profile.toString() + " is not in " + mProfileDeviceMap); + } } } From 1688c57226838b068281be668a1092b4645b0633 Mon Sep 17 00:00:00 2001 From: Zoey Chen Date: Mon, 31 Jul 2023 07:25:05 +0000 Subject: [PATCH 3/6] [Regional Preference] Add description for checked/not checked Bug: 288223637 Test: make RunSettingsRoboTests -j128 ROBOTEST_FILTER=LocaleListEditorTest Change-Id: I0d1a2de93ad2911c555acef2f4e00cd715c62f17 Merged-In: I0d1a2de93ad2911c555acef2f4e00cd715c62f17 --- .../LocaleDragAndDropAdapter.java | 19 ++++++- .../localepicker/LocaleListEditorTest.java | 55 +++++++++++++++++-- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java index f703c83d8a7..6054c599411 100644 --- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java +++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java @@ -31,6 +31,7 @@ import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.CompoundButton; +import androidx.annotation.VisibleForTesting; import androidx.core.view.MotionEventCompat; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; @@ -178,17 +179,33 @@ class LocaleDragAndDropAdapter // clear listener before setChecked() in case another item already bind to // current ViewHolder and checked event is triggered on stale listener mistakenly. checkbox.setOnCheckedChangeListener(null); - checkbox.setChecked(mRemoveMode ? feedItem.getChecked() : false); + boolean isChecked = mRemoveMode ? feedItem.getChecked() : false; + checkbox.setChecked(isChecked); + setCheckBoxDescription(dragCell, checkbox, isChecked); + checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { LocaleStore.LocaleInfo feedItem = (LocaleStore.LocaleInfo) dragCell.getTag(); feedItem.setChecked(isChecked); + setCheckBoxDescription(dragCell, checkbox, isChecked); } }); } + @VisibleForTesting + protected void setCheckBoxDescription(LocaleDragCell dragCell, CheckBox checkbox, + boolean isChecked) { + CharSequence checkedStatus = mContext.getText( + isChecked ? com.android.internal.R.string.checked + : com.android.internal.R.string.not_checked); + // Talkback + dragCell.setStateDescription(checkedStatus); + // Select to Speak + checkbox.setContentDescription(checkedStatus); + } + @Override public int getItemCount() { int itemCount = (null != mFeedItemList ? mFeedItemList.size() : 0); diff --git a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java index 5a529f832e5..5ff2bafa1e7 100644 --- a/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java +++ b/tests/robotests/src/com/android/settings/localepicker/LocaleListEditorTest.java @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,6 +35,10 @@ import android.os.Bundle; import android.os.LocaleList; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; @@ -46,6 +51,7 @@ import com.android.settings.R; import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowActivityManager; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.After; import org.junit.Before; @@ -58,7 +64,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.ArrayList; import java.util.List; @@ -75,11 +80,12 @@ public class LocaleListEditorTest { private static final int REQUEST_CONFIRM_SYSTEM_DEFAULT = 1; private LocaleListEditor mLocaleListEditor; - private Context mContext; private FragmentActivity mActivity; - private List mLocaleList; + private List mLocaleList; private Intent mIntent = new Intent(); + private LocaleDragCell mLocaleDragCell; + private LocaleDragAndDropAdapter.CustomViewHolder mCustomViewHolder; @Mock private LocaleDragAndDropAdapter mAdapter; @@ -95,11 +101,23 @@ public class LocaleListEditorTest { private IActivityManager mActivityService; @Mock private MetricsFeatureProvider mMetricsFeatureProvider; + @Mock + private TextView mLabel; + @Mock + private CheckBox mCheckbox; + @Mock + private TextView mMiniLabel; + @Mock + private TextView mLocalized; + @Mock + private TextView mCurrentDefault; + @Mock + private ImageView mDragHandle; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; + mContext = spy(RuntimeEnvironment.application); mLocaleListEditor = spy(new LocaleListEditor()); when(mLocaleListEditor.getContext()).thenReturn(mContext); mActivity = Robolectric.buildActivity(FragmentActivity.class).get(); @@ -300,6 +318,35 @@ public class LocaleListEditorTest { verify(mAdapter).doTheUpdate(); } + @Test + public void onBindViewHolder_shouldSetCheckedBoxText() { + ReflectionHelpers.setField(mLocaleListEditor, "mRemoveMode", true); + mLocaleList = new ArrayList<>(); + mLocaleList.add(mLocaleInfo); + when(mLocaleInfo.getFullNameNative()).thenReturn("English"); + when(mLocaleInfo.getLocale()).thenReturn(LocaleList.forLanguageTags("en-US").get(0)); + + mAdapter = spy(new LocaleDragAndDropAdapter(mLocaleListEditor, mLocaleList)); + ReflectionHelpers.setField(mAdapter, "mFeedItemList", mLocaleList); + ReflectionHelpers.setField(mAdapter, "mParent", mLocaleListEditor); + ReflectionHelpers.setField(mAdapter, "mCacheItemList", new ArrayList<>(mLocaleList)); + ReflectionHelpers.setField(mAdapter, "mContext", mContext); + ViewGroup view = new FrameLayout(mContext); + mCustomViewHolder = mAdapter.onCreateViewHolder(view, 0); + mLocaleDragCell = new LocaleDragCell(mContext, null); + ReflectionHelpers.setField(mCustomViewHolder, "mLocaleDragCell", mLocaleDragCell); + ReflectionHelpers.setField(mLocaleDragCell, "mLabel", mLabel); + ReflectionHelpers.setField(mLocaleDragCell, "mLocalized", mLocalized); + ReflectionHelpers.setField(mLocaleDragCell, "mCurrentDefault", mCurrentDefault); + ReflectionHelpers.setField(mLocaleDragCell, "mMiniLabel", mMiniLabel); + ReflectionHelpers.setField(mLocaleDragCell, "mDragHandle", mDragHandle); + ReflectionHelpers.setField(mLocaleDragCell, "mCheckbox", mCheckbox); + + mAdapter.onBindViewHolder(mCustomViewHolder, 0); + + verify(mAdapter).setCheckBoxDescription(any(LocaleDragCell.class), any(), anyBoolean()); + } + private void setUpLocaleConditions() { ShadowActivityManager.setService(mActivityService); mLocaleList = new ArrayList<>(); From c52abcd3fa262f5a08797d4e411bb5d88b303246 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Thu, 3 Aug 2023 11:04:31 -0700 Subject: [PATCH 4/6] Import translations. DO NOT MERGE ANYWHERE BUG:291684185 Auto-generated-cl: translation import Change-Id: Ia444bb69cc499bd8d4a5ffc8c72babdda213c385 --- res/values-ja/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml index 20395045625..5d13ee4df28 100644 --- a/res/values-ja/strings.xml +++ b/res/values-ja/strings.xml @@ -240,10 +240,10 @@ "標準時間" "地域で選択" "UTC オフセットで選択" - "画面消灯後からロックまでの時間" + "画面が自動的に消灯してからロックまでの時間" "タイムアウトから %1$s" "画面消灯の直後にロック(%1$s がロック解除を管理している場合を除く)" - "画面消灯後から%1$s後にロック(%2$s がロック解除を管理している場合を除く)" + "画面が自動的に消灯してから%1$s後にロック(%2$s がロック解除を管理している場合を除く)" "ロック画面にテキストを追加" "なし" "例: 佐藤のAndroid" From 68e466ff0109f9499f73bb3bd1dcc43b6e73f20a Mon Sep 17 00:00:00 2001 From: Yu Chao Date: Tue, 1 Aug 2023 07:47:48 +0000 Subject: [PATCH 5/6] Migrate VpnSettings from RestrictedSettingsFragment to RestrictedDashboardFragment. This is required for adding an overlay vpn_settings2.xml for Tips Button. Test: VpnSettingsTest Bug: 293213974 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f9ca569249331a062e6f58a49bb0bb53aa69b3db) Merged-In: I26531afe75215c9531c0122d2e86fd5d0da4d3db Change-Id: I26531afe75215c9531c0122d2e86fd5d0da4d3db --- src/com/android/settings/vpn2/VpnSettings.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java index a91bb6c7e66..8cec2f42d96 100644 --- a/src/com/android/settings/vpn2/VpnSettings.java +++ b/src/com/android/settings/vpn2/VpnSettings.java @@ -61,7 +61,7 @@ import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; import com.android.settings.R; -import com.android.settings.RestrictedSettingsFragment; +import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.widget.GearPreference; import com.android.settings.widget.GearPreference.OnGearClickListener; @@ -80,7 +80,7 @@ import java.util.Set; * Settings screen listing VPNs. Configured VPNs and networks managed by apps * are shown in the same list. */ -public class VpnSettings extends RestrictedSettingsFragment implements +public class VpnSettings extends RestrictedDashboardFragment implements Handler.Callback, Preference.OnPreferenceClickListener { private static final String LOG_TAG = "VpnSettings"; private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG); @@ -135,7 +135,6 @@ public class VpnSettings extends RestrictedSettingsFragment implements mUnavailable = isUiRestricted(); setHasOptionsMenu(!mUnavailable); - addPreferencesFromResource(R.xml.vpn_settings2); mPreferenceScreen = getPreferenceScreen(); } @@ -211,6 +210,16 @@ public class VpnSettings extends RestrictedSettingsFragment implements mUpdater.sendEmptyMessage(RESCAN_MESSAGE); } + @Override + protected int getPreferenceScreenResId() { + return R.xml.vpn_settings2; + } + + @Override + protected String getLogTag() { + return LOG_TAG; + } + @Override public void onPause() { if (mUnavailable) { From 28be567a83b01c5818775164a7dc895bec7c7aa5 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Fri, 21 Jul 2023 19:31:29 +0800 Subject: [PATCH 6/6] Show policy transparency dialog for Wi-Fi network restrictions - In order to support various user restrictions of individual Wi-Fi networks, WifiEntry provides the hasAdminRestrictions method for unified management. - Settings will refer to WifiEntry#hasAdminRestrictions to restrict individual Wi-Fi networks. Bug: 289448751 Bug: 289951241 Test: manual test atest -c LongPressWifiEntryPreferenceTest Change-Id: Iae5996a87ee72a3073300c7f62dfa14a9f31c21d --- .../wifi/LongPressWifiEntryPreference.java | 21 +++++++++++++++- .../LongPressWifiEntryPreferenceTest.java | 25 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/wifi/LongPressWifiEntryPreference.java b/src/com/android/settings/wifi/LongPressWifiEntryPreference.java index 6343e06e074..ec94e74e0ff 100644 --- a/src/com/android/settings/wifi/LongPressWifiEntryPreference.java +++ b/src/com/android/settings/wifi/LongPressWifiEntryPreference.java @@ -22,6 +22,7 @@ import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.preference.PreferenceViewHolder; +import com.android.settingslib.RestrictedLockUtils; import com.android.wifitrackerlib.WifiEntry; /** @@ -34,7 +35,7 @@ public class LongPressWifiEntryPreference extends WifiEntryPreference { public LongPressWifiEntryPreference(Context context, WifiEntry wifiEntry, Fragment fragment) { super(context, wifiEntry); mFragment = fragment; - checkRestrictionAndSetDisabled(UserManager.DISALLOW_ADD_WIFI_CONFIG); + checkRestrictionAndSetDisabled(); } @Override @@ -65,4 +66,22 @@ public class LongPressWifiEntryPreference extends WifiEntryPreference { } return enabled; } + + @VisibleForTesting + void checkRestrictionAndSetDisabled() { + if (!getWifiEntry().hasAdminRestrictions()) { + return; + } + RestrictedLockUtils.EnforcedAdmin admin = null; + Context context = getContext(); + if (context != null) { + admin = RestrictedLockUtils.getProfileOrDeviceOwner(context, context.getUser()); + } + if (admin == null) { + // Use UserManager.DISALLOW_ADD_WIFI_CONFIG as default Wi-Fi network restriction. + admin = RestrictedLockUtils.EnforcedAdmin.createDefaultEnforcedAdminWithRestriction( + UserManager.DISALLOW_ADD_WIFI_CONFIG); + } + setDisabledByAdmin(admin); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/LongPressWifiEntryPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/LongPressWifiEntryPreferenceTest.java index efc2018ec85..457d9ab4113 100644 --- a/tests/robotests/src/com/android/settings/wifi/LongPressWifiEntryPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/wifi/LongPressWifiEntryPreferenceTest.java @@ -18,6 +18,10 @@ package com.android.settings.wifi; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -60,7 +64,7 @@ public class LongPressWifiEntryPreferenceTest { when(mWifiEntry.canDisconnect()).thenReturn(false); when(mWifiEntry.isSaved()).thenReturn(false); - mPreference = new LongPressWifiEntryPreference(mContext, mWifiEntry, mFragment); + mPreference = spy(new LongPressWifiEntryPreference(mContext, mWifiEntry, mFragment)); } @Test @@ -106,4 +110,23 @@ public class LongPressWifiEntryPreferenceTest { assertThat(mPreference.shouldEnabled()).isTrue(); } + + @Test + public void checkRestrictionAndSetDisabled_hasAdminRestrictions_doSetDisabledByAdmin() { + when(mContext.getUser()).thenReturn(null); + when(mWifiEntry.hasAdminRestrictions()).thenReturn(true); + + mPreference.checkRestrictionAndSetDisabled(); + + verify(mPreference).setDisabledByAdmin(any()); + } + + @Test + public void checkRestrictionAndSetDisabled_noAdminRestrictions_doNotSetDisabledByAdmin() { + when(mWifiEntry.hasAdminRestrictions()).thenReturn(false); + + mPreference.checkRestrictionAndSetDisabled(); + + verify(mPreference, never()).setDisabledByAdmin(any()); + } }