Snap for 7442307 from ee2b43c9f1 to sc-v2-release
Change-Id: Icd1dddee0bbd1ce7da1329b557708afee90713ed
This commit is contained in:
@@ -182,6 +182,7 @@
|
||||
|
||||
<activity android:name=".Settings$CreateShortcutActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.SubSettings"
|
||||
android:label="@string/settings_shortcut">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.CREATE_SHORTCUT" />
|
||||
@@ -3713,6 +3714,7 @@
|
||||
android:name="Settings$GestureNavigationSettingsActivity"
|
||||
android:label="@string/gesture_settings_activity_title"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.SubSettings"
|
||||
android:enabled="true">
|
||||
<intent-filter android:priority="32">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -2424,7 +2424,7 @@
|
||||
errorLine1=" android:fillColor="@color/face_intro_outline""
|
||||
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
|
||||
<location
|
||||
file="res/drawable/face_enroll_introduction.xml"
|
||||
file="res/drawable/face_enroll_icon_large.xml"
|
||||
line="25"
|
||||
column="9"/>
|
||||
</issue>
|
||||
|
||||
@@ -19,26 +19,27 @@
|
||||
android:width="300dp"
|
||||
android:height="300dp"
|
||||
android:viewportWidth="300"
|
||||
android:viewportHeight="300">
|
||||
android:viewportHeight="300"
|
||||
android:tint="@color/face_enroll_icon_color">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/face_intro_outline"
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M150,0C67.16,0,0,67.16,0,150s67.16,150,150,150 s150-67.16,150-150S232.84,0,150,0 M150,4c39,0,75.66,15.19,103.24,42.76C280.81,74.34,296,111,296,150s-15.19,75.66-42.76,103.24 C225.66,280.81,189,296,150,296s-75.66-15.19-103.24-42.76C19.19,225.66,4,189,4,150S19.19,74.34,46.76,46.76 C74.34,19.19,111,4,150,4" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M220,120c0,5.52-4.48,10-10,10s-10-4.48-10-10 s4.48-10,10-10S220,114.48,220,120" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M90,130c-5.52,0-10-4.48-10-10s4.48-10,10-10 s10,4.48,10,10S95.52,130,90,130" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M164.2,215.88c-3.83,3.25-8.79,5.22-14.2,5.22 c-12.13,0-22-9.87-22-22c0-0.03,0-0.06,0-0.09l-8-0.03c0,0.04,0,0.08,0,0.13c0,6.24,1.9,12.03,5.16,16.83 c5.4,7.95,14.51,13.17,24.84,13.17c1.04,0,2.06-0.05,3.08-0.15c6.18-0.63,11.81-3.14,16.3-6.95L164.2,215.88z" />
|
||||
<path
|
||||
android:fillColor="?android:attr/colorAccent"
|
||||
android:fillColor="#FF000000"
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M 153 140 L 153 166 L 137 166 L 137 174 L 161 174 L 161 140 Z" />
|
||||
</vector>
|
||||
26
res/drawable/ic_power_settings.xml
Normal file
26
res/drawable/ic_power_settings.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:pathData="M11,2h2v10h-2zM18.37,5.64l-1.41,1.41c2.73,2.73 2.72,7.16 -0.01,9.89 -2.73,2.73 -7.17,2.73 -9.89,0.01 -2.73,-2.73 -2.74,-7.18 -0.01,-9.91l-1.41,-1.4c-3.51,3.51 -3.51,9.21 0.01,12.73 3.51,3.51 9.21,3.51 12.72,-0.01 3.51,-3.51 3.51,-9.2 0,-12.72z"
|
||||
android:fillColor="@android:color/white"/>
|
||||
</vector>
|
||||
@@ -63,7 +63,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="invisible"
|
||||
android:background="@drawable/face_enroll_introduction"/>
|
||||
android:background="@drawable/face_enroll_icon_large"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/face_enroll_introduction" />
|
||||
android:src="@drawable/face_enroll_icon_large" />
|
||||
|
||||
</com.google.android.setupdesign.view.FillContentLayout>
|
||||
|
||||
|
||||
@@ -31,4 +31,14 @@
|
||||
android:focusable="false"
|
||||
android:clickable="false"
|
||||
android:adjustViewBounds="true"/>
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lottie_view"
|
||||
android:layout_width="412dp"
|
||||
android:layout_height="300dp"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/protection_background"
|
||||
android:scaleType="fitCenter"
|
||||
android:adjustViewBounds="true"
|
||||
android:clipToOutline="true"/>
|
||||
</FrameLayout>
|
||||
18
res/values-mcc234/strings.xml
Normal file
18
res/values-mcc234/strings.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<string name="cell_broadcast_settings">Emergency alerts</string>
|
||||
</resources>
|
||||
@@ -27,7 +27,7 @@
|
||||
<color name="notification_importance_button_selected">#AECBFA</color> <!-- material blue 200 -->
|
||||
<color name="notification_importance_button_unselected">#5F6368</color>
|
||||
<color name="notification_history_background">#202124</color>
|
||||
<color name="face_intro_outline">?android:attr/colorAccent</color>
|
||||
|
||||
<!-- Palette list preference colors. -->
|
||||
<color name="palette_list_gradient_background">@android:color/black</color>
|
||||
<color name="palette_list_color_red">@color/palette_list_dark_mode_color_red</color>
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<!-- Search bar background color -->
|
||||
<color name="search_bar_background">?androidprv:attr/colorSurfaceHighlight</color>
|
||||
|
||||
<color name="face_intro_outline">#ffdadce0</color>
|
||||
<color name="face_enroll_icon_color">#42a5f5</color> <!-- Blue 400 -->
|
||||
|
||||
<color name="back_gesture_indicator">#4182ef</color>
|
||||
|
||||
|
||||
@@ -5179,7 +5179,7 @@
|
||||
<!-- Settings title for accessibility settings screen -->
|
||||
<string name="accessibility_settings_title">Accessibility settings</string>
|
||||
<!-- Summary for Accessibility settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
|
||||
<string name="accessibility_settings_summary">Screen readers, interaction controls</string>
|
||||
<string name="accessibility_settings_summary">Display, interaction, audio</string>
|
||||
<!-- Settings title for a brief version of Vision-Related Accessibility Settings. Displayed in Setup Wizard only. [CHAR LIMIT=35] -->
|
||||
<string name="vision_settings_title">Vision Settings</string>
|
||||
<!-- Settings description for a brief version of Vision-Related Accessibility Settings. Tells the user that they can adjust these settings now to help them through the remainder of the Setup Wizard and that they can later be changed in Settings. Displayed in Setup Wizard only. [CHAR LIMIT=none] -->
|
||||
|
||||
@@ -93,10 +93,4 @@
|
||||
android:title="@string/gesture_prevent_ringing_screen_title"
|
||||
android:fragment="com.android.settings.gestures.PreventRingingGestureSettings"
|
||||
settings:controller="com.android.settings.gestures.PreventRingingParentPreferenceController" />
|
||||
|
||||
<Preference
|
||||
android:key="gesture_power_menu_summary"
|
||||
android:title="@string/power_menu_setting_name"
|
||||
android:fragment="com.android.settings.gestures.PowerMenuSettings"
|
||||
settings:controller="com.android.settings.gestures.PowerMenuPreferenceController" />
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -43,6 +43,14 @@
|
||||
android:fragment="com.android.settings.datetime.DateTimeSettings"
|
||||
settings:controller="com.android.settings.datetime.DateTimePreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="gesture_power_menu_summary"
|
||||
android:title="@string/power_menu_setting_name"
|
||||
android:icon="@drawable/ic_power_settings"
|
||||
android:order="-220"
|
||||
android:fragment="com.android.settings.gestures.PowerMenuSettings"
|
||||
settings:controller="com.android.settings.gestures.PowerMenuPreferenceController" />
|
||||
|
||||
<!-- System updates -->
|
||||
<Preference
|
||||
android:key="additional_system_update_settings"
|
||||
|
||||
@@ -62,7 +62,57 @@ import java.util.List;
|
||||
/**
|
||||
* Utility class for creating the edit dialog.
|
||||
*/
|
||||
public class AccessibilityEditDialogUtils {
|
||||
public class AccessibilityDialogUtils {
|
||||
|
||||
/** Denotes the dialog emuns for show dialog. */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface DialogEnums {
|
||||
|
||||
/** OPEN: Settings > Accessibility > Any toggle service > Shortcut > Settings. */
|
||||
int EDIT_SHORTCUT = 1;
|
||||
|
||||
/** OPEN: Settings > Accessibility > Magnification > Shortcut > Settings. */
|
||||
int MAGNIFICATION_EDIT_SHORTCUT = 1001;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle use service to
|
||||
* enable service.
|
||||
*/
|
||||
int ENABLE_WARNING_FROM_TOGGLE = 1002;
|
||||
|
||||
/** OPEN: Settings > Accessibility > Downloaded toggle service > Shortcut checkbox. */
|
||||
int ENABLE_WARNING_FROM_SHORTCUT = 1003;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Shortcut checkbox
|
||||
* toggle.
|
||||
*/
|
||||
int ENABLE_WARNING_FROM_SHORTCUT_TOGGLE = 1004;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle use service to
|
||||
* disable service.
|
||||
*/
|
||||
int DISABLE_WARNING_FROM_TOGGLE = 1005;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Magnification > Toggle user service in button
|
||||
* navigation.
|
||||
*/
|
||||
int ACCESSIBILITY_BUTTON_TUTORIAL = 1006;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Magnification > Toggle user service in gesture
|
||||
* navigation.
|
||||
*/
|
||||
int GESTURE_NAVIGATION_TUTORIAL = 1007;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle user service > Show
|
||||
* launch tutorial.
|
||||
*/
|
||||
int LAUNCH_ACCESSIBILITY_TUTORIAL = 1008;
|
||||
}
|
||||
|
||||
/**
|
||||
* IntDef enum for dialog type that indicates different dialog for user to choose the shortcut
|
||||
@@ -77,7 +127,7 @@ public class AccessibilityEditDialogUtils {
|
||||
DialogType.EDIT_MAGNIFICATION_SWITCH_SHORTCUT,
|
||||
})
|
||||
|
||||
public @interface DialogType {
|
||||
public @interface DialogType {
|
||||
int EDIT_SHORTCUT_GENERIC = 0;
|
||||
int EDIT_SHORTCUT_GENERIC_SUW = 1;
|
||||
int EDIT_SHORTCUT_MAGNIFICATION = 2;
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.icu.text.CaseMap;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.CheckBox;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.utils.LocaleUtils;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Base class for accessibility fragments shortcut functions and dialog management.
|
||||
*/
|
||||
public abstract class AccessibilityShortcutPreferenceFragment extends SettingsPreferenceFragment
|
||||
implements ShortcutPreference.OnClickCallback {
|
||||
private static final String KEY_SHORTCUT_PREFERENCE = "shortcut_preference";
|
||||
protected static final String KEY_SAVED_USER_SHORTCUT_TYPE = "shortcut_type";
|
||||
protected static final int NOT_SET = -1;
|
||||
// Save user's shortcutType value when savedInstance has value (e.g. device rotated).
|
||||
protected int mSavedCheckBoxValue = NOT_SET;
|
||||
|
||||
protected ShortcutPreference mShortcutPreference;
|
||||
private AccessibilityManager.TouchExplorationStateChangeListener
|
||||
mTouchExplorationStateChangeListener;
|
||||
private SettingsContentObserver mSettingsContentObserver;
|
||||
private CheckBox mSoftwareTypeCheckBox;
|
||||
private CheckBox mHardwareTypeCheckBox;
|
||||
|
||||
/** Returns the accessibility component name. */
|
||||
protected abstract ComponentName getComponentName();
|
||||
|
||||
/** Returns the accessibility feature name. */
|
||||
protected abstract CharSequence getLabelName();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Restore the user shortcut type.
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(
|
||||
KEY_SAVED_USER_SHORTCUT_TYPE)) {
|
||||
mSavedCheckBoxValue = savedInstanceState.getInt(KEY_SAVED_USER_SHORTCUT_TYPE, NOT_SET);
|
||||
}
|
||||
|
||||
final int resId = getPreferenceScreenResId();
|
||||
if (resId <= 0) {
|
||||
final PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
|
||||
getPrefContext());
|
||||
setPreferenceScreen(preferenceScreen);
|
||||
}
|
||||
|
||||
final List<String> shortcutFeatureKeys = new ArrayList<>();
|
||||
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS);
|
||||
shortcutFeatureKeys.add(Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
|
||||
mSettingsContentObserver = new SettingsContentObserver(new Handler(), shortcutFeatureKeys) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
updateShortcutPreferenceData();
|
||||
updateShortcutPreference();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
mShortcutPreference = new ShortcutPreference(getPrefContext(), /* attrs= */ null);
|
||||
mShortcutPreference.setPersistent(false);
|
||||
mShortcutPreference.setKey(getShortcutPreferenceKey());
|
||||
mShortcutPreference.setOnClickCallback(this);
|
||||
|
||||
final CharSequence title = getString(R.string.accessibility_shortcut_title, getLabelName());
|
||||
mShortcutPreference.setTitle(title);
|
||||
getPreferenceScreen().addPreference(mShortcutPreference);
|
||||
|
||||
mTouchExplorationStateChangeListener = isTouchExplorationEnabled -> {
|
||||
removeDialog(DialogEnums.EDIT_SHORTCUT);
|
||||
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
|
||||
};
|
||||
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
final AccessibilityManager am = getPrefContext().getSystemService(
|
||||
AccessibilityManager.class);
|
||||
am.addTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
|
||||
mSettingsContentObserver.register(getContentResolver());
|
||||
updateShortcutPreferenceData();
|
||||
updateShortcutPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
final AccessibilityManager am = getPrefContext().getSystemService(
|
||||
AccessibilityManager.class);
|
||||
am.removeTouchExplorationStateChangeListener(mTouchExplorationStateChangeListener);
|
||||
mSettingsContentObserver.unregister(getContentResolver());
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
final int value = getShortcutTypeCheckBoxValue();
|
||||
if (value != NOT_SET) {
|
||||
outState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE, value);
|
||||
}
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DialogEnums.EDIT_SHORTCUT:
|
||||
final CharSequence dialogTitle = getPrefContext().getString(
|
||||
R.string.accessibility_shortcut_title, getLabelName());
|
||||
final int dialogType = WizardManagerHelper.isAnySetupWizard(getIntent())
|
||||
? AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC_SUW :
|
||||
AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC;
|
||||
final Dialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
getPrefContext(), dialogType, dialogTitle,
|
||||
this::callOnAlertDialogCheckboxClicked);
|
||||
setupEditShortcutDialog(dialog);
|
||||
return dialog;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported dialogId " + dialogId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
switch (dialogId) {
|
||||
case DialogEnums.EDIT_SHORTCUT:
|
||||
return SettingsEnums.DIALOG_ACCESSIBILITY_SERVICE_EDIT_SHORTCUT;
|
||||
default:
|
||||
return SettingsEnums.ACTION_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsClicked(ShortcutPreference preference) {
|
||||
showDialog(DialogEnums.EDIT_SHORTCUT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToggleClicked(ShortcutPreference preference) {
|
||||
if (getComponentName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(),
|
||||
getComponentName().flattenToString(), AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
if (preference.isChecked()) {
|
||||
AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), shortcutTypes,
|
||||
getComponentName());
|
||||
showDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
|
||||
} else {
|
||||
AccessibilityUtil.optOutAllValuesFromSettings(getPrefContext(), shortcutTypes,
|
||||
getComponentName());
|
||||
}
|
||||
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
|
||||
}
|
||||
|
||||
protected String getShortcutPreferenceKey() {
|
||||
return KEY_SHORTCUT_PREFERENCE;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setupEditShortcutDialog(Dialog dialog) {
|
||||
final View dialogSoftwareView = dialog.findViewById(R.id.software_shortcut);
|
||||
mSoftwareTypeCheckBox = dialogSoftwareView.findViewById(R.id.checkbox);
|
||||
setDialogTextAreaClickListener(dialogSoftwareView, mSoftwareTypeCheckBox);
|
||||
|
||||
final View dialogHardwareView = dialog.findViewById(R.id.hardware_shortcut);
|
||||
mHardwareTypeCheckBox = dialogHardwareView.findViewById(R.id.checkbox);
|
||||
setDialogTextAreaClickListener(dialogHardwareView, mHardwareTypeCheckBox);
|
||||
|
||||
updateEditShortcutDialogCheckBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns accumulated {@link AccessibilityUtil.UserShortcutType} checkbox value or
|
||||
* {@code NOT_SET} if checkboxes did not exist.
|
||||
*/
|
||||
protected int getShortcutTypeCheckBoxValue() {
|
||||
if (mSoftwareTypeCheckBox == null || mHardwareTypeCheckBox == null) {
|
||||
return NOT_SET;
|
||||
}
|
||||
|
||||
int value = AccessibilityUtil.UserShortcutType.EMPTY;
|
||||
if (mSoftwareTypeCheckBox.isChecked()) {
|
||||
value |= AccessibilityUtil.UserShortcutType.SOFTWARE;
|
||||
}
|
||||
if (mHardwareTypeCheckBox.isChecked()) {
|
||||
value |= AccessibilityUtil.UserShortcutType.HARDWARE;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will be invoked when a button in the edit shortcut dialog is clicked.
|
||||
*
|
||||
* @param dialog The dialog that received the click
|
||||
* @param which The button that was clicked
|
||||
*/
|
||||
protected void callOnAlertDialogCheckboxClicked(DialogInterface dialog, int which) {
|
||||
if (getComponentName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int value = getShortcutTypeCheckBoxValue();
|
||||
|
||||
saveNonEmptyUserShortcutType(value);
|
||||
AccessibilityUtil.optInAllValuesToSettings(getPrefContext(), value, getComponentName());
|
||||
AccessibilityUtil.optOutAllValuesFromSettings(getPrefContext(), ~value, getComponentName());
|
||||
mShortcutPreference.setChecked(value != AccessibilityUtil.UserShortcutType.EMPTY);
|
||||
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void saveNonEmptyUserShortcutType(int type) {
|
||||
if (type == AccessibilityUtil.UserShortcutType.EMPTY) {
|
||||
return;
|
||||
}
|
||||
|
||||
final PreferredShortcut shortcut = new PreferredShortcut(
|
||||
getComponentName().flattenToString(), type);
|
||||
PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut);
|
||||
}
|
||||
|
||||
private void setDialogTextAreaClickListener(View dialogView, CheckBox checkBox) {
|
||||
final View dialogTextArea = dialogView.findViewById(R.id.container);
|
||||
dialogTextArea.setOnClickListener(v -> checkBox.toggle());
|
||||
}
|
||||
|
||||
protected CharSequence getShortcutTypeSummary(Context context) {
|
||||
if (!mShortcutPreference.isSettingsEditable()) {
|
||||
return context.getText(R.string.accessibility_shortcut_edit_dialog_title_hardware);
|
||||
}
|
||||
|
||||
if (!mShortcutPreference.isChecked()) {
|
||||
return context.getText(R.string.switch_off_text);
|
||||
}
|
||||
|
||||
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(context,
|
||||
getComponentName().flattenToString(), AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
|
||||
final List<CharSequence> list = new ArrayList<>();
|
||||
final CharSequence softwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_edit_summary_software);
|
||||
|
||||
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.SOFTWARE)) {
|
||||
list.add(softwareTitle);
|
||||
}
|
||||
if (hasShortcutType(shortcutTypes, AccessibilityUtil.UserShortcutType.HARDWARE)) {
|
||||
final CharSequence hardwareTitle = context.getText(
|
||||
R.string.accessibility_shortcut_hardware_keyword);
|
||||
list.add(hardwareTitle);
|
||||
}
|
||||
|
||||
// Show software shortcut if first time to use.
|
||||
if (list.isEmpty()) {
|
||||
list.add(softwareTitle);
|
||||
}
|
||||
|
||||
return CaseMap.toTitle().wholeString().noLowercase().apply(Locale.getDefault(), /* iter= */
|
||||
null, LocaleUtils.getConcatenatedString(list));
|
||||
}
|
||||
|
||||
private void updateEditShortcutDialogCheckBox() {
|
||||
// If it is during onConfigChanged process then restore the value, or get the saved value
|
||||
// when shortcutPreference is checked.
|
||||
int value = restoreOnConfigChangedValue();
|
||||
if (value == NOT_SET) {
|
||||
final int lastNonEmptyUserShortcutType = PreferredShortcuts.retrieveUserShortcutType(
|
||||
getPrefContext(), getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
value = mShortcutPreference.isChecked() ? lastNonEmptyUserShortcutType
|
||||
: AccessibilityUtil.UserShortcutType.EMPTY;
|
||||
}
|
||||
|
||||
mSoftwareTypeCheckBox.setChecked(
|
||||
hasShortcutType(value, AccessibilityUtil.UserShortcutType.SOFTWARE));
|
||||
mHardwareTypeCheckBox.setChecked(
|
||||
hasShortcutType(value, AccessibilityUtil.UserShortcutType.HARDWARE));
|
||||
}
|
||||
|
||||
private int restoreOnConfigChangedValue() {
|
||||
final int savedValue = mSavedCheckBoxValue;
|
||||
mSavedCheckBoxValue = NOT_SET;
|
||||
return savedValue;
|
||||
}
|
||||
|
||||
private boolean hasShortcutType(int value, @AccessibilityUtil.UserShortcutType int type) {
|
||||
return (value & type) == type;
|
||||
}
|
||||
|
||||
protected void updateShortcutPreferenceData() {
|
||||
if (getComponentName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int shortcutTypes = AccessibilityUtil.getUserShortcutTypesFromSettings(
|
||||
getPrefContext(), getComponentName());
|
||||
if (shortcutTypes != AccessibilityUtil.UserShortcutType.EMPTY) {
|
||||
final PreferredShortcut shortcut = new PreferredShortcut(
|
||||
getComponentName().flattenToString(), shortcutTypes);
|
||||
PreferredShortcuts.saveUserShortcutType(getPrefContext(), shortcut);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateShortcutPreference() {
|
||||
if (getComponentName() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int shortcutTypes = PreferredShortcuts.retrieveUserShortcutType(getPrefContext(),
|
||||
getComponentName().flattenToString(), AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
mShortcutPreference.setChecked(
|
||||
AccessibilityUtil.hasValuesInSettings(getPrefContext(), shortcutTypes,
|
||||
getComponentName()));
|
||||
mShortcutPreference.setSummary(getShortcutTypeSummary(getPrefContext()));
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,14 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.AnimatedImageDrawable;
|
||||
import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.Animatable2;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
@@ -27,15 +32,31 @@ import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.airbnb.lottie.LottieDrawable;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A custom {@link ImageView} preference for showing animated or static image, such as <a
|
||||
* href="https://developers.google.com/speed/webp/">animated webp</a> and static png.
|
||||
*/
|
||||
public class AnimatedImagePreference extends Preference {
|
||||
|
||||
private static final String TAG = "AnimatedImagePreference";
|
||||
private Uri mImageUri;
|
||||
private int mMaxHeight = -1;
|
||||
|
||||
private final Animatable2.AnimationCallback mAnimationCallback =
|
||||
new Animatable2.AnimationCallback() {
|
||||
@Override
|
||||
public void onAnimationEnd(Drawable drawable) {
|
||||
((Animatable2) drawable).start();
|
||||
}
|
||||
};
|
||||
|
||||
AnimatedImagePreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.preference_animated_image);
|
||||
@@ -46,21 +67,27 @@ public class AnimatedImagePreference extends Preference {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
final ImageView imageView = holder.itemView.findViewById(R.id.animated_img);
|
||||
if (imageView == null) {
|
||||
final LottieAnimationView lottieView = holder.itemView.findViewById(R.id.lottie_view);
|
||||
if (imageView == null || lottieView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mImageUri != null) {
|
||||
imageView.setImageURI(mImageUri);
|
||||
resetAnimations(imageView, lottieView);
|
||||
hideAllChildViews(holder.itemView);
|
||||
|
||||
final Drawable drawable = imageView.getDrawable();
|
||||
if (drawable instanceof AnimatedImageDrawable) {
|
||||
((AnimatedImageDrawable) drawable).start();
|
||||
imageView.setImageURI(mImageUri);
|
||||
if (imageView.getDrawable() != null) {
|
||||
startAnimationWith(imageView);
|
||||
} else {
|
||||
// The lottie image from the raw folder also returns null.
|
||||
startLottieAnimationWith(lottieView);
|
||||
}
|
||||
}
|
||||
|
||||
if (mMaxHeight > -1) {
|
||||
imageView.setMaxHeight(mMaxHeight);
|
||||
lottieView.setMaxHeight(mMaxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,4 +114,68 @@ public class AnimatedImagePreference extends Preference {
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void startAnimationWith(ImageView imageView) {
|
||||
startAnimation(imageView.getDrawable());
|
||||
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void startLottieAnimationWith(LottieAnimationView lottieView) {
|
||||
final InputStream inputStream = getInputStreamFromUri(mImageUri);
|
||||
Objects.requireNonNull(inputStream, "Invalid resource.");
|
||||
lottieView.setAnimation(inputStream, /* cacheKey= */ null);
|
||||
lottieView.setRepeatCount(LottieDrawable.INFINITE);
|
||||
lottieView.playAnimation();
|
||||
|
||||
lottieView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void startAnimation(Drawable drawable) {
|
||||
if (!(drawable instanceof Animatable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawable instanceof Animatable2) {
|
||||
((Animatable2) drawable).registerAnimationCallback(mAnimationCallback);
|
||||
} else if (drawable instanceof AnimationDrawable) {
|
||||
((AnimationDrawable) drawable).setOneShot(false);
|
||||
}
|
||||
|
||||
((Animatable) drawable).start();
|
||||
}
|
||||
|
||||
private void resetAnimations(ImageView imageView, LottieAnimationView lottieView) {
|
||||
resetAnimation(imageView.getDrawable());
|
||||
|
||||
lottieView.cancelAnimation();
|
||||
}
|
||||
|
||||
private void resetAnimation(Drawable drawable) {
|
||||
if (!(drawable instanceof Animatable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawable instanceof Animatable2) {
|
||||
((Animatable2) drawable).clearAnimationCallbacks();
|
||||
}
|
||||
|
||||
((Animatable) drawable).stop();
|
||||
}
|
||||
|
||||
private InputStream getInputStreamFromUri(Uri uri) {
|
||||
try {
|
||||
return getContext().getContentResolver().openInputStream(uri);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "Cannot find content uri: " + uri, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void hideAllChildViews(View itemView) {
|
||||
final ViewGroup viewGroup = (ViewGroup) itemView;
|
||||
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
||||
viewGroup.getChildAt(i).setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
|
||||
import static com.android.settings.accessibility.AccessibilityEditDialogUtils.CustomButton;
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
|
||||
@@ -166,7 +166,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
|
||||
}
|
||||
|
||||
private Dialog createMagnificationModeDialog() {
|
||||
mMagnificationModesListView = AccessibilityEditDialogUtils.createSingleChoiceListView(
|
||||
mMagnificationModesListView = AccessibilityDialogUtils.createSingleChoiceListView(
|
||||
mContext, mModeInfos, this::onMagnificationModeSelected);
|
||||
|
||||
final View headerView = LayoutInflater.from(mContext).inflate(
|
||||
@@ -179,7 +179,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
|
||||
final CharSequence title = mContext.getString(
|
||||
R.string.accessibility_magnification_mode_dialog_title);
|
||||
|
||||
return AccessibilityEditDialogUtils.createCustomDialog(mContext, title,
|
||||
return AccessibilityDialogUtils.createCustomDialog(mContext, title,
|
||||
mMagnificationModesListView, this::onMagnificationModeDialogPositiveButtonClicked);
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ public class MagnificationModePreferenceController extends BasePreferenceControl
|
||||
}
|
||||
|
||||
private Dialog createMagnificationShortCutConfirmDialog() {
|
||||
return AccessibilityEditDialogUtils.createMagnificationSwitchShortcutDialog(mContext,
|
||||
return AccessibilityDialogUtils.createMagnificationSwitchShortcutDialog(mContext,
|
||||
this::onSwitchShortcutDialogButtonClicked);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
|
||||
import static com.android.settings.accessibility.AccessibilityStatsLogUtils.logAccessibilityServiceEnabled;
|
||||
import static com.android.settings.accessibility.PreferredShortcuts.retrieveUserShortcutType;
|
||||
|
||||
@@ -49,7 +50,6 @@ import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Switch;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.R;
|
||||
@@ -232,14 +232,18 @@ public class ToggleAccessibilityServicePreferenceFragment extends
|
||||
|
||||
@Override
|
||||
protected void updateSwitchBarToggleSwitch() {
|
||||
final boolean checked = AccessibilityUtils.getEnabledServicesFromSettings(getPrefContext())
|
||||
.contains(mComponentName);
|
||||
final boolean checked = isAccessibilityServiceEnabled();
|
||||
if (mToggleServiceSwitchPreference.isChecked() == checked) {
|
||||
return;
|
||||
}
|
||||
mToggleServiceSwitchPreference.setChecked(checked);
|
||||
}
|
||||
|
||||
private boolean isAccessibilityServiceEnabled() {
|
||||
return AccessibilityUtils.getEnabledServicesFromSettings(getPrefContext())
|
||||
.contains(mComponentName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the device is encrypted with legacy full disk encryption. Newer devices
|
||||
* should be using File Based Encryption.
|
||||
@@ -314,7 +318,6 @@ public class ToggleAccessibilityServicePreferenceFragment extends
|
||||
}
|
||||
|
||||
private void handleConfirmServiceEnabled(boolean confirmed) {
|
||||
mToggleServiceSwitchPreference.setChecked(confirmed);
|
||||
getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED, confirmed);
|
||||
onPreferenceToggled(mPreferenceKey, confirmed);
|
||||
}
|
||||
@@ -338,8 +341,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
|
||||
|
||||
@Override
|
||||
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||
if (isChecked != mToggleServiceSwitchPreference.isChecked()) {
|
||||
onPreferenceClick(mToggleServiceSwitchPreference);
|
||||
if (isChecked != isAccessibilityServiceEnabled()) {
|
||||
onPreferenceClick(isChecked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,14 +536,8 @@ public class ToggleAccessibilityServicePreferenceFragment extends
|
||||
mDialog.dismiss();
|
||||
}
|
||||
|
||||
private boolean onPreferenceClick(Preference preference) {
|
||||
boolean checked = ((SettingsMainSwitchPreference) preference).isChecked();
|
||||
if (checked) {
|
||||
mToggleServiceSwitchPreference.setChecked(true);
|
||||
getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED,
|
||||
/* enableService */ true);
|
||||
showDialog(DialogEnums.DISABLE_WARNING_FROM_TOGGLE);
|
||||
} else {
|
||||
private boolean onPreferenceClick(boolean isChecked) {
|
||||
if (isChecked) {
|
||||
mToggleServiceSwitchPreference.setChecked(false);
|
||||
getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED,
|
||||
/* disableService */ false);
|
||||
@@ -552,6 +549,11 @@ public class ToggleAccessibilityServicePreferenceFragment extends
|
||||
showPopupDialog(DialogEnums.LAUNCH_ACCESSIBILITY_TUTORIAL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mToggleServiceSwitchPreference.setChecked(true);
|
||||
getArguments().putBoolean(AccessibilitySettings.EXTRA_CHECKED,
|
||||
/* enableService */ true);
|
||||
showDialog(DialogEnums.DISABLE_WARNING_FROM_TOGGLE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.ComponentName;
|
||||
@@ -50,7 +52,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
import com.android.settings.utils.LocaleUtils;
|
||||
import com.android.settings.widget.SettingsMainSwitchBar;
|
||||
@@ -61,8 +63,6 @@ import com.android.settingslib.widget.OnMainSwitchChangeListener;
|
||||
|
||||
import com.google.android.setupcompat.util.WizardManagerHelper;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -136,7 +136,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
|
||||
setupDefaultShortcutIfNecessary(getPrefContext());
|
||||
final int resId = getPreferenceScreenResId();
|
||||
if (resId <= 0) {
|
||||
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
|
||||
final PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
|
||||
getPrefContext());
|
||||
setPreferenceScreen(preferenceScreen);
|
||||
}
|
||||
@@ -228,7 +228,7 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
|
||||
R.string.accessibility_shortcut_title, mPackageName);
|
||||
final int dialogType = WizardManagerHelper.isAnySetupWizard(getIntent())
|
||||
? DialogType.EDIT_SHORTCUT_GENERIC_SUW : DialogType.EDIT_SHORTCUT_GENERIC;
|
||||
dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
getPrefContext(), dialogType, dialogTitle,
|
||||
this::callOnAlertDialogCheckboxClicked);
|
||||
setupEditShortcutDialog(dialog);
|
||||
@@ -256,56 +256,6 @@ public abstract class ToggleFeaturePreferenceFragment extends SettingsPreference
|
||||
}
|
||||
}
|
||||
|
||||
/** Denotes the dialog emuns for show dialog */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
protected @interface DialogEnums {
|
||||
|
||||
/** OPEN: Settings > Accessibility > Any toggle service > Shortcut > Settings. */
|
||||
int EDIT_SHORTCUT = 1;
|
||||
|
||||
/** OPEN: Settings > Accessibility > Magnification > Shortcut > Settings. */
|
||||
int MAGNIFICATION_EDIT_SHORTCUT = 1001;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle use service to
|
||||
* enable service.
|
||||
*/
|
||||
int ENABLE_WARNING_FROM_TOGGLE = 1002;
|
||||
|
||||
/** OPEN: Settings > Accessibility > Downloaded toggle service > Shortcut checkbox. */
|
||||
int ENABLE_WARNING_FROM_SHORTCUT = 1003;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Shortcut checkbox
|
||||
* toggle.
|
||||
*/
|
||||
int ENABLE_WARNING_FROM_SHORTCUT_TOGGLE = 1004;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle use service to
|
||||
* disable service.
|
||||
*/
|
||||
int DISABLE_WARNING_FROM_TOGGLE = 1005;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Magnification > Toggle user service in button
|
||||
* navigation.
|
||||
*/
|
||||
int ACCESSIBILITY_BUTTON_TUTORIAL = 1006;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Magnification > Toggle user service in gesture
|
||||
* navigation.
|
||||
*/
|
||||
int GESTURE_NAVIGATION_TUTORIAL = 1007;
|
||||
|
||||
/**
|
||||
* OPEN: Settings > Accessibility > Downloaded toggle service > Toggle user service > Show
|
||||
* launch tutorial.
|
||||
*/
|
||||
int LAUNCH_ACCESSIBILITY_TUTORIAL = 1008;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.ACCESSIBILITY_SERVICE;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME;
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.DialogEnums;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
|
||||
@@ -44,7 +45,7 @@ import androidx.preference.PreferenceCategory;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.settings.DialogCreatable;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
import com.android.settings.utils.LocaleUtils;
|
||||
|
||||
@@ -134,7 +135,7 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
final int dialogType = WizardManagerHelper.isAnySetupWizard(getIntent())
|
||||
? DialogType.EDIT_SHORTCUT_MAGNIFICATION_SUW
|
||||
: DialogType.EDIT_SHORTCUT_MAGNIFICATION;
|
||||
dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(getPrefContext(),
|
||||
dialog = AccessibilityDialogUtils.showEditShortcutDialog(getPrefContext(),
|
||||
dialogType, dialogTitle, this::callOnAlertDialogCheckboxClicked);
|
||||
setupMagnificationEditShortcutDialog(dialog);
|
||||
return dialog;
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.widget.LinearLayout;
|
||||
import android.widget.SearchView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -35,6 +36,8 @@ import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.datetime.timezone.model.TimeZoneData;
|
||||
import com.android.settings.datetime.timezone.model.TimeZoneDataLoader;
|
||||
|
||||
import com.google.android.material.appbar.AppBarLayout;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -43,12 +46,15 @@ import java.util.Locale;
|
||||
* The search matches the prefix of words in the search text.
|
||||
*/
|
||||
public abstract class BaseTimeZonePicker extends InstrumentedFragment
|
||||
implements SearchView.OnQueryTextListener {
|
||||
implements SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener {
|
||||
|
||||
public static final String EXTRA_RESULT_REGION_ID =
|
||||
"com.android.settings.datetime.timezone.result_region_id";
|
||||
public static final String EXTRA_RESULT_TIME_ZONE_ID =
|
||||
"com.android.settings.datetime.timezone.result_time_zone_id";
|
||||
|
||||
protected AppBarLayout mAppBarLayout;
|
||||
|
||||
private final int mTitleResId;
|
||||
private final int mSearchHintResId;
|
||||
private final boolean mSearchEnabled;
|
||||
@@ -88,6 +94,7 @@ public abstract class BaseTimeZonePicker extends InstrumentedFragment
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(),
|
||||
LinearLayoutManager.VERTICAL, /* reverseLayout */ false));
|
||||
mRecyclerView.setAdapter(mAdapter);
|
||||
mAppBarLayout = getActivity().findViewById(R.id.app_bar);
|
||||
|
||||
// Initialize TimeZoneDataLoader only when mRecyclerView is ready to avoid race
|
||||
// during onDateLoaderReady callback.
|
||||
@@ -121,6 +128,7 @@ public abstract class BaseTimeZonePicker extends InstrumentedFragment
|
||||
inflater.inflate(R.menu.time_zone_base_search_menu, menu);
|
||||
|
||||
final MenuItem searchMenuItem = menu.findItem(R.id.time_zone_search_menu);
|
||||
searchMenuItem.setOnActionExpandListener(this);
|
||||
mSearchView = (SearchView) searchMenuItem.getActionView();
|
||||
|
||||
mSearchView.setQueryHint(getText(mSearchHintResId));
|
||||
@@ -148,6 +156,21 @@ public abstract class BaseTimeZonePicker extends InstrumentedFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(MenuItem item) {
|
||||
// To prevent a large space on tool bar.
|
||||
mAppBarLayout.setExpanded(false /*expanded*/, false /*animate*/);
|
||||
// To prevent user can expand the collpasing tool bar view.
|
||||
ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(MenuItem item) {
|
||||
ViewCompat.setNestedScrollingEnabled(mRecyclerView, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return false;
|
||||
|
||||
@@ -272,7 +272,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
final Map<String, BatteryHistEntry> entryMap = batteryHistoryMap.get(timestamp);
|
||||
if (entryMap == null || entryMap.isEmpty()) {
|
||||
Log.e(TAG, "abnormal entry list in the timestamp:"
|
||||
+ ConvertUtils.utcToLocalTime(timestamp));
|
||||
+ ConvertUtils.utcToLocalTime(mPrefContext, timestamp));
|
||||
continue;
|
||||
}
|
||||
// Averages the battery level in each time slot to avoid corner conditions.
|
||||
@@ -287,7 +287,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
Log.d(TAG, String.format(
|
||||
"setBatteryHistoryMap() size=%d\nkeys=%s\nlevels=%s",
|
||||
batteryHistoryMap.size(),
|
||||
utcToLocalTime(mBatteryHistoryKeys),
|
||||
utcToLocalTime(mPrefContext, mBatteryHistoryKeys),
|
||||
Arrays.toString(mBatteryHistoryLevels)));
|
||||
|
||||
// Loads item icon and label in the background.
|
||||
@@ -496,9 +496,9 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
if (mTrapezoidIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
final String fromHour = ConvertUtils.utcToLocalTimeHour(
|
||||
final String fromHour = ConvertUtils.utcToLocalTimeHour(mPrefContext,
|
||||
mBatteryHistoryKeys[mTrapezoidIndex * 2], mIs24HourFormat);
|
||||
final String toHour = ConvertUtils.utcToLocalTimeHour(
|
||||
final String toHour = ConvertUtils.utcToLocalTimeHour(mPrefContext,
|
||||
mBatteryHistoryKeys[(mTrapezoidIndex + 1) * 2], mIs24HourFormat);
|
||||
return String.format("%s - %s", fromHour, toHour);
|
||||
}
|
||||
@@ -584,11 +584,11 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
mHandler.post(() -> mPreferenceScreen.addPreference(mFooterPreference));
|
||||
}
|
||||
|
||||
private static String utcToLocalTime(long[] timestamps) {
|
||||
private static String utcToLocalTime(Context context, long[] timestamps) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (int index = 0; index < timestamps.length; index++) {
|
||||
builder.append(String.format("%s| ",
|
||||
ConvertUtils.utcToLocalTime(timestamps[index])));
|
||||
ConvertUtils.utcToLocalTime(context, timestamps[index])));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@@ -56,14 +56,8 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
private static final List<String> ACCESSIBILITY_SERVICE_NAMES =
|
||||
Arrays.asList("SwitchAccessService", "TalkBackService", "JustSpeakService");
|
||||
|
||||
// For drawing the percentage information.
|
||||
private static final String[] PERCENTAGES = new String[] {
|
||||
formatPercentage(/*percentage=*/ 100, /*round=*/ true),
|
||||
formatPercentage(/*percentage=*/ 50, /*round=*/ true),
|
||||
formatPercentage(/*percentage=*/ 0, /*round=*/ true)};
|
||||
|
||||
private static final int DEFAULT_TRAPEZOID_COUNT = 12;
|
||||
private static final int DEFAULT_TIMESTAMP_COUNT = 4;
|
||||
private static final int DEFAULT_TIMESTAMP_COUNT = 5;
|
||||
private static final int DIVIDER_COLOR = Color.parseColor("#CDCCC5");
|
||||
private static final long UPDATE_STATE_DELAYED_TIME = 500L;
|
||||
|
||||
@@ -82,6 +76,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
private float mTrapezoidVOffset;
|
||||
private float mTrapezoidHOffset;
|
||||
private boolean mIsSlotsClickabled;
|
||||
private String[] mPercentages = getPercentages();
|
||||
|
||||
@VisibleForTesting int mSelectedIndex;
|
||||
@VisibleForTesting String[] mTimestamps;
|
||||
@@ -96,7 +91,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
new Rect[] {new Rect(), new Rect(), new Rect()};
|
||||
// For drawing the timestamp information.
|
||||
private final Rect[] mTimestampsBounds =
|
||||
new Rect[] {new Rect(), new Rect(), new Rect(), new Rect()};
|
||||
new Rect[] {new Rect(), new Rect(), new Rect(), new Rect(), new Rect()};
|
||||
|
||||
@VisibleForTesting
|
||||
Handler mHandler = new Handler();
|
||||
@@ -107,6 +102,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
private Paint mTextPaint;
|
||||
private Paint mDividerPaint;
|
||||
private Paint mTrapezoidPaint;
|
||||
|
||||
@VisibleForTesting
|
||||
Paint mTrapezoidCurvePaint = null;
|
||||
private TrapezoidSlot[] mTrapezoidSlots;
|
||||
@@ -201,12 +197,13 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
if (mTimestamps == null) {
|
||||
mTimestamps = new String[DEFAULT_TIMESTAMP_COUNT];
|
||||
}
|
||||
final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 8;
|
||||
final long timeSlotOffset = DateUtils.HOUR_IN_MILLIS * 6;
|
||||
final boolean is24HourFormat = DateFormat.is24HourFormat(getContext());
|
||||
for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) {
|
||||
mTimestamps[index] =
|
||||
ConvertUtils.utcToLocalTimeHour(
|
||||
latestTimestamp - (3 - index) * timeSlotOffset,
|
||||
getContext(),
|
||||
latestTimestamp - (4 - index) * timeSlotOffset,
|
||||
is24HourFormat);
|
||||
}
|
||||
requestLayout();
|
||||
@@ -217,9 +214,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
// Measures text bounds and updates indent configuration.
|
||||
if (mTextPaint != null) {
|
||||
for (int index = 0; index < PERCENTAGES.length; index++) {
|
||||
for (int index = 0; index < mPercentages.length; index++) {
|
||||
mTextPaint.getTextBounds(
|
||||
PERCENTAGES[index], 0, PERCENTAGES[index].length(),
|
||||
mPercentages[index], 0, mPercentages[index].length(),
|
||||
mPercentageBounds[index]);
|
||||
}
|
||||
// Updates the indent configurations.
|
||||
@@ -396,7 +393,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
private void drawPercentage(Canvas canvas, int index, float offsetY) {
|
||||
if (mTextPaint != null) {
|
||||
canvas.drawText(
|
||||
PERCENTAGES[index],
|
||||
mPercentages[index],
|
||||
getWidth() - mPercentageBounds[index].width() - mPercentageBounds[index].left,
|
||||
offsetY + mPercentageBounds[index].height() *.5f,
|
||||
mTextPaint);
|
||||
@@ -429,7 +426,7 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
final float baselineX = mDividerWidth * .5f;
|
||||
final float offsetX = mDividerWidth + unitWidth;
|
||||
for (int index = 0; index < DEFAULT_TIMESTAMP_COUNT; index++) {
|
||||
xOffsets[index] = baselineX + index * offsetX * 4;
|
||||
xOffsets[index] = baselineX + index * offsetX * 3;
|
||||
}
|
||||
drawTimestamp(canvas, xOffsets);
|
||||
}
|
||||
@@ -443,11 +440,11 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
getTimestampY(0), mTextPaint);
|
||||
// Draws the last timestamp info.
|
||||
canvas.drawText(
|
||||
mTimestamps[3],
|
||||
xOffsets[3] - mTimestampsBounds[3].width() - mTimestampsBounds[3].left,
|
||||
getTimestampY(3), mTextPaint);
|
||||
mTimestamps[4],
|
||||
xOffsets[4] - mTimestampsBounds[4].width() - mTimestampsBounds[4].left,
|
||||
getTimestampY(4), mTextPaint);
|
||||
// Draws the rest of timestamp info since it is located in the center.
|
||||
for (int index = 1; index <= 2; index++) {
|
||||
for (int index = 1; index <= 3; index++) {
|
||||
canvas.drawText(
|
||||
mTimestamps[index],
|
||||
xOffsets[index] -
|
||||
@@ -544,6 +541,13 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
|
||||
&& mLevels[trapezoidIndex + 1] != 0;
|
||||
}
|
||||
|
||||
private static String[] getPercentages() {
|
||||
return new String[] {
|
||||
formatPercentage(/*percentage=*/ 100, /*round=*/ true),
|
||||
formatPercentage(/*percentage=*/ 50, /*round=*/ true),
|
||||
formatPercentage(/*percentage=*/ 0, /*round=*/ true)};
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isAccessibilityEnabled(Context context) {
|
||||
final AccessibilityManager accessibilityManager =
|
||||
|
||||
@@ -184,7 +184,8 @@ public class BatteryHistEntry {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final String recordAtDateTime = ConvertUtils.utcToLocalTime(mTimestamp);
|
||||
final String recordAtDateTime =
|
||||
ConvertUtils.utcToLocalTime(/*context=*/ null, mTimestamp);
|
||||
final StringBuilder builder = new StringBuilder()
|
||||
.append("\nBatteryHistEntry{")
|
||||
.append(String.format("\n\tpackage=%s|label=%s|uid=%d|userId=%d|isHidden=%b",
|
||||
|
||||
@@ -17,6 +17,7 @@ import android.annotation.IntDef;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
@@ -133,8 +134,8 @@ public final class ConvertUtils {
|
||||
}
|
||||
|
||||
/** Converts UTC timestamp to human readable local time string. */
|
||||
public static String utcToLocalTime(long timestamp) {
|
||||
final Locale currentLocale = Locale.getDefault();
|
||||
public static String utcToLocalTime(Context context, long timestamp) {
|
||||
final Locale currentLocale = getLocale(context);
|
||||
final String currentZoneId = TimeZone.getDefault().getID();
|
||||
if (!currentZoneId.equals(sZoneId)
|
||||
|| !currentLocale.equals(sLocale)
|
||||
@@ -148,8 +149,9 @@ public final class ConvertUtils {
|
||||
}
|
||||
|
||||
/** Converts UTC timestamp to local time hour data. */
|
||||
public static String utcToLocalTimeHour(long timestamp, boolean is24HourFormat) {
|
||||
final Locale currentLocale = Locale.getDefault();
|
||||
public static String utcToLocalTimeHour(
|
||||
Context context, long timestamp, boolean is24HourFormat) {
|
||||
final Locale currentLocale = getLocale(context);
|
||||
final String currentZoneId = TimeZone.getDefault().getID();
|
||||
if (!currentZoneId.equals(sZoneIdForHour)
|
||||
|| !currentLocale.equals(sLocaleForHour)
|
||||
@@ -159,7 +161,7 @@ public final class ConvertUtils {
|
||||
sZoneIdForHour = currentZoneId;
|
||||
sIs24HourFormat = is24HourFormat;
|
||||
sSimpleDateFormatForHour = new SimpleDateFormat(
|
||||
sIs24HourFormat ? "HH" : "h aa", currentLocale);
|
||||
sIs24HourFormat ? "HH" : "h", currentLocale);
|
||||
}
|
||||
return sSimpleDateFormatForHour.format(new Date(timestamp))
|
||||
.toLowerCase(currentLocale);
|
||||
@@ -356,4 +358,15 @@ public final class ConvertUtils {
|
||||
? entry3 : null;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Locale getLocale(Context context) {
|
||||
if (context == null) {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
final LocaleList locales =
|
||||
context.getResources().getConfiguration().getLocales();
|
||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||
: Locale.getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,18 +26,16 @@ import com.android.settings.core.TogglePreferenceController;
|
||||
*/
|
||||
public class GestureNavigationSettingsAssistController extends TogglePreferenceController {
|
||||
|
||||
// This value is based on SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
|
||||
// behaviour. We assume that the gestures are enabled by default.
|
||||
private static final int ASSIST_TOUCH_GESTURE_DEFAULT_VALUE = 1;
|
||||
|
||||
public GestureNavigationSettingsAssistController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
boolean onByDefault = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_assistTouchGestureEnabledDefault);
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, ASSIST_TOUCH_GESTURE_DEFAULT_VALUE)
|
||||
Settings.Secure.ASSIST_TOUCH_GESTURE_ENABLED, onByDefault ? 1 : 0)
|
||||
== 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settings.network.telephony.NetworkProviderWorker;
|
||||
import com.android.settings.slices.CustomSliceable;
|
||||
import com.android.settings.slices.SliceBackgroundWorker;
|
||||
import com.android.settings.slices.SliceBroadcastReceiver;
|
||||
import com.android.settings.slices.SliceBuilderUtils;
|
||||
import com.android.settings.wifi.WifiUtils;
|
||||
import com.android.settings.wifi.slice.WifiSlice;
|
||||
@@ -163,6 +164,18 @@ public class ProviderModelSlice extends WifiSlice {
|
||||
return listBuilder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PendingIntent getBroadcastIntent(Context context) {
|
||||
final Intent intent = new Intent(getUri().toString())
|
||||
// The FLAG_RECEIVER_FOREGROUND flag is necessary to avoid the intent delay of
|
||||
// the first sending after the device restarts
|
||||
.addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||
.setData(getUri())
|
||||
.setClass(context, SliceBroadcastReceiver.class);
|
||||
return PendingIntent.getBroadcast(context, 0 /* requestCode */, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the current carrier's mobile data status.
|
||||
*/
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.android.settings.network.ims.WifiCallingQueryImsState;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -86,7 +87,8 @@ public class NetworkProviderWifiCallingGroup extends
|
||||
}
|
||||
|
||||
private void setSubscriptionInfoList(Context context) {
|
||||
mSubInfoListForWfc = SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager);
|
||||
mSubInfoListForWfc = new ArrayList<>(
|
||||
SubscriptionUtil.getActiveSubscriptions(mSubscriptionManager));
|
||||
if (mSubInfoListForWfc != null) {
|
||||
mSubInfoListForWfc.removeIf(info -> {
|
||||
final int subId = info.getSubscriptionId();
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityShortcutPreferenceFragment.KEY_SAVED_USER_SHORTCUT_TYPE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
/** Tests for {@link AccessibilityShortcutPreferenceFragment} */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AccessibilityShortcutPreferenceFragmentTest {
|
||||
|
||||
private static final String PLACEHOLDER_PACKAGE_NAME = "com.placeholder.example";
|
||||
private static final String PLACEHOLDER_CLASS_NAME = PLACEHOLDER_PACKAGE_NAME + ".placeholder";
|
||||
private static final ComponentName PLACEHOLDER_COMPONENT_NAME = new ComponentName(
|
||||
PLACEHOLDER_PACKAGE_NAME, PLACEHOLDER_CLASS_NAME);
|
||||
private static final String PLACEHOLDER_DIALOG_TITLE = "title";
|
||||
|
||||
private static final String SOFTWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS;
|
||||
private static final String HARDWARE_SHORTCUT_KEY =
|
||||
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE;
|
||||
|
||||
private TestAccessibilityShortcutPreferenceFragment mFragment;
|
||||
private PreferenceScreen mScreen;
|
||||
private Context mContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private PreferenceManager mPreferenceManager;
|
||||
|
||||
@Before
|
||||
public void setUpTestFragment() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mFragment = spy(new TestAccessibilityShortcutPreferenceFragment());
|
||||
when(mFragment.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
when(mFragment.getPreferenceManager().getContext()).thenReturn(mContext);
|
||||
when(mFragment.getContext()).thenReturn(mContext);
|
||||
mScreen = spy(new PreferenceScreen(mContext, null));
|
||||
when(mScreen.getPreferenceManager()).thenReturn(mPreferenceManager);
|
||||
doReturn(mScreen).when(mFragment).getPreferenceScreen();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_assignDefaultValueToVariable() {
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
// Compare to default UserShortcutType
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
|
||||
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSharedPreference_assignToVariable() {
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
|
||||
putUserShortcutTypeIntoSharedPreference(mContext, hardwareShortcut);
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
mFragment.mShortcutPreference.setChecked(false);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(AccessibilityUtil.UserShortcutType.EMPTY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
final PreferredShortcut hardwareShortcut = new PreferredShortcut(
|
||||
PLACEHOLDER_COMPONENT_NAME.flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
PreferredShortcuts.saveUserShortcutType(mContext, hardwareShortcut);
|
||||
mFragment.mShortcutPreference.setChecked(true);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
|
||||
final int checkboxValue = mFragment.getShortcutTypeCheckBoxValue();
|
||||
assertThat(checkboxValue).isEqualTo(AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_assignToVariable() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, AccessibilityDialogUtils.DialogType.EDIT_SHORTCUT_GENERIC,
|
||||
PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
null);
|
||||
mFragment.mShortcutPreference = shortcutPreference;
|
||||
|
||||
savedInstanceState.putInt(KEY_SAVED_USER_SHORTCUT_TYPE,
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
mFragment.onCreate(savedInstanceState);
|
||||
mFragment.setupEditShortcutDialog(dialog);
|
||||
final int value = mFragment.getShortcutTypeCheckBoxValue();
|
||||
mFragment.saveNonEmptyUserShortcutType(value);
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
mFragment.getComponentName().flattenToString(),
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE);
|
||||
assertThat(expectedType).isEqualTo(
|
||||
AccessibilityUtil.UserShortcutType.SOFTWARE
|
||||
| AccessibilityUtil.UserShortcutType.HARDWARE);
|
||||
}
|
||||
|
||||
private void callEmptyOnClicked(DialogInterface dialog, int which) {}
|
||||
|
||||
private void putStringIntoSettings(String key, String componentName) {
|
||||
Settings.Secure.putString(mContext.getContentResolver(), key, componentName);
|
||||
}
|
||||
|
||||
private void putUserShortcutTypeIntoSharedPreference(Context context,
|
||||
PreferredShortcut shortcut) {
|
||||
PreferredShortcuts.saveUserShortcutType(context, shortcut);
|
||||
}
|
||||
|
||||
public static class TestAccessibilityShortcutPreferenceFragment
|
||||
extends AccessibilityShortcutPreferenceFragment {
|
||||
@Override
|
||||
protected ComponentName getComponentName() {
|
||||
return PLACEHOLDER_COMPONENT_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CharSequence getLabelName() {
|
||||
return PLACEHOLDER_PACKAGE_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -18,13 +18,19 @@ package com.android.settings.accessibility;
|
||||
|
||||
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.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.AnimatedImageDrawable;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.net.Uri;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -34,18 +40,22 @@ import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/** Tests for {@link AnimatedImagePreference}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AnimatedImagePreferenceTest {
|
||||
private final Context mContext = RuntimeEnvironment.application;
|
||||
private Uri mImageUri;
|
||||
private View mRootView;
|
||||
private PreferenceViewHolder mViewHolder;
|
||||
@@ -54,32 +64,53 @@ public class AnimatedImagePreferenceTest {
|
||||
@Spy
|
||||
private ImageView mImageView;
|
||||
|
||||
@Mock
|
||||
private AnimatedImageDrawable mAnimatedImageDrawable;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
final LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||
mRootView = spy(inflater.inflate(R.layout.preference_animated_image, /* root= */ null));
|
||||
mViewHolder = spy(PreferenceViewHolder.createInstanceForTests(mRootView));
|
||||
mImageView = spy(new ImageView(context));
|
||||
mImageView = spy(new ImageView(mContext));
|
||||
|
||||
mAnimatedImagePreference = new AnimatedImagePreference(context);
|
||||
mAnimatedImagePreference = new AnimatedImagePreference(mContext);
|
||||
mImageUri = new Uri.Builder().build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readImageUri_animatedImage_startAnimation() {
|
||||
public void playAnimation_animatedImageDrawable_success() {
|
||||
final AnimatedImageDrawable drawable = mock(AnimatedImageDrawable.class);
|
||||
doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
|
||||
doReturn(mAnimatedImageDrawable).when(mImageView).getDrawable();
|
||||
doReturn(drawable).when(mImageView).getDrawable();
|
||||
|
||||
mAnimatedImagePreference.setImageUri(mImageUri);
|
||||
mAnimatedImagePreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(mAnimatedImageDrawable).start();
|
||||
verify(drawable).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playAnimation_animatedVectorDrawable_success() {
|
||||
final AnimatedVectorDrawable drawable = mock(AnimatedVectorDrawable.class);
|
||||
doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
|
||||
doReturn(drawable).when(mImageView).getDrawable();
|
||||
|
||||
mAnimatedImagePreference.setImageUri(mImageUri);
|
||||
mAnimatedImagePreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(drawable).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playAnimation_animationDrawable_success() {
|
||||
final AnimationDrawable drawable = mock(AnimationDrawable.class);
|
||||
doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
|
||||
doReturn(drawable).when(mImageView).getDrawable();
|
||||
|
||||
mAnimatedImagePreference.setImageUri(mImageUri);
|
||||
mAnimatedImagePreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(drawable).start();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -102,4 +133,22 @@ public class AnimatedImagePreferenceTest {
|
||||
|
||||
assertThat(mImageView.getMaxHeight()).isEqualTo(maxHeight);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setImageUriAndRebindViewHolder_lottieImageFromRawFolder_setAnimation() {
|
||||
final int fakeLottieResId = 111111;
|
||||
final Uri lottieImageUri =
|
||||
new Uri.Builder().scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
|
||||
.authority(mContext.getPackageName())
|
||||
.appendPath(String.valueOf(fakeLottieResId))
|
||||
.build();
|
||||
final LottieAnimationView lottieView = spy(new LottieAnimationView(mContext));
|
||||
doReturn(mImageView).when(mRootView).findViewById(R.id.animated_img);
|
||||
doReturn(lottieView).when(mRootView).findViewById(R.id.lottie_view);
|
||||
|
||||
mAnimatedImagePreference.setImageUri(lottieImageUri);
|
||||
mAnimatedImagePreference.onBindViewHolder(mViewHolder);
|
||||
|
||||
verify(lottieView).setAnimation(any(InputStream.class), eq(null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityEditDialogUtils.CustomButton;
|
||||
import static com.android.settings.accessibility.AccessibilityDialogUtils.CustomButton;
|
||||
import static com.android.settings.accessibility.MagnificationCapabilities.MagnificationMode;
|
||||
import static com.android.settings.accessibility.MagnificationModePreferenceController.MagnificationModeInfo;
|
||||
import static com.android.settings.accessibility.MagnificationPreferenceFragment.ON;
|
||||
|
||||
@@ -43,7 +43,7 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityUtil.UserShortcutType;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
|
||||
@@ -118,9 +118,9 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
@Test
|
||||
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
|
||||
mFragment.mComponentName = PLACEHOLDER_COMPONENT_NAME;
|
||||
|
||||
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
putStringIntoSettings(HARDWARE_SHORTCUT_KEY, PLACEHOLDER_COMPONENT_NAME.flattenToString());
|
||||
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
@@ -145,7 +145,7 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
@@ -163,7 +163,7 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
@Test
|
||||
public void setupEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
@@ -185,7 +185,7 @@ public class ToggleFeaturePreferenceFragmentTest {
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_assignToVariable() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_GENERIC, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
|
||||
@@ -53,7 +53,7 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.DialogCreatable;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.accessibility.AccessibilityEditDialogUtils.DialogType;
|
||||
import com.android.settings.accessibility.AccessibilityDialogUtils.DialogType;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowSettingsPreferenceFragment;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
@@ -186,6 +186,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
public void updateShortcutPreferenceData_hasValueInSettings_assignToVariable() {
|
||||
putStringIntoSettings(SOFTWARE_SHORTCUT_KEY, MAGNIFICATION_CONTROLLER_NAME);
|
||||
setMagnificationTripleTapEnabled(/* enabled= */ true);
|
||||
|
||||
mFragment.updateShortcutPreferenceData();
|
||||
|
||||
final int expectedType = PreferredShortcuts.retrieveUserShortcutType(mContext,
|
||||
@@ -209,7 +210,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
@Test
|
||||
public void setupMagnificationEditShortcutDialog_shortcutPreferenceOff_checkboxIsEmptyValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_MAGNIFICATION, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
@@ -226,7 +227,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
@Test
|
||||
public void setupMagnificationEditShortcutDialog_shortcutPreferenceOn_checkboxIsSavedValue() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_MAGNIFICATION, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final ShortcutPreference shortcutPreference = new ShortcutPreference(mContext, /* attrs= */
|
||||
@@ -247,7 +248,7 @@ public class ToggleScreenMagnificationPreferenceFragmentTest {
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void restoreValueFromSavedInstanceState_assignToVariable() {
|
||||
mContext.setTheme(R.style.Theme_AppCompat);
|
||||
final AlertDialog dialog = AccessibilityEditDialogUtils.showEditShortcutDialog(
|
||||
final AlertDialog dialog = AccessibilityDialogUtils.showEditShortcutDialog(
|
||||
mContext, DialogType.EDIT_SHORTCUT_MAGNIFICATION, PLACEHOLDER_DIALOG_TITLE,
|
||||
this::callEmptyOnClicked);
|
||||
final Bundle savedInstanceState = new Bundle();
|
||||
|
||||
@@ -134,7 +134,7 @@ public class AppBatteryPreferenceControllerTest {
|
||||
mController.updateBattery();
|
||||
|
||||
assertThat(mBatteryPreference.getSummary())
|
||||
.isEqualTo("No battery use since last full charge");
|
||||
.isEqualTo("No battery use for past 24 hours");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -147,7 +147,7 @@ public class AppBatteryPreferenceControllerTest {
|
||||
|
||||
mController.updateBattery();
|
||||
|
||||
assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use since last full charge");
|
||||
assertThat(mBatteryPreference.getSummary()).isEqualTo("60% use for past 24 hours");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.LocaleList;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
@@ -100,6 +101,8 @@ public final class BatteryChartPreferenceControllerTest {
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mMetricsFeatureProvider = mFeatureFactory.metricsFeatureProvider;
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mContext.getResources().getConfiguration().setLocales(
|
||||
new LocaleList(new Locale("en_US")));
|
||||
mBatteryChartPreferenceController = createController();
|
||||
mBatteryChartPreferenceController.mPrefContext = mContext;
|
||||
mBatteryChartPreferenceController.mAppListPrefGroup = mAppListGroup;
|
||||
@@ -573,14 +576,12 @@ public final class BatteryChartPreferenceControllerTest {
|
||||
// Verifies the title in the preference group.
|
||||
verify(mBatteryChartPreferenceController.mAppListPrefGroup)
|
||||
.setTitle(captor.capture());
|
||||
assertThat(captor.getValue())
|
||||
.isEqualTo("App usage for 4 pm - 7 am");
|
||||
assertThat(captor.getValue()).isEqualTo("App usage for 4 - 7");
|
||||
// Verifies the title in the expandable divider.
|
||||
captor = ArgumentCaptor.forClass(String.class);
|
||||
verify(mBatteryChartPreferenceController.mExpandDividerPreference)
|
||||
.setTitle(captor.capture());
|
||||
assertThat(captor.getValue())
|
||||
.isEqualTo("System usage for 4 pm - 7 am");
|
||||
assertThat(captor.getValue()).isEqualTo("System usage for 4 - 7");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -716,7 +717,8 @@ public final class BatteryChartPreferenceControllerTest {
|
||||
private void setUpBatteryHistoryKeys() {
|
||||
mBatteryChartPreferenceController.mBatteryHistoryKeys =
|
||||
new long[] {1619196786769L, 0L, 1619247636826L};
|
||||
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.utcToLocalTimeHour(
|
||||
mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
// Simulates the locale in GMT.
|
||||
ConvertUtils.sSimpleDateFormatForHour
|
||||
.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.Context;
|
||||
import android.os.LocaleList;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
@@ -41,6 +42,7 @@ import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@@ -60,6 +62,8 @@ public final class BatteryChartViewTest {
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider;
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mContext.getResources().getConfiguration().setLocales(
|
||||
new LocaleList(new Locale("en_US")));
|
||||
mBatteryChartView = new BatteryChartView(mContext);
|
||||
doReturn(mockAccessibilityManager).when(mContext)
|
||||
.getSystemService(AccessibilityManager.class);
|
||||
@@ -234,11 +238,11 @@ public final class BatteryChartViewTest {
|
||||
final long timestamp = 1619196786769L;
|
||||
ConvertUtils.sSimpleDateFormatForHour = null;
|
||||
// Invokes the method first to create the SimpleDateFormat.
|
||||
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.utcToLocalTimeHour(
|
||||
mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.sSimpleDateFormatForHour
|
||||
.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
|
||||
final String[] expectedTimestamps =
|
||||
new String[] {"9 am", "5 pm", "1 am", "9 am"};
|
||||
final String[] expectedTimestamps = new String[] {"00", "06", "12", "18", "00"};
|
||||
|
||||
mBatteryChartView.setLatestTimestamp(timestamp);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
@@ -315,6 +316,7 @@ public final class ConvertUtilsTest {
|
||||
.isEqualTo(entry.mConsumePower * ratio);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUtcToLocalTime_returnExpectedResult() {
|
||||
ConvertUtils.sZoneId = null;
|
||||
ConvertUtils.sLocale = null;
|
||||
@@ -322,48 +324,76 @@ public final class ConvertUtilsTest {
|
||||
final String expectedZoneId = "America/Los_Angeles";
|
||||
ConvertUtils.sSimpleDateFormat = null;
|
||||
// Invokes the method first to create the SimpleDateFormat.
|
||||
ConvertUtils.utcToLocalTime(/*timestamp=*/ 0);
|
||||
ConvertUtils.utcToLocalTime(mContext, /*timestamp=*/ 0);
|
||||
ConvertUtils.sSimpleDateFormat
|
||||
.setTimeZone(TimeZone.getTimeZone(expectedZoneId));
|
||||
mContext.getResources().getConfiguration().setLocales(
|
||||
new LocaleList(new Locale("en_US")));
|
||||
|
||||
assertThat(ConvertUtils.utcToLocalTime(timestamp))
|
||||
.isEqualTo("Apr 23,2021 09:53:06");
|
||||
assertThat(ConvertUtils.utcToLocalTime(mContext, timestamp))
|
||||
.isEqualTo("Apr 24,2021 00:53:06");
|
||||
assertThat(ConvertUtils.sZoneId).isNotEqualTo(expectedZoneId);
|
||||
assertThat(ConvertUtils.sLocale).isEqualTo(Locale.getDefault());
|
||||
assertThat(ConvertUtils.sLocale).isEqualTo(new Locale("en_US"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUtcToLocalTimeHour_12HourFormat_returnExpectedResult() {
|
||||
ConvertUtils.sZoneIdForHour = null;
|
||||
ConvertUtils.sLocaleForHour = null;
|
||||
final long timestamp = 1619196786769L;
|
||||
final long timestamp = 1619000086769L;
|
||||
final String expectedZoneId = "America/Los_Angeles";
|
||||
ConvertUtils.sSimpleDateFormatForHour = null;
|
||||
// Invokes the method first to create the SimpleDateFormat.
|
||||
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.utcToLocalTimeHour(
|
||||
mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.sSimpleDateFormatForHour
|
||||
.setTimeZone(TimeZone.getTimeZone(expectedZoneId));
|
||||
mContext.getResources().getConfiguration().setLocales(
|
||||
new LocaleList(new Locale("en_US")));
|
||||
|
||||
assertThat(ConvertUtils.utcToLocalTimeHour(
|
||||
timestamp, /*is24HourFormat=*/ false)).isEqualTo("9 am");
|
||||
mContext, timestamp, /*is24HourFormat=*/ false)).isEqualTo("6");
|
||||
assertThat(ConvertUtils.sZoneIdForHour).isNotEqualTo(expectedZoneId);
|
||||
assertThat(ConvertUtils.sLocaleForHour).isEqualTo(Locale.getDefault());
|
||||
assertThat(ConvertUtils.sLocaleForHour).isEqualTo(new Locale("en_US"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUtcToLocalTimeHour_24HourFormat_returnExpectedResult() {
|
||||
ConvertUtils.sZoneIdForHour = null;
|
||||
ConvertUtils.sLocaleForHour = null;
|
||||
final long timestamp = 1619196786769L;
|
||||
final long timestamp = 1619000086769L;
|
||||
final String expectedZoneId = "America/Los_Angeles";
|
||||
ConvertUtils.sSimpleDateFormatForHour = null;
|
||||
// Invokes the method first to create the SimpleDateFormat.
|
||||
ConvertUtils.utcToLocalTimeHour(/*timestamp=*/ 0, /*is24HourFormat=*/ true);
|
||||
ConvertUtils.utcToLocalTimeHour(
|
||||
mContext, /*timestamp=*/ 0, /*is24HourFormat=*/ false);
|
||||
ConvertUtils.sSimpleDateFormatForHour
|
||||
.setTimeZone(TimeZone.getTimeZone(expectedZoneId));
|
||||
mContext.getResources().getConfiguration().setLocales(
|
||||
new LocaleList(new Locale("en_US")));
|
||||
|
||||
assertThat(ConvertUtils.utcToLocalTimeHour(
|
||||
timestamp, /*is24HourFormat=*/ true)).isEqualTo("09");
|
||||
mContext, timestamp, /*is24HourFormat=*/ true)).isEqualTo("18");
|
||||
assertThat(ConvertUtils.sZoneIdForHour).isNotEqualTo(expectedZoneId);
|
||||
assertThat(ConvertUtils.sLocaleForHour).isEqualTo(Locale.getDefault());
|
||||
assertThat(ConvertUtils.sLocaleForHour).isEqualTo(new Locale("en_US"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocale_nullContext_returnDefaultLocale() {
|
||||
assertThat(ConvertUtils.getLocale(/*context=*/ null))
|
||||
.isEqualTo(Locale.getDefault());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocale_nullLocaleList_returnDefaultLocale() {
|
||||
mContext.getResources().getConfiguration().setLocales(null);
|
||||
assertThat(ConvertUtils.getLocale(mContext)).isEqualTo(Locale.getDefault());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getLocale_emptyLocaleList_returnDefaultLocale() {
|
||||
mContext.getResources().getConfiguration().setLocales(new LocaleList());
|
||||
assertThat(ConvertUtils.getLocale(mContext)).isEqualTo(Locale.getDefault());
|
||||
}
|
||||
|
||||
private static BatteryHistEntry createBatteryHistEntry(
|
||||
|
||||
@@ -142,6 +142,16 @@ public class ProviderModelSliceTest {
|
||||
mockBuilder();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getBroadcastIntent_shouldHaveFlagReceiverForeground() {
|
||||
final PendingIntent pendingIntent = mMockProviderModelSlice.getBroadcastIntent(mContext);
|
||||
|
||||
final int flags = pendingIntent.getIntent().getFlags();
|
||||
assertThat(flags & Intent.FLAG_RECEIVER_FOREGROUND)
|
||||
.isEqualTo(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void getSlice_noWifiAndHasCarrierNoData_oneCarrier() {
|
||||
|
||||
Reference in New Issue
Block a user