Snap for 7519874 from 83e4f3c658 to sc-release

Change-Id: Iad140400c1bd5bf56accd17b5f057e2ce6ed10ea
This commit is contained in:
Android Build Coastguard Worker
2021-07-03 03:11:11 +00:00
54 changed files with 656 additions and 317 deletions

View File

@@ -1486,6 +1486,7 @@
</activity>
<activity android:name=".security.RequestManageCredentials"
android:theme="@style/Theme.SubSettings"
android:exported="true">
<intent-filter>
<action android:name="android.security.MANAGE_CREDENTIALS"/>
@@ -1910,7 +1911,6 @@
</activity>
<activity android:name=".password.SetupChooseLockGeneric$InternalActivity"
android:theme="@style/GlifTheme.Light"
android:exported="false"
android:excludeFromRecents="true" />

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<shape>
</shape>

View File

@@ -0,0 +1,25 @@
<!--
~ Copyright (C) 2021 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M6,13.5C6,11.57 7.75,10 9.9,10h6.27l-2.59,2.59L15,14l5,-5 -5,-5 -1.41,1.41L16.17,8H9.9C6.65,8 4,10.47 4,13.5S6.65,19 9.9,19H17v-2H9.9C7.75,17 6,15.43 6,13.5z"/>
</vector>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<shape>
</shape>

View File

@@ -123,11 +123,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/request_manage_credentials_more"
android:textColor="?android:attr/colorBackground"
android:theme="@style/Theme.CollapsingToolbar.Settings"
app:backgroundTint="?android:attr/colorAccent"
app:elevation="3dp"
app:icon="@drawable/ic_arrow_downward"
app:iconTint="?android:attr/textColorPrimary"
app:iconTint="?android:attr/colorBackground"
app:layout_anchor="@id/apps_list"
app:layout_anchorGravity="bottom|center" />

View File

@@ -97,11 +97,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/request_manage_credentials_more"
android:textColor="?android:attr/colorBackground"
android:theme="@style/Theme.CollapsingToolbar.Settings"
app:backgroundTint="?android:attr/colorAccent"
app:elevation="3dp"
app:icon="@drawable/ic_arrow_downward"
app:iconTint="?android:attr/textColorPrimary"
app:iconTint="?android:attr/colorBackground"
app:layout_anchor="@id/apps_list"
app:layout_anchorGravity="bottom|center" />

View File

@@ -67,11 +67,12 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/request_manage_credentials_more"
android:textColor="?android:attr/colorBackground"
app:layout_anchor="@id/apps_list"
app:layout_anchorGravity="bottom|center"
app:elevation="3dp"
app:icon="@drawable/ic_arrow_downward"
app:iconTint="?android:attr/textColorPrimary"
app:iconTint="?android:attr/colorBackground"
app:backgroundTint="?android:attr/colorAccent"
android:theme="@style/Theme.CollapsingToolbar.Settings"/>

View File

@@ -49,5 +49,8 @@
<color name="biometric_enroll_intro_color_icon">#669df6</color>
<color name="biometric_enroll_intro_color_outline">#5e5e5e</color>
<color name="fingerprint_enrollment_finish_color_outline">#669df6</color>
<!-- Material inverse ripple color, useful for inverted backgrounds. -->
<color name="ripple_material_inverse">@*android:color/ripple_material_light</color>
</resources>

View File

@@ -207,4 +207,7 @@
<!-- Fingerprint enrollment color -->
<color name="fingerprint_enrollment_finish_color_outline">#1A73E8</color>
<!-- Material inverse ripple color, useful for inverted backgrounds. -->
<color name="ripple_material_inverse">@*android:color/ripple_material_dark</color>
</resources>

View File

@@ -6865,7 +6865,11 @@
<!-- Label for button to uninstall all certificates installed by the credential management app [CHAR LIMIT=30] -->
<string name="uninstall_certs_credential_management_app">Uninstall certificates</string>
<!-- Label for button to remove the credential management app [CHAR LIMIT=30] -->
<string name="remove_credential_management_app">Remove</string>
<string name="remove_credential_management_app">Remove app</string>
<!-- Dialog title for button to remove the credential management app [CHAR LIMIT=30] -->
<string name="remove_credential_management_app_dialog_title">Remove this app?</string>
<!-- Dialog message for button to remove the credential management app [CHAR LIMIT=NONE] -->
<string name="remove_credential_management_app_dialog_message">This app won\u2019t manage certificates, but it will stay on your device. Any certificates installed by the app will be uninstalled.</string>
<!-- List item found in the credential management app's authentication policy [CHAR LIMIT=NONE] -->
<plurals name="number_of_urls">
<item quantity="one"><xliff:g id="number">%d</xliff:g> URL</item>
@@ -7487,7 +7491,7 @@
<!-- Button label for enabling a system CA certificate. -->
<string name="trusted_credentials_enable_label">Enable</string>
<!-- Button label for removing a user CA certificate. -->
<string name="trusted_credentials_remove_label">Remove</string>
<string name="trusted_credentials_remove_label">Uninstall</string>
<!-- Button label for trusting a user CA certificate. -->
<string name="trusted_credentials_trust_label">Trust</string>
<!-- Alert dialog confirmation when enabling a system CA certificate. -->
@@ -10030,6 +10034,10 @@
<string name="switch_on_text">On</string>
<string name="switch_off_text">Off</string>
<!-- Switch text for nfc feature being on [CHAR LIMIT=NONE] -->
<string name="nfc_setting_on">On</string>
<!-- Switch text for nfc feature being off [CHAR LIMIT=NONE] -->
<string name="nfc_setting_off">Off</string>
<!-- The subtext when screen pinning feature is enabled. [CHAR LIMIT=28] -->
<string name="screen_pinning_switch_on_text">On</string>
@@ -11590,9 +11598,9 @@
<!-- [CHAR LIMIT=60] Title of work profile setting page -->
<string name="managed_profile_settings_title">Work profile settings</string>
<!-- [CHAR LIMIT=NONE] Settings toggle. This setting lets a user's personal apps identify contacts using the user's work directory. -->
<string name="managed_profile_contact_search_title">Let personal apps identify contacts using work directory</string>
<string name="managed_profile_contact_search_title">Search for work directory contacts in personal apps</string>
<!-- [CHAR LIMIT=NONE] Settings toggle description. This setting lets a user's personal apps identify contacts using the user's work directory. "Searches" is a noun. -->
<string name="managed_profile_contact_search_summary">Searches and incoming calls may be visible to your IT admin</string>
<string name="managed_profile_contact_search_summary">Your searches and incoming calls may be visible to your IT admin</string>
<!-- [CHAR LIMIT=NONE] Settings label. This setting lets the user show their work events on their personal calendar. The adjective 'Cross-profile' is referring to the work and personal profiles a user has on their phone. -->
<string name="cross_profile_calendar_title">Cross-profile calendar</string>
<!-- [CHAR LIMIT=NONE] Setting description. If the user turns on this setting, they can see their work events on their personal calendar. -->
@@ -11763,7 +11771,7 @@
<!-- One-handed mode show notification action [CHAR_LIMIT=60] -->
<string name="one_handed_action_show_notification_title">Show notifications</string>
<!-- One-handed mode show notification action [CHAR_LIMIT=NONE] -->
<string name="one_handed_action_show_notification_summary">Notification and settings will appear.</string>
<string name="one_handed_action_show_notification_summary">Notifications and settings will appear.</string>
<!-- One-handed mode Intro text for gesture navigation [CHAR_LIMIT=NONE] -->
<!-- Summary text for ambient display double tap [CHAR LIMIT=NONE]-->
@@ -12144,6 +12152,9 @@
<item quantity="one"><xliff:g id="count">%1$d</xliff:g> password</item>
<item quantity="other"><xliff:g id="count">%1$d</xliff:g> passwords</item>
</plurals>
<!-- DO NOT TRANSLATE Summary placeholder for when the passwords count is still loading or is
unavailable. -->
<string name="autofill_passwords_count_placeholder" translatable="false">\u2014</string>
<!-- Keywords for the auto-fill feature. [CHAR LIMIT=NONE] -->
<string name="autofill_keywords">auto, fill, autofill, password</string>
@@ -12445,6 +12456,8 @@
<string name="prevent_ringing_option_vibrate_summary">Vibrate</string>
<!-- Summary for prevent ringing setting -->
<string name="prevent_ringing_option_mute_summary">Mute</string>
<!-- Summary for prevent ringing setting when the option itself is unavailable. [CHAR LIMIT=NONE] -->
<string name="prevent_ringing_option_unavailable_lpp_summary">To enable, first change \"Press and hold power button\" to the power menu.</string>
<!-- Title for detail page of wifi network [CHAR LIMIT=30] -->
<string name="pref_title_network_details">Network details</string>

