diff --git a/res/values/strings.xml b/res/values/strings.xml index 7e363e6f238..3d1c90c83c6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -571,11 +571,15 @@ Roaming charges may apply. - Set time automatically + Automatic date and time + + Set automatically using your network and wireless signals - Set automatically + Automatic time zone + + Set automatically based on mobile networks near you - Location will be used for setting the time zone when this toggle is on + Set automatically using your device location, if available. An active Wifi connection may also be required. Use locale default @@ -3772,7 +3776,7 @@ Location services - Use location + Use location for time zone Cannot set the time zone automatically @@ -3800,7 +3804,7 @@ - Automatic time zone is off + Not available when automatic time zone is off @@ -3811,7 +3815,7 @@ allowed for the user, e.g. because of device policy --> Location time zone detection changes are not allowed - Location may be used to set time zone + If your device location is available, it may be used to set your time zone View legal info, status, software version @@ -13670,4 +13674,11 @@ Search Settings + + + contacts, storage, account + + Contacts storage + + No default set diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml index a69dc26ce3f..25b8a5acf69 100644 --- a/res/xml/accessibility_settings_for_setup_wizard.xml +++ b/res/xml/accessibility_settings_for_setup_wizard.xml @@ -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"/> + + + @@ -48,6 +48,7 @@ @@ -60,6 +61,7 @@ createPreferenceControllers(Context context) { + // Requires lifecycle, so added programmatically (normally via resId). final List 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; } diff --git a/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java b/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java new file mode 100644 index 00000000000..bc6931de466 --- /dev/null +++ b/src/com/android/settings/applications/contacts/ContactsStoragePreferenceController.java @@ -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; + } +} diff --git a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java index f1e12a4a6fe..2c65934dd72 100644 --- a/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java +++ b/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBase.java @@ -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(); diff --git a/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt b/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt index f6e6f168144..b16bff1353b 100644 --- a/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt +++ b/src/com/android/settings/bluetooth/ui/model/DeviceSettingPreferenceModel.kt @@ -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 } diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt index a5997e7bc83..ecd700beee5 100644 --- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt +++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatter.kt @@ -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 { diff --git a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt index c0fbd4f2c4a..885217e460e 100644 --- a/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt +++ b/src/com/android/settings/bluetooth/ui/view/DeviceDetailsMoreSettingsFragment.kt @@ -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 - // 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) diff --git a/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt b/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt index 67a0ebc8398..fe66cb5dd51 100644 --- a/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt +++ b/src/com/android/settings/bluetooth/ui/viewmodel/BluetoothDeviceDetailsViewModel.kt @@ -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( diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java index 3750cf1ebbe..9b60df43029 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingConfirmDialogFragment.java @@ -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; diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java index 95b9bc36b92..e842b37eef7 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragment.java @@ -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; diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragment.java index aceeb94420e..a8ad70b3695 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragment.java @@ -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; diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java index ebc8cecadbf..b91a1f1df04 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java @@ -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 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); } diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index 6333f22b95b..4d53772cf66 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -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> controllers = mPreferenceControllers.values(); for (List controllerList : controllers) { diff --git a/src/com/android/settings/datetime/AutoTimePreferenceController.java b/src/com/android/settings/datetime/AutoTimePreferenceController.java index 2942acb1956..5b17e7ecb6c 100644 --- a/src/com/android/settings/datetime/AutoTimePreferenceController.java +++ b/src/com/android/settings/datetime/AutoTimePreferenceController.java @@ -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(); diff --git a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java index 8eccf319784..2f062897b48 100644 --- a/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java +++ b/src/com/android/settings/datetime/AutoTimeZonePreferenceController.java @@ -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 diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt new file mode 100644 index 00000000000..a039a3a4e82 --- /dev/null +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreference.kt @@ -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.. 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) diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java index e6ac6069d9a..7b0b2a67c63 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt index 0075068f4dc..fbc749bb1ec 100644 --- a/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt +++ b/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionScreen.kt @@ -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" } diff --git a/src/com/android/settings/deviceinfo/legal/CopyrightPreferenceController.java b/src/com/android/settings/deviceinfo/legal/CopyrightPreferenceController.java index 68e51f40df7..4c2413a8c23 100644 --- a/src/com/android/settings/deviceinfo/legal/CopyrightPreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/CopyrightPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/LegalPreference.kt b/src/com/android/settings/deviceinfo/legal/LegalPreference.kt new file mode 100644 index 00000000000..af3537bebb0 --- /dev/null +++ b/src/com/android/settings/deviceinfo/legal/LegalPreference.kt @@ -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 = context.packageManager.queryIntentActivities(intent, 0) + return list.firstOrNull { + (it.activityInfo.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM) != 0 + } + } +} +// LINT.ThenChange(LegalPreferenceController.java) diff --git a/src/com/android/settings/deviceinfo/legal/LegalPreferenceController.java b/src/com/android/settings/deviceinfo/legal/LegalPreferenceController.java index fe45923d60b..adbc2d75a3c 100644 --- a/src/com/android/settings/deviceinfo/legal/LegalPreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/LegalPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/LegalSettingsScreen.kt b/src/com/android/settings/deviceinfo/legal/LegalSettingsScreen.kt new file mode 100644 index 00000000000..f990b5dbeb0 --- /dev/null +++ b/src/com/android/settings/deviceinfo/legal/LegalSettingsScreen.kt @@ -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" + } +} diff --git a/src/com/android/settings/deviceinfo/legal/LicensePreferenceController.java b/src/com/android/settings/deviceinfo/legal/LicensePreferenceController.java index 67af15b4fc6..9bd74fd3a8d 100644 --- a/src/com/android/settings/deviceinfo/legal/LicensePreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/LicensePreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/ModuleLicensesListPreferenceController.java b/src/com/android/settings/deviceinfo/legal/ModuleLicensesListPreferenceController.java index 9faff856074..7b6ca460cbe 100644 --- a/src/com/android/settings/deviceinfo/legal/ModuleLicensesListPreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/ModuleLicensesListPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/ModuleLicensesScreen.kt b/src/com/android/settings/deviceinfo/legal/ModuleLicensesScreen.kt new file mode 100644 index 00000000000..c7f5e9c05d6 --- /dev/null +++ b/src/com/android/settings/deviceinfo/legal/ModuleLicensesScreen.kt @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/TermsPreferenceController.java b/src/com/android/settings/deviceinfo/legal/TermsPreferenceController.java index bccc44579b9..764bde44a04 100644 --- a/src/com/android/settings/deviceinfo/legal/TermsPreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/TermsPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreference.kt b/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreference.kt new file mode 100644 index 00000000000..7a934c29058 --- /dev/null +++ b/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreference.kt @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceController.java b/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceController.java index caa5afcdc58..cc9c0928df9 100644 --- a/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceController.java @@ -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) diff --git a/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceController.java b/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceController.java index 9d8b3f95027..ebb9152d80a 100644 --- a/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceController.java +++ b/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceController.java @@ -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) diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceController.java b/src/com/android/settings/display/AutoBrightnessPreferenceController.java index 3014f62b0a6..0a80d695b5f 100644 --- a/src/com/android/settings/display/AutoBrightnessPreferenceController.java +++ b/src/com/android/settings/display/AutoBrightnessPreferenceController.java @@ -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 diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java b/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java new file mode 100644 index 00000000000..7cdf3e0ea35 --- /dev/null +++ b/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java @@ -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(); + } +} diff --git a/src/com/android/settings/display/BrightnessLevelPreferenceController.java b/src/com/android/settings/display/BrightnessLevelPreferenceController.java index a32c965cb29..96043db4c41 100644 --- a/src/com/android/settings/display/BrightnessLevelPreferenceController.java +++ b/src/com/android/settings/display/BrightnessLevelPreferenceController.java @@ -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; } diff --git a/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizard.java b/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizard.java new file mode 100644 index 00000000000..6e002aed5fa --- /dev/null +++ b/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizard.java @@ -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(); + } +} diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardTest.java index 2ae598418ce..58578e76f50 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsForSetupWizardTest.java @@ -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 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) { diff --git a/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java new file mode 100644 index 00000000000..a934cba9a3c --- /dev/null +++ b/tests/robotests/src/com/android/settings/applications/contacts/ContactsStoragePreferenceControllerTest.java @@ -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"); + } +} diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java index e326c1e2630..9f0cb6e35d9 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDevicePairingDetailBaseTest.java @@ -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(); } diff --git a/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt b/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt index 51c0c3076ee..1ea804449c8 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt +++ b/tests/robotests/src/com/android/settings/bluetooth/ui/view/DeviceDetailsFragmentFormatterTest.kt @@ -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) } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragmentTest.java index fc38cd2817d..a8451b1e24e 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingErrorDialogFragmentTest.java @@ -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 diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragmentTest.java index 67cb2aa915b..8d89646d3fb 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingIncompatibleDialogFragmentTest.java @@ -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 diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java index 58696dccbea..fb5aa1c957e 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java @@ -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()); diff --git a/tests/robotests/src/com/android/settings/datetime/AutoTimePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/AutoTimePreferenceControllerTest.java index 9ac318a542a..ffb5141171c 100644 --- a/tests/robotests/src/com/android/settings/datetime/AutoTimePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/datetime/AutoTimePreferenceControllerTest.java @@ -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 = diff --git a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java index c2d0445e023..651915b4cab 100644 --- a/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/datetime/AutoTimeZonePreferenceControllerTest.java @@ -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)); } diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java index 420b9a337b4..51763bc2a71 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceControllerTest.java @@ -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) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt new file mode 100644 index 00000000000..69ea549bc43 --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/firmwareversion/FirmwareVersionDetailPreferenceTest.kt @@ -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..() + + 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 = 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 = 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) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/LegalSettingsScreenTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/legal/LegalSettingsScreenTest.kt new file mode 100644 index 00000000000..48e21b47dcc --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/LegalSettingsScreenTest.kt @@ -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() + } +} diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/LicensePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/legal/LicensePreferenceControllerTest.java index f51c7ad0e43..d6fdf73b3a2 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/legal/LicensePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/LicensePreferenceControllerTest.java @@ -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) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/TermsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/legal/TermsPreferenceControllerTest.java index 2a91fe1ee65..f8ccd0e432c 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/legal/TermsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/TermsPreferenceControllerTest.java @@ -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) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceControllerTest.java index c06f069e2d5..2f8a8d44c2f 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceControllerTest.java @@ -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 { @@ -54,4 +55,5 @@ public class WallpaperAttributionsPreferenceControllerTest { assertThat(mController.getAvailabilityStatus()) .isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE); } -} \ No newline at end of file +} +// LINT.ThenChange(WallpaperAttributionsPreferenceTest.kt) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceTest.kt b/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceTest.kt new file mode 100644 index 00000000000..00e0b0150f3 --- /dev/null +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/WallpaperAttributionsPreferenceTest.kt @@ -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() + + 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) diff --git a/tests/robotests/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceControllerTest.java index 55604c33373..0836839516c 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/legal/WebViewLicensePreferenceControllerTest.java @@ -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) diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizardTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizardTest.java new file mode 100644 index 00000000000..1113d688f2b --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizardTest.java @@ -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); + } +} + diff --git a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java index 13cd86d5a2a..0122044f13c 100644 --- a/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AutoBrightnessPreferenceControllerTest.java @@ -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( diff --git a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizardTest.java b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizardTest.java new file mode 100644 index 00000000000..25ddd1e6003 --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerForSetupWizardTest.java @@ -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); + } +} diff --git a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java index 009ca95e4d3..eb830404307 100644 --- a/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/BrightnessLevelPreferenceControllerTest.java @@ -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 = diff --git a/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt b/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt index d310604ccf9..2f7417d212f 100644 --- a/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/apn/ApnEditPageProviderTest.kt @@ -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 {} @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() } -} \ No newline at end of file +}