Snap for 9325779 from 8d4a48e1d1 to udc-release
Change-Id: I09f48931d78d22dc982c44c7ac8084d99d095f64
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
<?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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingStart="@dimen/preference_no_icon_padding_start"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/charge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:fontFamily="@*android:string/config_headlineFontFamily"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textSize="36sp"
|
||||
android:textColor="?android:attr/colorAccent" />
|
||||
|
||||
<com.android.settings.widget.UsageView
|
||||
android:id="@+id/battery_usage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="141dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
settings:sideLabels="@array/battery_labels"
|
||||
android:colorAccent="?android:attr/colorAccent"
|
||||
android:gravity="end"
|
||||
settings:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bottom_summary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -4582,8 +4582,6 @@
|
||||
<string name="power_usage_summary_title">Battery</string>
|
||||
<!-- Activity title summary for App Fuel Gauge summary -->
|
||||
<string name="power_usage_summary">What has been using the battery</string>
|
||||
<!-- Message to show when battery usage data is not available [CHAR LIMIT=30] -->
|
||||
<string name="power_usage_not_available">Battery usage data isn\u2019t available.</string>
|
||||
<!-- Display the battery level and status [CHAR_LIMIT=60] -->
|
||||
<string name="power_usage_level_and_status"><xliff:g id="level">%1$s</xliff:g>
|
||||
- <xliff:g id="status">%2$s</xliff:g></string>
|
||||
@@ -4631,8 +4629,6 @@
|
||||
|
||||
<!-- Title for the screen usage in power use UI [CHAR_LIMIT=60] -->
|
||||
<string name="device_screen_usage">Screen usage since full charge</string>
|
||||
<!-- Label for list of apps using battery in power use UI. Note: ^1 should be used in all translations[CHAR_LIMIT=120] -->
|
||||
<string name="power_usage_list_summary">Battery usage since full charge</string>
|
||||
<!-- Temp string used to debug new battery estimates [DO NOT TRANSLATE] -->
|
||||
<string name="power_usage_enhanced_debug" translatable="false"><xliff:g id="time">%1$s</xliff:g> left (New ML est)</string>
|
||||
<!-- Temp string used to debug old battery estimates [DO NOT TRANSLATE] -->
|
||||
@@ -4800,8 +4796,6 @@
|
||||
<!-- Label for power consumed by Calling -->
|
||||
<string name="power_phone">Voice calls</string>
|
||||
|
||||
<!-- Description for battery usage time for an app, i.e. Used for 30min. Note: ^1 should be used in all translations [CHAR LIMIT=60] -->
|
||||
<string name="battery_used_for">Used for <xliff:g id="time">^1</xliff:g></string>
|
||||
<!-- Description for battery screen usage time for an app, i.e. Screen usage 30min. Note: ^1 should be used in all translations [CHAR LIMIT=60] -->
|
||||
<string name="battery_screen_usage">Screen usage <xliff:g id="time">^1</xliff:g></string>
|
||||
<!-- Description for battery usage info for an app, i.e. 60% used by facebook. [CHAR LIMIT=60] -->
|
||||
@@ -4870,9 +4864,6 @@
|
||||
<!-- Description for other users aggregated battery usage data [CHAR LIMIT=120] -->
|
||||
<string name="battery_usage_other_users">Other users</string>
|
||||
|
||||
<!-- Graph subtext displayed to user when enhanced battery estimate is being used [CHAR LIMIT=120] -->
|
||||
<string name="advanced_battery_graph_subtext">Battery left estimate is based on your device usage</string>
|
||||
|
||||
<!-- Description for battery time left, i.e. 50min Estimated time left. [CHAR LIMIT=80]-->
|
||||
<string name="estimated_time_left">Estimated time left</string>
|
||||
|
||||
@@ -5141,6 +5132,8 @@
|
||||
<string name="adaptive_connectivity_title">Adaptive connectivity</string>
|
||||
<!-- Summary of Adaptive connectivity preference. [CHAR LIMIT=NONE] -->
|
||||
<string name="adaptive_connectivity_summary">Extends battery life and improves device performance by automatically managing your network connections</string>
|
||||
<!-- Title for adaptive connectivity main switch preferences. [CHAR LIMIT=50] -->
|
||||
<string name="adaptive_connectivity_main_switch_title">Use adaptive connectivity</string>
|
||||
|
||||
<!-- Title of preference group for credential storage settings [CHAR LIMIT=30] -->
|
||||
<string name="credentials_title">Credential storage</string>
|
||||
@@ -10510,12 +10503,15 @@
|
||||
<string name="wifi_calling_summary">Use Wi\u2011Fi for calls to improve quality</string>
|
||||
|
||||
<!-- Mobile network settings screen, title of Backup calling setting. [CHAR LIMIT=NONE] -->
|
||||
<!-- Deprecated ToDo: b/260059444 remove it next version-->
|
||||
<string name="backup_calling_settings_title">Backup calling</string>
|
||||
|
||||
<!-- Backup calling summary. [CHAR LIMIT=100] -->
|
||||
<!-- Deprecated ToDo: b/260059444 remove it next version-->
|
||||
<string name="backup_calling_setting_summary">If <xliff:g id="backup_calling_operator_text" example="Google Fi">%1$s</xliff:g> is unavailable or roaming, use your mobile data SIM for <xliff:g id="backup_calling_carrier_text" example="Google Fi">%1$s</xliff:g> calls.</string>
|
||||
|
||||
<!-- List of synonyms for the cross SIM calling titles, used to match in settings search [CHAR LIMIT=NONE] -->
|
||||
<!-- Deprecated ToDo: b/260059444 remove it next version-->
|
||||
<string name="keywords_backup_calling">backup calling</string>
|
||||
|
||||
<!-- Title for enable MMS notification when trying to receive MMS. [CHAR LIMIT=40] -->
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
<com.android.settingslib.widget.MainSwitchPreference
|
||||
android:key="adaptive_connectivity"
|
||||
android:title="@string/adaptive_connectivity_title"
|
||||
android:title="@string/adaptive_connectivity_main_switch_title"
|
||||
settings:controller="com.android.settings.network.AdaptiveConnectivityTogglePreferenceController"/>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -183,14 +183,6 @@
|
||||
android:persistent="true"
|
||||
settings:controller="com.android.settings.network.telephony.VideoCallingPreferenceController"/>
|
||||
|
||||
<SwitchPreference
|
||||
android:key="backup_calling_key"
|
||||
android:title="@string/backup_calling_settings_title"
|
||||
android:persistent="false"
|
||||
android:summary="@string/backup_calling_setting_summary"
|
||||
settings:keywords="@string/keywords_backup_calling"
|
||||
settings:controller="com.android.settings.network.telephony.BackupCallingPreferenceController"/>
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<com.android.settings.network.telephony.cdma.CdmaListPreference
|
||||
|
||||
@@ -43,12 +43,4 @@
|
||||
settings:controller="com.android.settings.network.telephony.NetworkProviderWifiCallingPreferenceController"
|
||||
settings:allowDividerAbove="true"
|
||||
/>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="provider_model_backup_calling_category"
|
||||
android:title="@string/backup_calling_settings_title"
|
||||
android:order="25"
|
||||
settings:controller="com.android.settings.network.telephony.NetworkProviderBackupCallingPreferenceController"
|
||||
settings:allowDividerAbove="true"
|
||||
/>
|
||||
</PreferenceScreen>
|
||||
|
||||
@@ -208,7 +208,7 @@ public class ActivityEmbeddingRulesController {
|
||||
final SplitPlaceholderRule placeholderRule = new SplitPlaceholderRule(
|
||||
activityFilters,
|
||||
intent,
|
||||
true /* stickyPlaceholder */,
|
||||
false /* stickyPlaceholder */,
|
||||
SplitRule.FINISH_ADJACENT,
|
||||
ActivityEmbeddingUtils.getMinCurrentScreenSplitWidthPx(mContext),
|
||||
ActivityEmbeddingUtils.getMinSmallestScreenSplitWidthPx(mContext),
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.applications.intentpicker;
|
||||
import static android.content.pm.verify.domain.DomainVerificationUserState.DOMAIN_STATE_NONE;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.verify.domain.DomainOwner;
|
||||
@@ -113,7 +114,7 @@ public class ProgressDialogFragment extends InstrumentedDialogFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
return SettingsEnums.PROGRESS_DIALOG;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings.applications.intentpicker;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.verify.domain.DomainVerificationManager;
|
||||
@@ -73,7 +74,7 @@ public class SupportedLinksDialogFragment extends InstrumentedDialogFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
return SettingsEnums.SUPPORTED_LINKS_DIALOG;
|
||||
}
|
||||
|
||||
/** Display the dialog. */
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* 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.biometrics2.factory;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentFactory;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.android.settings.biometrics2.ui.view.FingerprintEnrollIntroFragment;
|
||||
|
||||
/**
|
||||
* Fragment factory for biometrics
|
||||
*/
|
||||
public class BiometricsFragmentFactory extends FragmentFactory {
|
||||
|
||||
private final Application mApplication;
|
||||
private final ViewModelProvider mViewModelProvider;
|
||||
|
||||
public BiometricsFragmentFactory(Application application,
|
||||
ViewModelProvider viewModelProvider) {
|
||||
mApplication = application;
|
||||
mViewModelProvider = viewModelProvider;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
|
||||
final Class<? extends Fragment> clazz = loadFragmentClass(classLoader, className);
|
||||
if (FingerprintEnrollIntroFragment.class.equals(clazz)) {
|
||||
final DevicePolicyManager devicePolicyManager =
|
||||
mApplication.getSystemService(DevicePolicyManager.class);
|
||||
if (devicePolicyManager != null) {
|
||||
return new FingerprintEnrollIntroFragment(mViewModelProvider,
|
||||
devicePolicyManager.getResources());
|
||||
}
|
||||
}
|
||||
return super.instantiate(classLoader, className);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_C
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -80,17 +81,30 @@ public final class CredentialModel {
|
||||
@Nullable
|
||||
private Long mClearGkPwHandleMillis = null;
|
||||
|
||||
public CredentialModel(@NonNull Intent intent, @NonNull Clock clock) {
|
||||
mUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
mSensorId = intent.getIntExtra(EXTRA_KEY_SENSOR_ID, INVALID_SENSOR_ID);
|
||||
mChallenge = intent.getLongExtra(EXTRA_KEY_CHALLENGE, INVALID_CHALLENGE);
|
||||
mToken = intent.getByteArrayExtra(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
mGkPwHandle = intent.getLongExtra(EXTRA_KEY_GK_PW_HANDLE,
|
||||
INVALID_GK_PW_HANDLE);
|
||||
public CredentialModel(@NonNull Bundle bundle, @NonNull Clock clock) {
|
||||
mUserId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
mSensorId = bundle.getInt(EXTRA_KEY_SENSOR_ID, INVALID_SENSOR_ID);
|
||||
mChallenge = bundle.getLong(EXTRA_KEY_CHALLENGE, INVALID_CHALLENGE);
|
||||
mToken = bundle.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
mGkPwHandle = bundle.getLong(EXTRA_KEY_GK_PW_HANDLE, INVALID_GK_PW_HANDLE);
|
||||
mClock = clock;
|
||||
mInitMillis = mClock.millis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a bundle which can be used to recreate CredentialModel
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getBundle() {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt(Intent.EXTRA_USER_ID, mUserId);
|
||||
bundle.putInt(EXTRA_KEY_SENSOR_ID, mSensorId);
|
||||
bundle.putLong(EXTRA_KEY_CHALLENGE, mChallenge);
|
||||
bundle.putByteArray(EXTRA_KEY_CHALLENGE_TOKEN, mToken);
|
||||
bundle.putLong(EXTRA_KEY_GK_PW_HANDLE, mGkPwHandle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get userId for this credential
|
||||
*/
|
||||
|
||||
@@ -25,7 +25,7 @@ import static com.android.settings.biometrics2.ui.model.FingerprintEnrollIntroSt
|
||||
import static com.google.android.setupdesign.util.DynamicColorPalette.ColorType.ACCENT;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyResourcesManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
@@ -44,6 +44,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
@@ -63,9 +64,6 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
|
||||
private static final String TAG = "FingerprintEnrollIntroFragment";
|
||||
|
||||
@NonNull private final ViewModelProvider mViewModelProvider;
|
||||
@Nullable private final DevicePolicyResourcesManager mDevicePolicyMgrRes;
|
||||
|
||||
private FingerprintEnrollIntroViewModel mViewModel = null;
|
||||
|
||||
private View mView = null;
|
||||
@@ -75,12 +73,8 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
private TextView mFooterMessage6 = null;
|
||||
@Nullable private PorterDuffColorFilter mIconColorFilter;
|
||||
|
||||
public FingerprintEnrollIntroFragment(
|
||||
@NonNull ViewModelProvider viewModelProvider,
|
||||
@Nullable DevicePolicyResourcesManager devicePolicyMgrRes) {
|
||||
public FingerprintEnrollIntroFragment() {
|
||||
super();
|
||||
mViewModelProvider = viewModelProvider;
|
||||
mDevicePolicyMgrRes = devicePolicyMgrRes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -127,15 +121,6 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
footerTitle2.setText(
|
||||
R.string.security_settings_fingerprint_enroll_introduction_footer_title_2);
|
||||
|
||||
return mView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
final Context context = view.getContext();
|
||||
|
||||
final TextView footerLink = mView.findViewById(R.id.footer_learn_more);
|
||||
footerLink.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
final String footerLinkStr = getContext().getString(
|
||||
@@ -146,18 +131,28 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
// footer buttons
|
||||
mPrimaryFooterButton = new FooterButton.Builder(context)
|
||||
.setText(R.string.security_settings_fingerprint_enroll_introduction_agree)
|
||||
.setListener(mViewModel::onNextButtonClick)
|
||||
.setButtonType(FooterButton.ButtonType.OPT_IN)
|
||||
.setTheme(R.style.SudGlifButton_Primary)
|
||||
.build();
|
||||
mSecondaryFooterButton = new FooterButton.Builder(context)
|
||||
.setListener(mViewModel::onSkipOrCancelButtonClick)
|
||||
.setButtonType(FooterButton.ButtonType.NEXT)
|
||||
.setTheme(R.style.SudGlifButton_Primary)
|
||||
.build();
|
||||
getFooterBarMixin().setPrimaryButton(mPrimaryFooterButton);
|
||||
getFooterBarMixin().setSecondaryButton(mSecondaryFooterButton, true /* usePrimaryStyle */);
|
||||
|
||||
return mView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
final Context context = view.getContext();
|
||||
|
||||
mPrimaryFooterButton.setOnClickListener(mViewModel::onNextButtonClick);
|
||||
mSecondaryFooterButton.setOnClickListener(mViewModel::onSkipOrCancelButtonClick);
|
||||
|
||||
if (mViewModel.canAssumeUdfps()) {
|
||||
mFooterMessage6.setVisibility(View.VISIBLE);
|
||||
mIconShield.setVisibility(View.VISIBLE);
|
||||
@@ -165,7 +160,7 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
mFooterMessage6.setVisibility(View.GONE);
|
||||
mIconShield.setVisibility(View.GONE);
|
||||
}
|
||||
mSecondaryFooterButton.setText(getContext(),
|
||||
mSecondaryFooterButton.setText(context,
|
||||
mViewModel.getEnrollmentRequest().isAfterSuwOrSuwSuggestedAction()
|
||||
? R.string.security_settings_fingerprint_enroll_introduction_cancel
|
||||
: R.string.security_settings_fingerprint_enroll_introduction_no_thanks);
|
||||
@@ -181,23 +176,37 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
setHeaderText(getActivity(),
|
||||
R.string.security_settings_fingerprint_enroll_introduction_title);
|
||||
}
|
||||
observePageStatusLiveDataIfNeed();
|
||||
}
|
||||
|
||||
mViewModel.getPageStatusLiveData().observe(this, this::updateFooterButtons);
|
||||
private void observePageStatusLiveDataIfNeed() {
|
||||
final LiveData<FingerprintEnrollIntroStatus> statusLiveData =
|
||||
mViewModel.getPageStatusLiveData();
|
||||
final FingerprintEnrollIntroStatus status = statusLiveData.getValue();
|
||||
if (status != null && status.hasScrollToBottom()) {
|
||||
// Do not requireScrollWithButton() again when "I agree" or "Done" button is visible,
|
||||
// because if we requireScrollWithButton() again, it will become "More" after scroll-up.
|
||||
return;
|
||||
}
|
||||
|
||||
final RequireScrollMixin requireScrollMixin = getLayout()
|
||||
.getMixin(RequireScrollMixin.class);
|
||||
requireScrollMixin.requireScrollWithButton(getActivity(), mPrimaryFooterButton,
|
||||
getMoreButtonTextRes(), mViewModel::onNextButtonClick);
|
||||
requireScrollMixin.setOnRequireScrollStateChangedListener(scrollNeeded -> {
|
||||
if (!scrollNeeded) {
|
||||
mViewModel.setHasScrolledToBottom();
|
||||
}
|
||||
});
|
||||
|
||||
// Always set true to setHasScrolledToBottom() before registering listener through
|
||||
// setOnRequireScrollStateChangedListener(), because listener will not be called if first
|
||||
// scrollNeeded is true
|
||||
mViewModel.setHasScrolledToBottom(true);
|
||||
requireScrollMixin.setOnRequireScrollStateChangedListener(
|
||||
scrollNeeded -> mViewModel.setHasScrolledToBottom(!scrollNeeded));
|
||||
statusLiveData.observe(this, this::updateFooterButtons);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
mViewModel = mViewModelProvider.get(FingerprintEnrollIntroViewModel.class);
|
||||
mViewModel = new ViewModelProvider(getActivity())
|
||||
.get(FingerprintEnrollIntroViewModel.class);
|
||||
getLifecycle().addObserver(mViewModel);
|
||||
super.onAttach(context);
|
||||
}
|
||||
@@ -232,12 +241,16 @@ public class FingerprintEnrollIntroFragment extends Fragment {
|
||||
private String getDescriptionDisabledByAdmin(@NonNull Context context) {
|
||||
final int defaultStrId =
|
||||
R.string.security_settings_fingerprint_enroll_introduction_message_unlock_disabled;
|
||||
if (mDevicePolicyMgrRes == null) {
|
||||
|
||||
final DevicePolicyManager devicePolicyManager = getActivity()
|
||||
.getSystemService(DevicePolicyManager.class);
|
||||
if (devicePolicyManager != null) {
|
||||
return devicePolicyManager.getResources().getString(FINGERPRINT_UNLOCK_DISABLED,
|
||||
() -> context.getString(defaultStrId));
|
||||
} else {
|
||||
Log.w(TAG, "getDescriptionDisabledByAdmin, null device policy manager res");
|
||||
return "";
|
||||
}
|
||||
return mDevicePolicyMgrRes.getString(FINGERPRINT_UNLOCK_DISABLED,
|
||||
() -> context.getString(defaultStrId));
|
||||
}
|
||||
|
||||
private void setHeaderText(@NonNull Activity activity, int resId) {
|
||||
|
||||
@@ -19,20 +19,19 @@ package com.android.settings.biometrics2.ui.view;
|
||||
import static androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.APPLICATION_KEY;
|
||||
|
||||
import static com.android.settings.biometrics2.factory.BiometricsViewModelFactory.CHALLENGE_GENERATOR;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_CONTINUE_ENROLL;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.FingerprintEnrollIntroViewModel.FINGERPRINT_ENROLL_INTRO_ACTION_SKIP_OR_CANCEL;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
@@ -42,7 +41,6 @@ import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.viewmodel.CreationExtras;
|
||||
import androidx.lifecycle.viewmodel.MutableCreationExtras;
|
||||
@@ -51,11 +49,9 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.BiometricEnrollBase;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollFindSensor;
|
||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollEnrolling;
|
||||
import com.android.settings.biometrics.fingerprint.SetupFingerprintEnrollFindSensor;
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
import com.android.settings.biometrics2.factory.BiometricsFragmentFactory;
|
||||
import com.android.settings.biometrics2.factory.BiometricsViewModelFactory;
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModel;
|
||||
import com.android.settings.biometrics2.ui.model.EnrollmentRequest;
|
||||
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel;
|
||||
import com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.FingerprintChallengeGenerator;
|
||||
@@ -99,15 +95,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
mViewModel = viewModelProvider.get(FingerprintEnrollmentViewModel.class);
|
||||
mViewModel.setRequest(new EnrollmentRequest(getIntent(), getApplicationContext()));
|
||||
mViewModel.setSavedInstanceState(savedInstanceState);
|
||||
getLifecycle().addObserver(mViewModel);
|
||||
|
||||
mAutoCredentialViewModel = viewModelProvider.get(AutoCredentialViewModel.class);
|
||||
mAutoCredentialViewModel.setCredentialModel(new CredentialModel(getIntent(),
|
||||
SystemClock.elapsedRealtimeClock()));
|
||||
getLifecycle().addObserver(mAutoCredentialViewModel);
|
||||
|
||||
mViewModel.getSetResultLiveData().observe(this, this::onSetActivityResult);
|
||||
mAutoCredentialViewModel.getActionLiveData().observe(this, this::onCredentialAction);
|
||||
mAutoCredentialViewModel.setCredentialModel(savedInstanceState, getIntent());
|
||||
checkCredential();
|
||||
|
||||
// Theme
|
||||
setTheme(mViewModel.getRequest().getTheme());
|
||||
@@ -116,21 +107,35 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
|
||||
// fragment
|
||||
setContentView(R.layout.biometric_enrollment_container);
|
||||
final FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
fragmentManager.setFragmentFactory(
|
||||
new BiometricsFragmentFactory(getApplication(), viewModelProvider));
|
||||
|
||||
final FingerprintEnrollIntroViewModel fingerprintEnrollIntroViewModel =
|
||||
final FingerprintEnrollIntroViewModel introViewModel =
|
||||
viewModelProvider.get(FingerprintEnrollIntroViewModel.class);
|
||||
fingerprintEnrollIntroViewModel.setEnrollmentRequest(mViewModel.getRequest());
|
||||
fingerprintEnrollIntroViewModel.setUserId(mAutoCredentialViewModel.getUserId());
|
||||
fingerprintEnrollIntroViewModel.getActionLiveData().observe(
|
||||
this, this::observeIntroAction);
|
||||
final String tag = "FingerprintEnrollIntroFragment";
|
||||
fragmentManager.beginTransaction()
|
||||
.setReorderingAllowed(true)
|
||||
.add(R.id.fragment_container_view, FingerprintEnrollIntroFragment.class, null, tag)
|
||||
.commit();
|
||||
introViewModel.setEnrollmentRequest(mViewModel.getRequest());
|
||||
introViewModel.setUserId(mAutoCredentialViewModel.getUserId());
|
||||
if (savedInstanceState == null) {
|
||||
final String tag = "FingerprintEnrollIntroFragment";
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.setReorderingAllowed(true)
|
||||
.add(R.id.fragment_container_view, FingerprintEnrollIntroFragment.class, null,
|
||||
tag)
|
||||
.commit();
|
||||
}
|
||||
|
||||
// observe LiveData
|
||||
getLifecycle().addObserver(mViewModel);
|
||||
mViewModel.getSetResultLiveData().observe(this, this::onSetActivityResult);
|
||||
|
||||
mAutoCredentialViewModel.getGenerateChallengeFailedLiveData().observe(this,
|
||||
this::onGenerateChallengeFailed);
|
||||
|
||||
// Clear ActionLiveData in FragmentViewModel to prevent getting previous action during
|
||||
// recreate, like press 'I agree' then press 'back' in FingerprintEnrollFindSensor activity.
|
||||
introViewModel.clearActionLiveData();
|
||||
introViewModel.getActionLiveData().observe(this, this::observeIntroAction);
|
||||
}
|
||||
|
||||
private void onGenerateChallengeFailed(@NonNull Boolean ignoredBoolean) {
|
||||
onSetActivityResult(new ActivityResult(RESULT_CANCELED, null));
|
||||
}
|
||||
|
||||
private void onSetActivityResult(@NonNull ActivityResult result) {
|
||||
@@ -141,10 +146,10 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
finish();
|
||||
}
|
||||
|
||||
private void onCredentialAction(@NonNull Integer action) {
|
||||
switch (action) {
|
||||
private void checkCredential() {
|
||||
switch (mAutoCredentialViewModel.checkCredential()) {
|
||||
case CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK: {
|
||||
final Intent intent = mAutoCredentialViewModel.getChooseLockIntent(this,
|
||||
final Intent intent = mAutoCredentialViewModel.createChooseLockIntent(this,
|
||||
mViewModel.getRequest().isSuw(), mViewModel.getRequest().getSuwExtras());
|
||||
if (!mViewModel.isWaitingActivityResult().compareAndSet(false, true)) {
|
||||
Log.w(TAG, "chooseLock, fail to set isWaiting flag to true");
|
||||
@@ -153,7 +158,7 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
return;
|
||||
}
|
||||
case CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK: {
|
||||
final boolean launched = mAutoCredentialViewModel.getConfirmLockLauncher(
|
||||
final boolean launched = mAutoCredentialViewModel.createConfirmLockLauncher(
|
||||
this,
|
||||
LAUNCH_CONFIRM_LOCK_ACTIVITY,
|
||||
getString(R.string.security_settings_fingerprint_preference_title)
|
||||
@@ -168,12 +173,9 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE: {
|
||||
Log.w(TAG, "observeCredentialLiveData, finish with action:" + action);
|
||||
if (mViewModel.getRequest().isAfterSuwOrSuwSuggestedAction()) {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
}
|
||||
finish();
|
||||
case CREDENTIAL_VALID:
|
||||
case CREDENTIAL_IS_GENERATING_CHALLENGE: {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,10 +188,15 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
if (mAutoCredentialViewModel.checkNewCredentialFromActivityResult(
|
||||
isChooseLock, activityResult)) {
|
||||
overridePendingTransition(R.anim.sud_slide_next_in, R.anim.sud_slide_next_out);
|
||||
} else {
|
||||
onSetActivityResult(activityResult);
|
||||
}
|
||||
}
|
||||
|
||||
private void observeIntroAction(@NonNull Integer action) {
|
||||
private void observeIntroAction(@Nullable Integer action) {
|
||||
if (action == null) {
|
||||
return;
|
||||
}
|
||||
switch (action) {
|
||||
case FINGERPRINT_ENROLL_INTRO_ACTION_DONE_AND_FINISH: {
|
||||
onSetActivityResult(
|
||||
@@ -207,9 +214,9 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
Log.w(TAG, "startNext, isSuw:" + isSuw + ", fail to set isWaiting flag");
|
||||
}
|
||||
final Intent intent = new Intent(this, isSuw
|
||||
? SetupFingerprintEnrollEnrolling.class
|
||||
? SetupFingerprintEnrollFindSensor.class
|
||||
: FingerprintEnrollFindSensor.class);
|
||||
intent.putExtras(mAutoCredentialViewModel.getCredentialBundle());
|
||||
intent.putExtras(mAutoCredentialViewModel.createCredentialIntentExtra());
|
||||
intent.putExtras(mViewModel.getNextActivityBaseIntentExtras());
|
||||
mNextActivityLauncher.launch(intent);
|
||||
}
|
||||
@@ -272,5 +279,6 @@ public class FingerprintEnrollmentActivity extends FragmentActivity {
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mViewModel.onSaveInstanceState(outState);
|
||||
mAutoCredentialViewModel.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,20 +30,21 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.biometrics.BiometricUtils;
|
||||
import com.android.settings.biometrics.BiometricUtils.GatekeeperCredentialNotMatchException;
|
||||
import com.android.settings.biometrics2.data.repository.FingerprintRepository;
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModel;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
@@ -57,31 +58,40 @@ import java.lang.annotation.RetentionPolicy;
|
||||
* AutoCredentialViewModel which uses CredentialModel to determine next actions for activity, like
|
||||
* start ChooseLockActivity, start ConfirmLockActivity, GenerateCredential, or do nothing.
|
||||
*/
|
||||
public class AutoCredentialViewModel extends AndroidViewModel implements DefaultLifecycleObserver {
|
||||
public class AutoCredentialViewModel extends AndroidViewModel {
|
||||
|
||||
private static final String TAG = "AutoCredentialViewModel";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_CREDENTIAL_MODEL = "credential_model";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
/**
|
||||
* Valid credential, activity does nothing.
|
||||
*/
|
||||
public static final int CREDENTIAL_VALID = 0;
|
||||
|
||||
/**
|
||||
* This credential looks good, but still need to run generateChallenge().
|
||||
*/
|
||||
public static final int CREDENTIAL_IS_GENERATING_CHALLENGE = 1;
|
||||
|
||||
/**
|
||||
* Need activity to run choose lock
|
||||
*/
|
||||
public static final int CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK = 1;
|
||||
public static final int CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK = 2;
|
||||
|
||||
/**
|
||||
* Need activity to run confirm lock
|
||||
*/
|
||||
public static final int CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK = 2;
|
||||
|
||||
/**
|
||||
* Fail to use challenge from hardware generateChallenge(), shall finish activity with proper
|
||||
* error code
|
||||
*/
|
||||
public static final int CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE = 3;
|
||||
public static final int CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK = 3;
|
||||
|
||||
@IntDef(prefix = { "CREDENTIAL_" }, value = {
|
||||
CREDENTIAL_VALID,
|
||||
CREDENTIAL_IS_GENERATING_CHALLENGE,
|
||||
CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK,
|
||||
CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK,
|
||||
CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE
|
||||
CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface CredentialAction {}
|
||||
@@ -157,11 +167,10 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NonNull private final LockPatternUtils mLockPatternUtils;
|
||||
@NonNull private final ChallengeGenerator mChallengeGenerator;
|
||||
private CredentialModel mCredentialModel = null;
|
||||
@NonNull private final MutableLiveData<Integer> mActionLiveData =
|
||||
@NonNull private final MutableLiveData<Boolean> mGenerateChallengeFailedLiveData =
|
||||
new MutableLiveData<>();
|
||||
|
||||
public AutoCredentialViewModel(
|
||||
@@ -173,51 +182,65 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
mChallengeGenerator = challengeGenerator;
|
||||
}
|
||||
|
||||
public void setCredentialModel(@NonNull CredentialModel credentialModel) {
|
||||
mCredentialModel = credentialModel;
|
||||
/**
|
||||
* Set CredentialModel, the source is coming from savedInstanceState or activity intent
|
||||
*/
|
||||
public void setCredentialModel(@Nullable Bundle savedInstanceState, @NonNull Intent intent) {
|
||||
final Bundle bundle;
|
||||
if (savedInstanceState != null) {
|
||||
bundle = savedInstanceState.getBundle(KEY_CREDENTIAL_MODEL);
|
||||
} else {
|
||||
bundle = intent.getExtras();
|
||||
}
|
||||
mCredentialModel = new CredentialModel(bundle, SystemClock.elapsedRealtimeClock());
|
||||
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "setCredentialModel " + mCredentialModel + ", savedInstanceState exist:"
|
||||
+ (savedInstanceState != null));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Observe ActionLiveData for actions about choosing lock, confirming lock, or finishing
|
||||
* activity
|
||||
* Handle onSaveInstanceState from activity
|
||||
*/
|
||||
@NonNull
|
||||
public LiveData<Integer> getActionLiveData() {
|
||||
return mActionLiveData;
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
outState.putBundle(KEY_CREDENTIAL_MODEL, mCredentialModel.getBundle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
checkCredential();
|
||||
@NonNull
|
||||
public LiveData<Boolean> getGenerateChallengeFailedLiveData() {
|
||||
return mGenerateChallengeFailedLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check credential status for biometric enrollment.
|
||||
*/
|
||||
private void checkCredential() {
|
||||
@CredentialAction
|
||||
public int checkCredential() {
|
||||
if (isValidCredential()) {
|
||||
return;
|
||||
return CREDENTIAL_VALID;
|
||||
}
|
||||
final long gkPwHandle = mCredentialModel.getGkPwHandle();
|
||||
if (isUnspecifiedPassword()) {
|
||||
mActionLiveData.postValue(CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK);
|
||||
return CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK;
|
||||
} else if (CredentialModel.isValidGkPwHandle(gkPwHandle)) {
|
||||
generateChallenge(gkPwHandle);
|
||||
return CREDENTIAL_IS_GENERATING_CHALLENGE;
|
||||
} else {
|
||||
mActionLiveData.postValue(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
return CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK;
|
||||
}
|
||||
}
|
||||
|
||||
private void generateChallenge(long gkPwHandle) {
|
||||
mChallengeGenerator.setCallback((sensorId, userId, challenge) -> {
|
||||
mCredentialModel.setSensorId(sensorId);
|
||||
mCredentialModel.setChallenge(challenge);
|
||||
try {
|
||||
final byte[] newToken = requestGatekeeperHat(gkPwHandle, challenge, userId);
|
||||
mCredentialModel.setSensorId(sensorId);
|
||||
mCredentialModel.setChallenge(challenge);
|
||||
mCredentialModel.setToken(newToken);
|
||||
} catch (IllegalStateException e) {
|
||||
Log.e(TAG, "generateChallenge, IllegalStateException", e);
|
||||
mActionLiveData.postValue(CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE);
|
||||
mGenerateChallengeFailedLiveData.postValue(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,7 +254,7 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
// Check credential again
|
||||
if (!isValidCredential()) {
|
||||
Log.w(TAG, "generateChallenge, invalid Credential");
|
||||
mActionLiveData.postValue(CREDENTIAL_FAIL_DURING_GENERATE_CHALLENGE);
|
||||
mGenerateChallengeFailedLiveData.postValue(true);
|
||||
}
|
||||
});
|
||||
mChallengeGenerator.generateChallenge(getUserId());
|
||||
@@ -282,16 +305,16 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
final VerifyCredentialResponse response = mLockPatternUtils
|
||||
.verifyGatekeeperPasswordHandle(gkPwHandle, challenge, userId);
|
||||
if (!response.isMatched()) {
|
||||
throw new IllegalStateException("Unable to request Gatekeeper HAT");
|
||||
throw new GatekeeperCredentialNotMatchException("Unable to request Gatekeeper HAT");
|
||||
}
|
||||
return response.getGatekeeperHAT();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Credential bundle which will be used to launch next activity.
|
||||
* Get Credential intent extra which will be used to launch next activity.
|
||||
*/
|
||||
@NonNull
|
||||
public Bundle getCredentialBundle() {
|
||||
public Bundle createCredentialIntentExtra() {
|
||||
final Bundle retBundle = new Bundle();
|
||||
final long gkPwHandle = mCredentialModel.getGkPwHandle();
|
||||
if (CredentialModel.isValidGkPwHandle(gkPwHandle)) {
|
||||
@@ -311,10 +334,10 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Intent for choosing lock
|
||||
* Create Intent for choosing lock
|
||||
*/
|
||||
@NonNull
|
||||
public Intent getChooseLockIntent(@NonNull Context context, boolean isSuw,
|
||||
public Intent createChooseLockIntent(@NonNull Context context, boolean isSuw,
|
||||
@NonNull Bundle suwExtras) {
|
||||
final Intent intent = BiometricUtils.getChooseLockIntent(context, isSuw,
|
||||
suwExtras);
|
||||
@@ -331,10 +354,10 @@ public class AutoCredentialViewModel extends AndroidViewModel implements Default
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ConfirmLockLauncher
|
||||
* Create ConfirmLockLauncher
|
||||
*/
|
||||
@NonNull
|
||||
public ChooseLockSettingsHelper getConfirmLockLauncher(@NonNull Activity activity,
|
||||
public ChooseLockSettingsHelper createConfirmLockLauncher(@NonNull Activity activity,
|
||||
int requestCode, @NonNull String title) {
|
||||
final ChooseLockSettingsHelper.Builder builder =
|
||||
new ChooseLockSettingsHelper.Builder(activity);
|
||||
|
||||
@@ -144,6 +144,13 @@ public class FingerprintEnrollIntroViewModel extends AndroidViewModel
|
||||
return mPageStatusLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear user's action live data
|
||||
*/
|
||||
public void clearActionLiveData() {
|
||||
mActionLiveData.setValue(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's action live data (like clicking Agree, Skip, or Done)
|
||||
*/
|
||||
@@ -161,8 +168,8 @@ public class FingerprintEnrollIntroViewModel extends AndroidViewModel
|
||||
/**
|
||||
* Update onboarding intro page has scrolled to bottom
|
||||
*/
|
||||
public void setHasScrolledToBottom() {
|
||||
mHasScrolledToBottomLiveData.postValue(true);
|
||||
public void setHasScrolledToBottom(boolean value) {
|
||||
mHasScrolledToBottomLiveData.postValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,7 +48,7 @@ public class PrivateVolumeForget extends InstrumentedFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DEVICEINFO_STORAGE;
|
||||
return SettingsEnums.PRIVATE_VOLUME_FORGET;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ public class PrivateVolumeFormat extends InstrumentedFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DEVICEINFO_STORAGE;
|
||||
return SettingsEnums.PRIVATE_VOLUME_FORMAT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,7 +40,7 @@ public class PrivateVolumeUnmount extends InstrumentedFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DEVICEINFO_STORAGE;
|
||||
return SettingsEnums.PRIVATE_VOLUME_UNMOUNT;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -95,7 +95,7 @@ public class PublicVolumeSettings extends SettingsPreferenceFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.DEVICEINFO_STORAGE;
|
||||
return SettingsEnums.PUBLIC_VOLUME_SETTINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,10 +20,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.settings.fuelgauge.batteryusage.BatteryHistEntry;
|
||||
import com.android.settingslib.fuelgauge.Estimate;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -103,12 +101,6 @@ public interface PowerUsageFeatureProvider {
|
||||
*/
|
||||
String getOldEstimateDebugString(String timeRemaining);
|
||||
|
||||
/**
|
||||
* Returns the string to show in the advanced usage battery page when enhanced estimates are
|
||||
* enabled. This string notifies users that the estimate is using enhanced prediction.
|
||||
*/
|
||||
String getAdvancedUsageScreenInfoString();
|
||||
|
||||
/**
|
||||
* Returns a signal to indicate if the device will need to warn the user they may not make it
|
||||
* to their next charging time.
|
||||
@@ -143,11 +135,6 @@ public interface PowerUsageFeatureProvider {
|
||||
*/
|
||||
Intent getResumeChargeIntent();
|
||||
|
||||
/**
|
||||
* Returns battery history data with corresponding timestamp key.
|
||||
*/
|
||||
Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context);
|
||||
|
||||
/**
|
||||
* Returns {@link Set} for hidding applications background usage time.
|
||||
*/
|
||||
|
||||
@@ -24,10 +24,8 @@ import android.util.ArraySet;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.fuelgauge.batteryusage.BatteryHistEntry;
|
||||
import com.android.settingslib.fuelgauge.Estimate;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/** Implementation of {@code PowerUsageFeatureProvider} */
|
||||
@@ -122,11 +120,6 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAdvancedUsageScreenInfoString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getEarlyWarningSignal(Context context, String id) {
|
||||
return false;
|
||||
@@ -158,11 +151,6 @@ public class PowerUsageFeatureProviderImpl implements PowerUsageFeatureProvider
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<CharSequence> getHideBackgroundUsageTimeSet(Context context) {
|
||||
return new ArraySet<>();
|
||||
|
||||
@@ -167,7 +167,7 @@ public class BatterySaverScheduleSettings extends RadioButtonPickerFragment {
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return 0;
|
||||
return SettingsEnums.FUELGAUGE_BATTERY_SAVER_SCHEDULE;
|
||||
}
|
||||
|
||||
private void logPowerSaver() {
|
||||
|
||||
@@ -70,9 +70,6 @@ public class BatteryEntry {
|
||||
}
|
||||
}
|
||||
|
||||
public static final int MSG_UPDATE_NAME_ICON = 1;
|
||||
public static final int MSG_REPORT_FULLY_DRAWN = 2;
|
||||
|
||||
private static final String TAG = "BatteryEntry";
|
||||
private static final String PACKAGE_SYSTEM = "android";
|
||||
|
||||
|
||||
@@ -21,14 +21,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
@@ -38,14 +33,14 @@ import androidx.preference.PreferenceCategory;
|
||||
import com.android.settingslib.connectivity.ConnectivitySubsystemsRecoveryManager;
|
||||
import com.android.settingslib.utils.HandlerInjector;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper class to restart connectivity for all requested subsystems.
|
||||
*/
|
||||
public class InternetResetHelper implements LifecycleObserver,
|
||||
ConnectivitySubsystemsRecoveryManager.RecoveryStatusCallback {
|
||||
public class InternetResetHelper implements LifecycleObserver {
|
||||
|
||||
protected static final String TAG = "InternetResetHelper";
|
||||
public static final long RESTART_TIMEOUT_MS = 15_000; // 15 seconds
|
||||
@@ -61,41 +56,40 @@ public class InternetResetHelper implements LifecycleObserver,
|
||||
protected final IntentFilter mWifiStateFilter;
|
||||
protected final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@WorkerThread
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent != null && TextUtils.equals(intent.getAction(),
|
||||
WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
updateWifiStateChange();
|
||||
}
|
||||
updateWifiStateChange();
|
||||
}
|
||||
};
|
||||
|
||||
protected ConnectivitySubsystemsRecoveryManager mConnectivitySubsystemsRecoveryManager;
|
||||
protected HandlerThread mWorkerThread;
|
||||
protected boolean mIsRecoveryReady;
|
||||
protected boolean mIsWifiReady;
|
||||
protected RecoveryWorker mRecoveryWorker;
|
||||
protected boolean mIsWifiReady = true;
|
||||
protected HandlerInjector mHandlerInjector;
|
||||
protected final Runnable mResumeRunnable = () -> {
|
||||
resumePreferences();
|
||||
};
|
||||
protected final Runnable mTimeoutRunnable = () -> {
|
||||
mIsRecoveryReady = true;
|
||||
Log.w(TAG, "Resume preferences due to connectivity subsystems recovery timed out.");
|
||||
mRecoveryWorker.clearRecovering();
|
||||
mIsWifiReady = true;
|
||||
resumePreferences();
|
||||
};
|
||||
|
||||
public InternetResetHelper(Context context, Lifecycle lifecycle) {
|
||||
public InternetResetHelper(Context context, Lifecycle lifecycle,
|
||||
NetworkMobileProviderController mobileNetworkController,
|
||||
Preference wifiTogglePreferences,
|
||||
PreferenceCategory connectedWifiEntryPreferenceCategory,
|
||||
PreferenceCategory firstWifiEntryPreferenceCategory,
|
||||
PreferenceCategory wifiEntryPreferenceCategory,
|
||||
Preference resettingPreference) {
|
||||
mContext = context;
|
||||
mMobileNetworkController = mobileNetworkController;
|
||||
mWifiTogglePreferences = wifiTogglePreferences;
|
||||
mWifiNetworkPreferences.add(connectedWifiEntryPreferenceCategory);
|
||||
mWifiNetworkPreferences.add(firstWifiEntryPreferenceCategory);
|
||||
mWifiNetworkPreferences.add(wifiEntryPreferenceCategory);
|
||||
mResettingPreference = resettingPreference;
|
||||
|
||||
mHandlerInjector = new HandlerInjector(context.getMainThreadHandler());
|
||||
mWifiManager = mContext.getSystemService(WifiManager.class);
|
||||
mWifiStateFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
|
||||
mWorkerThread = new HandlerThread(TAG
|
||||
+ "{" + Integer.toHexString(System.identityHashCode(this)) + "}",
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mWorkerThread.start();
|
||||
mConnectivitySubsystemsRecoveryManager = new ConnectivitySubsystemsRecoveryManager(
|
||||
mContext, mWorkerThread.getThreadHandler());
|
||||
mRecoveryWorker = RecoveryWorker.getInstance(mContext, this);
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
@@ -118,72 +112,18 @@ public class InternetResetHelper implements LifecycleObserver,
|
||||
/** @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) */
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
|
||||
public void onDestroy() {
|
||||
mHandlerInjector.removeCallbacks(mResumeRunnable);
|
||||
mHandlerInjector.removeCallbacks(mTimeoutRunnable);
|
||||
mWorkerThread.quit();
|
||||
}
|
||||
|
||||
@Override
|
||||
@WorkerThread
|
||||
public void onSubsystemRestartOperationBegin() {
|
||||
Log.d(TAG, "The connectivity subsystem is starting for recovery.");
|
||||
}
|
||||
|
||||
@Override
|
||||
@WorkerThread
|
||||
public void onSubsystemRestartOperationEnd() {
|
||||
Log.d(TAG, "The connectivity subsystem is done for recovery.");
|
||||
if (!mIsRecoveryReady) {
|
||||
mIsRecoveryReady = true;
|
||||
mHandlerInjector.postDelayed(mResumeRunnable, 0 /* delayMillis */);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@WorkerThread
|
||||
protected void updateWifiStateChange() {
|
||||
if (!mIsWifiReady && mWifiManager.isWifiEnabled()) {
|
||||
Log.d(TAG, "The Wi-Fi subsystem is done for recovery.");
|
||||
mIsWifiReady = true;
|
||||
mHandlerInjector.postDelayed(mResumeRunnable, 0 /* delayMillis */);
|
||||
resumePreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resetting preference.
|
||||
*/
|
||||
@UiThread
|
||||
public void setResettingPreference(Preference preference) {
|
||||
mResettingPreference = preference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mobile network controller.
|
||||
*/
|
||||
@UiThread
|
||||
public void setMobileNetworkController(NetworkMobileProviderController controller) {
|
||||
mMobileNetworkController = controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Wi-Fi toggle preference.
|
||||
*/
|
||||
@UiThread
|
||||
public void setWifiTogglePreference(Preference preference) {
|
||||
mWifiTogglePreferences = preference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Wi-Fi network preference.
|
||||
*/
|
||||
@UiThread
|
||||
public void addWifiNetworkPreference(PreferenceCategory preference) {
|
||||
if (preference != null) {
|
||||
mWifiNetworkPreferences.add(preference);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
protected void suspendPreferences() {
|
||||
Log.d(TAG, "Suspend the subsystem preferences");
|
||||
if (mMobileNetworkController != null) {
|
||||
@@ -201,9 +141,9 @@ public class InternetResetHelper implements LifecycleObserver,
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
protected void resumePreferences() {
|
||||
if (mIsRecoveryReady && mMobileNetworkController != null) {
|
||||
boolean isRecoveryReady = !mRecoveryWorker.isRecovering();
|
||||
if (isRecoveryReady && mMobileNetworkController != null) {
|
||||
Log.d(TAG, "Resume the Mobile Network controller");
|
||||
mMobileNetworkController.hidePreference(false /* hide */, true /* immediately */);
|
||||
}
|
||||
@@ -214,7 +154,7 @@ public class InternetResetHelper implements LifecycleObserver,
|
||||
pref.setVisible(true);
|
||||
}
|
||||
}
|
||||
if (mIsRecoveryReady && mIsWifiReady) {
|
||||
if (isRecoveryReady && mIsWifiReady) {
|
||||
mHandlerInjector.removeCallbacks(mTimeoutRunnable);
|
||||
if (mResettingPreference != null) {
|
||||
Log.d(TAG, "Resume the Resetting preference");
|
||||
@@ -223,21 +163,99 @@ public class InternetResetHelper implements LifecycleObserver,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart connectivity for all requested subsystems.
|
||||
*/
|
||||
@UiThread
|
||||
protected void showResettingAndSendTimeoutChecks() {
|
||||
suspendPreferences();
|
||||
mHandlerInjector.postDelayed(mTimeoutRunnable, RESTART_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
/** Restart connectivity for all requested subsystems. */
|
||||
public void restart() {
|
||||
if (!mConnectivitySubsystemsRecoveryManager.isRecoveryAvailable()) {
|
||||
if (!mRecoveryWorker.isRecoveryAvailable()) {
|
||||
Log.e(TAG, "The connectivity subsystem is not available to restart.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d(TAG, "The connectivity subsystem is restarting for recovery.");
|
||||
suspendPreferences();
|
||||
mIsRecoveryReady = false;
|
||||
showResettingAndSendTimeoutChecks();
|
||||
mIsWifiReady = !mWifiManager.isWifiEnabled();
|
||||
mHandlerInjector.postDelayed(mTimeoutRunnable, RESTART_TIMEOUT_MS);
|
||||
mConnectivitySubsystemsRecoveryManager.triggerSubsystemRestart(null /* reason */, this);
|
||||
mRecoveryWorker.triggerRestart();
|
||||
}
|
||||
|
||||
/** Check if the connectivity subsystem is under recovering. */
|
||||
public void checkRecovering() {
|
||||
if (!mRecoveryWorker.isRecovering()) return;
|
||||
mIsWifiReady = false;
|
||||
showResettingAndSendTimeoutChecks();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a singleton class for ConnectivitySubsystemsRecoveryManager worker.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
public static class RecoveryWorker implements
|
||||
ConnectivitySubsystemsRecoveryManager.RecoveryStatusCallback {
|
||||
private static final String TAG = "RecoveryWorker";
|
||||
private static RecoveryWorker sInstance;
|
||||
private static WeakReference<InternetResetHelper> sCallback;
|
||||
private static ConnectivitySubsystemsRecoveryManager sRecoveryManager;
|
||||
private static boolean sIsRecovering;
|
||||
|
||||
/**
|
||||
* Create a singleton class for ConnectivitySubsystemsRecoveryManager.
|
||||
*
|
||||
* @param context The context to use for the content resolver.
|
||||
* @param callback The callback of {@link InternetResetHelper} object.
|
||||
* @return an instance of {@link RecoveryWorker} object.
|
||||
*/
|
||||
public static RecoveryWorker getInstance(Context context, InternetResetHelper callback) {
|
||||
sCallback = new WeakReference<>(callback);
|
||||
if (sInstance != null) return sInstance;
|
||||
|
||||
sInstance = new RecoveryWorker();
|
||||
Context appContext = context.getApplicationContext();
|
||||
sRecoveryManager = new ConnectivitySubsystemsRecoveryManager(appContext,
|
||||
appContext.getMainThreadHandler());
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
/** Returns true, If the subsystem service is recovering. */
|
||||
public boolean isRecovering() {
|
||||
return sIsRecovering;
|
||||
}
|
||||
|
||||
/** Clear the recovering flag. */
|
||||
public void clearRecovering() {
|
||||
sIsRecovering = false;
|
||||
}
|
||||
|
||||
/** Returns true, If the subsystem service is recovery available. */
|
||||
public boolean isRecoveryAvailable() {
|
||||
return sRecoveryManager.isRecoveryAvailable();
|
||||
}
|
||||
|
||||
/** Trigger connectivity recovery for all requested technologies. */
|
||||
public boolean triggerRestart() {
|
||||
if (!isRecoveryAvailable()) {
|
||||
Log.e(TAG, "The connectivity subsystem is not available to restart.");
|
||||
return false;
|
||||
}
|
||||
sIsRecovering = true;
|
||||
sRecoveryManager.triggerSubsystemRestart(null /* reason */, sInstance);
|
||||
Log.d(TAG, "The connectivity subsystem is restarting for recovery.");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubsystemRestartOperationBegin() {
|
||||
Log.d(TAG, "The connectivity subsystem is starting for recovery.");
|
||||
sIsRecovering = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubsystemRestartOperationEnd() {
|
||||
Log.d(TAG, "The connectivity subsystem is done for recovery.");
|
||||
sIsRecovering = false;
|
||||
InternetResetHelper callback = sCallback.get();
|
||||
if (callback == null) return;
|
||||
callback.resumePreferences();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
private Uri mAirplaneModeSettingUri;
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
private IntentFilter mFilter = new IntentFilter();
|
||||
private MobileDataContentObserver mDataContentObserver;
|
||||
|
||||
private int mPhysicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
private int mLogicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||
@@ -125,6 +126,13 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao();
|
||||
mAirplaneModeObserver = new AirplaneModeObserver(new Handler(Looper.getMainLooper()));
|
||||
mAirplaneModeSettingUri = Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON);
|
||||
mDataContentObserver = new MobileDataContentObserver(
|
||||
new Handler(Looper.getMainLooper()));
|
||||
mDataContentObserver.setOnMobileDataChangedListener(() -> {
|
||||
mExecutor.execute(() -> {
|
||||
insertMobileNetworkInfo(context);
|
||||
});
|
||||
});
|
||||
mFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
|
||||
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
|
||||
mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
|
||||
@@ -163,6 +171,9 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
public void addRegister(LifecycleOwner lifecycleOwner) {
|
||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(), this);
|
||||
mAirplaneModeObserver.register(mContext);
|
||||
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
mDataContentObserver.register(mContext, mSubId);
|
||||
}
|
||||
mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
|
||||
observeAllSubInfo(lifecycleOwner);
|
||||
observeAllUiccInfo(lifecycleOwner);
|
||||
@@ -170,6 +181,9 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
}
|
||||
|
||||
public void removeRegister() {
|
||||
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
mDataContentObserver.unRegister(mContext);
|
||||
}
|
||||
mAirplaneModeObserver.unRegister(mContext);
|
||||
if (mDataSubscriptionChangedReceiver != null) {
|
||||
mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
|
||||
@@ -404,7 +418,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
|
||||
return new MobileNetworkInfoEntity(String.valueOf(mSubId),
|
||||
MobileNetworkUtils.isContactDiscoveryEnabled(context, mSubId),
|
||||
MobileNetworkUtils.isContactDiscoveryVisible(context, mSubId),
|
||||
MobileNetworkUtils.isMobileDataEnabled(context),
|
||||
mTelephonyManager.isDataEnabled(),
|
||||
MobileNetworkUtils.isCdmaOptions(context, mSubId),
|
||||
MobileNetworkUtils.isGsmOptions(context, mSubId),
|
||||
MobileNetworkUtils.isWorldMode(context, mSubId),
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.network.telephony.CallsDefaultSubscriptionController;
|
||||
import com.android.settings.network.telephony.NetworkProviderBackupCallingPreferenceController;
|
||||
import com.android.settings.network.telephony.NetworkProviderWifiCallingPreferenceController;
|
||||
import com.android.settings.network.telephony.SmsDefaultSubscriptionController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
@@ -42,9 +41,6 @@ public class NetworkProviderCallsSmsFragment extends DashboardFragment {
|
||||
static final String LOG_TAG = "NetworkProviderCallsSmsFragment";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFERENCE_CATEGORY_CALLING = "provider_model_calling_category";
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFERENCE_CATEGORY_BACKUP_CALLING =
|
||||
"provider_model_backup_calling_category";
|
||||
|
||||
@VisibleForTesting
|
||||
static final String KEY_PREFERENCE_CALLS= "provider_model_calls_preference";
|
||||
@@ -67,12 +63,6 @@ public class NetworkProviderCallsSmsFragment extends DashboardFragment {
|
||||
mNetworkProviderWifiCallingPreferenceController.init(getSettingsLifecycle());
|
||||
controllers.add(mNetworkProviderWifiCallingPreferenceController);
|
||||
|
||||
NetworkProviderBackupCallingPreferenceController backupCallingPrefCtrl =
|
||||
new NetworkProviderBackupCallingPreferenceController(context,
|
||||
KEY_PREFERENCE_CATEGORY_BACKUP_CALLING);
|
||||
backupCallingPrefCtrl.init(getSettingsLifecycle());
|
||||
controllers.add(backupCallingPrefCtrl);
|
||||
|
||||
return controllers;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.mobile.dataservice.DataServiceUtils;
|
||||
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
|
||||
@@ -181,10 +182,7 @@ public class NetworkProviderDownloadedSimListController extends
|
||||
|
||||
@Override
|
||||
public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
|
||||
if ((mSubInfoEntityList != null &&
|
||||
(subInfoEntityList.isEmpty() || !subInfoEntityList.equals(mSubInfoEntityList)))
|
||||
|| (!subInfoEntityList.isEmpty() && mSubInfoEntityList == null)) {
|
||||
Log.d(TAG, "subInfo list from framework is changed, update the subInfo entity list.");
|
||||
if (DataServiceUtils.shouldUpdateEntityList(mSubInfoEntityList, subInfoEntityList)) {
|
||||
mSubInfoEntityList = subInfoEntityList;
|
||||
mPreferenceCategory.setVisible(isAvailable());
|
||||
update();
|
||||
|
||||
@@ -337,6 +337,8 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
addConnectedEthernetNetworkController();
|
||||
addWifiSwitchPreferenceController();
|
||||
mWifiStatusMessagePreference = findPreference(PREF_KEY_WIFI_STATUS_MESSAGE);
|
||||
|
||||
checkConnectivityRecovering();
|
||||
}
|
||||
|
||||
private void updateAirplaneModeMsgPreference(boolean visible) {
|
||||
@@ -382,6 +384,17 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
mWifiSwitchPreferenceController.displayPreference(getPreferenceScreen());
|
||||
}
|
||||
|
||||
private void checkConnectivityRecovering() {
|
||||
mInternetResetHelper = new InternetResetHelper(getContext(), getLifecycle(),
|
||||
mNetworkMobileProviderController,
|
||||
findPreference(WifiSwitchPreferenceController.KEY),
|
||||
mConnectedWifiEntryPreferenceCategory,
|
||||
mFirstWifiEntryPreferenceCategory,
|
||||
mWifiEntryPreferenceCategory,
|
||||
mResetInternetPreference);
|
||||
mInternetResetHelper.checkRecovering();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
@@ -1455,16 +1468,6 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
EventLog.writeEvent(0x534e4554, "252995826", UserHandle.myUserId(), "User is a guest");
|
||||
return;
|
||||
}
|
||||
if (mInternetResetHelper == null) {
|
||||
mInternetResetHelper = new InternetResetHelper(getContext(), getLifecycle());
|
||||
mInternetResetHelper.setResettingPreference(mResetInternetPreference);
|
||||
mInternetResetHelper.setMobileNetworkController(mNetworkMobileProviderController);
|
||||
mInternetResetHelper.setWifiTogglePreference(
|
||||
findPreference(WifiSwitchPreferenceController.KEY));
|
||||
mInternetResetHelper.addWifiNetworkPreference(mConnectedWifiEntryPreferenceCategory);
|
||||
mInternetResetHelper.addWifiNetworkPreference(mFirstWifiEntryPreferenceCategory);
|
||||
mInternetResetHelper.addWifiNetworkPreference(mWifiEntryPreferenceCategory);
|
||||
}
|
||||
mInternetResetHelper.restart();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,10 @@ import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Looper;
|
||||
import android.os.RecoverySystem;
|
||||
import android.os.SystemClock;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.network.apn.ApnSettings;
|
||||
|
||||
@@ -43,6 +45,10 @@ import java.util.function.Consumer;
|
||||
*/
|
||||
public class ResetNetworkOperationBuilder {
|
||||
|
||||
private static final String TAG = "ResetNetworkOpBuilder";
|
||||
|
||||
private static final boolean DRY_RUN = false;
|
||||
|
||||
private Context mContext;
|
||||
private List<Runnable> mResetSequence = new ArrayList<Runnable>();
|
||||
|
||||
@@ -127,10 +133,17 @@ public class ResetNetworkOperationBuilder {
|
||||
public ResetNetworkOperationBuilder resetEsim(String callerPackage,
|
||||
Consumer<Boolean> resultCallback) {
|
||||
Runnable runnable = () -> {
|
||||
Boolean wipped = RecoverySystem.wipeEuiccData(mContext, callerPackage);
|
||||
if (resultCallback != null) {
|
||||
resultCallback.accept(wipped);
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
|
||||
if (!DRY_RUN) {
|
||||
Boolean wipped = RecoverySystem.wipeEuiccData(mContext, callerPackage);
|
||||
if (resultCallback != null) {
|
||||
resultCallback.accept(wipped);
|
||||
}
|
||||
}
|
||||
|
||||
long endTime = SystemClock.elapsedRealtime();
|
||||
Log.i(TAG, "Reset eSIM, takes " + (endTime - startTime) + " ms");
|
||||
};
|
||||
mResetSequence.add(runnable);
|
||||
return this;
|
||||
@@ -179,14 +192,21 @@ public class ResetNetworkOperationBuilder {
|
||||
*/
|
||||
public ResetNetworkOperationBuilder resetApn(int subscriptionId) {
|
||||
Runnable runnable = () -> {
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
|
||||
Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);
|
||||
|
||||
if (SubscriptionManager.isUsableSubscriptionId(subscriptionId)) {
|
||||
uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(subscriptionId));
|
||||
}
|
||||
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
resolver.delete(uri, null, null);
|
||||
if (!DRY_RUN) {
|
||||
ContentResolver resolver = mContext.getContentResolver();
|
||||
resolver.delete(uri, null, null);
|
||||
}
|
||||
|
||||
long endTime = SystemClock.elapsedRealtime();
|
||||
Log.i(TAG, "Reset " + uri + ", takes " + (endTime - startTime) + " ms");
|
||||
};
|
||||
mResetSequence.add(runnable);
|
||||
return this;
|
||||
@@ -205,7 +225,14 @@ public class ResetNetworkOperationBuilder {
|
||||
if (service == null) {
|
||||
return;
|
||||
}
|
||||
Runnable runnable = () -> serviceAccess.accept(service);
|
||||
Runnable runnable = () -> {
|
||||
long startTime = SystemClock.elapsedRealtime();
|
||||
if (!DRY_RUN) {
|
||||
serviceAccess.accept(service);
|
||||
}
|
||||
long endTime = SystemClock.elapsedRealtime();
|
||||
Log.i(TAG, "Reset " + serviceName + ", takes " + (endTime - startTime) + " ms");
|
||||
};
|
||||
mResetSequence.add(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Preference controller for "Backup Calling"
|
||||
* Deprecated ToDo: b/260059444 remove it next version
|
||||
**/
|
||||
public class BackupCallingPreferenceController extends TelephonyTogglePreferenceController {
|
||||
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_START;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.preference.Preference;
|
||||
@@ -32,16 +37,22 @@ import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.network.MobileDataContentObserver;
|
||||
import com.android.settings.network.MobileNetworkRepository;
|
||||
import com.android.settings.wifi.WifiPickerTrackerHelper;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.mobile.dataservice.DataServiceUtils;
|
||||
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.UiccInfoEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Preference controller for "Mobile data"
|
||||
*/
|
||||
public class MobileDataPreferenceController extends TelephonyTogglePreferenceController
|
||||
implements LifecycleObserver, OnStart, OnStop {
|
||||
implements LifecycleObserver, MobileNetworkRepository.MobileNetworkCallback {
|
||||
|
||||
private static final String DIALOG_TAG = "MobileDataDialog";
|
||||
|
||||
@@ -56,12 +67,26 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
|
||||
boolean mNeedDialog;
|
||||
|
||||
private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
|
||||
protected MobileNetworkRepository mMobileNetworkRepository;
|
||||
protected LifecycleOwner mLifecycleOwner;
|
||||
private List<SubscriptionInfoEntity> mSubscriptionInfoEntityList = new ArrayList<>();
|
||||
private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>();
|
||||
private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
SubscriptionInfoEntity mSubscriptionInfoEntity;
|
||||
MobileNetworkInfoEntity mMobileNetworkInfoEntity;
|
||||
|
||||
public MobileDataPreferenceController(Context context, String key) {
|
||||
public MobileDataPreferenceController(Context context, String key, Lifecycle lifecycle,
|
||||
LifecycleOwner lifecycleOwner, int subId) {
|
||||
super(context, key);
|
||||
mSubId = subId;
|
||||
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
|
||||
mDataContentObserver = new MobileDataContentObserver(new Handler(Looper.getMainLooper()));
|
||||
mDataContentObserver.setOnMobileDataChangedListener(() -> updateState(mPreference));
|
||||
mMobileNetworkRepository = MobileNetworkRepository.createBySubId(context, this, mSubId);
|
||||
mLifecycleOwner = lifecycleOwner;
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,18 +102,14 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnLifecycleEvent(ON_START)
|
||||
public void onStart() {
|
||||
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
mDataContentObserver.register(mContext, mSubId);
|
||||
}
|
||||
mMobileNetworkRepository.addRegister(mLifecycleOwner);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnLifecycleEvent(ON_STOP)
|
||||
public void onStop() {
|
||||
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
mDataContentObserver.unRegister(mContext);
|
||||
}
|
||||
mMobileNetworkRepository.removeRegister();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -122,39 +143,47 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
mTelephonyManager = getTelephonyManager();
|
||||
return mTelephonyManager.isDataEnabled();
|
||||
return mMobileNetworkInfoEntity == null ? false
|
||||
: mMobileNetworkInfoEntity.isMobileDataEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
if (isOpportunistic()) {
|
||||
preference.setEnabled(false);
|
||||
preference.setSummary(R.string.mobile_data_settings_summary_auto_switch);
|
||||
} else {
|
||||
preference.setEnabled(true);
|
||||
preference.setSummary(R.string.mobile_data_settings_summary);
|
||||
mPreference = (SwitchPreference) preference;
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
|
||||
if (mSubscriptionInfoEntity == null || mPreference == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||
preference.setSelectable(false);
|
||||
preference.setSummary(R.string.mobile_data_settings_summary_unavailable);
|
||||
mPreference.setChecked(isChecked());
|
||||
if (mSubscriptionInfoEntity.isOpportunistic) {
|
||||
mPreference.setEnabled(false);
|
||||
mPreference.setSummary(R.string.mobile_data_settings_summary_auto_switch);
|
||||
} else {
|
||||
preference.setSelectable(true);
|
||||
mPreference.setEnabled(true);
|
||||
mPreference.setSummary(R.string.mobile_data_settings_summary);
|
||||
}
|
||||
if (!mSubscriptionInfoEntity.isValidSubscription) {
|
||||
mPreference.setSelectable(false);
|
||||
mPreference.setSummary(R.string.mobile_data_settings_summary_unavailable);
|
||||
} else {
|
||||
mPreference.setSelectable(true);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOpportunistic() {
|
||||
SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
|
||||
return info != null && info.isOpportunistic();
|
||||
}
|
||||
|
||||
public void init(FragmentManager fragmentManager, int subId) {
|
||||
public void init(FragmentManager fragmentManager, int subId,
|
||||
SubscriptionInfoEntity subInfoEntity, MobileNetworkInfoEntity networkInfoEntity) {
|
||||
mFragmentManager = fragmentManager;
|
||||
mSubId = subId;
|
||||
mTelephonyManager = null;
|
||||
mTelephonyManager = getTelephonyManager();
|
||||
mSubscriptionInfoEntity = subInfoEntity;
|
||||
mMobileNetworkInfoEntity = networkInfoEntity;
|
||||
}
|
||||
|
||||
private TelephonyManager getTelephonyManager() {
|
||||
@@ -179,9 +208,8 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
|
||||
final boolean enableData = !isChecked();
|
||||
mTelephonyManager = getTelephonyManager();
|
||||
final boolean isMultiSim = (mTelephonyManager.getActiveModemCount() > 1);
|
||||
final int defaultSubId = mSubscriptionManager.getDefaultDataSubscriptionId();
|
||||
final boolean needToDisableOthers = mSubscriptionManager
|
||||
.isActiveSubscriptionId(defaultSubId) && defaultSubId != mSubId;
|
||||
final boolean needToDisableOthers = mDefaultSubId != mSubId;
|
||||
|
||||
if (enableData && isMultiSim && needToDisableOthers) {
|
||||
mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG;
|
||||
return true;
|
||||
@@ -194,4 +222,62 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
|
||||
mSubId);
|
||||
dialogFragment.show(mFragmentManager, DIALOG_TAG);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setSubscriptionInfoEntity(SubscriptionInfoEntity subscriptionInfoEntity) {
|
||||
mSubscriptionInfoEntity = subscriptionInfoEntity;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setMobileNetworkInfoEntity(MobileNetworkInfoEntity mobileNetworkInfoEntity) {
|
||||
mMobileNetworkInfoEntity = mobileNetworkInfoEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAirplaneModeChanged(boolean airplaneModeEnabled) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAvailableSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActiveSubInfoChanged(List<SubscriptionInfoEntity> subInfoEntityList) {
|
||||
if (DataServiceUtils.shouldUpdateEntityList(mSubscriptionInfoEntityList,
|
||||
subInfoEntityList)) {
|
||||
mSubscriptionInfoEntityList = subInfoEntityList;
|
||||
mSubscriptionInfoEntityList.forEach(entity -> {
|
||||
if (Integer.parseInt(entity.subId) == mSubId) {
|
||||
mSubscriptionInfoEntity = entity;
|
||||
}
|
||||
});
|
||||
if (mSubscriptionInfoEntity != null
|
||||
&& mSubscriptionInfoEntity.isDefaultDataSubscription) {
|
||||
mDefaultSubId = Integer.parseInt(mSubscriptionInfoEntity.subId);
|
||||
}
|
||||
update();
|
||||
refreshSummary(mPreference);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAllMobileNetworkInfoChanged(
|
||||
List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
|
||||
if (DataServiceUtils.shouldUpdateEntityList(mMobileNetworkInfoEntityList,
|
||||
mobileNetworkInfoEntityList)) {
|
||||
mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList;
|
||||
mMobileNetworkInfoEntityList.forEach(entity -> {
|
||||
if (Integer.parseInt(entity.subId) == mSubId) {
|
||||
mMobileNetworkInfoEntity = entity;
|
||||
update();
|
||||
refreshSummary(mPreference);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
private static final String KEY_ROAMING_PREF = "button_roaming_key";
|
||||
private static final String KEY_CALLS_PREF = "calls_preference";
|
||||
private static final String KEY_SMS_PREF = "sms_preference";
|
||||
private static final String KEY_MOBILE_DATA_PREF = "mobile_data_enable";
|
||||
|
||||
//String keys for preference lookup
|
||||
private static final String BUTTON_CDMA_SYSTEM_SELECT_KEY = "cdma_system_select_key";
|
||||
@@ -175,7 +176,9 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
new CallsDefaultSubscriptionController(context, KEY_CALLS_PREF,
|
||||
getSettingsLifecycle(), this),
|
||||
new SmsDefaultSubscriptionController(context, KEY_SMS_PREF, getSettingsLifecycle(),
|
||||
this));
|
||||
this),
|
||||
new MobileDataPreferenceController(context, KEY_MOBILE_DATA_PREF,
|
||||
getSettingsLifecycle(), this, mSubId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -231,10 +234,16 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
REQUEST_CODE_DELETE_SUBSCRIPTION);
|
||||
use(DisableSimFooterPreferenceController.class).init(mSubId);
|
||||
use(NrDisabledInDsdsFooterPreferenceController.class).init(mSubId);
|
||||
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
|
||||
use(MobileDataPreferenceController.class).setWifiPickerTrackerHelper(
|
||||
new WifiPickerTrackerHelper(getSettingsLifecycle(), context,
|
||||
null /* WifiPickerTrackerCallback */));
|
||||
|
||||
final MobileDataPreferenceController mobileDataPreferenceController =
|
||||
use(MobileDataPreferenceController.class);
|
||||
if (mobileDataPreferenceController != null) {
|
||||
mobileDataPreferenceController.init(getFragmentManager(), mSubId,
|
||||
mSubscriptionInfoEntity, mMobileNetworkInfoEntity);
|
||||
mobileDataPreferenceController.setWifiPickerTrackerHelper(
|
||||
new WifiPickerTrackerHelper(getSettingsLifecycle(), context,
|
||||
null /* WifiPickerTrackerCallback */));
|
||||
}
|
||||
|
||||
final RoamingPreferenceController roamingPreferenceController =
|
||||
use(RoamingPreferenceController.class);
|
||||
@@ -269,11 +278,6 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
|
||||
final VideoCallingPreferenceController videoCallingPreferenceController =
|
||||
use(VideoCallingPreferenceController.class).init(mSubId);
|
||||
final BackupCallingPreferenceController crossSimCallingPreferenceController =
|
||||
use(BackupCallingPreferenceController.class).init(mSubId);
|
||||
use(CallingPreferenceCategoryController.class).setChildren(
|
||||
Arrays.asList(wifiCallingPreferenceController, videoCallingPreferenceController,
|
||||
crossSimCallingPreferenceController));
|
||||
use(Enhanced4gLtePreferenceController.class).init(mSubId)
|
||||
.addListener(videoCallingPreferenceController);
|
||||
use(Enhanced4gCallingPreferenceController.class).init(mSubId)
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* Preference controller for "Backup Calling"
|
||||
* Deprecated ToDo: b/260059444 remove it next version
|
||||
**/
|
||||
public class NetworkProviderBackupCallingGroup extends
|
||||
TelephonyTogglePreferenceController implements LifecycleObserver,
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Preference controller for "Backup Calling" summary list
|
||||
* Deprecated ToDo: b/260059444 remove it next version
|
||||
*/
|
||||
public class NetworkProviderBackupCallingPreferenceController extends
|
||||
BasePreferenceController implements LifecycleObserver {
|
||||
|
||||
@@ -26,6 +26,7 @@ android_test {
|
||||
"androidx.test.runner",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.ext.junit",
|
||||
"mockito-target",
|
||||
],
|
||||
|
||||
test_suites: ["device-tests"],
|
||||
|
||||
@@ -20,6 +20,8 @@ import static com.android.settings.testutils.CommonUtils.set_wifi_enabled;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -31,6 +33,7 @@ import android.util.Log;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.test.core.app.ActivityScenario;
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
@@ -40,6 +43,9 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.testutils.CommonUtils;
|
||||
import com.android.settings.testutils.UiUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assume;
|
||||
@@ -47,6 +53,8 @@ import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
@@ -54,6 +62,12 @@ import java.net.URL;
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class MobileDataPreferenceControllerComponentTest {
|
||||
|
||||
@Mock
|
||||
private Lifecycle mLifecycle;
|
||||
@Mock
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
|
||||
public static final int TIMEOUT = 2000;
|
||||
private static int sSubscriptionId = 2;
|
||||
public final String TAG = this.getClass().getName();
|
||||
@@ -116,9 +130,11 @@ public class MobileDataPreferenceControllerComponentTest {
|
||||
try {
|
||||
URL url = new URL("https://www.google.net");
|
||||
MobileDataPreferenceController controller = new MobileDataPreferenceController(
|
||||
mInstrumentation.getTargetContext(), "mobile_data");
|
||||
mInstrumentation.getTargetContext(), "mobile_data", mLifecycle,
|
||||
mLifecycleOwner, sSubscriptionId);
|
||||
FragmentManager manager = ((FragmentActivity) activity).getSupportFragmentManager();
|
||||
controller.init(manager, sSubscriptionId);
|
||||
controller.init(manager, sSubscriptionId, mock(SubscriptionInfoEntity.class), mock(
|
||||
MobileNetworkInfoEntity.class));
|
||||
|
||||
// Make sure mobile network can connect at first.
|
||||
assertThat(UiUtils.waitUntilCondition(1000,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.settings.fuelgauge.batterysaver;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
@@ -82,6 +83,12 @@ public final class BatterySaverScheduleSettingsTest {
|
||||
verifySchedule("key_battery_saver_percentage", expectedPercentage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMetricsCategory_returnExpectedResult() {
|
||||
assertThat(mBatterySaverScheduleSettings.getMetricsCategory())
|
||||
.isEqualTo(SettingsEnums.FUELGAUGE_BATTERY_SAVER_SCHEDULE);
|
||||
}
|
||||
|
||||
private void setSchedule(int scheduleType, int schedulePercentage) {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.AUTOMATIC_POWER_SAVE_MODE, scheduleType);
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.biometrics2.ui.model;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_CHALLENGE;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class CredentialModelTest {
|
||||
|
||||
private final Clock mClock = SystemClock.elapsedRealtimeClock();
|
||||
|
||||
public static Bundle newCredentialModelIntentExtras(int userId, long challenge, int sensorId,
|
||||
@Nullable byte[] token, long gkPwHandle) {
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt(Intent.EXTRA_USER_ID, userId);
|
||||
bundle.putInt(EXTRA_KEY_SENSOR_ID, sensorId);
|
||||
bundle.putLong(EXTRA_KEY_CHALLENGE, challenge);
|
||||
bundle.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||
bundle.putLong(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public static Bundle newValidTokenCredentialIntentExtras(int userId) {
|
||||
return newCredentialModelIntentExtras(userId, 1L, 1, new byte[] { 0 }, 0L);
|
||||
}
|
||||
|
||||
public static Bundle newInvalidChallengeCredentialIntentExtras(int userId) {
|
||||
return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null, 0L);
|
||||
}
|
||||
|
||||
public static Bundle newGkPwHandleCredentialIntentExtras(int userId, long gkPwHandle) {
|
||||
return newCredentialModelIntentExtras(userId, INVALID_CHALLENGE, 1, null, gkPwHandle);
|
||||
}
|
||||
|
||||
private static void checkBundleLongValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final int value1 = bundle1.getInt(key);
|
||||
final int value2 = bundle2.getInt(key);
|
||||
assertWithMessage("bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2).that(value1).isEqualTo(value2);
|
||||
}
|
||||
|
||||
private static void checkBundleIntValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final long value1 = bundle1.getLong(key);
|
||||
final long value2 = bundle2.getLong(key);
|
||||
assertWithMessage("bundle not match, key:" + key + ", value1:" + value1 + ", value2:"
|
||||
+ value2).that(value1).isEqualTo(value2);
|
||||
}
|
||||
|
||||
private static void checkBundleByteArrayValue(@NonNull Bundle bundle1, @NonNull Bundle bundle2,
|
||||
@NonNull String key) {
|
||||
if (!bundle1.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
final byte[] value1 = bundle1.getByteArray(key);
|
||||
final byte[] value2 = bundle2.getByteArray(key);
|
||||
final String errMsg = "bundle not match, key:" + key + ", value1:" + Arrays.toString(value1)
|
||||
+ ", value2:" + Arrays.toString(value2);
|
||||
if (value1 == null) {
|
||||
assertWithMessage(errMsg).that(value2).isNull();
|
||||
} else {
|
||||
assertWithMessage(errMsg).that(value1.length).isEqualTo(value2.length);
|
||||
for (int i = 0; i < value1.length; ++i) {
|
||||
assertWithMessage(errMsg).that(value1[i]).isEqualTo(value2[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void verifySameCredentialModels(@NonNull CredentialModel model1,
|
||||
@NonNull CredentialModel model2) {
|
||||
|
||||
assertThat(model1.getUserId()).isEqualTo(model2.getUserId());
|
||||
assertThat(model1.getSensorId()).isEqualTo(model2.getSensorId());
|
||||
assertThat(model1.getChallenge()).isEqualTo(model2.getChallenge());
|
||||
assertThat(model1.getGkPwHandle()).isEqualTo(model2.getGkPwHandle());
|
||||
|
||||
final byte[] token1 = model1.getToken();
|
||||
final byte[] token2 = model2.getToken();
|
||||
if (token1 == null) {
|
||||
assertThat(token2).isNull();
|
||||
} else {
|
||||
assertThat(token2).isNotNull();
|
||||
assertThat(token1.length).isEqualTo(token2.length);
|
||||
for (int i = 0; i < token1.length; ++i) {
|
||||
assertThat(token1[i]).isEqualTo(token2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final Bundle bundle1 = model1.getBundle();
|
||||
final Bundle bundle2 = model2.getBundle();
|
||||
final Set<String> keySet1 = bundle1.keySet();
|
||||
assertThat(keySet1.equals(bundle2.keySet())).isTrue();
|
||||
checkBundleIntValue(bundle1, bundle2, Intent.EXTRA_USER_ID);
|
||||
checkBundleIntValue(bundle1, bundle2, EXTRA_KEY_SENSOR_ID);
|
||||
checkBundleLongValue(bundle1, bundle2, EXTRA_KEY_CHALLENGE);
|
||||
checkBundleByteArrayValue(bundle1, bundle2, EXTRA_KEY_CHALLENGE);
|
||||
checkBundleLongValue(bundle1, bundle2, EXTRA_KEY_GK_PW_HANDLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameValueFromBundle() {
|
||||
final Bundle bundle = newCredentialModelIntentExtras(1234, 6677L, 1,
|
||||
new byte[] { 33, 44, 55 }, 987654321);
|
||||
|
||||
final CredentialModel model1 = new CredentialModel(bundle, mClock);
|
||||
final CredentialModel model2 = new CredentialModel(model1.getBundle(), mClock);
|
||||
|
||||
verifySameCredentialModels(model1, model2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sameValueFromBundle_nullToken() {
|
||||
final Bundle bundle = newCredentialModelIntentExtras(22, 33L, 1, null, 21L);
|
||||
|
||||
final CredentialModel model1 = new CredentialModel(bundle, mClock);
|
||||
final CredentialModel model2 = new CredentialModel(model1.getBundle(), mClock);
|
||||
|
||||
verifySameCredentialModels(model1, model2);
|
||||
}
|
||||
}
|
||||
@@ -24,12 +24,24 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_CHALLENGE;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_GK_PW_HANDLE;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.INVALID_SENSOR_ID;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.isValidGkPwHandle;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModel.isValidToken;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newCredentialModelIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newGkPwHandleCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newInvalidChallengeCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.model.CredentialModelTest.newValidTokenCredentialIntentExtras;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_IS_GENERATING_CHALLENGE;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CREDENTIAL_VALID;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.ChallengeGenerator;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.CredentialAction;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.GenerateChallengeCallback;
|
||||
import static com.android.settings.biometrics2.ui.viewmodel.AutoCredentialViewModel.KEY_CREDENTIAL_MODEL;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN;
|
||||
import static com.android.settings.password.ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
@@ -38,20 +50,17 @@ import static org.mockito.Mockito.when;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.activity.result.ActivityResult;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.VerifyCredentialResponse;
|
||||
import com.android.settings.biometrics2.ui.model.CredentialModel;
|
||||
import com.android.settings.password.ChooseLockPattern;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.testutils.InstantTaskExecutorRule;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -68,248 +77,326 @@ public class AutoCredentialViewModelTest {
|
||||
@Rule public final MockitoRule mockito = MockitoJUnit.rule();
|
||||
@Rule public final InstantTaskExecutorRule mTaskExecutorRule = new InstantTaskExecutorRule();
|
||||
|
||||
@Mock private LifecycleOwner mLifecycleOwner;
|
||||
@Mock private LockPatternUtils mLockPatternUtils;
|
||||
private TestChallengeGenerator mChallengeGenerator = null;
|
||||
private AutoCredentialViewModel mAutoCredentialViewModel;
|
||||
private AutoCredentialViewModel mViewModel;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mChallengeGenerator = new TestChallengeGenerator();
|
||||
mAutoCredentialViewModel = new AutoCredentialViewModel(
|
||||
mViewModel = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
}
|
||||
|
||||
private CredentialModel newCredentialModel(int userId, long challenge,
|
||||
@Nullable byte[] token, long gkPwHandle) {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(Intent.EXTRA_USER_ID, userId);
|
||||
intent.putExtra(EXTRA_KEY_SENSOR_ID, 1);
|
||||
intent.putExtra(EXTRA_KEY_CHALLENGE, challenge);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, token);
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
return new CredentialModel(intent, SystemClock.elapsedRealtimeClock());
|
||||
}
|
||||
|
||||
private CredentialModel newValidTokenCredentialModel(int userId) {
|
||||
return newCredentialModel(userId, 1L, new byte[] { 0 }, 0L);
|
||||
}
|
||||
|
||||
private CredentialModel newInvalidChallengeCredentialModel(int userId) {
|
||||
return newCredentialModel(userId, INVALID_CHALLENGE, null, 0L);
|
||||
}
|
||||
|
||||
private CredentialModel newGkPwHandleCredentialModel(int userId, long gkPwHandle) {
|
||||
return newCredentialModel(userId, INVALID_CHALLENGE, null, gkPwHandle);
|
||||
}
|
||||
|
||||
private void verifyNothingHappen() {
|
||||
assertThat(mAutoCredentialViewModel.getActionLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
private void verifyOnlyActionLiveData(@CredentialAction int action) {
|
||||
final Integer value = mAutoCredentialViewModel.getActionLiveData().getValue();
|
||||
assertThat(value).isEqualTo(action);
|
||||
}
|
||||
|
||||
private void setupGenerateTokenFlow(long gkPwHandle, int userId, int newSensorId,
|
||||
long newChallenge) {
|
||||
private void setupGenerateChallenge(int userId, int newSensorId, long newChallenge) {
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
mChallengeGenerator.mUserId = userId;
|
||||
mChallengeGenerator.mSensorId = newSensorId;
|
||||
mChallengeGenerator.mChallenge = newChallenge;
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_validCredentialCase() {
|
||||
public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent() {
|
||||
final Bundle extras = newCredentialModelIntentExtras(12, 33, 1, new byte[] { 2, 3 }, 3L);
|
||||
|
||||
AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
|
||||
mViewModel.setCredentialModel(null, new Intent().putExtras(extras));
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL, extras);
|
||||
viewModel2.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
final Bundle bundle1 = mViewModel.createCredentialIntentExtra();
|
||||
final Bundle bundle2 = viewModel2.createCredentialIntentExtra();
|
||||
assertThat(bundle1.getLong(EXTRA_KEY_GK_PW_HANDLE))
|
||||
.isEqualTo(bundle2.getLong(EXTRA_KEY_GK_PW_HANDLE));
|
||||
assertThat(bundle1.getLong(Intent.EXTRA_USER_ID))
|
||||
.isEqualTo(bundle2.getLong(Intent.EXTRA_USER_ID));
|
||||
assertThat(bundle1.getLong(EXTRA_KEY_CHALLENGE))
|
||||
.isEqualTo(bundle2.getLong(EXTRA_KEY_CHALLENGE));
|
||||
assertThat(bundle1.getInt(EXTRA_KEY_SENSOR_ID))
|
||||
.isEqualTo(bundle2.getInt(EXTRA_KEY_SENSOR_ID));
|
||||
final byte[] token1 = bundle1.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
final byte[] token2 = bundle2.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN);
|
||||
assertThat(token1).isNotNull();
|
||||
assertThat(token2).isNotNull();
|
||||
assertThat(token1.length).isEqualTo(token2.length);
|
||||
for (int i = 0; i < token2.length; ++i) {
|
||||
assertThat(token1[i]).isEqualTo(token2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetCredentialModel_sameResultFromSavedInstanceOrIntent_invalidValues() {
|
||||
final Bundle extras = newCredentialModelIntentExtras(UserHandle.USER_NULL,
|
||||
INVALID_CHALLENGE, INVALID_SENSOR_ID, null, INVALID_GK_PW_HANDLE);
|
||||
|
||||
AutoCredentialViewModel viewModel2 = new AutoCredentialViewModel(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
mLockPatternUtils,
|
||||
mChallengeGenerator);
|
||||
|
||||
mViewModel.setCredentialModel(null, new Intent().putExtras(extras));
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL, extras);
|
||||
viewModel2.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
final Bundle bundle1 = mViewModel.createCredentialIntentExtra();
|
||||
final Bundle bundle2 = viewModel2.createCredentialIntentExtra();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_GK_PW_HANDLE)).isFalse();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_CHALLENGE_TOKEN)).isFalse();
|
||||
assertThat(bundle1.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue();
|
||||
assertThat(bundle2.containsKey(EXTRA_KEY_SENSOR_ID)).isTrue();
|
||||
assertThat(bundle1.containsKey(Intent.EXTRA_USER_ID)).isFalse();
|
||||
assertThat(bundle2.containsKey(Intent.EXTRA_USER_ID)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckCredential_validCredentialCase() {
|
||||
final int userId = 99;
|
||||
mAutoCredentialViewModel.setCredentialModel(newValidTokenCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newValidTokenCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
verifyNothingHappen();
|
||||
assertThat(action).isEqualTo(CREDENTIAL_VALID);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_needToChooseLock() {
|
||||
public void testCheckCredential_needToChooseLock() {
|
||||
final int userId = 100;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_UNSPECIFIED);
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
verifyOnlyActionLiveData(CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK);
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CHOOSE_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_needToConfirmLockFoSomething() {
|
||||
public void testCheckCredential_needToConfirmLockFoSomething() {
|
||||
final int userId = 101;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
verifyOnlyActionLiveData(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_needToConfirmLockForNumeric() {
|
||||
public void testCheckCredential_needToConfirmLockForNumeric() {
|
||||
final int userId = 102;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_NUMERIC);
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
verifyOnlyActionLiveData(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_needToConfirmLockForAlphabetic() {
|
||||
public void testCheckCredential_needToConfirmLockForAlphabetic() {
|
||||
final int userId = 103;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_ALPHABETIC);
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
verifyOnlyActionLiveData(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(action).isEqualTo(CREDENTIAL_FAIL_NEED_TO_CONFIRM_LOCK);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkCredential_generateChallenge() {
|
||||
public void testCheckCredential_generateChallenge() {
|
||||
final int userId = 104;
|
||||
final long gkPwHandle = 1111L;
|
||||
final CredentialModel credentialModel = newGkPwHandleCredentialModel(userId, gkPwHandle);
|
||||
mAutoCredentialViewModel.setCredentialModel(credentialModel);
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final int newSensorId = 10;
|
||||
final long newChallenge = 20L;
|
||||
setupGenerateTokenFlow(gkPwHandle, userId, newSensorId, newChallenge);
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
// Run credential check
|
||||
mAutoCredentialViewModel.onCreate(mLifecycleOwner);
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
assertThat(mAutoCredentialViewModel.getActionLiveData().getValue()).isNull();
|
||||
assertThat(credentialModel.getSensorId()).isEqualTo(newSensorId);
|
||||
assertThat(credentialModel.getChallenge()).isEqualTo(newChallenge);
|
||||
assertThat(CredentialModel.isValidToken(credentialModel.getToken())).isTrue();
|
||||
assertThat(CredentialModel.isValidGkPwHandle(credentialModel.getGkPwHandle())).isFalse();
|
||||
assertThat(action).isEqualTo(CREDENTIAL_IS_GENERATING_CHALLENGE);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(isValidToken(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN))).isTrue();
|
||||
assertThat(isValidGkPwHandle(extras.getLong(EXTRA_KEY_GK_PW_HANDLE))).isFalse();
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserId() {
|
||||
public void testCheckCredential_generateChallengeFail() {
|
||||
final int userId = 104;
|
||||
final long gkPwHandle = 1111L;
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final int newSensorId = 10;
|
||||
final long newChallenge = 20L;
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newBadCredential(0));
|
||||
|
||||
// Run credential check
|
||||
@CredentialAction final int action = mViewModel.checkCredential();
|
||||
|
||||
assertThat(action).isEqualTo(CREDENTIAL_IS_GENERATING_CHALLENGE);
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isTrue();
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserId_fromIntent() {
|
||||
final int userId = 106;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
|
||||
// Get userId
|
||||
assertThat(mAutoCredentialViewModel.getUserId()).isEqualTo(userId);
|
||||
assertThat(mViewModel.getUserId()).isEqualTo(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUserId_fromSavedInstance() {
|
||||
final int userId = 106;
|
||||
final Bundle savedInstance = new Bundle();
|
||||
savedInstance.putBundle(KEY_CREDENTIAL_MODEL,
|
||||
newInvalidChallengeCredentialIntentExtras(userId));
|
||||
mViewModel.setCredentialModel(savedInstance, new Intent());
|
||||
|
||||
// Get userId
|
||||
assertThat(mViewModel.getUserId()).isEqualTo(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_invalidChooseLock() {
|
||||
final int userId = 107;
|
||||
final long gkPwHandle = 3333L;
|
||||
mAutoCredentialViewModel.setCredentialModel(
|
||||
newGkPwHandleCredentialModel(userId, gkPwHandle));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(true,
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED + 1, intent));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
verifyNothingHappen();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_invalidConfirmLock() {
|
||||
final int userId = 107;
|
||||
final long gkPwHandle = 3333L;
|
||||
mAutoCredentialViewModel.setCredentialModel(
|
||||
newGkPwHandleCredentialModel(userId, gkPwHandle));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
intent.putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(false,
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK + 1, intent));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
verifyNothingHappen();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_nullDataChooseLock() {
|
||||
final int userId = 108;
|
||||
final long gkPwHandle = 4444L;
|
||||
mAutoCredentialViewModel.setCredentialModel(
|
||||
newGkPwHandleCredentialModel(userId, gkPwHandle));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newGkPwHandleCredentialIntentExtras(userId, gkPwHandle)));
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(true,
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED, null));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
verifyNothingHappen();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_nullDataConfirmLock() {
|
||||
final int userId = 109;
|
||||
mAutoCredentialViewModel.setCredentialModel(newInvalidChallengeCredentialModel(userId));
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
|
||||
// run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(false,
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK, null));
|
||||
|
||||
assertThat(ret).isFalse();
|
||||
verifyNothingHappen();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_validChooseLock() {
|
||||
final int userId = 108;
|
||||
final CredentialModel credentialModel = newInvalidChallengeCredentialModel(userId);
|
||||
mAutoCredentialViewModel.setCredentialModel(credentialModel);
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final long gkPwHandle = 6666L;
|
||||
final int newSensorId = 50;
|
||||
final long newChallenge = 60L;
|
||||
setupGenerateTokenFlow(gkPwHandle, userId, newSensorId, newChallenge);
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
// Run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(true,
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(true,
|
||||
new ActivityResult(ChooseLockPattern.RESULT_FINISHED, intent));
|
||||
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(mAutoCredentialViewModel.getActionLiveData().getValue()).isNull();
|
||||
assertThat(credentialModel.getSensorId()).isEqualTo(newSensorId);
|
||||
assertThat(credentialModel.getChallenge()).isEqualTo(newChallenge);
|
||||
assertThat(CredentialModel.isValidToken(credentialModel.getToken())).isTrue();
|
||||
assertThat(CredentialModel.isValidGkPwHandle(credentialModel.getGkPwHandle())).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(isValidToken(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN))).isTrue();
|
||||
assertThat(isValidGkPwHandle(extras.getLong(EXTRA_KEY_GK_PW_HANDLE))).isFalse();
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -317,28 +404,30 @@ public class AutoCredentialViewModelTest {
|
||||
@Test
|
||||
public void testCheckNewCredentialFromActivityResult_validConfirmLock() {
|
||||
final int userId = 109;
|
||||
final CredentialModel credentialModel = newInvalidChallengeCredentialModel(userId);
|
||||
mAutoCredentialViewModel.setCredentialModel(credentialModel);
|
||||
mViewModel.setCredentialModel(null,
|
||||
new Intent().putExtras(newInvalidChallengeCredentialIntentExtras(userId)));
|
||||
when(mLockPatternUtils.getActivePasswordQuality(userId)).thenReturn(
|
||||
PASSWORD_QUALITY_SOMETHING);
|
||||
|
||||
final long gkPwHandle = 5555L;
|
||||
final int newSensorId = 80;
|
||||
final long newChallenge = 90L;
|
||||
setupGenerateTokenFlow(gkPwHandle, userId, newSensorId, newChallenge);
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
setupGenerateChallenge(userId, newSensorId, newChallenge);
|
||||
when(mLockPatternUtils.verifyGatekeeperPasswordHandle(gkPwHandle, newChallenge, userId))
|
||||
.thenReturn(newGoodCredential(gkPwHandle, new byte[] { 1 }));
|
||||
|
||||
// Run checkNewCredentialFromActivityResult()
|
||||
final boolean ret = mAutoCredentialViewModel.checkNewCredentialFromActivityResult(false,
|
||||
final Intent intent = new Intent().putExtra(EXTRA_KEY_GK_PW_HANDLE, gkPwHandle);
|
||||
final boolean ret = mViewModel.checkNewCredentialFromActivityResult(false,
|
||||
new ActivityResult(Activity.RESULT_OK, intent));
|
||||
|
||||
assertThat(ret).isTrue();
|
||||
assertThat(mAutoCredentialViewModel.getActionLiveData().getValue()).isNull();
|
||||
assertThat(credentialModel.getSensorId()).isEqualTo(newSensorId);
|
||||
assertThat(credentialModel.getChallenge()).isEqualTo(newChallenge);
|
||||
assertThat(CredentialModel.isValidToken(credentialModel.getToken())).isTrue();
|
||||
assertThat(CredentialModel.isValidGkPwHandle(credentialModel.getGkPwHandle())).isFalse();
|
||||
assertThat(mViewModel.getGenerateChallengeFailedLiveData().getValue()).isNull();
|
||||
final Bundle extras = mViewModel.createCredentialIntentExtra();
|
||||
assertThat(extras.getInt(EXTRA_KEY_SENSOR_ID)).isEqualTo(newSensorId);
|
||||
assertThat(extras.getLong(EXTRA_KEY_CHALLENGE)).isEqualTo(newChallenge);
|
||||
assertThat(isValidToken(extras.getByteArray(EXTRA_KEY_CHALLENGE_TOKEN))).isTrue();
|
||||
assertThat(isValidGkPwHandle(extras.getLong(EXTRA_KEY_GK_PW_HANDLE))).isFalse();
|
||||
assertThat(mChallengeGenerator.mCallbackRunCount).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -377,4 +466,12 @@ public class AutoCredentialViewModelTest {
|
||||
.setGatekeeperHAT(hat)
|
||||
.build();
|
||||
}
|
||||
|
||||
private VerifyCredentialResponse newBadCredential(int timeout) {
|
||||
if (timeout > 0) {
|
||||
return VerifyCredentialResponse.fromTimeout(timeout);
|
||||
} else {
|
||||
return VerifyCredentialResponse.fromError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import android.hardware.fingerprint.FingerprintManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
@@ -92,6 +93,18 @@ public class FingerprintEnrollIntroViewModelTest {
|
||||
assertThat(status.getEnrollableStatus()).isEqualTo(FINGERPRINT_ENROLLABLE_UNKNOWN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearActionLiveData() {
|
||||
final MutableLiveData<Integer> actionLiveData =
|
||||
(MutableLiveData<Integer>) mViewModel.getActionLiveData();
|
||||
actionLiveData.postValue(1);
|
||||
assertThat(actionLiveData.getValue()).isEqualTo(1);
|
||||
|
||||
mViewModel.clearActionLiveData();
|
||||
|
||||
assertThat(actionLiveData.getValue()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetEnrollmentRequest() {
|
||||
final EnrollmentRequest request = newAllFalseRequest(mApplication);
|
||||
@@ -202,11 +215,13 @@ public class FingerprintEnrollIntroViewModelTest {
|
||||
|
||||
@Test
|
||||
public void testSetHasScrolledToBottom() {
|
||||
mViewModel.setHasScrolledToBottom();
|
||||
|
||||
mViewModel.setHasScrolledToBottom(true);
|
||||
FingerprintEnrollIntroStatus status = mViewModel.getPageStatusLiveData().getValue();
|
||||
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(true);
|
||||
|
||||
mViewModel.setHasScrolledToBottom(false);
|
||||
status = mViewModel.getPageStatusLiveData().getValue();
|
||||
assertThat(status.hasScrollToBottom()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.network;
|
||||
|
||||
import static com.android.settings.network.InternetResetHelper.RESTART_TIMEOUT_MS;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -29,8 +31,6 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
@@ -39,7 +39,6 @@ import androidx.preference.PreferenceCategory;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settingslib.connectivity.ConnectivitySubsystemsRecoveryManager;
|
||||
import com.android.settingslib.utils.HandlerInjector;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -47,6 +46,7 @@ import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
@@ -55,66 +55,46 @@ public class InternetResetHelperTest {
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Spy
|
||||
private final Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
public HandlerThread mWorkerThread;
|
||||
InternetResetHelper.RecoveryWorker mRecoveryWorker;
|
||||
@Mock
|
||||
public ConnectivitySubsystemsRecoveryManager mConnectivitySubsystemsRecoveryManager;
|
||||
HandlerInjector mHandlerInjector;
|
||||
@Mock
|
||||
public NetworkMobileProviderController mMobileNetworkController;
|
||||
|
||||
private Context mContext;
|
||||
private InternetResetHelper mInternetResetHelper;
|
||||
private Preference mResettingPreference;
|
||||
private Preference mWifiTogglePreferences;
|
||||
private PreferenceCategory mConnectedWifiEntryPreferences;
|
||||
private PreferenceCategory mFirstWifiEntryPreference;
|
||||
private PreferenceCategory mWifiEntryPreferences;
|
||||
|
||||
private FakeHandlerInjector mFakeHandlerInjector;
|
||||
|
||||
private static class FakeHandlerInjector extends HandlerInjector {
|
||||
|
||||
private Runnable mRunnable;
|
||||
|
||||
FakeHandlerInjector(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDelayed(Runnable runnable, long delayMillis) {
|
||||
mRunnable = runnable;
|
||||
}
|
||||
|
||||
public Runnable getRunnable() {
|
||||
return mRunnable;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
when(mContext.getSystemService(WifiManager.class)).thenReturn(mWifiManager);
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(false);
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
mResettingPreference = new Preference(mContext);
|
||||
mResettingPreference = spy(new Preference(mContext));
|
||||
mWifiTogglePreferences = new Preference(mContext);
|
||||
mConnectedWifiEntryPreferences = spy(new PreferenceCategory(mContext));
|
||||
mFirstWifiEntryPreference = spy(new PreferenceCategory(mContext));
|
||||
mWifiEntryPreferences = spy(new PreferenceCategory(mContext));
|
||||
|
||||
final Lifecycle lifecycle = mock(Lifecycle.class);
|
||||
mInternetResetHelper = new InternetResetHelper(mContext, lifecycle);
|
||||
mInternetResetHelper.mWorkerThread = mWorkerThread;
|
||||
mFakeHandlerInjector = new FakeHandlerInjector(mContext.getMainThreadHandler());
|
||||
mInternetResetHelper.mHandlerInjector = mFakeHandlerInjector;
|
||||
mInternetResetHelper.mConnectivitySubsystemsRecoveryManager =
|
||||
mConnectivitySubsystemsRecoveryManager;
|
||||
mInternetResetHelper.setResettingPreference(mResettingPreference);
|
||||
mInternetResetHelper.setMobileNetworkController(mMobileNetworkController);
|
||||
mInternetResetHelper.setWifiTogglePreference(mWifiTogglePreferences);
|
||||
mInternetResetHelper.addWifiNetworkPreference(mConnectedWifiEntryPreferences);
|
||||
mInternetResetHelper.addWifiNetworkPreference(mWifiEntryPreferences);
|
||||
mInternetResetHelper = new InternetResetHelper(mContext, mock(Lifecycle.class),
|
||||
mMobileNetworkController,
|
||||
mWifiTogglePreferences,
|
||||
mConnectedWifiEntryPreferences,
|
||||
mFirstWifiEntryPreference,
|
||||
mWifiEntryPreferences,
|
||||
mResettingPreference);
|
||||
mInternetResetHelper.mHandlerInjector = mHandlerInjector;
|
||||
mInternetResetHelper.mRecoveryWorker = mRecoveryWorker;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -135,30 +115,10 @@ public class InternetResetHelperTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDestroy_quitWorkerThread() {
|
||||
public void onDestroy_removeCallbacks() {
|
||||
mInternetResetHelper.onDestroy();
|
||||
|
||||
verify(mWorkerThread).quit();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSubsystemRestartOperationEnd_recoveryIsNotReady_postResumeRunnable() {
|
||||
mInternetResetHelper.mIsRecoveryReady = false;
|
||||
|
||||
mInternetResetHelper.onSubsystemRestartOperationEnd();
|
||||
|
||||
assertThat(mInternetResetHelper.mIsRecoveryReady).isTrue();
|
||||
assertThat(mFakeHandlerInjector.getRunnable())
|
||||
.isEqualTo(mInternetResetHelper.mResumeRunnable);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onSubsystemRestartOperationEnd_recoveryIsReady_doNothing() {
|
||||
mInternetResetHelper.mIsRecoveryReady = true;
|
||||
|
||||
mInternetResetHelper.onSubsystemRestartOperationEnd();
|
||||
|
||||
assertThat(mFakeHandlerInjector.getRunnable()).isNull();
|
||||
verify(mHandlerInjector).removeCallbacks(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -169,19 +129,16 @@ public class InternetResetHelperTest {
|
||||
mInternetResetHelper.updateWifiStateChange();
|
||||
|
||||
assertThat(mInternetResetHelper.mIsWifiReady).isFalse();
|
||||
assertThat(mFakeHandlerInjector.getRunnable()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateWifiStateChange_wifiIsNotReadyAndWifiEnabled_postResumeRunnable() {
|
||||
public void updateWifiStateChange_wifiIsNotReadyAndWifiEnabled_updateWifiIsReady() {
|
||||
mInternetResetHelper.mIsWifiReady = false;
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
|
||||
mInternetResetHelper.updateWifiStateChange();
|
||||
|
||||
assertThat(mInternetResetHelper.mIsWifiReady).isTrue();
|
||||
assertThat(mFakeHandlerInjector.getRunnable())
|
||||
.isEqualTo(mInternetResetHelper.mResumeRunnable);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -191,7 +148,6 @@ public class InternetResetHelperTest {
|
||||
mInternetResetHelper.updateWifiStateChange();
|
||||
|
||||
assertThat(mInternetResetHelper.mIsWifiReady).isTrue();
|
||||
assertThat(mFakeHandlerInjector.getRunnable()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -203,16 +159,15 @@ public class InternetResetHelperTest {
|
||||
// Hide subsystem preferences
|
||||
verify(mMobileNetworkController).hidePreference(true /* hide */, true /* immediately*/);
|
||||
assertThat(mWifiTogglePreferences.isVisible()).isFalse();
|
||||
verify(mConnectedWifiEntryPreferences).removeAll();
|
||||
assertThat(mConnectedWifiEntryPreferences.isVisible()).isFalse();
|
||||
verify(mWifiEntryPreferences).removeAll();
|
||||
assertThat(mFirstWifiEntryPreference.isVisible()).isFalse();
|
||||
assertThat(mWifiEntryPreferences.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resumePreferences_onlyRecoveryReady_shouldShowSubSysHideResetting() {
|
||||
mInternetResetHelper.suspendPreferences();
|
||||
mInternetResetHelper.mIsRecoveryReady = true;
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(false);
|
||||
mInternetResetHelper.mIsWifiReady = false;
|
||||
|
||||
mInternetResetHelper.resumePreferences();
|
||||
@@ -224,13 +179,14 @@ public class InternetResetHelperTest {
|
||||
// Hide Wi-Fi preferences
|
||||
assertThat(mWifiTogglePreferences.isVisible()).isFalse();
|
||||
assertThat(mConnectedWifiEntryPreferences.isVisible()).isFalse();
|
||||
assertThat(mFirstWifiEntryPreference.isVisible()).isFalse();
|
||||
assertThat(mWifiEntryPreferences.isVisible()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resumePreferences_onlyWifiReady_shouldShowSubSysHideResetting() {
|
||||
mInternetResetHelper.suspendPreferences();
|
||||
mInternetResetHelper.mIsRecoveryReady = false;
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(true);
|
||||
mInternetResetHelper.mIsWifiReady = true;
|
||||
|
||||
mInternetResetHelper.resumePreferences();
|
||||
@@ -240,6 +196,7 @@ public class InternetResetHelperTest {
|
||||
// Show Wi-Fi preferences
|
||||
assertThat(mWifiTogglePreferences.isVisible()).isTrue();
|
||||
assertThat(mConnectedWifiEntryPreferences.isVisible()).isTrue();
|
||||
assertThat(mFirstWifiEntryPreference.isVisible()).isTrue();
|
||||
assertThat(mWifiEntryPreferences.isVisible()).isTrue();
|
||||
// Hide Mobile Network controller
|
||||
verify(mMobileNetworkController, never())
|
||||
@@ -249,14 +206,16 @@ public class InternetResetHelperTest {
|
||||
@Test
|
||||
public void resumePreferences_allReady_shouldShowSubSysHideResetting() {
|
||||
mInternetResetHelper.suspendPreferences();
|
||||
mInternetResetHelper.mIsRecoveryReady = true;
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(false);
|
||||
mInternetResetHelper.mIsWifiReady = true;
|
||||
|
||||
mInternetResetHelper.resumePreferences();
|
||||
|
||||
// Show subsystem preferences
|
||||
verify(mMobileNetworkController).hidePreference(false, true);
|
||||
assertThat(mWifiTogglePreferences.isVisible()).isTrue();
|
||||
assertThat(mConnectedWifiEntryPreferences.isVisible()).isTrue();
|
||||
assertThat(mFirstWifiEntryPreference.isVisible()).isTrue();
|
||||
assertThat(mWifiEntryPreferences.isVisible()).isTrue();
|
||||
// Hide resetting preference
|
||||
assertThat(mResettingPreference.isVisible()).isFalse();
|
||||
@@ -264,22 +223,39 @@ public class InternetResetHelperTest {
|
||||
|
||||
@Test
|
||||
public void restart_recoveryNotAvailable_shouldDoTriggerSubsystemRestart() {
|
||||
when(mConnectivitySubsystemsRecoveryManager.isRecoveryAvailable()).thenReturn(false);
|
||||
when(mRecoveryWorker.isRecoveryAvailable()).thenReturn(false);
|
||||
|
||||
mInternetResetHelper.restart();
|
||||
|
||||
verify(mConnectivitySubsystemsRecoveryManager, never())
|
||||
.triggerSubsystemRestart(any(), any());
|
||||
verify(mRecoveryWorker, never()).triggerRestart();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void restart_recoveryAvailable_triggerSubsystemRestart() {
|
||||
when(mConnectivitySubsystemsRecoveryManager.isRecoveryAvailable()).thenReturn(true);
|
||||
when(mRecoveryWorker.isRecoveryAvailable()).thenReturn(true);
|
||||
|
||||
mInternetResetHelper.restart();
|
||||
|
||||
assertThat(mFakeHandlerInjector.getRunnable())
|
||||
.isEqualTo(mInternetResetHelper.mTimeoutRunnable);
|
||||
verify(mConnectivitySubsystemsRecoveryManager).triggerSubsystemRestart(any(), any());
|
||||
verify(mHandlerInjector)
|
||||
.postDelayed(mInternetResetHelper.mTimeoutRunnable, RESTART_TIMEOUT_MS);
|
||||
verify(mRecoveryWorker).triggerRestart();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkRecovering_isRecovering_showResetting() {
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(true);
|
||||
|
||||
mInternetResetHelper.checkRecovering();
|
||||
|
||||
verify(mResettingPreference).setVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkRecovering_isNotRecovering_doNotShowResetting() {
|
||||
when(mRecoveryWorker.isRecovering()).thenReturn(false);
|
||||
|
||||
mInternetResetHelper.checkRecovering();
|
||||
|
||||
verify(mResettingPreference, never()).setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,13 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
/**
|
||||
* Deprecated ToDo: b/260059444 remove it next version
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BackupCallingPreferenceControllerTest {
|
||||
private static final int SUB_ID = 2;
|
||||
@@ -47,6 +51,7 @@ public class BackupCallingPreferenceControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void controller_isUnavailable() {
|
||||
assertThat(mController.getAvailabilityStatus())
|
||||
.isEqualTo(BasePreferenceController.CONDITIONALLY_UNAVAILABLE);
|
||||
|
||||
@@ -28,18 +28,24 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.content.Context;
|
||||
import android.os.Looper;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
import androidx.preference.SwitchPreference;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
|
||||
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -49,6 +55,10 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class MobileDataPreferenceControllerTest {
|
||||
private static final String SUB_ID_1 = "1";
|
||||
private static final String SUB_ID_2 = "2";
|
||||
private static final String DISPLAY_NAME_1 = "Sub 1";
|
||||
private static final String DISPLAY_NAME_2 = "Sub 2";
|
||||
private static final int SUB_ID = 2;
|
||||
private static final int SUB_ID_OTHER = 3;
|
||||
|
||||
@@ -64,7 +74,15 @@ public class MobileDataPreferenceControllerTest {
|
||||
private SubscriptionInfo mSubscriptionInfo;
|
||||
@Mock
|
||||
private FragmentTransaction mFragmentTransaction;
|
||||
|
||||
@Mock
|
||||
private Lifecycle mLifecycle;
|
||||
@Mock
|
||||
private LifecycleOwner mLifecycleOwner;
|
||||
private SubscriptionInfoEntity mSubInfo1;
|
||||
private SubscriptionInfoEntity mSubInfo2;
|
||||
private MobileNetworkInfoEntity mNetworkInfo1;
|
||||
private MobileNetworkInfoEntity mNetworkInfo2;
|
||||
private LifecycleRegistry mLifecycleRegistry;
|
||||
private MobileDataPreferenceController mController;
|
||||
private SwitchPreference mPreference;
|
||||
private Context mContext;
|
||||
@@ -73,6 +91,10 @@ public class MobileDataPreferenceControllerTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mContext = spy(ApplicationProvider.getApplicationContext());
|
||||
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
||||
@@ -83,22 +105,45 @@ public class MobileDataPreferenceControllerTest {
|
||||
doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
|
||||
|
||||
mPreference = new SwitchPreference(mContext);
|
||||
mController = new MobileDataPreferenceController(mContext, "mobile_data");
|
||||
mController.init(mFragmentManager, SUB_ID);
|
||||
mController = new MobileDataPreferenceController(mContext, "mobile_data", mLifecycle,
|
||||
mLifecycleOwner, SUB_ID);
|
||||
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
|
||||
mPreference.setKey(mController.getPreferenceKey());
|
||||
mLifecycleRegistry = new LifecycleRegistry(mLifecycleOwner);
|
||||
when(mLifecycleOwner.getLifecycle()).thenReturn(mLifecycleRegistry);
|
||||
}
|
||||
|
||||
private SubscriptionInfoEntity setupSubscriptionInfoEntity(String subId, String displayName,
|
||||
boolean isOpportunistic, boolean isValid, boolean isActive, boolean isAvailable,
|
||||
boolean isDefaultData) {
|
||||
int id = Integer.parseInt(subId);
|
||||
return new SubscriptionInfoEntity(subId, id, id,
|
||||
displayName, displayName, 0, "mcc", "mnc", "countryIso", false, id,
|
||||
TelephonyManager.DEFAULT_PORT_INDEX, isOpportunistic, null,
|
||||
SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, displayName, false,
|
||||
"1234567890", true, "default", false, isValid, true, isActive, isAvailable, false,
|
||||
false, isDefaultData, false, false);
|
||||
}
|
||||
|
||||
private MobileNetworkInfoEntity setupMobileNetworkInfoEntity(String subId,
|
||||
boolean isDatEnabled) {
|
||||
return new MobileNetworkInfoEntity(subId, false, false, isDatEnabled, false, false, false,
|
||||
false, false, false, false, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_invalidSubscription_returnAvailableUnsearchable() {
|
||||
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID, mSubInfo1,
|
||||
mNetworkInfo1);
|
||||
|
||||
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE_UNSEARCHABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isDialogNeeded_disableSingleSim_returnFalse() {
|
||||
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
|
||||
true);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
|
||||
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
assertThat(mController.isDialogNeeded()).isFalse();
|
||||
@@ -106,12 +151,15 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isDialogNeeded_enableNonDefaultSimInMultiSimMode_returnTrue() {
|
||||
doReturn(false).when(mTelephonyManager).isDataEnabled();
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager)
|
||||
.getActiveSubscriptionInfo(SUB_ID);
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
|
||||
false);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), false);
|
||||
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
||||
// Ideally, it would be better if we could set the default data subscription to
|
||||
// SUB_ID_OTHER, and set that as an active subscription id.
|
||||
when(mSubscriptionManager.isActiveSubscriptionId(anyInt())).thenReturn(true);
|
||||
mSubInfo2 = setupSubscriptionInfoEntity(SUB_ID_2, DISPLAY_NAME_2, false, true, true, true,
|
||||
true);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
|
||||
doReturn(2).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
assertThat(mController.isDialogNeeded()).isTrue();
|
||||
@@ -132,8 +180,11 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_singleSim_On_shouldEnableData() {
|
||||
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
|
||||
true);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
|
||||
mController.setSubscriptionInfoEntity(mSubInfo1);
|
||||
mController.setMobileNetworkInfoEntity(mNetworkInfo1);
|
||||
doReturn(1).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
@@ -143,8 +194,11 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_multiSim_On_shouldEnableData() {
|
||||
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
|
||||
true);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
|
||||
mController.setSubscriptionInfoEntity(mSubInfo1);
|
||||
mController.setMobileNetworkInfoEntity(mNetworkInfo1);
|
||||
doReturn(2).when(mTelephonyManager).getActiveModemCount();
|
||||
|
||||
mController.onPreferenceChange(mPreference, true);
|
||||
@@ -154,18 +208,20 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void isChecked_returnUserDataEnabled() {
|
||||
mController.init(mFragmentManager, SUB_ID);
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), false);
|
||||
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
|
||||
assertThat(mController.isChecked()).isFalse();
|
||||
|
||||
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||
mNetworkInfo1 = setupMobileNetworkInfoEntity(String.valueOf(SUB_ID), true);
|
||||
mController.setMobileNetworkInfoEntity(mNetworkInfo1);
|
||||
assertThat(mController.isChecked()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_opportunistic_disabled() {
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||
mController.init(mFragmentManager, SUB_ID);
|
||||
doReturn(true).when(mSubscriptionInfo).isOpportunistic();
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, true, true, true, true,
|
||||
true);
|
||||
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isFalse();
|
||||
@@ -176,9 +232,9 @@ public class MobileDataPreferenceControllerTest {
|
||||
|
||||
@Test
|
||||
public void updateState_notOpportunistic_enabled() {
|
||||
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||
mController.init(mFragmentManager, SUB_ID);
|
||||
doReturn(false).when(mSubscriptionInfo).isOpportunistic();
|
||||
mSubInfo1 = setupSubscriptionInfoEntity(SUB_ID_1, DISPLAY_NAME_1, false, true, true, true,
|
||||
true);
|
||||
mController.init(mFragmentManager, SUB_ID, mSubInfo1, mNetworkInfo1);
|
||||
mController.updateState(mPreference);
|
||||
|
||||
assertThat(mPreference.isEnabled()).isTrue();
|
||||
|
||||
@@ -40,6 +40,7 @@ import com.android.settings.network.CarrierConfigCache;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
@@ -47,6 +48,9 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Deprecated ToDo: b/260059444 remove it next version
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NetworkProviderBackupCallingGroupTest {
|
||||
|
||||
@@ -133,12 +137,14 @@ public class NetworkProviderBackupCallingGroupTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldShowBackupCallingForSub_invalidSubId_returnFalse() {
|
||||
assertThat(mNetworkProviderBackupCallingGroup.hasBackupCallingFeature(
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID)).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldShowBackupCallingForSub_carrierConfigIsUnavailable_returnFalse() {
|
||||
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CROSS_SIM_IMS_AVAILABLE_BOOL,
|
||||
false);
|
||||
@@ -148,6 +154,7 @@ public class NetworkProviderBackupCallingGroupTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void
|
||||
shouldShowBackupCallingForSub_crossSimDisabled_returnFalse() {
|
||||
doReturn(false).when(mNetworkProviderBackupCallingGroup).isCrossSimEnabledByPlatform(
|
||||
@@ -158,6 +165,7 @@ public class NetworkProviderBackupCallingGroupTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldBackupCallingForSub_crossSimEnabled_returnTrue() {
|
||||
doReturn(true).when(mNetworkProviderBackupCallingGroup).isCrossSimEnabledByPlatform(
|
||||
mContext, SUB_ID_1);
|
||||
|
||||
Reference in New Issue
Block a user