View File

@@ -422,13 +422,15 @@
<style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored">
<item name="android:theme">@style/RoundedCornerThemeOverlay</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamilyMedium</item>
</style>
<style name="ActionSecondaryButton" parent="android:Widget.DeviceDefault.Button"/>
<style name="RoundedCornerThemeOverlay">
<item name="android:buttonCornerRadius">24dp</item>
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:paddingHorizontal">16dp</item>
<item name="android:colorControlHighlight">@color/ripple_material_inverse</item>
</style>
<style name="LockPatternContainerStyle">
@@ -468,13 +470,16 @@
<style name="device_info_dialog_label">
<item name="android:textAlignment">viewStart</item>
<item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body1</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
<style name="device_info_dialog_value">
<item name="android:textAlignment">viewStart</item>
<item name="android:textAppearance">@*android:style/TextAppearance.DeviceDefault.Body2</item>
<item name="android:fontFamily">@*android:string/config_bodyFontFamily</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:paddingBottom">24dp</item>
</style>
@@ -821,21 +826,18 @@
<item name="android:fontFamily">google-sans-medium</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="RequestManageCredentialsDontAllowButton"
parent="@style/Widget.AppCompat.Button.Borderless">
parent="@style/Widget.AppCompat.Button.Borderless.Colored">
<item name="android:fontFamily">google-sans-medium</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
</style>
<style name="RequestManageCredentialsFab">
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:layout_marginBottom">12dp</item>
</style>

View File

@@ -37,6 +37,7 @@
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_main"
android:title="@string/autofill_app"
settings:keywords="@string/autofill_keywords">
<extra
android:name="for_work"

View File

@@ -38,6 +38,7 @@
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_main"
android:title="@string/autofill_app"
settings:keywords="@string/autofill_keywords">
<extra
android:name="for_work"

View File

@@ -28,6 +28,7 @@
android:persistent="false"
android:title="@string/autofill_passwords"
settings:controller="com.android.settings.applications.autofill.PasswordsPreferenceController"
settings:forWork="true"
settings:keywords="@string/autofill_keywords" />
<com.android.settings.widget.WorkOnlyCategory
@@ -38,6 +39,7 @@
<com.android.settings.widget.GearPreference
android:fragment="com.android.settings.applications.defaultapps.DefaultAutofillPicker"
android:key="default_autofill_work"
android:title="@string/autofill_app"
settings:searchable="false">
<extra
android:name="for_work"

View File

@@ -20,12 +20,10 @@
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:title="@string/auto_brightness_title">
<com.android.settings.widget.VideoPreference
<com.android.settingslib.widget.IllustrationPreference
android:key="auto_brightness_video"
android:title="@string/summary_placeholder"
settings:animation="@raw/aab_brightness"
settings:preview="@drawable/aab_brightness"
settings:controller="com.android.settings.widget.VideoPreferenceController"/>
settings:searchable="false"
settings:lottie_rawRes="@raw/lottie_adaptive_brightness"/>
<com.android.settings.widget.SettingsMainSwitchPreference
android:key="auto_brightness"

View File

@@ -65,13 +65,6 @@
android:icon="@drawable/ic_folder_vd_theme_24"
android:title="@string/bluetooth_show_files_received_via_bluetooth"/>
<SwitchPreference
android:key="uwb_settings"
android:title="@string/uwb_settings_title"
android:order="100"
android:summary="@string/summary_placeholder"
settings:controller="com.android.settings.uwb.UwbPreferenceController"/>
<PreferenceCategory
android:key="dashboard_tile_placeholder"
android:order="-8"/>

View File

@@ -24,7 +24,7 @@
<com.android.settingslib.widget.IllustrationPreference
android:key="gesture_double_tap_power_video"
settings:searchable="false"
app:lottie_rawRes="@raw/lottie_quick_open_camera"/>
app:lottie_rawRes="@drawable/quickly_open_camera"/>
<SwitchPreference
android:key="gesture_double_tap_power"

View File

@@ -24,7 +24,7 @@
<com.android.settingslib.widget.IllustrationPreference
android:key="gesture_double_twist_video"
settings:searchable="false"
app:lottie_rawRes="@raw/lottie_flip_camera_for_selfie"/>
app:lottie_rawRes="@drawable/flip_camera_for_selfie"/>
<SwitchPreference
android:key="gesture_double_twist"

View File

@@ -81,15 +81,15 @@
settings:searchable="false"
settings:controller="com.android.settings.gestures.PickupGesturePreferenceController" />
<com.android.settings.widget.PrimarySwitchPreference
android:key="gesture_prevent_ringing_summary"
android:title="@string/gesture_prevent_ringing_screen_title"
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
<Preference
android:key="gesture_power_menu_summary"
android:title="@string/power_menu_setting_name"
android:fragment="com.android.settings.gestures.PowerMenuSettings"
settings:controller="com.android.settings.gestures.PowerMenuPreferenceController" />
<com.android.settings.widget.PrimarySwitchPreference
android:key="gesture_prevent_ringing_summary"
android:title="@string/gesture_prevent_ringing_screen_title"
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
</PreferenceScreen>

View File

