Snap for 11578433 from b4f24809eb to 24Q3-release
Change-Id: I291d0cdebc125820fc6320a1054129c6cd331fdf
@@ -1,9 +0,0 @@
|
||||
package: "com.android.settings.flags"
|
||||
container: "system"
|
||||
|
||||
flag {
|
||||
name: "enable_volume_plus_quick_settings"
|
||||
namespace: "pixel_cross_device_control"
|
||||
description: "Gates whether to enable VolumePlus quick settings panel."
|
||||
bug: "309052662"
|
||||
}
|
||||
9
aconfig/settings_threadnetwork_flag_declarations.aconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
package: "com.android.settings.flags"
|
||||
container: "system"
|
||||
|
||||
flag {
|
||||
name: "thread_settings_enabled"
|
||||
namespace: "thread_network"
|
||||
description: "Controls whether the Thread Settings UX is displayed"
|
||||
bug: "329384658"
|
||||
}
|
||||
@@ -17,6 +17,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:shape="rectangle" >
|
||||
<solid android:color="?androidprv:attr/materialColorPrimary"/>
|
||||
<corners android:radius="20dp" />
|
||||
<solid android:color="?androidprv:attr/materialColorPrimaryContainer"/>
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
@@ -17,6 +17,6 @@
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:shape="oval" >
|
||||
<solid android:color="?androidprv:attr/materialColorSurfaceContainer"/>
|
||||
<solid android:color="?androidprv:attr/materialColorSurfaceContainerHighest"/>
|
||||
<size android:width="36dp" android:height="36dp" />
|
||||
</shape>
|
||||
@@ -21,6 +21,6 @@
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="?androidprv:attr/materialColorOnPrimary"
|
||||
android:fillColor="?androidprv:attr/materialColorOnPrimaryContainer"
|
||||
android:pathData="M20.41,4.94l-1.35,-1.35c-0.78,-0.78 -2.05,-0.78 -2.83,0L3,16.82L3,21h4.18L20.41,7.77c0.79,-0.78 0.79,-2.05 0,-2.83zM6.41,19.06L5,19v-1.36l9.82,-9.82 1.41,1.41 -9.82,9.83z"/>
|
||||
</vector>
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="?androidprv:attr/materialColorOnPrimary"
|
||||
android:pathData="M14.43,10l-2.43,-8l-2.43,8l-7.57,0l6.18,4.41l-2.35,7.59l6.17,-4.69l6.18,4.69l-2.35,-7.59l6.17,-4.41z"/>
|
||||
android:pathData="M12,17.27L18.18,21l-1.64,-7.03L22,9.24l-7.19,-0.61L12,2 9.19,8.63 2,9.24l5.46,4.73L5.82,21 12,17.27z"/>
|
||||
</vector>
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:paddingHorizontal="4dp"
|
||||
android:textColor="?androidprv:attr/materialColorOnSurface"
|
||||
android:background="@drawable/color_contrast_preview_tag_background"
|
||||
android:textSize="11sp"
|
||||
@@ -164,7 +165,9 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_article_filled_24dp"
|
||||
android:padding="6dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="6dp"
|
||||
android:paddingVertical="6dp"
|
||||
app:layout_constraintStart_toStartOf="@+id/email_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/email_body" />
|
||||
|
||||
@@ -172,7 +175,7 @@
|
||||
android:id="@+id/email_attachment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingEnd="10dp"
|
||||
android:textColor="?androidprv:attr/materialColorOnTertiaryContainer"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintStart_toEndOf="@+id/ic_article_filled"
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
@@ -36,6 +35,7 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Space
|
||||
|
||||
@@ -4989,7 +4989,7 @@
|
||||
<!-- Title for the accessibility preference to high contrast text. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_toggle_maximize_text_contrast_preference_title">Maximize text contrast</string>
|
||||
<!-- Summary for the accessibility preference to high contrast text. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_toggle_maximize_text_contrast_preference_summary">Change text color to black or white to increase contrast with the background.</string>
|
||||
<string name="accessibility_toggle_maximize_text_contrast_preference_summary">Add a black or white background around text to increase contrast</string>
|
||||
<!-- Title for the accessibility preference to auto update screen magnification. [CHAR LIMIT=35] -->
|
||||
<string name="accessibility_toggle_screen_magnification_auto_update_preference_title">Auto
|
||||
update screen magnification</string>
|
||||
@@ -10479,6 +10479,9 @@
|
||||
<!-- Summary text for 3-button navigation [CHAR LIMIT=NONE] -->
|
||||
<string name="legacy_navigation_summary">Go back, Home, and switch apps with buttons at the bottom of your screen.</string>
|
||||
|
||||
<!-- Accessibility string for gesture nav tutorial button [CHAR_LIMIT=NONE] -->
|
||||
<string name="nav_tutorial_button_description">Start gesture navigation tutorial</string>
|
||||
|
||||
<!-- Search keywords for System Navigation settings. [CHAR_LIMIT=NONE]-->
|
||||
<string name="keywords_system_navigation">system navigation, 2 button navigation, 3 button navigation, gesture navigation, swipe</string>
|
||||
|
||||
@@ -11997,6 +12000,9 @@
|
||||
<string name="confirm_format_ext4_text">16K developer option is supported with ext4 filesystem. Device will be wiped and filesystem will be changed to ext4 after confirmation.</string>
|
||||
<!-- Toast on failure to reformat data to ext4 -->
|
||||
<string name="format_ext4_failure_toast">Failed to reformat and wipe the data partiton to ext4.</string>
|
||||
<!-- Dialog to OEM unlock the device before using 16K developer option -->
|
||||
<string name="confirm_oem_unlock_for_16k_title">OEM unlock required</string>
|
||||
<string name="confirm_oem_unlock_for_16k_text">Device needs to be OEM unlocked before using 16K developer option. OEM unlock will also require formatting userdata. Please OEM unlock the device and try again.</string>
|
||||
|
||||
<!-- DSU Loader. Do not translate. -->
|
||||
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
<style name="SuwAlertDialogThemeCompat" parent="@style/Theme.AppCompat.Dialog.Alert">
|
||||
<!-- Referenced SudThemeGlifV3 style -->
|
||||
<item name="android:textAllCaps">false</item>
|
||||
|
||||
<item name="android:colorBackground">@android:color/system_neutral1_900</item>
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
<!-- copied from Theme.DeviceDefault.Dialog.Alert -->
|
||||
<item name="colorAccent">@*android:color/accent_device_default_dark</item>
|
||||
@@ -243,7 +243,7 @@
|
||||
<style name="SuwAlertDialogThemeCompat.Light" parent="@style/Theme.AppCompat.Light.Dialog.Alert">
|
||||
<!-- Referenced SudThemeGlifV3.Light style -->
|
||||
<item name="android:textAllCaps">false</item>
|
||||
|
||||
<item name="android:colorBackground">@android:color/system_neutral1_50</item>
|
||||
<item name="android:windowSoftInputMode">adjustResize</item>
|
||||
<!-- copied from Theme.DeviceDefault.Light.Dialog.Alert -->
|
||||
<item name="colorAccent">@*android:color/accent_device_default_light</item>
|
||||
|
||||
@@ -69,9 +69,11 @@
|
||||
android:summary="@string/lockscreen_trivial_controls_summary"
|
||||
settings:controller="com.android.settings.display.ControlsTrivialPrivacyPreferenceController"/>
|
||||
|
||||
<!-- Shortcuts -->
|
||||
<Preference
|
||||
android:key="customizable_lock_screen_quick_affordances"
|
||||
android:title="@string/lockscreen_quick_affordances_title"
|
||||
android:summary="@string/summary_placeholder"
|
||||
settings:controller="com.android.settings.display.CustomizableLockScreenQuickAffordancesPreferenceController" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
|
||||
@@ -32,6 +32,8 @@ public class DefaultCombinedPickerPrivate extends DefaultCombinedPicker {
|
||||
|
||||
/** Returns whether the user is handled by this fragment. */
|
||||
public static boolean isUserHandledByFragment(UserManager userManager) {
|
||||
return android.os.Flags.allowPrivateProfile() && userManager.isPrivateProfile();
|
||||
return android.os.Flags.allowPrivateProfile()
|
||||
&& android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
&& userManager.isPrivateProfile();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceScreen
|
||||
import com.android.net.thread.platform.flags.Flags
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.TogglePreferenceController
|
||||
import com.android.settings.flags.Flags
|
||||
import java.util.concurrent.Executor
|
||||
|
||||
/** Controller for the "Thread" toggle in "Connected devices > Connection preferences". */
|
||||
@@ -110,7 +110,7 @@ class ThreadNetworkPreferenceController @VisibleForTesting constructor(
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus(): Int {
|
||||
return if (!Flags.threadEnabledPlatform()) {
|
||||
return if (!Flags.threadSettingsEnabled()) {
|
||||
CONDITIONALLY_UNAVAILABLE
|
||||
} else if (!isThreadSupportedOnDevice) {
|
||||
UNSUPPORTED_ON_DEVICE
|
||||
|
||||
@@ -164,6 +164,7 @@ class AppDataUsageRepository(
|
||||
|
||||
private fun shouldSkipProfile(userManager : UserManager, userHandle: UserHandle): Boolean {
|
||||
if (android.os.Flags.allowPrivateProfile()
|
||||
&& android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
&& android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()) {
|
||||
return (userManager.isQuietModeEnabled(userHandle)
|
||||
&& userManager.getUserProperties(userHandle).showInQuietMode
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.development;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
/** Dialog when user interacts 16K pages developer option and device is not OEM unlocked */
|
||||
public class Enable16KOemUnlockDialog extends InstrumentedDialogFragment
|
||||
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
|
||||
|
||||
public static final String TAG = "Enable16KOemUnlockDialog";
|
||||
|
||||
/** This method is used to prompt user to do OEM unlock before using 16k */
|
||||
public static void show(@NonNull Fragment hostFragment) {
|
||||
final FragmentManager manager = hostFragment.getActivity().getSupportFragmentManager();
|
||||
Fragment existingFragment = manager.findFragmentByTag(TAG);
|
||||
if (existingFragment == null) {
|
||||
existingFragment = new Enable16KOemUnlockDialog();
|
||||
}
|
||||
|
||||
if (existingFragment instanceof Enable16KOemUnlockDialog) {
|
||||
existingFragment.setTargetFragment(hostFragment, 0 /* requestCode */);
|
||||
((Enable16KOemUnlockDialog) existingFragment).show(manager, TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DIALOG_ENABLE_16K_PAGES;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(R.string.confirm_oem_unlock_for_16k_title)
|
||||
.setMessage(R.string.confirm_oem_unlock_for_16k_text)
|
||||
.setPositiveButton(android.R.string.ok, this /* onClickListener */)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull DialogInterface dialog, int buttonId) {
|
||||
// Do nothing. OEM unlock has to be done by user
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(@NonNull DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,10 @@ import android.os.SystemUpdateManager;
|
||||
import android.os.UpdateEngine;
|
||||
import android.os.UpdateEngineStable;
|
||||
import android.os.UpdateEngineStableCallback;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.oemlock.OemLockManager;
|
||||
import android.util.Log;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
@@ -116,6 +119,12 @@ public class Enable16kPagesPreferenceController extends DeveloperOptionsPreferen
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
mEnable16k = (Boolean) newValue;
|
||||
// Prompt user to do oem unlock first
|
||||
if (!isDeviceOEMUnlocked()) {
|
||||
Enable16KOemUnlockDialog.show(mFragment);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isDataf2fs()) {
|
||||
EnableExt4WarningDialog.show(mFragment, this);
|
||||
return false;
|
||||
@@ -418,4 +427,30 @@ public class Enable16kPagesPreferenceController extends DeveloperOptionsPreferen
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isDeviceOEMUnlocked() {
|
||||
// OEM unlock is checked for bootloader, carrier and user. Check all three to ensure
|
||||
// that device is unlocked and it is also allowed by user as well as carrier
|
||||
final OemLockManager oemLockManager = mContext.getSystemService(OemLockManager.class);
|
||||
final UserManager userManager = mContext.getSystemService(UserManager.class);
|
||||
if (oemLockManager == null || userManager == null) {
|
||||
Log.e(TAG, "Required services not found on device to check for OEM unlock state.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If either of device or carrier is not allowed to unlock, return false
|
||||
if (!oemLockManager.isDeviceOemUnlocked()
|
||||
|| !oemLockManager.isOemUnlockAllowedByCarrier()) {
|
||||
Log.e(TAG, "Device is not OEM unlocked or it is not allowed by carrier");
|
||||
return false;
|
||||
}
|
||||
|
||||
final UserHandle userHandle = UserHandle.of(UserHandle.myUserId());
|
||||
if (userManager.hasBaseUserRestriction(UserManager.DISALLOW_FACTORY_RESET, userHandle)) {
|
||||
Log.e(TAG, "Factory reset is not allowed for user.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,6 +247,7 @@ public class SystemNavigationGestureSettings extends RadioButtonPickerFragment i
|
||||
switch (systemNavKey) {
|
||||
case KEY_SYSTEM_NAV_GESTURAL:
|
||||
if (isGestureTutorialAvailable()){
|
||||
videoPref.setContentDescription(R.string.nav_tutorial_button_description);
|
||||
videoPref.setOnPreferenceClickListener(preference -> {
|
||||
startActivity(mLaunchSandboxIntent);
|
||||
return true;
|
||||
|
||||
@@ -68,6 +68,7 @@ public class LocationForPrivateProfilePreferenceController
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (!android.os.Flags.allowPrivateProfile()
|
||||
|| !android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
|| !android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()
|
||||
|| !isPrivateProfileAvailable()) {
|
||||
return CONDITIONALLY_UNAVAILABLE;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.AccessNetworkConstants
|
||||
import android.telephony.NetworkRegistrationInfo
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class NetworkSelectRepository(context: Context, subId: Int) {
|
||||
private val telephonyManager =
|
||||
context.getSystemService(TelephonyManager::class.java)!!.createForSubscriptionId(subId)
|
||||
|
||||
data class NetworkRegistrationAndForbiddenInfo(
|
||||
val networkList: List<NetworkRegistrationInfo>,
|
||||
val forbiddenPlmns: List<String>,
|
||||
)
|
||||
|
||||
/** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
|
||||
fun launchUpdateNetworkRegistrationInfo(
|
||||
lifecycleOwner: LifecycleOwner,
|
||||
action: (NetworkRegistrationAndForbiddenInfo) -> Unit,
|
||||
) {
|
||||
lifecycleOwner.lifecycleScope.launch {
|
||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
withContext(Dispatchers.Default) {
|
||||
getNetworkRegistrationInfo()
|
||||
}?.let(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getNetworkRegistrationInfo(): NetworkRegistrationAndForbiddenInfo? {
|
||||
if (telephonyManager.dataState != TelephonyManager.DATA_CONNECTED) return null
|
||||
// Try to get the network registration states
|
||||
val serviceState = telephonyManager.serviceState ?: return null
|
||||
val networkList = serviceState.getNetworkRegistrationInfoListForTransportType(
|
||||
AccessNetworkConstants.TRANSPORT_TYPE_WWAN
|
||||
)
|
||||
if (networkList.isEmpty()) return null
|
||||
// Due to the aggregation of cell between carriers, it's possible to get CellIdentity
|
||||
// containing forbidden PLMN.
|
||||
// Getting current network from ServiceState is no longer a good idea.
|
||||
// Add an additional rule to avoid from showing forbidden PLMN to the user.
|
||||
return NetworkRegistrationAndForbiddenInfo(networkList, getForbiddenPlmns())
|
||||
}
|
||||
|
||||
/**
|
||||
* Update forbidden PLMNs from the USIM App
|
||||
*/
|
||||
private fun getForbiddenPlmns(): List<String> {
|
||||
return telephonyManager.forbiddenPlmns?.toList() ?: emptyList()
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,10 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.AccessNetworkConstants;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.CellIdentity;
|
||||
import android.telephony.CellInfo;
|
||||
import android.telephony.NetworkRegistrationInfo;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -52,13 +50,11 @@ import com.android.settings.network.telephony.scan.NetworkScanRepository;
|
||||
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanCellInfos;
|
||||
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanComplete;
|
||||
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanError;
|
||||
import com.android.settings.network.telephony.scan.NetworkScanRepository.NetworkScanResult;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -101,6 +97,8 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
private NetworkScanRepository mNetworkScanRepository;
|
||||
private boolean mUpdateScanResult = false;
|
||||
|
||||
private NetworkSelectRepository mNetworkSelectRepository;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
@@ -138,6 +136,7 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
mCarrierConfigManager.registerCarrierConfigChangeListener(mNetworkScanExecutor,
|
||||
mCarrierConfigChangeListener);
|
||||
mNetworkScanRepository = new NetworkScanRepository(context, mSubId);
|
||||
mNetworkSelectRepository = new NetworkSelectRepository(context, mSubId);
|
||||
}
|
||||
|
||||
@Keep
|
||||
@@ -202,35 +201,37 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
mProgressHeader = setPinnedHeaderView(
|
||||
com.android.settingslib.widget.progressbar.R.layout.progress_header
|
||||
).findViewById(com.android.settingslib.widget.progressbar.R.id.progress_bar_animation);
|
||||
forceUpdateConnectedPreferenceCategory();
|
||||
mNetworkSelectRepository.launchUpdateNetworkRegistrationInfo(
|
||||
getViewLifecycleOwner(),
|
||||
(info) -> {
|
||||
forceUpdateConnectedPreferenceCategory(info);
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
launchNetworkScan();
|
||||
}
|
||||
|
||||
private void launchNetworkScan() {
|
||||
mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), new Function1<>() {
|
||||
@Override
|
||||
public Unit invoke(@NonNull NetworkScanResult networkScanResult) {
|
||||
if (!mUpdateScanResult) {
|
||||
// Not update UI if not in scan mode.
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
if (networkScanResult instanceof NetworkScanCellInfos networkScanCellInfos) {
|
||||
scanResultHandler(networkScanCellInfos.getCellInfos());
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
if (!isPreferenceScreenEnabled()) {
|
||||
clearPreferenceSummary();
|
||||
enablePreferenceScreen(true);
|
||||
} else if (networkScanResult instanceof NetworkScanComplete
|
||||
&& mCellInfoList == null) {
|
||||
// In case the scan timeout before getting any results
|
||||
addMessagePreference(R.string.empty_networks_list);
|
||||
} else if (networkScanResult instanceof NetworkScanError) {
|
||||
addMessagePreference(R.string.network_query_error);
|
||||
}
|
||||
|
||||
mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), (networkScanResult) -> {
|
||||
if (!mUpdateScanResult) {
|
||||
// Not update UI if not in scan mode.
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
if (networkScanResult instanceof NetworkScanCellInfos networkScanCellInfos) {
|
||||
scanResultHandler(networkScanCellInfos.getCellInfos());
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
if (!isPreferenceScreenEnabled()) {
|
||||
clearPreferenceSummary();
|
||||
enablePreferenceScreen(true);
|
||||
} else if (networkScanResult instanceof NetworkScanComplete
|
||||
&& mCellInfoList == null) {
|
||||
// In case the scan timeout before getting any results
|
||||
addMessagePreference(R.string.empty_networks_list);
|
||||
} else if (networkScanResult instanceof NetworkScanError) {
|
||||
addMessagePreference(R.string.network_query_error);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -238,7 +239,6 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
updateForbiddenPlmns();
|
||||
setProgressBarVisible(true);
|
||||
mUpdateScanResult = true;
|
||||
}
|
||||
@@ -477,45 +477,26 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
* - If the device has no data, we will remove the connected network operators list from the
|
||||
* screen.
|
||||
*/
|
||||
private void forceUpdateConnectedPreferenceCategory() {
|
||||
if (mTelephonyManager.getDataState() == mTelephonyManager.DATA_CONNECTED) {
|
||||
// Try to get the network registration states
|
||||
final ServiceState ss = mTelephonyManager.getServiceState();
|
||||
if (ss == null) {
|
||||
return;
|
||||
private void forceUpdateConnectedPreferenceCategory(
|
||||
NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo info) {
|
||||
for (NetworkRegistrationInfo regInfo : info.getNetworkList()) {
|
||||
final CellIdentity cellIdentity = regInfo.getCellIdentity();
|
||||
if (cellIdentity == null) {
|
||||
continue;
|
||||
}
|
||||
final List<NetworkRegistrationInfo> networkList =
|
||||
ss.getNetworkRegistrationInfoListForTransportType(
|
||||
AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
|
||||
if (networkList == null || networkList.size() == 0) {
|
||||
return;
|
||||
}
|
||||
// Due to the aggregation of cell between carriers, it's possible to get CellIdentity
|
||||
// containing forbidden PLMN.
|
||||
// Getting current network from ServiceState is no longer a good idea.
|
||||
// Add an additional rule to avoid from showing forbidden PLMN to the user.
|
||||
if (mForbiddenPlmns == null) {
|
||||
updateForbiddenPlmns();
|
||||
}
|
||||
for (NetworkRegistrationInfo regInfo : networkList) {
|
||||
final CellIdentity cellIdentity = regInfo.getCellIdentity();
|
||||
if (cellIdentity == null) {
|
||||
continue;
|
||||
}
|
||||
final NetworkOperatorPreference pref = new NetworkOperatorPreference(
|
||||
getPrefContext(), mForbiddenPlmns, mShow4GForLTE);
|
||||
pref.updateCell(null, cellIdentity);
|
||||
if (pref.isForbiddenNetwork()) {
|
||||
continue;
|
||||
}
|
||||
pref.setSummary(R.string.network_connected);
|
||||
// Update the signal strength icon, since the default signalStrength value
|
||||
// would be zero
|
||||
// (it would be quite confusing why the connected network has no signal)
|
||||
pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
|
||||
mPreferenceCategory.addPreference(pref);
|
||||
break;
|
||||
final NetworkOperatorPreference pref = new NetworkOperatorPreference(
|
||||
getPrefContext(), info.getForbiddenPlmns(), mShow4GForLTE);
|
||||
pref.updateCell(null, cellIdentity);
|
||||
if (pref.isForbiddenNetwork()) {
|
||||
continue;
|
||||
}
|
||||
pref.setSummary(R.string.network_connected);
|
||||
// Update the signal strength icon, since the default signalStrength value
|
||||
// would be zero
|
||||
// (it would be quite confusing why the connected network has no signal)
|
||||
pref.setIcon(SignalStrength.NUM_SIGNAL_STRENGTH_BINS - 1);
|
||||
mPreferenceCategory.addPreference(pref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ public class PrivateSpaceGaiaEducationFragment extends InstrumentedFragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
if (android.os.Flags.allowPrivateProfile()) {
|
||||
if (android.os.Flags.allowPrivateProfile()
|
||||
&& android.multiuser.Flags.enablePrivateSpaceFeatures()) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.server.accessibility.Flags.enableMagnificationOneFingerPanningGesture;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
@@ -28,7 +27,10 @@ import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.platform.test.annotations.RequiresFlagsDisabled;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -51,8 +53,9 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
|
||||
private static final String ONE_FINGER_PANNING_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_SINGLE_FINGER_PANNING_ENABLED;
|
||||
|
||||
@Rule public final SetFlagsRule mSetFlagsRule =
|
||||
new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule =
|
||||
DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final SwitchPreference mSwitchPreference = spy(new SwitchPreference(mContext));
|
||||
@@ -88,16 +91,16 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_defaultState_disabled() {
|
||||
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
|
||||
public void getAvailabilityStatus_flagDisabled_disabled() {
|
||||
int status = mController.getAvailabilityStatus();
|
||||
|
||||
assertThat(status).isEqualTo(DISABLED_FOR_USER);
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
|
||||
public void getAvailabilityStatus_featureFlagEnabled_enabled() {
|
||||
enableFlag();
|
||||
|
||||
int status = mController.getAvailabilityStatus();
|
||||
|
||||
assertThat(status).isEqualTo(AVAILABLE);
|
||||
@@ -158,9 +161,8 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE)
|
||||
public void performClick_switchDefaultState_shouldReturnTrue() {
|
||||
enableFlag();
|
||||
|
||||
mSwitchPreference.performClick();
|
||||
|
||||
verify(mSwitchPreference).setChecked(true);
|
||||
@@ -168,13 +170,6 @@ public class MagnificationOneFingerPanningPreferenceControllerTest {
|
||||
assertThat(mSwitchPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
private void enableFlag() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MAGNIFICATION_ONE_FINGER_PANNING_GESTURE);
|
||||
assertThat(enableMagnificationOneFingerPanningGesture()).isTrue();
|
||||
// This ensures that preference change listeners are added correctly.
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
private String enabledSummary() {
|
||||
return mContext.getString(
|
||||
R.string.accessibility_magnification_one_finger_panning_summary_on);
|
||||
|
||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 148 KiB |
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.network.telephony
|
||||
|
||||
import android.content.Context
|
||||
import android.telephony.AccessNetworkConstants
|
||||
import android.telephony.NetworkRegistrationInfo
|
||||
import android.telephony.ServiceState
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.network.telephony.scan.NetworkScanRepositoryTest
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.stub
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NetworkSelectRepositoryTest {
|
||||
|
||||
private val mockServiceState = mock<ServiceState> {
|
||||
on {
|
||||
getNetworkRegistrationInfoListForTransportType(
|
||||
AccessNetworkConstants.TRANSPORT_TYPE_WWAN
|
||||
)
|
||||
} doReturn NetworkRegistrationInfos
|
||||
}
|
||||
|
||||
private val mockTelephonyManager = mock<TelephonyManager> {
|
||||
on { createForSubscriptionId(SUB_ID) } doReturn mock
|
||||
on { dataState } doReturn TelephonyManager.DATA_CONNECTED
|
||||
on { serviceState } doReturn mockServiceState
|
||||
}
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
|
||||
}
|
||||
|
||||
private val repository = NetworkSelectRepository(context, SUB_ID)
|
||||
|
||||
@Test
|
||||
fun getNetworkRegistrationInfo_notConnected_returnNull() {
|
||||
mockTelephonyManager.stub {
|
||||
on { dataState } doReturn TelephonyManager.DATA_DISCONNECTED
|
||||
}
|
||||
|
||||
val info = repository.getNetworkRegistrationInfo()
|
||||
|
||||
assertThat(info).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkRegistrationInfo_nullServiceState_returnNull() {
|
||||
mockTelephonyManager.stub {
|
||||
on { serviceState } doReturn null
|
||||
}
|
||||
|
||||
val info = repository.getNetworkRegistrationInfo()
|
||||
|
||||
assertThat(info).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkRegistrationInfo_emptyNetworkList_returnNull() {
|
||||
mockServiceState.stub {
|
||||
on {
|
||||
getNetworkRegistrationInfoListForTransportType(
|
||||
AccessNetworkConstants.TRANSPORT_TYPE_WWAN
|
||||
)
|
||||
} doReturn emptyList()
|
||||
}
|
||||
|
||||
val info = repository.getNetworkRegistrationInfo()
|
||||
|
||||
assertThat(info).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getNetworkRegistrationInfo_hasNetworkList_returnInfo() {
|
||||
mockServiceState.stub {
|
||||
on {
|
||||
getNetworkRegistrationInfoListForTransportType(
|
||||
AccessNetworkConstants.TRANSPORT_TYPE_WWAN
|
||||
)
|
||||
} doReturn NetworkRegistrationInfos
|
||||
}
|
||||
mockTelephonyManager.stub {
|
||||
on { forbiddenPlmns } doReturn arrayOf(FORBIDDEN_PLMN)
|
||||
}
|
||||
|
||||
val info = repository.getNetworkRegistrationInfo()
|
||||
|
||||
assertThat(info).isEqualTo(
|
||||
NetworkSelectRepository.NetworkRegistrationAndForbiddenInfo(
|
||||
networkList = NetworkRegistrationInfos,
|
||||
forbiddenPlmns = listOf(FORBIDDEN_PLMN),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SUB_ID = 1
|
||||
val NetworkRegistrationInfos = listOf(NetworkRegistrationInfo.Builder().build())
|
||||
const val FORBIDDEN_PLMN = "Forbidden PLMN"
|
||||
}
|
||||
}
|
||||
@@ -33,13 +33,13 @@ import androidx.preference.PreferenceManager
|
||||
import androidx.preference.SwitchPreference
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.net.thread.platform.flags.Flags
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.BasePreferenceController.AVAILABLE
|
||||
import com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE
|
||||
import com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING
|
||||
import com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE
|
||||
import com.android.settings.connecteddevice.threadnetwork.ThreadNetworkPreferenceController.BaseThreadNetworkController
|
||||
import com.android.settings.flags.Flags
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@@ -68,7 +68,7 @@ class ThreadNetworkPreferenceControllerTest {
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_THREAD_ENABLED_PLATFORM)
|
||||
mSetFlagsRule.enableFlags(Flags.FLAG_THREAD_SETTINGS_ENABLED)
|
||||
context = spy(ApplicationProvider.getApplicationContext<Context>())
|
||||
executor = ContextCompat.getMainExecutor(context)
|
||||
fakeThreadNetworkController = FakeThreadNetworkController(executor)
|
||||
@@ -96,7 +96,7 @@ class ThreadNetworkPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
fun availabilityStatus_flagDisabled_returnsConditionallyUnavailable() {
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_THREAD_ENABLED_PLATFORM)
|
||||
mSetFlagsRule.disableFlags(Flags.FLAG_THREAD_SETTINGS_ENABLED)
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE)
|
||||
}
|
||||
|
||||
|
||||