Snap for 12415101 from d6f73f35b6 to 25Q1-release

Change-Id: I3686d9e294be9b07d62c914ec4ee0a5811d5122a
This commit is contained in:
Android Build Coastguard Worker
2024-09-25 23:23:18 +00:00
61 changed files with 1338 additions and 229 deletions

View File

@@ -571,11 +571,15 @@
<string name="roaming_warning">Roaming charges may apply.</string>
<!-- Date & time setting screen setting switch title: whether the system clock (Unix epoch time) should be determined automatically [CHAR LIMIT=100] -->
<string name="date_time_auto">Set time automatically</string>
<string name="date_time_auto">Automatic date and time</string>
<!-- Date & time setting screen setting switch summary: whether the system clock (Unix epoch time) should be determined automatically [CHAR LIMIT=100] -->
<string name="date_time_auto_summary">Set automatically using your network and wireless signals</string>
<!-- Date & time setting screen setting switch title: whether the time zone should be determined automatically [CHAR LIMIT=100] -->
<string name="zone_auto_title">Set automatically</string>
<string name="zone_auto_title">Automatic time zone</string>
<!-- Date & time setting screen setting switch summary: whether the time zone should be determined automatically [CHAR LIMIT=100] -->
<string name="zone_auto_title_summary">Set automatically based on mobile networks near you</string>
<!-- Date & time setting screen setting switch summary for non-telephony devices [CHAR LIMIT=100] -->
<string name="auto_zone_requires_location_summary">Location will be used for setting the time zone when this toggle is on</string>
<string name="auto_zone_requires_location_summary">Set automatically using your device location, if available. An active Wifi connection may also be required.</string>
<!-- Date & time setting screen setting option summary text for the automatic 24 hour setting checkbox [CHAR LIMIT=100] -->
<string name="date_time_24hour_auto">Use locale default</string>
<!-- Date & time setting screen setting check box title -->
@@ -3772,7 +3776,7 @@
<string name="location_services_screen_title">Location services</string>
<!-- [CHAR LIMIT=60] Date&Time settings screen, toggle button title -->
<string name="location_time_zone_detection_toggle_title">Use location</string>
<string name="location_time_zone_detection_toggle_title">Use location for time zone</string>
<!-- [CHAR LIMIT=50] Date&Time settings screen, title of the dialog when AutoTimeZone is degraded -->
<string name="location_time_zone_detection_status_title">Cannot set the time zone automatically</string>
<!-- Date&Time settings screen, summary of the dialog when AutoTimeZone is degraded by settings-->
@@ -3800,7 +3804,7 @@
<!-- [CHAR LIMIT=NONE] Location settings screen, summary when location time zone detection is not
applicable due to other settings like the "automatic time zone detection enabled" setting
being set to "off". -->
<string name="location_time_zone_detection_auto_is_off">Automatic time zone is off</string>
<string name="location_time_zone_detection_auto_is_off">Not available when automatic time zone is off</string>
<!-- [CHAR LIMIT=NONE] Location settings screen, summary when location time zone detection is not
applicable for the user for unspecified reasons. More specific messages are used when there
is a clear reason. -->
@@ -3811,7 +3815,7 @@
allowed for the user, e.g. because of device policy -->
<string name="location_time_zone_detection_not_allowed">Location time zone detection changes are not allowed</string>
<!-- [CHAR LIMIT=NONE] Location settings screen, summary when location time zone detection is enabled. -->
<string name="location_time_zone_detection_auto_is_on">Location may be used to set time zone</string>
<string name="location_time_zone_detection_auto_is_on">If your device location is available, it may be used to set your time zone</string>
<!-- Main settings screen, setting summary for the user to go into the About phone screen-->
<string name="about_settings_summary">View legal info, status, software version</string>
<!-- About phone settings screen, setting option name to go to dialog that shows legal info -->
@@ -13670,4 +13674,11 @@
<!-- Text for Search bar of Settings home screen [CHAR LIMIT=34] -->
<string name="homepage_search">Search Settings</string>
<!-- Keywords for contacts storage item [CHAR LIMIT=NONE] -->
<string name="keywords_contacts_storage">contacts, storage, account</string>
<!-- Text for Contacts Storage Settings title [CHAR LIMIT=50]-->
<string name="contacts_storage_settings_title">Contacts storage</string>
<!-- Text for displaying when no account is set as default account [CHAR LIMIT=50] -->
<string name="contacts_storage_no_account_set">No default set</string>
</resources>

View File

@@ -43,7 +43,8 @@
android:title="@string/auto_brightness_title"
android:fragment="com.android.settings.accessibility.AutoBrightnessPreferenceFragmentForSetupWizard"
settings:useAdminDisabledSummary="true"
settings:userRestriction="no_config_brightness"/>
settings:userRestriction="no_config_brightness"
settings:controller="com.android.settings.display.AutoBrightnessPreferenceControllerForSetupWizard"/>
<Preference
android:fragment="com.android.settings.accessibility.ToggleScreenMagnificationPreferenceFragmentForSetupWizard"

View File

@@ -79,6 +79,15 @@
android:key="dashboard_tile_placeholder"
android:order="10"/>
<Preference
android:key="contacts_storage"
android:title="@string/contacts_storage_settings_title"
android:summary="@string/summary_placeholder"
android:order="13"
settings:controller="com.android.settings.applications.contacts.ContactsStoragePreferenceController"
settings:keywords="@string/keywords_contacts_storage">
</Preference>
<Preference
android:key="hibernated_apps"
android:title="@string/unused_apps"

View File

@@ -23,7 +23,7 @@
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_time"
android:title="@string/date_time_auto"
settings:useAdditionalSummary="true"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.AutoTimePreferenceController" />
@@ -48,6 +48,7 @@
<com.android.settingslib.RestrictedSwitchPreference
android:key="auto_zone"
android:title="@string/zone_auto_title"
android:summary="@string/summary_placeholder"
settings:userRestriction="no_config_date_time"
settings:controller="com.android.settings.datetime.AutoTimeZonePreferenceController" />
@@ -60,6 +61,7 @@
<SwitchPreferenceCompat
android:key="location_time_zone_detection"
android:title="@string/location_time_zone_detection_toggle_title"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.datetime.LocationTimeZoneDetectionPreferenceController"/>
<com.android.settingslib.RestrictedPreference

View File

@@ -17,8 +17,13 @@
package com.android.settings;
import android.app.settings.SettingsEnums;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.deviceinfo.legal.LegalSettingsScreen;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
@@ -44,4 +49,10 @@ public class LegalSettings extends DashboardFragment {
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.about_legal);
@Nullable
@Override
public String getPreferenceScreenBindingKey(@NonNull Context context) {
return LegalSettingsScreen.KEY;
}
}

View File

@@ -41,8 +41,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.display.AutoBrightnessPreferenceController;
import com.android.settings.display.BrightnessLevelPreferenceController;
import com.android.settings.display.BrightnessLevelPreferenceControllerForSetupWizard;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -168,16 +167,10 @@ public class AccessibilitySettingsForSetupWizard extends DashboardFragment
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
// Requires lifecycle, so added programmatically (normally via resId).
final List<AbstractPreferenceController> controllers = new ArrayList<>();
BrightnessLevelPreferenceController brightnessLevelPreferenceController =
new BrightnessLevelPreferenceController(context, getSettingsLifecycle());
brightnessLevelPreferenceController.setInSetupWizard(true);
controllers.add(brightnessLevelPreferenceController);
String autoBrightnessKey = context.getString(R.string.preference_key_auto_brightness);
AutoBrightnessPreferenceController autoBrightnessPreferenceController =
new AutoBrightnessPreferenceController(context, autoBrightnessKey);
autoBrightnessPreferenceController.setInSetupWizard(true);
controllers.add(autoBrightnessPreferenceController);
controllers.add(new BrightnessLevelPreferenceControllerForSetupWizard(
context, getSettingsLifecycle()));
return controllers;
}

View File