@@ -24,10 +24,10 @@
android:title="@string/nfc_main_switch_title"
settings:controller="com.android.settings.nfc.NfcPreferenceController"/>
<com.android.settingslib.widget.LayoutPreference
<com.android.settingslib.widget.IllustrationPreference
android:key="nfc_detection_point"
android:selectable="false"
android:layout="@layout/nfc_detection_point"
settings:searchable="false"
settings:lottie_rawRes="@drawable/nfc_detection_point"
settings:controller="com.android.settings.nfc.NfcDetectionPointController"/>
<SwitchPreference

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -22,28 +22,32 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.accessibility.rtt.TelecomUtil;
import com.android.settings.core.BasePreferenceController;
import java.util.List;
/** A controller to control the status for RTT setting in Accessibility screen.*/
/** A controller to control the status for RTT setting in Accessibility screen. */
public class RTTSettingPreferenceController extends BasePreferenceController {
private static final String TAG = "RTTSettingsCtr";
private static final String DIALER_RTT_CONFIGURATION = "dialer_rtt_configuration";
private final Context mContext;
private final PackageManager mPackageManager;
private final TelecomManager mTelecomManager;
private final CarrierConfigManager mCarrierConfigManager;
private final CharSequence[] mModes;
private final String mDialerPackage;
@@ -55,17 +59,17 @@ public class RTTSettingPreferenceController extends BasePreferenceController {
mContext = context;
mModes = mContext.getResources().getTextArray(R.array.rtt_setting_mode);
mDialerPackage = mContext.getString(R.string.config_rtt_setting_package_name);
mPackageManager = context.getPackageManager();
mTelecomManager = context.getSystemService(TelecomManager.class);
mPackageManager = mContext.getPackageManager();
mCarrierConfigManager = mContext.getSystemService(CarrierConfigManager.class);
mRTTIntent = new Intent(context.getString(R.string.config_rtt_setting_intent_action));
Log.d(TAG, "init controller");
}
@Override
public int getAvailabilityStatus() {
final List<ResolveInfo> resolved =
mPackageManager.queryIntentActivities(mRTTIntent, 0 /* flags */);
return resolved != null && !resolved.isEmpty() && isDialerSupportRTTSetting()
return resolved != null && !resolved.isEmpty() && isRttSettingSupported()
? AVAILABLE
: UNSUPPORTED_ON_DEVICE;
}
@@ -80,17 +84,55 @@ public class RTTSettingPreferenceController extends BasePreferenceController {
@Override
public CharSequence getSummary() {
final int option = Settings.Secure.getInt(mContext.getContentResolver(),
DIALER_RTT_CONFIGURATION, 1 /* not visible */);
DIALER_RTT_CONFIGURATION, 0 /* Invalid value */);
Log.d(TAG, "DIALER_RTT_CONFIGURATION value = " + option);
return mModes[option];
}
private boolean isDialerSupportRTTSetting() {
final TelephonyManager telephonyManager = createTelephonyManagerFromSubId();
final boolean isCarrierAndRttSupported = telephonyManager.isRttSupported()
&& getBooleanCarrierConfig(CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
@VisibleForTesting
boolean isRttSettingSupported() {
Log.d(TAG, "isRttSettingSupported [start]");
if (!isDefaultDialerSupportedRTT(mContext)) {
Log.d(TAG, "Dialer doesn't support RTT.");
return false;
}
// At least one PhoneAccount must have both isRttSupported and
// ignore_rtt_mode_setting_bool being true
for (PhoneAccountHandle phoneAccountHandle :
TelecomUtil.getCallCapablePhoneAccounts(mContext)) {
final int subId =
TelecomUtil.getSubIdForPhoneAccountHandle(mContext, phoneAccountHandle);
Log.d(TAG, "subscription id for the device: " + subId);
return isCarrierAndRttSupported
&& TextUtils.equals(mTelecomManager.getDefaultDialerPackage(), mDialerPackage);
final boolean isRttCallingSupported = isRttSupportedByTelecom(phoneAccountHandle);
Log.d(TAG, "rtt calling supported by telecom:: " + isRttCallingSupported);
if (isRttCallingSupported) {
PersistableBundle carrierConfig = mCarrierConfigManager.getConfigForSubId(subId);
// If IGNORE_RTT_MODE_SETTING_BOOL=true, RTT visibility is not supported because
// this means we must use the legacy Telecom setting, which does not support RTT
// visibility.
if (carrierConfig != null
&& getBooleanCarrierConfig(
CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL)) {
Log.d(TAG, "RTT visibility setting is supported.");
return true;
}
Log.d(TAG, "IGNORE_RTT_MODE_SETTING_BOOL is false.");
}
}
Log.d(TAG, "isRttSettingSupported [Not support]");
return false;
}
private boolean isRttSupportedByTelecom(PhoneAccountHandle phoneAccountHandle) {
PhoneAccount phoneAccount =
TelecomUtil.getTelecomManager(mContext).getPhoneAccount(phoneAccountHandle);
if (phoneAccount != null && phoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_RTT)) {
Log.d(TAG, "Phone account has RTT capability.");
return true;
}
return false;
}
/**
@@ -100,25 +142,24 @@ public class RTTSettingPreferenceController extends BasePreferenceController {
* @return boolean value of corresponding key.
*/
private boolean getBooleanCarrierConfig(String key) {
final CarrierConfigManager configManager =
mContext.getSystemService(CarrierConfigManager.class);
if (configManager == null) {
if (mCarrierConfigManager == null) {
// Return static default defined in CarrierConfigManager.
return CarrierConfigManager.getDefaultConfig().getBoolean(key);
}
// If an invalid subId is used, this bundle will contain default values.
final int subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
final PersistableBundle bundle = configManager.getConfigForSubId(subId);
final PersistableBundle bundle = mCarrierConfigManager.getConfigForSubId(subId);
return bundle != null
? bundle.getBoolean(key)
: CarrierConfigManager.getDefaultConfig().getBoolean(key);
}
private TelephonyManager createTelephonyManagerFromSubId() {
final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class);
final int subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
return telephonyManager.createForSubscriptionId(subId);
/** Returns whether is a correct default dialer which supports RTT. */
private static boolean isDefaultDialerSupportedRTT(Context context) {
return TextUtils.equals(
context.getString(R.string.config_rtt_setting_package_name),
TelecomUtil.getTelecomManager(context).getDefaultDialerPackage());
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2021 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.rtt;
import android.content.Context;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* A util class checks some SIM card information and permissions.
*/
public abstract class TelecomUtil {
private static final String TAG = "TelecomUtil";
/** Get a list of phone accounts which are call capable. */
public static List<PhoneAccountHandle> getCallCapablePhoneAccounts(Context context) {
return Optional.ofNullable(getTelecomManager(context).getCallCapablePhoneAccounts())
.orElse(new ArrayList<>());
}
/** Returns a {@link TelecomManager} instance. */
public static TelecomManager getTelecomManager(Context context) {
return context.getApplicationContext().getSystemService(TelecomManager.class);
}
/** Returns a subscription id of the SIM. */
public static int getSubIdForPhoneAccountHandle(
Context context, PhoneAccountHandle phoneAccountHandle) {
Optional<SubscriptionInfo> info = getSubscriptionInfo(context, phoneAccountHandle);
return info.map(SubscriptionInfo::getSubscriptionId)
.orElse(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
}
/**
* @return the {@link SubscriptionInfo} of the SIM if {@code phoneAccountHandle} corresponds
* to a valid SIM. Absent otherwise.
*/
private static Optional<SubscriptionInfo> getSubscriptionInfo(
Context context, PhoneAccountHandle phoneAccountHandle) {
if (TextUtils.isEmpty(phoneAccountHandle.getId())) {
return Optional.empty();
}
SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
List<SubscriptionInfo> subscriptionInfos =
subscriptionManager.getActiveSubscriptionInfoList();
if (subscriptionInfos == null) {
return Optional.empty();
}
for (SubscriptionInfo info : subscriptionInfos) {
if (phoneAccountHandle.getId().startsWith(info.getIccId())) {
return Optional.of(info);
}
}
Log.d(TAG, "Failed to find SubscriptionInfo for phoneAccountHandle");
return Optional.empty();
}
}

View File

@@ -55,6 +55,7 @@ import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.widget.AppPreference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -76,28 +77,30 @@ public class PasswordsPreferenceController extends BasePreferenceController
private LifecycleOwner mLifecycleOwner;
public PasswordsPreferenceController(Context context, String preferenceKey) {
this(context, preferenceKey,
AutofillServiceInfo.getAvailableServices(context, UserHandle.myUserId()));
}
@VisibleForTesting
public PasswordsPreferenceController(
Context context, String preferenceKey, List<AutofillServiceInfo> availableServices) {
super(context, preferenceKey);
mPm = context.getPackageManager();
mIconFactory = IconDrawableFactory.newInstance(mContext);
mServices = new ArrayList<>();
}
@OnLifecycleEvent(ON_CREATE)
void onCreate(LifecycleOwner lifecycleOwner) {
init(lifecycleOwner, AutofillServiceInfo.getAvailableServices(mContext, getUser()));
}
@VisibleForTesting
void init(LifecycleOwner lifecycleOwner, List<AutofillServiceInfo> availableServices) {
mLifecycleOwner = lifecycleOwner;
for (int i = availableServices.size() - 1; i >= 0; i--) {
final String passwordsActivity = availableServices.get(i).getPasswordsActivity();
if (TextUtils.isEmpty(passwordsActivity)) {
availableServices.remove(i);
}
}
mServices = availableServices;
}
@OnLifecycleEvent(ON_CREATE)
void onCreate(LifecycleOwner lifecycleOwner) {
mLifecycleOwner = lifecycleOwner;
// TODO: Reverse the loop above and add to mServices directly.
mServices.clear();
mServices.addAll(availableServices);
}
@Override
@@ -109,8 +112,7 @@ public class PasswordsPreferenceController extends BasePreferenceController
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final PreferenceGroup group = screen.findPreference(getPreferenceKey());
// TODO(b/169455298): Show work profile passwords too.
addPasswordPreferences(screen.getContext(), UserHandle.myUserId(), group);
addPasswordPreferences(screen.getContext(), getUser(), group);
}
private void addPasswordPreferences(
@@ -126,11 +128,17 @@ public class PasswordsPreferenceController extends BasePreferenceController
serviceInfo.applicationInfo,
user);
pref.setIcon(Utils.getSafeIcon(icon));
pref.setIntent(
new Intent(Intent.ACTION_MAIN)
.setClassName(serviceInfo.packageName, service.getPasswordsActivity()));
// Set an empty summary to avoid a UI flicker when the value loads.
pref.setSummary(R.string.summary_placeholder);
pref.setOnPreferenceClickListener(p -> {
final Intent intent =
new Intent(Intent.ACTION_MAIN)
.setClassName(
serviceInfo.packageName,
service.getPasswordsActivity());
prefContext.startActivityAsUser(intent, UserHandle.of(user));
return true;
});
// Set a placeholder summary to avoid a UI flicker when the value loads.
pref.setSummary(R.string.autofill_passwords_count_placeholder);
final MutableLiveData<Integer> passwordCount = new MutableLiveData<>();
passwordCount.observe(
@@ -213,4 +221,9 @@ public class PasswordsPreferenceController extends BasePreferenceController
}
}
}
private int getUser() {
UserHandle workUser = getWorkProfileUser();
return workUser != null ? workUser.getIdentifier() : UserHandle.myUserId();
}
}

View File

@@ -159,6 +159,9 @@ public class ApplicationViewHolder extends RecyclerView.ViewHolder {
if (mSwitch != null && mWidgetContainer != null) {
mWidgetContainer.setOnClickListener(listener);
mWidgetContainer.setFocusable(false);
mWidgetContainer.setClickable(false);
mSwitch.setFocusable(true);
mSwitch.setClickable(true);
mSwitch.setChecked(checked);
mSwitch.setEnabled(enabled);
}

View File

@@ -82,6 +82,10 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
// Intent extra. If true, parental consent will be requested before user enrollment.
public static final String EXTRA_REQUIRE_PARENTAL_CONSENT = "require_consent";
// Intent extra. If true, the screen asking the user to return the device to their parent will
// be skipped after enrollment.
public static final String EXTRA_SKIP_RETURN_TO_PARENT = "skip_return_to_parent";
// If EXTRA_REQUIRE_PARENTAL_CONSENT was used to start the activity then the result
// intent will include this extra containing a bundle of the form:
// "modality" -> consented (boolean).
@@ -102,6 +106,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
private boolean mIsFaceEnrollable = false;
private boolean mIsFingerprintEnrollable = false;
private boolean mParentalOptionsRequired = false;
private boolean mSkipReturnToParent = false;
private Bundle mParentalOptions;
@Nullable private Long mGkPwHandle;
@Nullable private ParentalConsentHelper mParentalConsentHelper;
@@ -170,6 +175,7 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
// determine what can be enrolled
final boolean isSetupWizard = WizardManagerHelper.isAnySetupWizard(getIntent());
if (mHasFeatureFace) {
final FaceManager faceManager = getSystemService(FaceManager.class);
final List<FaceSensorPropertiesInternal> faceProperties =
@@ -193,9 +199,11 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
}
}
// TODO(b/188847063): replace with real flag when ready
mParentalOptionsRequired = intent.getBooleanExtra(
BiometricEnrollActivity.EXTRA_REQUIRE_PARENTAL_CONSENT, false);
mParentalOptionsRequired = intent.getBooleanExtra(EXTRA_REQUIRE_PARENTAL_CONSENT, false);
mSkipReturnToParent = intent.getBooleanExtra(EXTRA_SKIP_RETURN_TO_PARENT, false);
Log.d(TAG, "parentalOptionsRequired: " + mParentalOptionsRequired
+ ", skipReturnToParent: " + mSkipReturnToParent);
if (mParentalOptionsRequired && mParentalOptions == null) {
mParentalConsentHelper = new ParentalConsentHelper(
@@ -376,7 +384,12 @@ public class BiometricEnrollActivity extends InstrumentedActivity {
private void finishOrLaunchHandToParent(int resultCode) {
if (mParentalOptionsRequired) {
launchHandoffToParent();
if (!mSkipReturnToParent) {
launchHandoffToParent();
} else {
setResult(RESULT_OK, newResultIntent());
finish();
}
} else {
setResult(resultCode);
finish();

View File

@@ -215,8 +215,10 @@ public class FaceEnrollEducation extends BiometricEnrollBase {
}
protected void onSkipButtonClick(View view) {
setResult(RESULT_SKIP);
finish();
if (!BiometricUtils.tryStartingNextBiometricEnroll(this, ENROLL_NEXT_BIOMETRIC_REQUEST)) {
setResult(RESULT_SKIP);
finish();
}
}
@Override

View File

@@ -36,6 +36,8 @@ import android.os.Vibrator;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -116,6 +118,9 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
private AccessibilityManager mAccessibilityManager;
private boolean mIsAccessibilityEnabled;
private OrientationEventListener mOrientationEventListener;
private int mPreviousRotation = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -128,6 +133,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
mAccessibilityManager = getSystemService(AccessibilityManager.class);
mIsAccessibilityEnabled = mAccessibilityManager.isEnabled();
listenOrientationEvent();
if (mCanAssumeUdfps) {
if (BiometricUtils.isReverseLandscape(getApplicationContext())) {
setContentView(R.layout.udfps_enroll_enrolling_land);
@@ -255,6 +262,12 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
stopIconAnimation();
}
@Override
protected void onDestroy() {
stopListenOrientationEvent();
super.onDestroy();
}
private void animateProgress(int progress) {
if (mCanAssumeUdfps) {
// UDFPS animations are owned by SystemUI
@@ -451,6 +464,31 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
}
}
private void listenOrientationEvent() {
mOrientationEventListener = new OrientationEventListener(this) {
@Override
public void onOrientationChanged(int orientation) {
final int currentRotation = getDisplay().getRotation();
if ((mPreviousRotation == Surface.ROTATION_90
&& currentRotation == Surface.ROTATION_270) || (
mPreviousRotation == Surface.ROTATION_270
&& currentRotation == Surface.ROTATION_90)) {
mPreviousRotation = currentRotation;
recreate();
}
}
};
mOrientationEventListener.enable();
mPreviousRotation = getDisplay().getRotation();
}
private void stopListenOrientationEvent() {
if (mOrientationEventListener != null) {
mOrientationEventListener.disable();
}
mOrientationEventListener = null;
}
private final Animator.AnimatorListener mProgressAnimationListener
= new Animator.AnimatorListener() {

View File

@@ -45,7 +45,7 @@ public class FingerprintErrorDialog extends BiometricErrorDialog {
// This message happens when the underlying crypto layer decides to revoke the
// enrollment auth token.
return R.string.security_settings_fingerprint_enroll_error_timeout_dialog_message;
case FingerprintManager.FINGERPRINT_ERROR_BAD_CALIBARTION:
case FingerprintManager.FINGERPRINT_ERROR_BAD_CALIBRATION:
return R.string.security_settings_fingerprint_bad_calibration;
default:
// There's nothing specific to tell the user about. Ask them to try again.

View File

@@ -229,14 +229,18 @@ public abstract class DeviceListPreferenceFragment extends
@VisibleForTesting
void enableScanning() {
// BluetoothAdapter already handles repeated scan requests
startScanning();
mScanEnabled = true;
if (!mScanEnabled) {
startScanning();
mScanEnabled = true;
}
}
@VisibleForTesting
void disableScanning() {
stopScanning();
mScanEnabled = false;
if (mScanEnabled) {
stopScanning();
mScanEnabled = false;
}
}
@Override

View File

@@ -54,9 +54,9 @@ public class NfcAndPaymentFragmentController extends BasePreferenceController {
public CharSequence getSummary() {
if (mNfcAdapter != null) {
if (mNfcAdapter.isEnabled()) {
return mContext.getText(R.string.switch_on_text);
return mContext.getText(R.string.nfc_setting_on);
} else {
return mContext.getText(R.string.switch_off_text);
return mContext.getText(R.string.nfc_setting_off);
}
}
return null;

View File

@@ -48,8 +48,7 @@ import com.google.android.setupcompat.util.WizardManagerHelper;
import com.google.android.setupdesign.util.ThemeHelper;
/** Base activity for Settings pages */
public class SettingsBaseActivity extends FragmentActivity implements CategoryHandler,
AppBarLayout.OnOffsetChangedListener {
public class SettingsBaseActivity extends FragmentActivity implements CategoryHandler {
/**
* What type of page transition should be apply.
@@ -59,16 +58,12 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
protected static final boolean DEBUG_TIMING = false;
private static final String TAG = "SettingsBaseActivity";
private static final int DEFAULT_REQUEST = -1;
private static final int FULLY_EXPANDED_OFFSET = 0;
private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
private static final float TOOLBAR_LINE_SPACING_MULTIPLIER = 1.1f;
private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
protected CategoryMixin mCategoryMixin;
protected CollapsingToolbarLayout mCollapsingToolbarLayout;
protected AppBarLayout mAppBarLayout;
private Toolbar mToolbar;
private boolean mIsToolbarCollapsed;
@Override
public CategoryMixin getCategoryMixin() {
@@ -106,11 +101,9 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
super.setContentView(R.layout.collapsing_toolbar_base_layout);
mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mAppBarLayout = findViewById(R.id.app_bar);
mAppBarLayout.addOnOffsetChangedListener(this);
if (savedInstanceState != null) {
mIsToolbarCollapsed = savedInstanceState.getBoolean(KEY_IS_TOOLBAR_COLLAPSED);
if (mCollapsingToolbarLayout != null) {
mCollapsingToolbarLayout.setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER);
}
initCollapsingToolbar();
disableCollapsingToolbarLayoutScrollingBehavior();
} else {
super.setContentView(R.layout.settings_base_layout);
@@ -202,23 +195,6 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
}
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int offset) {
if (offset == FULLY_EXPANDED_OFFSET) {
mIsToolbarCollapsed = false;
} else {
mIsToolbarCollapsed = true;
}
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (isChangingConfigurations()) {
outState.putBoolean(KEY_IS_TOOLBAR_COLLAPSED, mIsToolbarCollapsed);
}
}
/**
* SubSetting page should show a toolbar by default. If the page wouldn't show a toolbar,
* override this method and return false value.
@@ -285,43 +261,4 @@ public class SettingsBaseActivity extends FragmentActivity implements CategoryHa
private int getTransitionType(Intent intent) {
return intent.getIntExtra(EXTRA_PAGE_TRANSITION_TYPE, TransitionType.TRANSITION_NONE);
}
@SuppressWarnings("RestrictTo")
private void initCollapsingToolbar() {
if (mCollapsingToolbarLayout == null || mAppBarLayout == null) {
return;
}
mCollapsingToolbarLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
if (mIsToolbarCollapsed) {
return;
}
final int count = mCollapsingToolbarLayout.getLineCount();
if (count > TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_three_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_three_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
mCollapsingToolbarLayout
.setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
.getDimensionPixelSize(R.dimen.toolbar_two_lines_height);
mCollapsingToolbarLayout.setScrimVisibleHeightTrigger(
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_two_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
mCollapsingToolbarLayout
.setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER);
}
}
});
}
}

View File

@@ -21,6 +21,7 @@ import static android.content.Intent.EXTRA_USER_ID;
import android.annotation.IntDef;
import android.app.Activity;
import android.content.Context;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
@@ -113,6 +114,7 @@ public abstract class ProfileSelectFragment extends DashboardFragment {
viewPager.setAdapter(new ProfileSelectFragment.ViewPagerAdapter(this));
final TabLayout tabs = tabContainer.findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
setupTabTextColor(tabs);
tabContainer.setVisibility(View.VISIBLE);
final TabLayout.Tab tab = tabs.getTabAt(selectedTab);
tab.select();
@@ -129,6 +131,30 @@ public abstract class ProfileSelectFragment extends DashboardFragment {
return mContentView;
}
/**
* TabLayout uses ColorStateList of 2 states, selected state and empty state.
* It's expected to use textColorSecondary default state color as empty state tabTextColor.
*
* However, TabLayout uses textColorSecondary by a not expected state.
* This method sets tabTextColor with the color of expected textColorSecondary state.
*/
private void setupTabTextColor(TabLayout tabLayout) {
final ColorStateList defaultColorStateList = tabLayout.getTabTextColors();
final ColorStateList resultColorStateList = new ColorStateList(
new int[][]{
new int[]{android.R.attr.state_selected},
new int[]{}
},
new int[] {
defaultColorStateList.getColorForState(new int[]{android.R.attr.state_selected},
Utils.getColorAttrDefaultColor(getContext(),
com.android.internal.R.attr.colorAccentPrimaryVariant)),
Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorSecondary)
}
);
tabLayout.setTabTextColors(resultColorStateList);
}
@Override
public int getMetricsCategory() {
return METRICS_CATEGORY_UNKNOWN;

View File

@@ -48,8 +48,6 @@ import android.widget.Toast;
import androidx.annotation.VisibleForTesting;
import com.android.internal.app.LocalePicker;
import com.android.internal.inputmethod.Completable;
import com.android.internal.inputmethod.ResultCallbacks;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.view.IInputMethodManager;
import com.android.settings.R;
@@ -262,13 +260,9 @@ public abstract class DevelopmentTiles extends TileService {
return false;
}
@VisibleForTesting
boolean isImeTraceEnabled() {
private boolean isImeTraceEnabled() {
try {
// TODO(b/175742251): Get rid of dependency on IInputMethodManager
final Completable.Boolean value = Completable.createBoolean();
mInputMethodManager.isImeTraceEnabled(ResultCallbacks.of(value));
return Completable.getResult(value);
return mInputMethodManager.isImeTraceEnabled();
} catch (RemoteException e) {
Log.e(TAG, "Could not get ime trace status, defaulting to false.", e);
}
@@ -328,16 +322,13 @@ public abstract class DevelopmentTiles extends TileService {
}
}
protected void setImeTraceEnabled(boolean isEnabled) {
private void setImeTraceEnabled(boolean isEnabled) {
try {
// TODO(b/175742251): Get rid of dependency on IInputMethodManager
final Completable.Void value = Completable.createVoid();
if (isEnabled) {
mInputMethodManager.startImeTrace(ResultCallbacks.of(value));
mInputMethodManager.startImeTrace();
} else {
mInputMethodManager.stopImeTrace(ResultCallbacks.of(value));
mInputMethodManager.stopImeTrace();
}
Completable.getResult(value);
} catch (RemoteException e) {
Log.e(TAG, "Could not set ime trace status." + e.toString());
}

View File

@@ -386,8 +386,6 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
+ otherData.documentsAndOtherSize
+ otherData.trashSize
+ otherData.allAppsExceptGamesSize;
attributedSize += otherData.externalStats.totalBytes
- otherData.externalStats.appBytes;
attributedSize -= otherData.duplicateCodeSize;
}

View File

@@ -50,7 +50,7 @@ public class SmartAutoRotateBatterySaverController extends BasePreferenceControl
if (mPreference == null) {
return;
}
mPreference.setVisible(isPowerSaveMode());
mPreference.setVisible(isAvailable());
updateState(mPreference);
}
};

View File

@@ -45,7 +45,7 @@ public class SmartAutoRotateCameraStateController extends BasePreferenceControll
mPrivacyManager = SensorPrivacyManager.getInstance(context);
mPrivacyManager.addSensorPrivacyListener(CAMERA, (sensor, enabled) -> {
if (mPreference != null) {
mPreference.setVisible(enabled);
mPreference.setVisible(isAvailable());
}
updateState(mPreference);
});

View File

@@ -23,19 +23,24 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnResume;
import com.android.settingslib.widget.BannerMessagePreference;
/**
* The controller of camera based rotate permission warning preference. The preference appears when
* the camera permission is missing for the camera based rotation feature.
*/
public class SmartAutoRotatePermissionController extends BasePreferenceController {
public class SmartAutoRotatePermissionController extends BasePreferenceController implements
LifecycleObserver, OnResume {
private final Intent mIntent;
private BannerMessagePreference mPreference;
public SmartAutoRotatePermissionController(Context context, String key) {
super(context, key);
@@ -48,15 +53,27 @@ public class SmartAutoRotatePermissionController extends BasePreferenceControlle
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
final BannerMessagePreference preference =
(BannerMessagePreference) screen.findPreference(getPreferenceKey());
preference
mPreference = screen.findPreference(getPreferenceKey());
mPreference
.setPositiveButtonText(R.string.auto_rotate_manage_permission_button)
.setPositiveButtonOnClickListener(v -> {
mContext.startActivity(mIntent);
});
}
@Override
public void onResume() {
updateState(mPreference);
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
if (preference != null) {
preference.setVisible(isAvailable());
}
}
@Override
@AvailabilityStatus
public int getAvailabilityStatus() {

View File

@@ -37,10 +37,15 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import com.google.common.annotations.VisibleForTesting;
/** The controller manages the behaviour of the Prevent Ringing gesture setting. */
public class PreventRingingParentPreferenceController extends TogglePreferenceController
implements LifecycleObserver, OnStart, OnStop {
@VisibleForTesting
static final int KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE = 1;
final String SECURE_KEY = VOLUME_HUSH_GESTURE;
private PrimarySwitchPreference mPreference;
@@ -59,6 +64,10 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo
@Override
public boolean isChecked() {
if (!isVolumePowerKeyChordSetToHush()) {
return false;
}
final int preventRinging = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.VOLUME_HUSH_GESTURE,
Settings.Secure.VOLUME_HUSH_VIBRATE);
@@ -85,25 +94,47 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo
final int value = Settings.Secure.getInt(
mContext.getContentResolver(), SECURE_KEY, VOLUME_HUSH_VIBRATE);
CharSequence summary;
switch (value) {
case VOLUME_HUSH_VIBRATE:
summary = mContext.getText(R.string.prevent_ringing_option_vibrate_summary);
break;
case VOLUME_HUSH_MUTE:
summary = mContext.getText(R.string.prevent_ringing_option_mute_summary);
break;
// VOLUME_HUSH_OFF
default:
summary = mContext.getText(R.string.switch_off_text);
if (isVolumePowerKeyChordSetToHush()) {
switch (value) {
case VOLUME_HUSH_VIBRATE:
summary = mContext.getText(R.string.prevent_ringing_option_vibrate_summary);
break;
case VOLUME_HUSH_MUTE:
summary = mContext.getText(R.string.prevent_ringing_option_mute_summary);
break;
// VOLUME_HUSH_OFF
default:
summary = mContext.getText(R.string.switch_off_text);
}
preference.setEnabled(true);
mPreference.setSwitchEnabled(true);
} else {
summary = mContext.getText(R.string.prevent_ringing_option_unavailable_lpp_summary);
preference.setEnabled(false);
mPreference.setSwitchEnabled(false);
}
preference.setSummary(summary);
}
@Override
public int getAvailabilityStatus() {
return mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)
? AVAILABLE : UNSUPPORTED_ON_DEVICE;
if (!mContext.getResources().getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
return UNSUPPORTED_ON_DEVICE;
}
if (isVolumePowerKeyChordSetToHush()) {
return AVAILABLE;
}
if (mContext.getResources().getBoolean(
com.android.internal
.R.bool.config_longPressOnPowerForAssistantSettingAvailable)) {
// The power + volume key chord is not set to hush gesture - it's been disabled
// by long press power for Assistant.
return DISABLED_DEPENDENT_SETTING;
}
return UNSUPPORTED_ON_DEVICE;
}
@Override
@@ -121,9 +152,26 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo
}
}
/**
* Returns true if power + volume up key chord is actually set to "mute toggle". If not,
* this setting will have no effect and should be disabled.
*
* This handles the condition when long press on power for Assistant changes power + volume
* chord to power menu and this setting needs to be disabled.
*/
private boolean isVolumePowerKeyChordSetToHush() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.KEY_CHORD_POWER_VOLUME_UP,
mContext.getResources().getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp))
== KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE;
}
private class SettingObserver extends ContentObserver {
private final Uri mVolumeHushGestureUri = Settings.Secure.getUriFor(
Settings.Secure.VOLUME_HUSH_GESTURE);
private final Uri mKeyChordVolumePowerUpUri = Settings.Global.getUriFor(
Settings.Global.KEY_CHORD_POWER_VOLUME_UP);
private final Preference mPreference;
@@ -133,6 +181,7 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo
}
public void register(ContentResolver cr) {
cr.registerContentObserver(mKeyChordVolumePowerUpUri, false, this);
cr.registerContentObserver(mVolumeHushGestureUri, false, this);
}
@@ -143,7 +192,8 @@ public class PreventRingingParentPreferenceController extends TogglePreferenceCo
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
if (uri == null || mVolumeHushGestureUri.equals(uri)) {
if (uri == null || mVolumeHushGestureUri.equals(uri)
|| mKeyChordVolumePowerUpUri.equals(uri)) {
updateState(mPreference);
}
}

View File

@@ -24,11 +24,9 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.SearchIndexable;
/** Dashboard Fragment to display all recent location requests, sorted by recency. */
@SearchIndexable
/** @deprecated Use {@link RecentLocationAccessSeeAllFragment} instead. */
@Deprecated
public class RecentLocationRequestSeeAllFragment extends DashboardFragment {
private static final String TAG = "RecentLocationReqAll";
public static final String PATH =
@@ -99,10 +97,4 @@ public class RecentLocationRequestSeeAllFragment extends DashboardFragment {
R.string.menu_hide_system);
updateMenu();
}
/**
* For Search.
*/
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.location_recent_requests_see_all);
}

View File

@@ -603,7 +603,11 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
public String getNetworkType(Context context, Config config,
TelephonyDisplayInfo telephonyDisplayInfo, int subId) {
String iconKey = getIconKey(telephonyDisplayInfo);
int resId = mapIconSets(config).get(iconKey).dataContentDescription;
MobileIconGroup iconGroup = mapIconSets(config).get(iconKey);
int resId = 0;
if (iconGroup != null) {
resId = iconGroup.dataContentDescription;
}
return resId != 0
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId)
: "";

View File

@@ -134,6 +134,8 @@ public class SetNewPasswordActivity extends Activity implements SetNewPasswordCo
intent.putExtra(EXTRA_KEY_IS_CALLING_APP_ADMIN, true);
}
intent.putExtra(EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY, mDevicePasswordRequirementOnly);
// Copy the setup wizard intent extra to the intent.
WizardManagerHelper.copyWizardManagerExtras(getIntent(), intent);
startActivity(intent);
finish();
}

View File

@@ -16,8 +16,11 @@
package com.android.settings.security;
import android.app.Dialog;
import android.app.admin.DevicePolicyEventLogger;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -25,12 +28,15 @@ import android.security.IKeyChainService;
import android.security.KeyChain;
import android.stats.devicepolicy.DevicePolicyEnums;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.widget.ActionButtonsPreference;
import java.util.concurrent.ExecutorService;
@@ -48,9 +54,16 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont
private final Handler mHandler = new Handler(Looper.getMainLooper());
private boolean mHasCredentialManagerPackage;
private Fragment mFragment;
private final int mRemoveIcon;
public CredentialManagementAppButtonsController(Context context, String preferenceKey) {
super(context, preferenceKey);
if (context.getResources().getConfiguration().getLayoutDirection()
== View.LAYOUT_DIRECTION_RTL) {
mRemoveIcon = R.drawable.ic_redo_24;
} else {
mRemoveIcon = R.drawable.ic_undo_24;
}
}
public void setParentFragment(Fragment fragment) {
@@ -84,8 +97,8 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont
.setButton1Icon(R.drawable.ic_upload)
.setButton1OnClickListener(view -> uninstallCertificates())
.setButton2Text(R.string.remove_credential_management_app)
.setButton2Icon(R.drawable.ic_delete)
.setButton2OnClickListener(view -> removeCredentialManagementApp());
.setButton2Icon(mRemoveIcon)
.setButton2OnClickListener(view -> showRemoveCredentialManagementAppDialog());
}
}
@@ -103,18 +116,54 @@ public class CredentialManagementAppButtonsController extends BasePreferenceCont
});
}
private void removeCredentialManagementApp() {
mExecutor.execute(() -> {
try {
IKeyChainService service = KeyChain.bind(mContext).getService();
service.removeCredentialManagementApp();
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.CREDENTIAL_MANAGEMENT_APP_REMOVED)
.write();
mFragment.getActivity().finish();
} catch (InterruptedException | RemoteException e) {
Log.e(TAG, "Unable to remove the credential management app");
}
});
private void showRemoveCredentialManagementAppDialog() {
final RemoveCredentialManagementAppDialog dialog =
RemoveCredentialManagementAppDialog.newInstance();
dialog.show(mFragment.getParentFragmentManager(),
RemoveCredentialManagementAppDialog.class.getName());
}
}
/**
* Implements an AlertDialog for confirming that a user wants to remove the credential
* management app. The app will no longer be able to manage certificates, but it will stay on
* the device. All certificates installed by the credential management app will be uninstalled.
*/
public static class RemoveCredentialManagementAppDialog extends InstrumentedDialogFragment {
public static RemoveCredentialManagementAppDialog newInstance() {
return new RemoveCredentialManagementAppDialog();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getContext(), R.style.Theme_AlertDialog)
.setTitle(R.string.remove_credential_management_app_dialog_title)
.setMessage(R.string.remove_credential_management_app_dialog_message)
.setPositiveButton(R.string.remove_credential_management_app,
(dialog, which) -> removeCredentialManagementApp())
.setNegativeButton(R.string.cancel, (dialog, which) -> dismiss())
.create();
}
private void removeCredentialManagementApp() {
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
try {
IKeyChainService service = KeyChain.bind(getContext()).getService();
service.removeCredentialManagementApp();
DevicePolicyEventLogger
.createEvent(DevicePolicyEnums.CREDENTIAL_MANAGEMENT_APP_REMOVED)
.write();
getParentFragment().getActivity().finish();
} catch (InterruptedException | RemoteException e) {
Log.e(TAG, "Unable to remove the credential management app");
}
});
}
@Override
public int getMetricsCategory() {
return SettingsEnums.CREDENTIAL_MANAGEMENT_APP_REMOVE_APP;
}
}
}

