Merge "Add missing required permissions for Settings" into main
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 25aa508..19e774c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5140,9 +5140,9 @@
<activity
android:name=".privatespace.PrivateSpaceAuthenticationActivity"
android:theme="@*android:style/Theme.DeviceDefault.Settings.Dialog.NoActionBar"
- android:exported="true">
+ android:exported="false">
<intent-filter>
- <action android:name="com.android.settings.action.PRIVATE_SPACE_SETUP_FLOW" />
+ <action android:name="com.android.settings.action.OPEN_PRIVATE_SPACE_SETTINGS" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
@@ -5154,6 +5154,14 @@
android:exported="false">
</activity>
+ <receiver android:name=".privatespace.PrivateSpaceBroadcastReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.PRE_BOOT_COMPLETED"/>
+ <action android:name="android.intent.action.BOOT_COMPLETED"/>
+ </intent-filter>
+ </receiver>
+
<activity-alias android:name="UsageStatsActivity"
android:exported="true"
android:label="@string/testing_usage_stats"
diff --git a/res/layout/preference_progress_category.xml b/res/layout/preference_progress_category.xml
index b04f5be..192f601 100644
--- a/res/layout/preference_progress_category.xml
+++ b/res/layout/preference_progress_category.xml
@@ -54,6 +54,7 @@
<ProgressBar
android:id="@+id/scanning_progress"
style="?android:attr/progressBarStyleSmallTitle"
+ android:focusable="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
diff --git a/res/xml/display_settings.xml b/res/xml/display_settings.xml
index a59b30b..0c6d673 100644
--- a/res/xml/display_settings.xml
+++ b/res/xml/display_settings.xml
@@ -36,7 +36,10 @@
android:key="auto_brightness_entry"
android:title="@string/auto_brightness_title"
android:fragment="com.android.settings.display.AutoBrightnessSettings"
- settings:controller="com.android.settings.display.AutoBrightnessPreferenceController"/>
+ settings:useAdminDisabledSummary="true"
+ settings:userRestriction="no_config_brightness"
+ settings:controller="com.android.settings.display.AutoBrightnessPreferenceController" />
+
<SwitchPreferenceCompat
android:key="even_dimmer_activated"
android:title="@string/even_dimmer_display_title"
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 7d1e02d..b44d3c7 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -1385,7 +1385,7 @@
* @param activity the Activity need to setup the edge to edge feature.
*/
public static void setupEdgeToEdge(@NonNull FragmentActivity activity) {
- if (com.android.window.flags.Flags.edgeToEdgeByDefault()) {
+ if (com.android.window.flags.Flags.enforceEdgeToEdge()) {
ViewCompat.setOnApplyWindowInsetsListener(activity.findViewById(android.R.id.content),
(v, windowInsets) -> {
Insets insets = windowInsets.getInsets(
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index 8250f70..0ee3986 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -136,12 +136,8 @@
@Override
public boolean onPreferenceClick(Preference preference) {
mMetricsFeatureProvider.logClickedPreference(preference, mMetricsCategory);
- final CachedBluetoothDevice device =
- ((BluetoothDevicePreference) preference).getBluetoothDevice();
- FeatureFactory.getFeatureFactory()
- .getAudioSharingFeatureProvider()
- .handleMediaDeviceOnClick(mLocalManager);
- return device.setActive();
+ mDevicePreferenceCallback.onDeviceClick(preference);
+ return true;
}
@Override
diff --git a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
index 0535d15..56ef4b0 100644
--- a/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
+++ b/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupController.java
@@ -35,6 +35,7 @@
import com.android.settings.R;
import com.android.settings.accessibility.HearingAidUtils;
import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
+import com.android.settings.bluetooth.BluetoothDevicePreference;
import com.android.settings.bluetooth.BluetoothDeviceUpdater;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
@@ -150,6 +151,13 @@
}
}
+ @Override
+ public void onDeviceClick(Preference preference) {
+ final CachedBluetoothDevice cachedDevice =
+ ((BluetoothDevicePreference) preference).getBluetoothDevice();
+ cachedDevice.setActive();
+ }
+
public void init(DashboardFragment fragment) {
mFragmentManager = fragment.getParentFragmentManager();
mBluetoothDeviceUpdater =
diff --git a/src/com/android/settings/connecteddevice/DevicePreferenceCallback.java b/src/com/android/settings/connecteddevice/DevicePreferenceCallback.java
index 7ee2063..c91e2a0 100644
--- a/src/com/android/settings/connecteddevice/DevicePreferenceCallback.java
+++ b/src/com/android/settings/connecteddevice/DevicePreferenceCallback.java
@@ -18,19 +18,26 @@
import androidx.preference.Preference;
-/**
- * Callback to add or remove {@link Preference} in device group.
- */
+/** Callback to add or remove {@link Preference} in device group. */
public interface DevicePreferenceCallback {
/**
* Called when a device(i.e. bluetooth, usb) is added
+ *
* @param preference present the device
*/
void onDeviceAdded(Preference preference);
/**
* Called when a device(i.e. bluetooth, usb) is removed
+ *
* @param preference present the device
*/
void onDeviceRemoved(Preference preference);
+
+ /**
+ * Called when a device(i.e. bluetooth, usb) is click
+ *
+ * @param preference present the device
+ */
+ default void onDeviceClick(Preference preference) {}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
index 9fe4d50..50812e9 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProvider.java
@@ -50,7 +50,4 @@
*/
boolean isAudioSharingFilterMatched(
@NonNull CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager);
-
- /** Handle preference onClick in "Media devices" section. */
- void handleMediaDeviceOnClick(LocalBluetoothManager localBtManager);
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
index 259ed7a..96200db 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingFeatureProviderImpl.java
@@ -52,7 +52,4 @@
@NonNull CachedBluetoothDevice cachedDevice, LocalBluetoothManager localBtManager) {
return false;
}
-
- @Override
- public void handleMediaDeviceOnClick(LocalBluetoothManager localBtManager) {}
}
diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
index d925de3..bf21183 100644
--- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java
+++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java
@@ -18,11 +18,15 @@
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
import android.content.Context;
+import android.os.Process;
+import android.os.UserManager;
import android.provider.Settings;
+import androidx.preference.Preference;
+
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
-
+import com.android.settingslib.PrimarySwitchPreference;
public class AutoBrightnessPreferenceController extends TogglePreferenceController {
@@ -56,6 +60,17 @@
}
@Override
+ public void updateState(Preference preference) {
+ super.updateState(preference);
+ PrimarySwitchPreference pref = (PrimarySwitchPreference) preference;
+ if (pref.isEnabled() && UserManager.get(mContext).hasBaseUserRestriction(
+ UserManager.DISALLOW_CONFIG_BRIGHTNESS, Process.myUserHandle())) {
+ pref.setEnabled(false);
+ pref.setSwitchEnabled(false);
+ }
+ }
+
+ @Override
public CharSequence getSummary() {
return mContext.getText(isChecked()
? R.string.auto_brightness_summary_on
diff --git a/src/com/android/settings/network/MobileNetworkRepository.java b/src/com/android/settings/network/MobileNetworkRepository.java
index 381f3c1..672e2ed 100644
--- a/src/com/android/settings/network/MobileNetworkRepository.java
+++ b/src/com/android/settings/network/MobileNetworkRepository.java
@@ -245,7 +245,11 @@
}
private void createTelephonyManagerBySubId(int subId) {
- if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ || mTelephonyCallbackMap.containsKey(subId)) {
+ if (DEBUG) {
+ Log.d(TAG, "createTelephonyManagerBySubId: directly return for subId = " + subId);
+ }
return;
}
PhoneCallStateTelephonyCallback
diff --git a/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java b/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java
index 53d6b22..f61f7bb 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceAuthenticationActivity.java
@@ -50,7 +50,7 @@
* This class represents an activity responsible for user authentication before starting the private
* space setup flow or accessing the private space settings page if already created. Also prompts
* user to set a device lock if not set with an alert dialog. This can be launched using the intent
- * com.android.settings.action.PRIVATE_SPACE_SETUP_FLOW.
+ * com.android.settings.action.OPEN_PRIVATE_SPACE_SETTINGS.
*/
public class PrivateSpaceAuthenticationActivity extends FragmentActivity {
private static final String TAG = "PrivateSpaceAuthCheck";
diff --git a/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java b/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java
new file mode 100644
index 0000000..4c59ab9
--- /dev/null
+++ b/src/com/android/settings/privatespace/PrivateSpaceBroadcastReceiver.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2024 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.privatespace;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.UserManager;
+import android.util.Log;
+
+/** Broadcast receiver for enabling/disabling Private Space Root Activity. */
+public class PrivateSpaceBroadcastReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "PrivateSpaceBroadcastReceiver";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.blockPrivateSpaceCreation()) {
+ Log.d("Here", "Intent: " + intent.getAction());
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(context);
+ // Disable the PrivateSpaceAuthenticationActivity when
+ // -Private Profile is not present and
+ // -Private Profile cannot be added.
+ final int enableState = privateSpaceMaintainer.doesPrivateSpaceExist()
+ || context.getSystemService(UserManager.class).canAddPrivateProfile()
+ ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+ ComponentName privateSpaceAuth = new ComponentName(context,
+ PrivateSpaceAuthenticationActivity.class);
+ Log.d(TAG, "Setting component " + privateSpaceAuth + " state: " + enableState);
+ context.getPackageManager().setComponentEnabledSetting(
+ privateSpaceAuth,
+ enableState,
+ PackageManager.DONT_KILL_APP);
+ }
+ }
+}
diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
index 3fb9b15..6623516 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
@@ -155,7 +155,7 @@
return true;
}
- List<UserInfo> users = mUserManager.getProfiles(0);
+ List<UserInfo> users = mUserManager.getProfiles(mContext.getUserId());
for (UserInfo user : users) {
if (user.isPrivateProfile()) {
mUserHandle = user.getUserHandle();
diff --git a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
index 4e1741a..3272f12 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceSafetySource.java
@@ -44,11 +44,27 @@
return;
}
- // Check the profile type - we don't want to show this for anything other than primary user.
UserManager userManager = context.getSystemService(UserManager.class);
- if (userManager != null && !userManager.isMainUser()) {
- Log.i(TAG, "setSafetySourceData not main user");
- return;
+ PrivateSpaceMaintainer privateSpaceMaintainer =
+ PrivateSpaceMaintainer.getInstance(context);
+ if (android.multiuser.Flags.enablePrivateSpaceFeatures()
+ && android.multiuser.Flags.blockPrivateSpaceCreation()) {
+ // Do not add the entry point when
+ // -Private Profile is not present and
+ // -Private Profile cannot be added.
+ if (!privateSpaceMaintainer.doesPrivateSpaceExist()
+ && userManager != null
+ && !userManager.canAddPrivateProfile()) {
+ Log.i(TAG, "Private Space not allowed for user " + context.getUser());
+ return;
+ }
+ } else {
+ // Check the profile type - we don't want to show this for anything other than primary
+ // user.
+ if (userManager != null && !userManager.isMainUser()) {
+ Log.i(TAG, "setSafetySourceData not main user");
+ return;
+ }
}
if (!Flags.allowPrivateProfile()
diff --git a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
index 94e4a88..f702894 100644
--- a/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingLabelSim.kt
@@ -56,12 +56,12 @@
imageVector = Icons.Outlined.SignalCellularAlt,
title = stringResource(R.string.sim_onboarding_label_sim_title),
actionButton = BottomAppBarButton(
- stringResource(R.string.sim_onboarding_next),
- nextAction
+ text = stringResource(R.string.sim_onboarding_next),
+ onClick = nextAction
),
dismissButton = BottomAppBarButton(
- stringResource(R.string.cancel),
- cancelAction
+ text = stringResource(R.string.cancel),
+ onClick = cancelAction
),
) {
LabelSimBody(onboardingService)
diff --git a/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt b/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
index 4fad332..0306aad 100644
--- a/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingPrimarySim.kt
@@ -59,12 +59,12 @@
imageVector = Icons.Outlined.SignalCellularAlt,
title = stringResource(id = R.string.sim_onboarding_primary_sim_title),
actionButton = BottomAppBarButton(
- stringResource(id = R.string.done),
- nextAction
+ text = stringResource(id = R.string.done),
+ onClick = nextAction
),
dismissButton = BottomAppBarButton(
- stringResource(id = R.string.cancel),
- cancelAction
+ text = stringResource(id = R.string.cancel),
+ onClick = cancelAction
),
) {
val callsSelectedId = rememberSaveable {
diff --git a/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt b/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
index 5e71b12..b033a28 100644
--- a/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
+++ b/src/com/android/settings/spa/network/SimOnboardingSelectSim.kt
@@ -16,12 +16,12 @@
package com.android.settings.spa.network
-import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.SignalCellularAlt
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
@@ -29,7 +29,6 @@
import androidx.compose.ui.res.stringResource
import com.android.settings.R
import com.android.settings.network.SimOnboardingService
-import com.android.settings.sim.SimDialogActivity
import com.android.settingslib.spa.framework.theme.SettingsDimension
import com.android.settingslib.spa.widget.preference.CheckboxPreference
import com.android.settingslib.spa.widget.preference.CheckboxPreferenceModel
@@ -46,44 +45,47 @@
cancelAction: () -> Unit,
onboardingService: SimOnboardingService
) {
+ var actionButtonController = rememberSaveable { mutableStateOf(false) }
+
SuwScaffold(
imageVector = Icons.Outlined.SignalCellularAlt,
title = stringResource(id = R.string.sim_onboarding_select_sim_title),
actionButton = BottomAppBarButton(
- stringResource(id = R.string.sim_onboarding_next),
- nextAction
+ text = stringResource(id = R.string.sim_onboarding_next),
+ enabled = actionButtonController.value,
+ onClick = nextAction
),
dismissButton = BottomAppBarButton(
- stringResource(id = R.string.cancel),
- cancelAction
+ text = stringResource(id = R.string.cancel),
+ onClick = cancelAction
),
) {
- selectSimBody(onboardingService)
+ SelectSimBody(onboardingService, actionButtonController)
}
}
@Composable
-private fun selectSimBody(onboardingService: SimOnboardingService) {
+private fun SelectSimBody(
+ onboardingService: SimOnboardingService,
+ isFinished: MutableState<Boolean>
+) {
Column(Modifier.padding(SettingsDimension.itemPadding)) {
SettingsBody(stringResource(id = R.string.sim_onboarding_select_sim_msg))
}
- var isFinished = rememberSaveable { mutableStateOf(false) }
isFinished.value = onboardingService.isSimSelectionFinished
for (subInfo in onboardingService.getSelectableSubscriptionInfoList()) {
var title = onboardingService.getSubscriptionInfoDisplayName(subInfo)
- var summaryNumber =
- subInfo.number // TODO using the SubscriptionUtil.getFormattedPhoneNumber
+ val phoneNumber = phoneNumber(subInfo)
var checked = rememberSaveable {
mutableStateOf(
onboardingService.getSelectedSubscriptionInfoList().contains(subInfo)
)
}
-
CheckboxPreference(remember {
object : CheckboxPreferenceModel {
override val title = title
override val summary: () -> String
- get() = { summaryNumber }
+ get() = { phoneNumber.value ?: "" }
override val checked = { checked.value }
override val onCheckedChange = { newChecked: Boolean ->
checked.value = newChecked
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
index 404dbe5..edefec2 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityGestureNavigationTutorialTest.java
@@ -54,11 +54,10 @@
import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.LooperMode;
+import org.robolectric.shadows.ShadowLooper;
/** Tests for {@link AccessibilityGestureNavigationTutorial}. */
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
public final class AccessibilityGestureNavigationTutorialTest {
@Rule
@@ -178,6 +177,7 @@
final AlertDialog alertDialog =
createAccessibilityTutorialDialog(mContext, mShortcutTypes);
alertDialog.show();
+ ShadowLooper.idleMainLooper();
assertThat(alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility())
.isEqualTo(View.GONE);
@@ -204,6 +204,7 @@
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
assertThat(alertDialog.isShowing()).isFalse();
}
@@ -216,6 +217,7 @@
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
verify(mOnClickListener).onClick(alertDialog, DialogInterface.BUTTON_POSITIVE);
}
@@ -228,6 +230,7 @@
alertDialog.show();
alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
+ ShadowLooper.idleMainLooper();
final Intent intent = shadowOf(activity).peekNextStartedActivity();
assertThat(intent.getComponent().getClassName()).isEqualTo(SubSettings.class.getName());
@@ -243,6 +246,7 @@
showGestureNavigationTutorialDialog(mContext, mOnDismissListener);
alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
assertThat(alertDialog.isShowing()).isFalse();
verify(mOnDismissListener).onDismiss(alertDialog);
diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
index b13d0e4..08cbaae 100644
--- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest.java
@@ -53,15 +53,14 @@
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLooper;
/**
* Tests for {@link AccessibilityQuickSettingsPrimarySwitchPreferenceController}.
*/
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
public class AccessibilityQuickSettingsPrimarySwitchPreferenceControllerTest {
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
@@ -160,6 +159,7 @@
mController.onCreate(savedInstanceState);
mController.displayPreference(mScreen);
+ ShadowLooper.idleMainLooper();
assertThat(getLatestPopupWindow().isShowing()).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/HearingAidDialogFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingAidDialogFragmentTest.java
index adfd573..9d37c2a 100644
--- a/tests/robotests/src/com/android/settings/accessibility/HearingAidDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingAidDialogFragmentTest.java
@@ -44,11 +44,10 @@
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
+import org.robolectric.shadows.ShadowLooper;
/** Tests for {@link HearingAidDialogFragment}. */
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
ShadowAlertDialogCompat.class,
@@ -81,6 +80,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
final Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
@@ -93,6 +93,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
+ ShadowLooper.idleMainLooper();
assertThat(dialog.isShowing()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/HearingAidPairingDialogFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/HearingAidPairingDialogFragmentTest.java
index d082b1f..7abf9a4 100644
--- a/tests/robotests/src/com/android/settings/accessibility/HearingAidPairingDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/HearingAidPairingDialogFragmentTest.java
@@ -60,12 +60,11 @@
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowLooper;
/** Tests for {@link HearingAidPairingDialogFragment}. */
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowAlertDialogCompat.class,
com.android.settings.testutils.shadow.ShadowBluetoothAdapter.class,
@@ -122,6 +121,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
final Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
@@ -135,6 +135,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick();
+ ShadowLooper.idleMainLooper();
final Intent intent = shadowOf(mActivity).getNextStartedActivity();
assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
@@ -147,6 +148,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_NEGATIVE).performClick();
+ ShadowLooper.idleMainLooper();
assertThat(dialog.isShowing()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
index 14306e0..af72beb 100644
--- a/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/PreviewSizeSeekBarControllerTest.java
@@ -61,15 +61,14 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLooper;
/**
* Tests for {@link PreviewSizeSeekBarController}.
*/
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {ShadowInteractionJankMonitor.class})
public class PreviewSizeSeekBarControllerTest {
@@ -194,8 +193,9 @@
mSeekBarPreference.setProgress(mSeekBarPreference.getMax());
mSeekBarPreference.onProgressChanged(new SeekBar(mContext), /* progress= */
0, /* fromUser= */ false);
+ ShadowLooper.idleMainLooper();
- verify(mInteractionListener).notifyPreferenceChanged();
+ verify(mInteractionListener).onProgressChanged();
}
@Test
@@ -259,6 +259,7 @@
mSeekBarController.onCreate(savedInstanceState);
mSeekBarController.displayPreference(mPreferenceScreen);
+ ShadowLooper.idleMainLooper();
assertThat(getLatestPopupWindow().isShowing()).isTrue();
}
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreferenceFragmentTest.java
index 8212ba2..0230e26 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreferenceFragmentTest.java
@@ -52,7 +52,7 @@
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
+import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowToast;
import java.util.ArrayList;
@@ -61,7 +61,6 @@
/** Tests for {@link TextReadingPreferenceFragment}. */
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {
com.android.settings.testutils.shadow.ShadowFragment.class,
})
@@ -98,6 +97,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
+ ShadowLooper.idleMainLooper();
assertThat(mFragment.mNeedResetSettings).isTrue();
}
@@ -112,6 +112,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
+ ShadowLooper.idleMainLooper();
verify(listener1).resetState();
verify(listener2).resetState();
@@ -126,6 +127,7 @@
dialog.show();
dialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
+ ShadowLooper.idleMainLooper();
assertThat(ShadowToast.getTextOfLatestToast())
.isEqualTo(mContext.getString(R.string.accessibility_text_reading_reset_message));
diff --git a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
index 6fb1c3f..3d0f223 100644
--- a/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragmentTest.java
@@ -74,15 +74,14 @@
import org.mockito.Spy;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
-import org.robolectric.annotation.LooperMode;
import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.shadows.ShadowLooper;
import java.util.Locale;
/** Tests for {@link ToggleFeaturePreferenceFragment} */
@RunWith(RobolectricTestRunner.class)
-@LooperMode(LooperMode.Mode.LEGACY)
@Config(shadows = {
ShadowFragment.class,
})
@@ -252,6 +251,7 @@
final CheckBox hardwareTypeCheckBox = dialogHardwareView.findViewById(R.id.checkbox);
hardwareTypeCheckBox.setChecked(true);
dialog.getButton(DialogInterface.BUTTON_POSITIVE).callOnClick();
+ ShadowLooper.idleMainLooper();
final boolean skipTimeoutRestriction = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.SKIP_ACCESSIBILITY_SHORTCUT_DIALOG_TIMEOUT_RESTRICTION, 0) != 0;
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
index 5a7e247..6aa2831 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
@@ -372,6 +372,6 @@
public void onClick_Preference_setActive() {
mBluetoothDeviceUpdater.onPreferenceClick(mPreference);
- verify(mCachedBluetoothDevice).setActive();
+ verify(mDevicePreferenceCallback).onDeviceClick(mPreference);
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
index 357420a..8f07cca 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/AvailableMediaDeviceGroupControllerTest.java
@@ -32,9 +32,9 @@
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
import android.media.AudioManager;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.util.Pair;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
@@ -46,6 +46,7 @@
import com.android.settings.R;
import com.android.settings.bluetooth.AvailableMediaBluetoothDeviceUpdater;
+import com.android.settings.bluetooth.BluetoothDevicePreference;
import com.android.settings.bluetooth.Utils;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowAudioManager;
@@ -64,7 +65,8 @@
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -79,11 +81,11 @@
ShadowAlertDialogCompat.class,
})
public class AvailableMediaDeviceGroupControllerTest {
- @Rule
- public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+ @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
private static final String TEST_DEVICE_ADDRESS = "00:A1:A1:A1:A1:A1";
private static final String PREFERENCE_KEY_1 = "pref_key_1";
+ private static final String TEST_DEVICE_NAME = "test";
@Mock private AvailableMediaBluetoothDeviceUpdater mAvailableMediaBluetoothDeviceUpdater;
@Mock private PreferenceScreen mPreferenceScreen;
@@ -96,6 +98,9 @@
@Mock private LocalBluetoothManager mLocalBluetoothManager;
@Mock private CachedBluetoothDeviceManager mCachedDeviceManager;
@Mock private CachedBluetoothDevice mCachedBluetoothDevice;
+ @Mock private BluetoothDevice mDevice;
+ @Mock
+ private Drawable mDrawable;
private PreferenceGroup mPreferenceGroup;
private Context mContext;
@@ -107,8 +112,6 @@
@Before
public void setUp() {
- MockitoAnnotations.initMocks(this);
-
mContext = spy(RuntimeEnvironment.application);
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
@@ -262,4 +265,19 @@
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog.isShowing()).isTrue();
}
+
+ @Test
+ public void onDeviceClick_setActive() {
+ when(mCachedBluetoothDevice.getDevice()).thenReturn(mDevice);
+ Pair<Drawable, String> pair = new Pair<>(mDrawable, TEST_DEVICE_NAME);
+ when(mCachedBluetoothDevice.getDrawableWithDescription()).thenReturn(pair);
+ BluetoothDevicePreference preference =
+ new BluetoothDevicePreference(
+ mContext,
+ mCachedBluetoothDevice,
+ true,
+ BluetoothDevicePreference.SortType.TYPE_NO_SORT);
+ mAvailableMediaDeviceGroupController.onDeviceClick(preference);
+ verify(mCachedBluetoothDevice).setActive();
+ }
}
diff --git a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
index e063f69..5b7778e 100644
--- a/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
+++ b/tests/spa_unit/src/com/android/settings/spa/network/SimOnboardingSelectSimTest.kt
@@ -18,19 +18,31 @@
import android.content.Context
import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.platform.LocalLifecycleOwner
+import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsOn
+import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
+import androidx.lifecycle.testing.TestLifecycleOwner
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.android.settings.network.SimOnboardingService
+import com.android.settingslib.spa.testutils.waitUntilExists
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
import org.mockito.kotlin.stub
import org.mockito.kotlin.verify
@@ -38,8 +50,20 @@
class SimOnboardingSelectSimTest {
@get:Rule
val composeTestRule = createComposeRule()
+ private val mockSubscriptionManager = mock<SubscriptionManager> {
+ on { addOnSubscriptionsChangedListener(any(), any()) } doAnswer {
+ val listener = it.arguments[1] as SubscriptionManager.OnSubscriptionsChangedListener
+ listener.onSubscriptionsChanged()
+ }
+ on { getPhoneNumber(SUB_ID_1) } doReturn NUMBER_1
+ on { getPhoneNumber(SUB_ID_2) } doReturn NUMBER_2
+ on { getPhoneNumber(SUB_ID_3) } doReturn NUMBER_3
+ }
- private val context: Context = ApplicationProvider.getApplicationContext()
+ private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
+ on { getSystemService(SubscriptionManager::class.java) } doReturn mockSubscriptionManager
+ }
+
private var mockSimOnboardingService = mock<SimOnboardingService> {
on { targetSubId }.doReturn(-1)
on { targetSubInfo }.doReturn(null)
@@ -78,6 +102,24 @@
@Test
fun simOnboardingSelectSimImpl_clickNextAction_verifyNextAction() {
+ mockSimOnboardingService.stub {
+ on { targetSubId }.doReturn(SUB_ID_1)
+ on { targetSubInfo }.doReturn(SUB_INFO_1)
+ on { availableSubInfoList }.doReturn(listOf(SUB_INFO_1, SUB_INFO_2, SUB_INFO_3))
+ on { activeSubInfoList }.doReturn(listOf(SUB_INFO_2, SUB_INFO_3))
+ on { getSelectableSubscriptionInfoList() }.doReturn(
+ listOf(
+ SUB_INFO_1,
+ SUB_INFO_2,
+ SUB_INFO_3
+ )
+ )
+ on { getSubscriptionInfoDisplayName(SUB_INFO_1) }.doReturn(DISPLAY_NAME_1)
+ on { getSubscriptionInfoDisplayName(SUB_INFO_2) }.doReturn(DISPLAY_NAME_2)
+ on { getSubscriptionInfoDisplayName(SUB_INFO_3) }.doReturn(DISPLAY_NAME_3)
+ on {isSimSelectionFinished}.doReturn(true)
+ }
+
composeTestRule.setContent {
SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService)
}
@@ -85,7 +127,7 @@
composeTestRule.onNodeWithText(context.getString(R.string.sim_onboarding_next))
.performClick()
- verify(nextAction)
+ verify(nextAction)()
}
@Test
@@ -97,7 +139,7 @@
composeTestRule.onNodeWithText(context.getString(R.string.cancel))
.performClick()
- verify(cancelAction)
+ verify(cancelAction)()
}
@Test
@@ -120,15 +162,23 @@
}
composeTestRule.setContent {
- SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService)
+ CompositionLocalProvider(
+ LocalContext provides context,
+ LocalLifecycleOwner provides TestLifecycleOwner(),
+ ) {
+ SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService)
+ }
}
+// composeTestRule.setContent {
+// SimOnboardingSelectSimImpl(nextAction, cancelAction, mockSimOnboardingService)
+// }
composeTestRule.onNodeWithText(DISPLAY_NAME_1).assertIsDisplayed()
- composeTestRule.onNodeWithText(NUMBER_1).assertIsDisplayed()
+ composeTestRule.waitUntilExists(hasText(NUMBER_1))
composeTestRule.onNodeWithText(DISPLAY_NAME_2).assertIsDisplayed()
- composeTestRule.onNodeWithText(NUMBER_2).assertIsDisplayed()
+ composeTestRule.waitUntilExists(hasText(NUMBER_2))
composeTestRule.onNodeWithText(DISPLAY_NAME_3).assertIsDisplayed()
- composeTestRule.onNodeWithText(NUMBER_3).assertIsDisplayed()
+ composeTestRule.waitUntilExists(hasText(NUMBER_3))
}
private companion object {
@@ -141,24 +191,28 @@
const val NUMBER_1 = "000000001"
const val NUMBER_2 = "000000002"
const val NUMBER_3 = "000000003"
+ const val MCC = "310"
const val PRIMARY_SIM_ASK_EVERY_TIME = -1
val SUB_INFO_1: SubscriptionInfo = SubscriptionInfo.Builder().apply {
setId(SUB_ID_1)
setDisplayName(DISPLAY_NAME_1)
setNumber(NUMBER_1)
+ setMcc(MCC)
}.build()
val SUB_INFO_2: SubscriptionInfo = SubscriptionInfo.Builder().apply {
setId(SUB_ID_2)
setDisplayName(DISPLAY_NAME_2)
setNumber(NUMBER_2)
+ setMcc(MCC)
}.build()
val SUB_INFO_3: SubscriptionInfo = SubscriptionInfo.Builder().apply {
setId(SUB_ID_3)
setDisplayName(DISPLAY_NAME_3)
setNumber(NUMBER_3)
+ setMcc(MCC)
}.build()
}
}