@@ -0,0 +1,68 @@
/*
* 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.applications.contacts;
import android.accounts.Account;
import android.content.Context;
import android.os.UserHandle;
import android.provider.ContactsContract;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.flags.Flags;
import com.android.settingslib.accounts.AuthenticatorHelper;
/**
* A preference controller handling the logic for updating summary of contacts default account.
*/
public class ContactsStoragePreferenceController extends BasePreferenceController {
private static final String TAG = "ContactsStorageController";
private final AuthenticatorHelper mAuthenticatorHelper;
public ContactsStoragePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
mAuthenticatorHelper = new AuthenticatorHelper(mContext,
new UserHandle(UserHandle.myUserId()), null);
}
@Override
public int getAvailabilityStatus() {
return Flags.enableContactsDefaultAccountInSettings()
? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
}
@Override
public CharSequence getSummary() {
Account currentDefaultAccount =
ContactsContract.Settings.getDefaultAccount(mContext.getContentResolver());
if (currentDefaultAccount == null) {
return mContext.getResources().getString(
R.string.contacts_storage_no_account_set);
}
String accountTypeLabel = (String) mAuthenticatorHelper.getLabelForType(mContext,
currentDefaultAccount.type);
// If there's no account type, or the account type is the same as the
// current default account name, just return the account name.
if (accountTypeLabel == null || accountTypeLabel.equals(currentDefaultAccount.name)) {
return currentDefaultAccount.name;
}
return accountTypeLabel + " | " + currentDefaultAccount.name;
}
}

View File