View File

@@ -288,7 +288,7 @@ public class RequestManageCredentials extends Activity {
// On down scroll, hide text in floating action button by setting
// extended to false.
if (dy > 0 && mExtendedFab.getVisibility() == View.VISIBLE) {
mExtendedFab.setExtended(false);
mExtendedFab.shrink();
}
if (isRecyclerScrollable()) {
mExtendedFab.show();

View File

@@ -50,7 +50,6 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
private SettingsMainSwitchBar mMainSwitchBar;
private CharSequence mTitle;
private boolean mIsVisible;
private EnforcedAdmin mEnforcedAdmin;
private RestrictedPreferenceHelper mRestrictedHelper;
@@ -87,7 +86,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
}
mMainSwitchBar = (SettingsMainSwitchBar) holder.findViewById(R.id.main_switch_bar);
initMainSwitchBar();
if (mIsVisible) {
if (isVisible()) {
mMainSwitchBar.show();
if (mMainSwitchBar.isChecked() != isChecked()) {
setChecked(isChecked());
@@ -101,7 +100,6 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
private void init(Context context, AttributeSet attrs) {
setLayoutResource(R.layout.preference_widget_main_switch);
mSwitchChangeListeners.add(this);
mIsVisible = true;
if (attrs != null) {
final TypedArray a = context.obtainStyledAttributes(attrs,
@@ -151,7 +149,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
* Show the MainSwitchBar
*/
public void show() {
mIsVisible = true;
setVisible(true);
if (mMainSwitchBar != null) {
mMainSwitchBar.show();
}
@@ -161,7 +159,7 @@ public class SettingsMainSwitchPreference extends TwoStatePreference implements
* Hide the MainSwitchBar
*/
public void hide() {
mIsVisible = false;
setVisible(false);
if (mMainSwitchBar != null) {
mMainSwitchBar.hide();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 The Android Open Source Project
* Copyright (C) 2021 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.
@@ -25,22 +25,15 @@ import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.PersistableBundle;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.ResolveInfoBuilder;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowPackageManager;
@@ -51,72 +44,40 @@ public class RTTSettingPreferenceControllerTest {
private ShadowPackageManager mShadowPackageManager;
private RTTSettingPreferenceController mController;
private TelephonyManager mTelephonyManagerFromSubId;
@Mock
private PersistableBundle mPersistableBundle;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
final Context context = spy(ApplicationProvider.getApplicationContext());
final int subId = SubscriptionManager.getDefaultVoiceSubscriptionId();
final String rttSettingsPackageName =
context.getString(R.string.config_rtt_setting_package_name);
final CarrierConfigManager configManager = spy(new CarrierConfigManager(context));
final TelephonyManager telephonyManager = spy(new TelephonyManager(context));
final TelecomManager telecomManager = spy(new TelecomManager(context));
mTelephonyManagerFromSubId = spy(new TelephonyManager(context, subId));
doReturn(telephonyManager).when(context).getSystemService(TelephonyManager.class);
doReturn(mTelephonyManagerFromSubId).when(telephonyManager).createForSubscriptionId(subId);
doReturn(telecomManager).when(context).getSystemService(TelecomManager.class);
doReturn(configManager).when(context).getSystemService(CarrierConfigManager.class);
doReturn(mPersistableBundle).when(configManager).getConfigForSubId(subId);
doReturn(rttSettingsPackageName).when(telecomManager).getDefaultDialerPackage();
mShadowPackageManager = shadowOf(context.getPackageManager());
mController = spy(new RTTSettingPreferenceController(context, "rtt_setting"));
mController.mRTTIntent = new Intent("com.android.test.action.example");
}
@Test
public void getStatus_carrierAndRttSupported_settingsIntent_available() {
doReturn(true).when(mTelephonyManagerFromSubId).isRttSupported();
doReturn(true).when(mPersistableBundle).getBoolean(
CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
setupTestIntent();
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
@Test
public void getStatus_rttSupported_settingsIntent_unsupported() {
doReturn(true).when(mTelephonyManagerFromSubId).isRttSupported();
doReturn(false).when(mPersistableBundle).getBoolean(
CarrierConfigManager.KEY_IGNORE_RTT_MODE_SETTING_BOOL);
setupTestIntent();
public void getAvailabilityStatus_resolvedIsEmpty_shouldReturnUNSUPPORTED_ON_DEVICE() {
doReturn(true).when(mController).isRttSettingSupported();
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getStatus_settingsIntent_unsupported() {
doReturn(false).when(mTelephonyManagerFromSubId).isRttSupported();
public void getAvailabilityStatus_intentIsHandledButRttSettingNotSupported_returnAVAILABLE() {
setupTestIntent();
doReturn(false).when(mController).isRttSettingSupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.UNSUPPORTED_ON_DEVICE);
}
@Test
public void getStatus_unsupported() {
doReturn(false).when(mTelephonyManagerFromSubId).isRttSupported();
public void getAvailabilityStatus_intentCanBeHandledAndRttSettingSupported_returnAVAILABLE() {
setupTestIntent();
doReturn(true).when(mController).isRttSettingSupported();
assertThat(mController.getAvailabilityStatus()).isEqualTo(
BasePreferenceController.UNSUPPORTED_ON_DEVICE);
assertThat(mController.getAvailabilityStatus())
.isEqualTo(BasePreferenceController.AVAILABLE);
}
private void setupTestIntent() {

View File

@@ -89,7 +89,7 @@ public class DefaultAutofillPreferenceControllerTest {
final Preference pref = mock(Preference.class);
mController.updateState(pref);
verify(pref).setSummary(R.string.app_list_preference_none);
verify(pref).setTitle(R.string.app_list_preference_none);
}
@Test

View File

@@ -24,10 +24,8 @@ import static com.android.settings.development.qstile.DevelopmentTiles.WinscopeT
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;
@@ -39,7 +37,6 @@ import android.os.RemoteException;
import android.view.IWindowManager;
import android.widget.Toast;
import com.android.internal.inputmethod.IBooleanResultCallback;
import com.android.internal.view.IInputMethodManager;
import com.android.settings.testutils.shadow.ShadowParcel;
@@ -71,10 +68,6 @@ public class WinscopeTraceTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mWinscopeTrace = spy(new DevelopmentTiles.WinscopeTrace());
// default ImeTraceEnabled value, prevent tests from actually calling into IMM and
// await the result forever.
doReturn(false).when(mWinscopeTrace).isImeTraceEnabled();
doNothing().when(mWinscopeTrace).setImeTraceEnabled(anyBoolean());
ReflectionHelpers.setField(mWinscopeTrace, "mWindowManager", mWindowManager);
ReflectionHelpers.setField(mWinscopeTrace, "mInputMethodManager", mInputMethodManager);
ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", mSurfaceFlinger);
@@ -100,6 +93,7 @@ public class WinscopeTraceTest {
public void sfReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
// Assume Window Trace and Input Method Manager are disabled.
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
ShadowParcel.sReadBoolResult = true;
assertThat(mWinscopeTrace.isEnabled()).isTrue();
verify(mSurfaceFlinger)
@@ -120,6 +114,7 @@ public class WinscopeTraceTest {
public void wmAndSfAndImmReturnTraceDisabled_shouldReturnDisabled() throws RemoteException {
ShadowParcel.sReadBoolResult = false;
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isFalse();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
@@ -132,7 +127,7 @@ public class WinscopeTraceTest {
throws RemoteException {
ShadowParcel.sReadBoolResult = false;
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
doReturn(true).when(mWinscopeTrace).isImeTraceEnabled();
doReturn(true).when(mInputMethodManager).isImeTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isTrue();
verify(mSurfaceFlinger)
.transact(eq(SURFACE_FLINGER_LAYER_TRACE_STATUS_CODE), any(), any(),
@@ -145,7 +140,7 @@ public class WinscopeTraceTest {
public void immReturnsTraceEnabled_shouldReturnEnabled() throws RemoteException {
// Assume Window Manager and Surface Trace are disabled.
ShadowParcel.sReadBoolResult = false;
doReturn(true).when(mWinscopeTrace).isImeTraceEnabled();
doReturn(true).when(mInputMethodManager).isImeTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isTrue();
}
@@ -154,6 +149,7 @@ public class WinscopeTraceTest {
public void immReturnsTraceDisabled_shouldReturnDisabled() throws RemoteException {
// Assume Window Manager and Surface Trace are disabled.
ShadowParcel.sReadBoolResult = false;
doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
assertThat(mWinscopeTrace.isEnabled()).isFalse();
}
@@ -171,6 +167,7 @@ public class WinscopeTraceTest {
public void sfUnavailableAndWmAndImmReturnTraceDisabled_shouldReturnDisabled()
throws RemoteException {
doReturn(false).when(mWindowManager).isWindowTraceEnabled();
doReturn(false).when(mInputMethodManager).isImeTraceEnabled();
ReflectionHelpers.setField(mWinscopeTrace, "mSurfaceFlinger", null);
assertThat(mWinscopeTrace.isEnabled()).isFalse();
}
@@ -185,7 +182,7 @@ public class WinscopeTraceTest {
@Test
public void setIsEnableTrue_shouldEnableImeTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(true);
verify(mWinscopeTrace).setImeTraceEnabled(eq(true));
verify(mInputMethodManager).startImeTrace();
verifyNoMoreInteractions(mInputMethodManager);
}
@@ -213,7 +210,7 @@ public class WinscopeTraceTest {
@Config(shadows = ShadowParcel.class)
public void setIsEnableFalse_shouldDisableImeTrace() throws RemoteException {
mWinscopeTrace.setIsEnabled(false);
verify(mWinscopeTrace).setImeTraceEnabled(eq(false));
verify(mInputMethodManager).stopImeTrace();
verifyNoMoreInteractions(mInputMethodManager);
verify(mToast).show();
}
@@ -254,8 +251,7 @@ public class WinscopeTraceTest {
@Test
public void setIsEnableAndImmThrowsRemoteException_shouldFailGracefully()
throws RemoteException {
doThrow(new RemoteException("Unknown")).when(mInputMethodManager)
.isImeTraceEnabled(any(IBooleanResultCallback.Stub.class));
doThrow(new RemoteException("Unknown")).when(mInputMethodManager).isImeTraceEnabled();
mWinscopeTrace.setIsEnabled(true);
}

View File

@@ -54,7 +54,6 @@ import com.android.settings.applications.manageapplications.ManageApplications;
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
import com.android.settings.deviceinfo.StorageItemPreference;
import com.android.settings.testutils.shadow.ShadowUserManager;
import com.android.settingslib.applications.StorageStatsSource;
import com.android.settingslib.deviceinfo.StorageVolumeProvider;
import org.junit.Before;
@@ -340,12 +339,6 @@ public class StorageItemPreferenceControllerTest {
result.documentsAndOtherSize = MEGABYTE_IN_BYTES * 50;
result.trashSize = KILOBYTE_IN_BYTES * 100;
result.allAppsExceptGamesSize = MEGABYTE_IN_BYTES * 90;
result.externalStats =
new StorageStatsSource.ExternalStorageStats(
MEGABYTE_IN_BYTES * 500, // total
MEGABYTE_IN_BYTES * 100, // audio
MEGABYTE_IN_BYTES * 150, // video
MEGABYTE_IN_BYTES * 200, 0); // image
final SparseArray<StorageAsyncLoader.StorageResult> results = new SparseArray<>();
results.put(0, result);

View File

@@ -22,6 +22,8 @@ import static android.provider.Settings.Secure.VOLUME_HUSH_OFF;
import static android.provider.Settings.Secure.VOLUME_HUSH_VIBRATE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
@@ -33,8 +35,10 @@ import android.content.res.Resources;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.widget.PrimarySwitchPreference;
import org.junit.Before;
import org.junit.Test;
@@ -50,6 +54,9 @@ public class PreventRingingParentPreferenceControllerTest {
@Mock
private Resources mResources;
@Mock
PreferenceScreen mScreen;
private Context mContext;
private PreventRingingParentPreferenceController mController;
private Preference mPreference;
@@ -58,21 +65,53 @@ public class PreventRingingParentPreferenceControllerTest {
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application.getApplicationContext());
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(
PreventRingingParentPreferenceController.KEY_CHORD_POWER_VOLUME_UP_MUTE_TOGGLE);
mController = new PreventRingingParentPreferenceController(mContext, "test_key");
mPreference = new Preference(mContext);
mPreference = new PrimarySwitchPreference(mContext);
when(mScreen.findPreference("test_key")).thenReturn(mPreference);
mController.displayPreference(mScreen);
}
@Test
public void testIsAvailable_configIsTrue_shouldAvailableUnSearchable() {
when(mContext.getResources()).thenReturn(mResources);
public void isAvailable_configIsTrueAndKeyChordMute_shouldAvailableUnSearchable() {
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
@Test
public void testIsAvailable_configIsFalse_shouldReturnFalse() {
public void getAvailabilityStatus_configIsTrueAndKeyNotMute_shouldReturnDisabledDependent() {
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(true);
when(mResources.getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2);
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
public void getAvailabilityStatus_configIsTrueLppDisabled_shouldReturnUnsupportedOnDevice() {
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(true);
when(mResources.getBoolean(
com.android.internal.R.bool.config_longPressOnPowerForAssistantSettingAvailable))
.thenReturn(false);
when(mResources.getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2);
assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
public void isAvailable_configIsFalse_shouldReturnFalse() {
when(mContext.getResources()).thenReturn(mResources);
when(mResources.getBoolean(
com.android.internal.R.bool.config_volumeHushGestureEnabled)).thenReturn(false);
@@ -101,6 +140,21 @@ public class PreventRingingParentPreferenceControllerTest {
R.string.switch_off_text));
}
@Test
public void updateState_keyChordDisabled_summaryUpdated() {
when(mResources.getInteger(
com.android.internal.R.integer.config_keyChordPowerVolumeUp)).thenReturn(2);
// Ensure that the state displays unchecked even if the underlying field is set.
Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE,
VOLUME_HUSH_MUTE);
mController.updateState(mPreference);
assertThat(mPreference.isEnabled()).isFalse();
assertThat(mPreference.getSummary()).isEqualTo(mContext.getResources().getText(
R.string.prevent_ringing_option_unavailable_lpp_summary));
assertThat(mController.isChecked()).isFalse();
}
@Test
public void isChecked_vibrate_shouldReturnTrue() {
Settings.Secure.putInt(mContext.getContentResolver(), VOLUME_HUSH_GESTURE,

View File

@@ -76,6 +76,7 @@ public class SettingsMainSwitchPreferenceTest {
mPreference.onBindViewHolder(mHolder);
assertThat(mPreference.isShowing()).isTrue();
assertThat(mPreference.isVisible()).isTrue();
}
@Test
@@ -85,5 +86,6 @@ public class SettingsMainSwitchPreferenceTest {
mPreference.onBindViewHolder(mHolder);
assertThat(mPreference.isShowing()).isFalse();
assertThat(mPreference.isVisible()).isFalse();
}
}

View File

@@ -21,11 +21,19 @@ import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_U
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.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Looper;
import android.os.UserHandle;
import android.service.autofill.AutofillServiceInfo;
import androidx.lifecycle.Lifecycle;
@@ -40,9 +48,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.collect.Lists;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.util.Collections;
import java.util.List;
@@ -56,7 +64,7 @@ public class PasswordsPreferenceControllerTest {
@Before
public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
mContext = spy(ApplicationProvider.getApplicationContext());
if (Looper.myLooper() == null) {
Looper.prepare(); // needed to create the preference screen
}
@@ -66,6 +74,15 @@ public class PasswordsPreferenceControllerTest {
mScreen.addPreference(mPasswordsPreferenceCategory);
}
@Test
// Tests that getAvailabilityStatus() does not throw an exception if it's called before the
// Controller is initialized (this can happen during indexing).
public void getAvailabilityStatus_withoutInit_returnsUnavailable() {
PasswordsPreferenceController controller =
new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
assertThat(controller.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_noServices_returnsUnavailable() {
PasswordsPreferenceController controller =
@@ -105,21 +122,26 @@ public class PasswordsPreferenceControllerTest {
assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(0);
}
@Ignore("TODO: Fix the test to handle the service binding.")
@Test
@UiThreadTest
public void displayPreference_withPasswords_addsPreference() {
AutofillServiceInfo service = createServiceWithPasswords();
service.getServiceInfo().packageName = "";
service.getServiceInfo().name = "";
PasswordsPreferenceController controller =
createControllerWithServices(Lists.newArrayList(service));
controller.onCreate(() -> mock(Lifecycle.class));
doReturn(false).when(mContext).bindServiceAsUser(any(), any(), anyInt(), any());
controller.displayPreference(mScreen);
assertThat(mPasswordsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
Preference pref = mPasswordsPreferenceCategory.getPreference(0);
assertThat(pref.getIcon()).isNotNull();
assertThat(pref.getIntent().getComponent())
pref.performClick();
ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
UserHandle user = mContext.getUser();
verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(user));
assertThat(intentCaptor.getValue().getComponent())
.isEqualTo(
new ComponentName(
service.getServiceInfo().packageName,
@@ -128,8 +150,10 @@ public class PasswordsPreferenceControllerTest {
private PasswordsPreferenceController createControllerWithServices(
List<AutofillServiceInfo> availableServices) {
return new PasswordsPreferenceController(
mContext, mPasswordsPreferenceCategory.getKey(), availableServices);
PasswordsPreferenceController controller =
new PasswordsPreferenceController(mContext, mPasswordsPreferenceCategory.getKey());
controller.init(() -> mock(Lifecycle.class), availableServices);
return controller;
}
private AutofillServiceInfo createServiceWithPasswords() {

View File

@@ -62,7 +62,7 @@ public class CustomSiteMapRegistryTest {
}
@Test
public void shouldContainRecentLocationRequestSeeAllFragmentPairs() {
public void shouldContainRecentLocationAccessSeeAllFragmentPairs() {
assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(
RecentLocationAccessSeeAllFragment.class.getName())).isEqualTo(
LocationSettings.class.getName());