Snap for 9705326 from 9e2e47c553 to udc-release
Change-Id: I2ee82479c6dd09d36711aacdc38261b28766bb4c
This commit is contained in:
65
res/layout/locale_dialog.xml
Normal file
65
res/layout/locale_dialog.xml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2023 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/admin_details_dialog_padding"
|
||||
android:paddingStart="@dimen/admin_details_dialog_padding"
|
||||
android:paddingEnd="@dimen/admin_details_dialog_padding"
|
||||
android:paddingBottom="@dimen/admin_details_dialog_padding_bottom"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal"
|
||||
android:paddingBottom="@dimen/admin_details_dialog_title_bottom_padding">
|
||||
<ImageView
|
||||
android:layout_width="@dimen/admin_details_dialog_icon_size"
|
||||
android:layout_height="@dimen/admin_details_dialog_icon_size"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/ic_settings_language"
|
||||
android:tint="#4F8438"
|
||||
android:contentDescription="@null"/>
|
||||
<TextView
|
||||
android:id="@+id/dialog_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textAppearance="@style/TextAppearance.AdminDialogTitle"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fadeScrollbars="false">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/dialog_msg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLength="200"
|
||||
android:gravity="left"
|
||||
android:autoLink="email|phone|web"
|
||||
android:textColor="?android:attr/textColorSecondary"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@@ -228,6 +228,11 @@
|
||||
<!-- Summary of checkbox for enabling Bluetooth LE audio [CHAR LIMIT=none]-->
|
||||
<string name="bluetooth_enable_leaudio_summary">Enables Bluetooth LE audio feature if the device supports LE audio hardware capabilities.</string>
|
||||
|
||||
<!-- Setting Checkbox title for enabling Bluetooth LE Audio Allow List. [CHAR LIMIT=none] -->
|
||||
<string name="bluetooth_enable_leaudio_allow_list">Enable Bluetooth LE audio Allow List</string>
|
||||
<!-- Summary of checkbox for enabling Bluetooth LE audio Allow List [CHAR LIMIT=none]-->
|
||||
<string name="bluetooth_enable_leaudio_allow_list_summary">Enable Bluetooth LE audio allow list feature.</string>
|
||||
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
<string name="connected_device_media_device_title">Media devices</string>
|
||||
<!-- Title for Bluetooth device group with media capability group [CHAR LIMIT=none]-->
|
||||
@@ -372,6 +377,21 @@
|
||||
<!-- Link for Locale helper page. [CHAR LIMIT=NONE]-->
|
||||
<string name="link_locale_picker_footer_learn_more" translatable="false">https://support.google.com/android?p=per_language_app_settings</string>
|
||||
|
||||
<!-- Title for asking to change system locale or not. [CHAR LIMIT=50]-->
|
||||
<string name="title_change_system_locale">Change system language to %s ?</string>
|
||||
|
||||
<!-- The text of the confirmation dialog showing the system locale will be changed. [CHAR LIMIT=NONE]-->
|
||||
<string name="desc_notice_device_locale_settings_change">Your device settings and regional preferences will change.</string>
|
||||
|
||||
<!-- A dialog button for confirmmation of system locale change. [CHAR LIMIT=25]-->
|
||||
<string name="button_label_confirmation_of_system_locale_change">Change</string>
|
||||
|
||||
<!-- Title for saying this selected locale is unavailable to use. [CHAR LIMIT=50]-->
|
||||
<string name="title_unavailable_locale">%s not available</string>
|
||||
|
||||
<!-- The text of the confirmation dialog for saying this selected locale is unavailable to use. [CHAR LIMIT=NONE]-->
|
||||
<string name="desc_unavailable_locale">This language can’t be used as a system language, but you’ve let apps and websites know you prefer this language.</string>
|
||||
|
||||
<!-- Regional Preferences begin -->
|
||||
<!-- The title of the menu entry of regional preferences. [CHAR LIMIT=50] -->
|
||||
<string name="regional_preferences_title">Regional preferences</string>
|
||||
|
||||
@@ -345,6 +345,11 @@
|
||||
android:title="@string/bluetooth_enable_leaudio"
|
||||
android:summary="@string/bluetooth_enable_leaudio_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_enable_leaudio_allow_list"
|
||||
android:title="@string/bluetooth_enable_leaudio_allow_list"
|
||||
android:summary="@string/bluetooth_enable_leaudio_allow_list_summary" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="bluetooth_disable_le_audio_hw_offload"
|
||||
android:title="@string/bluetooth_disable_le_audio_hw_offload" />
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
@@ -45,13 +44,13 @@ public class CameraFlashNotificationPreferenceController extends TogglePreferenc
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.System.getInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_CAMERA_FLASH_NOTIFICATION, OFF) != OFF;
|
||||
Settings.System.CAMERA_FLASH_NOTIFICATION, OFF) != OFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setChecked(boolean isChecked) {
|
||||
return Settings.System.putInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_CAMERA_FLASH_NOTIFICATION, (isChecked ? ON : OFF));
|
||||
Settings.System.CAMERA_FLASH_NOTIFICATION, (isChecked ? ON : OFF));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,8 +19,6 @@ package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
@@ -95,10 +93,10 @@ public class FlashNotificationsPreviewPreferenceController extends
|
||||
@NonNull Lifecycle.Event event) {
|
||||
if (event == Lifecycle.Event.ON_RESUME) {
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.System.getUriFor(SETTING_KEY_CAMERA_FLASH_NOTIFICATION),
|
||||
Settings.System.getUriFor(Settings.System.CAMERA_FLASH_NOTIFICATION),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.System.getUriFor(SETTING_KEY_SCREEN_FLASH_NOTIFICATION),
|
||||
Settings.System.getUriFor(Settings.System.SCREEN_FLASH_NOTIFICATION),
|
||||
/* notifyForDescendants= */ false, mContentObserver);
|
||||
} else if (event == Lifecycle.Event.ON_PAUSE) {
|
||||
mContentResolver.unregisterContentObserver(mContentObserver);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.camera2.CameraAccessException;
|
||||
import android.hardware.camera2.CameraCharacteristics;
|
||||
@@ -43,19 +41,10 @@ class FlashNotificationsUtil {
|
||||
static final String EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE =
|
||||
"com.android.internal.intent.extra.FLASH_NOTIFICATION_PREVIEW_TYPE";
|
||||
|
||||
static final String SETTING_KEY_CAMERA_FLASH_NOTIFICATION =
|
||||
"camera_flash_notification";
|
||||
static final String SETTING_KEY_SCREEN_FLASH_NOTIFICATION =
|
||||
"screen_flash_notification";
|
||||
static final String SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR =
|
||||
"screen_flash_notification_color_global";
|
||||
|
||||
static final int TYPE_SHORT_PREVIEW = 0;
|
||||
static final int TYPE_LONG_PREVIEW = 1;
|
||||
|
||||
static final int DEFAULT_SCREEN_FLASH_COLOR =
|
||||
ScreenFlashNotificationColor.YELLOW.mColorInt;
|
||||
|
||||
static final int DEFAULT_SCREEN_FLASH_COLOR = ScreenFlashNotificationColor.YELLOW.mColorInt;
|
||||
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
@@ -128,9 +117,9 @@ class FlashNotificationsUtil {
|
||||
|
||||
final boolean isTorchAvailable = FlashNotificationsUtil.isTorchAvailable(context);
|
||||
final boolean isCameraFlashEnabled = Settings.System.getInt(context.getContentResolver(),
|
||||
SETTING_KEY_CAMERA_FLASH_NOTIFICATION, State.OFF) != State.OFF;
|
||||
Settings.System.CAMERA_FLASH_NOTIFICATION, State.OFF) != State.OFF;
|
||||
final boolean isScreenFlashEnabled = Settings.System.getInt(context.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION, State.OFF) != State.OFF;
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION, State.OFF) != State.OFF;
|
||||
|
||||
return ((isTorchAvailable && isCameraFlashEnabled) ? State.CAMERA : State.OFF)
|
||||
| (isScreenFlashEnabled ? State.SCREEN : State.OFF);
|
||||
|
||||
@@ -19,8 +19,6 @@ package com.android.settings.accessibility;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.DEFAULT_SCREEN_FLASH_COLOR;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
@@ -59,7 +57,7 @@ public class ScreenFlashNotificationPreferenceController extends TogglePreferenc
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
return Settings.System.getInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION, OFF) != OFF;
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION, OFF) != OFF;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,7 +65,7 @@ public class ScreenFlashNotificationPreferenceController extends TogglePreferenc
|
||||
if (isChecked) checkAndSetInitialColor();
|
||||
|
||||
return Settings.System.putInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION, (isChecked ? ON : OFF));
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION, (isChecked ? ON : OFF));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +77,8 @@ public class ScreenFlashNotificationPreferenceController extends TogglePreferenc
|
||||
public CharSequence getSummary() {
|
||||
return FlashNotificationsUtil.getColorDescriptionText(mContext,
|
||||
Settings.System.getInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, DEFAULT_SCREEN_FLASH_COLOR));
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
|
||||
DEFAULT_SCREEN_FLASH_COLOR));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,12 +93,12 @@ public class ScreenFlashNotificationPreferenceController extends TogglePreferenc
|
||||
if (getPreferenceKey().equals(preference.getKey()) && mParentFragment != null) {
|
||||
|
||||
final int initialColor = Settings.System.getInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR,
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR,
|
||||
DEFAULT_SCREEN_FLASH_COLOR);
|
||||
|
||||
final Consumer<Integer> consumer = color -> {
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, color);
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, color);
|
||||
refreshColorSummary();
|
||||
};
|
||||
|
||||
@@ -115,10 +114,10 @@ public class ScreenFlashNotificationPreferenceController extends TogglePreferenc
|
||||
|
||||
private void checkAndSetInitialColor() {
|
||||
if (Settings.System.getInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT)
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT)
|
||||
== Color.TRANSPARENT) {
|
||||
Settings.System.putInt(mContext.getContentResolver(),
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, DEFAULT_SCREEN_FLASH_COLOR);
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, DEFAULT_SCREEN_FLASH_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,11 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.credentials.CredentialManager;
|
||||
import android.credentials.ListEnabledProvidersException;
|
||||
import android.credentials.ListEnabledProvidersResponse;
|
||||
import android.credentials.CredentialProviderInfo;
|
||||
import android.credentials.SetEnabledProvidersException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.os.OutcomeReceiver;
|
||||
import android.os.UserHandle;
|
||||
import android.util.IconDrawableFactory;
|
||||
@@ -71,10 +68,9 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
|
||||
private final PackageManager mPm;
|
||||
private final IconDrawableFactory mIconFactory;
|
||||
private final List<ServiceInfo> mServices;
|
||||
private final List<CredentialProviderInfo> mServices;
|
||||
private final Set<String> mEnabledPackageNames;
|
||||
private final @Nullable CredentialManager mCredentialManager;
|
||||
private final CancellationSignal mCancellationSignal = new CancellationSignal();
|
||||
private final Executor mExecutor;
|
||||
private final Map<String, SwitchPreference> mPrefs = new HashMap<>(); // key is package name
|
||||
|
||||
@@ -132,42 +128,20 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
lifecycleOwner,
|
||||
mCredentialManager.getCredentialProviderServices(
|
||||
getUser(), CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY));
|
||||
|
||||
mCredentialManager.listEnabledProviders(
|
||||
mCancellationSignal,
|
||||
mExecutor,
|
||||
new OutcomeReceiver<ListEnabledProvidersResponse, ListEnabledProvidersException>() {
|
||||
@Override
|
||||
public void onResult(ListEnabledProvidersResponse result) {
|
||||
Set<String> enabledPackages = new HashSet<>();
|
||||
for (String flattenedComponentName : result.getProviderComponentNames()) {
|
||||
ComponentName cn =
|
||||
ComponentName.unflattenFromString(flattenedComponentName);
|
||||
if (cn != null) {
|
||||
enabledPackages.add(cn.getPackageName());
|
||||
}
|
||||
}
|
||||
|
||||
setEnabledPackageNames(enabledPackages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ListEnabledProvidersException e) {
|
||||
Log.e(TAG, "listEnabledProviders error: " + e.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setAvailableServices(LifecycleOwner lifecycleOwner, List<ServiceInfo> availableServices) {
|
||||
void setAvailableServices(
|
||||
LifecycleOwner lifecycleOwner, List<CredentialProviderInfo> availableServices) {
|
||||
mServices.clear();
|
||||
mServices.addAll(availableServices);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setEnabledPackageNames(Set<String> enabledPackages) {
|
||||
mEnabledPackageNames.clear();
|
||||
mEnabledPackageNames.addAll(enabledPackages);
|
||||
for (CredentialProviderInfo cpi : availableServices) {
|
||||
if (cpi.isEnabled()) {
|
||||
mEnabledPackageNames.add(cpi.getServiceInfo().packageName);
|
||||
}
|
||||
}
|
||||
|
||||
for (String packageName : mPrefs.keySet()) {
|
||||
mPrefs.get(packageName).setChecked(mEnabledPackageNames.contains(packageName));
|
||||
@@ -189,22 +163,22 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
PreferenceGroup group = screen.findPreference(getPreferenceKey());
|
||||
Context context = screen.getContext();
|
||||
|
||||
for (ServiceInfo serviceInfo : mServices) {
|
||||
CharSequence title = "";
|
||||
if (serviceInfo.nonLocalizedLabel != null) {
|
||||
title = serviceInfo.loadLabel(mPm);
|
||||
}
|
||||
|
||||
group.addPreference(
|
||||
addProviderPreference(
|
||||
context,
|
||||
title,
|
||||
mIconFactory.getBadgedIcon(
|
||||
serviceInfo, serviceInfo.applicationInfo, getUser()),
|
||||
serviceInfo.packageName));
|
||||
for (CredentialProviderInfo service : mServices) {
|
||||
group.addPreference(createPreference(context, service));
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates a preference object based on the provider info. */
|
||||
@VisibleForTesting
|
||||
public SwitchPreference createPreference(Context context, CredentialProviderInfo service) {
|
||||
CharSequence label = service.getLabel(context);
|
||||
return addProviderPreference(
|
||||
context,
|
||||
label == null ? "" : label,
|
||||
service.getServiceIcon(mContext),
|
||||
service.getServiceInfo().packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the package name as an enabled credential manager provider.
|
||||
*
|
||||
@@ -246,9 +220,10 @@ public class CredentialManagerPreferenceController extends BasePreferenceControl
|
||||
public List<String> getEnabledSettings() {
|
||||
// Get all the component names that match the enabled package names.
|
||||
List<String> enabledServices = new ArrayList<>();
|
||||
for (ServiceInfo service : mServices) {
|
||||
if (mEnabledPackageNames.contains(service.packageName)) {
|
||||
enabledServices.add(service.getComponentName().flattenToString());
|
||||
for (CredentialProviderInfo service : mServices) {
|
||||
ComponentName cn = service.getServiceInfo().getComponentName();
|
||||
if (mEnabledPackageNames.contains(service.getServiceInfo().packageName)) {
|
||||
enabledServices.add(cn.flattenToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.bluetooth.BluetoothStatusCodes;
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
/**
|
||||
* Preference controller to control Bluetooth LE audio feature
|
||||
*/
|
||||
public class BluetoothLeAudioAllowListPreferenceController
|
||||
extends DeveloperOptionsPreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, PreferenceControllerMixin {
|
||||
|
||||
private static final String PREFERENCE_KEY = "bluetooth_enable_leaudio_allow_list";
|
||||
|
||||
private static final String LE_AUDIO_ALLOW_LIST_SWITCH_SUPPORT_PROPERTY =
|
||||
"ro.bluetooth.leaudio_allow_list.supported";
|
||||
@VisibleForTesting
|
||||
static final String LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY =
|
||||
"persist.bluetooth.leaudio.enable_allow_list";
|
||||
|
||||
private static final String LE_AUDIO_DYNAMIC_SWITCH_PROPERTY =
|
||||
"ro.bluetooth.leaudio_switcher.supported";
|
||||
@VisibleForTesting
|
||||
static final String LE_AUDIO_DYNAMIC_ENABLED_PROPERTY =
|
||||
"persist.bluetooth.leaudio_switcher.enabled";
|
||||
|
||||
@VisibleForTesting
|
||||
BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private final DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
@VisibleForTesting
|
||||
boolean mChanged = false;
|
||||
|
||||
public BluetoothLeAudioAllowListPreferenceController(Context context,
|
||||
DevelopmentSettingsDashboardFragment fragment) {
|
||||
super(context);
|
||||
mFragment = fragment;
|
||||
mBluetoothAdapter = context.getSystemService(BluetoothManager.class).getAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return PREFERENCE_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
BluetoothRebootDialog.show(mFragment);
|
||||
mChanged = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
if (mBluetoothAdapter == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int leAudioSupportedState = mBluetoothAdapter.isLeAudioSupported();
|
||||
boolean leAudioEnabled = false;
|
||||
|
||||
if ((leAudioSupportedState == BluetoothStatusCodes.FEATURE_SUPPORTED)
|
||||
|| (leAudioSupportedState == BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED
|
||||
&& SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_SWITCH_PROPERTY, false)
|
||||
&& SystemProperties.getBoolean(LE_AUDIO_DYNAMIC_ENABLED_PROPERTY, false))) {
|
||||
leAudioEnabled = true;
|
||||
}
|
||||
|
||||
final boolean leAudioAllowListSupport =
|
||||
SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_SWITCH_SUPPORT_PROPERTY, false);
|
||||
|
||||
if (leAudioEnabled && leAudioAllowListSupport) {
|
||||
final boolean leAudioAllowListEnabled =
|
||||
SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
|
||||
((SwitchPreference) mPreference).setChecked(leAudioAllowListEnabled);
|
||||
} else {
|
||||
mPreference.setEnabled(false);
|
||||
((SwitchPreference) mPreference).setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the RebootDialog confirm is clicked.
|
||||
*/
|
||||
public void onRebootDialogConfirmed() {
|
||||
if (!mChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean leAudioAllowListEnabled =
|
||||
SystemProperties.getBoolean(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
|
||||
SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY,
|
||||
Boolean.toString(!leAudioAllowListEnabled));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the RebootDialog cancel is clicked.
|
||||
*/
|
||||
public void onRebootDialogCanceled() {
|
||||
mChanged = false;
|
||||
}
|
||||
}
|
||||
@@ -389,6 +389,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
getDevelopmentOptionsController(
|
||||
BluetoothLeAudioPreferenceController.class);
|
||||
leAudioFeatureController.onRebootDialogConfirmed();
|
||||
|
||||
final BluetoothLeAudioAllowListPreferenceController leAudioAllowListController =
|
||||
getDevelopmentOptionsController(
|
||||
BluetoothLeAudioAllowListPreferenceController.class);
|
||||
leAudioAllowListController.onRebootDialogConfirmed();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -406,6 +411,11 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
getDevelopmentOptionsController(
|
||||
BluetoothLeAudioPreferenceController.class);
|
||||
leAudioFeatureController.onRebootDialogCanceled();
|
||||
|
||||
final BluetoothLeAudioAllowListPreferenceController leAudioAllowListController =
|
||||
getDevelopmentOptionsController(
|
||||
BluetoothLeAudioAllowListPreferenceController.class);
|
||||
leAudioAllowListController.onRebootDialogCanceled();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -602,6 +612,7 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new BluetoothAvrcpVersionPreferenceController(context));
|
||||
controllers.add(new BluetoothMapVersionPreferenceController(context));
|
||||
controllers.add(new BluetoothLeAudioPreferenceController(context, fragment));
|
||||
controllers.add(new BluetoothLeAudioAllowListPreferenceController(context, fragment));
|
||||
controllers.add(new BluetoothA2dpHwOffloadPreferenceController(context, fragment));
|
||||
controllers.add(new BluetoothLeAudioHwOffloadPreferenceController(context, fragment));
|
||||
controllers.add(new BluetoothMaxConnectedAudioDevicesPreferenceController(context));
|
||||
|
||||
@@ -118,7 +118,7 @@ public class BatterySaverButtonPreferenceController extends
|
||||
@Override
|
||||
public boolean setChecked(boolean stateOn) {
|
||||
return BatterySaverUtils.setPowerSaveMode(mContext, stateOn,
|
||||
true /* needFirstTimeWarning */);
|
||||
false /* needFirstTimeWarning */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
198
src/com/android/settings/localepicker/LocaleDialogFragment.java
Normal file
198
src/com/android/settings/localepicker/LocaleDialogFragment.java
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.localepicker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.ResultReceiver;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedSettingsFragment;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
/**
|
||||
* Create a dialog for system locale events.
|
||||
*/
|
||||
public class LocaleDialogFragment extends InstrumentedDialogFragment {
|
||||
private static final String TAG = LocaleDialogFragment.class.getSimpleName();
|
||||
|
||||
static final int DIALOG_CONFIRM_SYSTEM_DEFAULT = 0;
|
||||
static final int DIALOG_NOT_AVAILABLE_LOCALE = 1;
|
||||
|
||||
static final String ARG_DIALOG_TYPE = "arg_dialog_type";
|
||||
static final String ARG_TARGET_LOCALE = "arg_target_locale";
|
||||
static final String ARG_RESULT_RECEIVER = "arg_result_receiver";
|
||||
|
||||
/**
|
||||
* Show dialog
|
||||
*/
|
||||
public static void show(
|
||||
@NonNull RestrictedSettingsFragment fragment,
|
||||
int dialogType,
|
||||
LocaleStore.LocaleInfo localeInfo) {
|
||||
show(fragment, dialogType, localeInfo, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show dialog
|
||||
*/
|
||||
public static void show(
|
||||
@NonNull RestrictedSettingsFragment fragment,
|
||||
int dialogType,
|
||||
LocaleStore.LocaleInfo localeInfo,
|
||||
ResultReceiver resultReceiver) {
|
||||
FragmentManager manager = fragment.getChildFragmentManager();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_DIALOG_TYPE, dialogType);
|
||||
args.putSerializable(ARG_TARGET_LOCALE, localeInfo);
|
||||
args.putParcelable(ARG_RESULT_RECEIVER, resultReceiver);
|
||||
|
||||
LocaleDialogFragment localeDialogFragment = new LocaleDialogFragment();
|
||||
localeDialogFragment.setArguments(args);
|
||||
localeDialogFragment.show(manager, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
int dialogType = getArguments().getInt(ARG_DIALOG_TYPE);
|
||||
switch (dialogType) {
|
||||
case DIALOG_CONFIRM_SYSTEM_DEFAULT:
|
||||
return SettingsEnums.DIALOG_SYSTEM_LOCALE_CHANGE;
|
||||
case DIALOG_NOT_AVAILABLE_LOCALE:
|
||||
return SettingsEnums.DIALOG_SYSTEM_LOCALE_UNAVAILABLE;
|
||||
default:
|
||||
return SettingsEnums.DIALOG_SYSTEM_LOCALE_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
LocaleDialogController controller = new LocaleDialogController(this);
|
||||
LocaleDialogController.DialogContent dialogContent = controller.getDialogContent();
|
||||
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(getContext()).inflate(
|
||||
R.layout.locale_dialog, null);
|
||||
setDialogTitle(viewGroup, dialogContent.mTitle);
|
||||
setDialogMessage(viewGroup, dialogContent.mMessage);
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
|
||||
.setView(viewGroup);
|
||||
if (!dialogContent.mPositiveButton.isEmpty()) {
|
||||
builder.setPositiveButton(dialogContent.mPositiveButton, controller);
|
||||
}
|
||||
if (!dialogContent.mNegativeButton.isEmpty()) {
|
||||
builder.setNegativeButton(dialogContent.mNegativeButton, controller);
|
||||
}
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private static void setDialogTitle(View root, String content) {
|
||||
TextView titleView = root.findViewById(R.id.dialog_title);
|
||||
if (titleView == null) {
|
||||
return;
|
||||
}
|
||||
titleView.setText(content);
|
||||
}
|
||||
|
||||
private static void setDialogMessage(View root, String content) {
|
||||
TextView textView = root.findViewById(R.id.dialog_msg);
|
||||
if (textView == null) {
|
||||
return;
|
||||
}
|
||||
textView.setText(content);
|
||||
}
|
||||
|
||||
static class LocaleDialogController implements DialogInterface.OnClickListener {
|
||||
private final Context mContext;
|
||||
private final int mDialogType;
|
||||
private final LocaleStore.LocaleInfo mLocaleInfo;
|
||||
private final ResultReceiver mResultReceiver;
|
||||
|
||||
LocaleDialogController(
|
||||
@NonNull Context context, @NonNull LocaleDialogFragment dialogFragment) {
|
||||
mContext = context;
|
||||
Bundle arguments = dialogFragment.getArguments();
|
||||
mDialogType = arguments.getInt(ARG_DIALOG_TYPE);
|
||||
mLocaleInfo = (LocaleStore.LocaleInfo) arguments.getSerializable(
|
||||
ARG_TARGET_LOCALE);
|
||||
mResultReceiver = (ResultReceiver) arguments.getParcelable(ARG_RESULT_RECEIVER);
|
||||
}
|
||||
|
||||
LocaleDialogController(@NonNull LocaleDialogFragment dialogFragment) {
|
||||
this(dialogFragment.getContext(), dialogFragment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (mResultReceiver != null && mDialogType == DIALOG_CONFIRM_SYSTEM_DEFAULT) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(ARG_DIALOG_TYPE, DIALOG_CONFIRM_SYSTEM_DEFAULT);
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
mResultReceiver.send(Activity.RESULT_OK, bundle);
|
||||
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
mResultReceiver.send(Activity.RESULT_CANCELED, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DialogContent getDialogContent() {
|
||||
DialogContent
|
||||
dialogContent = new DialogContent();
|
||||
switch (mDialogType) {
|
||||
case DIALOG_CONFIRM_SYSTEM_DEFAULT:
|
||||
dialogContent.mTitle = String.format(mContext.getString(
|
||||
R.string.title_change_system_locale), mLocaleInfo.getFullNameNative());
|
||||
dialogContent.mMessage = mContext.getString(
|
||||
R.string.desc_notice_device_locale_settings_change);
|
||||
dialogContent.mPositiveButton = mContext.getString(
|
||||
R.string.button_label_confirmation_of_system_locale_change);
|
||||
dialogContent.mNegativeButton = mContext.getString(R.string.cancel);
|
||||
break;
|
||||
case DIALOG_NOT_AVAILABLE_LOCALE:
|
||||
dialogContent.mTitle = String.format(mContext.getString(
|
||||
R.string.title_unavailable_locale), mLocaleInfo.getFullNameNative());
|
||||
dialogContent.mMessage = mContext.getString(R.string.desc_unavailable_locale);
|
||||
dialogContent.mPositiveButton = mContext.getString(R.string.okay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dialogContent;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class DialogContent {
|
||||
String mTitle = "";
|
||||
String mMessage = "";
|
||||
String mPositiveButton = "";
|
||||
String mNegativeButton = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,14 @@
|
||||
|
||||
package com.android.settings.localepicker;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.LocaleList;
|
||||
import android.os.Looper;
|
||||
import android.os.ResultReceiver;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -49,9 +53,11 @@ class LocaleDragAndDropAdapter
|
||||
private static final String TAG = "LocaleDragAndDropAdapter";
|
||||
private static final String CFGKEY_SELECTED_LOCALES = "selectedLocales";
|
||||
private final Context mContext;
|
||||
private final List<LocaleStore.LocaleInfo> mFeedItemList;
|
||||
private List<LocaleStore.LocaleInfo> mFeedItemList;
|
||||
private List<LocaleStore.LocaleInfo> mCacheItemList;
|
||||
private final ItemTouchHelper mItemTouchHelper;
|
||||
private RecyclerView mParentView = null;
|
||||
private LocaleListEditor mParent;
|
||||
private boolean mRemoveMode = false;
|
||||
private boolean mDragEnabled = true;
|
||||
private NumberFormat mNumberFormatter = NumberFormat.getNumberInstance();
|
||||
@@ -81,12 +87,15 @@ class LocaleDragAndDropAdapter
|
||||
}
|
||||
}
|
||||
|
||||
public LocaleDragAndDropAdapter(Context context, List<LocaleStore.LocaleInfo> feedItemList) {
|
||||
LocaleDragAndDropAdapter(LocaleListEditor parent,
|
||||
List<LocaleStore.LocaleInfo> feedItemList) {
|
||||
mFeedItemList = feedItemList;
|
||||
mContext = context;
|
||||
mParent = parent;
|
||||
mCacheItemList = new ArrayList<>(feedItemList);
|
||||
mContext = parent.getContext();
|
||||
|
||||
final float dragElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8,
|
||||
context.getResources().getDisplayMetrics());
|
||||
mContext.getResources().getDisplayMetrics());
|
||||
|
||||
mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0 /* no swipe */) {
|
||||
@@ -168,13 +177,13 @@ class LocaleDragAndDropAdapter
|
||||
checkbox.setOnCheckedChangeListener(null);
|
||||
checkbox.setChecked(mRemoveMode ? feedItem.getChecked() : false);
|
||||
checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
LocaleStore.LocaleInfo feedItem =
|
||||
(LocaleStore.LocaleInfo) dragCell.getTag();
|
||||
feedItem.setChecked(isChecked);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
LocaleStore.LocaleInfo feedItem =
|
||||
(LocaleStore.LocaleInfo) dragCell.getTag();
|
||||
feedItem.setChecked(isChecked);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -308,6 +317,42 @@ class LocaleDragAndDropAdapter
|
||||
});
|
||||
}
|
||||
|
||||
public void doTheUpdateWithMovingLocaleItem() {
|
||||
LocaleStore.LocaleInfo localeInfo = mFeedItemList.get(0);
|
||||
if (!localeInfo.getLocale().equals(LocalePicker.getLocales().get(0))) {
|
||||
LocaleDialogFragment.show(mParent,
|
||||
LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT,
|
||||
localeInfo,
|
||||
new ResultReceiver(new Handler(Looper.getMainLooper())) {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
super.onReceiveResult(resultCode, resultData);
|
||||
int type = resultData.getInt(LocaleDialogFragment.ARG_DIALOG_TYPE);
|
||||
if (type == LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
doTheUpdate();
|
||||
if (!localeInfo.isTranslated()) {
|
||||
LocaleDialogFragment.show(mParent,
|
||||
LocaleDialogFragment
|
||||
.DIALOG_NOT_AVAILABLE_LOCALE,
|
||||
localeInfo);
|
||||
}
|
||||
} else {
|
||||
if (!localeInfo.getLocale()
|
||||
.equals(mCacheItemList.get(0).getLocale())) {
|
||||
mFeedItemList = new ArrayList<>(mCacheItemList);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
mCacheItemList = new ArrayList<>(mFeedItemList);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
doTheUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void setDragEnabled(boolean enabled) {
|
||||
mDragEnabled = enabled;
|
||||
}
|
||||
@@ -315,6 +360,7 @@ class LocaleDragAndDropAdapter
|
||||
/**
|
||||
* Saves the list of checked locales to preserve status when the list is destroyed.
|
||||
* (for instance when the device is rotated)
|
||||
*
|
||||
* @param outInstanceState Bundle in which to place the saved state
|
||||
*/
|
||||
public void saveState(Bundle outInstanceState) {
|
||||
@@ -332,6 +378,7 @@ class LocaleDragAndDropAdapter
|
||||
/**
|
||||
* Restores the list of checked locales to preserve status when the list is recreated.
|
||||
* (for instance when the device is rotated)
|
||||
*
|
||||
* @param savedInstanceState Bundle with the data saved by {@link #saveState(Bundle)}
|
||||
*/
|
||||
public void restoreState(Bundle savedInstanceState) {
|
||||
|
||||
@@ -105,7 +105,7 @@ public class LocaleListEditor extends RestrictedSettingsFragment {
|
||||
|
||||
LocaleStore.fillCache(this.getContext());
|
||||
final List<LocaleStore.LocaleInfo> feedsList = getUserLocaleList();
|
||||
mAdapter = new LocaleDragAndDropAdapter(this.getContext(), feedsList);
|
||||
mAdapter = new LocaleDragAndDropAdapter(this, feedsList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,7 @@ class LocaleRecyclerView extends RecyclerView {
|
||||
if (e.getAction() == MotionEvent.ACTION_UP || e.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
LocaleDragAndDropAdapter adapter = (LocaleDragAndDropAdapter) this.getAdapter();
|
||||
if (adapter != null) {
|
||||
adapter.doTheUpdate();
|
||||
adapter.doTheUpdateWithMovingLocaleItem();
|
||||
}
|
||||
}
|
||||
return super.onTouchEvent(e);
|
||||
|
||||
@@ -50,6 +50,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
@@ -560,7 +561,8 @@ public class SubscriptionUtil {
|
||||
if (TextUtils.isEmpty(rawPhoneNumber)) {
|
||||
return null;
|
||||
}
|
||||
String countryIso = MccTable.countryCodeForMcc(subscriptionInfo.getMccString());
|
||||
String countryIso = MccTable.countryCodeForMcc(subscriptionInfo.getMccString())
|
||||
.toUpperCase(Locale.ROOT);
|
||||
return PhoneNumberUtils.formatNumber(rawPhoneNumber, countryIso);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.text.BidiFormatter;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.preference.Preference;
|
||||
@@ -54,7 +55,7 @@ import java.util.List;
|
||||
public class AppChannelsBypassingDndPreferenceController extends NotificationPreferenceController
|
||||
implements PreferenceControllerMixin, LifecycleObserver {
|
||||
|
||||
private static final String KEY = "zen_mode_bypassing_app_channels_list";
|
||||
@VisibleForTesting static final String KEY = "zen_mode_bypassing_app_channels_list";
|
||||
private static final String ARG_FROM_SETTINGS = "fromSettings";
|
||||
|
||||
private RestrictedSwitchPreference mAllNotificationsToggle;
|
||||
@@ -74,8 +75,8 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
|
||||
mAllNotificationsToggle = new RestrictedSwitchPreference(mPreferenceCategory.getContext());
|
||||
mAllNotificationsToggle.setTitle(R.string.zen_mode_bypassing_app_channels_toggle_all);
|
||||
mAllNotificationsToggle.setDisabledByAdmin(mAdmin);
|
||||
mAllNotificationsToggle.setEnabled(
|
||||
(mAdmin == null || !mAllNotificationsToggle.isDisabledByAdmin()));
|
||||
mAllNotificationsToggle.setEnabled(!mAppRow.banned
|
||||
&& (mAdmin == null || !mAllNotificationsToggle.isDisabledByAdmin()));
|
||||
mAllNotificationsToggle.setOnPreferenceClickListener(
|
||||
new Preference.OnPreferenceClickListener() {
|
||||
@Override
|
||||
@@ -206,6 +207,9 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
|
||||
}
|
||||
|
||||
private boolean areAllChannelsBypassing() {
|
||||
if (mAppRow.banned) {
|
||||
return false;
|
||||
}
|
||||
boolean allChannelsBypassing = true;
|
||||
for (NotificationChannel channel : mChannels) {
|
||||
if (showNotification(channel)) {
|
||||
@@ -226,7 +230,7 @@ public class AppChannelsBypassingDndPreferenceController extends NotificationPre
|
||||
* Whether notifications from this channel would show if DND weren't on.
|
||||
*/
|
||||
private boolean showNotification(NotificationChannel channel) {
|
||||
return channel.getImportance() != IMPORTANCE_NONE;
|
||||
return !mAppRow.banned && channel.getImportance() != IMPORTANCE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.android.settings.spa.app.specialaccess.PictureInPictureListProvider
|
||||
import com.android.settings.spa.app.specialaccess.SpecialAppAccessPageProvider
|
||||
import com.android.settings.spa.app.specialaccess.WifiControlAppListProvider
|
||||
import com.android.settings.spa.app.specialaccess.UseFullScreenIntentAppListProvider
|
||||
import com.android.settings.spa.core.instrumentation.SpaLogProvider
|
||||
import com.android.settings.spa.development.UsageStatsPageProvider
|
||||
import com.android.settings.spa.home.HomePageProvider
|
||||
import com.android.settings.spa.network.NetworkAndInternetPageProvider
|
||||
@@ -87,4 +88,5 @@ open class SettingsSpaEnvironment(context: Context) : SpaEnvironment(context) {
|
||||
),
|
||||
)
|
||||
}
|
||||
override val logger = SpaLogProvider
|
||||
}
|
||||
|
||||
@@ -16,18 +16,29 @@
|
||||
|
||||
package com.android.settings.spa
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.RemoteException
|
||||
import android.os.UserHandle
|
||||
import android.util.Log
|
||||
import com.android.settingslib.spa.framework.BrowseActivity
|
||||
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
|
||||
import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL
|
||||
import com.android.settingslib.spa.framework.util.appendSpaParams
|
||||
|
||||
class SpaActivity : BrowseActivity() {
|
||||
companion object {
|
||||
private const val TAG = "SpaActivity"
|
||||
@JvmStatic
|
||||
fun Context.startSpaActivity(destination: String) {
|
||||
val intent = Intent(this, SpaActivity::class.java)
|
||||
.appendSpaParams(destination = destination)
|
||||
if (isLaunchedFromInternal()) {
|
||||
intent.appendSpaParams(sessionName = SESSION_BROWSE)
|
||||
} else {
|
||||
intent.appendSpaParams(sessionName = SESSION_EXTERNAL)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
@@ -37,5 +48,15 @@ class SpaActivity : BrowseActivity() {
|
||||
startSpaActivity("$destinationPrefix/$packageName/${UserHandle.myUserId()}")
|
||||
return true
|
||||
}
|
||||
|
||||
fun Context.isLaunchedFromInternal(): Boolean {
|
||||
var pkg: String? = null
|
||||
try {
|
||||
pkg = ActivityManager.getService().getLaunchedFromPackage(getActivityToken())
|
||||
} catch (e: RemoteException) {
|
||||
Log.v(TAG, "Could not talk to activity manager.", e)
|
||||
}
|
||||
return applicationContext.packageName == pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.spa.core.instrumentation
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
|
||||
/**
|
||||
* This class stores some metrics temporary data. Such as the timestamp of the page enter for
|
||||
* calculating the duration time on page.
|
||||
*/
|
||||
class MetricsDataModel {
|
||||
@VisibleForTesting
|
||||
val pageTimeStampList = mutableListOf<PageTimeStamp>()
|
||||
|
||||
fun addTimeStamp(dataItem: PageTimeStamp){
|
||||
pageTimeStampList.add(dataItem)
|
||||
}
|
||||
|
||||
fun getPageDuration(pageId: String, removed: Boolean = true): String {
|
||||
val lastItem = pageTimeStampList.findLast { it.pageId == pageId }
|
||||
if (removed && lastItem != null) {
|
||||
pageTimeStampList.remove(lastItem)
|
||||
}
|
||||
return if (lastItem == null) "0"
|
||||
else (System.currentTimeMillis() - lastItem.timeStamp).toString()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.spa.core.instrumentation
|
||||
|
||||
import android.app.settings.SettingsEnums
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.settings.core.instrumentation.ElapsedTimeUtils
|
||||
import com.android.settings.core.instrumentation.SettingsStatsLog
|
||||
import com.android.settingslib.spa.framework.common.LOG_DATA_SESSION_NAME
|
||||
import com.android.settingslib.spa.framework.common.LogCategory
|
||||
import com.android.settingslib.spa.framework.common.LogEvent
|
||||
import com.android.settingslib.spa.framework.common.SpaLogger
|
||||
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
|
||||
import com.android.settingslib.spa.framework.util.SESSION_EXTERNAL
|
||||
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
|
||||
import com.android.settingslib.spa.framework.util.SESSION_SLICE
|
||||
import com.android.settingslib.spa.framework.util.SESSION_UNKNOWN
|
||||
|
||||
/**
|
||||
* To receive the events from spa framework and logging the these events.
|
||||
*/
|
||||
object SpaLogProvider : SpaLogger {
|
||||
private val dataModel = MetricsDataModel()
|
||||
|
||||
override fun event(id: String, event: LogEvent, category: LogCategory, extraData: Bundle) {
|
||||
when(event) {
|
||||
LogEvent.PAGE_ENTER, LogEvent.PAGE_LEAVE ->
|
||||
write(SpaLogData(id, event, extraData, dataModel))
|
||||
else -> return //TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
}
|
||||
}
|
||||
|
||||
private fun write(data: SpaLogData) {
|
||||
with(data) {
|
||||
SettingsStatsLog.write(
|
||||
SettingsStatsLog.SETTINGS_SPA_REPORTED /* atomName */,
|
||||
getSessionType(),
|
||||
getPageId(),
|
||||
getTarget(),
|
||||
getAction(),
|
||||
getKey(),
|
||||
getValue(),
|
||||
getPreValue(),
|
||||
getElapsedTime()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
class SpaLogData(val id: String, val event: LogEvent,
|
||||
val extraData: Bundle, val dataModel: MetricsDataModel) {
|
||||
|
||||
fun getSessionType(): Int {
|
||||
if (!extraData.containsKey(LOG_DATA_SESSION_NAME)) {
|
||||
return SettingsEnums.SESSION_UNKNOWN
|
||||
}
|
||||
val sessionSource = extraData.getString(LOG_DATA_SESSION_NAME)
|
||||
return when(sessionSource) {
|
||||
SESSION_BROWSE -> SettingsEnums.BROWSE
|
||||
SESSION_SEARCH -> SettingsEnums.SEARCH
|
||||
SESSION_SLICE -> SettingsEnums.SLICE_TYPE
|
||||
SESSION_EXTERNAL -> SettingsEnums.EXTERNAL
|
||||
else -> SettingsEnums.SESSION_UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
fun getPageId(): String {
|
||||
return when(event) {
|
||||
LogEvent.PAGE_ENTER, LogEvent.PAGE_LEAVE -> id
|
||||
else -> getPageIdByEntryId(id)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
fun getTarget(): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getAction(): Int {
|
||||
return event.action
|
||||
}
|
||||
|
||||
//TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
fun getKey(): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getValue(): String? {
|
||||
when(event) {
|
||||
LogEvent.PAGE_ENTER -> dataModel.addTimeStamp(
|
||||
PageTimeStamp(id, System.currentTimeMillis()))
|
||||
LogEvent.PAGE_LEAVE -> return dataModel.getPageDuration(id)
|
||||
else -> {} //TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
//TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
fun getPreValue(): String? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun getElapsedTime(): Long {
|
||||
return ElapsedTimeUtils.getElapsedTime(System.currentTimeMillis())
|
||||
}
|
||||
|
||||
//TODO(b/253979024): Will be implemented in subsequent CLs.
|
||||
private fun getPageIdByEntryId(id: String): String {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The buffer is keeping the time stamp while spa page entering.
|
||||
*/
|
||||
data class PageTimeStamp(val pageId: String, val timeStamp: Long)
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
@@ -81,28 +82,30 @@ public class CameraFlashNotificationPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isChecked_setOff_assertFalse() {
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_setOn_assertTrue() {
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setTrue_assertNotZero() {
|
||||
public void setChecked_setTrue_assertNotOff() {
|
||||
mController.setChecked(true);
|
||||
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION,
|
||||
0)).isNotEqualTo(0);
|
||||
assertThat(
|
||||
Settings.System.getInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION,
|
||||
OFF)).isNotEqualTo(OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setFalse_assertNotOne() {
|
||||
public void setChecked_setFalse_assertNotOn() {
|
||||
mController.setChecked(false);
|
||||
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION,
|
||||
1)).isNotEqualTo(1);
|
||||
assertThat(
|
||||
Settings.System.getInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION,
|
||||
OFF)).isNotEqualTo(ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -18,8 +18,6 @@ package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.ACTION_FLASH_NOTIFICATION_START_PREVIEW;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.EXTRA_FLASH_NOTIFICATION_PREVIEW_TYPE;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_LONG_PREVIEW;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.TYPE_SHORT_PREVIEW;
|
||||
import static com.android.settings.accessibility.ShadowFlashNotificationsUtils.setFlashNotificationsState;
|
||||
@@ -48,7 +46,6 @@ import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -131,7 +128,6 @@ public class FlashNotificationsPreviewPreferenceControllerTest {
|
||||
verify(mPreference).setEnabled(eq(true));
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testHandlePreferenceTreeClick_invalidPreference() {
|
||||
mController.handlePreferenceTreeClick(mock(Preference.class));
|
||||
@@ -165,16 +161,16 @@ public class FlashNotificationsPreviewPreferenceControllerTest {
|
||||
public void onStateChanged_onResume_cameraUri_verifyRegister() {
|
||||
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.System.getUriFor(SETTING_KEY_CAMERA_FLASH_NOTIFICATION)), anyBoolean(),
|
||||
eq(mController.mContentObserver));
|
||||
eq(Settings.System.getUriFor(Settings.System.CAMERA_FLASH_NOTIFICATION)),
|
||||
anyBoolean(), eq(mController.mContentObserver));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onStateChanged_onResume_screenUri_verifyRegister() {
|
||||
mController.onStateChanged(mock(LifecycleOwner.class), Lifecycle.Event.ON_RESUME);
|
||||
verify(mContentResolver).registerContentObserver(
|
||||
eq(Settings.System.getUriFor(SETTING_KEY_SCREEN_FLASH_NOTIFICATION)), anyBoolean(),
|
||||
eq(mController.mContentObserver));
|
||||
eq(Settings.System.getUriFor(Settings.System.SCREEN_FLASH_NOTIFICATION)),
|
||||
anyBoolean(), eq(mController.mContentObserver));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -21,8 +21,8 @@ import static android.hardware.camera2.CameraCharacteristics.LENS_FACING;
|
||||
import static android.hardware.camera2.CameraCharacteristics.LENS_FACING_BACK;
|
||||
import static android.hardware.camera2.CameraMetadata.LENS_FACING_FRONT;
|
||||
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_CAMERA_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.getColorDescriptionText;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.getFlashNotificationsState;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.getScreenColor;
|
||||
@@ -156,8 +156,8 @@ public class FlashNotificationsUtilTest {
|
||||
@Test
|
||||
public void getFlashNotificationsState_torchPresent_cameraOff_screenOff_assertOff() {
|
||||
setTorchPresent();
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
|
||||
|
||||
assertThat(getFlashNotificationsState(mContext))
|
||||
.isEqualTo(FlashNotificationsUtil.State.OFF);
|
||||
@@ -166,8 +166,8 @@ public class FlashNotificationsUtilTest {
|
||||
@Test
|
||||
public void getFlashNotificationsState_torchNotPresent_cameraOn_screenOff_assertOff() {
|
||||
setTorchNotPresent();
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
|
||||
|
||||
assertThat(getFlashNotificationsState(mContext))
|
||||
.isEqualTo(FlashNotificationsUtil.State.OFF);
|
||||
@@ -176,8 +176,8 @@ public class FlashNotificationsUtilTest {
|
||||
@Test
|
||||
public void getFlashNotificationsState_torchPresent_cameraOn_screenOff_assertCamera() {
|
||||
setTorchPresent();
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
|
||||
|
||||
assertThat(getFlashNotificationsState(mContext))
|
||||
.isEqualTo(FlashNotificationsUtil.State.CAMERA);
|
||||
@@ -186,8 +186,8 @@ public class FlashNotificationsUtilTest {
|
||||
@Test
|
||||
public void getFlashNotificationsState_torchPresent_cameraOff_screenOn_assertScreen() {
|
||||
setTorchPresent();
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, OFF);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON);
|
||||
|
||||
assertThat(getFlashNotificationsState(mContext))
|
||||
.isEqualTo(FlashNotificationsUtil.State.SCREEN);
|
||||
@@ -196,8 +196,8 @@ public class FlashNotificationsUtilTest {
|
||||
@Test
|
||||
public void testGetFlashNotificationsState_torchPresent_cameraOn_screenOn_assertCameraScreen() {
|
||||
setTorchPresent();
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_CAMERA_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.CAMERA_FLASH_NOTIFICATION, ON);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON);
|
||||
|
||||
assertThat(getFlashNotificationsState(mContext))
|
||||
.isEqualTo(FlashNotificationsUtil.State.CAMERA_SCREEN);
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
|
||||
import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.DEFAULT_SCREEN_FLASH_COLOR;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION;
|
||||
import static com.android.settings.accessibility.FlashNotificationsUtil.SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR;
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -114,48 +114,50 @@ public class ScreenFlashNotificationPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isChecked_setOff_assertFalse() {
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 0);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, OFF);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isChecked_setOn_assertTrue() {
|
||||
Settings.System.putInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION, 1);
|
||||
Settings.System.putInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION, ON);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_whenTransparentColor_setTrue_assertNotTransparentColor() {
|
||||
Settings.System.putInt(mContentResolver,
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT);
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, Color.TRANSPARENT);
|
||||
mController.setChecked(true);
|
||||
assertThat(Settings.System.getInt(mContentResolver,
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0))
|
||||
.isEqualTo(DEFAULT_SCREEN_FLASH_COLOR);
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0)).isEqualTo(
|
||||
DEFAULT_SCREEN_FLASH_COLOR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_whenNotTransparent_setTrue_assertSameColor() {
|
||||
Settings.System.putInt(mContentResolver,
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0x4D0000FF);
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0x4D0000FF);
|
||||
mController.setChecked(true);
|
||||
assertThat(Settings.System.getInt(mContentResolver,
|
||||
SETTING_KEY_SCREEN_FLASH_NOTIFICATION_COLOR, 0))
|
||||
Settings.System.SCREEN_FLASH_NOTIFICATION_COLOR, 0))
|
||||
.isEqualTo(0x4D0000FF);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setTrue_assertOn() {
|
||||
mController.setChecked(true);
|
||||
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION,
|
||||
0)).isEqualTo(1);
|
||||
assertThat(
|
||||
Settings.System.getInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION,
|
||||
OFF)).isEqualTo(ON);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_setFalse_assertOff() {
|
||||
mController.setChecked(false);
|
||||
assertThat(Settings.System.getInt(mContentResolver, SETTING_KEY_SCREEN_FLASH_NOTIFICATION,
|
||||
1)).isEqualTo(0);
|
||||
assertThat(
|
||||
Settings.System.getInt(mContentResolver, Settings.System.SCREEN_FLASH_NOTIFICATION,
|
||||
OFF)).isEqualTo(OFF);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static android.bluetooth.BluetoothStatusCodes.FEATURE_SUPPORTED;
|
||||
|
||||
import static com.android.settings.development.BluetoothLeAudioAllowListPreferenceController
|
||||
.LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.content.Context;
|
||||
import android.os.SystemProperties;
|
||||
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BluetoothLeAudioAllowListPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
@Mock
|
||||
private DevelopmentSettingsDashboardFragment mFragment;
|
||||
|
||||
@Mock
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private Context mContext;
|
||||
private SwitchPreference mPreference;
|
||||
private BluetoothLeAudioPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mController = spy(new BluetoothLeAudioPreferenceController(mContext, mFragment));
|
||||
when(mPreferenceScreen.findPreference(mController.getPreferenceKey()))
|
||||
.thenReturn(mPreference);
|
||||
mController.mBluetoothAdapter = mBluetoothAdapter;
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
when(mBluetoothAdapter.isLeAudioSupported())
|
||||
.thenReturn(FEATURE_SUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebootDialogConfirmedAsLeAudioAllowListDisabled_shouldSwitchStatus() {
|
||||
SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(false));
|
||||
mController.mChanged = true;
|
||||
|
||||
mController.onRebootDialogConfirmed();
|
||||
final boolean mode = SystemProperties.getBoolean(
|
||||
LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
|
||||
assertThat(mode).isFalse();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void onRebootDialogConfirmedAsLeAudioAllowListEnabled_shouldSwitchStatus() {
|
||||
SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(true));
|
||||
mController.mChanged = true;
|
||||
|
||||
mController.onRebootDialogConfirmed();
|
||||
final boolean status = SystemProperties.getBoolean(
|
||||
LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
|
||||
assertThat(status).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebootDialogCanceled_shouldNotSwitchStatus() {
|
||||
SystemProperties.set(LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, Boolean.toString(false));
|
||||
mController.mChanged = true;
|
||||
|
||||
mController.onRebootDialogCanceled();
|
||||
final boolean status = SystemProperties.getBoolean(
|
||||
LE_AUDIO_ALLOW_LIST_ENABLED_PROPERTY, false);
|
||||
assertThat(status).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -18,17 +18,13 @@ package com.android.settings.fuelgauge.batterysaver;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.PowerManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.SettingsSlicesContract;
|
||||
@@ -85,6 +81,15 @@ public class BatterySaverButtonPreferenceControllerTest {
|
||||
assertThat(mPreference.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSwitchChanged_isCheckedAndAcked_setPowerSaveMode() {
|
||||
setLowPowerWarningAcked(/* acked= */ 1);
|
||||
|
||||
mController.onSwitchChanged(/* switchView= */ null, /* isChecked= */ true);
|
||||
|
||||
verify(mPowerManager).setPowerSaveModeEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_lowPowerOn_preferenceIsChecked() {
|
||||
when(mPowerManager.isPowerSaveMode()).thenReturn(true);
|
||||
@@ -104,11 +109,10 @@ public class BatterySaverButtonPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setChecked_on_showWarningMessage() {
|
||||
public void setChecked_on_setPowerSaveMode() {
|
||||
mController.setChecked(true);
|
||||
|
||||
verify(mContext).sendBroadcast(any(Intent.class));
|
||||
verify(mPowerManager, never()).setPowerSaveModeEnabled(anyBoolean());
|
||||
verify(mPowerManager).setPowerSaveModeEnabled(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,5 +147,9 @@ public class BatterySaverButtonPreferenceControllerTest {
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
|
||||
acked);
|
||||
Settings.Secure.putInt(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Secure.EXTRA_LOW_POWER_WARNING_ACKNOWLEDGED,
|
||||
acked);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,13 +93,13 @@ public class KeyboardLayoutPickerControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLifecycle_onStart_NoInputDevice_shouldFinish() {
|
||||
public void testLifecycle_onStart_NoInputDevice_shouldReturn() {
|
||||
final FragmentActivity activity = Robolectric.setupActivity(FragmentActivity.class);
|
||||
when(mInputManager.getInputDeviceByDescriptor(anyString())).thenReturn(null);
|
||||
when(mFragment.getActivity()).thenReturn(activity);
|
||||
|
||||
mController.onStart();
|
||||
assertThat(activity.isFinishing()).isTrue();
|
||||
verify(mInputManager, never()).getEnabledKeyboardLayoutsForInputDevice(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.notification.app;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settingslib.PrimarySwitchPreference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AppChannelsBypassingDndPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private NotificationBackend mBackend;
|
||||
|
||||
private NotificationBackend.AppRow mAppRow;
|
||||
private AppChannelsBypassingDndPreferenceController mController;
|
||||
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private PreferenceCategory mCategory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
|
||||
mAppRow = new NotificationBackend.AppRow();
|
||||
mAppRow.uid = 42;
|
||||
mAppRow.pkg = "com.example.exampling";
|
||||
|
||||
mController = new AppChannelsBypassingDndPreferenceController(context, mBackend);
|
||||
mController.onResume(mAppRow, null, null, null, null, null, new ArrayList<>());
|
||||
|
||||
PreferenceManager preferenceManager = new PreferenceManager(context);
|
||||
mPreferenceScreen = preferenceManager.createPreferenceScreen(context);
|
||||
mCategory = new PreferenceCategory(context);
|
||||
mCategory.setKey(AppChannelsBypassingDndPreferenceController.KEY);
|
||||
mPreferenceScreen.addPreference(mCategory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_showsAllAndChannels() {
|
||||
when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
|
||||
buildGroupList(true, true, false));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
ShadowApplication.runBackgroundTasks();
|
||||
|
||||
assertThat(mCategory.getPreferenceCount()).isEqualTo(4); // "All" + 3 channels
|
||||
assertThat(mCategory.getPreference(0).getTitle().toString()).isEqualTo(
|
||||
"Allow all notifications");
|
||||
assertThat(mCategory.getPreference(1).getTitle().toString()).isEqualTo("Channel 1");
|
||||
assertThat(mCategory.getPreference(2).getTitle().toString()).isEqualTo("Channel 2");
|
||||
assertThat(mCategory.getPreference(3).getTitle().toString()).isEqualTo("Channel 3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_canToggleAllInterrupt() {
|
||||
when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
|
||||
buildGroupList(true, true, false));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
ShadowApplication.runBackgroundTasks();
|
||||
|
||||
assertThat(mCategory.getPreference(0).isEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_canToggleInterruptIfChannelEnabled() {
|
||||
when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
|
||||
buildGroupList(true, false, true));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
ShadowApplication.runBackgroundTasks();
|
||||
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
1)).isSwitchEnabled()).isTrue();
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
2)).isSwitchEnabled()).isFalse();
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
3)).isSwitchEnabled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_appBlocked_cannotToggleAllOrChannelInterrupts() {
|
||||
mAppRow.banned = true;
|
||||
when(mBackend.getGroups(eq(mAppRow.pkg), eq(mAppRow.uid))).thenReturn(
|
||||
buildGroupList(true, false, true));
|
||||
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
ShadowApplication.runBackgroundTasks();
|
||||
|
||||
assertThat(mCategory.getPreference(0).isEnabled()).isFalse();
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
1)).isSwitchEnabled()).isFalse();
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
2)).isSwitchEnabled()).isFalse();
|
||||
assertThat(((PrimarySwitchPreference) mCategory.getPreference(
|
||||
3)).isSwitchEnabled()).isFalse();
|
||||
}
|
||||
|
||||
private static ParceledListSlice<NotificationChannelGroup> buildGroupList(
|
||||
boolean... enabledByChannel) {
|
||||
NotificationChannelGroup group = new NotificationChannelGroup("group", "The Group");
|
||||
for (int i = 0; i < enabledByChannel.length; i++) {
|
||||
group.addChannel(new NotificationChannel("channel-" + (i + 1), "Channel " + (i + 1),
|
||||
enabledByChannel[i] ? NotificationManager.IMPORTANCE_DEFAULT
|
||||
: NotificationManager.IMPORTANCE_NONE));
|
||||
}
|
||||
return new ParceledListSlice<>(Collections.singletonList(group));
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,15 @@ import com.android.settings.spa.SpaActivity.Companion.startSpaActivity
|
||||
import com.android.settings.spa.SpaActivity.Companion.startSpaActivityForApp
|
||||
import com.android.settingslib.spa.framework.util.KEY_DESTINATION
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Answers
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
|
||||
@@ -39,9 +42,14 @@ class SpaActivityTest {
|
||||
@get:Rule
|
||||
val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@Mock
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private lateinit var context: Context
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
`when`(context.applicationContext.packageName).thenReturn("com.android.settings")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun startSpaActivity() {
|
||||
context.startSpaActivity(DESTINATION)
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.spa.core.instrumentation
|
||||
|
||||
import android.os.SystemClock
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/** Tests for {@link MetricsDataModel}. */
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MetricsDataModelTest {
|
||||
private val TEST_PID = "pseudo_page_id"
|
||||
|
||||
private lateinit var metricsDataModel: MetricsDataModel
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
metricsDataModel = MetricsDataModel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun initMetricsDataModel() {
|
||||
assertThat(metricsDataModel.pageTimeStampList.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addTimeStamp_addOnePageTimeStamp_sizeShouldBeOne() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
|
||||
assertThat(metricsDataModel.pageTimeStampList.size).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun addTimeStamp_addTwoSamePageTimeStamp_sizeShouldBeTwo() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
|
||||
assertThat(metricsDataModel.pageTimeStampList.size).isEqualTo(2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageDuration_getExistPageId_mustFoundValue() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
SystemClock.sleep(5)
|
||||
|
||||
assertThat(metricsDataModel.getPageDuration(TEST_PID).toInt()).isGreaterThan(0)
|
||||
assertThat(metricsDataModel.pageTimeStampList.size).isEqualTo(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageDuration_getNonExistPageId_valueShouldBeZero() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
|
||||
assertThat(metricsDataModel.getPageDuration("WRONG_ID").toLong()).isEqualTo(0L)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageDuration_getExistPageIdAndDonotRemoved_sizeShouldBeOne() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, System.currentTimeMillis()))
|
||||
SystemClock.sleep(5)
|
||||
|
||||
assertThat(metricsDataModel.getPageDuration(TEST_PID, false).toLong()).isGreaterThan(0L)
|
||||
assertThat(metricsDataModel.pageTimeStampList.size).isEqualTo(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageDuration_getTwoExistPageId_theOrderIsLIFO() {
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, 10000L))
|
||||
metricsDataModel.addTimeStamp(PageTimeStamp(TEST_PID, 20000L))
|
||||
|
||||
// The formula is d1 = t1 - 20000, d2 = t2 - 10000
|
||||
// d2 - d1 = t2 - t1 + 10000, because t2 > t1 the result of d2 - d1 is greater 10000
|
||||
val duration1 = metricsDataModel.getPageDuration(TEST_PID).toLong()
|
||||
SystemClock.sleep(5)
|
||||
val duration2 = metricsDataModel.getPageDuration(TEST_PID).toLong()
|
||||
|
||||
assertThat(duration2 - duration1).isGreaterThan(10000L)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.settings.spa.core.instrumentation
|
||||
|
||||
import android.app.settings.SettingsEnums
|
||||
import android.os.Bundle
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settingslib.spa.framework.common.LOG_DATA_SESSION_NAME
|
||||
import com.android.settingslib.spa.framework.common.LogEvent
|
||||
import com.android.settingslib.spa.framework.util.SESSION_BROWSE
|
||||
import com.android.settingslib.spa.framework.util.SESSION_SEARCH
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
/** Tests for {@link SpaLogData}. */
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SpaLogDataTest {
|
||||
private val TEST_PID = "pseudo_page_id"
|
||||
|
||||
private lateinit var bundle: Bundle
|
||||
private lateinit var dataModel: MetricsDataModel
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
bundle = Bundle()
|
||||
dataModel = MetricsDataModel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSessionType_withoutSessionExtraData_returnSessionUnknow() {
|
||||
val spaLogData = SpaLogData(TEST_PID, LogEvent.PAGE_ENTER, bundle, dataModel)
|
||||
|
||||
assertThat(spaLogData.getSessionType()).isEqualTo(SettingsEnums.SESSION_UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSessionType_hasSessionBrowseExtraData_returnSessionBrowse() {
|
||||
bundle.putString(LOG_DATA_SESSION_NAME, SESSION_BROWSE)
|
||||
val spaLogData = SpaLogData(TEST_PID, LogEvent.PAGE_ENTER, bundle, dataModel)
|
||||
|
||||
assertThat(spaLogData.getSessionType()).isEqualTo(SettingsEnums.BROWSE)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSessionType_hasSessionSearchExtraData_returnSessionSearch() {
|
||||
bundle.putString(LOG_DATA_SESSION_NAME, SESSION_SEARCH)
|
||||
val spaLogData = SpaLogData(TEST_PID, LogEvent.PAGE_ENTER, bundle, dataModel)
|
||||
|
||||
assertThat(spaLogData.getSessionType()).isEqualTo(SettingsEnums.SEARCH)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getSessionType_hasSessionUnknownExtraData_returnSessionUnknow() {
|
||||
bundle.putString(LOG_DATA_SESSION_NAME, "SESSION_OTHER")
|
||||
val spaLogData = SpaLogData(TEST_PID, LogEvent.PAGE_ENTER, bundle, dataModel)
|
||||
|
||||
assertThat(spaLogData.getSessionType()).isEqualTo(SettingsEnums.SESSION_UNKNOWN)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun getPageId_withPageEvent_returnInputId() {
|
||||
val spaLogData1 = SpaLogData(TEST_PID, LogEvent.PAGE_ENTER, bundle, dataModel)
|
||||
assertThat(spaLogData1.getPageId()).isEqualTo(TEST_PID)
|
||||
|
||||
val spaLogData2 = SpaLogData(TEST_PID, LogEvent.PAGE_LEAVE, bundle, dataModel)
|
||||
assertThat(spaLogData2.getPageId()).isEqualTo(TEST_PID)
|
||||
}
|
||||
}
|
||||
@@ -27,12 +27,14 @@ import static org.mockito.Mockito.spy;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.credentials.CredentialProviderInfo;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
@@ -87,7 +89,7 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
@Test
|
||||
public void getAvailabilityStatus_withServices_returnsAvailable() {
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(createServiceInfo()));
|
||||
createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
@@ -103,24 +105,59 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
@Test
|
||||
public void displayPreference_withServices_preferencesAdded() {
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(createServiceInfo()));
|
||||
createControllerWithServices(Lists.newArrayList(createCredentialProviderInfo()));
|
||||
controller.displayPreference(mScreen);
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
assertThat(mCredentialsPreferenceCategory.getPreferenceCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildSwitchPreference() {
|
||||
CredentialProviderInfo providerInfo1 =
|
||||
createCredentialProviderInfo(
|
||||
"com.android.provider1", "ClassA", "Service Title", false);
|
||||
CredentialProviderInfo providerInfo2 =
|
||||
createCredentialProviderInfo(
|
||||
"com.android.provider2", "ClassA", "Service Title", false);
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
|
||||
// Test the data is correct.
|
||||
assertThat(providerInfo1.isEnabled()).isFalse();
|
||||
assertThat(providerInfo2.isEnabled()).isFalse();
|
||||
assertThat(controller.getEnabledProviders().size()).isEqualTo(0);
|
||||
|
||||
// Toggle one provider and make sure it worked.
|
||||
assertThat(controller.togglePackageNameEnabled("com.android.provider1")).isTrue();
|
||||
Set<String> enabledProviders = controller.getEnabledProviders();
|
||||
assertThat(enabledProviders.size()).isEqualTo(1);
|
||||
assertThat(enabledProviders.contains("com.android.provider1")).isTrue();
|
||||
|
||||
// Create the pref (checked).
|
||||
SwitchPreference pref = controller.createPreference(mContext, providerInfo1);
|
||||
assertThat(pref.getTitle().toString()).isEqualTo("Service Title");
|
||||
assertThat(pref.isChecked()).isTrue();
|
||||
|
||||
// Create the pref (not checked).
|
||||
SwitchPreference pref2 = controller.createPreference(mContext, providerInfo2);
|
||||
assertThat(pref2.getTitle().toString()).isEqualTo("Service Title");
|
||||
assertThat(pref2.isChecked()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_handlesToggleAndSave() {
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(
|
||||
Lists.newArrayList(
|
||||
createServiceInfo("com.android.provider1", "ClassA"),
|
||||
createServiceInfo("com.android.provider1", "ClassB"),
|
||||
createServiceInfo("com.android.provider2", "ClassA"),
|
||||
createServiceInfo("com.android.provider3", "ClassA"),
|
||||
createServiceInfo("com.android.provider4", "ClassA"),
|
||||
createServiceInfo("com.android.provider5", "ClassA"),
|
||||
createServiceInfo("com.android.provider6", "ClassA")));
|
||||
createCredentialProviderInfo("com.android.provider1", "ClassA"),
|
||||
createCredentialProviderInfo("com.android.provider1", "ClassB"),
|
||||
createCredentialProviderInfo("com.android.provider2", "ClassA"),
|
||||
createCredentialProviderInfo("com.android.provider3", "ClassA"),
|
||||
createCredentialProviderInfo("com.android.provider4", "ClassA"),
|
||||
createCredentialProviderInfo("com.android.provider5", "ClassA"),
|
||||
createCredentialProviderInfo("com.android.provider6", "ClassA")));
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
|
||||
@@ -177,8 +214,38 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
assertThat(currentlyEnabledServices.contains("com.android.provider6/ClassA")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlesCredentialProviderInfoEnabledDisabled() {
|
||||
CredentialProviderInfo providerInfo1 =
|
||||
createCredentialProviderInfo(
|
||||
"com.android.provider1", "ClassA", "Service Title", false);
|
||||
CredentialProviderInfo providerInfo2 =
|
||||
createCredentialProviderInfo(
|
||||
"com.android.provider2", "ClassA", "Service Title", true);
|
||||
CredentialManagerPreferenceController controller =
|
||||
createControllerWithServices(Lists.newArrayList(providerInfo1, providerInfo2));
|
||||
assertThat(controller.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
assertThat(controller.isConnected()).isFalse();
|
||||
|
||||
// Test the data is correct.
|
||||
assertThat(providerInfo1.isEnabled()).isFalse();
|
||||
assertThat(providerInfo2.isEnabled()).isTrue();
|
||||
|
||||
// Check that they are all actually registered.
|
||||
Set<String> enabledProviders = controller.getEnabledProviders();
|
||||
assertThat(enabledProviders.size()).isEqualTo(1);
|
||||
assertThat(enabledProviders.contains("com.android.provider1")).isFalse();
|
||||
assertThat(enabledProviders.contains("com.android.provider2")).isTrue();
|
||||
|
||||
// Check that the settings string has the right component names.
|
||||
List<String> enabledServices = controller.getEnabledSettings();
|
||||
assertThat(enabledServices.size()).isEqualTo(1);
|
||||
assertThat(enabledServices.contains("com.android.provider1/ClassA")).isFalse();
|
||||
assertThat(enabledServices.contains("com.android.provider2/ClassA")).isTrue();
|
||||
}
|
||||
|
||||
private CredentialManagerPreferenceController createControllerWithServices(
|
||||
List<ServiceInfo> availableServices) {
|
||||
List<CredentialProviderInfo> availableServices) {
|
||||
CredentialManagerPreferenceController controller =
|
||||
new CredentialManagerPreferenceController(
|
||||
mContext, mCredentialsPreferenceCategory.getKey());
|
||||
@@ -186,11 +253,17 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
return controller;
|
||||
}
|
||||
|
||||
private ServiceInfo createServiceInfo() {
|
||||
return createServiceInfo("com.android.provider", "CredManProvider");
|
||||
private CredentialProviderInfo createCredentialProviderInfo() {
|
||||
return createCredentialProviderInfo("com.android.provider", "CredManProvider");
|
||||
}
|
||||
|
||||
private ServiceInfo createServiceInfo(String packageName, String className) {
|
||||
private CredentialProviderInfo createCredentialProviderInfo(
|
||||
String packageName, String className) {
|
||||
return createCredentialProviderInfo(packageName, className, null, false);
|
||||
}
|
||||
|
||||
private CredentialProviderInfo createCredentialProviderInfo(
|
||||
String packageName, String className, CharSequence label, boolean isEnabled) {
|
||||
ServiceInfo si = new ServiceInfo();
|
||||
si.packageName = packageName;
|
||||
si.name = className;
|
||||
@@ -200,6 +273,9 @@ public class CredentialManagerPreferenceControllerTest {
|
||||
si.applicationInfo.packageName = packageName;
|
||||
si.applicationInfo.nonLocalizedLabel = "test";
|
||||
|
||||
return si;
|
||||
return new CredentialProviderInfo.Builder(si)
|
||||
.setOverrideLabel(label)
|
||||
.setEnabled(isEnabled)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.localepicker;
|
||||
|
||||
import static com.android.settings.localepicker.LocaleDialogFragment.ARG_DIALOG_TYPE;
|
||||
import static com.android.settings.localepicker.LocaleDialogFragment.ARG_RESULT_RECEIVER;
|
||||
import static com.android.settings.localepicker.LocaleDialogFragment.ARG_TARGET_LOCALE;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import androidx.test.annotation.UiThreadTest;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.internal.app.LocaleStore;
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@UiThreadTest
|
||||
public class LocaleDialogFragmentTest {
|
||||
@Rule
|
||||
public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
private Context mContext;
|
||||
private LocaleDialogFragment mDialogFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mContext = ApplicationProvider.getApplicationContext();
|
||||
mDialogFragment = new LocaleDialogFragment();
|
||||
}
|
||||
|
||||
private void setArgument(
|
||||
int type, ResultReceiver receiver) {
|
||||
LocaleStore.LocaleInfo localeInfo = LocaleStore.getLocaleInfo(Locale.ENGLISH);
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_DIALOG_TYPE, type);
|
||||
args.putSerializable(ARG_TARGET_LOCALE, localeInfo);
|
||||
args.putParcelable(ARG_RESULT_RECEIVER, receiver);
|
||||
mDialogFragment.setArguments(args);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDialogContent_confirmSystemDefault_has2ButtonText() {
|
||||
setArgument(LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT, null);
|
||||
LocaleDialogFragment.LocaleDialogController controller =
|
||||
new LocaleDialogFragment.LocaleDialogController(mContext, mDialogFragment);
|
||||
|
||||
LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent =
|
||||
controller.getDialogContent();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(
|
||||
mContext, "button_label_confirmation_of_system_locale_change"),
|
||||
dialogContent.mPositiveButton);
|
||||
assertEquals(ResourcesUtils.getResourcesString(mContext, "cancel"),
|
||||
dialogContent.mNegativeButton);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDialogContent_unavailableLocale_has1ButtonText() {
|
||||
setArgument(LocaleDialogFragment.DIALOG_NOT_AVAILABLE_LOCALE, null);
|
||||
LocaleDialogFragment.LocaleDialogController controller =
|
||||
new LocaleDialogFragment.LocaleDialogController(mContext, mDialogFragment);
|
||||
|
||||
LocaleDialogFragment.LocaleDialogController.DialogContent dialogContent =
|
||||
controller.getDialogContent();
|
||||
|
||||
assertEquals(ResourcesUtils.getResourcesString(mContext, "okay"),
|
||||
dialogContent.mPositiveButton);
|
||||
assertTrue(dialogContent.mNegativeButton.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClick_clickPositiveButton_sendOK() {
|
||||
ResultReceiver resultReceiver = spy(new ResultReceiver(null));
|
||||
setArgument(LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT, resultReceiver);
|
||||
LocaleDialogFragment.LocaleDialogController controller =
|
||||
new LocaleDialogFragment.LocaleDialogController(mContext, mDialogFragment);
|
||||
|
||||
controller.onClick(null, DialogInterface.BUTTON_POSITIVE);
|
||||
|
||||
verify(resultReceiver).send(eq(Activity.RESULT_OK), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClick_clickNegativeButton_sendCancel() {
|
||||
ResultReceiver resultReceiver = spy(new ResultReceiver(null));
|
||||
setArgument(LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT, resultReceiver);
|
||||
LocaleDialogFragment.LocaleDialogController controller =
|
||||
new LocaleDialogFragment.LocaleDialogController(mContext, mDialogFragment);
|
||||
|
||||
controller.onClick(null, DialogInterface.BUTTON_NEGATIVE);
|
||||
|
||||
verify(resultReceiver).send(eq(Activity.RESULT_CANCELED), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_systemLocaleChange() {
|
||||
setArgument(LocaleDialogFragment.DIALOG_CONFIRM_SYSTEM_DEFAULT, null);
|
||||
|
||||
int result = mDialogFragment.getMetricsCategory();
|
||||
|
||||
assertEquals(SettingsEnums.DIALOG_SYSTEM_LOCALE_CHANGE, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_unavailableLocale() {
|
||||
setArgument(LocaleDialogFragment.DIALOG_NOT_AVAILABLE_LOCALE, null);
|
||||
|
||||
int result = mDialogFragment.getMetricsCategory();
|
||||
|
||||
assertEquals(SettingsEnums.DIALOG_SYSTEM_LOCALE_UNAVAILABLE, result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user