diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 1990ce04b4d..f4ff282238c 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3241,6 +3241,17 @@ + + + + + + + + + diff --git a/res/drawable/button_border_selected.xml b/res/drawable/button_border_selected.xml index c2b947d83f1..65dfe1b67a3 100644 --- a/res/drawable/button_border_selected.xml +++ b/res/drawable/button_border_selected.xml @@ -19,7 +19,7 @@ diff --git a/res/drawable/face_enroll_introduction.xml b/res/drawable/face_enroll_introduction.xml index 6065f237237..576ac58d981 100644 --- a/res/drawable/face_enroll_introduction.xml +++ b/res/drawable/face_enroll_introduction.xml @@ -16,8 +16,8 @@ --> diff --git a/res/layout/notif_importance_preference.xml b/res/layout/notif_importance_preference.xml index 3507675c44a..2fc2740a829 100644 --- a/res/layout/notif_importance_preference.xml +++ b/res/layout/notif_importance_preference.xml @@ -33,7 +33,7 @@ android:focusable="true"> + android:textAppearance="@style/TextAppearance.NotificationImportanceDetail" + android:visibility="gone" /> + android:textAppearance="@style/TextAppearance.NotificationImportanceDetail" + android:visibility="gone" /> \ No newline at end of file diff --git a/res/layout/profile_owner_add.xml b/res/layout/profile_owner_add.xml index 84c51fd8316..2ee5dfce740 100644 --- a/res/layout/profile_owner_add.xml +++ b/res/layout/profile_owner_add.xml @@ -27,12 +27,17 @@ android:layout_height="0dp" android:layout_weight="1" android:scrollbars = "vertical" - android:padding="?dialogPreferredPadding" + android:paddingStart="24dp" + android:paddingEnd="24dp" + android:paddingTop="12dp" + android:paddingBottom="6dp" android:gravity="center_vertical"/> + android:paddingStart="24dp" + android:paddingEnd="24dp" + android:paddingTop="6dp" + android:paddingBottom="12dp"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index d09851a3241..5083de49217 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8100,7 +8100,7 @@ Block - Gentle + Silent Prioritized @@ -8117,19 +8117,10 @@ In the pull-down shade, collapse notifications to one line - Helps you focus with notifications only in the pull-down shade. Always silent. - - - Displays below priority notifications. Always silent. - - - Displays below priority notifications. Always silent. - - - Displays below priority notifications. Always silent. + Helps you focus without sound or vibration - Gets your attention with sound & a status bar icon. Shows on lock screen. + Gets your attention with sound or vibration When device is unlocked, show notifications as a banner across the top of the screen @@ -10251,8 +10242,6 @@ Show global actions Global actions - - The global actions panel can be accessed even when the device is locked. Swipe fingerprint for notifications diff --git a/res/xml/adaptive_sleep_detail.xml b/res/xml/adaptive_sleep_detail.xml index 2fa511bc247..606bb55d465 100644 --- a/res/xml/adaptive_sleep_detail.xml +++ b/res/xml/adaptive_sleep_detail.xml @@ -33,7 +33,7 @@ android:title="@string/adaptive_sleep_title" android:summary="@string/adaptive_sleep_description" settings:keywords="@string/keywords_display_adaptive_sleep" - settings:controller="com.android.settings.display.AdaptiveSleepPreferenceController" + settings:controller="com.android.settings.display.AdaptiveSleepDetailPreferenceController" settings:useAdminDisabledSummary="true" settings:allowDividerAbove="true" /> diff --git a/res/xml/global_actions_panel_settings.xml b/res/xml/global_actions_panel_settings.xml index af155bc74fc..2dc0fe9a046 100644 --- a/res/xml/global_actions_panel_settings.xml +++ b/res/xml/global_actions_panel_settings.xml @@ -33,8 +33,4 @@ app:controller="com.android.settings.gestures.GlobalActionsPanelPreferenceController" app:allowDividerAbove="true" /> - - - \ No newline at end of file + diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java index f6fe0c25183..b4ebc5759cf 100644 --- a/src/com/android/settings/Settings.java +++ b/src/com/android/settings/Settings.java @@ -165,6 +165,7 @@ public class Settings extends SettingsActivity { public static class BluetoothDeviceDetailActivity extends SettingsActivity { /* empty */ } public static class WifiCallingDisclaimerActivity extends SettingsActivity { /* empty */ } public static class MobileNetworkListActivity extends SettingsActivity {} + public static class GlobalActionsPanelSettingsActivity extends SettingsActivity {} // Top level categories for new IA public static class NetworkDashboardActivity extends SettingsActivity {} diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index 1dbae001f13..cb98892e853 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -36,6 +36,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.os.Vibrator; +import android.provider.DeviceConfig; import android.provider.SearchIndexableResource; import android.provider.Settings; import android.text.TextUtils; @@ -168,6 +169,8 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements private static final String ANIMATION_ON_VALUE = "1"; private static final String ANIMATION_OFF_VALUE = "0"; + static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled"; + private final Map mLongPressTimeoutValueToTitleMap = new HashMap<>(); private final Handler mHandler = new Handler(); @@ -389,6 +392,15 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements : stateSummaryCombo; } + @VisibleForTesting + static boolean isRampingRingerEnabled(final Context context) { + return (Settings.Global.getInt( + context.getContentResolver(), + Settings.Global.APPLY_RAMPING_RINGER, 0) == 1) + && DeviceConfig.getBoolean( + DeviceConfig.NAMESPACE_TELEPHONY, RAMPING_RINGER_ENABLED, false); + } + private void handleToggleTextContrastPreferenceClick() { Settings.Secure.putInt(getContentResolver(), Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED, @@ -866,7 +878,7 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements Settings.System.RING_VIBRATION_INTENSITY, vibrator.getDefaultRingVibrationIntensity()); if (Settings.System.getInt(context.getContentResolver(), - Settings.System.VIBRATE_WHEN_RINGING, 0) == 0) { + Settings.System.VIBRATE_WHEN_RINGING, 0) == 0 && !isRampingRingerEnabled(context)) { ringIntensity = Vibrator.VIBRATION_INTENSITY_OFF; } CharSequence ringIntensityString = diff --git a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java index 818c41449d1..4dee34824af 100644 --- a/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java +++ b/src/com/android/settings/accessibility/RingVibrationIntensityPreferenceController.java @@ -29,7 +29,7 @@ public class RingVibrationIntensityPreferenceController public RingVibrationIntensityPreferenceController(Context context) { super(context, PREF_KEY, Settings.System.RING_VIBRATION_INTENSITY, - Settings.System.VIBRATE_WHEN_RINGING); + Settings.System.VIBRATE_WHEN_RINGING, /* supportRampingRinger= */ true); } @Override diff --git a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java b/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java index 3e12011762f..babfb9a2000 100644 --- a/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/RingVibrationPreferenceFragment.java @@ -46,7 +46,11 @@ public class RingVibrationPreferenceFragment extends VibrationPreferenceFragment @Override protected String getVibrationEnabledSetting() { - return Settings.System.VIBRATE_WHEN_RINGING; + if (AccessibilitySettings.isRampingRingerEnabled(getContext())) { + return Settings.Global.APPLY_RAMPING_RINGER; + } else { + return Settings.System.VIBRATE_WHEN_RINGING; + } } @Override diff --git a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java index e52f92d0946..9d7117640cd 100644 --- a/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java +++ b/src/com/android/settings/accessibility/VibrationIntensityPreferenceController.java @@ -40,15 +40,17 @@ public abstract class VibrationIntensityPreferenceController extends BasePrefere private final SettingObserver mSettingsContentObserver; private final String mSettingKey; private final String mEnabledKey; + private final boolean mSupportRampingRinger; private Preference mPreference; public VibrationIntensityPreferenceController(Context context, String prefkey, - String settingKey, String enabledKey) { + String settingKey, String enabledKey, boolean supportRampingRinger) { super(context, prefkey); mVibrator = mContext.getSystemService(Vibrator.class); mSettingKey = settingKey; mEnabledKey = enabledKey; + mSupportRampingRinger= supportRampingRinger; mSettingsContentObserver = new SettingObserver(settingKey) { @Override public void onChange(boolean selfChange, Uri uri) { @@ -57,6 +59,11 @@ public abstract class VibrationIntensityPreferenceController extends BasePrefere }; } + public VibrationIntensityPreferenceController(Context context, String prefkey, + String settingKey, String enabledKey) { + this(context, prefkey, settingKey, enabledKey, /* supportRampingRinger= */ false); + } + @Override public void onStart() { mContext.getContentResolver().registerContentObserver( @@ -80,10 +87,11 @@ public abstract class VibrationIntensityPreferenceController extends BasePrefere public CharSequence getSummary() { final int intensity = Settings.System.getInt(mContext.getContentResolver(), mSettingKey, getDefaultIntensity()); - final boolean enabled = Settings.System.getInt(mContext.getContentResolver(), - mEnabledKey, 1) == 1; + final boolean enabled = (Settings.System.getInt(mContext.getContentResolver(), + mEnabledKey, 1) == 1) || + (mSupportRampingRinger && AccessibilitySettings.isRampingRingerEnabled(mContext)); return getIntensityString(mContext, enabled ? intensity : Vibrator.VIBRATION_INTENSITY_OFF); - } + } public static CharSequence getIntensityString(Context context, int intensity) { final boolean supportsMultipleIntensities = context.getResources().getBoolean( diff --git a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java index deaef469c42..480041a6719 100644 --- a/src/com/android/settings/accessibility/VibrationPreferenceFragment.java +++ b/src/com/android/settings/accessibility/VibrationPreferenceFragment.java @@ -114,11 +114,20 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm boolean vibrationEnabled = candidate.getIntensity() != Vibrator.VIBRATION_INTENSITY_OFF; if (hasVibrationEnabledSetting()) { // Update vibration enabled setting - boolean wasEnabled = Settings.System.getInt(getContext().getContentResolver(), - getVibrationEnabledSetting(), 1) == 1; + final String vibrationEnabledSetting = getVibrationEnabledSetting(); + final boolean wasEnabled = TextUtils.equals( + vibrationEnabledSetting, Settings.Global.APPLY_RAMPING_RINGER) + ? true + : (Settings.System.getInt( + getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1); if (vibrationEnabled != wasEnabled) { - Settings.System.putInt(getContext().getContentResolver(), - getVibrationEnabledSetting(), vibrationEnabled ? 1 : 0); + if (vibrationEnabledSetting.equals(Settings.Global.APPLY_RAMPING_RINGER)) { + Settings.Global.putInt(getContext().getContentResolver(), + vibrationEnabledSetting, 0); + } else { + Settings.System.putInt(getContext().getContentResolver(), + vibrationEnabledSetting, vibrationEnabled ? 1 : 0); + } } } // There are two conditions that need to change the intensity. @@ -196,8 +205,12 @@ public abstract class VibrationPreferenceFragment extends RadioButtonPickerFragm protected String getDefaultKey() { int vibrationIntensity = Settings.System.getInt(getContext().getContentResolver(), getVibrationIntensitySetting(), getDefaultVibrationIntensity()); - final boolean vibrationEnabled = Settings.System.getInt(getContext().getContentResolver(), - getVibrationEnabledSetting(), 1) == 1; + final String vibrationEnabledSetting = getVibrationEnabledSetting(); + final boolean vibrationEnabled = TextUtils.equals( + vibrationEnabledSetting, Settings.Global.APPLY_RAMPING_RINGER) + ? true + : (Settings.System.getInt( + getContext().getContentResolver(), vibrationEnabledSetting, 1) == 1); if (!vibrationEnabled) { vibrationIntensity = Vibrator.VIBRATION_INTENSITY_OFF; } diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java index d2b21b0158a..971c6f53f99 100644 --- a/src/com/android/settings/applications/manageapplications/ManageApplications.java +++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java @@ -1169,10 +1169,16 @@ public class ManageApplications extends InstrumentedFragment }); } - public void filterSearch(String query) { + @VisibleForTesting + void filterSearch(String query) { if (mSearchFilter == null) { mSearchFilter = new SearchFilter(); } + // If we haven't load apps list completely, don't filter anything. + if(mOriginalEntries == null) { + Log.w(TAG, "Apps haven't loaded completely yet, so nothing can be filtered"); + return; + } mSearchFilter.filter(query); } diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java index 0d0bd2016c5..8b06975bc06 100644 --- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java +++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminAdd.java @@ -312,7 +312,7 @@ public class DeviceAdminAdd extends Activity { addAndFinish(); } }) - .setNeutralButton(R.string.cancel, null) + .setNegativeButton(R.string.cancel, null) .setOnDismissListener(new DialogInterface.OnDismissListener() { public void onDismiss(DialogInterface dialogInterface) { finish(); diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index 956ba49d6be..429d93bd5ce 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -51,7 +51,7 @@ public class FaceEnrollEducation extends BiometricEnrollBase { private static final int ON = 1; private static final int OFF = 0; // 8 seconds. - private static final long FACE_ENROLL_EDUCATION_DELAY = 8000; + private static final long FACE_ENROLL_EDUCATION_DELAY = 3000; private FaceManager mFaceManager; private FaceEnrollAccessibilityToggle mSwitchDiversity; @@ -101,14 +101,26 @@ public class FaceEnrollEducation extends BiometricEnrollBase { mDescriptionText = findViewById(R.id.sud_layout_description); mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class); - mFooterBarMixin.setSecondaryButton( - new FooterButton.Builder(this) - .setText(R.string.security_settings_face_enroll_enrolling_skip) - .setListener(this::onSkipButtonClick) - .setButtonType(FooterButton.ButtonType.SKIP) - .setTheme(R.style.SudGlifButton_Secondary) - .build() - ); + + if (WizardManagerHelper.isAnySetupWizard(getIntent())) { + mFooterBarMixin.setSecondaryButton( + new FooterButton.Builder(this) + .setText(R.string.skip_label) + .setListener(this::onSkipButtonClick) + .setButtonType(FooterButton.ButtonType.SKIP) + .setTheme(R.style.SudGlifButton_Secondary) + .build() + ); + } else { + mFooterBarMixin.setSecondaryButton( + new FooterButton.Builder(this) + .setText(R.string.security_settings_face_enroll_introduction_cancel) + .setListener(this::onSkipButtonClick) + .setButtonType(FooterButton.ButtonType.CANCEL) + .setTheme(R.style.SudGlifButton_Secondary) + .build() + ); + } final FooterButton footerButton = new FooterButton.Builder(this) .setText(R.string.security_settings_face_enroll_education_start) diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java index ce5c768eb20..e92c967c8f5 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintEnrollEnrolling.java @@ -49,6 +49,7 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.google.android.setupcompat.template.FooterBarMixin; import com.google.android.setupcompat.template.FooterButton; +import com.google.android.setupdesign.util.DescriptionStyler; /** * Activity which handles the actual enrolling for fingerprint. @@ -137,6 +138,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling { mProgressBar = (ProgressBar) findViewById(R.id.fingerprint_progress_bar); mVibrator = getSystemService(Vibrator.class); + if (getLayout().shouldApplyPartnerHeavyThemeResource()) { + DescriptionStyler.applyPartnerCustomizationStyle(mRepeatMessage); + } mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class); mFooterBarMixin.setSecondaryButton( new FooterButton.Builder(this) diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index d073dbc84c3..b35a9747a43 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -83,6 +83,7 @@ import com.android.settings.gestures.AssistGestureSettings; import com.android.settings.gestures.DoubleTapPowerSettings; import com.android.settings.gestures.DoubleTapScreenSettings; import com.android.settings.gestures.DoubleTwistGestureSettings; +import com.android.settings.gestures.GlobalActionsPanelSettings; import com.android.settings.gestures.PickupGestureSettings; import com.android.settings.gestures.SwipeToNotificationSettings; import com.android.settings.gestures.SystemNavigationGestureSettings; @@ -279,7 +280,8 @@ public class SettingsGateway { ToggleBackupSettingFragment.class.getName(), PreviouslyConnectedDeviceDashboardFragment.class.getName(), BatterySaverScheduleSettings.class.getName(), - MobileNetworkListFragment.class.getName() + MobileNetworkListFragment.class.getName(), + GlobalActionsPanelSettings.class.getName() }; public static final String[] SETTINGS_FOR_RESTRICTED = { diff --git a/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java b/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java index 4aaa4906335..81efaa6d157 100644 --- a/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java +++ b/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceController.java @@ -82,10 +82,10 @@ public class AllowBackgroundActivityStartsPreferenceController private boolean isDefaultEnabled() { // The default in the absence of user preference is settable via DeviceConfig. - // Note that the default default is enabled. + // Note that the default default is disabled. return DeviceConfig.getBoolean( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED, - /*defaultValue*/ true); + /*defaultValue*/ false); } } diff --git a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java index ddc3ad6643e..537c705d0bf 100644 --- a/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java +++ b/src/com/android/settings/deviceinfo/PhoneNumberPreferenceController.java @@ -120,7 +120,7 @@ public class PhoneNumberPreferenceController extends BasePreferenceController { private CharSequence getFirstPhoneNumber() { final List subscriptionInfoList = mSubscriptionManager.getActiveSubscriptionInfoList(true); - if (subscriptionInfoList == null) { + if (subscriptionInfoList == null || subscriptionInfoList.isEmpty()) { return mContext.getText(R.string.device_info_default); } diff --git a/src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java new file mode 100644 index 00000000000..5ce7be5b43e --- /dev/null +++ b/src/com/android/settings/display/AdaptiveSleepDetailPreferenceController.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2019 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.preference.Preference; + +public class AdaptiveSleepDetailPreferenceController extends AdaptiveSleepPreferenceController { + public AdaptiveSleepDetailPreferenceController(Context context, String key) { + super(context, key); + } + + @Override + @AvailabilityStatus + public int getAvailabilityStatus() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_adaptive_sleep_available) + ? AVAILABLE + : UNSUPPORTED_ON_DEVICE; + } + + @Override + public boolean isSliceable() { + return true; + } + + @Override + public void updateState(Preference preference) { + super.updateState(preference); + preference.setEnabled(super.hasSufficientPermissions); + } +} diff --git a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java index fab3efad39e..6b91792800e 100644 --- a/src/com/android/settings/display/AdaptiveSleepPreferenceController.java +++ b/src/com/android/settings/display/AdaptiveSleepPreferenceController.java @@ -29,7 +29,7 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle private final String SYSTEM_KEY = ADAPTIVE_SLEEP; private final int DEFAULT_VALUE = 0; - private final boolean hasSufficientPermissions; + final boolean hasSufficientPermissions; public AdaptiveSleepPreferenceController(Context context, String key) { super(context, key); @@ -57,17 +57,10 @@ public class AdaptiveSleepPreferenceController extends TogglePreferenceControlle @Override @AvailabilityStatus public int getAvailabilityStatus() { - final boolean supportedOnDevice = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_adaptive_sleep_available); - if (!supportedOnDevice) { - return UNSUPPORTED_ON_DEVICE; - } - return hasSufficientPermissions ? AVAILABLE : DISABLED_DEPENDENT_SETTING; - } - - @Override - public boolean isSliceable() { - return true; + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_adaptive_sleep_available) + ? AVAILABLE_UNSEARCHABLE + : UNSUPPORTED_ON_DEVICE; } @Override diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java index 0c099ca3dff..c0b45907097 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java +++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java @@ -277,8 +277,7 @@ public class MobileNetworkUtils { return true; } - if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA - && !isTdscdmaSupported(context, telephonyManager)) { + if (shouldSpeciallyUpdateGsmCdma(context, subId)) { return true; } } @@ -296,16 +295,15 @@ public class MobileNetworkUtils { if (isGsmBasicOptions(context, subId)) { return true; } - final int settingsNetworkMode = android.provider.Settings.Global.getInt( + final int networkMode = android.provider.Settings.Global.getInt( context.getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, Phone.PREFERRED_NT_MODE); if (isWorldMode(context, subId)) { - if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO - || settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) { + if (networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO + || networkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) { return true; - } else if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA - && !MobileNetworkUtils.isTdscdmaSupported(context, subId)) { + } else if (shouldSpeciallyUpdateGsmCdma(context, subId)) { return true; } } @@ -362,16 +360,24 @@ public class MobileNetworkUtils { return false; } + final int networkMode = android.provider.Settings.Global.getInt( + context.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, + Phone.PREFERRED_NT_MODE); + if (networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO + && isWorldMode(context, subId)) { + return false; + } + if (shouldSpeciallyUpdateGsmCdma(context, subId)) { + return false; + } + if (isGsmBasicOptions(context, subId)) { return true; } - final int settingsNetworkMode = android.provider.Settings.Global.getInt( - context.getContentResolver(), - android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, - Phone.PREFERRED_NT_MODE); if (isWorldMode(context, subId)) { - if (settingsNetworkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) { + if (networkMode == TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA) { return true; } } @@ -414,7 +420,6 @@ public class MobileNetworkUtils { return false; } - /** * Return subId that supported by search. If there are more than one, return first one, * otherwise return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} @@ -461,4 +466,33 @@ public class MobileNetworkUtils { } } } + + /** + * This method is migrated from {@link com.android.phone.MobileNetworkSettings} and we should + * use it carefully. This code snippet doesn't have very clear meaning however we should + * update GSM or CDMA differently based on what it returns. + * + * 1. For all CDMA settings, make them visible if it return {@code true} + * 2. For GSM settings, make them visible if it return {@code true} unless 3 + * 3. For network select settings, make it invisible if it return {@code true} + */ + @VisibleForTesting + static boolean shouldSpeciallyUpdateGsmCdma(Context context, int subId) { + final int networkMode = android.provider.Settings.Global.getInt( + context.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId, + Phone.PREFERRED_NT_MODE); + if (networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM + || networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA + || networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA + || networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA + || networkMode == TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA + || networkMode == TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) { + if (!isTdscdmaSupported(context, subId) && isWorldMode(context, subId)) { + return true; + } + } + + return false; + } } diff --git a/src/com/android/settings/notification/AppBubbleNotificationSettings.java b/src/com/android/settings/notification/AppBubbleNotificationSettings.java index f55c262e3e9..2517573f0ad 100644 --- a/src/com/android/settings/notification/AppBubbleNotificationSettings.java +++ b/src/com/android/settings/notification/AppBubbleNotificationSettings.java @@ -61,7 +61,10 @@ public class AppBubbleNotificationSettings extends NotificationSettingsBase impl Context context, AppBubbleNotificationSettings fragment) { List controllers = new ArrayList<>(); controllers.add(new HeaderPreferenceController(context, fragment)); - controllers.add(new BubblePreferenceController(context, new NotificationBackend())); + controllers.add(new BubblePreferenceController(context, fragment != null + ? fragment.getChildFragmentManager() + : null, + new NotificationBackend(), true /* isAppPage */)); return controllers; } diff --git a/src/com/android/settings/notification/BubblePreferenceController.java b/src/com/android/settings/notification/BubblePreferenceController.java index 200c4b2dfec..b68f11db0c8 100644 --- a/src/com/android/settings/notification/BubblePreferenceController.java +++ b/src/com/android/settings/notification/BubblePreferenceController.java @@ -18,6 +18,7 @@ package com.android.settings.notification; import static android.provider.Settings.Secure.NOTIFICATION_BUBBLES; +import android.annotation.Nullable; import android.content.Context; import android.provider.Settings; @@ -40,15 +41,13 @@ public class BubblePreferenceController extends NotificationPreferenceController static final int SYSTEM_WIDE_OFF = 0; private FragmentManager mFragmentManager; + private boolean mIsAppPage; - public BubblePreferenceController(Context context, NotificationBackend backend) { - super(context, backend); - } - - public BubblePreferenceController(Context context, FragmentManager fragmentManager, - NotificationBackend backend) { + public BubblePreferenceController(Context context, @Nullable FragmentManager fragmentManager, + NotificationBackend backend, boolean isAppPage) { super(context, backend); mFragmentManager = fragmentManager; + mIsAppPage = isAppPage; } @Override @@ -61,7 +60,7 @@ public class BubblePreferenceController extends NotificationPreferenceController if (!super.isAvailable()) { return false; } - if (!isGloballyEnabled()) { + if (!mIsAppPage && !isGloballyEnabled()) { return false; } if (mChannel != null) { @@ -96,7 +95,7 @@ public class BubblePreferenceController extends NotificationPreferenceController mChannel.setAllowBubbles(value); saveChannel(); return true; - } else if (mAppRow != null) { + } else if (mAppRow != null && mFragmentManager != null) { RestrictedSwitchPreference pref = (RestrictedSwitchPreference) preference; // if the global setting is off, toggling app level permission requires extra // confirmation diff --git a/src/com/android/settings/notification/ChannelNotificationSettings.java b/src/com/android/settings/notification/ChannelNotificationSettings.java index 9f9d438a90f..8399a494994 100644 --- a/src/com/android/settings/notification/ChannelNotificationSettings.java +++ b/src/com/android/settings/notification/ChannelNotificationSettings.java @@ -114,7 +114,8 @@ public class ChannelNotificationSettings extends NotificationSettingsBase { mControllers.add(new BadgePreferenceController(context, mBackend)); mControllers.add(new DndPreferenceController(context, mBackend)); mControllers.add(new NotificationsOffPreferenceController(context)); - mControllers.add(new BubblePreferenceController(context, mBackend)); + mControllers.add(new BubblePreferenceController(context, getChildFragmentManager(), + mBackend, false /* isAppPage */)); return new ArrayList<>(mControllers); } } diff --git a/src/com/android/settings/notification/ImportancePreference.java b/src/com/android/settings/notification/ImportancePreference.java index f48882d8518..0d39c8f0fe0 100644 --- a/src/com/android/settings/notification/ImportancePreference.java +++ b/src/com/android/settings/notification/ImportancePreference.java @@ -24,6 +24,7 @@ import static android.view.View.GONE; import static android.view.View.VISIBLE; import android.content.Context; +import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.transition.AutoTransition; import android.transition.TransitionManager; @@ -31,8 +32,10 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageView; import android.widget.TextView; +import com.android.settings.Utils; import com.android.settingslib.R; import androidx.preference.Preference; @@ -50,6 +53,7 @@ public class ImportancePreference extends Preference { Drawable selectedBackground; Drawable unselectedBackground; private static final int BUTTON_ANIM_TIME_MS = 100; + private static final boolean SHOW_BUTTON_SUMMARY = false; public ImportancePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -140,32 +144,45 @@ public class ImportancePreference extends Preference { }); } + private ColorStateList getAccentTint() { + return Utils.getColorAccent(getContext()); + } + + private ColorStateList getRegularTint() { + return Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary); + } + void setImportanceSummary(ViewGroup parent, int importance, boolean fromUser) { if (fromUser) { AutoTransition transition = new AutoTransition(); transition.setDuration(BUTTON_ANIM_TIME_MS); TransitionManager.beginDelayedTransition(parent, transition); } + + ColorStateList colorAccent = getAccentTint(); + ColorStateList colorNormal = getRegularTint(); + if (importance >= IMPORTANCE_DEFAULT) { parent.findViewById(R.id.silence_summary).setVisibility(GONE); + ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorNormal); + ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorNormal); + + ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorAccent); + ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorAccent); + TextView view = parent.findViewById(R.id.alert_summary); view.setText(R.string.notification_channel_summary_default); view.setVisibility(VISIBLE); } else { parent.findViewById(R.id.alert_summary).setVisibility(GONE); + ((ImageView) parent.findViewById(R.id.alert_icon)).setImageTintList(colorNormal); + ((TextView) parent.findViewById(R.id.alert_label)).setTextColor(colorNormal); + + ((ImageView) parent.findViewById(R.id.silence_icon)).setImageTintList(colorAccent); + ((TextView) parent.findViewById(R.id.silence_label)).setTextColor(colorAccent); TextView view = parent.findViewById(R.id.silence_summary); view.setVisibility(VISIBLE); - if (mDisplayInStatusBar) { - if (mDisplayOnLockscreen) { - view.setText(R.string.notification_channel_summary_low_status_lock); - } else { - view.setText(R.string.notification_channel_summary_low_status); - } - } else if (mDisplayOnLockscreen) { - view.setText(R.string.notification_channel_summary_low_lock); - } else { - view.setText(R.string.notification_channel_summary_low); - } + view.setText(R.string.notification_channel_summary_low); } } } diff --git a/src/com/android/settings/notification/NotificationBackend.java b/src/com/android/settings/notification/NotificationBackend.java index 7d7ca8231f9..a8396a14929 100644 --- a/src/com/android/settings/notification/NotificationBackend.java +++ b/src/com/android/settings/notification/NotificationBackend.java @@ -98,8 +98,7 @@ public class NotificationBackend { AppRow row) { row.systemApp = Utils.isSystemPackage(context.getResources(), pm, app); List roles = rm.getHeldRolesFromController(app.packageName); - if (roles.contains(RoleManager.ROLE_SMS) - || roles.contains(RoleManager.ROLE_DIALER) + if (roles.contains(RoleManager.ROLE_DIALER) || roles.contains(RoleManager.ROLE_EMERGENCY)) { row.systemApp = true; } diff --git a/src/com/android/settings/notification/NotificationSettingsBase.java b/src/com/android/settings/notification/NotificationSettingsBase.java index 32d8e913f78..fdd71e5c4a0 100644 --- a/src/com/android/settings/notification/NotificationSettingsBase.java +++ b/src/com/android/settings/notification/NotificationSettingsBase.java @@ -53,6 +53,7 @@ import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.Utils; import com.android.settings.applications.AppInfoBase; import com.android.settings.core.SubSettingLauncher; import com.android.settings.dashboard.DashboardFragment; @@ -279,6 +280,12 @@ abstract public class NotificationSettingsBase extends DashboardFragment { return null; } + private Drawable getAlertingIcon() { + Drawable icon = getContext().getDrawable(R.drawable.ic_notifications); + icon.setTintList(Utils.getColorAccent(getContext())); + return icon; + } + protected Preference populateSingleChannelPrefs(PreferenceGroup parent, final NotificationChannel channel, final boolean groupBlocked) { MasterSwitchPreference channelPref = new MasterSwitchPreference(getPrefContext()); @@ -286,8 +293,10 @@ abstract public class NotificationSettingsBase extends DashboardFragment { && isChannelBlockable(channel) && isChannelConfigurable(channel) && !groupBlocked); - channelPref.setIcon(channel.getImportance() > IMPORTANCE_LOW - ? R.drawable.ic_notification_alert : R.drawable.ic_notification_silence); + channelPref.setIcon(null); + if (channel.getImportance() > IMPORTANCE_LOW) { + channelPref.setIcon(getAlertingIcon()); + } channelPref.setIconSize(MasterSwitchPreference.ICON_SIZE_SMALL); channelPref.setKey(channel.getId()); channelPref.setTitle(channel.getName()); @@ -314,9 +323,10 @@ abstract public class NotificationSettingsBase extends DashboardFragment { channel.lockFields( NotificationChannel.USER_LOCKED_IMPORTANCE); MasterSwitchPreference channelPref1 = (MasterSwitchPreference) preference; - channelPref1.setIcon(channel.getImportance() > IMPORTANCE_LOW - ? R.drawable.ic_notification_alert - : R.drawable.ic_notification_silence); + channelPref1.setIcon(null); + if (channel.getImportance() > IMPORTANCE_LOW) { + channelPref1.setIcon(getAlertingIcon()); + } toggleBehaviorIconState(channelPref1.getIcon(), importance != IMPORTANCE_NONE); mBackend.updateChannel(mPkg, mUid, channel); @@ -330,9 +340,14 @@ abstract public class NotificationSettingsBase extends DashboardFragment { } private void toggleBehaviorIconState(Drawable icon, boolean enabled) { + if (icon == null) return; + LayerDrawable layerDrawable = (LayerDrawable) icon; GradientDrawable background = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id.back); + + if (background == null) return; + if (enabled) { background.clearColorFilter(); } else { diff --git a/src/com/android/settings/slices/SliceBuilderUtils.java b/src/com/android/settings/slices/SliceBuilderUtils.java index cf45d57381d..0e510325f8b 100644 --- a/src/com/android/settings/slices/SliceBuilderUtils.java +++ b/src/com/android/settings/slices/SliceBuilderUtils.java @@ -300,6 +300,10 @@ public class SliceBuilderUtils { private static Slice buildSliderSlice(Context context, SliceData sliceData, BasePreferenceController controller) { final SliderPreferenceController sliderController = (SliderPreferenceController) controller; + if (sliderController.getMax() <= sliderController.getMin()) { + Log.e(TAG, "Invalid sliderController: " + sliderController.getPreferenceKey()); + return null; + } final PendingIntent actionIntent = getSliderAction(context, sliceData); final PendingIntent contentIntent = getContentPendingIntent(context, sliceData); final IconCompat icon = getSafeIcon(context, sliceData); diff --git a/src/com/android/settings/widget/VideoPreference.java b/src/com/android/settings/widget/VideoPreference.java index ca3e5ccb317..1af9065dbc6 100644 --- a/src/com/android/settings/widget/VideoPreference.java +++ b/src/com/android/settings/widget/VideoPreference.java @@ -24,10 +24,12 @@ import android.media.MediaPlayer; import android.net.Uri; import android.util.AttributeSet; import android.util.Log; +import android.util.TypedValue; import android.view.Surface; import android.view.TextureView; import android.view.View; import android.widget.ImageView; +import android.widget.LinearLayout; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; @@ -51,11 +53,12 @@ public class VideoPreference extends Preference { @VisibleForTesting boolean mVideoReady; private boolean mVideoPaused; - private float mAspectRadio = 1.0f; + private float mAspectRatio = 1.0f; private int mPreviewResource; private boolean mViewVisible; private Surface mSurface; private int mAnimationId; + private int mHeight = LinearLayout.LayoutParams.MATCH_PARENT - 1; // video height in pixels public VideoPreference(Context context) { super(context); @@ -121,7 +124,11 @@ public class VideoPreference extends Preference { R.id.video_container); imageView.setImageResource(mPreviewResource); - layout.setAspectRatio(mAspectRadio); + layout.setAspectRatio(mAspectRatio); + if (mHeight >= LinearLayout.LayoutParams.MATCH_PARENT) { + layout.setLayoutParams(new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, mHeight)); + } updateViewStates(imageView, playButton); video.setOnClickListener(v -> updateViewStates(imageView, playButton)); @@ -247,8 +254,17 @@ public class VideoPreference extends Preference { return mVideoPaused; } + /** + * sets the height of the video preference + * @param height in dp + */ + public void setHeight(float height) { + mHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, height, + mContext.getResources().getDisplayMetrics()); + } + @VisibleForTesting void updateAspectRatio() { - mAspectRadio = mMediaPlayer.getVideoWidth() / (float) mMediaPlayer.getVideoHeight(); + mAspectRatio = mMediaPlayer.getVideoWidth() / (float) mMediaPlayer.getVideoHeight(); } } diff --git a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java index 5f3cbb28dcc..5e49b2e7498 100644 --- a/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java +++ b/src/com/android/settings/wifi/details/WifiDetailPreferenceController.java @@ -54,7 +54,6 @@ import android.widget.Toast; import androidx.annotation.VisibleForTesting; import androidx.core.text.BidiFormatter; -import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.PreferenceFragmentCompat; @@ -151,7 +150,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController private AccessPoint mAccessPoint; private final ConnectivityManager mConnectivityManager; - private final Fragment mFragment; + private final PreferenceFragmentCompat mFragment; private final Handler mHandler; private LinkProperties mLinkProperties; private Network mNetwork; @@ -296,7 +295,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController AccessPoint accessPoint, ConnectivityManager connectivityManager, Context context, - Fragment fragment, + PreferenceFragmentCompat fragment, Handler handler, Lifecycle lifecycle, WifiManager wifiManager, @@ -311,7 +310,7 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController AccessPoint accessPoint, ConnectivityManager connectivityManager, Context context, - Fragment fragment, + PreferenceFragmentCompat fragment, Handler handler, Lifecycle lifecycle, WifiManager wifiManager, @@ -441,9 +440,11 @@ public class WifiDetailPreferenceController extends AbstractPreferenceController if (usingDataUsageHeader(mContext)) { mSummaryHeaderController.updateState(mDataUsageSummaryPref); } else { - mEntityHeaderController.setSummary( - mAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/)) - .done(mFragment.getActivity(), true /* rebind */); + mEntityHeaderController + .setSummary( + mAccessPoint.getSettingsSummary(true /*convertSavedAsDisconnected*/)) + .setRecyclerView(mFragment.getListView(), mLifecycle) + .done(mFragment.getActivity(), true /* rebind */); } } diff --git a/src/com/android/settings/wifi/qrcode/QrCamera.java b/src/com/android/settings/wifi/qrcode/QrCamera.java index 6088fa597ac..c6825879558 100644 --- a/src/com/android/settings/wifi/qrcode/QrCamera.java +++ b/src/com/android/settings/wifi/qrcode/QrCamera.java @@ -62,7 +62,14 @@ public class QrCamera extends Handler { private static final int MSG_AUTO_FOCUS = 1; - private static double MIN_RATIO_DIFF_PERCENT = 0.1; + /** + * The max allowed difference between picture size ratio and preview size ratio. + * Uses to filter the picture sizes of similar preview size ratio, for example, if a preview + * size is 1920x1440, MAX_RATIO_DIFF 0.1 could allow picture size of 720x480 or 352x288 or + * 176x44 but not 1920x1080. + */ + private static double MAX_RATIO_DIFF = 0.1; + private static long AUTOFOCUS_INTERVAL_MS = 1500L; private static Map> HINTS = new ArrayMap<>(); @@ -168,7 +175,8 @@ public class QrCamera extends Handler { mParameters = mCamera.getParameters(); mPreviewSize = getBestPreviewSize(mParameters); mParameters.setPreviewSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); - mParameters.setPictureSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); + Size pictureSize = getBestPictureSize(mParameters); + mParameters.setPreviewSize(pictureSize.getWidth(), pictureSize.getHeight()); if (mParameters.getSupportedFlashModes().contains(Parameters.FLASH_MODE_OFF)) { mParameters.setFlashMode(Parameters.FLASH_MODE_OFF); @@ -338,8 +346,8 @@ public class QrCamera extends Handler { private QrYuvLuminanceSource getFrameImage(byte[] imageData) { final Rect frame = mScannerCallback.getFramePosition(mPreviewSize, mCameraOrientation); - final Camera.Size size = mParameters.getPictureSize(); - QrYuvLuminanceSource image = new QrYuvLuminanceSource(imageData, size.width, size.height); + final QrYuvLuminanceSource image = new QrYuvLuminanceSource(imageData, + mPreviewSize.getWidth(), mPreviewSize.getHeight()); return (QrYuvLuminanceSource) image.crop(frame.left, frame.top, frame.width(), frame.height()); } @@ -379,6 +387,48 @@ public class QrCamera extends Handler { return bestChoice; } + /** Get best picture size from the list of camera supported picture sizes. Compares the + * picture size and aspect ratio to choose the best one. */ + private Size getBestPictureSize(Camera.Parameters parameters) { + final Camera.Size previewSize = parameters.getPreviewSize(); + final double previewRatio = getRatio(previewSize.width, previewSize.height); + List bestChoices = new ArrayList<>(); + final List similarChoices = new ArrayList<>(); + + // Filter by ratio + for (Camera.Size size : parameters.getSupportedPictureSizes()) { + double ratio = getRatio(size.width, size.height); + if (ratio == previewRatio) { + bestChoices.add(new Size(size.width, size.height)); + } else if (Math.abs(ratio - previewRatio) < MAX_RATIO_DIFF) { + similarChoices.add(new Size(size.width, size.height)); + } + } + + if (bestChoices.size() == 0 && similarChoices.size() == 0) { + Log.d(TAG, "No proper picture size, return default picture size"); + Camera.Size defaultPictureSize = parameters.getPictureSize(); + return new Size(defaultPictureSize.width, defaultPictureSize.height); + } + + if (bestChoices.size() == 0) { + bestChoices = similarChoices; + } + + // Get the best by area + int bestAreaDifference = Integer.MAX_VALUE; + Size bestChoice = null; + final int previewArea = previewSize.width * previewSize.height; + for (Size size : bestChoices) { + int areaDifference = Math.abs(size.getWidth() * size.getHeight() - previewArea); + if (areaDifference < bestAreaDifference) { + bestAreaDifference = areaDifference; + bestChoice = size; + } + } + return bestChoice; + } + private double getRatio(double x, double y) { return (x < y) ? x / y : y / x; } diff --git a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java b/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java index 08fcb10d0b5..d9682d2421c 100644 --- a/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java +++ b/src/com/android/settings/wifi/qrcode/QrCodeGenerator.java @@ -20,10 +20,16 @@ import android.graphics.Bitmap; import android.graphics.Color; import com.google.zxing.BarcodeFormat; +import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; +import java.nio.charset.CharsetEncoder; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + public final class QrCodeGenerator { /** * Generates a barcode image with {@code contents}. @@ -34,8 +40,13 @@ public final class QrCodeGenerator { */ public static Bitmap encodeQrCode(String contents, int size) throws WriterException, IllegalArgumentException { + final Map hints = new HashMap<>(); + if (!isIso88591(contents)) { + hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name()); + } + final BitMatrix qrBits = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, - size, size); + size, size, hints); final Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565); for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { @@ -44,4 +55,9 @@ public final class QrCodeGenerator { } return bitmap; } + + private static boolean isIso88591(String contents) { + CharsetEncoder encoder = StandardCharsets.ISO_8859_1.newEncoder(); + return encoder.canEncode(contents); + } } diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java index 43bdc30b2f9..5813bd8db5f 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java @@ -25,12 +25,14 @@ import android.app.UiModeManager; import android.content.ContentResolver; import android.content.Context; import android.os.Vibrator; +import android.provider.DeviceConfig; import android.provider.Settings; import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.testutils.XmlTestUtils; +import com.android.settings.testutils.shadow.ShadowDeviceConfig; import org.junit.Before; import org.junit.Test; @@ -38,6 +40,7 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; import java.util.List; @@ -135,6 +138,32 @@ public class AccessibilitySettingsTest { } } + @Test + @Config(shadows = {ShadowDeviceConfig.class}) + public void testIsRampingRingerEnabled_bothFlagsOn_Enabled() { + Settings.Global.putInt( + mContext.getContentResolver(), Settings.Global.APPLY_RAMPING_RINGER, 1 /* ON */); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY, + AccessibilitySettings.RAMPING_RINGER_ENABLED, "true", false /* makeDefault*/); + assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isTrue(); + } + + @Test + @Config(shadows = {ShadowDeviceConfig.class}) + public void testIsRampingRingerEnabled_settingsFlagOff_Disabled() { + Settings.Global.putInt( + mContext.getContentResolver(), Settings.Global.APPLY_RAMPING_RINGER, 0 /* OFF */); + assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isFalse(); + } + + @Test + @Config(shadows = {ShadowDeviceConfig.class}) + public void testIsRampingRingerEnabled_deviceConfigFlagOff_Disabled() { + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY, + AccessibilitySettings.RAMPING_RINGER_ENABLED, "false", false /* makeDefault*/); + assertThat(AccessibilitySettings.isRampingRingerEnabled(mContext)).isFalse(); + } + private void verifyAccessibilityTimeoutSummary(String preferenceKey, int resId) { final Preference preference = new Preference(mContext); doReturn(preference).when(mSettings).findPreference(preferenceKey); diff --git a/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java new file mode 100644 index 00000000000..d23d2f03666 --- /dev/null +++ b/tests/robotests/src/com/android/settings/accessibility/RingVibrationPreferenceFragmentTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019 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.accessibility; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.provider.DeviceConfig; +import android.provider.Settings; + +import com.android.settings.testutils.shadow.ShadowDeviceConfig; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +public class RingVibrationPreferenceFragmentTest { + + private Context mContext; + private RingVibrationPreferenceFragment mFragment; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + mFragment = spy(new RingVibrationPreferenceFragment()); + doReturn(mContext).when(mFragment).getContext(); + } + + @Test + @Config(shadows = {ShadowDeviceConfig.class}) + public void getVibrationEnabledSetting_rampingRingerEnabled_returnApplyRampingRinger() { + // Turn on both flags to enable ramping ringer. + Settings.Global.putInt( + mContext.getContentResolver(), Settings.Global.APPLY_RAMPING_RINGER, 1 /* ON */); + DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY, + AccessibilitySettings.RAMPING_RINGER_ENABLED, "true", false /* makeDefault*/); + assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo( + Settings.Global.APPLY_RAMPING_RINGER); + } + + @Test + public void getVibrationEnabledSetting_rampingRingerDisabled_returnVibrationWhenRinging() { + // Turn off Settings.Global.APPLY_RAMPING_RINGER to disable ramping ringer. + Settings.Global.putInt( + mContext.getContentResolver(), Settings.Global.APPLY_RAMPING_RINGER, 0 /* OFF */); + assertThat(mFragment.getVibrationEnabledSetting()).isEqualTo( + Settings.System.VIBRATE_WHEN_RINGING); + } +} diff --git a/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java index afe08489503..81658628897 100644 --- a/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/AllowBackgroundActivityStartsPreferenceControllerTest.java @@ -115,7 +115,7 @@ public class AllowBackgroundActivityStartsPreferenceControllerTest { public void onDeveloperOptionsSwitchDisabled_noDefault_shouldResetPreference() { mController.onDeveloperOptionsSwitchDisabled(); - verify(mPreference).setChecked(true); + verify(mPreference).setChecked(false); verify(mPreference).setEnabled(false); assertThat(getModeFroMSettings()).isEqualTo(-1); diff --git a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java index 023135d4d7f..3e6e4360f37 100644 --- a/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/deviceinfo/PhoneNumberPreferenceControllerTest.java @@ -149,6 +149,16 @@ public class PhoneNumberPreferenceControllerTest { assertThat(primaryNumber).isEqualTo(mContext.getString(R.string.device_info_default)); } + @Test + public void getSummary_getEmptySubscriptionInfo_shouldShowUnknown() { + List infos = new ArrayList<>(); + when(mSubscriptionManager.getActiveSubscriptionInfoList(eq(true))).thenReturn(infos); + + CharSequence primaryNumber = mController.getSummary(); + + assertThat(primaryNumber).isEqualTo(mContext.getString(R.string.device_info_default)); + } + @Test public void isSliceable_shouldBeTrue() { assertThat(mController.isSliceable()).isTrue(); diff --git a/tests/robotests/src/com/android/settings/display/AdaptiveSleepDetailPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AdaptiveSleepDetailPreferenceControllerTest.java new file mode 100644 index 00000000000..91a4ed6379b --- /dev/null +++ b/tests/robotests/src/com/android/settings/display/AdaptiveSleepDetailPreferenceControllerTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2019 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.UNSUPPORTED_ON_DEVICE; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; + +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.internal.R; +import com.android.settings.testutils.shadow.SettingsShadowResources; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(RobolectricTestRunner.class) +@Config(shadows = {SettingsShadowResources.class}) +public class AdaptiveSleepDetailPreferenceControllerTest { + + private AdaptiveSleepDetailPreferenceController mController; + @Mock + private PackageManager mPackageManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + Context context = Mockito.spy(RuntimeEnvironment.application); + doReturn(mPackageManager).when(context).getPackageManager(); + mController = new AdaptiveSleepDetailPreferenceController(context, "test_key"); + } + + @Test + public void isSliceable_returnTrue() { + mController.onPreferenceChange(null, true); + assertThat(mController.isSliceable()).isTrue(); + } + + @Test + public void getAvailabilityStatus_configTrueSet_shouldReturnAvailable() { + SettingsShadowResources.overrideResource(R.bool.config_adaptive_sleep_available, true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test + public void getAvailabilityStatus_configFalseSet_shouldReturnUnsupportedOnDevice() { + SettingsShadowResources.overrideResource(R.bool.config_adaptive_sleep_available, false); + assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); + } +} diff --git a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java index 295eac5b71f..9928e6c30d8 100644 --- a/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/display/AdaptiveSleepPreferenceControllerTest.java @@ -133,10 +133,10 @@ public class AdaptiveSleepPreferenceControllerTest { } @Test - public void isSliceable_returnsTrue() { + public void isSliceable_returnsFalse() { final AdaptiveSleepPreferenceController controller = new AdaptiveSleepPreferenceController(mContext, "any_key"); - assertThat(controller.isSliceable()).isTrue(); + assertThat(controller.isSliceable()).isFalse(); } @Test diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java index 61599e68ee7..2bfaecac538 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java @@ -219,4 +219,86 @@ public class MobileNetworkUtilsTest { assertThat(MobileNetworkUtils.shouldDisplayNetworkSelectOptions(mContext, SUB_ID_1)) .isTrue(); } + + @Test + public void shouldSpeciallyUpdateGsmCdma_notWorldMode_returnFalse() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isFalse(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_supportTdscdma_returnFalse() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, true); + + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isFalse(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteTdscdmaGsm_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteTdscdmaGsmWcdma_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteTdscdma_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_TDSCDMA); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteTdscdmaWcdma_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_WCDMA); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteTdscdmaCdmaEvdoGsmWcdma_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } + + @Test + public void shouldSpeciallyUpdateGsmCdma_ModeLteCdmaEvdoGsmWcdma_returnTrue() { + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_MODE_ENABLED_BOOL, true); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_SUPPORT_TDSCDMA_BOOL, false); + + Settings.Global.putInt(mContext.getContentResolver(), + android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, + TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA); + assertThat(MobileNetworkUtils.shouldSpeciallyUpdateGsmCdma(mContext, SUB_ID_1)).isTrue(); + } } diff --git a/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java index 67324e95845..aafefb51823 100644 --- a/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/BubblePreferenceControllerTest.java @@ -78,6 +78,7 @@ public class BubblePreferenceControllerTest { private FragmentManager mFragmentManager; private BubblePreferenceController mController; + private BubblePreferenceController mAppPageController; @Before public void setUp() { @@ -87,7 +88,10 @@ public class BubblePreferenceControllerTest { shadowApplication.setSystemService(Context.USER_SERVICE, mUm); mContext = RuntimeEnvironment.application; when(mFragmentManager.beginTransaction()).thenReturn(mock(FragmentTransaction.class)); - mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend)); + mController = spy(new BubblePreferenceController(mContext, mFragmentManager, mBackend, + false /* isAppPage */)); + mAppPageController = spy(new BubblePreferenceController(mContext, mFragmentManager, + mBackend, true /* isAppPage */)); } @Test @@ -150,6 +154,16 @@ public class BubblePreferenceControllerTest { assertFalse(mController.isAvailable()); } + @Test + public void testIsAvailable_app_evenIfOffGlobally() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + mAppPageController.onResume(appRow, null, null, null); + Settings.Secure.putInt(mContext.getContentResolver(), + NOTIFICATION_BUBBLES, SYSTEM_WIDE_OFF); + + assertTrue(mAppPageController.isAvailable()); + } + @Test public void testIsAvailable_app() { NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); diff --git a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java index b4379aadc44..75b369a6e2b 100644 --- a/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java +++ b/tests/robotests/src/com/android/settings/notification/ImportancePreferenceTest.java @@ -32,6 +32,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -143,84 +144,44 @@ public class ImportancePreferenceTest { } @Test - public void setImportanceSummary_status() { - ViewGroup parent = new LinearLayout(mContext); - TextView tv = new TextView(mContext); - tv.setId(R.id.silence_summary); - parent.addView(tv); - TextView other = new TextView(mContext); - other.setId(R.id.alert_summary); - parent.addView(other); - + public void setImportanceSummary() { final ImportancePreference preference = spy(new ImportancePreference(mContext)); + final LayoutInflater inflater = LayoutInflater.from(mContext); + final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests( + inflater.inflate(R.layout.notif_importance_preference, null)); - preference.setDisplayInStatusBar(true); - preference.setDisplayOnLockscreen(false); + preference.setConfigurable(true); + preference.setImportance(IMPORTANCE_DEFAULT); + preference.onBindViewHolder(holder); - preference.setImportanceSummary(parent, IMPORTANCE_LOW, true); - - assertThat(tv.getText()).isEqualTo( - mContext.getString(R.string.notification_channel_summary_low_status)); - } - - @Test - public void setImportanceSummary_lock() { - ViewGroup parent = new LinearLayout(mContext); - TextView tv = new TextView(mContext); - tv.setId(R.id.silence_summary); - parent.addView(tv); - TextView other = new TextView(mContext); - other.setId(R.id.alert_summary); - parent.addView(other); - - final ImportancePreference preference = spy(new ImportancePreference(mContext)); - - preference.setDisplayInStatusBar(false); - preference.setDisplayOnLockscreen(true); - - preference.setImportanceSummary(parent, IMPORTANCE_LOW, true); - - assertThat(tv.getText()).isEqualTo( - mContext.getString(R.string.notification_channel_summary_low_lock)); - } - - @Test - public void setImportanceSummary_statusLock() { - ViewGroup parent = new LinearLayout(mContext); - TextView tv = new TextView(mContext); - tv.setId(R.id.silence_summary); - parent.addView(tv); - TextView other = new TextView(mContext); - other.setId(R.id.alert_summary); - parent.addView(other); - - final ImportancePreference preference = spy(new ImportancePreference(mContext)); + TextView tv = holder.itemView.findViewById(R.id.silence_summary); preference.setDisplayInStatusBar(true); preference.setDisplayOnLockscreen(true); - preference.setImportanceSummary(parent, IMPORTANCE_LOW, true); + preference.setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_LOW, true); assertThat(tv.getText()).isEqualTo( - mContext.getString(R.string.notification_channel_summary_low_status_lock)); + mContext.getString(R.string.notification_channel_summary_low)); } @Test - public void setImportanceSummary_statusLock_default() { - ViewGroup parent = new LinearLayout(mContext); - TextView tv = new TextView(mContext); - tv.setId(R.id.alert_summary); - parent.addView(tv); - TextView other = new TextView(mContext); - other.setId(R.id.silence_summary); - parent.addView(other); - + public void setImportanceSummary_default() { final ImportancePreference preference = spy(new ImportancePreference(mContext)); + final LayoutInflater inflater = LayoutInflater.from(mContext); + final PreferenceViewHolder holder = PreferenceViewHolder.createInstanceForTests( + inflater.inflate(R.layout.notif_importance_preference, null)); + + preference.setConfigurable(true); + preference.setImportance(IMPORTANCE_DEFAULT); + preference.onBindViewHolder(holder); + + TextView tv = holder.itemView.findViewById(R.id.alert_summary); preference.setDisplayInStatusBar(true); preference.setDisplayOnLockscreen(true); - preference.setImportanceSummary(parent, IMPORTANCE_DEFAULT, true); + preference.setImportanceSummary((ViewGroup) holder.itemView, IMPORTANCE_DEFAULT, true); assertThat(tv.getText()).isEqualTo( mContext.getString(R.string.notification_channel_summary_default)); diff --git a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java index 2e47930b73c..1db7c8df729 100644 --- a/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java +++ b/tests/robotests/src/com/android/settings/slices/SliceBuilderUtilsTest.java @@ -43,6 +43,7 @@ import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settings.testutils.FakeCopyableController; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.FakeInvalidSliderController; import com.android.settings.testutils.FakeSliderController; import com.android.settings.testutils.FakeToggleController; import com.android.settings.testutils.FakeUnavailablePreferenceController; @@ -67,6 +68,7 @@ public class SliceBuilderUtilsTest { private final Uri URI = Uri.parse("content://com.android.settings.slices/test"); private final Class TOGGLE_CONTROLLER = FakeToggleController.class; private final Class SLIDER_CONTROLLER = FakeSliderController.class; + private final Class INVALID_SLIDER_CONTROLLER = FakeInvalidSliderController.class; private final Class COPYABLE_CONTROLLER = FakeCopyableController.class; private final Class CONTEXT_CONTROLLER = FakeContextOnlyPreferenceController.class; @@ -470,6 +472,14 @@ public class SliceBuilderUtilsTest { assertThat(actualIconResource).isEqualTo(expectedIconResource); } + @Test + public void buildSliderSlice_invalidSlider_returnNull() { + final SliceData data = getDummyData(INVALID_SLIDER_CONTROLLER, SliceData.SliceType.SLIDER, + 0x0 /* icon */); + + assertThat(SliceBuilderUtils.buildSlice(mContext, data)).isNull(); + } + @Test public void getSafeIcon_replacesEmptyIconWithSettingsIcon() { final int settingsIcon = R.drawable.ic_settings_accent; diff --git a/tests/robotests/src/com/android/settings/testutils/FakeInvalidSliderController.java b/tests/robotests/src/com/android/settings/testutils/FakeInvalidSliderController.java new file mode 100644 index 00000000000..cb49f65d632 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/FakeInvalidSliderController.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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.testutils; + +import android.content.Context; + +public class FakeInvalidSliderController extends FakeSliderController { + + public FakeInvalidSliderController(Context context, String key) { + super(context, key); + } + + @Override + public int getMax() { + // Return 0 to make it invalid + return 0; + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java index bd2ce1e56cf..3f67137717d 100644 --- a/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java +++ b/tests/robotests/src/com/android/settings/wifi/qrcode/QrCameraTest.java @@ -128,4 +128,23 @@ public class QrCameraTest { assertThat(mQrCode).isEqualTo(googleUrl); } + + @Test + public void testDecode_unicodePictureCaptured_QrCodeCorrectValue() { + final String unicodeTest = "中文測試"; + + try { + final Bitmap bmp = QrCodeGenerator.encodeQrCode(unicodeTest, 320); + final int[] intArray = new int[bmp.getWidth() * bmp.getHeight()]; + bmp.getPixels(intArray, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), bmp.getHeight()); + LuminanceSource source = new RGBLuminanceSource(bmp.getWidth(), bmp.getHeight(), + intArray); + final BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); + mCamera.decodeImage(bitmap); + bmp.recycle(); + } catch (WriterException e) { + } + + assertThat(mQrCode).isEqualTo(unicodeTest); + } }