@@ -359,7 +359,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
String aliasName = device.getAlias();
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
: aliasName;
showConnectingDialog("Connecting to " + deviceName + "...");
showConnectingDialog(deviceName);
// Wait for AUTO_DISMISS_TIME_THRESHOLD_MS and check if the paired device supports audio
// sharing.
if (!mHandler.hasMessages(AUTO_DISMISS_MESSAGE_ID)) {
@@ -385,14 +385,15 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
}
// TODO: use DialogFragment
private void showConnectingDialog(@NonNull String message) {
private void showConnectingDialog(@NonNull String deviceName) {
postOnMainThread(() -> {
String message = getContext().getString(R.string.progress_dialog_connect_device_content,
deviceName);
if (mProgressDialog != null) {
Log.d(getLogTag(), "showConnectingDialog, is already showing");
TextView textView = mProgressDialog.findViewById(R.id.message);
if (textView != null && !message.equals(textView.getText().toString())) {
Log.d(getLogTag(), "showConnectingDialog, update message");
// TODO: use string res once finalized
textView.setText(message);
}
return;
@@ -405,7 +406,6 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
null);
TextView textView = customView.findViewById(R.id.message);
if (textView != null) {
// TODO: use string res once finalized
textView.setText(message);
}
AlertDialog dialog = builder.setView(customView).setCancelable(false).create();

View File

@@ -16,6 +16,7 @@
package com.android.settings.bluetooth.ui.model
import android.content.Intent
import com.android.settingslib.bluetooth.devicesettings.DeviceSettingId
import com.android.settingslib.bluetooth.devicesettings.shared.model.DeviceSettingIcon
import com.android.settingslib.bluetooth.devicesettings.shared.model.ToggleModel
@@ -31,7 +32,7 @@ sealed interface DeviceSettingPreferenceModel {
val title: String,
val summary: String? = null,
val icon: DeviceSettingIcon? = null,
val onClick: (() -> Unit)? = null,
val intent: Intent? = null,
) : DeviceSettingPreferenceModel
/** Models a switch preference. */
@@ -42,7 +43,7 @@ sealed interface DeviceSettingPreferenceModel {
val icon: DeviceSettingIcon? = null,
val checked: Boolean,
val onCheckedChange: ((Boolean) -> Unit),
val onPrimaryClick: (() -> Unit)? = null,
val intent: Intent? = null,
) : DeviceSettingPreferenceModel
/** Models a multi-toggle preference. */
@@ -71,6 +72,6 @@ sealed interface DeviceSettingPreferenceModel {
data class HelpPreference(
@DeviceSettingId override val id: Int,
val icon: DeviceSettingIcon,
val onClick: (() -> Unit),
val intent: Intent,
) : DeviceSettingPreferenceModel
}

View File

@@ -18,6 +18,7 @@ package com.android.settings.bluetooth.ui.view
import android.bluetooth.BluetoothAdapter
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.os.Bundle
import androidx.compose.animation.AnimatedVisibility
@@ -101,13 +102,13 @@ class DeviceDetailsFragmentFormatterImpl(
) : DeviceDetailsFragmentFormatter {
private val repository =
featureFactory.bluetoothFeatureProvider.getDeviceSettingRepository(
context,
fragment.requireActivity().application,
bluetoothAdapter,
fragment.lifecycleScope,
)
private val spatialAudioInteractor =
featureFactory.bluetoothFeatureProvider.getSpatialAudioInteractor(
context,
fragment.requireActivity().application,
context.getSystemService(AudioManager::class.java),
fragment.lifecycleScope,
)
@@ -312,10 +313,10 @@ class DeviceDetailsFragmentFormatterImpl(
return { deviceSettingIcon(model.icon) }
}
}
if (model.onPrimaryClick != null) {
if (model.intent != null) {
TwoTargetSwitchPreference(
switchPrefModel,
primaryOnClick = model.onPrimaryClick::invoke,
primaryOnClick = { startActivity(model.intent) },
)
} else {
SwitchPreference(switchPrefModel)
@@ -329,7 +330,7 @@ class DeviceDetailsFragmentFormatterImpl(
override val title = model.title
override val summary = { model.summary ?: "" }
override val onClick = {
model.onClick?.invoke()
model.intent?.let { startActivity(it) }
Unit
}
override val icon: (@Composable () -> Unit)?
@@ -361,7 +362,12 @@ class DeviceDetailsFragmentFormatterImpl(
)
.launch()
}
override val icon = @Composable { deviceSettingIcon(null) }
override val icon =
@Composable {
deviceSettingIcon(
DeviceSettingIcon.ResourceIcon(R.drawable.ic_chevron_right_24dp)
)
}
}
)
}
@@ -376,6 +382,11 @@ class DeviceDetailsFragmentFormatterImpl(
icon?.let { Icon(it, modifier = Modifier.size(SettingsDimension.itemIconSize)) }
}
private fun startActivity(intent: Intent) {
intent.removeFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
private fun getPreferenceKey(settingId: Int) = "DEVICE_SETTING_${settingId}"
companion object {

View File

@@ -16,9 +16,11 @@
package com.android.settings.bluetooth.ui.view
import android.app.settings.SettingsEnums
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.Context
import android.content.Intent
import android.graphics.PorterDuff
import android.os.Bundle
import android.view.Menu
@@ -48,8 +50,7 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() {
private lateinit var cachedDevice: CachedBluetoothDevice
private lateinit var helpItem: StateFlow<DeviceSettingPreferenceModel.HelpPreference?>
// TODO(b/343317785): add metrics category
override fun getMetricsCategory(): Int = 0
override fun getMetricsCategory(): Int = SettingsEnums.BLUETOOTH_DEVICE_DETAILS_MORE_SETTINGS
override fun onPrepareOptionsMenu(menu: Menu) {
super.onPrepareOptionsMenu(menu)
@@ -73,7 +74,10 @@ class DeviceDetailsMoreSettingsFragment : DashboardFragment() {
override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
if (menuItem.itemId == MENU_HELP_ITEM_ID) {
helpItem.value?.let { it.onClick() }
helpItem.value?.intent?.let {
it.removeFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
requireContext().startActivity(it)
}
return true
}
return super.onOptionsItemSelected(menuItem)

View File

@@ -101,7 +101,7 @@ class BluetoothDeviceDetailsViewModel(
DeviceSettingStateModel.ActionSwitchPreferenceState(newState)
)
},
onPrimaryClick = { intent?.let { application.startActivity(it) } },
intent = intent,
)
} else {
DeviceSettingPreferenceModel.PlainPreference(
@@ -109,7 +109,7 @@ class BluetoothDeviceDetailsViewModel(
title = title,
summary = summary,
icon = icon,
onClick = { intent?.let { application.startActivity(it) } },
intent = intent,
)
}
}
@@ -119,7 +119,7 @@ class BluetoothDeviceDetailsViewModel(
DeviceSettingPreferenceModel.HelpPreference(
id = id,
icon = DeviceSettingIcon.ResourceIcon(R.drawable.ic_help),
onClick = { application.startActivity(intent) },
intent = intent,
)
is DeviceSettingModel.MultiTogglePreference ->
DeviceSettingPreferenceModel.MultiTogglePreference(

View File

@@ -72,7 +72,7 @@ public class AudioSharingConfirmDialogFragment extends InstrumentedDialogFragmen
.setTitleIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
.setIsCustomBodyEnabled(true)
.setCustomMessage(R.string.audio_sharing_comfirm_dialog_content)
.setPositiveButton(com.android.settings.R.string.okay, (d, w) -> {})
.setPositiveButton(R.string.okay, (d, w) -> {})
.build();
dialog.setCanceledOnTouchOutside(true);
return dialog;

View File

@@ -26,6 +26,7 @@ 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;
import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -65,15 +66,13 @@ public class AudioSharingErrorDialogFragment extends InstrumentedDialogFragment
@Override
@NonNull
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
// TODO: put strings to res till they are finalized
AlertDialog dialog =
AudioSharingDialogFactory.newBuilder(getActivity())
.setTitle("Couldn't share audio")
.setTitleIcon(com.android.settings.R.drawable.ic_warning_24dp)
.setTitle(R.string.audio_sharing_retry_dialog_title)
.setTitleIcon(R.drawable.ic_warning_24dp)
.setIsCustomBodyEnabled(true)
.setCustomMessage("Something went wrong. Please try again.")
.setPositiveButton(com.android.settings.R.string.okay, (d, w) -> {
})
.setCustomMessage(R.string.audio_sharing_retry_dialog_content)
.setPositiveButton(R.string.okay, (d, w) -> {})
.build();
dialog.setCanceledOnTouchOutside(true);
return dialog;

View File

@@ -27,6 +27,7 @@ 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;
import com.android.settingslib.bluetooth.BluetoothUtils;
@@ -88,15 +89,14 @@ public class AudioSharingIncompatibleDialogFragment extends InstrumentedDialogFr
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Bundle arguments = requireArguments();
String deviceName = arguments.getString(BUNDLE_KEY_DEVICE_NAME);
// TODO: move strings to res once they are finalized
AlertDialog dialog =
AudioSharingDialogFactory.newBuilder(getActivity())
.setTitle("Can't share audio with " + deviceName)
.setTitleIcon(com.android.settings.R.drawable.ic_warning_24dp)
.setTitle(getString(R.string.audio_sharing_incompatible_dialog_title,
deviceName))
.setTitleIcon(R.drawable.ic_warning_24dp)
.setIsCustomBodyEnabled(true)
.setCustomMessage(
"Audio sharing only works with headphones that support LE Audio.")
.setPositiveButton(com.android.settings.R.string.okay, (d, w) -> {})
.setCustomMessage(R.string.audio_sharing_incompatible_dialog_content)
.setPositiveButton(R.string.okay, (d, w) -> {})
.build();
dialog.setCanceledOnTouchOutside(true);
return dialog;

View File

@@ -571,10 +571,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
if (mBroadcast != null) {
mBroadcast.startPrivateBroadcast();
mSinksInAdding.clear();
// TODO: use string res once finalized.
AudioSharingUtils.postOnMainThread(mContext,
() -> AudioSharingProgressDialogFragment.show(mFragment,
"Starting audio stream..."));
mContext.getString(
R.string.audio_sharing_progress_dialog_start_stream_content)));
mMetricsFeatureProvider.action(
mContext,
SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_ON,
@@ -830,8 +830,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
private void addSourceToTargetSinks(List<BluetoothDevice> targetActiveSinks,
@NonNull String sinkName) {
mSinksInAdding.addAll(targetActiveSinks);
// TODO: move to res once finalized
String progressMessage = "Sharing with " + sinkName + "...";
String progressMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_add_source_content, sinkName);
showProgressDialog(progressMessage);
AudioSharingUtils.addSourceToTargetSinks(targetActiveSinks, mBtManager);
}

View File

@@ -249,6 +249,15 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (isCatalystEnabled()) {
Intent intent = preference.getIntent();
if (intent != null && preference.getContext().getPackageManager().queryIntentActivities(
intent, 0).isEmpty()) {
Log.w(TAG, "No activity to start for " + intent);
return true;
}
}
final Collection<List<AbstractPreferenceController>> controllers =
mPreferenceControllers.values();
for (List<AbstractPreferenceController> controllerList : controllers) {

View File

@@ -27,6 +27,8 @@ import android.app.time.TimeConfiguration;
import android.app.time.TimeManager;
import android.content.Context;
import androidx.preference.Preference;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
@@ -76,6 +78,17 @@ public class AutoTimePreferenceController extends TogglePreferenceController {
}
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
refreshSummary(preference);
}
@Override
public CharSequence getSummary() {
return mContext.getString(R.string.date_time_auto_summary);
}
@Override
public boolean isChecked() {
return isEnabled();

View File

@@ -129,11 +129,11 @@ public class AutoTimeZonePreferenceController extends TogglePreferenceController
// time zone must use location.
if (LocationProviderStatusPreferenceController.hasLocationTimeZoneNoTelephonyFallback(
mTimeManager.getTimeZoneCapabilitiesAndConfig().getDetectorStatus())) {
return mContext.getResources().getString(R.string.auto_zone_requires_location_summary);
return mContext.getString(R.string.auto_zone_requires_location_summary);
}
// If the user has a dedicated toggle to control location use, the summary can
// be empty because the use of location is explicit.
return "";
// If the user has a dedicated toggle to control location use, explain what it does.
return mContext.getString(R.string.zone_auto_title_summary);
}
@VisibleForTesting

View File

@@ -0,0 +1,104 @@
/*
* 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.deviceinfo.firmwareversion
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.SystemClock
import android.os.UserHandle
import android.os.UserManager
import androidx.preference.Preference
import com.android.internal.app.PlatLogoActivity
import com.android.settings.R
import com.android.settings.Utils
import com.android.settingslib.RestrictedLockUtils
import com.android.settingslib.RestrictedLockUtilsInternal
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.preference.PreferenceBinding
// LINT.IfChange
class FirmwareVersionDetailPreference :
PreferenceMetadata,
PreferenceSummaryProvider,
PreferenceBinding,
Preference.OnPreferenceClickListener {
private val hits = LongArray(ACTIVITY_TRIGGER_COUNT)
override val key: String
get() = "os_firmware_version"
override val title: Int
get() = R.string.firmware_version
override fun isIndexable(context: Context) = false
override fun intent(context: Context): Intent? =
Intent(Intent.ACTION_MAIN)
.setClassName("android", PlatLogoActivity::class.java.name)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
override fun getSummary(context: Context): CharSequence? =
Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
super.bind(preference, metadata)
preference.isCopyingEnabled = true
preference.onPreferenceClickListener = this
}
// return true swallows the click event, while return false will start the intent
override fun onPreferenceClick(preference: Preference): Boolean {
if (Utils.isMonkeyRunning()) return true
// remove oldest hit and check whether there are 3 clicks within 500ms
for (index in 1..<ACTIVITY_TRIGGER_COUNT) hits[index - 1] = hits[index]
hits[ACTIVITY_TRIGGER_COUNT - 1] = SystemClock.uptimeMillis()
if (hits[ACTIVITY_TRIGGER_COUNT - 1] - hits[0] > DELAY_TIMER_MILLIS) return true
val context = preference.context
val userManager = context.getSystemService(Context.USER_SERVICE) as? UserManager
if (userManager?.hasUserRestriction(UserManager.DISALLOW_FUN) != true) return false
// Sorry, no fun for you!
val myUserId = UserHandle.myUserId()
val enforcedAdmin =
RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
context,
UserManager.DISALLOW_FUN,
myUserId,
) ?: return true
val disallowedBySystem =
RestrictedLockUtilsInternal.hasBaseUserRestriction(
context,
UserManager.DISALLOW_FUN,
myUserId,
)
if (!disallowedBySystem) {
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(context, enforcedAdmin)
}
return true
}
companion object {
const val DELAY_TIMER_MILLIS = 500L
const val ACTIVITY_TRIGGER_COUNT = 3
}
}
// LINT.ThenChange(FirmwareVersionDetailPreferenceController.java)

View File

@@ -33,6 +33,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
// LINT.IfChange
public class FirmwareVersionDetailPreferenceController extends BasePreferenceController {
private static final String TAG = "firmwareDialogCtrl";
@@ -125,3 +126,4 @@ public class FirmwareVersionDetailPreferenceController extends BasePreferenceCon
mContext, UserManager.DISALLOW_FUN, UserHandle.myUserId());
}
}
// LINT.ThenChange(FirmwareVersionDetailPreference.kt)

View File

@@ -20,7 +20,6 @@ import android.content.Context
import android.os.Build
import com.android.settings.R
import com.android.settings.flags.Flags
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
@@ -47,7 +46,7 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider
override fun getPreferenceHierarchy(context: Context) =
preferenceHierarchy(this) {
+PreferenceWidget("os_firmware_version", R.string.firmware_version)
+FirmwareVersionDetailPreference()
+SecurityPatchLevelPreference()
+MainlineModuleVersionPreference()
+BasebandVersionPreference()
@@ -55,9 +54,6 @@ class FirmwareVersionScreen : PreferenceScreenCreator, PreferenceSummaryProvider
+SimpleBuildNumberPreference()
}
private class PreferenceWidget(override val key: String, override val title: Int) :
PreferenceMetadata
companion object {
const val KEY = "firmware_version"
}

View File

@@ -17,6 +17,7 @@ package com.android.settings.deviceinfo.legal;
import android.content.Context;
import android.content.Intent;
// LINT.IfChange
public class CopyrightPreferenceController extends LegalPreferenceController {
private static final Intent INTENT = new Intent("android.settings.COPYRIGHT");
@@ -30,3 +31,4 @@ public class CopyrightPreferenceController extends LegalPreferenceController {
return INTENT;
}
}
// LINT.ThenChange(LegalPreference.kt)

View File

@@ -0,0 +1,58 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import android.content.Intent
import android.content.pm.ApplicationInfo
import android.content.pm.ResolveInfo
import androidx.annotation.StringRes
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.PreferenceTitleProvider
// LINT.IfChange
class LegalPreference(
override val key: String,
@StringRes val defaultTitle: Int = 0,
val intentAction: String,
) : PreferenceMetadata, PreferenceTitleProvider, PreferenceAvailabilityProvider {
override fun getTitle(context: Context): CharSequence? {
val resolveInfo =
findMatchingSpecificActivity(context) ?: return context.getText(defaultTitle)
return resolveInfo.loadLabel(context.packageManager)
}
override fun isAvailable(context: Context) = (findMatchingSpecificActivity(context) != null)
override fun intent(context: Context) =
findMatchingSpecificActivity(context)?.let {
Intent()
.setClassName(it.activityInfo.packageName, it.activityInfo.name)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
private fun findMatchingSpecificActivity(context: Context): ResolveInfo? {
val intent = Intent(intentAction)
// Find the activity that is in the system image
val list: List<ResolveInfo> = context.packageManager.queryIntentActivities(intent, 0)
return list.firstOrNull {
(it.activityInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0
}
}
}
// LINT.ThenChange(LegalPreferenceController.java)

View File

@@ -27,6 +27,7 @@ import com.android.settings.core.BasePreferenceController;
import java.util.List;
// LINT.IfChange
public abstract class LegalPreferenceController extends BasePreferenceController {
private final PackageManager mPackageManager;
private Preference mPreference;
@@ -94,3 +95,4 @@ public abstract class LegalPreferenceController extends BasePreferenceController
mPreference.setTitle(resolveInfo.loadLabel(mPackageManager));
}
}
// LINT.ThenChange(LegalPreference.kt)

View File

@@ -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.deviceinfo.legal
import android.content.Context
import com.android.settings.LegalSettings
import com.android.settings.R
import com.android.settings.flags.Flags
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenCreator
@ProvidePreferenceScreen
open class LegalSettingsScreen : PreferenceScreenCreator {
override val key: String
get() = KEY
override val title: Int
get() = R.string.legal_information
override fun isFlagEnabled(context: Context) = Flags.catalystLegalInformation()
override fun fragmentClass() = LegalSettings::class.java
override fun getPreferenceHierarchy(context: Context) =
preferenceHierarchy(this) {
+LegalPreference("copyright", R.string.copyright_title, "android.settings.COPYRIGHT")
+LegalPreference("license", R.string.license_title, "android.settings.LICENSE")
+LegalPreference("terms", R.string.terms_title, "android.settings.TERMS")
+ModuleLicensesScreen.KEY // Use screen key in case it is overlaid.
+LegalPreference(
"webview_license",
R.string.webview_license_title,
"android.settings.WEBVIEW_LICENSE",
)
+WallpaperAttributionsPreference()
}
companion object {
const val KEY = "legal_information"
}
}

View File

@@ -17,6 +17,7 @@ package com.android.settings.deviceinfo.legal;
import android.content.Context;
import android.content.Intent;
// LINT.IfChange
public class LicensePreferenceController extends LegalPreferenceController {
private static final Intent INTENT = new Intent("android.settings.LICENSE");
@@ -30,3 +31,4 @@ public class LicensePreferenceController extends LegalPreferenceController {
return INTENT;
}
}
// LINT.ThenChange(LegalPreference.kt)

View File

@@ -24,6 +24,7 @@ import com.android.settings.core.BasePreferenceController;
import java.util.List;
// LINT.IfChange
public class ModuleLicensesListPreferenceController extends BasePreferenceController {
public ModuleLicensesListPreferenceController(Context context,
String preferenceKey) {
@@ -39,3 +40,4 @@ public class ModuleLicensesListPreferenceController extends BasePreferenceContro
: CONDITIONALLY_UNAVAILABLE;
}
}
// LINT.ThenChange(ModuleLicensesScreen.kt)

View File

@@ -0,0 +1,61 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import com.android.settings.R
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenCreator
// LINT.IfChange
@ProvidePreferenceScreen
class ModuleLicensesScreen : PreferenceScreenCreator, PreferenceAvailabilityProvider {
override val key: String
get() = KEY
override val title: Int
get() = R.string.module_license_title
// We need to avoid directly assign fragment attribute in the bind() API. So we need to create
// a screen and provide it to its parent screen LegalSettingsScreen.
// By the way, we also need to set the isFlagEnabled() as false. Let system render the legacy
// UI. The hierarchy will be added while migrating this page.
override fun isFlagEnabled(context: Context) = false
override fun fragmentClass() = ModuleLicensesDashboard::class.java
override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {}
override fun isAvailable(context: Context): Boolean {
val modules = context.packageManager.getInstalledModules(/* flags= */ 0)
return modules.any {
try {
ModuleLicenseProvider.getPackageAssetManager(context.packageManager, it.packageName)
.list("")
?.contains(ModuleLicenseProvider.GZIPPED_LICENSE_FILE_NAME) == true
} catch (e: Exception) {
false
}
}
}
companion object {
const val KEY = "module_license"
}
}
// LINT.ThenChange(ModuleLicensesListPreferenceController.java)

View File

@@ -17,6 +17,7 @@ package com.android.settings.deviceinfo.legal;
import android.content.Context;
import android.content.Intent;
// LINT.IfChange
public class TermsPreferenceController extends LegalPreferenceController {
private static final Intent INTENT = new Intent("android.settings.TERMS");
@@ -30,3 +31,4 @@ public class TermsPreferenceController extends LegalPreferenceController {
return INTENT;
}
}
// LINT.ThenChange(LegalPreference.kt)

View File

@@ -0,0 +1,49 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import androidx.preference.Preference
import com.android.settings.R
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.preference.PreferenceBinding
// LINT.IfChange
class WallpaperAttributionsPreference :
PreferenceMetadata, PreferenceBinding, PreferenceAvailabilityProvider {
override val key: String
get() = KEY
override val title: Int
get() = R.string.wallpaper_attributions
override val summary: Int
get() = R.string.wallpaper_attributions_values
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
super.bind(preference, metadata)
preference.isSelectable = false
}
override fun isAvailable(context: Context) =
context.resources.getBoolean(R.bool.config_show_wallpaper_attribution)
companion object {
const val KEY = "wallpaper_attributions"
}
}
// LINT.ThenChange(WallpaperAttributionsPreferenceController.java)

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
// LINT.IfChange
public class WallpaperAttributionsPreferenceController extends BasePreferenceController {
public WallpaperAttributionsPreferenceController(Context context, String key) {
@@ -33,3 +34,4 @@ public class WallpaperAttributionsPreferenceController extends BasePreferenceCon
: UNSUPPORTED_ON_DEVICE;
}
}
// LINT.ThenChange(WallpaperAttributionsPreference.kt)

View File

@@ -17,6 +17,7 @@ package com.android.settings.deviceinfo.legal;
import android.content.Context;
import android.content.Intent;
// LINT.IfChange
public class WebViewLicensePreferenceController extends LegalPreferenceController {
private static final Intent INTENT = new Intent("android.settings.WEBVIEW_LICENSE");
@@ -30,3 +31,4 @@ public class WebViewLicensePreferenceController extends LegalPreferenceControlle
return INTENT;
}
}
// LINT.ThenChange(LegalPreference.kt)

View File

@@ -22,28 +22,25 @@ import android.os.Process;
import android.os.UserManager;
import android.provider.Settings;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.R;
import com.android.settings.accessibility.Flags;
import com.android.settings.core.TogglePreferenceController;
import com.android.settingslib.PrimarySwitchPreference;
/**
* The top-level preference controller that updates the adaptive brightness.
*/
public class AutoBrightnessPreferenceController extends TogglePreferenceController {
private final String SYSTEM_KEY = SCREEN_BRIGHTNESS_MODE;
private final int DEFAULT_VALUE = SCREEN_BRIGHTNESS_MODE_MANUAL;
private boolean mInSetupWizard;
public AutoBrightnessPreferenceController(Context context, String key) {
public AutoBrightnessPreferenceController(@NonNull Context context, @NonNull String key) {
super(context, key);
}
public void setInSetupWizard(boolean inSetupWizard) {
mInSetupWizard = inSetupWizard;
}
@Override
public boolean isChecked() {
return Settings.System.getInt(mContext.getContentResolver(),
@@ -60,14 +57,10 @@ public class AutoBrightnessPreferenceController extends TogglePreferenceControll
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
if (!mContext.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available)) {
return UNSUPPORTED_ON_DEVICE;
}
if (mInSetupWizard && !Flags.addBrightnessSettingsInSuw()) {
return CONDITIONALLY_UNAVAILABLE;
}
return AVAILABLE_UNSEARCHABLE;
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available)
? AVAILABLE_UNSEARCHABLE
: UNSUPPORTED_ON_DEVICE;
}
@Override

View File

@@ -0,0 +1,44 @@
/*
* 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.display;
import android.content.Context;
import androidx.annotation.NonNull;
import com.android.settings.accessibility.Flags;
/**
* The top-level preference controller that updates the adaptive brightness in the SetupWizard.
*/
public class AutoBrightnessPreferenceControllerForSetupWizard
extends AutoBrightnessPreferenceController {
public AutoBrightnessPreferenceControllerForSetupWizard(@NonNull Context context,
@NonNull String key) {
super(context, key);
}
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
if (!Flags.addBrightnessSettingsInSuw()) {
return CONDITIONALLY_UNAVAILABLE;
}
return super.getAvailabilityStatus();
}
}

View File

@@ -20,7 +20,6 @@ import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MAX;
import static com.android.settingslib.display.BrightnessUtils.GAMMA_SPACE_MIN;
import static com.android.settingslib.display.BrightnessUtils.convertLinearToGammaFloat;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.content.ContentResolver;
import android.content.Context;
@@ -37,12 +36,13 @@ import android.os.UserManager;
import android.provider.Settings.System;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.accessibility.Flags;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.PreferenceControllerMixin;
import com.android.settings.core.SettingsBaseActivity;
@@ -54,18 +54,17 @@ import com.android.settingslib.transition.SettingsTransitionHelper;
import java.text.NumberFormat;
/**
* The top-level preference controller that updates the adaptive brightness level.
*/
public class BrightnessLevelPreferenceController extends BasePreferenceController implements
PreferenceControllerMixin, LifecycleObserver, OnStart, OnStop {
private static final String TAG = "BrightnessPrefCtrl";
private static final Uri BRIGHTNESS_ADJ_URI;
private final ContentResolver mContentResolver;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final DisplayManager mDisplayManager;
@Nullable
private Preference mPreference;
private boolean mInSetupWizard;
static {
BRIGHTNESS_ADJ_URI = System.getUriFor(System.SCREEN_AUTO_BRIGHTNESS_ADJ);
@@ -94,11 +93,13 @@ public class BrightnessLevelPreferenceController extends BasePreferenceControlle
}
};
public BrightnessLevelPreferenceController(Context context, Lifecycle lifecycle) {
public BrightnessLevelPreferenceController(@NonNull Context context,
@Nullable Lifecycle lifecycle) {
this(context, context.getString(R.string.preference_key_brightness_level), lifecycle);
}
private BrightnessLevelPreferenceController(Context context, String key, Lifecycle lifecycle) {
private BrightnessLevelPreferenceController(@NonNull Context context, @NonNull String key,
@Nullable Lifecycle lifecycle) {
super(context, key);
mDisplayManager = context.getSystemService(DisplayManager.class);
@@ -108,15 +109,8 @@ public class BrightnessLevelPreferenceController extends BasePreferenceControlle
mContentResolver = mContext.getContentResolver();
}
public void setInSetupWizard(boolean inSetupWizard) {
mInSetupWizard = inSetupWizard;
}
@Override
public int getAvailabilityStatus() {
if (mInSetupWizard && !Flags.addBrightnessSettingsInSuw()) {
return CONDITIONALLY_UNAVAILABLE;
}
return AVAILABLE;
}

View File

@@ -0,0 +1,47 @@
/*
* 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.display;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.settings.accessibility.Flags;
import com.android.settingslib.core.lifecycle.Lifecycle;
/**
* The top-level preference controller that updates the adaptive brightness level in the
* SetupWizard.
*/
public class BrightnessLevelPreferenceControllerForSetupWizard extends
BrightnessLevelPreferenceController {
public BrightnessLevelPreferenceControllerForSetupWizard(@NonNull Context context,
@Nullable Lifecycle lifecycle) {
super(context, lifecycle);
}
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {
if (!Flags.addBrightnessSettingsInSuw()) {
return CONDITIONALLY_UNAVAILABLE;
}
return super.getAvailabilityStatus();
}
}

View File

@@ -46,8 +46,7 @@ import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.display.AutoBrightnessPreferenceController;
import com.android.settings.display.BrightnessLevelPreferenceController;
import com.android.settings.display.BrightnessLevelPreferenceControllerForSetupWizard;
import com.android.settingslib.RestrictedPreference;
import com.android.settingslib.core.AbstractPreferenceController;
@@ -146,16 +145,15 @@ public class AccessibilitySettingsForSetupWizardTest {
}
@Test
public void createPreferenceControllers_brightnessPreferencesControllersAreCreated() {
public void createPreferenceControllers_lifeCycleDependencyControllerIsCreated() {
mFragment.onAttach(mContext);
List<AbstractPreferenceController> controllers =
mFragment.createPreferenceControllers(mContext);
assertTrue(controllers.stream().anyMatch(
controller -> controller instanceof BrightnessLevelPreferenceController));
assertTrue(controllers.stream().anyMatch(
controller -> controller instanceof AutoBrightnessPreferenceController));
controller ->
controller instanceof BrightnessLevelPreferenceControllerForSetupWizard));
}
private void addEnabledServiceInfo(ComponentName componentName, boolean isAccessibilityTool) {

View File

@@ -0,0 +1,162 @@
/*
* 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.applications.contacts;
import static android.provider.ContactsContract.Settings.KEY_DEFAULT_ACCOUNT;
import static android.provider.ContactsContract.Settings.QUERY_DEFAULT_ACCOUNT_METHOD;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.ContactsContract;
import com.android.settings.R;
import com.android.settings.flags.Flags;
import com.android.settings.testutils.shadow.ShadowAuthenticationHelper;
import org.junit.Before;
import android.platform.test.annotations.RequiresFlagsDisabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowAuthenticationHelper.class)
public class ContactsStoragePreferenceControllerTest {
private static final String CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY =
"contacts_default_account";
private static final Account TEST_ACCOUNT1 = new Account("test@gmail.com", "type1");
private static final Account TEST_ACCOUNT2 = new Account("test@samsung.com", "type2");
private static final Account TEST_ACCOUNT3 = new Account("LABEL3", "type3");
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
private Context mContext;
@Mock
private ContentResolver mContentResolver;
@Mock
private Resources mResources;
@Mock
private AccountManager mAccountManager;
private ContactsStoragePreferenceController mPreferenceController;
@Before
public void setUp() throws Exception {
when(mContext.getContentResolver()).thenReturn(mContentResolver);
when(mContext.getSystemService(eq(Context.ACCOUNT_SERVICE))).thenReturn(mAccountManager);
when(mAccountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[]{});
mPreferenceController = new ContactsStoragePreferenceController(mContext,
CONTACTS_DEFAULT_ACCOUNT_PREFERENCE_KEY);
}
@Test
@EnableFlags(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
public void getAvailabilityStatus_flagIsOn_shouldReturnAvailable() {
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
@RequiresFlagsDisabled(Flags.FLAG_ENABLE_CONTACTS_DEFAULT_ACCOUNT_IN_SETTINGS)
public void getAvailabilityStatus_flagIsOff_shouldReturnConditionallyUnavailable() {
assertThat(mPreferenceController.getAvailabilityStatus()).isEqualTo(
CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getSummary_noAccountIsSetAsDefault_shouldReturnNoAccountSetSummary() {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, null);
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getString(eq(R.string.contacts_storage_no_account_set))).thenReturn(
"No default set");
assertThat(mPreferenceController.getSummary()).isEqualTo("No default set");
}
@Test
public void getSummary_googleAccountIsSetAsDefault_shouldReturnGoogleAccountTypeAndAccountName() {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT1);
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL1 | test@gmail.com");
}
@Test
public void getSummary_samsungAccountIsSetAsDefault_shouldReturnSamsungAccountTypeAndAccountName() {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT2);
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL2 | test@samsung.com");
}
@Test
public void getSummary_accountLabelSameAsAccountName_onlyReturnAccountName() {
Bundle bundle = new Bundle();
bundle.putParcelable(KEY_DEFAULT_ACCOUNT, TEST_ACCOUNT3);
when(mContentResolver.call(eq(ContactsContract.AUTHORITY_URI),
eq(QUERY_DEFAULT_ACCOUNT_METHOD), any(), any())).thenReturn(bundle);
// Since package name and account name is the same, we only return account name.
assertThat(mPreferenceController.getSummary()).isEqualTo("LABEL3");
}
}

View File

@@ -211,9 +211,9 @@ public class BluetoothDevicePairingDetailBaseTest {
assertThat(dialog).isNotNull();
TextView message = dialog.findViewById(R.id.message);
assertThat(message).isNotNull();
// TODO: use stringr res once finalized
assertThat(message.getText().toString()).isEqualTo(
"Connecting to " + TEST_DEVICE_ADDRESS + "...");
mContext.getString(R.string.progress_dialog_connect_device_content,
TEST_DEVICE_ADDRESS));
verify(mFragment, never()).finish();
}

View File

@@ -178,11 +178,9 @@ class DeviceDetailsFragmentFormatterTest {
}.launchIn(testScope.backgroundScope)
delay(100)
runCurrent()
helpPreference!!.onClick()
ShadowLooper.idleMainLooper()
val shadowActivity = Shadows.shadowOf(fragmentActivity)
assertThat(shadowActivity.nextStartedActivity).isSameInstanceAs(intent)
assertThat(helpPreference?.intent).isSameInstanceAs(intent)
}
}

View File

@@ -24,11 +24,13 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothStatusCodes;
import android.platform.test.flag.junit.SetFlagsRule;
import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.flags.Flags;
@@ -114,6 +116,10 @@ public class AudioSharingErrorDialogFragmentTest {
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
TextView title = dialog.findViewById(R.id.title_text);
assertThat(title).isNotNull();
assertThat(title.getText().toString()).isEqualTo(
mParent.getString(R.string.audio_sharing_retry_dialog_title));
}
@Test

View File

@@ -120,9 +120,9 @@ public class AudioSharingIncompatibleDialogFragmentTest {
assertThat(dialog.isShowing()).isTrue();
TextView title = dialog.findViewById(R.id.title_text);
assertThat(title).isNotNull();
// TODO: use string res
assertThat(title.getText().toString()).isEqualTo(
"Can't share audio with " + TEST_DEVICE_NAME);
mParent.getString(R.string.audio_sharing_incompatible_dialog_title,
TEST_DEVICE_NAME));
}
@Test

View File

@@ -629,8 +629,8 @@ public class AudioSharingSwitchBarControllerTest {
AudioSharingProgressDialogFragment.class.getName());
AudioSharingProgressDialogFragment progressFragment =
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
// TODO: use string res once finalized
String expectedMessage = "Starting audio stream...";
String expectedMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_start_stream_content);
checkProgressDialogMessage(progressFragment, expectedMessage);
when(mBroadcast.isEnabled(null)).thenReturn(true);
@@ -640,8 +640,8 @@ public class AudioSharingSwitchBarControllerTest {
verify(mFeatureFactory.metricsFeatureProvider)
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
// TODO: use string res once finalized
expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
expectedMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_add_source_content, TEST_DEVICE_NAME2);
checkProgressDialogMessage(progressFragment, expectedMessage);
childFragments = mParentFragment.getChildFragmentManager().getFragments();
@@ -714,8 +714,8 @@ public class AudioSharingSwitchBarControllerTest {
AudioSharingProgressDialogFragment.class.getName());
AudioSharingProgressDialogFragment progressFragment =
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
// TODO: use string res once finalized
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
String expectedMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_add_source_content, TEST_DEVICE_NAME1);
checkProgressDialogMessage(progressFragment, expectedMessage);
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
@@ -755,8 +755,8 @@ public class AudioSharingSwitchBarControllerTest {
AudioSharingProgressDialogFragment.class.getName());
AudioSharingProgressDialogFragment progressFragment =
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
// TODO: use string res once finalized
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME2 + "...";
String expectedMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_add_source_content, TEST_DEVICE_NAME2);
checkProgressDialogMessage(progressFragment, expectedMessage);
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());
@@ -1027,8 +1027,8 @@ public class AudioSharingSwitchBarControllerTest {
// Progress dialog shows sharing progress for the auto add second sink.
AudioSharingProgressDialogFragment progressFragment =
(AudioSharingProgressDialogFragment) Iterables.getOnlyElement(childFragments);
// TODO: use string res once finalized
String expectedMessage = "Sharing with " + TEST_DEVICE_NAME1 + "...";
String expectedMessage = mContext.getString(
R.string.audio_sharing_progress_dialog_add_source_content, TEST_DEVICE_NAME1);
checkProgressDialogMessage(progressFragment, expectedMessage);
childFragments.forEach(fragment -> ((DialogFragment) fragment).dismiss());

View File

@@ -34,6 +34,8 @@ import android.os.UserHandle;
import androidx.preference.Preference;
import com.android.settings.R;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -153,6 +155,12 @@ public class AutoTimePreferenceControllerTest {
assertThat(mController.isEnabled()).isFalse();
}
@Test
public void getSummary() {
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.date_time_auto_summary));
}
private static TimeCapabilitiesAndConfig createCapabilitiesAndConfig(boolean autoSupported,
boolean autoEnabled) {
int configureAutoDetectionEnabledCapability =

View File

@@ -225,7 +225,8 @@ public class AutoTimeZonePreferenceControllerTest {
when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
when(mTimeManager.updateTimeZoneConfiguration(Mockito.any())).thenReturn(true);
assertThat(mController.getSummary()).isEqualTo("");
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.zone_auto_title_summary));
capabilitiesAndConfig = createCapabilitiesAndConfig(
/* autoSupported= */true, /* autoEnabled= */true, /* telephonySupported= */
@@ -233,7 +234,7 @@ public class AutoTimeZonePreferenceControllerTest {
when(mTimeManager.getTimeZoneCapabilitiesAndConfig()).thenReturn(capabilitiesAndConfig);
when(mTimeManager.updateTimeZoneConfiguration(Mockito.any())).thenReturn(true);
assertThat(mController.getSummary()).isEqualTo(
assertThat(mController.getSummary().toString()).isEqualTo(
mContext.getString(R.string.auto_zone_requires_location_summary));
}

View File

@@ -41,6 +41,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.util.ReflectionHelpers;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class FirmwareVersionDetailPreferenceControllerTest {
@@ -112,3 +113,4 @@ public class FirmwareVersionDetailPreferenceControllerTest {
}
}
}
// LINT.ThenChange(FirmwareVersionDetailPreferenceTest.kt)

View File

@@ -0,0 +1,76 @@
/*
* 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.deviceinfo.firmwareversion
import android.content.Context
import android.content.ContextWrapper
import android.os.Build
import android.os.SystemClock
import android.os.UserManager
import androidx.preference.Preference
import androidx.test.core.app.ApplicationProvider
import com.android.settings.deviceinfo.firmwareversion.FirmwareVersionDetailPreference.Companion.DELAY_TIMER_MILLIS
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.robolectric.RobolectricTestRunner
// LINT.IfChange
@RunWith(RobolectricTestRunner::class)
class FirmwareVersionDetailPreferenceTest {
private var userManager: UserManager? = null
private val context: Context =
object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
override fun getSystemService(name: String): Any? =
if (name == Context.USER_SERVICE) userManager else super.getSystemService(name)
}
private val preference = Preference(context)
private val firmwareVersionDetailPreference = FirmwareVersionDetailPreference()
@Test
fun getSummary() {
assertThat(firmwareVersionDetailPreference.getSummary(context))
.isEqualTo(Build.VERSION.RELEASE_OR_PREVIEW_DISPLAY)
}
@Test
fun onPreferenceClick_hits() {
prepareClick()
assertThat(firmwareVersionDetailPreference.onPreferenceClick(preference)).isFalse()
}
@Test
fun onPreferenceClick_restricted() {
prepareClick()
userManager = mock { on { hasUserRestriction(UserManager.DISALLOW_FUN) } doReturn true }
assertThat(firmwareVersionDetailPreference.onPreferenceClick(preference)).isTrue()
}
private fun prepareClick() {
SystemClock.sleep(DELAY_TIMER_MILLIS + 1)
assertThat(SystemClock.uptimeMillis()).isGreaterThan(DELAY_TIMER_MILLIS)
for (i in 1..<FirmwareVersionDetailPreference.ACTIVITY_TRIGGER_COUNT) {
assertThat(firmwareVersionDetailPreference.onPreferenceClick(preference)).isTrue()
}
}
}
// LINT.ThenChange(FirmwareVersionDetailPreferenceControllerTest.java)

View File

@@ -45,6 +45,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class CopyrightPreferenceControllerTest {
@@ -119,3 +120,4 @@ public class CopyrightPreferenceControllerTest {
return testResolveInfo;
}
}
// LINT.ThenChange(LegalPreferenceTest.kt)

View File

@@ -0,0 +1,92 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import android.content.ContextWrapper
import android.content.Intent
import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import androidx.test.core.app.ApplicationProvider
import com.android.settings.R
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
import org.robolectric.RobolectricTestRunner
// LINT.IfChange
@RunWith(RobolectricTestRunner::class)
class LegalPreferenceTest {
private val pkgManager = mock<PackageManager>()
private val context: Context =
object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
override fun getPackageManager(): PackageManager = pkgManager
}
private val copyrightPreference =
LegalPreference("copyright", R.string.copyright_title, "android.settings.COPYRIGHT")
@Test
fun isAvailable_systemApp_shouldReturnTrue() {
val testResolveInfos: MutableList<ResolveInfo> = ArrayList()
testResolveInfos.add(getTestResolveInfo(/* isSystemApp= */ true))
pkgManager.stub {
on { queryIntentActivities(any(Intent::class.java), anyInt()) } doReturn
testResolveInfos
}
assertThat(copyrightPreference.isAvailable(context)).isTrue()
}
@Test
fun isAvailable_nonSystemApp_shouldReturnFalse() {
val testResolveInfos: MutableList<ResolveInfo> = ArrayList()
testResolveInfos.add(getTestResolveInfo(/* isSystemApp= */ false))
pkgManager.stub {
on { queryIntentActivities(any(Intent::class.java), anyInt()) } doReturn
testResolveInfos
}
assertThat(copyrightPreference.isAvailable(context)).isFalse()
}
private fun getTestResolveInfo(isSystemApp: Boolean): ResolveInfo {
val testResolveInfo = ResolveInfo()
val testAppInfo = ApplicationInfo()
if (isSystemApp) {
testAppInfo.flags = testAppInfo.flags or ApplicationInfo.FLAG_SYSTEM
}
testResolveInfo.activityInfo =
ActivityInfo().apply {
name = "TestActivityName"
packageName = "TestPackageName"
applicationInfo = testAppInfo
}
return testResolveInfo
}
}
// LINT.ThenChange(CopyrightPreferenceControllerTest.java)

