diff --git a/src/com/android/settings/bluetooth/QrCodeScanModeActivity.java b/src/com/android/settings/bluetooth/QrCodeScanModeActivity.java index 5c5b61f091c..690c07ec560 100644 --- a/src/com/android/settings/bluetooth/QrCodeScanModeActivity.java +++ b/src/com/android/settings/bluetooth/QrCodeScanModeActivity.java @@ -30,7 +30,15 @@ import com.android.settingslib.R; import com.android.settingslib.bluetooth.BluetoothBroadcastUtils; import com.android.settingslib.bluetooth.BluetoothUtils; -//TODO (b/232365943): Add test case for tthe QrCode UI. +/** + * Finding a broadcast through QR code. + * + * To use intent action {@link BluetoothBroadcastUtils#ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER}, + * specify the bluetooth device sink of the broadcast to be provisioned in + * {@link BluetoothBroadcastUtils#EXTRA_BLUETOOTH_DEVICE_SINK} and check the operation for all + * coordinated set members throughout one session or not by + * {@link BluetoothBroadcastUtils#EXTRA_BLUETOOTH_SINK_IS_GROUP}. + */ public class QrCodeScanModeActivity extends QrCodeScanModeBaseActivity { private static final boolean DEBUG = BluetoothUtils.D; private static final String TAG = "QrCodeScanModeActivity"; diff --git a/src/com/android/settings/core/SettingsBaseActivity.java b/src/com/android/settings/core/SettingsBaseActivity.java index 7842459f2e1..322b971cfad 100644 --- a/src/com/android/settings/core/SettingsBaseActivity.java +++ b/src/com/android/settings/core/SettingsBaseActivity.java @@ -260,6 +260,9 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa } private int getTransitionType(Intent intent) { + if (intent == null) { + return TransitionType.TRANSITION_NONE; + } return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_NONE); } } diff --git a/src/com/android/settings/network/SubscriptionsPreferenceController.java b/src/com/android/settings/network/SubscriptionsPreferenceController.java index 44ad411c832..7ba16e31f45 100644 --- a/src/com/android/settings/network/SubscriptionsPreferenceController.java +++ b/src/com/android/settings/network/SubscriptionsPreferenceController.java @@ -456,7 +456,11 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl } @Override - public void onTelephonyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) { + public void onTelephonyDisplayInfoChanged(int subId, + TelephonyDisplayInfo telephonyDisplayInfo) { + if (subId != mSubsPrefCtrlInjector.getDefaultDataSubscriptionId()) { + return; + } mTelephonyDisplayInfo = telephonyDisplayInfo; update(); } diff --git a/src/com/android/settings/network/telephony/TelephonyDisplayInfoListener.java b/src/com/android/settings/network/telephony/TelephonyDisplayInfoListener.java index 334da3c931f..57a012c71b8 100644 --- a/src/com/android/settings/network/telephony/TelephonyDisplayInfoListener.java +++ b/src/com/android/settings/network/telephony/TelephonyDisplayInfoListener.java @@ -37,8 +37,9 @@ public class TelephonyDisplayInfoListener { private TelephonyManager mBaseTelephonyManager; private Callback mCallback; private Map mListeners; + private Map mDisplayInfos; - private TelephonyDisplayInfo mTelephonyDisplayInfo = + private static final TelephonyDisplayInfo mDefaultTelephonyDisplayInfo = new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE); /** @@ -48,19 +49,20 @@ public class TelephonyDisplayInfoListener { /** * Used to notify TelephonyDisplayInfo change. */ - void onTelephonyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo); + void onTelephonyDisplayInfoChanged(int subId, TelephonyDisplayInfo telephonyDisplayInfo); } public TelephonyDisplayInfoListener(Context context, Callback callback) { mBaseTelephonyManager = context.getSystemService(TelephonyManager.class); mCallback = callback; mListeners = new HashMap<>(); + mDisplayInfos = new HashMap<>(); } /** * Get TelephonyDisplayInfo. */ - public TelephonyDisplayInfo getTelephonyDisplayInfo() { - return mTelephonyDisplayInfo; + public TelephonyDisplayInfo getTelephonyDisplayInfo(int subId) { + return mDisplayInfos.get(subId); } /** Resumes listening telephony display info changes to the set of ids from the last call to @@ -85,15 +87,17 @@ public class TelephonyDisplayInfoListener { for (int idToRemove : Sets.difference(currentIds, ids)) { stopListening(idToRemove); mListeners.remove(idToRemove); + mDisplayInfos.remove(idToRemove); } for (int idToAdd : Sets.difference(ids, currentIds)) { PhoneStateListener listener = new PhoneStateListener() { @Override public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) { - mTelephonyDisplayInfo = telephonyDisplayInfo; - mCallback.onTelephonyDisplayInfoChanged(telephonyDisplayInfo); + mDisplayInfos.put(idToAdd, telephonyDisplayInfo); + mCallback.onTelephonyDisplayInfoChanged(idToAdd, telephonyDisplayInfo); } }; + mDisplayInfos.put(idToAdd, mDefaultTelephonyDisplayInfo); mListeners.put(idToAdd, listener); startListening(idToAdd); } diff --git a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java index 58afeb00a9b..ed8dc24063e 100644 --- a/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java +++ b/src/com/android/settings/network/telephony/gsm/AutoSelectPreferenceController.java @@ -52,6 +52,8 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; /** * Preference controller for "Auto Select Network" @@ -70,11 +72,17 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon ProgressDialog mProgressDialog; @VisibleForTesting SwitchPreference mSwitchPreference; + private AtomicBoolean mUpdatingConfig; + private int mCacheOfModeStatus; + private AtomicLong mRecursiveUpdate; public AutoSelectPreferenceController(Context context, String key) { super(context, key); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + mRecursiveUpdate = new AtomicLong(); + mUpdatingConfig = new AtomicBoolean(); + mCacheOfModeStatus = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN; mListeners = new ArrayList<>(); mUiHandler = new Handler(Looper.getMainLooper()); mAllowedNetworkTypesListener = new AllowedNetworkTypesListener( @@ -88,7 +96,9 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon displayPreference(mPreferenceScreen); } if (mSwitchPreference != null) { + mRecursiveUpdate.getAndIncrement(); updateState(mSwitchPreference); + mRecursiveUpdate.decrementAndGet(); } } @@ -118,8 +128,13 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon @Override public boolean isChecked() { - return mTelephonyManager.getNetworkSelectionMode() - == TelephonyManager.NETWORK_SELECTION_MODE_AUTO; + if (!mUpdatingConfig.get()) { + mCacheOfModeStatus = mTelephonyManager.getNetworkSelectionMode(); + for (OnNetworkSelectModeListener lsn : mListeners) { + lsn.onNetworkSelectModeUpdated(mCacheOfModeStatus); + } + } + return mCacheOfModeStatus == TelephonyManager.NETWORK_SELECTION_MODE_AUTO; } @Override @@ -147,6 +162,10 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon @Override public boolean setChecked(boolean isChecked) { + if (mRecursiveUpdate.get() != 0) { + // Changing from software are allowed and changing presentation only. + return true; + } if (isChecked) { setAutomaticSelectionMode(); } else { @@ -171,18 +190,17 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon } return ThreadUtils.postOnBackgroundThread(() -> { // set network selection mode in background + mUpdatingConfig.set(true); mTelephonyManager.setNetworkSelectionModeAutomatic(); - final int mode = mTelephonyManager.getNetworkSelectionMode(); + mUpdatingConfig.set(false); //Update UI in UI thread final long durationMillis = SystemClock.elapsedRealtime() - startMillis; mUiHandler.postDelayed(() -> { + mRecursiveUpdate.getAndIncrement(); mSwitchPreference.setEnabled(true); - mSwitchPreference.setChecked( - mode == TelephonyManager.NETWORK_SELECTION_MODE_AUTO); - for (OnNetworkSelectModeListener lsn : mListeners) { - lsn.onNetworkSelectModeChanged(); - } + mSwitchPreference.setChecked(isChecked()); + mRecursiveUpdate.decrementAndGet(); dismissProgressBar(); }, Math.max(MINIMUM_DIALOG_TIME_MILLIS - durationMillis, 0)); }); @@ -232,11 +250,11 @@ public class AutoSelectPreferenceController extends TelephonyTogglePreferenceCon } /** - * Callback when network select mode is changed + * Callback when network select mode might get updated * * @see TelephonyManager#getNetworkSelectionMode() */ public interface OnNetworkSelectModeListener { - void onNetworkSelectModeChanged(); + void onNetworkSelectModeUpdated(int mode); } } diff --git a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java index 54f5ce15d72..4c5dd953453 100644 --- a/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java +++ b/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceController.java @@ -48,11 +48,13 @@ public class OpenNetworkSelectPagePreferenceController extends private Preference mPreference; private PreferenceScreen mPreferenceScreen; private AllowedNetworkTypesListener mAllowedNetworkTypesListener; + private int mCacheOfModeStatus; public OpenNetworkSelectPagePreferenceController(Context context, String key) { super(context, key); mTelephonyManager = context.getSystemService(TelephonyManager.class); mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + mCacheOfModeStatus = TelephonyManager.NETWORK_SELECTION_MODE_UNKNOWN; mAllowedNetworkTypesListener = new AllowedNetworkTypesListener( context.getMainExecutor()); mAllowedNetworkTypesListener.setAllowedNetworkTypesListener( @@ -96,7 +98,7 @@ public class OpenNetworkSelectPagePreferenceController extends @Override public void updateState(Preference preference) { super.updateState(preference); - preference.setEnabled(mTelephonyManager.getNetworkSelectionMode() + preference.setEnabled(mCacheOfModeStatus != TelephonyManager.NETWORK_SELECTION_MODE_AUTO); Intent intent = new Intent(); @@ -125,7 +127,10 @@ public class OpenNetworkSelectPagePreferenceController extends } @Override - public void onNetworkSelectModeChanged() { - updateState(mPreference); + public void onNetworkSelectModeUpdated(int mode) { + mCacheOfModeStatus = mode; + if (mPreference != null) { + updateState(mPreference); + } } } diff --git a/tests/unit/src/com/android/settings/bluetooth/QrCodeScanModeActivityTest.java b/tests/unit/src/com/android/settings/bluetooth/QrCodeScanModeActivityTest.java new file mode 100644 index 00000000000..56764e3a145 --- /dev/null +++ b/tests/unit/src/com/android/settings/bluetooth/QrCodeScanModeActivityTest.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2022 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.bluetooth; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Intent; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.settingslib.bluetooth.BluetoothBroadcastUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; + +@RunWith(AndroidJUnit4.class) +public class QrCodeScanModeActivityTest { + + @Mock + private Intent mIntent; + private QrCodeScanModeActivity mActivity; + + @Before + public void setUp() { + mIntent = new Intent(BluetoothBroadcastUtils.ACTION_BLUETOOTH_LE_AUDIO_QR_CODE_SCANNER); + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> { + try { + mActivity = + spy((QrCodeScanModeActivity) InstrumentationRegistry + .getInstrumentation().newActivity( + getClass().getClassLoader(), + QrCodeScanModeActivity.class.getName(), mIntent)); + } catch (Exception e) { + throw new RuntimeException(e); // nothing to do + } + }); + } + + @Test + public void handleIntent_noIntentAction_shouldFinish() { + mIntent = new Intent(); + mActivity.handleIntent(mIntent); + verify(mActivity).finish(); + } + + @Test + public void handleIntent_hasIntentExtra_shouldShowFragment() { + doNothing().when(mActivity).showQrCodeScannerFragment(mIntent); + mActivity.handleIntent(mIntent); + verify(mActivity).showQrCodeScannerFragment(mIntent); + } + +} diff --git a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java index 3bcfcb48fa3..8ebd2b5d390 100644 --- a/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/SubscriptionsPreferenceControllerTest.java @@ -364,7 +364,8 @@ public class SubscriptionsPreferenceControllerTest { mController.onResume(); mController.displayPreference(mPreferenceScreen); - mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo); + mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(), + telephonyDisplayInfo); assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary); } @@ -388,7 +389,8 @@ public class SubscriptionsPreferenceControllerTest { mController.onResume(); mController.displayPreference(mPreferenceScreen); - mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo); + mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(), + telephonyDisplayInfo); assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary); } @@ -414,7 +416,8 @@ public class SubscriptionsPreferenceControllerTest { mController.onResume(); mController.displayPreference(mPreferenceScreen); - mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo); + mController.onTelephonyDisplayInfoChanged(sub.get(0).getSubscriptionId(), + telephonyDisplayInfo); assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary); } diff --git a/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java index f7e311131ce..53ae1b9eb53 100644 --- a/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/gsm/OpenNetworkSelectPagePreferenceControllerTest.java @@ -93,15 +93,18 @@ public class OpenNetworkSelectPagePreferenceControllerTest { mPreference = new Preference(mContext); mController = new OpenNetworkSelectPagePreferenceController(mContext, - "open_network_select"); + "open_network_select") { + @Override + public void updateState(Preference preference) { + super.updateState(mPreference); + } + }; mController.init(mLifecycle, SUB_ID); } @Test public void updateState_modeAuto_disabled() { - when(mTelephonyManager.getNetworkSelectionMode()).thenReturn( - TelephonyManager.NETWORK_SELECTION_MODE_AUTO); - + mController.onNetworkSelectModeUpdated(TelephonyManager.NETWORK_SELECTION_MODE_AUTO); mController.updateState(mPreference); assertThat(mPreference.isEnabled()).isFalse();