Snap for 11938003 from 7eac19fc3f to 24Q3-release
Change-Id: I7f3a5c7a35da6fa8a2db1ead74a1b9a064fecc6a
This commit is contained in:
@@ -7,3 +7,13 @@ flag {
|
||||
description: "Change to the new APN page."
|
||||
bug: "298906796"
|
||||
}
|
||||
|
||||
flag {
|
||||
name: "refactor_print_settings"
|
||||
namespace: "settings_experience"
|
||||
description: "Refactor the PrintSettings page."
|
||||
bug: "320076351"
|
||||
metadata {
|
||||
purpose: PURPOSE_BUGFIX
|
||||
}
|
||||
}
|
||||
|
||||
@@ -675,12 +675,6 @@
|
||||
android:title="@string/immediately_destroy_activities"
|
||||
android:summary="@string/immediately_destroy_activities_summary" />
|
||||
|
||||
<ListPreference
|
||||
android:key="app_process_limit"
|
||||
android:title="@string/app_process_limit_title"
|
||||
android:entries="@array/app_process_limit_entries"
|
||||
android:entryValues="@array/app_process_limit_values" />
|
||||
|
||||
<Preference
|
||||
android:key="background_check"
|
||||
android:fragment="com.android.settings.applications.appops.BackgroundCheckSummary"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# Default reviewers for this and subdirectories.
|
||||
beccahughes@google.com
|
||||
reemabajwa@google.com
|
||||
helenqin@google.com
|
||||
sgjerry@google.com
|
||||
@@ -7,4 +6,4 @@ leecam@google.com
|
||||
akaphle@google.com
|
||||
duqinmei@google.com
|
||||
|
||||
# Emergency approvers in case the above are not available
|
||||
# Emergency approvers in case the above are not available
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
import com.android.settingslib.R;
|
||||
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
|
||||
|
||||
public class BackgroundProcessLimitPreferenceController extends
|
||||
DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener,
|
||||
PreferenceControllerMixin {
|
||||
|
||||
private static final String APP_PROCESS_LIMIT_KEY = "app_process_limit";
|
||||
|
||||
private final String[] mListValues;
|
||||
private final String[] mListSummaries;
|
||||
|
||||
public BackgroundProcessLimitPreferenceController(Context context) {
|
||||
super(context);
|
||||
|
||||
mListValues = context.getResources().getStringArray(R.array.app_process_limit_values);
|
||||
mListSummaries = context.getResources().getStringArray(R.array.app_process_limit_entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return APP_PROCESS_LIMIT_KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
writeAppProcessLimitOptions(newValue);
|
||||
updateAppProcessLimitOptions();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updateAppProcessLimitOptions();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDeveloperOptionsSwitchDisabled() {
|
||||
super.onDeveloperOptionsSwitchDisabled();
|
||||
writeAppProcessLimitOptions(null);
|
||||
}
|
||||
|
||||
private void updateAppProcessLimitOptions() {
|
||||
try {
|
||||
final int limit = getActivityManagerService().getProcessLimit();
|
||||
int index = 0; // default
|
||||
for (int i = 0; i < mListValues.length; i++) {
|
||||
int val = Integer.parseInt(mListValues[i]);
|
||||
if (val >= limit) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final ListPreference listPreference = (ListPreference) mPreference;
|
||||
listPreference.setValue(mListValues[index]);
|
||||
listPreference.setSummary(mListSummaries[index]);
|
||||
} catch (RemoteException e) {
|
||||
// intentional no-op
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAppProcessLimitOptions(Object newValue) {
|
||||
try {
|
||||
final int limit = newValue != null ? Integer.parseInt(newValue.toString()) : -1;
|
||||
getActivityManagerService().setProcessLimit(limit);
|
||||
updateAppProcessLimitOptions();
|
||||
} catch (RemoteException e) {
|
||||
// intentional no-op
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
IActivityManager getActivityManagerService() {
|
||||
return ActivityManager.getService();
|
||||
}
|
||||
}
|
||||
@@ -740,7 +740,6 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
controllers.add(new StrictModePreferenceController(context));
|
||||
controllers.add(new ProfileGpuRenderingPreferenceController(context));
|
||||
controllers.add(new KeepActivitiesPreferenceController(context));
|
||||
controllers.add(new BackgroundProcessLimitPreferenceController(context));
|
||||
controllers.add(new CachedAppsFreezerPreferenceController(context));
|
||||
controllers.add(new ShowFirstCrashDialogPreferenceController(context));
|
||||
controllers.add(new AppsNotRespondingPreferenceController(context));
|
||||
|
||||
@@ -507,7 +507,9 @@ public class EnabledNetworkModePreferenceController extends
|
||||
}
|
||||
}
|
||||
} else if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
|
||||
if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) {
|
||||
if (mIsGlobalCdma) {
|
||||
enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
|
||||
} else if (MobileNetworkUtils.isTdscdmaSupported(mContext, mSubId)) {
|
||||
enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_TDSCDMA_CHOICES;
|
||||
} else if (!mDisplay2gOptions && !mDisplay3gOptions) {
|
||||
enabledNetworkType = mShow4gForLTE
|
||||
@@ -521,8 +523,6 @@ public class EnabledNetworkModePreferenceController extends
|
||||
: EnabledNetworks.ENABLED_NETWORKS_EXCEPT_GSM_CHOICES;
|
||||
} else if (!mLteEnabled) {
|
||||
enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_EXCEPT_LTE_CHOICES;
|
||||
} else if (mIsGlobalCdma) {
|
||||
enabledNetworkType = EnabledNetworks.ENABLED_NETWORKS_CDMA_CHOICES;
|
||||
} else {
|
||||
enabledNetworkType = mShow4gForLTE ? EnabledNetworks.ENABLED_NETWORKS_4G_CHOICES
|
||||
: EnabledNetworks.ENABLED_NETWORKS_CHOICES;
|
||||
|
||||
@@ -68,7 +68,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
|
||||
public class MobileNetworkSettings extends AbstractMobileNetworkSettings implements
|
||||
@@ -359,23 +358,17 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings impleme
|
||||
}
|
||||
|
||||
private void onSubscriptionDetailChanged() {
|
||||
if (mSubscriptionInfoEntity != null) {
|
||||
/**
|
||||
* Update the title when SIM stats got changed
|
||||
*/
|
||||
final Consumer<Activity> renameTitle = activity -> {
|
||||
if (activity != null && !activity.isFinishing()) {
|
||||
if (activity instanceof SettingsActivity) {
|
||||
((SettingsActivity) activity).setTitle(mSubscriptionInfoEntity.uniqueName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ThreadUtils.postOnMainThread(() -> {
|
||||
renameTitle.accept(getActivity());
|
||||
redrawPreferenceControllers();
|
||||
});
|
||||
final SubscriptionInfoEntity subscriptionInfoEntity = mSubscriptionInfoEntity;
|
||||
if (subscriptionInfoEntity == null) {
|
||||
return;
|
||||
}
|
||||
ThreadUtils.postOnMainThread(() -> {
|
||||
if (getActivity() instanceof SettingsActivity activity && !activity.isFinishing()) {
|
||||
// Update the title when SIM stats got changed
|
||||
activity.setTitle(subscriptionInfoEntity.uniqueName);
|
||||
}
|
||||
redrawPreferenceControllers();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.biometrics.PromptInfo;
|
||||
import android.multiuser.Flags;
|
||||
import android.os.Bundle;
|
||||
import android.os.CancellationSignal;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
@@ -149,6 +150,13 @@ public class BiometricFragment extends InstrumentedFragment {
|
||||
.setShowEmergencyCallButton(promptInfo.isShowEmergencyCallButton())
|
||||
.setReceiveSystemEvents(true)
|
||||
.setComponentNameForConfirmDeviceCredentialActivity(callingActivity);
|
||||
if (promptInfo.getLogoRes() != 0){
|
||||
promptBuilder.setLogoRes(promptInfo.getLogoRes());
|
||||
}
|
||||
String logoDescription = promptInfo.getLogoDescription();
|
||||
if (!TextUtils.isEmpty(logoDescription)) {
|
||||
promptBuilder.setLogoDescription(logoDescription);
|
||||
}
|
||||
|
||||
if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpaceFeatures()
|
||||
&& Flags.enableBiometricsToUnlockPrivateSpace()) {
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.android.settings.password;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PASSWORD_HEADER;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PATTERN_HEADER;
|
||||
import static android.app.admin.DevicePolicyResources.Strings.Settings.CONFIRM_WORK_PROFILE_PIN_HEADER;
|
||||
import static android.Manifest.permission.SET_BIOMETRIC_DIALOG_ADVANCED;
|
||||
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -31,6 +32,7 @@ import android.app.trust.TrustManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserProperties;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Color;
|
||||
@@ -44,6 +46,7 @@ import android.os.Looper;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
|
||||
@@ -65,6 +68,12 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
|
||||
private static final String TAG_BIOMETRIC_FRAGMENT = "fragment";
|
||||
|
||||
/** Use this extra value to provide a custom logo for the biometric prompt. **/
|
||||
public static final String CUSTOM_BIOMETRIC_PROMPT_LOGO_RES_ID_KEY = "custom_logo_res_id";
|
||||
/** Use this extra value to provide a custom logo description for the biometric prompt. **/
|
||||
public static final String CUSTOM_BIOMETRIC_PROMPT_LOGO_DESCRIPTION_KEY =
|
||||
"custom_logo_description";
|
||||
|
||||
public static class InternalActivity extends ConfirmDeviceCredentialActivity {
|
||||
}
|
||||
|
||||
@@ -202,6 +211,21 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
promptInfo.setDescription(mDetails);
|
||||
promptInfo.setDisallowBiometricsIfPolicyExists(mCheckDevicePolicyManager);
|
||||
|
||||
if (android.multiuser.Flags.enablePrivateSpaceFeatures()
|
||||
&& android.multiuser.Flags.usePrivateSpaceIconInBiometricPrompt()
|
||||
&& hasSetBiometricDialogAdvanced(mContext, getLaunchedFromUid())
|
||||
) {
|
||||
int iconResId = intent.getIntExtra(CUSTOM_BIOMETRIC_PROMPT_LOGO_RES_ID_KEY, 0);
|
||||
if (iconResId != 0) {
|
||||
promptInfo.setLogoRes(iconResId);
|
||||
}
|
||||
String logoDescription = intent.getStringExtra(
|
||||
CUSTOM_BIOMETRIC_PROMPT_LOGO_DESCRIPTION_KEY);
|
||||
if (!TextUtils.isEmpty(logoDescription)) {
|
||||
promptInfo.setLogoDescription(logoDescription);
|
||||
}
|
||||
}
|
||||
|
||||
final int policyType = mDevicePolicyManager.getManagedSubscriptionsPolicy().getPolicyType();
|
||||
|
||||
if (isEffectiveUserManagedProfile
|
||||
@@ -409,6 +433,14 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the calling uid has the permission to set biometric dialog icon and description.
|
||||
*/
|
||||
private static boolean hasSetBiometricDialogAdvanced(@NonNull Context context, int callingUid) {
|
||||
return context.checkPermission(SET_BIOMETRIC_DIALOG_ADVANCED, /* pid */ -1, callingUid)
|
||||
== PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
// User could be locked while Effective user is unlocked even though the effective owns the
|
||||
// credential. Otherwise, biometric can't unlock fbe/keystore through
|
||||
// verifyTiedProfileChallenge. In such case, we also wanna show the user message that
|
||||
|
||||
76
src/com/android/settings/print/PrintRepository.kt
Normal file
76
src/com/android/settings/print/PrintRepository.kt
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.print.PrintManager
|
||||
import android.printservice.PrintServiceInfo
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.spa.framework.util.mapItem
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.conflate
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class PrintRepository(private val context: Context) {
|
||||
|
||||
private val printManager = context.getSystemService(PrintManager::class.java)!!
|
||||
private val packageManager = context.packageManager
|
||||
|
||||
data class PrintServiceDisplayInfo(
|
||||
val title: String,
|
||||
val isEnabled: Boolean,
|
||||
val summary: String,
|
||||
val icon: Drawable,
|
||||
val componentName: String,
|
||||
)
|
||||
|
||||
fun printServiceDisplayInfosFlow(): Flow<List<PrintServiceDisplayInfo>> =
|
||||
printServicesFlow()
|
||||
.mapItem { printService -> printService.toPrintServiceDisplayInfo() }
|
||||
.conflate()
|
||||
.flowOn(Dispatchers.Default)
|
||||
|
||||
private fun PrintServiceInfo.toPrintServiceDisplayInfo() = PrintServiceDisplayInfo(
|
||||
title = resolveInfo.loadLabel(packageManager).toString(),
|
||||
isEnabled = isEnabled,
|
||||
summary = context.getString(
|
||||
if (isEnabled) R.string.print_feature_state_on else R.string.print_feature_state_off
|
||||
),
|
||||
icon = resolveInfo.loadIcon(packageManager),
|
||||
componentName = componentName.flattenToString(),
|
||||
)
|
||||
|
||||
private fun printServicesFlow(): Flow<List<PrintServiceInfo>> =
|
||||
printManager.printServicesChangeFlow()
|
||||
.map { printManager.getPrintServices(PrintManager.ALL_SERVICES) }
|
||||
.conflate()
|
||||
.flowOn(Dispatchers.Default)
|
||||
|
||||
private companion object {
|
||||
fun PrintManager.printServicesChangeFlow(): Flow<Unit> = callbackFlow {
|
||||
val listener = PrintManager.PrintServicesChangeListener { trySend(Unit) }
|
||||
addPrintServicesChangeListener(listener, null)
|
||||
trySend(Unit)
|
||||
awaitClose { removePrintServicesChangeListener(listener) }
|
||||
}.conflate().flowOn(Dispatchers.Default)
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.loader.app.LoaderManager.LoaderCallbacks;
|
||||
import androidx.loader.content.AsyncTaskLoader;
|
||||
@@ -54,7 +55,9 @@ import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceCategory;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.spa.SpaActivity;
|
||||
import com.android.settingslib.search.Indexable;
|
||||
import com.android.settingslib.search.SearchIndexable;
|
||||
import com.android.settingslib.widget.AppPreference;
|
||||
@@ -101,6 +104,15 @@ public class PrintSettingsFragment extends ProfileSettingsPreferenceFragment
|
||||
super(UserManager.DISALLOW_PRINTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
if (Flags.refactorPrintSettings()) {
|
||||
SpaActivity.startSpaActivity(context, PrintSettingsPageProvider.INSTANCE.getName());
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
|
||||
102
src/com/android/settings/print/PrintSettingsPageProvider.kt
Normal file
102
src/com/android/settings/print/PrintSettingsPageProvider.kt
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print
|
||||
|
||||
import android.app.settings.SettingsEnums
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.android.settings.R
|
||||
import com.android.settings.core.SubSettingLauncher
|
||||
import com.android.settings.print.PrintRepository.PrintServiceDisplayInfo
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_CHECKED
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_TITLE
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.compose.rememberDrawablePainter
|
||||
import com.android.settingslib.spa.framework.theme.SettingsDimension
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
import com.android.settingslib.spa.widget.ui.Category
|
||||
import com.android.settingslib.spaprivileged.template.common.UserProfilePager
|
||||
|
||||
object PrintSettingsPageProvider : SettingsPageProvider {
|
||||
override val name = "PrintSettings"
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = stringResource(R.string.print_settings)) {
|
||||
val context = LocalContext.current
|
||||
val printRepository = remember(context) { PrintRepository(context) }
|
||||
UserProfilePager {
|
||||
PrintServices(printRepository)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PrintServices(printRepository: PrintRepository) {
|
||||
val printServiceDisplayInfos by remember {
|
||||
printRepository.printServiceDisplayInfosFlow()
|
||||
}.collectAsStateWithLifecycle(initialValue = emptyList())
|
||||
Category(title = stringResource(R.string.print_settings_title)) {
|
||||
for (printServiceDisplayInfo in printServiceDisplayInfos) {
|
||||
PrintService(printServiceDisplayInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@Composable
|
||||
fun PrintService(displayInfo: PrintServiceDisplayInfo) {
|
||||
val context = LocalContext.current
|
||||
Preference(model = object : PreferenceModel {
|
||||
override val title = displayInfo.title
|
||||
override val summary = { displayInfo.summary }
|
||||
override val icon: @Composable () -> Unit = {
|
||||
Image(
|
||||
painter = rememberDrawablePainter(displayInfo.icon),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(SettingsDimension.appIconItemSize),
|
||||
)
|
||||
}
|
||||
override val onClick = {
|
||||
SubSettingLauncher(context).apply {
|
||||
setDestination(PrintServiceSettingsFragment::class.qualifiedName)
|
||||
setArguments(
|
||||
bundleOf(
|
||||
EXTRA_CHECKED to displayInfo.isEnabled,
|
||||
EXTRA_TITLE to displayInfo.title,
|
||||
EXTRA_SERVICE_COMPONENT_NAME to displayInfo.componentName
|
||||
)
|
||||
)
|
||||
setSourceMetricsCategory(SettingsEnums.PRINT_SETTINGS)
|
||||
}.launch()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import static android.app.admin.DevicePolicyManager.ACTION_SET_NEW_PASSWORD;
|
||||
|
||||
import static com.android.internal.app.SetScreenLockDialogActivity.LAUNCH_REASON_PRIVATE_SPACE_SETTINGS_ACCESS;
|
||||
import static com.android.settings.activityembedding.EmbeddedDeepLinkUtils.tryStartMultiPaneDeepLink;
|
||||
import static com.android.settings.password.ConfirmDeviceCredentialActivity.CUSTOM_BIOMETRIC_PROMPT_LOGO_DESCRIPTION_KEY;
|
||||
import static com.android.settings.password.ConfirmDeviceCredentialActivity.CUSTOM_BIOMETRIC_PROMPT_LOGO_RES_ID_KEY;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.KeyguardManager;
|
||||
@@ -228,6 +230,14 @@ public class PrivateSpaceAuthenticationActivity extends FragmentActivity {
|
||||
private void authenticatePrivateSpaceEntry() {
|
||||
Intent credentialIntent = mPrivateSpaceMaintainer.getPrivateProfileLockCredentialIntent();
|
||||
if (credentialIntent != null) {
|
||||
if (android.multiuser.Flags.usePrivateSpaceIconInBiometricPrompt()) {
|
||||
credentialIntent.putExtra(CUSTOM_BIOMETRIC_PROMPT_LOGO_RES_ID_KEY,
|
||||
com.android.internal.R.drawable.stat_sys_private_profile_status);
|
||||
credentialIntent.putExtra(CUSTOM_BIOMETRIC_PROMPT_LOGO_DESCRIPTION_KEY,
|
||||
getApplicationContext().getString(
|
||||
com.android.internal.R.string.private_space_biometric_prompt_title
|
||||
));
|
||||
}
|
||||
mVerifyDeviceLock.launch(credentialIntent);
|
||||
} else {
|
||||
Log.e(TAG, "verifyCredentialIntent is null even though device lock is set");
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.spa
|
||||
import android.content.Context
|
||||
import android.util.FeatureFlagUtils
|
||||
import com.android.settings.network.apn.ApnEditPageProvider
|
||||
import com.android.settings.print.PrintSettingsPageProvider
|
||||
import com.android.settings.spa.about.AboutPhonePageProvider
|
||||
import com.android.settings.spa.app.AllAppListPageProvider
|
||||
import com.android.settings.spa.app.AppsMainPageProvider
|
||||
@@ -120,6 +121,7 @@ open class SettingsSpaEnvironment(context: Context) : SpaEnvironment(context) {
|
||||
BatteryOptimizationModeAppListPageProvider,
|
||||
NetworkCellularGroupProvider(),
|
||||
WifiPrivacyPageProvider,
|
||||
PrintSettingsPageProvider,
|
||||
)
|
||||
|
||||
override val logger = if (FeatureFlagUtils.isEnabled(
|
||||
|
||||
@@ -87,12 +87,17 @@ private fun LabelSimPreference(
|
||||
}
|
||||
val phoneNumber = phoneNumber(subInfo)
|
||||
val alertDialogPresenter = rememberAlertDialogPresenter(
|
||||
confirmButton = AlertDialogButton(stringResource(R.string.mobile_network_sim_name_rename)) {
|
||||
confirmButton = AlertDialogButton(
|
||||
stringResource(R.string.mobile_network_sim_name_rename),
|
||||
titleSimName.isNotBlank()
|
||||
) {
|
||||
onboardingService.addItemForRenaming(
|
||||
subInfo, if (titleSimName.isEmpty()) originalSimCarrierName else titleSimName
|
||||
)
|
||||
},
|
||||
dismissButton = AlertDialogButton(stringResource(R.string.cancel)) {
|
||||
dismissButton = AlertDialogButton(
|
||||
stringResource(R.string.cancel),
|
||||
) {
|
||||
titleSimName = onboardingService.getSubscriptionInfoDisplayName(subInfo)
|
||||
},
|
||||
title = stringResource(R.string.sim_onboarding_label_sim_dialog_title),
|
||||
@@ -107,7 +112,7 @@ private fun LabelSimPreference(
|
||||
placeholder = {Text(text = originalSimCarrierName)},
|
||||
modifier = Modifier.fillMaxWidth().testTag("contentInput")
|
||||
) {
|
||||
titleSimName = if (it.matches(Regex("^\\s*$"))) originalSimCarrierName else it
|
||||
titleSimName = it
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
@@ -311,7 +311,9 @@ public class WifiConfigController2 implements TextWatcher,
|
||||
mHiddenSettingsSpinner = mView.findViewById(R.id.hidden_settings);
|
||||
if (!mHideMeteredAndPrivacy && mWifiManager.isConnectedMacRandomizationSupported()) {
|
||||
mPrivacySettingsSpinner = mView.findViewById(R.id.privacy_settings);
|
||||
mDhcpSettingsSpinner = mView.findViewById(R.id.dhcp_settings);
|
||||
if (Flags.androidVWifiApi()) {
|
||||
mDhcpSettingsSpinner = mView.findViewById(R.id.dhcp_settings);
|
||||
}
|
||||
mView.findViewById(R.id.privacy_settings_fields).setVisibility(View.VISIBLE);
|
||||
}
|
||||
mHiddenSettingsSpinner.setOnItemSelectedListener(this);
|
||||
|
||||
@@ -17,7 +17,7 @@ package {
|
||||
default_team: "trendy_team_android_kernel",
|
||||
}
|
||||
|
||||
android_test_helper_app {
|
||||
android_test {
|
||||
name: "test_16kb_app",
|
||||
srcs: ["test_16kb_app/src/**/*.java"],
|
||||
manifest: "test_16kb_app/test_16kb_app.xml",
|
||||
|
||||
8
tests/Enable16KbTests/TEST_MAPPING
Normal file
8
tests/Enable16KbTests/TEST_MAPPING
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"postsubmit": [
|
||||
{
|
||||
"name": "Enable16KbTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settings.development.test"
|
||||
android:sharedUserId="android.uid.systemui">
|
||||
android:installLocation="internalOnly"
|
||||
package="com.android.settings.development.test">
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
</application>
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class BackgroundProcessLimitPreferenceControllerTest {
|
||||
|
||||
@Mock
|
||||
private IActivityManager mActivityManager;
|
||||
@Mock
|
||||
private ListPreference mPreference;
|
||||
@Mock
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
/**
|
||||
* 0: Standard limit
|
||||
* 1: No Background processes
|
||||
* 2: At most 1 process
|
||||
* 3: At most 2 processes
|
||||
* 4: At most 3 processes
|
||||
* 5: At most 4 processes
|
||||
*/
|
||||
private String[] mListValues;
|
||||
private String[] mListSummaries;
|
||||
private Context mContext;
|
||||
private BackgroundProcessLimitPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mListValues = mContext.getResources()
|
||||
.getStringArray(com.android.settingslib.R.array.app_process_limit_values);
|
||||
mListSummaries = mContext.getResources()
|
||||
.getStringArray(com.android.settingslib.R.array.app_process_limit_entries);
|
||||
mController = spy(new BackgroundProcessLimitPreferenceController(mContext));
|
||||
doReturn(mActivityManager).when(mController).getActivityManagerService();
|
||||
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
|
||||
mController.displayPreference(mScreen);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_noBackgroundProcessSet_shouldSetToNoBackgroundProcess()
|
||||
throws RemoteException {
|
||||
mController.onPreferenceChange(mPreference, mListValues[1]);
|
||||
|
||||
verify(mActivityManager).setProcessLimit(Integer.valueOf(mListValues[1]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onPreferenceChange_1ProcessSet_shouldSetTo1BackgroundProcess()
|
||||
throws RemoteException {
|
||||
mController.onPreferenceChange(mPreference, mListValues[2]);
|
||||
|
||||
verify(mActivityManager).setProcessLimit(Integer.valueOf(mListValues[2]));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_noBackgroundProcessSet_shouldSetPreferenceToNoBackgroundProcess()
|
||||
throws RemoteException {
|
||||
when(mActivityManager.getProcessLimit()).thenReturn(Integer.valueOf(mListValues[1]));
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setValue(mListValues[1]);
|
||||
verify(mPreference).setSummary(mListSummaries[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_1ProcessSet_shouldSetPreference1BackgroundProcess()
|
||||
throws RemoteException {
|
||||
when(mActivityManager.getProcessLimit()).thenReturn(Integer.valueOf(mListValues[2]));
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setValue(mListValues[2]);
|
||||
verify(mPreference).setSummary(mListSummaries[2]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateState_veryHighLimit_shouldDefaultToStandardLimit() throws RemoteException {
|
||||
when(mActivityManager.getProcessLimit()).thenReturn(Integer.MAX_VALUE);
|
||||
|
||||
mController.updateState(mPreference);
|
||||
|
||||
verify(mPreference).setValue(mListValues[0]);
|
||||
verify(mPreference).setSummary(mListSummaries[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeveloperOptionsSwitchDisabled_shouldDisableAndResetPreference()
|
||||
throws RemoteException {
|
||||
mController.onDeveloperOptionsSwitchDisabled();
|
||||
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mActivityManager).setProcessLimit(-1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.print.PrintManager
|
||||
import android.printservice.PrintServiceInfo
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.spy
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PrintRepositoryTest {
|
||||
|
||||
private val printServiceInfo = PrintServiceInfo(
|
||||
/* resolveInfo = */ ResolveInfo().apply { serviceInfo = MockServiceInfo },
|
||||
/* settingsActivityName = */ "",
|
||||
/* addPrintersActivityName = */ "",
|
||||
/* advancedPrintOptionsActivityName = */ "",
|
||||
)
|
||||
|
||||
private val mockPrintManager = mock<PrintManager> {
|
||||
on { getPrintServices(PrintManager.ALL_SERVICES) } doReturn listOf(printServiceInfo)
|
||||
}
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
on { getSystemService(PrintManager::class.java) } doReturn mockPrintManager
|
||||
}
|
||||
|
||||
private val repository = PrintRepository(context)
|
||||
|
||||
@Test
|
||||
fun printServiceDisplayInfosFlow_title() = runBlocking {
|
||||
val displayInfo = repository.printServiceDisplayInfosFlow().firstWithTimeoutOrNull()!!
|
||||
.single()
|
||||
|
||||
assertThat(displayInfo.title).isEqualTo(LABEL)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun printServiceDisplayInfosFlow_isEnabled() = runBlocking {
|
||||
printServiceInfo.setIsEnabled(true)
|
||||
|
||||
val displayInfo = repository.printServiceDisplayInfosFlow().firstWithTimeoutOrNull()!!
|
||||
.single()
|
||||
|
||||
assertThat(displayInfo.isEnabled).isTrue()
|
||||
assertThat(displayInfo.summary)
|
||||
.isEqualTo(context.getString(R.string.print_feature_state_on))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun printServiceDisplayInfosFlow_notEnabled() = runBlocking {
|
||||
printServiceInfo.setIsEnabled(false)
|
||||
|
||||
val displayInfo = repository.printServiceDisplayInfosFlow().firstWithTimeoutOrNull()!!
|
||||
.single()
|
||||
|
||||
assertThat(displayInfo.isEnabled).isFalse()
|
||||
assertThat(displayInfo.summary)
|
||||
.isEqualTo(context.getString(R.string.print_feature_state_off))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun printServiceDisplayInfosFlow_componentName() = runBlocking {
|
||||
val displayInfo = repository.printServiceDisplayInfosFlow().firstWithTimeoutOrNull()!!
|
||||
.single()
|
||||
|
||||
assertThat(displayInfo.componentName).isEqualTo("$PACKAGE_NAME/$SERVICE_NAME")
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val PACKAGE_NAME = "package.name"
|
||||
const val SERVICE_NAME = "ServiceName"
|
||||
const val LABEL = "Label"
|
||||
val MockServiceInfo = mock<ServiceInfo> {
|
||||
on { loadLabel(any()) } doReturn LABEL
|
||||
on { loadIcon(any()) } doReturn mock<Drawable>()
|
||||
}.apply {
|
||||
packageName = PACKAGE_NAME
|
||||
name = SERVICE_NAME
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2024 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.print
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.isDisplayed
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settings.SettingsActivity
|
||||
import com.android.settings.print.PrintRepository.PrintServiceDisplayInfo
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_CHECKED
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_SERVICE_COMPONENT_NAME
|
||||
import com.android.settings.print.PrintSettingsFragment.EXTRA_TITLE
|
||||
import com.android.settings.print.PrintSettingsPageProvider.PrintService
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.any
|
||||
import org.mockito.kotlin.argThat
|
||||
import org.mockito.kotlin.doNothing
|
||||
import org.mockito.kotlin.spy
|
||||
import org.mockito.kotlin.verify
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class PrintSettingsPageProviderTest {
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
|
||||
doNothing().whenever(mock).startActivity(any())
|
||||
}
|
||||
|
||||
private val displayInfo = PrintServiceDisplayInfo(
|
||||
title = TITLE,
|
||||
isEnabled = true,
|
||||
summary = SUMMARY,
|
||||
icon = context.getDrawable(R.drawable.ic_settings_print)!!,
|
||||
componentName = "ComponentName",
|
||||
)
|
||||
|
||||
@Test
|
||||
fun printService_titleDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
PrintService(displayInfo)
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(TITLE).isDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun printService_summaryDisplayed() {
|
||||
composeTestRule.setContent {
|
||||
PrintService(displayInfo)
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(SUMMARY).isDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun printService_onClick() {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
PrintService(displayInfo)
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.onNodeWithText(TITLE).performClick()
|
||||
|
||||
verify(context).startActivity(argThat {
|
||||
val fragment = getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT)
|
||||
val arguments = getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS)!!
|
||||
fragment == PrintServiceSettingsFragment::class.qualifiedName &&
|
||||
arguments.getBoolean(EXTRA_CHECKED) == displayInfo.isEnabled &&
|
||||
arguments.getString(EXTRA_TITLE) == displayInfo.title &&
|
||||
arguments.getString(EXTRA_SERVICE_COMPONENT_NAME) == displayInfo.componentName
|
||||
})
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TITLE = "Title"
|
||||
const val SUMMARY = "Summary"
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.semantics.SemanticsProperties
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
@@ -186,7 +188,7 @@ class SimOnboardingLabelSimTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showDialog_clearContent_showOriginalDisplayName() {
|
||||
fun showDialog_clearContent_saveBtnIsDisabled() {
|
||||
preSetupContent()
|
||||
|
||||
composeTestRule.setContent {
|
||||
@@ -196,15 +198,12 @@ class SimOnboardingLabelSimTest {
|
||||
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
|
||||
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextClearance()
|
||||
|
||||
assertEquals(
|
||||
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
|
||||
.fetchSemanticsNode()
|
||||
.config[SemanticsProperties.EditableText].text, DISPLAY_NAME_1
|
||||
)
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.mobile_network_sim_name_rename))
|
||||
.assertIsNotEnabled()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showDialog_modifyContent_showModifiedDisplayName() {
|
||||
fun showDialog_modifyContent_showAndSaveModifiedDisplayName() {
|
||||
val inputData = "input_data"
|
||||
preSetupContent()
|
||||
|
||||
@@ -232,7 +231,7 @@ class SimOnboardingLabelSimTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun showDialog_onlySpaceCharContent_showAndSaveOriginalDisplayName() {
|
||||
fun showDialog_onlySpaceCharContent_saveBtnIsDisabled() {
|
||||
val spaceChars = " ";
|
||||
preSetupContent()
|
||||
|
||||
@@ -241,30 +240,12 @@ class SimOnboardingLabelSimTest {
|
||||
}
|
||||
|
||||
// Simulate real operation,
|
||||
// 1. Click preference of DISPLAY_NAME_1
|
||||
composeTestRule.onNodeWithText(DISPLAY_NAME_1).performClick()
|
||||
// 2. Input space chars to EditText view
|
||||
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextClearance()
|
||||
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT).performTextInput(spaceChars)
|
||||
// 3. Remove the string of DISPLAY_NAME_1 from EditText view
|
||||
repeat(DISPLAY_NAME_1.length) {
|
||||
composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
|
||||
.performKeyPress(KeyEvent(NativeKeyEvent(ACTION_DOWN, KEYCODE_FORWARD_DEL)))
|
||||
}
|
||||
|
||||
// Due to this TextField with Text and EditText, it need fetch correct node to get correct
|
||||
// content.
|
||||
assertEquals(
|
||||
DISPLAY_NAME_1, composeTestRule.onNodeWithTag(TEXT_FIELD_INPUT)
|
||||
.fetchSemanticsNode()
|
||||
.config[SemanticsProperties.EditableText].text
|
||||
)
|
||||
|
||||
// Click save button
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.mobile_network_sim_name_rename))
|
||||
.performClick()
|
||||
|
||||
// Check preference's name is still DISPLAY_NAME_1
|
||||
composeTestRule.onNodeWithText(DISPLAY_NAME_1).assertExists()
|
||||
.assertIsNotEnabled()
|
||||
}
|
||||
|
||||
fun preSetupContent() {
|
||||
|
||||
Reference in New Issue
Block a user