View File

@@ -0,0 +1,53 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.flag.junit.SetFlagsRule
import android.text.TextUtils
import androidx.test.core.app.ApplicationProvider
import com.android.settings.flags.Flags
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@RunWith(RobolectricTestRunner::class)
class LegalSettingsScreenTest {
@get:Rule val setFlagsRule = SetFlagsRule()
private val context: Context = ApplicationProvider.getApplicationContext()
private val legalSettingsScreen = LegalSettingsScreen()
@Test
fun screenKey_exist() {
assertThat(TextUtils.equals(legalSettingsScreen.key, LegalSettingsScreen.KEY)).isTrue()
}
@Test
@EnableFlags(Flags.FLAG_CATALYST_LEGAL_INFORMATION)
fun isFlagEnabled_returnTrue() {
assertThat(legalSettingsScreen.isFlagEnabled(context)).isTrue()
}
@Test
@DisableFlags(Flags.FLAG_CATALYST_LEGAL_INFORMATION)
fun isFlagDisabled_returnTrue() {
assertThat(legalSettingsScreen.isFlagEnabled(context)).isFalse()
}
}

View File

@@ -45,6 +45,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class LicensePreferenceControllerTest {
@@ -119,3 +120,4 @@ public class LicensePreferenceControllerTest {
return testResolveInfo;
}
}
// LINT.ThenChange(LegalPreferenceTest.kt)

