Snap for 11710546 from e24b145d48 to 24Q3-release
Change-Id: I7d3e8b929a2d437ebfc1d901e70ff144a69daef1
This commit is contained in:
|
Before Width: | Height: | Size: 95 B After Width: | Height: | Size: 95 B |
@@ -1339,9 +1339,9 @@
|
||||
<!-- Label for button to retry creating private space again on creation error. [CHAR LIMIT=30] -->
|
||||
<string name="private_space_tryagain_label">Try Again</string>
|
||||
<!-- Title for private space lock setup screen. [CHAR LIMIT=90] -->
|
||||
<string name="private_space_lockscreen_title">Use screen lock to unlock private space?</string>
|
||||
<string name="private_space_lockscreen_title">Choose a new lock for private space?</string>
|
||||
<!-- Summary for the private space lock setup screen. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_lockscreen_summary">You can unlock your private space the same way you unlock your device, or choose a different lock</string>
|
||||
<string name="private_space_lockscreen_summary">You can set a new lock just for private space, or use the same lock you use to unlock your device</string>
|
||||
<!-- Action label to use existing device lock for private space. [CHAR LIMIT=50] -->
|
||||
<string name="private_space_use_screenlock_label">Use screen lock</string>
|
||||
<!-- Label for private space lock setup button to choose a new lock. [CHAR LIMIT=50] -->
|
||||
@@ -1826,11 +1826,11 @@
|
||||
<!-- Bluetooth settings. Text displayed when Bluetooth is off and device list is empty [CHAR LIMIT=NONE]-->
|
||||
<string name="bluetooth_empty_list_bluetooth_off">When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices</string>
|
||||
<!-- Bluetooth settings. Text displayed when Bluetooth is off and device list is empty when auto-on feature is enabled [CHAR LIMIT=NONE]-->
|
||||
<string name="bluetooth_empty_list_bluetooth_off_auto_on_available">When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share, Find My Device, and device location use Bluetooth.</string>
|
||||
<string name="bluetooth_empty_list_bluetooth_off_auto_on_available">When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share and Find My Device use Bluetooth.</string>
|
||||
<!-- Bluetooth settings. Text displayed when Bluetooth is off and bluetooth scanning is turned on [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_scanning_on_info_message">When Bluetooth is turned on, your device can communicate with other nearby Bluetooth devices.\n\nTo improve device experience, apps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. You can change this in Bluetooth scanning settings.</string>
|
||||
<!-- Bluetooth settings. Text displayed when Bluetooth is off and bluetooth scanning is turned on [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_scanning_on_info_message_auto_on_available">When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share, Find My Device, and device location use Bluetooth.\n\nApps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. You can change this in Bluetooth scanning settings.</string>
|
||||
<string name="bluetooth_scanning_on_info_message_auto_on_available">When Bluetooth is on, your device can communicate with other nearby Bluetooth devices. Features like Quick Share and Find My Device use Bluetooth.\n\nApps and services can still scan for nearby devices at any time, even when Bluetooth is off. This can be used, for example, to improve location-based features and services. You can change this in Bluetooth scanning settings.</string>
|
||||
<!-- Bluetooth settings. Link text to bring the user to "scanning settings" screen. [CHAR LIMIT=NONE]-->
|
||||
<string name="bluetooth_scan_change">Change</string>
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/configure_notification_settings">
|
||||
android:title="@string/configure_notification_settings"
|
||||
android:key="configure_notification_settings">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="general_notifications_category"
|
||||
|
||||
22
res/xml/location_services_private_profile.xml
Normal file
22
res/xml/location_services_private_profile.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/location_services_screen_title"
|
||||
android:key="location_services_private_profile"
|
||||
settings:controller="com.android.settings.location.LocationInjectedServicesForPrivateProfilePreferenceController">
|
||||
</PreferenceScreen>
|
||||
@@ -126,6 +126,9 @@
|
||||
<PreferenceCategory
|
||||
android:key="ip_details_category"
|
||||
android:title="@string/wifi_setup_detail">
|
||||
<com.android.settings.spa.preference.ComposePreference
|
||||
android:key="server_name"
|
||||
settings:controller="com.android.settings.wifi.details2.ServerNamePreferenceController"/>
|
||||
<Preference
|
||||
android:key="type"
|
||||
android:title="@string/wifi_type_title"
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
@@ -65,11 +64,7 @@ public class VibrationIntensitySettingsFragment extends DashboardFragment {
|
||||
final int supportedIntensityLevels = context.getResources().getInteger(
|
||||
R.integer.config_vibration_supported_intensity_levels);
|
||||
final boolean hasVibrator = context.getSystemService(Vibrator.class).hasVibrator();
|
||||
if (Flags.separateAccessibilityVibrationSettingsFragments()) {
|
||||
return hasVibrator && supportedIntensityLevels > 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return hasVibrator && supportedIntensityLevels > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.preference.Preference;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
/** Controller for "Vibration & haptics" settings page. */
|
||||
public class VibrationPreferenceController extends BasePreferenceController {
|
||||
@@ -66,8 +65,7 @@ public class VibrationPreferenceController extends BasePreferenceController {
|
||||
|
||||
@Override
|
||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||
if (Flags.separateAccessibilityVibrationSettingsFragments()
|
||||
&& TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||
if (mContext.getResources().getInteger(
|
||||
R.integer.config_vibration_supported_intensity_levels) > 1) {
|
||||
launchVibrationSettingsFragment(VibrationIntensitySettingsFragment.class);
|
||||
|
||||
@@ -18,44 +18,23 @@ package com.android.settings.accessibility;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.Vibrator;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Accessibility settings for the vibration. */
|
||||
/**
|
||||
* Accessibility settings for the vibration.
|
||||
*/
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class VibrationSettings extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "VibrationSettings";
|
||||
|
||||
private static int getVibrationXmlResourceId(Context context) {
|
||||
if (Flags.separateAccessibilityVibrationSettingsFragments()) {
|
||||
return R.xml.accessibility_vibration_settings;
|
||||
}
|
||||
final int supportedIntensities = context.getResources().getInteger(
|
||||
R.integer.config_vibration_supported_intensity_levels);
|
||||
return supportedIntensities > 1
|
||||
? R.xml.accessibility_vibration_intensity_settings
|
||||
: R.xml.accessibility_vibration_settings;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.ACCESSIBILITY_VIBRATION;
|
||||
@@ -68,7 +47,7 @@ public class VibrationSettings extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return getVibrationXmlResourceId(getContext());
|
||||
return R.xml.accessibility_vibration_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -76,53 +55,19 @@ public class VibrationSettings extends DashboardFragment {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
if (Flags.separateAccessibilityVibrationSettingsFragments()) {
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
final RecyclerView rv = getListView();
|
||||
final Resources res = view.getResources();
|
||||
final int supportedIntensities = res.getInteger(
|
||||
R.integer.config_vibration_supported_intensity_levels);
|
||||
if (rv != null && supportedIntensities > 1) {
|
||||
final int bottom_padding = res.getDimensionPixelSize(
|
||||
com.android.settingslib.widget.theme.R.dimen.settingslib_listPreferredItemPaddingEnd);
|
||||
rv.setPaddingRelative(rv.getPaddingStart(), rv.getPaddingTop(), rv.getPaddingEnd(),
|
||||
rv.getPaddingBottom() + bottom_padding);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isPageSearchEnabled(Context context) {
|
||||
final int supportedIntensityLevels = context.getResources().getInteger(
|
||||
R.integer.config_vibration_supported_intensity_levels);
|
||||
final boolean hasVibrator = context.getSystemService(Vibrator.class).hasVibrator();
|
||||
if (Flags.separateAccessibilityVibrationSettingsFragments()) {
|
||||
return hasVibrator && supportedIntensityLevels == 1;
|
||||
} else {
|
||||
return hasVibrator;
|
||||
}
|
||||
return hasVibrator && supportedIntensityLevels == 1;
|
||||
}
|
||||
|
||||
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
new BaseSearchIndexProvider(R.xml.accessibility_vibration_settings) {
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
return VibrationSettings.isPageSearchEnabled(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||
boolean enabled) {
|
||||
final List<SearchIndexableResource> resourceData = new ArrayList<>();
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = getVibrationXmlResourceId(context);
|
||||
resourceData.add(sir);
|
||||
return resourceData;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
@@ -125,12 +125,12 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
protected CharSequence getPositiveButtonText() {
|
||||
final Bundle bundle = getArguments();
|
||||
if (TextUtils.isEmpty(bundle.getString(EXTRA_KEY))) {
|
||||
return getContext().getString(
|
||||
R.string.credman_confirmation_turn_off_positive_button);
|
||||
return getContext()
|
||||
.getString(R.string.credman_confirmation_turn_off_positive_button);
|
||||
}
|
||||
|
||||
return getContext().getString(
|
||||
R.string.credman_confirmation_change_provider_positive_button);
|
||||
return getContext()
|
||||
.getString(R.string.credman_confirmation_change_provider_positive_button);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,21 +259,21 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
return mCredentialManager;
|
||||
}
|
||||
|
||||
private List<CombinedProviderInfo> getAllProviders() {
|
||||
private List<CombinedProviderInfo> getAllProviders(int userId) {
|
||||
final Context context = getContext();
|
||||
final List<AutofillServiceInfo> autofillProviders =
|
||||
AutofillServiceInfo.getAvailableServices(context, getUser());
|
||||
AutofillServiceInfo.getAvailableServices(context, userId);
|
||||
|
||||
final CredentialManager service = getCredentialProviderService();
|
||||
final List<CredentialProviderInfo> credManProviders = new ArrayList<>();
|
||||
if (service != null) {
|
||||
credManProviders.addAll(
|
||||
service.getCredentialProviderServices(
|
||||
getUser(),
|
||||
userId,
|
||||
CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_INCLUDING_HIDDEN));
|
||||
}
|
||||
|
||||
final String selectedAutofillProvider = getSelectedAutofillProvider(context, getUser());
|
||||
final String selectedAutofillProvider = getSelectedAutofillProvider(context, userId);
|
||||
return CombinedProviderInfo.buildMergedList(
|
||||
autofillProviders, credManProviders, selectedAutofillProvider);
|
||||
}
|
||||
@@ -285,7 +285,8 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
|
||||
protected List<DefaultAppInfo> getCandidates() {
|
||||
final Context context = getContext();
|
||||
final List<CombinedProviderInfo> allProviders = getAllProviders();
|
||||
final int userId = getUser();
|
||||
final List<CombinedProviderInfo> allProviders = getAllProviders(userId);
|
||||
final List<DefaultAppInfo> candidates = new ArrayList<>();
|
||||
|
||||
for (CombinedProviderInfo cpi : allProviders) {
|
||||
@@ -295,10 +296,10 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
if (brandingService != null) {
|
||||
candidates.add(
|
||||
new CredentialManagerDefaultAppInfo(
|
||||
context, mPm, getUser(), brandingService, cpi));
|
||||
context, mPm, userId, brandingService, cpi));
|
||||
} else if (appInfo != null) {
|
||||
candidates.add(
|
||||
new CredentialManagerDefaultAppInfo(context, mPm, getUser(), appInfo, cpi));
|
||||
new CredentialManagerDefaultAppInfo(context, mPm, userId, appInfo, cpi));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,9 +362,23 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
|
||||
@Override
|
||||
protected String getDefaultKey() {
|
||||
final CombinedProviderInfo topProvider =
|
||||
CombinedProviderInfo.getTopProvider(getAllProviders());
|
||||
return topProvider == null ? "" : topProvider.getApplicationInfo().packageName;
|
||||
final int userId = getUser();
|
||||
final @Nullable CombinedProviderInfo topProvider =
|
||||
CombinedProviderInfo.getTopProvider(getAllProviders(userId));
|
||||
|
||||
if (topProvider != null) {
|
||||
// Apply device admin restrictions to top provider.
|
||||
if (topProvider.getDeviceAdminRestrictions(getContext(), userId) != null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
ApplicationInfo appInfo = topProvider.getApplicationInfo();
|
||||
if (appInfo != null) {
|
||||
return appInfo.packageName;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -392,7 +407,7 @@ public class DefaultCombinedPicker extends DefaultAppPickerFragment {
|
||||
@Override
|
||||
protected boolean setDefaultKey(String key) {
|
||||
// Get the list of providers and see if any match the key (package name).
|
||||
final List<CombinedProviderInfo> allProviders = getAllProviders();
|
||||
final List<CombinedProviderInfo> allProviders = getAllProviders(getUser());
|
||||
CombinedProviderInfo matchedProvider = null;
|
||||
for (CombinedProviderInfo cpi : allProviders) {
|
||||
if (cpi.getApplicationInfo().packageName.equals(key)) {
|
||||
|
||||
@@ -92,12 +92,14 @@ public class DefaultCombinedPreferenceController extends DefaultAppPreferenceCon
|
||||
@Override
|
||||
public void updateState(@NonNull Preference preference) {
|
||||
final CombinedProviderInfo topProvider = getTopProvider();
|
||||
final int userId = getUser();
|
||||
|
||||
if (topProvider != null && mContext != null) {
|
||||
updatePreferenceForProvider(
|
||||
preference,
|
||||
topProvider.getAppName(mContext),
|
||||
topProvider.getSettingsSubtitle(),
|
||||
topProvider.getAppIcon(mContext, getUser()),
|
||||
topProvider.getAppIcon(mContext, userId),
|
||||
topProvider.getPackageName(),
|
||||
topProvider.getSettingsActivity());
|
||||
} else {
|
||||
@@ -149,7 +151,17 @@ public class DefaultCombinedPreferenceController extends DefaultAppPreferenceCon
|
||||
}
|
||||
|
||||
private @Nullable CombinedProviderInfo getTopProvider() {
|
||||
return CombinedProviderInfo.getTopProvider(getAllProviders(getUser()));
|
||||
final int userId = getUser();
|
||||
final @Nullable CombinedProviderInfo topProvider =
|
||||
CombinedProviderInfo.getTopProvider(getAllProviders(userId));
|
||||
|
||||
// Apply device admin restrictions to top provider.
|
||||
if (topProvider != null
|
||||
&& topProvider.getDeviceAdminRestrictions(mContext, userId) != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return topProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.location.LocationServices;
|
||||
import com.android.settings.location.LocationServicesForPrivateProfile;
|
||||
import com.android.settings.location.LocationServicesForWork;
|
||||
|
||||
/**
|
||||
@@ -34,7 +35,7 @@ public class ProfileSelectLocationServicesFragment extends ProfileSelectFragment
|
||||
null /* bundle */,
|
||||
LocationServices::new,
|
||||
LocationServicesForWork::new,
|
||||
LocationServices::new);
|
||||
LocationServicesForPrivateProfile::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.location.SettingInjectorService;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
@@ -32,6 +33,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
|
||||
import java.util.List;
|
||||
@@ -110,13 +112,28 @@ public abstract class LocationInjectedServiceBasePreferenceController
|
||||
}
|
||||
|
||||
protected Map<Integer, List<Preference>> getLocationServices() {
|
||||
ArraySet<UserHandle> userHandles = new ArraySet<>();
|
||||
userHandles.add(UserHandle.of(UserHandle.myUserId()));
|
||||
|
||||
// If location access is locked down by device policy then we only show injected settings
|
||||
// for the primary profile.
|
||||
final int profileUserId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
|
||||
final int managedProfileId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
|
||||
if (managedProfileId != UserHandle.USER_NULL
|
||||
&& mLocationEnabler.getShareLocationEnforcedAdmin(managedProfileId) == null) {
|
||||
userHandles.add(UserHandle.of(managedProfileId));
|
||||
}
|
||||
if (android.os.Flags.allowPrivateProfile()
|
||||
&& android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
&& android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()) {
|
||||
final UserHandle privateProfile = Utils.getProfileOfType(mUserManager,
|
||||
ProfileSelectFragment.ProfileType.PRIVATE);
|
||||
if (privateProfile != null && mLocationEnabler
|
||||
.getShareLocationEnforcedAdmin(privateProfile.getIdentifier()) == null) {
|
||||
userHandles.add(privateProfile);
|
||||
}
|
||||
}
|
||||
|
||||
return mInjector.getInjectedSettings(mFragment.getPreferenceManager().getContext(),
|
||||
(profileUserId != UserHandle.USER_NULL
|
||||
&& mLocationEnabler.getShareLocationEnforcedAdmin(profileUserId) != null)
|
||||
? UserHandle.myUserId() : UserHandle.USER_CURRENT);
|
||||
userHandles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.profileselector.ProfileSelectFragment;
|
||||
import com.android.settings.widget.RestrictedAppPreference;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Retrieve the Location Services used in private profile user.
|
||||
*/
|
||||
public class LocationInjectedServicesForPrivateProfilePreferenceController extends
|
||||
LocationInjectedServiceBasePreferenceController {
|
||||
public LocationInjectedServicesForPrivateProfilePreferenceController(
|
||||
Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void injectLocationServices(PreferenceScreen screen) {
|
||||
if (!android.os.Flags.allowPrivateProfile()
|
||||
|| !android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
|| !android.multiuser.Flags.handleInterleavedSettingsForPrivateSpace()) {
|
||||
return;
|
||||
}
|
||||
final UserHandle privateProfile = Utils.getProfileOfType(mUserManager,
|
||||
ProfileSelectFragment.ProfileType.PRIVATE);
|
||||
if (privateProfile == null) {
|
||||
return;
|
||||
}
|
||||
final Map<Integer, List<Preference>> prefs = getLocationServices();
|
||||
for (Map.Entry<Integer, List<Preference>> entry : prefs.entrySet()) {
|
||||
for (Preference pref : entry.getValue()) {
|
||||
if (pref instanceof RestrictedAppPreference) {
|
||||
((RestrictedAppPreference) pref).checkRestrictionAndSetDisabled();
|
||||
}
|
||||
}
|
||||
if (entry.getKey() == privateProfile.getIdentifier()) {
|
||||
LocationSettings.addPreferencesSorted(entry.getValue(), screen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import android.os.UserHandle;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.widget.RestrictedAppPreference;
|
||||
|
||||
import java.util.List;
|
||||
@@ -40,6 +41,7 @@ public class LocationInjectedServicesForWorkPreferenceController extends
|
||||
|
||||
@Override
|
||||
protected void injectLocationServices(PreferenceScreen screen) {
|
||||
final int managedProfileId = Utils.getManagedProfileId(mUserManager, UserHandle.myUserId());
|
||||
final Map<Integer, List<Preference>> prefs = getLocationServices();
|
||||
for (Map.Entry<Integer, List<Preference>> entry : prefs.entrySet()) {
|
||||
for (Preference pref : entry.getValue()) {
|
||||
@@ -47,7 +49,7 @@ public class LocationInjectedServicesForWorkPreferenceController extends
|
||||
((RestrictedAppPreference) pref).checkRestrictionAndSetDisabled();
|
||||
}
|
||||
}
|
||||
if (entry.getKey() != UserHandle.myUserId()) {
|
||||
if (entry.getKey() == managedProfileId) {
|
||||
LocationSettings.addPreferencesSorted(entry.getValue(), screen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.location;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
|
||||
public class LocationServicesForPrivateProfile extends DashboardFragment {
|
||||
private static final String TAG = "LocationServicesForPrivateProfile";
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.LOCATION_SERVICES_FOR_PRIVATE_PROFILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.location_services_private_profile;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
use(LocationInjectedServicesForPrivateProfilePreferenceController.class).init(this);
|
||||
}
|
||||
}
|
||||
@@ -112,11 +112,10 @@ public class PrivateSpaceMaintainer {
|
||||
|
||||
registerBroadcastReceiver();
|
||||
|
||||
try {
|
||||
//TODO(b/313926659): To check and handle failure of startProfile
|
||||
mActivityManager.startProfile(mUserHandle);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Unexpected that " + mUserHandle.getIdentifier() + " is not a profile");
|
||||
if (!startProfile()) {
|
||||
// TODO(b/333884792): Add test to mock when startProfile fails.
|
||||
Log.e(TAG, "profile not started, created profile is deleted");
|
||||
deletePrivateSpace();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -314,6 +313,16 @@ public class PrivateSpaceMaintainer {
|
||||
return false;
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean startProfile() {
|
||||
try {
|
||||
return mActivityManager.startProfile(mUserHandle);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Unexpected that " + mUserHandle.getIdentifier() + " is not a profile");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
private void resetPrivateSpaceSettings() {
|
||||
setHidePrivateSpaceEntryPointSetting(HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL);
|
||||
|
||||
@@ -63,16 +63,16 @@ public class PrivateSpaceSetLockFragment extends InstrumentedFragment {
|
||||
final FooterBarMixin mixin = rootView.getMixin(FooterBarMixin.class);
|
||||
mixin.setPrimaryButton(
|
||||
new FooterButton.Builder(getContext())
|
||||
.setText(R.string.private_space_use_screenlock_label)
|
||||
.setListener(onClickUse())
|
||||
.setText(R.string.private_space_set_lock_label)
|
||||
.setListener(onClickNewLock())
|
||||
.setButtonType(FooterButton.ButtonType.NEXT)
|
||||
.setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Primary)
|
||||
.build());
|
||||
mixin.setSecondaryButton(
|
||||
new FooterButton.Builder(getContext())
|
||||
.setText(R.string.private_space_set_lock_label)
|
||||
.setListener(onClickNewLock())
|
||||
.setButtonType(FooterButton.ButtonType.NEXT)
|
||||
.setText(R.string.private_space_use_screenlock_label)
|
||||
.setListener(onClickUse())
|
||||
.setButtonType(FooterButton.ButtonType.SKIP)
|
||||
.setTheme(com.google.android.setupdesign.R.style.SudGlifButton_Secondary)
|
||||
.build());
|
||||
OnBackPressedCallback callback =
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.android.settings.wifi.WifiDialog2;
|
||||
import com.android.settings.wifi.WifiUtils;
|
||||
import com.android.settings.wifi.details2.AddDevicePreferenceController2;
|
||||
import com.android.settings.wifi.details2.CertificateDetailsPreferenceController;
|
||||
import com.android.settings.wifi.details2.ServerNamePreferenceController;
|
||||
import com.android.settings.wifi.details2.WifiAutoConnectPreferenceController2;
|
||||
import com.android.settings.wifi.details2.WifiDetailPreferenceController2;
|
||||
import com.android.settings.wifi.details2.WifiMeteredPreferenceController2;
|
||||
@@ -129,6 +130,8 @@ public class WifiNetworkDetailsFragment extends RestrictedDashboardFragment impl
|
||||
.setWifiEntryKey(wifiEntryKey);
|
||||
use(CertificateDetailsPreferenceController.class)
|
||||
.setWifiEntry(mNetworkDetailsTracker.getWifiEntry());
|
||||
use(ServerNamePreferenceController.class)
|
||||
.setWifiEntry(mNetworkDetailsTracker.getWifiEntry());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -37,6 +37,9 @@ import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.wifi.flags.Flags
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_CERTIFICATE_PINNING
|
||||
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA
|
||||
import com.android.wifitrackerlib.WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE
|
||||
import java.security.KeyStore
|
||||
import java.security.cert.X509Certificate
|
||||
|
||||
@@ -44,15 +47,13 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
||||
ComposePreferenceController(context, preferenceKey) {
|
||||
|
||||
private lateinit var wifiEntry: WifiEntry
|
||||
lateinit var certificateAliases: String
|
||||
lateinit var certX509: X509Certificate
|
||||
|
||||
fun setWifiEntry(entry: WifiEntry) {
|
||||
wifiEntry = entry
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus(): Int {
|
||||
return if (Flags.androidVWifiApi() && getCertX509(wifiEntry)) AVAILABLE
|
||||
return if (Flags.androidVWifiApi() && isCertificateDetailsAvailable(wifiEntry)) AVAILABLE
|
||||
else CONDITIONALLY_UNAVAILABLE
|
||||
}
|
||||
|
||||
@@ -64,26 +65,52 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
||||
@Composable
|
||||
fun CertificateDetails() {
|
||||
val context = LocalContext.current
|
||||
|
||||
val validationMethod = wifiEntry.certificateInfo!!.validationMethod
|
||||
val certificateDetailsSummary = when (validationMethod) {
|
||||
CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE ->
|
||||
stringResource(R.string.wifi_certificate_summary_system)
|
||||
|
||||
CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA -> {
|
||||
val aliasesSize = wifiEntry.certificateInfo?.caCertificateAliases?.size
|
||||
if (aliasesSize == 1) stringResource(R.string.one_cacrt)
|
||||
else
|
||||
String.format(
|
||||
stringResource(R.string.wifi_certificate_summary_Certificates),
|
||||
aliasesSize
|
||||
)
|
||||
}
|
||||
|
||||
else -> stringResource(R.string.wifi_certificate_summary_pinning)
|
||||
}
|
||||
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = stringResource(com.android.internal.R.string.ssl_certificate)
|
||||
override val summary = { certificateAliases }
|
||||
override val onClick: () -> Unit = { createCertificateDetailsDialog(context, certX509) }
|
||||
override val summary = { certificateDetailsSummary }
|
||||
override val onClick: () -> Unit = {
|
||||
if (validationMethod == CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA)
|
||||
getCertX509(wifiEntry)?.let {
|
||||
createCertificateDetailsDialog(
|
||||
context,
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getCertX509(wifiEntry: WifiEntry): Boolean {
|
||||
certificateAliases =
|
||||
wifiEntry.wifiConfiguration?.enterpriseConfig?.caCertificateAliases?.get(0)
|
||||
?: return false
|
||||
private fun getCertX509(wifiEntry: WifiEntry): X509Certificate? {
|
||||
val certificateAliases =
|
||||
wifiEntry.certificateInfo?.caCertificateAliases?.get(0)
|
||||
?: return null
|
||||
return try {
|
||||
val keyStore = KeyStore.getInstance("AndroidKeyStore")
|
||||
keyStore.load(AndroidKeyStoreLoadStoreParameter(KeyProperties.NAMESPACE_WIFI))
|
||||
val cert = keyStore.getCertificate(certificateAliases)
|
||||
certX509 = KeyChain.toCertificate(cert.encoded)
|
||||
true
|
||||
KeyChain.toCertificate(cert.encoded)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to open Android Keystore.", e)
|
||||
false
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +151,15 @@ class CertificateDetailsPreferenceController(context: Context, preferenceKey: St
|
||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false)
|
||||
}
|
||||
|
||||
private fun isCertificateDetailsAvailable(wifiEntry: WifiEntry): Boolean {
|
||||
val validationMethod = wifiEntry.certificateInfo?.validationMethod
|
||||
return validationMethod in listOf(
|
||||
CERTIFICATE_VALIDATION_METHOD_USING_SYSTEM_CERTIFICATE,
|
||||
CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA,
|
||||
CERTIFICATE_VALIDATION_METHOD_USING_CERTIFICATE_PINNING
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "CertificateDetailsPreferenceController"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.wifi.details2
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.android.settings.R
|
||||
import com.android.settings.spa.preference.ComposePreferenceController
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.wifi.flags.Flags
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
|
||||
class ServerNamePreferenceController(context: Context, preferenceKey: String) :
|
||||
ComposePreferenceController(context, preferenceKey) {
|
||||
|
||||
private lateinit var wifiEntry: WifiEntry
|
||||
|
||||
fun setWifiEntry(entry: WifiEntry) {
|
||||
wifiEntry = entry
|
||||
}
|
||||
|
||||
override fun getAvailabilityStatus(): Int {
|
||||
return if (Flags.androidVWifiApi() && wifiEntry.certificateInfo?.domain != null) AVAILABLE
|
||||
else CONDITIONALLY_UNAVAILABLE
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
ServerName()
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ServerName() {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = stringResource(R.string.server_name_title)
|
||||
override val summary = { wifiEntry.certificateInfo?.domain ?: "" }
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -17,35 +17,27 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link VibrationIntensitySettingsFragment}. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_SEPARATE_ACCESSIBILITY_VIBRATION_SETTINGS_FRAGMENTS)
|
||||
public class VibrationIntensitySettingsFragmentTest {
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private VibrationIntensitySettingsFragment mFragment;
|
||||
|
||||
@@ -18,7 +18,9 @@ package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
@@ -29,9 +31,6 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Vibrator;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
import android.provider.Settings;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
@@ -39,10 +38,8 @@ import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -51,10 +48,6 @@ import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class VibrationPreferenceControllerTest {
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
private static final String PREFERENCE_KEY = "preference_key";
|
||||
private static final int OFF = 0;
|
||||
private static final int ON = 1;
|
||||
@@ -130,7 +123,6 @@ public class VibrationPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_SEPARATE_ACCESSIBILITY_VIBRATION_SETTINGS_FRAGMENTS)
|
||||
public void handlePreferenceTreeClick_oneIntensityLevel_opensVibrationSettings() {
|
||||
when(mResources.getInteger(R.integer.config_vibration_supported_intensity_levels))
|
||||
.thenReturn(1);
|
||||
@@ -143,7 +135,6 @@ public class VibrationPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(Flags.FLAG_SEPARATE_ACCESSIBILITY_VIBRATION_SETTINGS_FRAGMENTS)
|
||||
public void handlePreferenceTreeClick_multipleIntensityLevels_opensVibrationIntensity() {
|
||||
when(mResources.getInteger(R.integer.config_vibration_supported_intensity_levels))
|
||||
.thenReturn(2);
|
||||
|
||||
@@ -17,35 +17,26 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled;
|
||||
import android.platform.test.flag.junit.CheckFlagsRule;
|
||||
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/** Tests for {@link VibrationSettings} fragment. */
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@RequiresFlagsEnabled(Flags.FLAG_SEPARATE_ACCESSIBILITY_VIBRATION_SETTINGS_FRAGMENTS)
|
||||
public class VibrationSettingsTest {
|
||||
|
||||
@Rule
|
||||
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
|
||||
|
||||
private Context mContext;
|
||||
private Resources mResources;
|
||||
private VibrationSettings mFragment;
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
package com.android.settings.biometrics.fingerprint2.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.testing.FragmentScenario
|
||||
import androidx.fragment.app.testing.launchFragmentInContainer
|
||||
@@ -47,6 +52,7 @@ import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.android.setupdesign.GlifLayout
|
||||
import com.google.android.setupdesign.template.RequireScrollMixin
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
@@ -67,7 +73,17 @@ class FingerprintEnrollIntroFragmentTest {
|
||||
private val backgroundDispatcher = StandardTestDispatcher()
|
||||
private lateinit var fragmentScenario: FragmentScenario<FingerprintEnrollIntroV2Fragment>
|
||||
private val fingerprintSensor =
|
||||
FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
var enrollFlow = Default
|
||||
val flowViewModel = FingerprintFlowViewModel(enrollFlow)
|
||||
|
||||
@@ -538,7 +538,7 @@ public class BatteryInfoTest {
|
||||
createIntentForGetBatteryInfoTest(
|
||||
ChargingType.WIRED, ChargingSpeed.FAST, /* batteryLevel= */ 56);
|
||||
var expectedStatusLabel = "Fast charging";
|
||||
var expectedRemainingLabel = "Full by 1:30 PM";
|
||||
var expectedRemainingLabel = "Full by ";
|
||||
var expectedChargeLabel = "56% - " + expectedStatusLabel + " - " + expectedRemainingLabel;
|
||||
var currentTimeMillis = Instant.parse("2024-04-01T13:00:00Z").toEpochMilli();
|
||||
|
||||
@@ -559,7 +559,7 @@ public class BatteryInfoTest {
|
||||
createIntentForGetBatteryInfoTest(
|
||||
ChargingType.WIRED, ChargingSpeed.REGULAR, /* batteryLevel= */ 12);
|
||||
var expectedStatusLabel = "Charging";
|
||||
var expectedRemainingLabel = "Fully charged by 2:00 PM";
|
||||
var expectedRemainingLabel = "Fully charged by ";
|
||||
var expectedChargeLabel = "12% - " + expectedRemainingLabel;
|
||||
var currentTimeMillis = Instant.parse("2024-04-01T13:00:00Z").toEpochMilli();
|
||||
|
||||
@@ -580,7 +580,7 @@ public class BatteryInfoTest {
|
||||
createIntentForGetBatteryInfoTest(
|
||||
ChargingType.WIRED, ChargingSpeed.SLOW, /* batteryLevel= */ 18);
|
||||
var expectedStatusLabel = "Charging";
|
||||
var expectedRemainingLabel = "Fully charged by 3:00 PM";
|
||||
var expectedRemainingLabel = "Fully charged by";
|
||||
var expectedChargeLabel = "18% - " + expectedRemainingLabel;
|
||||
var currentTimeMillis = Instant.parse("2024-04-01T13:00:00Z").toEpochMilli();
|
||||
|
||||
@@ -601,7 +601,7 @@ public class BatteryInfoTest {
|
||||
createIntentForGetBatteryInfoTest(
|
||||
ChargingType.WIRELESS, ChargingSpeed.REGULAR, /* batteryLevel= */ 45);
|
||||
var expectedStatusLabel = "Charging";
|
||||
var expectedRemainingLabel = "Fully charged by 4:00 PM";
|
||||
var expectedRemainingLabel = "Fully charged by";
|
||||
var expectedChargeLabel = "45% - " + expectedRemainingLabel;
|
||||
var currentTimeMillis = Instant.parse("2024-04-01T15:00:00Z").toEpochMilli();
|
||||
|
||||
@@ -622,7 +622,7 @@ public class BatteryInfoTest {
|
||||
createIntentForGetBatteryInfoTest(
|
||||
ChargingType.DOCKED, ChargingSpeed.REGULAR, /* batteryLevel= */ 66);
|
||||
var expectedStatusLabel = "Charging";
|
||||
var expectedRemainingLabel = "Fully charged by 2:00 PM";
|
||||
var expectedRemainingLabel = "Fully charged by";
|
||||
var expectedChargeLabel = "66% - " + expectedRemainingLabel;
|
||||
var currentTimeMillis = Instant.parse("2021-02-09T13:00:00.00Z").toEpochMilli();
|
||||
|
||||
@@ -693,10 +693,10 @@ public class BatteryInfoTest {
|
||||
.isEqualTo(expectedStatusLabel);
|
||||
assertWithMessage("remainingLabel is incorrect")
|
||||
.that(info.remainingLabel.toString())
|
||||
.isEqualTo(expectedRemainingLabel);
|
||||
.contains(expectedRemainingLabel);
|
||||
assertWithMessage("chargeLabel is incorrect")
|
||||
.that(info.chargeLabel.toString())
|
||||
.isEqualTo(expectedChargeLabel);
|
||||
.contains(expectedChargeLabel);
|
||||
}
|
||||
|
||||
private static Intent createBatteryIntent(int plugged, int level, int status) {
|
||||
|
||||
@@ -31,8 +31,10 @@ import android.content.Context;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.platform.test.flag.junit.SetFlagsRule;
|
||||
import android.provider.Settings;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.preference.Preference;
|
||||
@@ -50,6 +52,7 @@ 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.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -65,6 +68,8 @@ import java.util.Map;
|
||||
public class LocationInjectedServicesPreferenceControllerTest {
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Rule
|
||||
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
|
||||
|
||||
private static final String KEY_LOCATION_SERVICES = "location_service";
|
||||
|
||||
@@ -140,8 +145,13 @@ public class LocationInjectedServicesPreferenceControllerTest {
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
|
||||
ArgumentCaptor.forClass(ArraySet.class);
|
||||
verify(mSettingsInjector).getInjectedSettings(
|
||||
any(Context.class), eq(UserHandle.myUserId()));
|
||||
any(Context.class), profilesArgumentCaptor.capture());
|
||||
assertThat(profilesArgumentCaptor.getValue())
|
||||
.doesNotContain(UserHandle.of(fakeWorkProfileId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,6 +159,9 @@ public class LocationInjectedServicesPreferenceControllerTest {
|
||||
final int fakeWorkProfileId = 123;
|
||||
ShadowUserManager.getShadow().setProfileIdsWithDisabled(
|
||||
new int[]{UserHandle.myUserId(), fakeWorkProfileId});
|
||||
ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
|
||||
ShadowUserManager.getShadow().addProfile(new UserInfo(fakeWorkProfileId, "",
|
||||
UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_PROFILE));
|
||||
|
||||
// Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return null.
|
||||
// Empty enforcing users.
|
||||
@@ -159,8 +172,77 @@ public class LocationInjectedServicesPreferenceControllerTest {
|
||||
enforcingUsers);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
|
||||
ArgumentCaptor.forClass(ArraySet.class);
|
||||
verify(mSettingsInjector).getInjectedSettings(
|
||||
any(Context.class), eq(UserHandle.USER_CURRENT));
|
||||
any(Context.class), profilesArgumentCaptor.capture());
|
||||
assertThat(profilesArgumentCaptor.getValue()).contains(UserHandle.of(fakeWorkProfileId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateProfileDisallowShareLocationOn_getParentUserLocationServicesOnly() {
|
||||
mSetFlagsRule.enableFlags(
|
||||
android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
|
||||
android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES,
|
||||
android.multiuser.Flags.FLAG_HANDLE_INTERLEAVED_SETTINGS_FOR_PRIVATE_SPACE);
|
||||
final int fakePrivateProfileId = 123;
|
||||
ShadowUserManager.getShadow().setProfileIdsWithDisabled(
|
||||
new int[]{UserHandle.myUserId(), fakePrivateProfileId});
|
||||
ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
|
||||
ShadowUserManager.getShadow().setPrivateProfile(fakePrivateProfileId, "private", 0);
|
||||
ShadowUserManager.getShadow().addUserProfile(UserHandle.of(fakePrivateProfileId));
|
||||
|
||||
// Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return non-null.
|
||||
final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
|
||||
enforcingUsers.add(new UserManager.EnforcingUser(fakePrivateProfileId,
|
||||
UserManager.RESTRICTION_SOURCE_DEVICE_OWNER));
|
||||
final ComponentName componentName = new ComponentName("test", "test");
|
||||
// Ensure that RestrictedLockUtils.checkIfRestrictionEnforced doesn't return null.
|
||||
ShadowUserManager.getShadow().setUserRestrictionSources(
|
||||
UserManager.DISALLOW_SHARE_LOCATION,
|
||||
UserHandle.of(fakePrivateProfileId),
|
||||
enforcingUsers);
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(componentName);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
|
||||
ArgumentCaptor.forClass(ArraySet.class);
|
||||
verify(mSettingsInjector).getInjectedSettings(
|
||||
any(Context.class), profilesArgumentCaptor.capture());
|
||||
assertThat(profilesArgumentCaptor.getValue())
|
||||
.doesNotContain(UserHandle.of(fakePrivateProfileId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void privateProfileDisallowShareLocationOff_getAllUserLocationServices() {
|
||||
mSetFlagsRule.enableFlags(
|
||||
android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
|
||||
android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES,
|
||||
android.multiuser.Flags.FLAG_HANDLE_INTERLEAVED_SETTINGS_FOR_PRIVATE_SPACE);
|
||||
final int fakePrivateProfileId = 123;
|
||||
ShadowUserManager.getShadow().setProfileIdsWithDisabled(
|
||||
new int[]{UserHandle.myUserId(), fakePrivateProfileId});
|
||||
ShadowUserManager.getShadow().addProfile(new UserInfo(UserHandle.myUserId(), "", 0));
|
||||
ShadowUserManager.getShadow().setPrivateProfile(fakePrivateProfileId, "private", 0);
|
||||
ShadowUserManager.getShadow().addUserProfile(UserHandle.of(fakePrivateProfileId));
|
||||
|
||||
// Mock RestrictedLockUtils.checkIfRestrictionEnforced and let it return null.
|
||||
// Empty enforcing users.
|
||||
final List<UserManager.EnforcingUser> enforcingUsers = new ArrayList<>();
|
||||
ShadowUserManager.getShadow().setUserRestrictionSources(
|
||||
UserManager.DISALLOW_SHARE_LOCATION,
|
||||
UserHandle.of(fakePrivateProfileId),
|
||||
enforcingUsers);
|
||||
|
||||
mController.displayPreference(mScreen);
|
||||
|
||||
ArgumentCaptor<ArraySet<UserHandle>> profilesArgumentCaptor =
|
||||
ArgumentCaptor.forClass(ArraySet.class);
|
||||
verify(mSettingsInjector).getInjectedSettings(
|
||||
any(Context.class), profilesArgumentCaptor.capture());
|
||||
assertThat(profilesArgumentCaptor.getValue()).contains(UserHandle.of(fakePrivateProfileId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -180,7 +262,7 @@ public class LocationInjectedServicesPreferenceControllerTest {
|
||||
final Map<Integer, List<Preference>> map = new ArrayMap<>();
|
||||
map.put(UserHandle.myUserId(), preferences);
|
||||
doReturn(map).when(mSettingsInjector)
|
||||
.getInjectedSettings(any(Context.class), anyInt());
|
||||
.getInjectedSettings(any(Context.class), any(ArraySet.class));
|
||||
ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{UserHandle.myUserId()});
|
||||
|
||||
final int userId = UserHandle.myUserId();
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
package com.android.settings.tests.screenshot.biometrics.fingerprint
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import android.view.Surface
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
@@ -39,9 +44,7 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintScrollViewModel
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
|
||||
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
@@ -56,7 +59,19 @@ import platform.test.screenshot.matchers.PixelPerfectMatcher
|
||||
class Injector(step: FingerprintNavigationStep.UiStep) {
|
||||
|
||||
var enrollFlow = Default
|
||||
var fingerprintSensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.REAR)
|
||||
var fingerprintSensor =
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_REAR,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
var accessibilityInteractor =
|
||||
object : AccessibilityInteractor {
|
||||
override val isAccessibilityEnabled: Flow<Boolean> = flowOf(true)
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.android.settings.testutils2
|
||||
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerEnrollState
|
||||
@@ -23,7 +28,7 @@ import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAtt
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
@@ -35,16 +40,20 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor {
|
||||
var enrolledFingerprintsInternal: MutableList<FingerprintData> = mutableListOf()
|
||||
var challengeToGenerate: Pair<Long, ByteArray> = Pair(-1L, byteArrayOf())
|
||||
var authenticateAttempt = FingerprintAuthAttemptModel.Success(1)
|
||||
var enrollStateViewModel: List<FingerEnrollState> =
|
||||
listOf(FingerEnrollState.EnrollProgress(5, 5))
|
||||
var enrollStateViewModel: List<FingerEnrollState> = listOf(FingerEnrollState.EnrollProgress(5, 5))
|
||||
|
||||
var sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5,
|
||||
FingerprintSensorType.POWER_BUTTON
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
override suspend fun authenticate(): FingerprintAuthAttemptModel {
|
||||
return authenticateAttempt
|
||||
@@ -68,7 +77,7 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor {
|
||||
|
||||
override suspend fun enroll(
|
||||
hardwareAuthToken: ByteArray?,
|
||||
enrollReason: EnrollReason
|
||||
enrollReason: EnrollReason,
|
||||
): Flow<FingerEnrollState> = flowOf(*enrollStateViewModel.toTypedArray())
|
||||
|
||||
override suspend fun removeFingerprint(fp: FingerprintData): Boolean {
|
||||
@@ -84,5 +93,4 @@ class FakeFingerprintManagerInteractor : FingerprintManagerInteractor {
|
||||
override suspend fun hasSideFps(): Boolean {
|
||||
return sensorProp.sensorType == FingerprintSensorType.POWER_BUTTON
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.wifi.details2
|
||||
|
||||
import android.content.Context
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
@@ -24,13 +25,15 @@ import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import java.security.cert.X509Certificate
|
||||
import com.android.settings.R
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.whenever
|
||||
@@ -40,21 +43,26 @@ class CertificateDetailsPreferenceControllerTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
private val mockCertX509 = mock<X509Certificate> {}
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
doNothing().whenever(mock).startActivity(any())
|
||||
}
|
||||
|
||||
private val controller = CertificateDetailsPreferenceController(context, TEST_KEY)
|
||||
|
||||
private val mockCertificateInfo = mock<WifiEntry.CertificateInfo> {
|
||||
it.validationMethod =
|
||||
WifiEntry.CertificateInfo.CERTIFICATE_VALIDATION_METHOD_USING_INSTALLED_ROOTCA
|
||||
it.caCertificateAliases = arrayOf(MOCK_CA)
|
||||
}
|
||||
private val mockWifiEntry =
|
||||
mock<WifiEntry> { on { certificateInfo } doReturn mockCertificateInfo }
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
controller.certificateAliases = MOCK_CA
|
||||
controller.certX509 = mockCertX509
|
||||
controller.setWifiEntry(mockWifiEntry)
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||
fun title_isDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
@@ -62,8 +70,21 @@ class CertificateDetailsPreferenceControllerTest {
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(com.android.internal.R.string.ssl_certificate))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText(
|
||||
context.getString(com.android.internal.R.string.ssl_certificate)
|
||||
).assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||
fun one_caCertificate_summary() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
controller.Content()
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.one_cacrt)).assertIsDisplayed()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2024 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.wifi.details2
|
||||
|
||||
import android.content.Context
|
||||
import android.platform.test.annotations.RequiresFlagsEnabled
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ServerNamePreferenceControllerTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
doNothing().whenever(mock).startActivity(any())
|
||||
}
|
||||
private val controller = ServerNamePreferenceController(context, TEST_KEY)
|
||||
|
||||
private val mockCertificateInfo = mock<WifiEntry.CertificateInfo> {
|
||||
it.domain = DOMAIN
|
||||
}
|
||||
|
||||
private val mockWifiEntry =
|
||||
mock<WifiEntry> { on { certificateInfo } doReturn mockCertificateInfo }
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
controller.setWifiEntry(mockWifiEntry)
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||
fun title_isDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
controller.Content()
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.server_name_title))
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequiresFlagsEnabled(com.android.wifi.flags.Flags.FLAG_ANDROID_V_WIFI_API)
|
||||
fun summary_isDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
controller.Content()
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(DOMAIN).assertIsDisplayed()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TEST_KEY = "test_key"
|
||||
const val DOMAIN = "domain"
|
||||
}
|
||||
}
|
||||
@@ -18,18 +18,23 @@ package com.android.settings.fingerprint2.domain.interactor
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.Fingerprint
|
||||
import android.hardware.fingerprint.FingerprintEnrollOptions
|
||||
import android.hardware.fingerprint.FingerprintManager
|
||||
import android.hardware.fingerprint.FingerprintManager.CryptoObject
|
||||
import android.hardware.fingerprint.FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import android.os.CancellationSignal
|
||||
import android.os.Handler
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.android.settings.biometrics.GatekeeperPasswordProvider
|
||||
import com.android.settings.biometrics.fingerprint2.data.repository.FingerprintSensorRepository
|
||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.PressToAuthInteractor
|
||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.FingerprintManagerInteractorImpl
|
||||
import com.android.settings.biometrics.fingerprint2.domain.interactor.PressToAuthInteractor
|
||||
import com.android.settings.biometrics.fingerprint2.lib.domain.interactor.FingerprintManagerInteractor
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.Default
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.EnrollReason
|
||||
@@ -38,8 +43,7 @@ import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAtt
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
|
||||
import com.android.settings.password.ChooseLockSettingsHelper
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.cancelAndJoin
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -85,7 +89,18 @@ class FingerprintManagerInteractorTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
|
||||
val sensor =
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
val fingerprintSensorRepository =
|
||||
object : FingerprintSensorRepository {
|
||||
override val fingerprintSensor: Flow<FingerprintSensor> = flowOf(sensor)
|
||||
@@ -135,7 +150,7 @@ class FingerprintManagerInteractorTest {
|
||||
listOf(
|
||||
Fingerprint("Finger 1,", 2, 3L),
|
||||
Fingerprint("Finger 2,", 3, 3L),
|
||||
Fingerprint("Finger 3,", 4, 3L)
|
||||
Fingerprint("Finger 3,", 4, 3L),
|
||||
)
|
||||
val fingerprintList2: List<Fingerprint> =
|
||||
fingerprintList1.plus(
|
||||
@@ -160,7 +175,7 @@ class FingerprintManagerInteractorTest {
|
||||
gateKeeperPasswordProvider.requestGatekeeperHat(
|
||||
any(Intent::class.java),
|
||||
anyLong(),
|
||||
anyInt()
|
||||
anyInt(),
|
||||
)
|
||||
)
|
||||
.thenReturn(byteArray)
|
||||
@@ -223,7 +238,7 @@ class FingerprintManagerInteractorTest {
|
||||
removalCallback.value.onRemovalError(
|
||||
fingerprintToRemove,
|
||||
100,
|
||||
"Oh no, we couldn't find that one"
|
||||
"Oh no, we couldn't find that one",
|
||||
)
|
||||
|
||||
runCurrent()
|
||||
@@ -260,7 +275,7 @@ class FingerprintManagerInteractorTest {
|
||||
any(CancellationSignal::class.java),
|
||||
capture(authCallback),
|
||||
nullable(Handler::class.java),
|
||||
anyInt()
|
||||
anyInt(),
|
||||
)
|
||||
authCallback.value.onAuthenticationSucceeded(
|
||||
FingerprintManager.AuthenticationResult(null, fingerprint, 1, false)
|
||||
@@ -287,7 +302,7 @@ class FingerprintManagerInteractorTest {
|
||||
any(CancellationSignal::class.java),
|
||||
capture(authCallback),
|
||||
nullable(Handler::class.java),
|
||||
anyInt()
|
||||
anyInt(),
|
||||
)
|
||||
authCallback.value.onAuthenticationError(FINGERPRINT_ERROR_LOCKOUT_PERMANENT, "Lockout!!")
|
||||
|
||||
|
||||
@@ -18,6 +18,11 @@ package com.android.settings.fingerprint2.enrollment.viewmodel
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import android.view.Surface
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
@@ -33,9 +38,7 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
|
||||
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -94,7 +97,19 @@ class FingerprintEnrollFindSensorViewModelV2Test {
|
||||
)
|
||||
.create(FingerprintGatekeeperViewModel::class.java)
|
||||
|
||||
val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
|
||||
val sensor =
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
|
||||
navigationViewModel =
|
||||
FingerprintNavigationViewModel(
|
||||
@@ -159,12 +174,17 @@ class FingerprintEnrollFindSensorViewModelV2Test {
|
||||
fun udfpsLottieInfo() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5,
|
||||
FingerprintSensorType.UDFPS_OPTICAL,
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
var udfpsLottieInfo: Boolean? = null
|
||||
val job = launch { underTest.udfpsLottieInfo.collect { udfpsLottieInfo = it } }
|
||||
@@ -218,7 +238,17 @@ class FingerprintEnrollFindSensorViewModelV2Test {
|
||||
fun rfpsAnimation() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(0 /* sensorId */, SensorStrength.STRONG, 5, FingerprintSensorType.REAR)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_REAR,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
var showRfpsAnimation: Boolean? = null
|
||||
val job = launch { underTest.showRfpsAnimation.collect { showRfpsAnimation = it } }
|
||||
@@ -232,12 +262,17 @@ class FingerprintEnrollFindSensorViewModelV2Test {
|
||||
fun showPrimaryButton_ifUdfps() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5,
|
||||
FingerprintSensorType.UDFPS_OPTICAL,
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
var showPrimaryButton: Boolean? = null
|
||||
val job = launch { underTest.showPrimaryButton.collect { showPrimaryButton = it } }
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.android.settings.fingerprint2.ui.enrollment.viewmodel
|
||||
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.Default
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintEnrollConfirmationViewModel
|
||||
@@ -26,6 +31,7 @@ import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
@@ -68,8 +74,18 @@ class FingerprintEnrollConfirmationViewModelTest {
|
||||
@Test
|
||||
fun testCanEnrollFingerprints() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(0 /* sensorId */, SensorStrength.STRONG, 5, FingerprintSensorType.REAR)
|
||||
fakeFingerprintManagerInteractor.sensorProp = FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = mutableListOf()
|
||||
fakeFingerprintManagerInteractor.enrollableFingerprints = 5
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.android.settings.fingerprint2.ui.enrollment.viewmodel
|
||||
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.Default
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.BackgroundViewModel
|
||||
@@ -26,11 +31,8 @@ import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.Fing
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationStep.Enrollment
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.FingerprintNavigationViewModel
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.GatekeeperInfo
|
||||
import com.android.settings.biometrics.fingerprint2.ui.enrollment.viewmodel.NavigationState
|
||||
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -72,7 +74,18 @@ class FingerprintEnrollEnrollingViewModelTest {
|
||||
fakeFingerprintManagerInteractor,
|
||||
)
|
||||
.create(FingerprintGatekeeperViewModel::class.java)
|
||||
val sensor = FingerprintSensor(1, SensorStrength.STRONG, 5, FingerprintSensorType.POWER_BUTTON)
|
||||
val sensor =
|
||||
FingerprintSensorPropertiesInternal(
|
||||
1 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
val fingerprintFlowViewModel = FingerprintFlowViewModel(Default)
|
||||
|
||||
navigationViewModel =
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package com.android.settings.fingerprint2.ui.settings
|
||||
|
||||
import android.hardware.biometrics.ComponentInfoInternal
|
||||
import android.hardware.biometrics.SensorLocationInternal
|
||||
import android.hardware.biometrics.SensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintAuthAttemptModel
|
||||
import com.android.settings.biometrics.fingerprint2.lib.model.FingerprintData
|
||||
@@ -23,9 +28,7 @@ import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.Finger
|
||||
import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.FingerprintSettingsViewModel
|
||||
import com.android.settings.biometrics.fingerprint2.ui.settings.viewmodel.PreferenceViewModel
|
||||
import com.android.settings.testutils2.FakeFingerprintManagerInteractor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensor
|
||||
import com.android.systemui.biometrics.shared.model.FingerprintSensorType
|
||||
import com.android.systemui.biometrics.shared.model.SensorStrength
|
||||
import com.android.systemui.biometrics.shared.model.toFingerprintSensor
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
@@ -96,12 +99,18 @@ class FingerprintSettingsViewModelTest {
|
||||
fun authenticate_DoesNotRun_ifOptical() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
FingerprintSensorType.UDFPS_OPTICAL,
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_UDFPS_OPTICAL,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
|
||||
mutableListOf(FingerprintData("a", 1, 3L))
|
||||
|
||||
@@ -132,12 +141,18 @@ class FingerprintSettingsViewModelTest {
|
||||
fun authenticate_DoesNotRun_ifUltrasonic() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
FingerprintSensorType.UDFPS_ULTRASONIC,
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_UDFPS_ULTRASONIC,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
|
||||
mutableListOf(FingerprintData("a", 1, 3L))
|
||||
|
||||
@@ -166,12 +181,18 @@ class FingerprintSettingsViewModelTest {
|
||||
fun authenticate_DoesRun_ifNotUdfps() =
|
||||
testScope.runTest {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
FingerprintSensorType.POWER_BUTTON
|
||||
)
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal =
|
||||
mutableListOf(FingerprintData("a", 1, 3L))
|
||||
val success = FingerprintAuthAttemptModel.Success(1)
|
||||
@@ -324,8 +345,7 @@ class FingerprintSettingsViewModelTest {
|
||||
runCurrent()
|
||||
assertThat(authAttempt).isEqualTo(success)
|
||||
|
||||
fakeFingerprintManagerInteractor.authenticateAttempt =
|
||||
FingerprintAuthAttemptModel.Success(10)
|
||||
fakeFingerprintManagerInteractor.authenticateAttempt = FingerprintAuthAttemptModel.Success(10)
|
||||
underTest.shouldAuthenticate(false)
|
||||
advanceTimeBy(400)
|
||||
runCurrent()
|
||||
@@ -372,14 +392,19 @@ class FingerprintSettingsViewModelTest {
|
||||
|
||||
private fun setupAuth(): MutableList<FingerprintData> {
|
||||
fakeFingerprintManagerInteractor.sensorProp =
|
||||
FingerprintSensor(
|
||||
0 /* sensorId */,
|
||||
SensorStrength.STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
FingerprintSensorType.POWER_BUTTON
|
||||
)
|
||||
val fingerprints =
|
||||
mutableListOf(FingerprintData("a", 1, 3L), FingerprintData("b", 2, 5L))
|
||||
FingerprintSensorPropertiesInternal(
|
||||
0 /* sensorId */,
|
||||
SensorProperties.STRENGTH_STRONG,
|
||||
5 /* maxEnrollmentsPerUser */,
|
||||
listOf<ComponentInfoInternal>(),
|
||||
FingerprintSensorProperties.TYPE_POWER_BUTTON,
|
||||
false /* halControlsIllumination */,
|
||||
true /* resetLockoutRequiresHardwareAuthToken */,
|
||||
listOf<SensorLocationInternal>(SensorLocationInternal.DEFAULT),
|
||||
)
|
||||
.toFingerprintSensor()
|
||||
|
||||
val fingerprints = mutableListOf(FingerprintData("a", 1, 3L), FingerprintData("b", 2, 5L))
|
||||
fakeFingerprintManagerInteractor.enrolledFingerprintsInternal = fingerprints
|
||||
val success = FingerprintAuthAttemptModel.Success(1)
|
||||
fakeFingerprintManagerInteractor.authenticateAttempt = success
|
||||
|
||||
@@ -66,6 +66,7 @@ public class FaceFingerprintUnlockControllerTest {
|
||||
final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
.thenReturn(mLockPatternUtils);
|
||||
doReturn(true).when(mLockPatternUtils).isSecure(anyInt());
|
||||
|
||||
mFaceFingerprintUnlockController =
|
||||
new FaceFingerprintUnlockController(mContext, mLifecycle);
|
||||
|
||||
@@ -72,6 +72,7 @@ public class PrivateSpaceLockControllerTest {
|
||||
final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
.thenReturn(mLockPatternUtils);
|
||||
doReturn(true).when(mLockPatternUtils).isSecure(anyInt());
|
||||
|
||||
mPrivateSpaceLockController = new PrivateSpaceLockController(mContext,
|
||||
mSettingsPreferenceFragment);
|
||||
|
||||
@@ -68,6 +68,7 @@ public class UseOneLockControllerTest {
|
||||
final FakeFeatureFactory featureFactory = FakeFeatureFactory.setupForTest();
|
||||
when(featureFactory.securityFeatureProvider.getLockPatternUtils(mContext))
|
||||
.thenReturn(mLockPatternUtils);
|
||||
doReturn(true).when(mLockPatternUtils).isSecure(anyInt());
|
||||
mUseOneLockController = new UseOneLockController(mContext, preferenceKey);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user