Snap for 7519874 from 83e4f3c658
to sc-release
Change-Id: Iad140400c1bd5bf56accd17b5f057e2ce6ed10ea
This commit is contained in:
@@ -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" />
|
||||
|
||||
|
3
res/drawable/flip_camera_for_selfie.xml
Normal file
3
res/drawable/flip_camera_for_selfie.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape>
|
||||
</shape>
|
25
res/drawable/ic_redo_24.xml
Normal file
25
res/drawable/ic_redo_24.xml
Normal 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>
|
3
res/drawable/quickly_open_camera.xml
Normal file
3
res/drawable/quickly_open_camera.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape>
|
||||
</shape>
|
@@ -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" />
|
||||
|
||||
|
@@ -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" />
|
||||
|
||||
|
@@ -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"/>
|
||||
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"/>
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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>
|
||||
|
@@ -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
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
81
src/com/android/settings/accessibility/rtt/TelecomUtil.java
Normal file
81
src/com/android/settings/accessibility/rtt/TelecomUtil.java
Normal 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();
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
@@ -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() {
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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());
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -50,7 +50,7 @@ public class SmartAutoRotateBatterySaverController extends BasePreferenceControl
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
mPreference.setVisible(isPowerSaveMode());
|
||||
mPreference.setVisible(isAvailable());
|
||||
updateState(mPreference);
|
||||
}
|
||||
};
|
||||
|
@@ -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);
|
||||
});
|
||||
|
@@ -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() {
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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)
|
||||
: "";
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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();
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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() {
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
@@ -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() {
|
||||
|
@@ -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());
|
||||
|
Reference in New Issue
Block a user