View File

@@ -45,6 +45,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class TermsPreferenceControllerTest {
@@ -119,3 +120,4 @@ public class TermsPreferenceControllerTest {
return testResolveInfo;
}
}
// LINT.ThenChange(LegalPreferenceTest.kt)

View File

@@ -29,6 +29,7 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class WallpaperAttributionsPreferenceControllerTest {
@@ -55,3 +56,4 @@ public class WallpaperAttributionsPreferenceControllerTest {
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
}
// LINT.ThenChange(WallpaperAttributionsPreferenceTest.kt)

View File

@@ -0,0 +1,57 @@
/*
* 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.deviceinfo.legal
import android.content.Context
import android.content.ContextWrapper
import android.content.res.Resources
import androidx.test.core.app.ApplicationProvider
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.stub
import org.robolectric.RobolectricTestRunner
// LINT.IfChange
@RunWith(RobolectricTestRunner::class)
class WallpaperAttributionsPreferenceTest {
private val mockResources = mock<Resources>()
private val context: Context =
object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
override fun getResources(): Resources = mockResources
}
private val wallpaperAttributionsPreference = WallpaperAttributionsPreference()
@Test
fun isAvailable_configTrue_shouldReturnTrue() {
mockResources.stub { on { getBoolean(anyInt()) } doReturn true }
assertThat(wallpaperAttributionsPreference.isAvailable(context)).isTrue()
}
@Test
fun isAvailable_configFalse_shouldReturnFalse() {
mockResources.stub { on { getBoolean(anyInt()) } doReturn false }
assertThat(wallpaperAttributionsPreference.isAvailable(context)).isFalse()
}
}
// LINT.ThenChange(WallpaperAttributionsPreferenceControllerTest.java)

View File

@@ -45,6 +45,7 @@ import org.robolectric.RuntimeEnvironment;
import java.util.ArrayList;
import java.util.List;
// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class WebViewLicensePreferenceControllerTest {
@@ -119,3 +120,4 @@ public class WebViewLicensePreferenceControllerTest {
return testResolveInfo;
}
}
// LINT.ThenChange(LegalPreferenceTest.kt)

View File

@@ -0,0 +1,92 @@
/*
* 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.display;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.accessibility.Flags;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Tests for {@link AutoBrightnessPreferenceControllerForSetupWizard}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.class})
public class AutoBrightnessPreferenceControllerForSetupWizardTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "auto_brightness";
private Context mContext;
private AutoBrightnessPreferenceControllerForSetupWizard mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController =
new AutoBrightnessPreferenceControllerForSetupWizard(mContext, PREFERENCE_KEY);
}
@Test
@EnableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatus_configTrueAndFlagOn_shouldReturnAvailableUnsearchable() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
@EnableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatus_configFalseSetAndFlagOn_shouldReturnUnsupportedOnDevice() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, false);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
@DisableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatus_flagOff_shouldReturnConditionallyUnavailable() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -21,24 +21,18 @@ import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
import static android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;
import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import android.content.ContentResolver;
import android.content.Context;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.accessibility.Flags;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
@@ -46,13 +40,13 @@ import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
/**
* Tests for {@link AutoBrightnessPreferenceController}.
*/
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {SettingsShadowResources.class})
public class AutoBrightnessPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PREFERENCE_KEY = "auto_brightness";
private Context mContext;
@@ -130,34 +124,13 @@ public class AutoBrightnessPreferenceControllerTest {
}
@Test
public void getAvailabilityStatusNotInSUW_configTrueSet_shouldReturnAvailableUnsearchable() {
public void getAvailabilityStatus_configTrueSet_shouldReturnAvailableUnsearchable() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
@EnableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatusInSUW_configTrueAndFlagOn_shouldReturnAvailableUnsearchable() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, true);
mController.setInSetupWizard(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
}
@Test
@DisableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void
getAvailabilityStatusInSUW_configTrueAndFlagOff_shouldReturnConditionallyUnavailable() {
SettingsShadowResources.overrideResource(
com.android.internal.R.bool.config_automatic_brightness_available, true);
mController.setInSetupWizard(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_configFalseSet_shouldReturnUnsupportedOnDevice() {
SettingsShadowResources.overrideResource(

View File

@@ -0,0 +1,69 @@
/*
* 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.display;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.accessibility.Flags;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
/**
* Tests for {@link BrightnessLevelPreferenceControllerForSetupWizard}.
*/
@RunWith(RobolectricTestRunner.class)
public class BrightnessLevelPreferenceControllerForSetupWizardTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext;
private BrightnessLevelPreferenceControllerForSetupWizard mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = new BrightnessLevelPreferenceControllerForSetupWizard(mContext,
/* lifecycle= */ null);
}
@Test
@EnableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatus_flagOn_shouldReturnAvailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
@DisableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void getAvailabilityStatus_flagOff_shouldReturnConditionallyUnavailable() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
}

View File

@@ -33,9 +33,6 @@ import android.content.Context;
import android.content.Intent;
import android.hardware.display.BrightnessInfo;
import android.os.PowerManager;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings.System;
import android.view.Display;
@@ -43,12 +40,10 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.accessibility.Flags;
import com.android.settings.core.SettingsBaseActivity;
import com.android.settingslib.transition.SettingsTransitionHelper;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -61,12 +56,11 @@ import org.robolectric.shadows.ShadowActivity;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowContentResolver;
/**
* Tests for {@link BrightnessLevelPreferenceController}.
*/
@RunWith(RobolectricTestRunner.class)
public class BrightnessLevelPreferenceControllerTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@Mock
private PowerManager mPowerManager;
@Mock
@@ -95,28 +89,14 @@ public class BrightnessLevelPreferenceControllerTest {
mPowerManager);
when(mScreen.findPreference(anyString())).thenReturn(mPreference);
doReturn(mDisplay).when(mContext).getDisplay();
mController = spy(new BrightnessLevelPreferenceController(mContext, null));
mController = spy(new BrightnessLevelPreferenceController(mContext, /* lifecycle= */ null));
}
@Test
public void isAvailable_shouldAlwaysReturnTrueWhenNotInSetupWizard() {
public void isAvailable_shouldAlwaysReturnTrue() {
assertThat(mController.isAvailable()).isTrue();
}
@Test
@EnableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void isAvailable_inSetupWizardAndFlagOn_shouldReturnTrue() {
mController.setInSetupWizard(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
@DisableFlags(Flags.FLAG_ADD_BRIGHTNESS_SETTINGS_IN_SUW)
public void isAvailable_inSetupWizardAndFlagOff_shouldReturnFalse() {
mController.setInSetupWizard(true);
assertThat(mController.isAvailable()).isFalse();
}
@Test
public void onStart_shouldRegisterObserver() {
BrightnessLevelPreferenceController controller =

View File

@@ -19,19 +19,16 @@ package com.android.settings.network.apn
import android.content.Context
import android.net.Uri
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasScrollAction
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onChild
import androidx.compose.ui.test.onChildAt
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.onRoot
import androidx.compose.ui.test.performScrollToNode
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R
import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -39,8 +36,7 @@ import org.mockito.kotlin.mock
@RunWith(AndroidJUnit4::class)
class ApnEditPageProviderTest {
@get:Rule
val composeTestRule = createComposeRule()
@get:Rule val composeTestRule = createComposeRule()
private val context: Context = ApplicationProvider.getApplicationContext()
private val apnName = "apn_name"
@@ -51,86 +47,73 @@ class ApnEditPageProviderTest {
private val apnProtocolOptions =
context.resources.getStringArray(R.array.apn_protocol_entries).toList()
private val passwordTitle = context.resources.getString(R.string.apn_password)
private val apnInit = ApnData(
name = apnName,
proxy = proxy,
port = port,
apnType = apnType,
apnRoaming = apnProtocolOptions.indexOf(apnRoaming),
)
private val apnData = mutableStateOf(
apnInit
)
private val apnInit =
ApnData(
name = apnName,
proxy = proxy,
port = port,
apnType = apnType,
apnRoaming = apnProtocolOptions.indexOf(apnRoaming),
)
private val apnData = mutableStateOf(apnInit)
private val uri = mock<Uri> {}
@Test
fun apnEditPageProvider_name() {
Truth.assertThat(ApnEditPageProvider.name).isEqualTo("ApnEdit")
assertThat(ApnEditPageProvider.name).isEqualTo("ApnEdit")
}
@Test
fun title_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNodeWithText(context.getString(R.string.apn_edit)).assertIsDisplayed()
}
@Test
fun name_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNodeWithText(apnName, true).assertIsDisplayed()
}
@Test
fun proxy_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.onRoot().onChild().onChildAt(0)
.performScrollToNode(hasText(proxy, true))
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNode(hasScrollAction()).performScrollToNode(hasText(proxy, true))
composeTestRule.onNodeWithText(proxy, true).assertIsDisplayed()
}
@Test
fun port_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.onRoot().onChild().onChildAt(0)
.performScrollToNode(hasText(port, true))
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNode(hasScrollAction()).performScrollToNode(hasText(port, true))
composeTestRule.onNodeWithText(port, true).assertIsDisplayed()
}
@Test
fun apn_type_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.onRoot().onChild().onChildAt(0)
.performScrollToNode(hasText(apnType, true))
fun apnType_displayed() {
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNode(hasScrollAction()).performScrollToNode(hasText(apnType, true))
composeTestRule.onNodeWithText(apnType, true).assertIsDisplayed()
}
@Test
fun apn_roaming_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.onRoot().onChild().onChildAt(0)
.performScrollToNode(hasText(apnRoaming, true))
fun apnRoaming_displayed() {
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNode(hasScrollAction()).performScrollToNode(hasText(apnRoaming, true))
composeTestRule.onNodeWithText(apnRoaming, true).assertIsDisplayed()
}
@Test
fun password_displayed() {
composeTestRule.setContent {
ApnPage(apnInit, remember { apnData }, uri)
}
composeTestRule.onRoot().onChild().onChildAt(0)
.performScrollToNode(hasText(passwordTitle, true))
composeTestRule.setContent { ApnPage(apnInit, apnData, uri) }
composeTestRule.onNode(hasScrollAction()).performScrollToNode(hasText(passwordTitle, true))
composeTestRule.onNodeWithText(passwordTitle, true).assertIsDisplayed()
}
}