From a882fd268d975b1a6553faf2c5d46d5fb3f9ce9a Mon Sep 17 00:00:00 2001 From: Aleksandar Kiridzic Date: Fri, 2 Jun 2023 16:30:58 +0100 Subject: [PATCH 1/3] speech: On-device recognition settings profile selector `Settings > System > Languages > On-device speech recognition` entry is currently proceeding to the settings page for the personal profile by default. If a work profile exists, a profile selector should be shown first. Bug: 269575714 Test: Manual, already existing robotests Change-Id: Id95a9716358ec3a813c77275bd65f0cbdfc9aefc --- ...DeviceRecognitionPreferenceController.java | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java b/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java index 01f37b1f933..cd9f266cf90 100644 --- a/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java +++ b/src/com/android/settings/language/OnDeviceRecognitionPreferenceController.java @@ -16,9 +16,14 @@ package com.android.settings.language; +import android.app.Dialog; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.UserInfo; +import android.os.UserHandle; +import android.os.UserManager; +import android.text.TextUtils; import android.util.Log; import androidx.annotation.Nullable; @@ -26,8 +31,12 @@ import androidx.preference.Preference; import com.android.internal.R; import com.android.settings.core.BasePreferenceController; +import com.android.settings.dashboard.profileselector.ProfileSelectDialog; +import com.android.settings.dashboard.profileselector.UserAdapter; +import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.List; import java.util.Optional; /** Controller of the On-device recognition preference. */ @@ -37,6 +46,8 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr private Optional mIntent; + private WeakReference mProfileSelectDialog = new WeakReference<>(null); + public OnDeviceRecognitionPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); } @@ -59,6 +70,48 @@ public class OnDeviceRecognitionPreferenceController extends BasePreferenceContr } } + @Override + public boolean handlePreferenceTreeClick(Preference preference) { + if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { + return super.handlePreferenceTreeClick(preference); + } + show(preference); + return true; + } + + private void show(Preference preference) { + final List userHandles = new ArrayList<>(); + for (UserInfo userInfo : UserManager.get(mContext).getUsers()) { + userHandles.add(userInfo.getUserHandle()); + } + + // Only a single profile is installed. Proceed with its settings. + if (userHandles.size() == 1) { + mContext.startActivityAsUser(preference.getIntent(), userHandles.get(0)); + return; + } + + // Multiple profiles are installed. Show a dialog to the user to pick one to proceed with. + createAndShowProfileSelectDialog(preference.getIntent(), userHandles); + } + + private UserAdapter.OnClickListener createProfileDialogClickCallback( + Intent intent, List userHandles) { + return (int position) -> { + mContext.startActivityAsUser(intent, userHandles.get(position)); + if (mProfileSelectDialog.get() != null) { + mProfileSelectDialog.get().dismiss(); + } + }; + } + + private void createAndShowProfileSelectDialog(Intent intent, List userHandles) { + Dialog profileSelectDialog = ProfileSelectDialog.createDialog( + mContext, userHandles, createProfileDialogClickCallback(intent, userHandles)); + mProfileSelectDialog = new WeakReference<>(profileSelectDialog); + profileSelectDialog.show(); + } + /** * Create an {@link Intent} for the activity in the default on-device recognizer service if * there is a properly defined speech recognition xml meta-data for that service. From d41299016e6f7265798fceb839cb856e40651b43 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 6 Jun 2023 21:39:01 +0800 Subject: [PATCH 2/3] Correct typo in the launch via NFC bottom string Bug: 283521954 Test: manual check the string Change-Id: Ia32817ee1735831d0156a84ef7f48af94131dc73 --- res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index a72794dc4b5..9c713f60d64 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10564,7 +10564,7 @@ Allow launch on NFC scan - Allow this app to launch when a NFC tag is scanned.\nIf this permission is on, the app will be available as an option whenever a tag is detected. + Allow this app to launch when an NFC tag is scanned.\nIf this permission is on, the app will be available as an option whenever a tag is detected. Play media to From bf7865b27ecc39e47f41707aaf0feb8c45a42c10 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Wed, 7 Jun 2023 16:47:04 +0800 Subject: [PATCH 3/3] [Settings] Fix crash when user enter bluetooth page quickly. - When SliceManager try to pinSlice, process may not have the permssion yet, so in Androix lib it use try/catch to avoid Security exception. However, if SliceManger quickly unpinSlice after pinSlice, process may still not get the permission yet, then due to no security exception, it cause the settings crash. Bug: 283065718 Test: atest passed Test: Manual test passed Change-Id: I2293fca73e65dfaa34237abe57e0c6a3fe0f62bb --- .../BlockingPrefWithSliceController.java | 16 ++++++++++++++-- .../slices/SlicePreferenceController.java | 19 ++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java index b443047d7e8..93a2747cac0 100644 --- a/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java +++ b/src/com/android/settings/bluetooth/BlockingPrefWithSliceController.java @@ -113,15 +113,27 @@ public class BlockingPrefWithSliceController extends BasePreferenceController im @Override public void onStart() { - if (mLiveData != null) { + if (mLiveData == null) { + return; + } + + try { mLiveData.observeForever(this); + } catch (SecurityException e) { + Log.w(TAG, "observeForever - no permission"); } } @Override public void onStop() { - if (mLiveData != null) { + if (mLiveData == null) { + return; + } + + try { mLiveData.removeObserver(this); + } catch (SecurityException e) { + Log.w(TAG, "removeObserver - no permission"); } } diff --git a/src/com/android/settings/slices/SlicePreferenceController.java b/src/com/android/settings/slices/SlicePreferenceController.java index eb10bd42be1..9a88b5626dc 100644 --- a/src/com/android/settings/slices/SlicePreferenceController.java +++ b/src/com/android/settings/slices/SlicePreferenceController.java @@ -44,7 +44,6 @@ public class SlicePreferenceController extends BasePreferenceController implemen LiveData mLiveData; @VisibleForTesting SlicePreference mSlicePreference; - private boolean mIsObservering = false; private Uri mUri; public SlicePreferenceController(Context context, String preferenceKey) { @@ -74,9 +73,14 @@ public class SlicePreferenceController extends BasePreferenceController implemen @Override public void onStart() { - if (mLiveData != null && !mIsObservering) { - mIsObservering = true; + if (mLiveData == null) { + return; + } + + try { mLiveData.observeForever(this); + } catch (SecurityException e) { + Log.w(TAG, "observeForever - no permission"); } } @@ -91,9 +95,14 @@ public class SlicePreferenceController extends BasePreferenceController implemen } private void removeLiveDataObserver() { - if (mLiveData != null && mIsObservering && mLiveData.hasActiveObservers()) { - mIsObservering = false; + if (mLiveData == null) { + return; + } + + try { mLiveData.removeObserver(this); + } catch (SecurityException e) { + Log.w(TAG, "removeLiveDataObserver - no permission"); } } }