Snap for 10120310 from 5f40973695 to udc-qpr1-release
Change-Id: Ia120731de3dc4f6c8a68d3c05e987d82b02105bb
This commit is contained in:
@@ -1581,6 +1581,22 @@
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="switch_bar_state_disabled_color">#1FE3E3E3</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values-night/colors.xml"
|
||||
line="76"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -2957,6 +2973,22 @@
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <color name="switch_bar_state_disabled_color">#1F1F1F1F</color>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/values/colors.xml"
|
||||
line="219"
|
||||
column="5"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
@@ -6253,6 +6285,38 @@
|
||||
column="63"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <solid android:color="@color/switch_bar_state_disabled_color"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/switch_bar_bg_disabled.xml"
|
||||
line="22"
|
||||
column="20"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
message="Avoid using hardcoded color"
|
||||
category="Correctness"
|
||||
priority="4"
|
||||
summary="Using hardcoded color"
|
||||
explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes.
This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app."
|
||||
errorLine1=" <solid android:color="@color/switch_bar_state_disabled_color"/>"
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/switch_bar_bg_disabled.xml"
|
||||
line="22"
|
||||
column="20"/>
|
||||
</issue>
|
||||
|
||||
<issue
|
||||
id="HardCodedColor"
|
||||
severity="Error"
|
||||
|
||||
@@ -19,10 +19,11 @@ message BatteryOptimizeHistoricalLogEntry {
|
||||
APPLY = 2;
|
||||
RESET = 3;
|
||||
RESTORE = 4;
|
||||
BACKUP = 5;
|
||||
}
|
||||
|
||||
optional string package_name = 1;
|
||||
optional Action action = 2;
|
||||
optional string action_description = 3;
|
||||
optional int64 timestamp = 4;
|
||||
}
|
||||
}
|
||||
|
||||
26
res/drawable/switch_bar_bg_disabled.xml
Normal file
26
res/drawable/switch_bar_bg_disabled.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023 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.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/switch_bar_state_disabled_color"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_bar_radius"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -96,4 +96,6 @@
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/udfps_enroll_view" />
|
||||
</com.google.android.setupdesign.GlifLayout>
|
||||
@@ -24,6 +24,7 @@
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<com.google.android.setupdesign.GlifLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/setup_wizard_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -41,10 +42,11 @@
|
||||
<FrameLayout
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:layout_gravity="center_horizontal|bottom">
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
tools:ignore="Suspicious0dp">
|
||||
|
||||
<!-- Animation res MUST be set in code -->
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
@@ -59,6 +61,9 @@
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:lottie_speed=".85" />
|
||||
|
||||
<include layout="@layout/udfps_enroll_view" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -71,5 +71,8 @@
|
||||
<!-- Flash notifications colors -->
|
||||
<!-- Screen flash notification color selected stroke in color selection dialog -->
|
||||
<color name="screen_flash_color_button_outer_circle_stroke_color">#FFFFFF</color>
|
||||
|
||||
<!-- Switch bar disabled state color-->
|
||||
<color name="switch_bar_state_disabled_color">#1FE3E3E3</color>
|
||||
</resources>
|
||||
|
||||
|
||||
@@ -214,4 +214,7 @@
|
||||
<color name="screen_flash_preset_opacity_color_10">#4DFF017E</color> <!-- 30% Rose -->
|
||||
<color name="screen_flash_preset_opacity_color_11">#4DFF00FE</color> <!-- 30% Magenta -->
|
||||
<color name="screen_flash_preset_opacity_color_12">#667F00FF</color> <!-- 40% Violet -->
|
||||
|
||||
<!-- Switch bar disabled state color-->
|
||||
<color name="switch_bar_state_disabled_color">#1F1F1F1F</color>
|
||||
</resources>
|
||||
|
||||
@@ -119,9 +119,9 @@
|
||||
<!-- Connected devices settings. Title of the dialog to hint user to pair other ear of the hearing aid device. Shows when only one of the hearing aid device set is connected. [CHAR LIMIT=25] -->
|
||||
<string name="bluetooth_pair_other_ear_dialog_title">Pair your other ear</string>
|
||||
<!-- Connected devices settings. Message of the dialog to hint user to pair right ear of the hearing aid device. Shows when only left side of hearing aid device set is connected. [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_pair_other_ear_dialog_left_ear_message">Your left hearing aid is connected.\n\nTo pair the right one, make sure it\u2019s turned on and ready to pair.</string>
|
||||
<string name="bluetooth_pair_other_ear_dialog_left_ear_message">Your left hearing device is connected.\n\nTo pair the right one, make sure it\u2019s turned on and ready to pair.</string>
|
||||
<!-- Connected devices settings. Message of the dialog to hint user to pair other ear of the hearing aid device. Shows when only right side of the hearing aid device set is connected. [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_pair_other_ear_dialog_right_ear_message">Your right hearing aid is connected.\n\nTo pair the left one, make sure it\u2019s turned on and ready to pair.</string>
|
||||
<string name="bluetooth_pair_other_ear_dialog_right_ear_message">Your right hearing device is connected.\n\nTo pair the left one, make sure it\u2019s turned on and ready to pair.</string>
|
||||
<!-- Connected devices settings. Positive button of the dialog to help user to pair right ear of the hearing aid device. Dialog shows when only one of the hearing aid device set is connected. [CHAR LIMIT=20] -->
|
||||
<string name="bluetooth_pair_other_ear_dialog_right_ear_positive_button">Pair right ear</string>
|
||||
<!-- Connected devices settings. Positive button of the dialog to help user to pair left ear of the hearing aid device. Dialog shows when only one of the hearing aid device set is connected. [CHAR LIMIT=20] -->
|
||||
@@ -1182,20 +1182,20 @@
|
||||
<string name="current_screen_lock">Current screen lock</string>
|
||||
|
||||
<!-- Title for preference that guides the user through creating a backup unlock pattern for fingerprint [CHAR LIMIT=45]-->
|
||||
<string name="fingerprint_unlock_set_unlock_pattern">Fingerprint + Pattern</string>
|
||||
<string name="fingerprint_unlock_set_unlock_pattern">Pattern \u2022 Fingerprint</string>
|
||||
<!-- Title for preference that guides the user through creating a backup unlock PIN for fingerprint [CHAR LIMIT=45]-->
|
||||
<string name="fingerprint_unlock_set_unlock_pin">Fingerprint + PIN</string>
|
||||
<string name="fingerprint_unlock_set_unlock_pin">PIN \u2022 Fingerprint</string>
|
||||
<!-- Title for preference that guides the user through creating a backup unlock password for fingerprint [CHAR LIMIT=45]-->
|
||||
<string name="fingerprint_unlock_set_unlock_password">Fingerprint + Password</string>
|
||||
<string name="fingerprint_unlock_set_unlock_password">Password \u2022 Fingerprint</string>
|
||||
<!-- Title for preference that guides the user to skip fingerprint setup [CHAR LIMIT=60]-->
|
||||
<string name="fingerprint_unlock_skip_fingerprint">Continue without fingerprint</string>
|
||||
|
||||
<!-- Title for preference that guides the user through creating a backup unlock pattern for Face Unlock [CHAR LIMIT=45]-->
|
||||
<string name="face_unlock_set_unlock_pattern">Face Unlock + Pattern</string>
|
||||
<string name="face_unlock_set_unlock_pattern">Pattern \u2022 Face</string>
|
||||
<!-- Title for preference that guides the user through creating a backup unlock PIN for Face Unlock [CHAR LIMIT=45]-->
|
||||
<string name="face_unlock_set_unlock_pin">Face Unlock + PIN</string>
|
||||
<string name="face_unlock_set_unlock_pin">PIN \u2022 Face</string>
|
||||
<!-- Title for preference that guides the user through creating a backup unlock password for Face Unlock [CHAR LIMIT=45]-->
|
||||
<string name="face_unlock_set_unlock_password">Face Unlock + Password</string>
|
||||
<string name="face_unlock_set_unlock_password">Password \u2022 Face</string>
|
||||
<!-- Title for preference that guides the user to skip Face Unlock setup [CHAR LIMIT=60]-->
|
||||
<string name="face_unlock_skip_face">Continue without Face Unlock</string>
|
||||
|
||||
@@ -1505,6 +1505,8 @@
|
||||
<string name="bluetooth_companion_app_remove_association_dialog_title">Disconnect App?</string>
|
||||
<!-- Bluetooth device details companion apps. The body of confirmation dialog for remove association. [CHAR LIMIT=60] -->
|
||||
<string name="bluetooth_companion_app_body"><xliff:g id="app_name" example="App Name">%1$s</xliff:g> app will no longer connect to your <xliff:g id="device_name" example="Device Name">%2$s</xliff:g></string>
|
||||
<!-- Summary of Bluetooth LE Audio toggle in Device Details. [CHAR LIMIT=40] -->
|
||||
<string name="device_details_leaudio_toggle_summary">Experimental. Improves audio quality.</string>
|
||||
|
||||
<!-- Bluetooth device details. In the confirmation dialog for unpairing a paired device, this is the label on the button that will complete the unpairing action. -->
|
||||
<string name="bluetooth_unpair_dialog_forget_confirm_button">Forget device</string>
|
||||
@@ -4670,7 +4672,7 @@
|
||||
<!-- Introduction for the Hearing devices page to introduce feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="accessibility_hearingaid_intro">You can use hearing aids, cochlear implants, and other amplification devices with your phone</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when not connected. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_hearingaid_not_connected_summary">No hearing aids connected</string>
|
||||
<string name="accessibility_hearingaid_not_connected_summary">No hearing devices connected</string>
|
||||
<!-- Summary for the accessibility preference for hearing aid when adding new devices. [CHAR LIMIT=50] -->
|
||||
<string name="accessibility_hearingaid_adding_summary">Add hearing aids</string>
|
||||
<!-- Title of the pair instruction dialog. Dialog shows to ask the user to make sure that their hearing aid devices are in pairing mode. [CHAR LIMIT=25] -->
|
||||
@@ -10306,7 +10308,16 @@
|
||||
<string name="credman_confirmation_message_title">Turn off %1$s\?</string>
|
||||
|
||||
<!-- Message of the warning dialog for disabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||
<string name="credman_confirmation_message">Saved info like addresses or payment methods won\'t be filled in when you sign in. To keep your saved info filled in, set enable a password, passkey and data/or service.</string>
|
||||
<string name="credman_confirmation_message">
|
||||
<![CDATA[
|
||||
<b>Turn off this service?</b>
|
||||
<br/>
|
||||
<br/>
|
||||
Saved info like passwords, passkeys, payment methods, and other info won\'t be filled
|
||||
in when you sign in. To use your saved info, choose a password, passkey, or data
|
||||
service.
|
||||
]]>
|
||||
</string>
|
||||
|
||||
<!-- Title of the warning dialog for enabling the credential provider. [CHAR_LIMIT=NONE] -->
|
||||
<string name="credman_enable_confirmation_message_title">Use %1$s\?</string>
|
||||
|
||||
@@ -17,16 +17,26 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
/**
|
||||
* Preference for Flash notifications preview.
|
||||
*/
|
||||
public class FlashNotificationsPreviewPreference extends Preference {
|
||||
private Drawable mBackgroundEnabled;
|
||||
private Drawable mBackgroundDisabled;
|
||||
@ColorInt
|
||||
private int mTextColorDisabled;
|
||||
|
||||
public FlashNotificationsPreviewPreference(Context context) {
|
||||
super(context);
|
||||
@@ -52,5 +62,32 @@ public class FlashNotificationsPreviewPreference extends Preference {
|
||||
|
||||
private void init() {
|
||||
setLayoutResource(R.layout.flash_notification_preview_preference);
|
||||
mBackgroundEnabled = getContext().getDrawable(R.drawable.settingslib_switch_bar_bg_on);
|
||||
mBackgroundDisabled = getContext().getDrawable(R.drawable.switch_bar_bg_disabled);
|
||||
mTextColorDisabled = Utils.getColorAttrDefaultColor(getContext(),
|
||||
android.R.attr.textColorPrimary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
final boolean enabled = isEnabled();
|
||||
final View frame = holder.findViewById(R.id.frame);
|
||||
if (frame != null) {
|
||||
frame.setBackground(enabled ? mBackgroundEnabled : mBackgroundDisabled);
|
||||
}
|
||||
final TextView title = (TextView) holder.findViewById(android.R.id.title);
|
||||
if (title != null) {
|
||||
@ColorInt final int textColorEnabled = title.getCurrentTextColor();
|
||||
title.setAlpha(enabled ? 1f : 0.38f);
|
||||
title.setTextColor(enabled ? textColorEnabled : mTextColorDisabled);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
super.setEnabled(enabled);
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class FlashNotificationsPreviewPreferenceController extends
|
||||
new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange, @Nullable Uri uri) {
|
||||
onSettingChanged();
|
||||
updateState(mPreference);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -73,7 +73,7 @@ public class FlashNotificationsPreviewPreferenceController extends
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
onSettingChanged();
|
||||
updateState(mPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -103,10 +103,13 @@ public class FlashNotificationsPreviewPreferenceController extends
|
||||
}
|
||||
}
|
||||
|
||||
private void onSettingChanged() {
|
||||
if (mPreference == null) return;
|
||||
|
||||
mPreference.setEnabled(FlashNotificationsUtil.getFlashNotificationsState(mContext)
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
if (preference == null) {
|
||||
return;
|
||||
}
|
||||
preference.setEnabled(FlashNotificationsUtil.getFlashNotificationsState(mContext)
|
||||
!= FlashNotificationsUtil.State.OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,19 +554,7 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
// If we are disabling the last enabled provider then show a warning.
|
||||
if (mEnabledPackageNames.size() <= 1) {
|
||||
final DialogFragment fragment =
|
||||
newConfirmationDialogFragment(packageName, title, pref);
|
||||
|
||||
if (fragment == null || mFragmentManager == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
fragment.show(mFragmentManager, ConfirmationDialogFragment.TAG);
|
||||
} else {
|
||||
togglePackageNameDisabled(packageName);
|
||||
}
|
||||
togglePackageNameDisabled(packageName);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -682,35 +670,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
return new ErrorDialogFragment(host);
|
||||
}
|
||||
|
||||
private @Nullable ConfirmationDialogFragment newConfirmationDialogFragment(
|
||||
@NonNull String packageName,
|
||||
@NonNull CharSequence appName,
|
||||
@NonNull SwitchPreference pref) {
|
||||
DialogHost host =
|
||||
new DialogHost() {
|
||||
@Override
|
||||
public void onDialogClick(int whichButton) {
|
||||
if (whichButton == DialogInterface.BUTTON_POSITIVE) {
|
||||
// Since the package is now enabled then we
|
||||
// should remove it from the enabled list.
|
||||
togglePackageNameDisabled(packageName);
|
||||
} else if (whichButton == DialogInterface.BUTTON_NEGATIVE) {
|
||||
// Set the checked back to true because we
|
||||
// backed out of turning this off.
|
||||
pref.setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
// If we dismiss the dialog then re-enable.
|
||||
pref.setChecked(true);
|
||||
}
|
||||
};
|
||||
|
||||
return new ConfirmationDialogFragment(host, packageName, appName);
|
||||
}
|
||||
|
||||
protected int getUser() {
|
||||
if (mIsWorkProfile) {
|
||||
UserHandle workProfile = Utils.getManagedProfile(UserManager.get(mContext));
|
||||
@@ -800,46 +759,6 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
public void onClick(DialogInterface dialog, int which) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation dialog fragment shows a dialog to the user to confirm that they are disabling a
|
||||
* provider.
|
||||
*/
|
||||
public static class ConfirmationDialogFragment extends CredentialManagerDialogFragment {
|
||||
|
||||
ConfirmationDialogFragment(
|
||||
DialogHost dialogHost, @NonNull String packageName, @NonNull CharSequence appName) {
|
||||
super(dialogHost);
|
||||
|
||||
final Bundle argument = new Bundle();
|
||||
argument.putString(PACKAGE_NAME_KEY, packageName);
|
||||
argument.putCharSequence(APP_NAME_KEY, appName);
|
||||
setArguments(argument);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Bundle bundle = getArguments();
|
||||
final String title =
|
||||
getContext()
|
||||
.getString(
|
||||
R.string.credman_confirmation_message_title,
|
||||
bundle.getCharSequence(
|
||||
CredentialManagerDialogFragment.APP_NAME_KEY));
|
||||
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(title)
|
||||
.setMessage(getContext().getString(R.string.credman_confirmation_message))
|
||||
.setPositiveButton(R.string.credman_confirmation_message_positive_button, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getDialogHost().onDialogClick(which);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation dialog fragment shows a dialog to the user to confirm that they would like to
|
||||
* enable the new provider.
|
||||
|
||||
@@ -273,8 +273,13 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
|
||||
@Override
|
||||
protected CharSequence getConfirmationMessage(CandidateInfo appInfo) {
|
||||
// If we are selecting none then show a warning label.
|
||||
if (appInfo == null) {
|
||||
return null;
|
||||
final String message =
|
||||
getContext()
|
||||
.getString(
|
||||
R.string.credman_confirmation_message);
|
||||
return Html.fromHtml(message);
|
||||
}
|
||||
final CharSequence appName = appInfo.loadLabel();
|
||||
final String message =
|
||||
|
||||
@@ -261,6 +261,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
int rotation = getApplicationContext().getDisplay().getRotation();
|
||||
final GlifLayout layout = (GlifLayout) getLayoutInflater().inflate(
|
||||
R.layout.udfps_enroll_enrolling, null, false);
|
||||
final UdfpsEnrollView udfpsEnrollView = layout.findViewById(R.id.udfps_animation_view);
|
||||
updateUdfpsEnrollView(udfpsEnrollView, props.get(0));
|
||||
switch (rotation) {
|
||||
case Surface.ROTATION_90:
|
||||
final View sudContent = layout.findViewById(R.id.sud_layout_content);
|
||||
@@ -282,66 +284,52 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
? 0 : (int) getResources().getDimension(
|
||||
R.dimen.rotation_90_enroll_padding_end), 0);
|
||||
layoutContainer.setLayoutParams(lp);
|
||||
if (FeatureFlagUtils.isEnabled(getApplicationContext(),
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
|
||||
final UdfpsEnrollView udfpsEnrollView = addUdfpsEnrollView(props.get(0));
|
||||
layout.addView(udfpsEnrollView);
|
||||
setOnHoverListener(true, layout, udfpsEnrollView);
|
||||
}
|
||||
|
||||
setOnHoverListener(true, layout, udfpsEnrollView);
|
||||
setContentView(layout, lp);
|
||||
break;
|
||||
|
||||
case Surface.ROTATION_0:
|
||||
case Surface.ROTATION_180:
|
||||
if (FeatureFlagUtils.isEnabled(getApplicationContext(),
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
|
||||
final UdfpsEnrollView udfpsEnrollView = addUdfpsEnrollView(props.get(0));
|
||||
// In the portrait mode, set layout_container's height 0, so it's
|
||||
// always shown at the bottom of the screen.
|
||||
// Add udfps enroll view into layout_container instead of
|
||||
// udfps_enroll_enrolling, so that when the content is too long to
|
||||
// make udfps_enroll_enrolling larger than the screen, udfps enroll
|
||||
// view could still be set to right position by setting bottom margin to
|
||||
// its parent view (layout_container) because it's always at the
|
||||
// bottom of the screen.
|
||||
final FrameLayout portraitLayoutContainer = layout.findViewById(
|
||||
R.id.layout_container);
|
||||
final ViewGroup.LayoutParams containerLp =
|
||||
portraitLayoutContainer.getLayoutParams();
|
||||
containerLp.height = 0;
|
||||
// In the portrait mode, layout_container's height is 0, so it's
|
||||
// always shown at the bottom of the screen.
|
||||
final FrameLayout portraitLayoutContainer = layout.findViewById(
|
||||
R.id.layout_container);
|
||||
|
||||
// In the portrait mode, the title and lottie animation view may
|
||||
// overlap when title needs three lines, so adding some paddings
|
||||
// between them, and adjusting the fp progress view here accordingly.
|
||||
final int layoutLottieAnimationPadding = (int) getResources()
|
||||
.getDimension(R.dimen.udfps_lottie_padding_top);
|
||||
portraitLayoutContainer.setPadding(0,
|
||||
layoutLottieAnimationPadding, 0, 0);
|
||||
final ImageView progressView = udfpsEnrollView.findViewById(
|
||||
R.id.udfps_enroll_animation_fp_progress_view);
|
||||
progressView.setPadding(0, -(layoutLottieAnimationPadding),
|
||||
0, layoutLottieAnimationPadding);
|
||||
final ImageView fingerprintView = udfpsEnrollView.findViewById(
|
||||
R.id.udfps_enroll_animation_fp_view);
|
||||
fingerprintView.setPadding(0, -layoutLottieAnimationPadding,
|
||||
0, layoutLottieAnimationPadding);
|
||||
// In the portrait mode, the title and lottie animation view may
|
||||
// overlap when title needs three lines, so adding some paddings
|
||||
// between them, and adjusting the fp progress view here accordingly.
|
||||
final int layoutLottieAnimationPadding = (int) getResources()
|
||||
.getDimension(R.dimen.udfps_lottie_padding_top);
|
||||
portraitLayoutContainer.setPadding(0,
|
||||
layoutLottieAnimationPadding, 0, 0);
|
||||
final ImageView progressView = udfpsEnrollView.findViewById(
|
||||
R.id.udfps_enroll_animation_fp_progress_view);
|
||||
progressView.setPadding(0, -(layoutLottieAnimationPadding),
|
||||
0, layoutLottieAnimationPadding);
|
||||
final ImageView fingerprintView = udfpsEnrollView.findViewById(
|
||||
R.id.udfps_enroll_animation_fp_view);
|
||||
fingerprintView.setPadding(0, -layoutLottieAnimationPadding,
|
||||
0, layoutLottieAnimationPadding);
|
||||
|
||||
portraitLayoutContainer.addView(udfpsEnrollView);
|
||||
setOnHoverListener(false, layout, udfpsEnrollView);
|
||||
}
|
||||
// TODO(b/260970216) Instead of hiding the description text view, we should
|
||||
// make the header view scrollable if the text is too long.
|
||||
// If description text view has overlap with udfps progress view, hide it.
|
||||
View view = layout.getDescriptionTextView();
|
||||
layout.getViewTreeObserver().addOnDrawListener(() -> {
|
||||
if (view.getVisibility() == View.VISIBLE
|
||||
&& hasOverlap(view, udfpsEnrollView)) {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
|
||||
setOnHoverListener(false, layout, udfpsEnrollView);
|
||||
setContentView(layout);
|
||||
break;
|
||||
|
||||
case Surface.ROTATION_270:
|
||||
default:
|
||||
if (FeatureFlagUtils.isEnabled(getApplicationContext(),
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS)) {
|
||||
final UdfpsEnrollView udfpsEnrollView = addUdfpsEnrollView(props.get(0));
|
||||
layout.addView(udfpsEnrollView);
|
||||
setOnHoverListener(true, layout, udfpsEnrollView);
|
||||
}
|
||||
|
||||
setOnHoverListener(true, layout, udfpsEnrollView);
|
||||
setContentView(layout);
|
||||
break;
|
||||
}
|
||||
@@ -1241,10 +1229,8 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
}
|
||||
}
|
||||
|
||||
private UdfpsEnrollView addUdfpsEnrollView(FingerprintSensorPropertiesInternal udfpsProps) {
|
||||
UdfpsEnrollView udfpsEnrollView = (UdfpsEnrollView) getLayoutInflater().inflate(
|
||||
R.layout.udfps_enroll_view, null, false);
|
||||
|
||||
private UdfpsEnrollView updateUdfpsEnrollView(UdfpsEnrollView udfpsEnrollView,
|
||||
FingerprintSensorPropertiesInternal udfpsProps) {
|
||||
DisplayInfo displayInfo = new DisplayInfo();
|
||||
getDisplay().getDisplayInfo(displayInfo);
|
||||
mScaleFactor = mUdfpsUtils.getScaleFactor(displayInfo);
|
||||
@@ -1311,6 +1297,24 @@ public class FingerprintEnrollEnrolling extends BiometricsEnrollEnrolling {
|
||||
: R.id.sud_layout_content).setOnHoverListener(onHoverListener);
|
||||
}
|
||||
|
||||
|
||||
@VisibleForTesting boolean hasOverlap(View view1, View view2) {
|
||||
int[] firstPosition = new int[2];
|
||||
int[] secondPosition = new int[2];
|
||||
|
||||
view1.getLocationOnScreen(firstPosition);
|
||||
view2.getLocationOnScreen(secondPosition);
|
||||
|
||||
// Rect constructor parameters: left, top, right, bottom
|
||||
Rect rectView1 = new Rect(firstPosition[0], firstPosition[1],
|
||||
firstPosition[0] + view1.getMeasuredWidth(),
|
||||
firstPosition[1] + view1.getMeasuredHeight());
|
||||
Rect rectView2 = new Rect(secondPosition[0], secondPosition[1],
|
||||
secondPosition[0] + view2.getMeasuredWidth(),
|
||||
secondPosition[1] + view2.getMeasuredHeight());
|
||||
return rectView1.intersect(rectView2);
|
||||
}
|
||||
|
||||
public static class IconTouchDialog extends InstrumentedDialogFragment {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -185,7 +185,8 @@ public class FingerprintSettings extends SubSettings {
|
||||
private static final int MSG_FINGER_AUTH_HELP = 1004;
|
||||
|
||||
private static final int CONFIRM_REQUEST = 101;
|
||||
private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
|
||||
@VisibleForTesting
|
||||
static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
|
||||
@VisibleForTesting
|
||||
static final int ADD_FINGERPRINT_REQUEST = 10;
|
||||
private static final int AUTO_ADD_FIRST_FINGERPRINT_REQUEST = 11;
|
||||
@@ -1014,7 +1015,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
true);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_REQUEST_GK_PW_HANDLE, true);
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, mUserId);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, true);
|
||||
startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,22 +161,20 @@ public class UdfpsEnrollView extends FrameLayout implements UdfpsEnrollHelper.Li
|
||||
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams();
|
||||
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
|
||||
parentView.getViewTreeObserver().addOnDrawListener(() -> {
|
||||
final int[] coords = parentView.getLocationOnScreen();
|
||||
final int parentLeft = coords[0];
|
||||
final int parentTop = coords[1];
|
||||
final int parentRight = parentLeft + parentView.getWidth();
|
||||
params.gravity = Gravity.RIGHT | Gravity.TOP;
|
||||
final int rightMargin = parentRight - rotatedBounds.right - getPaddingX();
|
||||
final int topMargin = rotatedBounds.top - parentTop - getPaddingY();
|
||||
if (marginLayoutParams.rightMargin == rightMargin
|
||||
&& marginLayoutParams.topMargin == topMargin) {
|
||||
return;
|
||||
}
|
||||
marginLayoutParams.rightMargin = rightMargin;
|
||||
marginLayoutParams.topMargin = topMargin;
|
||||
setLayoutParams(params);
|
||||
});
|
||||
final int[] coords = parentView.getLocationOnScreen();
|
||||
final int parentLeft = coords[0];
|
||||
final int parentTop = coords[1];
|
||||
final int parentRight = parentLeft + parentView.getWidth();
|
||||
params.gravity = Gravity.RIGHT | Gravity.TOP;
|
||||
final int rightMargin = parentRight - rotatedBounds.right - getPaddingX();
|
||||
final int topMargin = rotatedBounds.top - parentTop - getPaddingY();
|
||||
if (marginLayoutParams.rightMargin == rightMargin
|
||||
&& marginLayoutParams.topMargin == topMargin) {
|
||||
return;
|
||||
}
|
||||
marginLayoutParams.rightMargin = rightMargin;
|
||||
marginLayoutParams.topMargin = topMargin;
|
||||
setLayoutParams(params);
|
||||
} else {
|
||||
final int[] coords = parentView.getLocationOnScreen();
|
||||
final int parentLeft = coords[0];
|
||||
|
||||
@@ -57,7 +57,9 @@ import com.android.settingslib.widget.LayoutPreference;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -92,13 +94,12 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
@VisibleForTesting
|
||||
final Map<String, Bitmap> mIconCache;
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private Set<BluetoothDevice> mBluetoothDevices;
|
||||
@VisibleForTesting
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
@VisibleForTesting
|
||||
Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
@VisibleForTesting
|
||||
boolean mIsRegisterCallback = false;
|
||||
@VisibleForTesting
|
||||
boolean mIsLeftDeviceEstimateReady;
|
||||
@VisibleForTesting
|
||||
boolean mIsRightDeviceEstimateReady;
|
||||
@@ -141,23 +142,13 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
if (!isAvailable()) {
|
||||
return;
|
||||
}
|
||||
mIsRegisterCallback = true;
|
||||
mCachedDevice.registerCallback(this);
|
||||
mBluetoothAdapter.addOnMetadataChangedListener(mCachedDevice.getDevice(),
|
||||
mContext.getMainExecutor(), mMetadataListener);
|
||||
|
||||
registerBluetoothDevice();
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
if (!mIsRegisterCallback) {
|
||||
return;
|
||||
}
|
||||
mCachedDevice.unregisterCallback(this);
|
||||
mBluetoothAdapter.removeOnMetadataChangedListener(mCachedDevice.getDevice(),
|
||||
mMetadataListener);
|
||||
mIsRegisterCallback = false;
|
||||
unRegisterBluetoothDevice();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,6 +166,40 @@ public class AdvancedBluetoothDetailsHeaderController extends BasePreferenceCont
|
||||
mCachedDevice = cachedBluetoothDevice;
|
||||
}
|
||||
|
||||
private void registerBluetoothDevice() {
|
||||
if (mBluetoothDevices == null) {
|
||||
mBluetoothDevices = new HashSet<>();
|
||||
}
|
||||
mBluetoothDevices.clear();
|
||||
if (mCachedDevice.getDevice() != null) {
|
||||
mBluetoothDevices.add(mCachedDevice.getDevice());
|
||||
}
|
||||
mCachedDevice.getMemberDevice().forEach(cbd -> {
|
||||
if (cbd != null) {
|
||||
mBluetoothDevices.add(cbd.getDevice());
|
||||
}
|
||||
});
|
||||
if (mBluetoothDevices.isEmpty()) {
|
||||
Log.d(TAG, "No BT devcie to register.");
|
||||
return;
|
||||
}
|
||||
mCachedDevice.registerCallback(this);
|
||||
mBluetoothDevices.forEach(bd ->
|
||||
mBluetoothAdapter.addOnMetadataChangedListener(bd,
|
||||
mContext.getMainExecutor(), mMetadataListener));
|
||||
}
|
||||
|
||||
private void unRegisterBluetoothDevice() {
|
||||
if (mBluetoothDevices == null || mBluetoothDevices.isEmpty()) {
|
||||
Log.d(TAG, "No BT devcie to unregister.");
|
||||
return;
|
||||
}
|
||||
mCachedDevice.unregisterCallback(this);
|
||||
mBluetoothDevices.forEach(bd -> mBluetoothAdapter.removeOnMetadataChangedListener(bd,
|
||||
mMetadataListener));
|
||||
mBluetoothDevices.clear();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void refresh() {
|
||||
if (mLayoutPreference != null && mCachedDevice != null) {
|
||||
|
||||
@@ -120,6 +120,10 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll
|
||||
pref.setTitle(profile.getNameResource(mCachedDevice.getDevice()));
|
||||
pref.setOnPreferenceClickListener(this);
|
||||
pref.setOrder(profile.getOrdinal());
|
||||
|
||||
if (profile instanceof LeAudioProfile) {
|
||||
pref.setSummary(R.string.device_details_leaudio_toggle_summary);
|
||||
}
|
||||
return pref;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,10 +196,11 @@ public abstract class DeviceListPreferenceFragment extends
|
||||
}
|
||||
|
||||
// Prevent updates while the list shows one of the state messages
|
||||
if (mBluetoothAdapter.getState() != BluetoothAdapter.STATE_ON) return;
|
||||
if (mBluetoothAdapter.getState() != BluetoothAdapter.STATE_ON) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mLeScanFilters != null
|
||||
|| (mFilter != null && mFilter.matches(cachedDevice.getDevice()))) {
|
||||
if (mFilter != null && mFilter.matches(cachedDevice.getDevice())) {
|
||||
createDevicePreference(cachedDevice);
|
||||
}
|
||||
}
|
||||
@@ -325,7 +326,12 @@ public abstract class DeviceListPreferenceFragment extends
|
||||
if (cachedDevice == null) {
|
||||
cachedDevice = mCachedDeviceManager.addDevice(device);
|
||||
}
|
||||
onDeviceAdded(cachedDevice);
|
||||
// Only add device preference when it's not found in the map and there's no other
|
||||
// state message showing in the list
|
||||
if (mDevicePreferenceMap.get(cachedDevice) == null
|
||||
&& mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
|
||||
createDevicePreference(cachedDevice);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,6 +48,8 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
|
||||
|
||||
private final DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
private final GraphicsDriverSystemPropertiesWrapper mSystemProperties;
|
||||
|
||||
@VisibleForTesting
|
||||
static final String PROPERTY_RO_GFX_ANGLE_SUPPORTED = "ro.gfx.angle.supported";
|
||||
|
||||
@@ -57,11 +59,34 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
|
||||
@VisibleForTesting
|
||||
static final String ANGLE_DRIVER_SUFFIX = "angle";
|
||||
|
||||
@VisibleForTesting
|
||||
static class Injector {
|
||||
public GraphicsDriverSystemPropertiesWrapper createSystemPropertiesWrapper() {
|
||||
return new GraphicsDriverSystemPropertiesWrapper() {
|
||||
@Override
|
||||
public String get(String key, String def) {
|
||||
return SystemProperties.get(key, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(String key, String val) {
|
||||
SystemProperties.set(key, val);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public GraphicsDriverEnableAngleAsSystemDriverController(
|
||||
Context context, DevelopmentSettingsDashboardFragment fragment) {
|
||||
this(context, fragment, new Injector());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
GraphicsDriverEnableAngleAsSystemDriverController(
|
||||
Context context, DevelopmentSettingsDashboardFragment fragment, Injector injector) {
|
||||
super(context);
|
||||
mFragment = fragment;
|
||||
mSystemProperties = injector.createSystemPropertiesWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,20 +101,27 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
|
||||
// set "persist.graphics.egl" to "" if enableAngleAsSystemDriver is false
|
||||
GraphicsEnvironment.getInstance().toggleAngleAsSystemDriver(enableAngleAsSystemDriver);
|
||||
// pop up a window asking user to reboot to make the new "persist.graphics.egl" take effect
|
||||
showRebootDialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void showRebootDialog() {
|
||||
RebootConfirmationDialogFragment.show(
|
||||
mFragment, R.string.reboot_dialog_enable_angle_as_system_driver,
|
||||
R.string.cancel, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
// set switch on if "persist.graphics.egl" is "angle" and angle is built in /vendor
|
||||
// set switch off otherwise.
|
||||
final String currentGlesDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
final String currentGlesDriver =
|
||||
mSystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL, "");
|
||||
final boolean isAngle = TextUtils.equals(ANGLE_DRIVER_SUFFIX, currentGlesDriver);
|
||||
final boolean isAngleSupported =
|
||||
TextUtils.equals(SystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED), "true");
|
||||
final boolean isAngleSupported = TextUtils
|
||||
.equals(mSystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED, ""), "true");
|
||||
((SwitchPreference) mPreference).setChecked(isAngle && isAngleSupported);
|
||||
((SwitchPreference) mPreference).setEnabled(isAngleSupported);
|
||||
}
|
||||
@@ -98,8 +130,8 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
|
||||
protected void onDeveloperOptionsSwitchEnabled() {
|
||||
// only enable the switch if ro.gfx.angle.supported is true
|
||||
// we use ro.gfx.angle.supported to indicate if ANGLE libs are installed under /vendor
|
||||
final boolean isAngleSupported =
|
||||
TextUtils.equals(SystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED), "true");
|
||||
final boolean isAngleSupported = TextUtils
|
||||
.equals(mSystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED, ""), "true");
|
||||
((SwitchPreference) mPreference).setEnabled(isAngleSupported);
|
||||
}
|
||||
|
||||
@@ -116,7 +148,8 @@ public class GraphicsDriverEnableAngleAsSystemDriverController
|
||||
@Override
|
||||
public void onRebootCancelled() {
|
||||
// if user presses button "Cancel", do not reboot the device, and toggles switch back
|
||||
final String currentGlesDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
final String currentGlesDriver =
|
||||
mSystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL, "");
|
||||
if (TextUtils.equals(ANGLE_DRIVER_SUFFIX, currentGlesDriver)) {
|
||||
// if persist.graphics.egl = "angle", set the property value back to ""
|
||||
GraphicsEnvironment.getInstance().toggleAngleAsSystemDriver(false);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.development.graphicsdriver;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.os.SystemProperties;
|
||||
/**
|
||||
* Wrapper interface to access {@link SystemProperties}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
interface GraphicsDriverSystemPropertiesWrapper {
|
||||
/**
|
||||
* Get the String value for the given {@code key}.
|
||||
*
|
||||
* @param key the key to lookup
|
||||
* @param def the default value in case the property is not set or empty
|
||||
* @return if the {@code key} isn't found, return {@code def} if it isn't null, or an empty
|
||||
* string otherwise
|
||||
*/
|
||||
@NonNull
|
||||
String get(@NonNull String key, @Nullable String def);
|
||||
/**
|
||||
* Set the value for the given {@code key} to {@code val}.
|
||||
*
|
||||
* @throws IllegalArgumentException if the {@code val} exceeds 91 characters
|
||||
* @throws RuntimeException if the property cannot be set, for example, if it was blocked by
|
||||
* SELinux. libc will log the underlying reason.
|
||||
*/
|
||||
void set(@NonNull String key, @Nullable String val);
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.app.backup.BackupDataInputStream;
|
||||
import android.app.backup.BackupDataOutput;
|
||||
import android.app.backup.BackupHelper;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.os.IDeviceIdleController;
|
||||
@@ -34,9 +35,11 @@ import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -47,6 +50,8 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
/** An inditifier for {@link BackupHelper}. */
|
||||
public static final String TAG = "BatteryBackupHelper";
|
||||
private static final String DEVICE_IDLE_SERVICE = "deviceidle";
|
||||
private static final String BATTERY_OPTIMIZE_BACKUP_FILE_NAME =
|
||||
"battery_optimize_backup_historical_logs";
|
||||
|
||||
static final String DELIMITER = ",";
|
||||
static final String DELIMITER_MODE = ":";
|
||||
@@ -141,6 +146,7 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
int backupCount = 0;
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
|
||||
final SharedPreferences sharedPreferences = getSharedPreferences(mContext);
|
||||
// Converts application into the AppUsageState.
|
||||
for (ApplicationInfo info : applications) {
|
||||
final int mode = BatteryOptimizeUtils.getMode(appOps, info.uid, info.packageName);
|
||||
@@ -157,6 +163,9 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
info.packageName + DELIMITER_MODE + optimizationMode;
|
||||
builder.append(packageOptimizeMode + DELIMITER);
|
||||
Log.d(TAG, "backupOptimizationMode: " + packageOptimizeMode);
|
||||
BatteryHistoricalLogUtil.writeLog(
|
||||
sharedPreferences, Action.BACKUP, info.packageName,
|
||||
/* actionDescription */ "mode: " + optimizationMode);
|
||||
backupCount++;
|
||||
}
|
||||
|
||||
@@ -210,6 +219,18 @@ public final class BatteryBackupHelper implements BackupHelper {
|
||||
restoreCount, (System.currentTimeMillis() - timestamp)));
|
||||
}
|
||||
|
||||
/** Dump the app optimization mode backup history data. */
|
||||
public static void dumpHistoricalData(Context context, PrintWriter writer) {
|
||||
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(
|
||||
getSharedPreferences(context), writer);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static SharedPreferences getSharedPreferences(Context context) {
|
||||
return context.getSharedPreferences(
|
||||
BATTERY_OPTIMIZE_BACKUP_FILE_NAME, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
private void restoreOptimizationMode(
|
||||
String packageName, @BatteryOptimizeUtils.OptimizationMode int mode) {
|
||||
final int uid = BatteryUtils.getInstance(mContext).getPackageUid(packageName);
|
||||
|
||||
@@ -37,40 +37,40 @@ public final class BatteryHistoricalLogUtil {
|
||||
@VisibleForTesting
|
||||
static final int MAX_ENTRIES = 40;
|
||||
|
||||
/**
|
||||
* Writes a log entry.
|
||||
*
|
||||
* <p>Keeps up to {@link #MAX_ENTRIES} in the log, once that number is exceeded, it prunes the
|
||||
* oldest one.
|
||||
*/
|
||||
static void writeLog(Context context, Action action, String pkg, String actionDescription) {
|
||||
/** Writes a log entry for battery optimization mode. */
|
||||
static void writeLog(
|
||||
Context context, Action action, String packageName, String actionDescription) {
|
||||
writeLog(getSharedPreferences(context), action, packageName, actionDescription);
|
||||
}
|
||||
|
||||
static void writeLog(SharedPreferences sharedPreferences, Action action,
|
||||
String packageName, String actionDescription) {
|
||||
writeLog(
|
||||
context,
|
||||
sharedPreferences,
|
||||
BatteryOptimizeHistoricalLogEntry.newBuilder()
|
||||
.setPackageName(pkg)
|
||||
.setPackageName(packageName)
|
||||
.setAction(action)
|
||||
.setActionDescription(actionDescription)
|
||||
.setTimestamp(System.currentTimeMillis())
|
||||
.build());
|
||||
}
|
||||
|
||||
private static void writeLog(Context context, BatteryOptimizeHistoricalLogEntry logEntry) {
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
|
||||
private static void writeLog(
|
||||
SharedPreferences sharedPreferences, BatteryOptimizeHistoricalLogEntry logEntry) {
|
||||
BatteryOptimizeHistoricalLog existingLog =
|
||||
parseLogFromString(sharedPreferences.getString(LOGS_KEY, ""));
|
||||
BatteryOptimizeHistoricalLog.Builder newLogBuilder = existingLog.toBuilder();
|
||||
// Prune old entries
|
||||
// Prune old entries to limit the max logging data count.
|
||||
if (existingLog.getLogEntryCount() >= MAX_ENTRIES) {
|
||||
newLogBuilder.removeLogEntry(0);
|
||||
}
|
||||
newLogBuilder.addLogEntry(logEntry);
|
||||
|
||||
String loggingContent =
|
||||
Base64.encodeToString(newLogBuilder.build().toByteArray(), Base64.DEFAULT);
|
||||
sharedPreferences
|
||||
.edit()
|
||||
.putString(
|
||||
LOGS_KEY,
|
||||
Base64.encodeToString(newLogBuilder.build().toByteArray(), Base64.DEFAULT))
|
||||
.putString(LOGS_KEY, loggingContent)
|
||||
.apply();
|
||||
}
|
||||
|
||||
@@ -79,34 +79,36 @@ public final class BatteryHistoricalLogUtil {
|
||||
storedLogs, BatteryOptimizeHistoricalLog.getDefaultInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the historical log that has previously been stored by this utility.
|
||||
*/
|
||||
/** Prints the historical log that has previously been stored by this utility. */
|
||||
public static void printBatteryOptimizeHistoricalLog(Context context, PrintWriter writer) {
|
||||
printBatteryOptimizeHistoricalLog(getSharedPreferences(context), writer);
|
||||
}
|
||||
|
||||
/** Prints the historical log that has previously been stored by this utility. */
|
||||
public static void printBatteryOptimizeHistoricalLog(
|
||||
SharedPreferences sharedPreferences, PrintWriter writer) {
|
||||
writer.println("Battery optimize state history:");
|
||||
SharedPreferences sharedPreferences = getSharedPreferences(context);
|
||||
BatteryOptimizeHistoricalLog existingLog =
|
||||
parseLogFromString(sharedPreferences.getString(LOGS_KEY, ""));
|
||||
List<BatteryOptimizeHistoricalLogEntry> logEntryList = existingLog.getLogEntryList();
|
||||
if (logEntryList.isEmpty()) {
|
||||
writer.println("\tNo past logs.");
|
||||
writer.println("\tnothing to dump");
|
||||
} else {
|
||||
writer.println("0:RESTRICTED 1:UNRESTRICTED 2:OPTIMIZED 3:UNKNOWN");
|
||||
writer.println("0:UNKNOWN 1:RESTRICTED 2:UNRESTRICTED 3:OPTIMIZED");
|
||||
logEntryList.forEach(entry -> writer.println(toString(entry)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unique key for logging, combined with package name, delimiter and user id.
|
||||
*/
|
||||
static String getPackageNameWithUserId(String pkgName, int userId) {
|
||||
return pkgName + ":" + userId;
|
||||
/** Gets the unique key for logging. */
|
||||
static String getPackageNameWithUserId(String packageName, int userId) {
|
||||
return packageName + ":" + userId;
|
||||
}
|
||||
|
||||
private static String toString(BatteryOptimizeHistoricalLogEntry entry) {
|
||||
return String.format("%s\tAction:%s\tEvent:%s\tTimestamp:%s", entry.getPackageName(),
|
||||
entry.getAction(), entry.getActionDescription(),
|
||||
ConvertUtils.utcToLocalTimeForLogging(entry.getTimestamp()));
|
||||
return String.format("%s\t%s\taction:%s\tevent:%s",
|
||||
ConvertUtils.utcToLocalTimeForLogging(entry.getTimestamp()),
|
||||
entry.getPackageName(), entry.getAction(),
|
||||
entry.getActionDescription());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -299,9 +299,10 @@ public class BatteryInfo {
|
||||
(double) PowerUtil.convertUsToMs(info.remainingTimeUs), false /* withSeconds */,
|
||||
true /* collapseTimeUnit */);
|
||||
int resId = R.string.power_charging_duration;
|
||||
info.remainingLabel = context.getString(R.string.power_remaining_charging_duration_only,
|
||||
timeString);
|
||||
info.chargeLabel = context.getString(resId, info.batteryPercentString, timeString);
|
||||
info.remainingLabel = chargeTimeMs <= 0 ? null : context.getString(
|
||||
R.string.power_remaining_charging_duration_only, timeString);
|
||||
info.chargeLabel = chargeTimeMs <= 0 ? info.batteryPercentString
|
||||
: context.getString(resId, info.batteryPercentString, timeString);
|
||||
} else if (dockDefenderMode == BatteryUtils.DockDefenderMode.FUTURE_BYPASS) {
|
||||
// Dock defender will be triggered in the future, charging will be optimized.
|
||||
info.chargeLabel = context.getString(R.string.power_charging_future_paused,
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.content.Intent;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.euicc.EuiccManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
@@ -135,6 +134,7 @@ public class MobileNetworkSummaryController extends AbstractPreferenceController
|
||||
return mContext.getString(R.string.mobile_network_tap_to_activate, displayName);
|
||||
} else {
|
||||
return mSubInfoEntityList.stream()
|
||||
.sorted((e1, e2) -> Integer.compare(e1.simSlotIndex, e2.simSlotIndex))
|
||||
.map(SubscriptionInfoEntity::getUniqueDisplayName)
|
||||
.collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
@@ -59,8 +59,10 @@ public class PrivacyDashboardFragment extends DashboardFragment {
|
||||
SafetyCenterUtils.getEnterpriseOverrideStringForPrivacyEntries();
|
||||
for (int i = 0; i < privacyOverrideStrings.size(); i++) {
|
||||
EnterpriseOverrideString overrideString = privacyOverrideStrings.get(i);
|
||||
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(), overrideString.getResource());
|
||||
replaceEnterpriseStringTitle(
|
||||
overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(),
|
||||
overrideString.getResource());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +95,9 @@ public class PrivacyDashboardFragment extends DashboardFragment {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
if (SafetyCenterManagerWrapper.get().isEnabled(context)) {
|
||||
// NOTE: This check likely should be moved to the super method. This is done
|
||||
// here to avoid potentially undesired side effects for existing implementors.
|
||||
if (!isPageSearchEnabled(context)) {
|
||||
return null;
|
||||
}
|
||||
return super.getXmlResourcesToIndex(context, enabled);
|
||||
@@ -120,5 +124,10 @@ public class PrivacyDashboardFragment extends DashboardFragment {
|
||||
keys.add(KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return !SafetyCenterManagerWrapper.get().isEnabled(context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,21 +77,23 @@ public class MoreSecurityPrivacyFragment extends DashboardFragment {
|
||||
SafetyCenterUtils.getEnterpriseOverrideStringForPrivacyEntries();
|
||||
for (int i = 0; i < privacyOverrideStrings.size(); i++) {
|
||||
EnterpriseOverrideString overrideString = privacyOverrideStrings.get(i);
|
||||
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(), overrideString.getResource());
|
||||
replaceEnterpriseStringTitle(
|
||||
overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(),
|
||||
overrideString.getResource());
|
||||
}
|
||||
List<EnterpriseOverrideString> securityOverrideStrings =
|
||||
SafetyCenterUtils.getEnterpriseOverrideStringForSecurityEntries();
|
||||
for (int i = 0; i < securityOverrideStrings.size(); i++) {
|
||||
EnterpriseOverrideString overrideString = securityOverrideStrings.get(i);
|
||||
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(), overrideString.getResource());
|
||||
replaceEnterpriseStringTitle(
|
||||
overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(),
|
||||
overrideString.getResource());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see confirmPatternThenDisableAndClear
|
||||
*/
|
||||
/** see confirmPatternThenDisableAndClear */
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (use(TrustAgentListPreferenceController.class)
|
||||
@@ -117,10 +119,8 @@ public class MoreSecurityPrivacyFragment extends DashboardFragment {
|
||||
controllers.addAll(
|
||||
SafetyCenterUtils.getControllersForAdvancedSecurity(context, lifecycle, host));
|
||||
return controllers;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.more_security_privacy_settings) {
|
||||
/**
|
||||
@@ -130,7 +130,9 @@ public class MoreSecurityPrivacyFragment extends DashboardFragment {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
if (!SafetyCenterManagerWrapper.get().isEnabled(context)) {
|
||||
// NOTE: This check likely should be moved to the super method. This is done
|
||||
// here to avoid potentially undesired side effects for existing implementors.
|
||||
if (!isPageSearchEnabled(context)) {
|
||||
return null;
|
||||
}
|
||||
return super.getXmlResourcesToIndex(context, enabled);
|
||||
@@ -157,5 +159,10 @@ public class MoreSecurityPrivacyFragment extends DashboardFragment {
|
||||
keys.add(KEY_NOTIFICATION_WORK_PROFILE_NOTIFICATIONS);
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return SafetyCenterManagerWrapper.get().isEnabled(context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -58,8 +58,10 @@ public class SecurityAdvancedSettings extends DashboardFragment {
|
||||
SafetyCenterUtils.getEnterpriseOverrideStringForSecurityEntries();
|
||||
for (int i = 0; i < securityOverrideStrings.size(); i++) {
|
||||
EnterpriseOverrideString overrideString = securityOverrideStrings.get(i);
|
||||
replaceEnterpriseStringTitle(overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(), overrideString.getResource());
|
||||
replaceEnterpriseStringTitle(
|
||||
overrideString.getPreferenceKey(),
|
||||
overrideString.getOverrideKey(),
|
||||
overrideString.getResource());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +79,7 @@ public class SecurityAdvancedSettings extends DashboardFragment {
|
||||
return CategoryKey.CATEGORY_SECURITY_ADVANCED_SETTINGS;
|
||||
} else {
|
||||
final SecuritySettingsFeatureProvider securitySettingsFeatureProvider =
|
||||
FeatureFactory.getFactory(context)
|
||||
.getSecuritySettingsFeatureProvider();
|
||||
FeatureFactory.getFactory(context).getSecuritySettingsFeatureProvider();
|
||||
|
||||
if (securitySettingsFeatureProvider.hasAlternativeSecuritySettingsFragment()) {
|
||||
return securitySettingsFeatureProvider.getAlternativeAdvancedSettingsCategoryKey();
|
||||
@@ -103,9 +104,7 @@ public class SecurityAdvancedSettings extends DashboardFragment {
|
||||
return buildPreferenceControllers(context, getSettingsLifecycle(), this /* host*/);
|
||||
}
|
||||
|
||||
/**
|
||||
* see confirmPatternThenDisableAndClear
|
||||
*/
|
||||
/** see confirmPatternThenDisableAndClear */
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (use(TrustAgentListPreferenceController.class)
|
||||
@@ -119,14 +118,12 @@ public class SecurityAdvancedSettings extends DashboardFragment {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,
|
||||
Lifecycle lifecycle, DashboardFragment host) {
|
||||
private static List<AbstractPreferenceController> buildPreferenceControllers(
|
||||
Context context, Lifecycle lifecycle, DashboardFragment host) {
|
||||
return SafetyCenterUtils.getControllersForAdvancedSecurity(context, lifecycle, host);
|
||||
}
|
||||
|
||||
/**
|
||||
* For Search. Please keep it in sync when updating "createPreferenceHierarchy()"
|
||||
*/
|
||||
/** For Search. Please keep it in sync when updating "createPreferenceHierarchy()" */
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider(R.xml.security_advanced_settings) {
|
||||
/**
|
||||
@@ -134,19 +131,26 @@ public class SecurityAdvancedSettings extends DashboardFragment {
|
||||
* page, and we don't want to index these entries.
|
||||
*/
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||
boolean enabled) {
|
||||
if (SafetyCenterManagerWrapper.get().isEnabled(context)) {
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
// NOTE: This check likely should be moved to the super method. This is done
|
||||
// here to avoid potentially undesired side effects for existing implementors.
|
||||
if (!isPageSearchEnabled(context)) {
|
||||
return null;
|
||||
}
|
||||
return super.getXmlResourcesToIndex(context, enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(Context
|
||||
context) {
|
||||
return buildPreferenceControllers(context, null /* lifecycle */,
|
||||
null /* host*/);
|
||||
public List<AbstractPreferenceController> createPreferenceControllers(
|
||||
Context context) {
|
||||
return buildPreferenceControllers(
|
||||
context, null /* lifecycle */, null /* host*/);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return !SafetyCenterManagerWrapper.get().isEnabled(context);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -83,6 +82,7 @@ import com.android.settingslib.RestrictedPreference;
|
||||
import com.android.settingslib.drawable.CircleFramedDrawable;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
import com.android.settingslib.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.users.CreateUserDialogController;
|
||||
import com.android.settingslib.users.EditUserInfoController;
|
||||
import com.android.settingslib.users.GrantAdminDialogController;
|
||||
import com.android.settingslib.users.UserCreatingDialog;
|
||||
@@ -119,6 +119,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
/** UserId of the user being removed */
|
||||
private static final String SAVE_REMOVING_USER = "removing_user";
|
||||
private static final String SAVE_CREATE_USER = "create_user";
|
||||
|
||||
private static final String KEY_USER_LIST = "user_list";
|
||||
private static final String KEY_USER_ME = "user_me";
|
||||
@@ -171,9 +172,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
static final int RESULT_GUEST_REMOVED = 100;
|
||||
|
||||
private static final String KEY_ADD_USER_LONG_MESSAGE_DISPLAYED =
|
||||
"key_add_user_long_message_displayed";
|
||||
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_SUMMARY = "summary";
|
||||
|
||||
@@ -222,6 +220,8 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
new GrantAdminDialogController();
|
||||
private EditUserInfoController mEditUserInfoController =
|
||||
new EditUserInfoController(Utils.FILE_PROVIDER_AUTHORITY);
|
||||
private CreateUserDialogController mCreateUserDialogController =
|
||||
new CreateUserDialogController(Utils.FILE_PROVIDER_AUTHORITY);
|
||||
private AddUserWhenLockedPreferenceController mAddUserWhenLockedPreferenceController;
|
||||
private GuestTelephonyPreferenceController mGuestTelephonyPreferenceController;
|
||||
private RemoveGuestOnExitPreferenceController mRemoveGuestOnExitPreferenceController;
|
||||
@@ -233,7 +233,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
private CharSequence mPendingUserName;
|
||||
private Drawable mPendingUserIcon;
|
||||
private boolean mGrantAdmin;
|
||||
private boolean mPendingUserIsAdmin;
|
||||
|
||||
// A place to cache the generated default avatar
|
||||
private Drawable mDefaultIconDrawable;
|
||||
@@ -348,7 +348,11 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
if (icicle.containsKey(SAVE_REMOVING_USER)) {
|
||||
mRemovingUserId = icicle.getInt(SAVE_REMOVING_USER);
|
||||
}
|
||||
mEditUserInfoController.onRestoreInstanceState(icicle);
|
||||
if (icicle.containsKey(SAVE_CREATE_USER)) {
|
||||
mCreateUserDialogController.onRestoreInstanceState(icicle);
|
||||
} else {
|
||||
mEditUserInfoController.onRestoreInstanceState(icicle);
|
||||
}
|
||||
}
|
||||
|
||||
mUserCaps = UserCapabilities.create(activity);
|
||||
@@ -440,7 +444,12 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
mEditUserInfoController.onSaveInstanceState(outState);
|
||||
if (mCreateUserDialogController.isActive()) {
|
||||
outState.putBoolean(SAVE_CREATE_USER, mCreateUserDialogController.isActive());
|
||||
mCreateUserDialogController.onSaveInstanceState(outState);
|
||||
} else {
|
||||
mEditUserInfoController.onSaveInstanceState(outState);
|
||||
}
|
||||
outState.putInt(SAVE_REMOVING_USER, mRemovingUserId);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
@@ -448,6 +457,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public void startActivityForResult(Intent intent, int requestCode) {
|
||||
mEditUserInfoController.startingActivityForResult();
|
||||
mCreateUserDialogController.startingActivityForResult();
|
||||
super.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
@@ -562,6 +572,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
&& resultCode == RESULT_GUEST_REMOVED) {
|
||||
scheduleGuestCreation();
|
||||
} else {
|
||||
mCreateUserDialogController.onActivityResult(requestCode, resultCode, data);
|
||||
mEditUserInfoController.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
@@ -704,37 +715,12 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.create();
|
||||
case DIALOG_ADD_USER: {
|
||||
final SharedPreferences preferences = getActivity().getPreferences(
|
||||
Context.MODE_PRIVATE);
|
||||
final boolean longMessageDisplayed = preferences.getBoolean(
|
||||
KEY_ADD_USER_LONG_MESSAGE_DISPLAYED, false);
|
||||
final int messageResId = longMessageDisplayed
|
||||
? com.android.settingslib.R.string.user_add_user_message_short
|
||||
: com.android.settingslib.R.string.user_add_user_message_long;
|
||||
Dialog dlg = new AlertDialog.Builder(context)
|
||||
.setTitle(com.android.settingslib.R.string.user_add_user_title)
|
||||
.setMessage(messageResId)
|
||||
.setPositiveButton(android.R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (!longMessageDisplayed) {
|
||||
preferences.edit().putBoolean(
|
||||
KEY_ADD_USER_LONG_MESSAGE_DISPLAYED,
|
||||
true).apply();
|
||||
}
|
||||
if (UserManager.isMultipleAdminEnabled()) {
|
||||
showDialog(DIALOG_GRANT_ADMIN);
|
||||
} else {
|
||||
showDialog(DIALOG_USER_PROFILE_EDITOR_ADD_USER);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create();
|
||||
return dlg;
|
||||
}
|
||||
case DIALOG_GRANT_ADMIN: {
|
||||
return buildGrantAdminDialog();
|
||||
synchronized (mUserLock) {
|
||||
mPendingUserName = getString(
|
||||
com.android.settingslib.R.string.user_new_user_name);
|
||||
mPendingUserIcon = null;
|
||||
}
|
||||
return buildAddUserDialog(USER_TYPE_USER);
|
||||
}
|
||||
case DIALOG_CHOOSE_USER_TYPE: {
|
||||
List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();
|
||||
@@ -919,17 +905,14 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
private Dialog buildAddUserDialog(int userType) {
|
||||
Dialog d;
|
||||
synchronized (mUserLock) {
|
||||
d = mEditUserInfoController.createDialog(
|
||||
d = mCreateUserDialogController.createDialog(
|
||||
getActivity(),
|
||||
this::startActivityForResult,
|
||||
null,
|
||||
mPendingUserName.toString(),
|
||||
getString(userType == USER_TYPE_USER
|
||||
? com.android.settingslib.R.string.user_info_settings_title
|
||||
: com.android.settingslib.R.string.profile_info_settings_title),
|
||||
(userName, userIcon) -> {
|
||||
UserManager.isMultipleAdminEnabled(),
|
||||
(userName, userIcon, isAdmin) -> {
|
||||
mPendingUserIcon = userIcon;
|
||||
mPendingUserName = userName;
|
||||
mPendingUserIsAdmin = isAdmin;
|
||||
addUserNow(userType);
|
||||
},
|
||||
() -> {
|
||||
@@ -943,26 +926,6 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
return d;
|
||||
}
|
||||
|
||||
private Dialog buildGrantAdminDialog() {
|
||||
return mGrantAdminDialogController.createDialog(
|
||||
getActivity(),
|
||||
(grantAdmin) -> {
|
||||
mGrantAdmin = grantAdmin;
|
||||
if (mGrantAdmin) {
|
||||
mMetricsFeatureProvider.action(getActivity(),
|
||||
SettingsEnums.ACTION_GRANT_ADMIN_FROM_SETTINGS_CREATION_DIALOG);
|
||||
} else {
|
||||
mMetricsFeatureProvider.action(getActivity(),
|
||||
SettingsEnums.ACTION_NOT_GRANT_ADMIN_FROM_SETTINGS_CREATION_DIALOG);
|
||||
}
|
||||
showDialog(DIALOG_USER_PROFILE_EDITOR_ADD_USER);
|
||||
},
|
||||
() -> {
|
||||
mGrantAdmin = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
@@ -1065,7 +1028,7 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
userName,
|
||||
mUserManager.USER_TYPE_FULL_SECONDARY,
|
||||
0);
|
||||
if (mGrantAdmin) {
|
||||
if (mPendingUserIsAdmin) {
|
||||
mUserManager.setUserAdmin(user.id);
|
||||
}
|
||||
} else {
|
||||
@@ -1665,6 +1628,9 @@ public class UserSettings extends SettingsPreferenceFragment
|
||||
synchronized (mUserLock) {
|
||||
mRemovingUserId = -1;
|
||||
updateUserList();
|
||||
if (mCreateUserDialogController.isActive()) {
|
||||
mCreateUserDialogController.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ import androidx.preference.PreferenceGroup;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.core.FeatureFlags;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.wifi.repository.WifiHotspotRepository;
|
||||
import com.android.settings.wifi.tether.WifiTetherAutoOffPreferenceController;
|
||||
import com.android.settings.wifi.tether.WifiTetherSecurityPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -94,6 +96,8 @@ public class AllInOneTetherSettingsTest {
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(FakeFeatureFactory.setupForTest().getWifiFeatureProvider().getWifiHotspotRepository())
|
||||
.thenReturn(mock(WifiHotspotRepository.class));
|
||||
doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class);
|
||||
doReturn(mConnectivityManager)
|
||||
.when(mContext).getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
@@ -19,20 +19,26 @@ package com.android.settings.accessibility;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.Shadows;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class FlashNotificationsPreviewPreferenceTest {
|
||||
@@ -41,37 +47,46 @@ public class FlashNotificationsPreviewPreferenceTest {
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
private final AttributeSet mAttributeSet = Robolectric.buildAttributeSet().build();
|
||||
private FlashNotificationsPreviewPreference mFlashNotificationsPreviewPreference;
|
||||
private PreferenceViewHolder mPreferenceViewHolder;
|
||||
|
||||
@Test
|
||||
public void constructor_assertLayoutResource_P00() {
|
||||
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
|
||||
mContext);
|
||||
assertThat(preference.getLayoutResource())
|
||||
.isEqualTo(R.layout.flash_notification_preview_preference);
|
||||
@Before
|
||||
public void setUp() {
|
||||
mPreferenceViewHolder = PreferenceViewHolder.createInstanceForTests(
|
||||
LayoutInflater.from(mContext).inflate(
|
||||
R.layout.flash_notification_preview_preference, null));
|
||||
mFlashNotificationsPreviewPreference = new FlashNotificationsPreviewPreference(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructor_assertLayoutResource_P01() {
|
||||
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
|
||||
mContext, mAttributeSet);
|
||||
assertThat(preference.getLayoutResource())
|
||||
.isEqualTo(R.layout.flash_notification_preview_preference);
|
||||
public void setEnabled_true_verifyEnabledUi() {
|
||||
@ColorInt final int textColorEnabled = ((TextView) mPreferenceViewHolder.findViewById(
|
||||
android.R.id.title)).getCurrentTextColor();
|
||||
|
||||
mFlashNotificationsPreviewPreference.setEnabled(true);
|
||||
mFlashNotificationsPreviewPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final View frame = mPreferenceViewHolder.findViewById(R.id.frame);
|
||||
final int backgroundResId = Shadows.shadowOf(frame.getBackground()).getCreatedFromResId();
|
||||
assertThat(backgroundResId).isEqualTo(R.drawable.settingslib_switch_bar_bg_on);
|
||||
final TextView title = (TextView) mPreferenceViewHolder.findViewById(android.R.id.title);
|
||||
assertThat(title.getAlpha()).isEqualTo(1f);
|
||||
assertThat(title.getCurrentTextColor()).isEqualTo(textColorEnabled);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructor_assertLayoutResource_P02() {
|
||||
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
|
||||
mContext, mAttributeSet, 0);
|
||||
assertThat(preference.getLayoutResource())
|
||||
.isEqualTo(R.layout.flash_notification_preview_preference);
|
||||
}
|
||||
public void setEnabled_false_verifyDisabledUi() {
|
||||
@ColorInt final int textColorDisabled = Utils.getColorAttrDefaultColor(mContext,
|
||||
android.R.attr.textColorPrimary);
|
||||
|
||||
@Test
|
||||
public void constructor_assertLayoutResource_P03() {
|
||||
FlashNotificationsPreviewPreference preference = new FlashNotificationsPreviewPreference(
|
||||
mContext, mAttributeSet, 0, 0);
|
||||
assertThat(preference.getLayoutResource())
|
||||
.isEqualTo(R.layout.flash_notification_preview_preference);
|
||||
mFlashNotificationsPreviewPreference.setEnabled(false);
|
||||
mFlashNotificationsPreviewPreference.onBindViewHolder(mPreferenceViewHolder);
|
||||
|
||||
final View frame = mPreferenceViewHolder.findViewById(R.id.frame);
|
||||
final int backgroundResId = Shadows.shadowOf(frame.getBackground()).getCreatedFromResId();
|
||||
assertThat(backgroundResId).isEqualTo(R.drawable.switch_bar_bg_disabled);
|
||||
final TextView title = (TextView) mPreferenceViewHolder.findViewById(android.R.id.title);
|
||||
assertThat(title.getAlpha()).isEqualTo(0.38f);
|
||||
assertThat(title.getCurrentTextColor()).isEqualTo(textColorDisabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,6 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.Vibrator;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.view.Display;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
@@ -203,8 +202,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_showOverlayPortrait() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
|
||||
|
||||
@@ -216,8 +213,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_showOverlayLandscape() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
|
||||
|
||||
@@ -229,8 +224,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_usesCorrectProgressBarFillColor() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
final TypedArray ta = mActivity.obtainStyledAttributes(null,
|
||||
R.styleable.BiometricsEnrollView, R.attr.biometricsEnrollStyle,
|
||||
@@ -250,9 +243,7 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_checkViewOverlapPortrait() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_90);
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
final GlifLayout defaultLayout = mActivity.findViewById(R.id.setup_wizard_layout);
|
||||
@@ -294,9 +285,9 @@ public class FingerprintEnrollEnrollingTest {
|
||||
udfpsEnrollView.getViewTreeObserver().addOnDrawListener(() -> {
|
||||
udfpsEnrollView.getLocationOnScreen(udfpsEnrollViewPosition);
|
||||
rectUdfpsEnrollView.set(new Rect(udfpsEnrollViewPosition[0],
|
||||
udfpsEnrollViewPosition[1], udfpsEnrollViewPosition[0]
|
||||
+ udfpsEnrollView.getWidth(), udfpsEnrollViewPosition[1]
|
||||
+ udfpsEnrollView.getHeight()));
|
||||
udfpsEnrollViewPosition[1], udfpsEnrollViewPosition[0]
|
||||
+ udfpsEnrollView.getWidth(), udfpsEnrollViewPosition[1]
|
||||
+ udfpsEnrollView.getHeight()));
|
||||
});
|
||||
|
||||
lottieAnimationContainer.getViewTreeObserver().addOnDrawListener(() -> {
|
||||
@@ -320,10 +311,36 @@ public class FingerprintEnrollEnrollingTest {
|
||||
.intersect(rectUdfpsEnrollView.get())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_descriptionViewGoneWithOverlap() {
|
||||
initializeActivityWithoutCreate(TYPE_UDFPS_OPTICAL);
|
||||
doReturn(true).when(mActivity).hasOverlap(any(), any());
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
|
||||
createActivity();
|
||||
|
||||
final GlifLayout defaultLayout = spy(mActivity.findViewById(R.id.setup_wizard_layout));
|
||||
final TextView descriptionTextView = defaultLayout.getDescriptionTextView();
|
||||
|
||||
defaultLayout.getViewTreeObserver().dispatchOnDraw();
|
||||
assertThat(descriptionTextView.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fingerprintUdfpsOverlayEnrollment_descriptionViewVisibleWithoutOverlap() {
|
||||
initializeActivityWithoutCreate(TYPE_UDFPS_OPTICAL);
|
||||
doReturn(false).when(mActivity).hasOverlap(any(), any());
|
||||
when(mMockDisplay.getRotation()).thenReturn(Surface.ROTATION_0);
|
||||
createActivity();
|
||||
|
||||
final GlifLayout defaultLayout = spy(mActivity.findViewById(R.id.setup_wizard_layout));
|
||||
final TextView descriptionTextView = defaultLayout.getDescriptionTextView();
|
||||
|
||||
defaultLayout.getViewTreeObserver().dispatchOnDraw();
|
||||
assertThat(descriptionTextView.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forwardEnrollProgressEvents() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
EnrollListener listener = new EnrollListener(mActivity);
|
||||
@@ -337,8 +354,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void forwardEnrollHelpEvents() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
EnrollListener listener = new EnrollListener(mActivity);
|
||||
@@ -352,8 +367,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void forwardEnrollAcquiredEvents() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
EnrollListener listener = new EnrollListener(mActivity);
|
||||
@@ -368,8 +381,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void forwardEnrollPointerDownEvents() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
EnrollListener listener = new EnrollListener(mActivity);
|
||||
@@ -383,8 +394,6 @@ public class FingerprintEnrollEnrollingTest {
|
||||
|
||||
@Test
|
||||
public void forwardEnrollPointerUpEvents() {
|
||||
FeatureFlagUtils.setEnabled(mContext,
|
||||
FeatureFlagUtils.SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, true);
|
||||
initializeActivityFor(TYPE_UDFPS_OPTICAL);
|
||||
|
||||
EnrollListener listener = new EnrollListener(mActivity);
|
||||
|
||||
@@ -20,8 +20,11 @@ import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFP
|
||||
|
||||
import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment;
|
||||
import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.ADD_FINGERPRINT_REQUEST;
|
||||
import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.CHOOSE_LOCK_GENERIC_REQUEST;
|
||||
import static com.android.settings.biometrics.fingerprint.FingerprintSettings.FingerprintSettingsFragment.KEY_FINGERPRINT_ADD;
|
||||
|
||||
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.anyString;
|
||||
@@ -54,6 +57,7 @@ import com.android.settings.biometrics.BiometricsSplitScreenDialog;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowLockPatternUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
@@ -63,6 +67,7 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -74,7 +79,7 @@ import java.util.ArrayList;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowSettingsPreferenceFragment.class, ShadowUtils.class, ShadowFragment.class,
|
||||
ShadowUserManager.class})
|
||||
ShadowUserManager.class, ShadowLockPatternUtils.class})
|
||||
public class FingerprintSettingsFragmentTest {
|
||||
private FingerprintSettingsFragment mFragment;
|
||||
private Context mContext;
|
||||
@@ -92,10 +97,62 @@ public class FingerprintSettingsFragmentTest {
|
||||
doReturn(true).when(mFingerprintManager).isHardwareDetected();
|
||||
ShadowUtils.setFingerprintManager(mFingerprintManager);
|
||||
FakeFeatureFactory.setupForTest();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFingerprint_inFullScreen_noDialog() {
|
||||
setUpFragment(false);
|
||||
// Click "Add Fingerprint"
|
||||
final Preference preference = new Preference(mContext);
|
||||
preference.setKey(KEY_FINGERPRINT_ADD);
|
||||
mFragment.onPreferenceTreeClick(preference);
|
||||
|
||||
verify(mFragment).startActivityForResult(any(), eq(ADD_FINGERPRINT_REQUEST));
|
||||
verify(mFragmentTransaction, never()).add(any(),
|
||||
eq(BiometricsSplitScreenDialog.class.getName()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFingerprint_inMultiWindow_showsDialog() {
|
||||
setUpFragment(false);
|
||||
|
||||
doReturn(true).when(mActivity).isInMultiWindowMode();
|
||||
|
||||
// Click "Add Fingerprint"
|
||||
final Preference preference = new Preference(mContext);
|
||||
preference.setKey(KEY_FINGERPRINT_ADD);
|
||||
mFragment.onPreferenceTreeClick(preference);
|
||||
|
||||
verify(mFragment, times(0)).startActivityForResult(any(), eq(ADD_FINGERPRINT_REQUEST));
|
||||
verify(mFragmentTransaction).add(any(), eq(BiometricsSplitScreenDialog.class.getName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChooseLockKeyForFingerprint() {
|
||||
setUpFragment(true);
|
||||
ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(
|
||||
Intent.class);
|
||||
verify(mFragment).startActivityForResult(intentArgumentCaptor.capture(),
|
||||
eq(CHOOSE_LOCK_GENERIC_REQUEST));
|
||||
|
||||
Intent intent = intentArgumentCaptor.getValue();
|
||||
assertThat(intent.getBooleanExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
|
||||
false)).isTrue();
|
||||
}
|
||||
|
||||
private void setUpFragment(boolean showChooseLock) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, 1L);
|
||||
if (!showChooseLock) {
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, new byte[0]);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, 1L);
|
||||
}
|
||||
|
||||
mActivity = spy(Robolectric.buildActivity(FragmentActivity.class, intent).get());
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
|
||||
@@ -112,49 +169,12 @@ public class FingerprintSettingsFragmentTest {
|
||||
doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt());
|
||||
|
||||
setSensor();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowUtils.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFingerprint_inFullScreen_noDialog() {
|
||||
// Start fragment
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(null);
|
||||
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
|
||||
mFragment.onResume();
|
||||
|
||||
// Click "Add Fingerprint"
|
||||
final Preference preference = new Preference(mContext);
|
||||
preference.setKey(KEY_FINGERPRINT_ADD);
|
||||
mFragment.onPreferenceTreeClick(preference);
|
||||
|
||||
verify(mFragment).startActivityForResult(any(), eq(ADD_FINGERPRINT_REQUEST));
|
||||
verify(mFragmentTransaction, never()).add(any(),
|
||||
eq(BiometricsSplitScreenDialog.class.getName()));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddFingerprint_inMultiWindow_showsDialog() {
|
||||
// Start fragment
|
||||
mFragment.onAttach(mContext);
|
||||
mFragment.onCreate(null);
|
||||
mFragment.onCreateView(LayoutInflater.from(mContext), mock(ViewGroup.class), Bundle.EMPTY);
|
||||
mFragment.onResume();
|
||||
|
||||
doReturn(true).when(mActivity).isInMultiWindowMode();
|
||||
|
||||
// Click "Add Fingerprint"
|
||||
final Preference preference = new Preference(mContext);
|
||||
preference.setKey(KEY_FINGERPRINT_ADD);
|
||||
mFragment.onPreferenceTreeClick(preference);
|
||||
|
||||
verify(mFragment, times(0)).startActivityForResult(any(), eq(ADD_FINGERPRINT_REQUEST));
|
||||
verify(mFragmentTransaction).add(any(), eq(BiometricsSplitScreenDialog.class.getName()));
|
||||
}
|
||||
|
||||
private void setSensor() {
|
||||
|
||||
@@ -56,6 +56,9 @@ import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowEntityHeaderController.class, ShadowDeviceConfig.class})
|
||||
public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
@@ -380,40 +383,68 @@ public class AdvancedBluetoothDetailsHeaderControllerTest {
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
Set<CachedBluetoothDevice> cacheBluetoothDevices = new HashSet<>();
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(cacheBluetoothDevices);
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice).registerCallback(mController);
|
||||
verify(mBluetoothAdapter).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_isRegisterCallback_unregisterCallback() {
|
||||
mController.mIsRegisterCallback = true;
|
||||
|
||||
mController.onStop();
|
||||
|
||||
verify(mBluetoothAdapter).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStart_notAvailable_registerCallback() {
|
||||
public void onStart_notAvailable_notNeedToRegisterCallback() {
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("false".getBytes());
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice, never()).registerCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_notRegisterCallback_unregisterCallback() {
|
||||
mController.mIsRegisterCallback = false;
|
||||
public void onStart_isAvailableButNoBluetoothDevice_notNeedToRegisterCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
when(mCachedDevice.getDevice()).thenReturn(null);
|
||||
Set<CachedBluetoothDevice> cacheBluetoothDevices = new HashSet<>();
|
||||
when(mCachedDevice.getMemberDevice()).thenReturn(cacheBluetoothDevices);
|
||||
|
||||
mController.onStart();
|
||||
|
||||
verify(mCachedDevice, never()).registerCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(mBluetoothDevice,
|
||||
mContext.getMainExecutor(), mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_availableAndHasBluetoothDevice_unregisterCallback() {
|
||||
onStart_isAvailable_registerCallback();
|
||||
|
||||
mController.onStop();
|
||||
|
||||
verify(mCachedDevice).unregisterCallback(mController);
|
||||
verify(mBluetoothAdapter).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStop_noBluetoothDevice_noNeedToUnregisterCallback() {
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_SETTINGS_UI,
|
||||
SettingsUIDeviceConfig.BT_ADVANCED_HEADER_ENABLED, "true", true);
|
||||
when(mBluetoothDevice.getMetadata(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET))
|
||||
.thenReturn("true".getBytes());
|
||||
when(mCachedDevice.getDevice()).thenReturn(null);
|
||||
|
||||
mController.onStart();
|
||||
mController.onStop();
|
||||
|
||||
verify(mCachedDevice, never()).unregisterCallback(mController);
|
||||
verify(mBluetoothAdapter, never()).removeOnMetadataChangedListener(mBluetoothDevice,
|
||||
mController.mMetadataListener);
|
||||
}
|
||||
|
||||
@@ -81,9 +81,10 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerTest {
|
||||
// since GraphicsEnvironment is mocked in Robolectric test environment,
|
||||
// we will override the system property persist.graphics.egl as if it is changed by
|
||||
// mGraphicsEnvironment.toggleAngleAsSystemDriver(true).
|
||||
// TODO: b/270994705 yuxinhu:
|
||||
// add test coverage to test mGraphicsEnvironment.toggleAngleAsSystemDriver()
|
||||
// works properly on Android devices / emulators.
|
||||
|
||||
// for test that actually verifies mGraphicsEnvironment.toggleAngleAsSystemDriver(true)
|
||||
// on a device/emulator, please refer to
|
||||
// GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest
|
||||
ShadowSystemProperties.override(PROPERTY_PERSISTENT_GRAPHICS_EGL, ANGLE_DRIVER_SUFFIX);
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
@@ -97,9 +98,10 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerTest {
|
||||
// since GraphicsEnvironment is mocked in Robolectric test environment,
|
||||
// we will override the system property persist.graphics.egl as if it is changed by
|
||||
// mGraphicsEnvironment.toggleAngleAsSystemDriver(false).
|
||||
// TODO: b/270994705 yuxinhu:
|
||||
// add test coverage to test mGraphicsEnvironment.toggleAngleAsSystemDriver()
|
||||
// works properly on Android devices / emulators.
|
||||
|
||||
// for test that actually verifies mGraphicsEnvironment.toggleAngleAsSystemDriver(true)
|
||||
// on a device/emulator, please refer to
|
||||
// GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest
|
||||
ShadowSystemProperties.override(PROPERTY_PERSISTENT_GRAPHICS_EGL, "");
|
||||
mController.onPreferenceChange(mPreference, false);
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
@@ -124,20 +126,14 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerTest {
|
||||
@Test
|
||||
public void updateState_angleSupported_angleUsed_preferenceShouldBeChecked() {
|
||||
ShadowSystemProperties.override(PROPERTY_RO_GFX_ANGLE_SUPPORTED, "true");
|
||||
// TODO: b/270994705 yuxinhu:
|
||||
// add test coverage to test mGraphicsEnvironment.toggleAngleAsSystemDriver()
|
||||
// works properly on Android devices / emulators.
|
||||
ShadowSystemProperties.override(PROPERTY_PERSISTENT_GRAPHICS_EGL, ANGLE_DRIVER_SUFFIX);
|
||||
mController.updateState(mPreference);
|
||||
verify(mPreference).setChecked(true); //false
|
||||
verify(mPreference).setChecked(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_angleSupported_angleNotUsed_preferenceShouldNotBeChecked() {
|
||||
ShadowSystemProperties.override(PROPERTY_RO_GFX_ANGLE_SUPPORTED, "true");
|
||||
// TODO: b/270994705 yuxinhu:
|
||||
// add test coverage to test mGraphicsEnvironment.toggleAngleAsSystemDriver(false)
|
||||
// works properly on Android devices / emulators.
|
||||
ShadowSystemProperties.override(PROPERTY_PERSISTENT_GRAPHICS_EGL, "");
|
||||
mController.updateState(mPreference);
|
||||
verify(mPreference).setChecked(false);
|
||||
|
||||
@@ -70,6 +70,8 @@ import org.robolectric.annotation.Implementation;
|
||||
import org.robolectric.annotation.Implements;
|
||||
import org.robolectric.annotation.Resetter;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -84,6 +86,8 @@ public final class BatteryBackupHelperTest {
|
||||
private static final int UID1 = 1;
|
||||
|
||||
private Context mContext;
|
||||
private PrintWriter mPrintWriter;
|
||||
private StringWriter mStringWriter;
|
||||
private BatteryBackupHelper mBatteryBackupHelper;
|
||||
|
||||
@Mock
|
||||
@@ -109,6 +113,8 @@ public final class BatteryBackupHelperTest {
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mStringWriter = new StringWriter();
|
||||
mPrintWriter = new PrintWriter(mStringWriter);
|
||||
doReturn(mContext).when(mContext).getApplicationContext();
|
||||
doReturn(mAppOpsManager).when(mContext).getSystemService(AppOpsManager.class);
|
||||
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
||||
@@ -126,6 +132,7 @@ public final class BatteryBackupHelperTest {
|
||||
@After
|
||||
public void resetShadows() {
|
||||
ShadowUserHandle.reset();
|
||||
BatteryBackupHelper.getSharedPreferences(mContext).edit().clear().apply();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -216,6 +223,8 @@ public final class BatteryBackupHelperTest {
|
||||
// 2 for UNRESTRICTED mode and 1 for RESTRICTED mode.
|
||||
final String expectedResult = PACKAGE_NAME1 + ":2," + PACKAGE_NAME2 + ":1,";
|
||||
verifyBackupData(expectedResult);
|
||||
verifyDumpHistoryData("com.android.testing.1\taction:BACKUP\tevent:mode: 2");
|
||||
verifyDumpHistoryData("com.android.testing.2\taction:BACKUP\tevent:mode: 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -232,6 +241,7 @@ public final class BatteryBackupHelperTest {
|
||||
// "com.android.testing.2" for RESTRICTED mode.
|
||||
final String expectedResult = PACKAGE_NAME2 + ":1,";
|
||||
verifyBackupData(expectedResult);
|
||||
verifyDumpHistoryData("com.android.testing.2\taction:BACKUP\tevent:mode: 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -248,6 +258,7 @@ public final class BatteryBackupHelperTest {
|
||||
// "com.android.testing.2" for RESTRICTED mode.
|
||||
final String expectedResult = PACKAGE_NAME2 + ":1,";
|
||||
verifyBackupData(expectedResult);
|
||||
verifyDumpHistoryData("com.android.testing.2\taction:BACKUP\tevent:mode: 1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -357,6 +368,11 @@ public final class BatteryBackupHelperTest {
|
||||
doReturn(dataKey).when(mBackupDataInputStream).getKey();
|
||||
}
|
||||
|
||||
private void verifyDumpHistoryData(String expectedResult) {
|
||||
BatteryBackupHelper.dumpHistoricalData(mContext, mPrintWriter);
|
||||
assertThat(mStringWriter.toString().contains(expectedResult)).isTrue();
|
||||
}
|
||||
|
||||
private void verifyBackupData(String expectedResult) throws Exception {
|
||||
final byte[] expectedBytes = expectedResult.getBytes();
|
||||
final ArgumentCaptor<byte[]> captor = ArgumentCaptor.forClass(byte[].class);
|
||||
|
||||
@@ -49,7 +49,7 @@ public final class BatteryHistoricalLogUtilTest {
|
||||
@Test
|
||||
public void printHistoricalLog_withDefaultLogs() {
|
||||
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(mContext, mTestPrintWriter);
|
||||
assertThat(mTestStringWriter.toString()).contains("No past logs");
|
||||
assertThat(mTestStringWriter.toString()).contains("nothing to dump");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -58,7 +58,7 @@ public final class BatteryHistoricalLogUtilTest {
|
||||
BatteryHistoricalLogUtil.printBatteryOptimizeHistoricalLog(mContext, mTestPrintWriter);
|
||||
|
||||
assertThat(mTestStringWriter.toString()).contains(
|
||||
"pkg1\tAction:APPLY\tEvent:logs\tTimestamp:");
|
||||
"pkg1\taction:APPLY\tevent:logs");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -133,18 +133,12 @@ public class MobileNetworkSummaryControllerTest {
|
||||
assertThat(mController.isAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void getSummary_noSubscriptions_correctSummaryAndClickHandler() {
|
||||
public void getSummary_noSubscriptions_returnSummaryCorrectly() {
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onResume();
|
||||
assertThat(mController.getSummary()).isEqualTo("Add a network");
|
||||
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
doNothing().when(mContext).startActivity(intentCaptor.capture());
|
||||
mPreference.getOnPreferenceClickListener().onPreferenceClick(mPreference);
|
||||
assertThat(intentCaptor.getValue().getAction()).isEqualTo(
|
||||
EuiccManager.ACTION_PROVISION_EMBEDDED_SUBSCRIPTION);
|
||||
assertThat(mController.getSummary()).isEqualTo("Add a network");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -300,15 +294,13 @@ public class MobileNetworkSummaryControllerTest {
|
||||
assertThat(captor.getValue()).isFalse();
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void onResume_noSubscriptionEsimDisabled_isDisabled() {
|
||||
public void onAvailableSubInfoChanged_noSubscriptionEsimDisabled_isDisabled() {
|
||||
Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
|
||||
SubscriptionUtil.setAvailableSubscriptionsForTesting(null);
|
||||
when(mEuiccManager.isEnabled()).thenReturn(false);
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
|
||||
mController.onResume();
|
||||
mController.onAvailableSubInfoChanged(null);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import static com.android.settings.password.ChooseLockGeneric.ChooseLockGenericF
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CALLER_APP_NAME;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_DEVICE_PASSWORD_REQUIREMENT_ONLY;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_BIOMETRICS;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FACE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_IS_CALLING_APP_ADMIN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_REQUESTED_MIN_COMPLEXITY;
|
||||
|
||||
@@ -126,7 +128,9 @@ public class ChooseLockGenericTest {
|
||||
when(mFaceManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
|
||||
when(mFakeFeatureFactory.mFaceFeatureProvider.isSetupWizardSupported(any())).thenReturn(
|
||||
false);
|
||||
true);
|
||||
ShadowUtils.setFingerprintManager(mFingerprintManager);
|
||||
ShadowUtils.setFaceManager(mFaceManager);
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -540,35 +544,63 @@ public class ChooseLockGenericTest {
|
||||
|
||||
@Test
|
||||
public void updatePreferenceText_supportBiometrics_showFaceAndFingerprint() {
|
||||
ShadowLockPatternUtils.setRequiredPasswordComplexity(PASSWORD_COMPLEXITY_LOW);
|
||||
final PasswordPolicy policy = new PasswordPolicy();
|
||||
policy.quality = PASSWORD_QUALITY_ALPHABETIC;
|
||||
ShadowLockPatternUtils.setRequestedProfilePasswordMetrics(policy.getMinMetrics());
|
||||
|
||||
ShadowStorageManager.setIsFileEncrypted(false);
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_FOR_BIOMETRICS, true);
|
||||
initActivity(intent);
|
||||
|
||||
final Intent passwordIntent = mFragment.getLockPatternIntent();
|
||||
assertThat(passwordIntent.getIntExtra(ChooseLockPassword.EXTRA_KEY_MIN_COMPLEXITY,
|
||||
PASSWORD_COMPLEXITY_NONE)).isEqualTo(PASSWORD_COMPLEXITY_LOW);
|
||||
|
||||
final String supportFingerprint = capitalize(mActivity.getResources().getString(
|
||||
R.string.security_settings_fingerprint));
|
||||
final String supportFace = capitalize(mActivity.getResources().getString(
|
||||
R.string.keywords_face_settings));
|
||||
String pinTitle =
|
||||
(String) mFragment.findPreference(ScreenLockType.PIN.preferenceKey).getTitle();
|
||||
String patternTitle =
|
||||
(String) mFragment.findPreference(ScreenLockType.PATTERN.preferenceKey).getTitle();
|
||||
String passwordTitle =
|
||||
(String) mFragment.findPreference(ScreenLockType.PASSWORD.preferenceKey).getTitle();
|
||||
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PIN)).contains(
|
||||
supportFace);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PATTERN)).contains(
|
||||
supportFace);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFingerprint);
|
||||
assertThat(mFragment.getBiometricsPreferenceTitle(ScreenLockType.PASSWORD)).contains(
|
||||
supportFace);
|
||||
assertThat(pinTitle).contains(supportFingerprint);
|
||||
assertThat(pinTitle).contains(supportFace);
|
||||
assertThat(patternTitle).contains(supportFingerprint);
|
||||
assertThat(patternTitle).contains(supportFace);
|
||||
assertThat(passwordTitle).contains(supportFingerprint);
|
||||
assertThat(passwordTitle).contains(supportFace);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceText_supportFingerprint_showFingerprint() {
|
||||
ShadowStorageManager.setIsFileEncrypted(false);
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_FOR_FINGERPRINT, true);
|
||||
initActivity(intent);
|
||||
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
|
||||
|
||||
assertThat(mFragment.findPreference(ScreenLockType.PIN.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.fingerprint_unlock_set_unlock_pin));
|
||||
assertThat(mFragment.findPreference(
|
||||
ScreenLockType.PATTERN.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.fingerprint_unlock_set_unlock_pattern));
|
||||
assertThat(mFragment.findPreference(
|
||||
ScreenLockType.PASSWORD.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.fingerprint_unlock_set_unlock_password));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePreferenceText_supportFace_showFace() {
|
||||
|
||||
ShadowStorageManager.setIsFileEncrypted(false);
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_FOR_FACE, true);
|
||||
initActivity(intent);
|
||||
mFragment.updatePreferencesOrFinish(false /* isRecreatingActivity */);
|
||||
|
||||
assertThat(mFragment.findPreference(ScreenLockType.PIN.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.face_unlock_set_unlock_pin));
|
||||
assertThat(mFragment.findPreference(
|
||||
ScreenLockType.PATTERN.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.face_unlock_set_unlock_pattern));
|
||||
assertThat(mFragment.findPreference(
|
||||
ScreenLockType.PASSWORD.preferenceKey).getTitle()).isEqualTo(
|
||||
mFragment.getString(R.string.face_unlock_set_unlock_password));
|
||||
}
|
||||
|
||||
private void initActivity(@Nullable Intent intent) {
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.development.graphicsdriver;
|
||||
|
||||
import static com.android.settings.development.graphicsdriver.GraphicsDriverEnableAngleAsSystemDriverController.ANGLE_DRIVER_SUFFIX;
|
||||
import static com.android.settings.development.graphicsdriver.GraphicsDriverEnableAngleAsSystemDriverController.Injector;
|
||||
import static com.android.settings.development.graphicsdriver.GraphicsDriverEnableAngleAsSystemDriverController.PROPERTY_PERSISTENT_GRAPHICS_EGL;
|
||||
import static com.android.settings.development.graphicsdriver.GraphicsDriverEnableAngleAsSystemDriverController.PROPERTY_RO_GFX_ANGLE_SUPPORTED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.development.DevelopmentSettingsDashboardFragment;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest {
|
||||
private Context mContext;
|
||||
private SwitchPreference mPreference;
|
||||
|
||||
private GraphicsDriverEnableAngleAsSystemDriverController mController;
|
||||
|
||||
@Mock
|
||||
private DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
@Mock
|
||||
private GraphicsDriverSystemPropertiesWrapper mSystemPropertiesMock;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
// Construct a GraphicsDriverEnableAngleAsSystemDriverController with two Overrides:
|
||||
// 1) Override the mSystemProperties with mSystemPropertiesMock,
|
||||
// so we can force the SystemProperties with values we need to run tests.
|
||||
// 2) Override the showRebootDialog() to do nothing.
|
||||
// We do not need to pop up the reboot dialog in the test.
|
||||
mController = new GraphicsDriverEnableAngleAsSystemDriverController(
|
||||
mContext, mFragment, new Injector(){
|
||||
@Override
|
||||
public GraphicsDriverSystemPropertiesWrapper createSystemPropertiesWrapper() {
|
||||
return mSystemPropertiesMock;
|
||||
}
|
||||
}) {
|
||||
@Override
|
||||
void showRebootDialog() {
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
final PreferenceManager preferenceManager = new PreferenceManager(mContext);
|
||||
final PreferenceScreen screen = preferenceManager.createPreferenceScreen(mContext);
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
screen.addPreference(mPreference);
|
||||
mController.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_switchOn_shouldEnableAngleAsSystemDriver() {
|
||||
// Add a callback when SystemProperty changes.
|
||||
// This allows the thread to wait until
|
||||
// GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl.
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
Runnable countDown = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(countDown);
|
||||
|
||||
// Test onPreferenceChange(true) updates the persist.graphics.egl to "angle"
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
try {
|
||||
countDownLatch.await(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
assertThat(systemEGLDriver).isEqualTo(ANGLE_DRIVER_SUFFIX);
|
||||
|
||||
// Done with the test, remove the callback
|
||||
SystemProperties.removeChangeCallback(countDown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_switchOff_shouldDisableAngleAsSystemDriver() {
|
||||
// Add a callback when SystemProperty changes.
|
||||
// This allows the thread to wait until
|
||||
// GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl.
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
Runnable countDown = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(countDown);
|
||||
|
||||
// Test onPreferenceChange(false) updates the persist.graphics.egl to ""
|
||||
mController.onPreferenceChange(mPreference, false);
|
||||
try {
|
||||
countDownLatch.await(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
assertThat(systemEGLDriver).isEqualTo("");
|
||||
|
||||
// Done with the test, remove the callback
|
||||
SystemProperties.removeChangeCallback(countDown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_angleNotSupported_PreferenceShouldDisabled() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())).thenReturn("");
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_angleNotSupported_PreferenceShouldNotBeChecked() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("");
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_angleSupported_PreferenceShouldEnabled() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("true");
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_angleSupported_angleIsSystemGLESDriver_PreferenceShouldBeChecked() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("true");
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
|
||||
.thenReturn(ANGLE_DRIVER_SUFFIX);
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
updateState_angleSupported_angleIsNotSystemGLESDriver_PreferenceShouldNotBeChecked() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("true");
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
|
||||
.thenReturn("");
|
||||
mController.updateState(mPreference);
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionSwitchEnabled_angleSupported_PreferenceShouldEnabled() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("true");
|
||||
mController.onDeveloperOptionsSwitchEnabled();
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionSwitchEnabled_angleNotSupported_PrefenceShouldDisabled() {
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any()))
|
||||
.thenReturn("false");
|
||||
mController.onDeveloperOptionsSwitchEnabled();
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionSwitchDisabled_angleIsNotSystemGLESDriver() {
|
||||
// Add a callback when SystemProperty changes.
|
||||
// This allows the thread to wait until
|
||||
// GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl.
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
Runnable countDown = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(countDown);
|
||||
|
||||
// Test that onDeveloperOptionSwitchDisabled,
|
||||
// persist.graphics.egl updates to ""
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
try {
|
||||
countDownLatch.await(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
assertThat(systemEGLDriver).isEqualTo("");
|
||||
|
||||
// Done with the test, remove the callback
|
||||
SystemProperties.removeChangeCallback(countDown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionSwitchDisabled_PreferenceShouldNotBeChecked() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionSwitchDisabled_PreferenceShouldDisabled() {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebootCancelled_ToggleSwitchFromOnToOff() {
|
||||
// Add a callback when SystemProperty changes.
|
||||
// This allows the thread to wait until
|
||||
// GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl.
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
Runnable countDown = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(countDown);
|
||||
|
||||
// Test that if the current persist.graphics.egl is "angle",
|
||||
// when reboot is cancelled, persist.graphics.egl is changed back to "",
|
||||
// and switch is set to unchecked.
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
|
||||
.thenReturn(ANGLE_DRIVER_SUFFIX);
|
||||
mController.onRebootCancelled();
|
||||
try {
|
||||
countDownLatch.await(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
assertThat(systemEGLDriver).isEqualTo("");
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
|
||||
// Done with the test, remove the callback.
|
||||
SystemProperties.removeChangeCallback(countDown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebootCancelled_ToggleSwitchFromOffToOn() {
|
||||
// Add a callback when SystemProperty changes.
|
||||
// This allows the thread to wait until
|
||||
// GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl.
|
||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||
Runnable countDown = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
countDownLatch.countDown();
|
||||
}
|
||||
};
|
||||
SystemProperties.addChangeCallback(countDown);
|
||||
|
||||
// Test that if the current persist.graphics.egl is "",
|
||||
// when reboot is cancelled, persist.graphics.egl is changed back to "angle",
|
||||
// and switch is set to checked.
|
||||
when(mSystemPropertiesMock.get(eq(PROPERTY_PERSISTENT_GRAPHICS_EGL), any()))
|
||||
.thenReturn("");
|
||||
mController.onRebootCancelled();
|
||||
try {
|
||||
countDownLatch.await(100, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
|
||||
final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL);
|
||||
assertThat(systemEGLDriver).isEqualTo(ANGLE_DRIVER_SUFFIX);
|
||||
assertThat(mPreference.isChecked()).isTrue();
|
||||
|
||||
// Done with the test, remove the callback.
|
||||
SystemProperties.removeChangeCallback(countDown);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user