Snap for 9321750 from 66284b5528 to udc-release
Change-Id: Ia826bdc12209da07090151f8610b177cc3dd1137
This commit is contained in:
@@ -125,6 +125,7 @@
|
||||
<uses-permission android:name="android.permission.READ_SAFETY_CENTER_STATUS" />
|
||||
<uses-permission android:name="android.permission.SEND_SAFETY_CENTER_UPDATE" />
|
||||
<uses-permission android:name="android.permission.START_VIEW_APP_FEATURES" />
|
||||
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_QUICK_AFFORDANCES" />
|
||||
|
||||
<application
|
||||
android:name=".SettingsApplication"
|
||||
|
||||
@@ -615,6 +615,9 @@
|
||||
<item>android.uid.system:1000</item>
|
||||
</string-array>
|
||||
|
||||
<!-- The default value for RedactionInterstitial in SUW -->
|
||||
<bool name="default_allow_sensitive_lockscreen_content">true</bool>
|
||||
|
||||
<!-- Whether to enable the app battery usage list page feature. -->
|
||||
<bool name="config_app_battery_usage_list_enabled">false</bool>
|
||||
|
||||
|
||||
@@ -10486,8 +10486,8 @@
|
||||
<!-- Title for the button to reboot with MTE enabled. [CHAR LIMIT=NONE] -->
|
||||
<string name="reboot_with_mte_title">Reboot with MTE</string>
|
||||
<string name="reboot_with_mte_message">System will reboot and allow to experiment with Memory Tagging Extension (MTE). MTE may negatively impact system performance and stability. Will be reset on next subsequent reboot.</string>
|
||||
<string name="reboot_with_mte_summary">Try MTE for a single boot for app development.</string>
|
||||
<string name="reboot_with_mte_already_enabled">MTE is enabled through Advanced memory protection.</string>
|
||||
<string name="reboot_with_mte_summary">Try MTE for a single boot for app development</string>
|
||||
<string name="reboot_with_mte_already_enabled">MTE is enabled through Advanced memory protection</string>
|
||||
<!-- Toast that is shown when the user initiates capturing a heap dump for the system server. [CHAR LIMIT=NONE] -->
|
||||
<string name="capturing_system_heap_dump_message">Capturing system heap dump</string>
|
||||
<!-- Toast that is shown if there's an error capturing the user initiated heap dump. [CHAR LIMIT=NONE] -->
|
||||
@@ -10627,6 +10627,14 @@
|
||||
<string name="lockscreen_double_line_clock_summary">Show double-line clock when available</string>
|
||||
<!-- Lockscreen double-line clock toggle [CHAR LIMIT=60] -->
|
||||
<string name="lockscreen_double_line_clock_setting_toggle">Double-line clock</string>
|
||||
<!-- Lock screen buttons preference [CHAR LIMIT=60] -->
|
||||
<string name="lockscreen_quick_affordances_title">Buttons</string>
|
||||
<!-- Summary for the lock screen button preference [CHAR LIMIT=60] -->
|
||||
<plurals name="lockscreen_quick_affordances_summary">
|
||||
<item quantity="zero">None</item>
|
||||
<item quantity="one"><xliff:g id="first">%1$s</xliff:g></item>
|
||||
<item quantity="other"><xliff:g id="first">%1$s</xliff:g>, <xliff:g id="second">%2$s</xliff:g></item>
|
||||
</plurals>
|
||||
|
||||
<!-- Title for RTT setting. [CHAR LIMIT=NONE] -->
|
||||
<string name="rtt_settings_title"></string>
|
||||
|
||||
@@ -69,6 +69,11 @@
|
||||
android:summary="@string/lockscreen_trivial_controls_summary"
|
||||
settings:controller="com.android.settings.display.ControlsTrivialPrivacyPreferenceController"/>
|
||||
|
||||
<Preference
|
||||
android:key="customizable_lock_screen_quick_affordances"
|
||||
android:title="@string/lockscreen_quick_affordances_title"
|
||||
settings:controller="com.android.settings.display.CustomizableLockScreenQuickAffordancesPreferenceController" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="lockscreen_double_line_clock_switch"
|
||||
android:title="@string/lockscreen_double_line_clock_setting_toggle"
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.annotation.UiThread;
|
||||
import android.app.Activity;
|
||||
import android.app.KeyguardManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.settings.SettingsEnums;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -68,7 +67,7 @@ import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.app.UnlaunchableAppActivity;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.TrustedCredentialsSettings.Tab;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settingslib.core.lifecycle.ObservableFragment;
|
||||
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.X509Certificate;
|
||||
@@ -81,7 +80,7 @@ import java.util.function.IntConsumer;
|
||||
/**
|
||||
* Fragment to display trusted credentials settings for one tab.
|
||||
*/
|
||||
public class TrustedCredentialsFragment extends InstrumentedFragment
|
||||
public class TrustedCredentialsFragment extends ObservableFragment
|
||||
implements TrustedCredentialsDialogBuilder.DelegateInterface {
|
||||
|
||||
public static final String ARG_POSITION = "tab";
|
||||
@@ -176,11 +175,6 @@ public class TrustedCredentialsFragment extends InstrumentedFragment
|
||||
return mFragmentView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.TRUSTED_CREDENTIALS;
|
||||
}
|
||||
|
||||
private void createChildView(
|
||||
LayoutInflater inflater, ViewGroup parent, Bundle childState, int i) {
|
||||
boolean isWork = mGroupAdapter.getUserInfoByGroup(i).isManagedProfile();
|
||||
|
||||
@@ -113,7 +113,7 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return SettingsEnums.SYSTEM_ALERT_WINDOW_APPS;
|
||||
return SettingsEnums.MODIFY_SYSTEM_SETTINGS;
|
||||
}
|
||||
|
||||
public static CharSequence getSummary(Context context, AppEntry entry) {
|
||||
|
||||
@@ -527,7 +527,7 @@ public class ManageApplications extends InstrumentedFragment
|
||||
case LIST_TYPE_OVERLAY:
|
||||
return SettingsEnums.SYSTEM_ALERT_WINDOW_APPS;
|
||||
case LIST_TYPE_WRITE_SETTINGS:
|
||||
return SettingsEnums.SYSTEM_ALERT_WINDOW_APPS;
|
||||
return SettingsEnums.MODIFY_SYSTEM_SETTINGS;
|
||||
case LIST_TYPE_MANAGE_SOURCES:
|
||||
return SettingsEnums.MANAGE_EXTERNAL_SOURCES;
|
||||
case LIST_TYPE_WIFI_ACCESS:
|
||||
|
||||
@@ -62,6 +62,11 @@ public class ControlsPrivacyPreferenceController extends TogglePreferenceControl
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
// hide if we should use customizable lock screen quick affordances
|
||||
if (CustomizableLockScreenUtils.isFeatureEnabled(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
// hide if lockscreen isn't secure for this user
|
||||
return isEnabled() && isSecure() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,10 @@ public class ControlsTrivialPrivacyPreferenceController extends TogglePreference
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (CustomizableLockScreenUtils.isFeatureEnabled(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
return showDeviceControlsSettingsEnabled() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.display;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.PreferenceControllerMixin;
|
||||
|
||||
/**
|
||||
* Preference for accessing an experience to customize lock screen quick affordances.
|
||||
*/
|
||||
public class CustomizableLockScreenQuickAffordancesPreferenceController extends
|
||||
BasePreferenceController implements PreferenceControllerMixin {
|
||||
|
||||
public CustomizableLockScreenQuickAffordancesPreferenceController(Context context, String key) {
|
||||
super(context, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
return CustomizableLockScreenUtils.isFeatureEnabled(mContext)
|
||||
? AVAILABLE
|
||||
: UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
final Preference preference = screen.findPreference(getPreferenceKey());
|
||||
if (preference != null) {
|
||||
preference.setOnPreferenceClickListener(preference1 -> {
|
||||
// TODO(b/258471384): open the buttons destination within wallpaper picker.
|
||||
final Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
|
||||
final String packageName =
|
||||
mContext.getString(R.string.config_wallpaper_picker_package);
|
||||
if (!TextUtils.isEmpty(packageName)) {
|
||||
intent.setPackage(packageName);
|
||||
}
|
||||
mContext.startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
refreshSummary(preference);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getSummary() {
|
||||
return CustomizableLockScreenUtils.getQuickAffordanceSummary(mContext);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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.display;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Utilities for display settings related to customizable lock screen features. */
|
||||
public final class CustomizableLockScreenUtils {
|
||||
|
||||
private static final String TAG = "CustomizableLockScreenUtils";
|
||||
private static final Uri BASE_URI = new Uri.Builder()
|
||||
.scheme(ContentResolver.SCHEME_CONTENT)
|
||||
.authority("com.android.systemui.keyguard.quickaffordance")
|
||||
.build();
|
||||
@VisibleForTesting
|
||||
static final Uri FLAGS_URI = BASE_URI.buildUpon()
|
||||
.path("flags")
|
||||
.build();
|
||||
@VisibleForTesting
|
||||
static final Uri SELECTIONS_URI = BASE_URI.buildUpon()
|
||||
.path("selections")
|
||||
.build();
|
||||
@VisibleForTesting
|
||||
static final String NAME = "name";
|
||||
@VisibleForTesting
|
||||
static final String VALUE = "value";
|
||||
@VisibleForTesting
|
||||
static final String ENABLED_FLAG = "is_feature_enabled";
|
||||
@VisibleForTesting
|
||||
static final String AFFORDANCE_NAME = "affordance_name";
|
||||
|
||||
private CustomizableLockScreenUtils() {}
|
||||
|
||||
/**
|
||||
* Queries and returns whether the customizable lock screen quick affordances feature is enabled
|
||||
* on the device.
|
||||
*
|
||||
* <p>This is a slow, blocking call that shouldn't be made on the main thread.
|
||||
*/
|
||||
public static boolean isFeatureEnabled(Context context) {
|
||||
try (Cursor cursor = context.getContentResolver().query(
|
||||
FLAGS_URI,
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor == null) {
|
||||
Log.w(TAG, "Cursor was null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
final int indexOfNameColumn = cursor.getColumnIndex(NAME);
|
||||
final int indexOfValueColumn = cursor.getColumnIndex(VALUE);
|
||||
if (indexOfNameColumn == -1 || indexOfValueColumn == -1) {
|
||||
Log.w(TAG, "Cursor doesn't contain " + NAME + " or " + VALUE + "!");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
final String name = cursor.getString(indexOfNameColumn);
|
||||
final int value = cursor.getInt(indexOfValueColumn);
|
||||
if (TextUtils.equals(ENABLED_FLAG, name)) {
|
||||
Log.d(TAG, ENABLED_FLAG + "=" + value);
|
||||
return value == 1;
|
||||
}
|
||||
}
|
||||
|
||||
Log.w(TAG, "Flag with name \"" + ENABLED_FLAG + "\" not found!");
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception while querying quick affordance content provider", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries and returns a summary text for the currently-selected lock screen quick affordances.
|
||||
*
|
||||
* <p>This is a slow, blocking call that shouldn't be made on the main thread.
|
||||
*/
|
||||
@Nullable
|
||||
public static CharSequence getQuickAffordanceSummary(Context context) {
|
||||
try (Cursor cursor = context.getContentResolver().query(
|
||||
SELECTIONS_URI,
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor == null) {
|
||||
Log.w(TAG, "Cursor was null!");
|
||||
return null;
|
||||
}
|
||||
|
||||
final int columnIndex = cursor.getColumnIndex(AFFORDANCE_NAME);
|
||||
if (columnIndex == -1) {
|
||||
Log.w(TAG, "Cursor doesn't contain \"" + AFFORDANCE_NAME + "\" column!");
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<String> affordanceNames = new ArrayList<>(cursor.getCount());
|
||||
while (cursor.moveToNext()) {
|
||||
final String affordanceName = cursor.getString(columnIndex);
|
||||
if (!TextUtils.isEmpty(affordanceName)) {
|
||||
affordanceNames.add(affordanceName);
|
||||
}
|
||||
}
|
||||
|
||||
// We don't display more than the first two items.
|
||||
final int usableAffordanceNameCount = Math.min(2, affordanceNames.size());
|
||||
final List<String> arguments = new ArrayList<>(usableAffordanceNameCount);
|
||||
if (!affordanceNames.isEmpty()) {
|
||||
arguments.add(affordanceNames.get(0));
|
||||
}
|
||||
if (affordanceNames.size() > 1) {
|
||||
arguments.add(affordanceNames.get(1));
|
||||
}
|
||||
|
||||
return context.getResources().getQuantityString(
|
||||
R.plurals.lockscreen_quick_affordances_summary,
|
||||
usableAffordanceNameCount,
|
||||
arguments.toArray());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception while querying quick affordance content provider", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,6 +87,10 @@ public class QRCodeScannerPreferenceController extends TogglePreferenceControlle
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (CustomizableLockScreenUtils.isFeatureEnabled(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
return isScannerActivityAvailable() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ public class WalletPrivacyPreferenceController extends TogglePreferenceControlle
|
||||
|
||||
@Override
|
||||
public int getAvailabilityStatus() {
|
||||
if (CustomizableLockScreenUtils.isFeatureEnabled(mContext)) {
|
||||
return UNSUPPORTED_ON_DEVICE;
|
||||
}
|
||||
|
||||
return isEnabled() && isSecure() ? AVAILABLE : DISABLED_DEPENDENT_SETTING;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
|
||||
import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -142,29 +141,6 @@ public class BatteryTipDialogFragment extends InstrumentedDialogFragment impleme
|
||||
.setPositiveButton(R.string.battery_tip_unrestrict_app_dialog_ok, this)
|
||||
.setNegativeButton(R.string.battery_tip_unrestrict_app_dialog_cancel, null)
|
||||
.create();
|
||||
case BatteryTip.TipType.BATTERY_DEFENDER:
|
||||
mMetricsFeatureProvider.action(context,
|
||||
SettingsEnums.ACTION_TIP_BATTERY_DEFENDER, mMetricsKey);
|
||||
final double chargeLimitLevel = 0.8f;
|
||||
final String percentage =
|
||||
NumberFormat.getPercentInstance().format(chargeLimitLevel);
|
||||
final String message = context.getString(
|
||||
R.string.battery_tip_limited_temporarily_dialog_msg, percentage);
|
||||
final boolean isPluggedIn = isPluggedIn();
|
||||
final AlertDialog.Builder dialogBuilder =
|
||||
new AlertDialog.Builder(context)
|
||||
.setTitle(R.string.battery_tip_limited_temporarily_title)
|
||||
.setMessage(message);
|
||||
if (isPluggedIn) {
|
||||
dialogBuilder
|
||||
.setPositiveButton(
|
||||
R.string.battery_tip_limited_temporarily_dialog_resume_charge,
|
||||
this)
|
||||
.setNegativeButton(R.string.okay, null);
|
||||
} else {
|
||||
dialogBuilder.setPositiveButton(R.string.okay, null);
|
||||
}
|
||||
return dialogBuilder.create();
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown type " + mBatteryTip.getType());
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.fuelgauge.batterytip.actions;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
/**
|
||||
* Action to open the Support Center article
|
||||
*/
|
||||
public class BatteryDefenderAction extends BatteryTipAction {
|
||||
private SettingsActivity mSettingsActivity;
|
||||
|
||||
public BatteryDefenderAction(SettingsActivity settingsActivity) {
|
||||
super(settingsActivity.getApplicationContext());
|
||||
mSettingsActivity = settingsActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePositiveAction(int metricsKey) {
|
||||
final Intent intent = FeatureFactory.getFactory(mContext)
|
||||
.getPowerUsageFeatureProvider(mContext).getResumeChargeIntent();
|
||||
if (intent != null) {
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,13 +189,16 @@ public class RedactionInterstitial extends SettingsActivity {
|
||||
}
|
||||
|
||||
private void loadFromSettings() {
|
||||
final boolean showUnRedactedDefault = getContext().getResources().getBoolean(
|
||||
R.bool.default_allow_sensitive_lockscreen_content);
|
||||
final boolean managedProfile = UserManager.get(getContext()).isManagedProfile(mUserId);
|
||||
// Hiding all notifications is device-wide setting, managed profiles can only set
|
||||
// whether their notifications are show in full or redacted.
|
||||
final boolean showNotifications = managedProfile || Settings.Secure.getIntForUser(
|
||||
getContentResolver(), LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, mUserId) != 0;
|
||||
final boolean showUnredacted = Settings.Secure.getIntForUser(
|
||||
getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 1, mUserId) != 0;
|
||||
getContentResolver(), LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
|
||||
showUnRedactedDefault ? 1 : 0, mUserId) != 0;
|
||||
|
||||
int checkedButtonId = R.id.hide_all;
|
||||
if (showNotifications) {
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.display;
|
||||
|
||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.MatrixCursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class CustomizableLockScreenQuickAffordancesPreferenceControllerTest {
|
||||
|
||||
private static final String KEY = "key";
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private ContentResolver mContentResolver;
|
||||
|
||||
private CustomizableLockScreenQuickAffordancesPreferenceController mUnderTest;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mContext.getContentResolver()).thenReturn(mContentResolver);
|
||||
when(mContext.getResources())
|
||||
.thenReturn(ApplicationProvider.getApplicationContext().getResources());
|
||||
|
||||
mUnderTest = new CustomizableLockScreenQuickAffordancesPreferenceController(mContext, KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_whenEnabled() {
|
||||
setEnabled(true);
|
||||
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(AVAILABLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAvailabilityStatus_whenNotEnabled() {
|
||||
setEnabled(false);
|
||||
|
||||
assertThat(mUnderTest.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayPreference_click() {
|
||||
setSelectedAffordanceNames("one", "two");
|
||||
final PreferenceScreen screen = mock(PreferenceScreen.class);
|
||||
final Preference preference = mock(Preference.class);
|
||||
when(screen.findPreference(KEY)).thenReturn(preference);
|
||||
|
||||
mUnderTest.displayPreference(screen);
|
||||
|
||||
final ArgumentCaptor<Preference.OnPreferenceClickListener> clickCaptor =
|
||||
ArgumentCaptor.forClass(Preference.OnPreferenceClickListener.class);
|
||||
verify(preference).setOnPreferenceClickListener(clickCaptor.capture());
|
||||
|
||||
clickCaptor.getValue().onPreferenceClick(preference);
|
||||
|
||||
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
|
||||
verify(preference).setOnPreferenceClickListener(clickCaptor.capture());
|
||||
verify(mContext).startActivity(intentCaptor.capture());
|
||||
assertThat(intentCaptor.getValue().getPackage()).isEqualTo(
|
||||
mContext.getString(R.string.config_wallpaper_picker_package));
|
||||
assertThat(intentCaptor.getValue().getAction()).isEqualTo(Intent.ACTION_SET_WALLPAPER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_whenNoneAreSelected() {
|
||||
setSelectedAffordanceNames();
|
||||
|
||||
assertThat(mUnderTest.getSummary()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_whenOneIsSelected() {
|
||||
setSelectedAffordanceNames("one");
|
||||
|
||||
assertThat(TextUtils.equals(mUnderTest.getSummary(), "one")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSummary_whenTwoAreSelected() {
|
||||
setSelectedAffordanceNames("one", "two");
|
||||
|
||||
assertThat(TextUtils.equals(mUnderTest.getSummary(), "one, two")).isTrue();
|
||||
}
|
||||
|
||||
private void setEnabled(boolean isEnabled) {
|
||||
final MatrixCursor cursor = new MatrixCursor(
|
||||
new String[] {
|
||||
CustomizableLockScreenUtils.NAME,
|
||||
CustomizableLockScreenUtils.VALUE
|
||||
});
|
||||
cursor.addRow(new Object[] { CustomizableLockScreenUtils.ENABLED_FLAG, isEnabled ? 1 : 0 });
|
||||
when(
|
||||
mContentResolver.query(
|
||||
CustomizableLockScreenUtils.FLAGS_URI, null, null, null))
|
||||
.thenReturn(cursor);
|
||||
}
|
||||
|
||||
private void setSelectedAffordanceNames(String... affordanceNames) {
|
||||
final MatrixCursor cursor = new MatrixCursor(
|
||||
new String[] { CustomizableLockScreenUtils.AFFORDANCE_NAME });
|
||||
for (final String name : affordanceNames) {
|
||||
cursor.addRow(new Object[] { name });
|
||||
}
|
||||
|
||||
when(
|
||||
mContentResolver.query(
|
||||
CustomizableLockScreenUtils.SELECTIONS_URI, null, null, null))
|
||||
.thenReturn(cursor);
|
||||
}
|
||||
}
|
||||
@@ -244,20 +244,4 @@ public class BatteryTipDialogFragmentTest {
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getText(R.string.battery_tip_dialog_summary_message));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCreateDialog_defenderTip_fireDialog() {
|
||||
mDialogFragment = BatteryTipDialogFragment.newInstance(mDefenderTip, METRICS_KEY);
|
||||
|
||||
FragmentController.setupFragment(mDialogFragment, FragmentActivity.class,
|
||||
0 /* containerViewId */, null /* bundle */);
|
||||
|
||||
final AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||
ShadowAlertDialogCompat shadowDialog = ShadowAlertDialogCompat.shadowOf(dialog);
|
||||
|
||||
assertThat(shadowDialog.getTitle()).isEqualTo(
|
||||
mContext.getString(R.string.battery_tip_limited_temporarily_title));
|
||||
assertThat(shadowDialog.getMessage()).isEqualTo(
|
||||
mContext.getString(R.string.battery_tip_limited_temporarily_dialog_msg, "80%"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.widget.RadioButton;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.RestrictedRadioButton;
|
||||
import com.android.settings.notification.RedactionInterstitial.RedactionInterstitialFragment;
|
||||
import com.android.settings.testutils.shadow.SettingsShadowResources;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
@@ -38,6 +39,7 @@ import org.robolectric.shadows.ShadowUserManager;
|
||||
@Config(shadows = {
|
||||
ShadowUtils.class,
|
||||
ShadowRestrictedLockUtilsInternal.class,
|
||||
SettingsShadowResources.class,
|
||||
})
|
||||
public class RedactionInterstitialTest {
|
||||
private RedactionInterstitial mActivity;
|
||||
@@ -134,6 +136,28 @@ public class RedactionInterstitialTest {
|
||||
assertSelectedButton(R.id.redact_sensitive);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultShowSensitiveContent_configDeny() {
|
||||
final ContentResolver resolver = RuntimeEnvironment.application.getContentResolver();
|
||||
Settings.Secure.putIntForUser(resolver,
|
||||
LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, UserHandle.myUserId());
|
||||
setupConfig(false);
|
||||
setupActivity();
|
||||
|
||||
assertSelectedButton(R.id.redact_sensitive);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultShowSensitiveContent_configAllow() {
|
||||
final ContentResolver resolver = RuntimeEnvironment.application.getContentResolver();
|
||||
Settings.Secure.putIntForUser(resolver,
|
||||
LOCK_SCREEN_SHOW_NOTIFICATIONS, 1, UserHandle.myUserId());
|
||||
setupConfig(true);
|
||||
setupActivity();
|
||||
|
||||
assertSelectedButton(R.id.show_all);
|
||||
}
|
||||
|
||||
private void setupActivity() {
|
||||
mActivity = buildActivity(RedactionInterstitial.class, new Intent()).setup().get();
|
||||
mFragment = (RedactionInterstitialFragment)
|
||||
@@ -142,6 +166,11 @@ public class RedactionInterstitialTest {
|
||||
assertThat(mFragment).isNotNull();
|
||||
}
|
||||
|
||||
private void setupConfig(boolean allowSensitiveContent) {
|
||||
SettingsShadowResources.overrideResource(
|
||||
R.bool.default_allow_sensitive_lockscreen_content, allowSensitiveContent);
|
||||
}
|
||||
|
||||
private void setupSettings(int show, int showUnredacted) {
|
||||
final ContentResolver resolver = RuntimeEnvironment.application.getContentResolver();
|
||||
Settings.Secure.putIntForUser(resolver,
|
||||
|
||||
@@ -30,13 +30,11 @@ android_test {
|
||||
|
||||
static_libs: [
|
||||
"Settings-core",
|
||||
"SpaLibTestUtils",
|
||||
"androidx.compose.runtime_runtime",
|
||||
"androidx.compose.ui_ui-test-junit4",
|
||||
"androidx.compose.ui_ui-test-manifest",
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.runner",
|
||||
"mockito-target-extended-minus-junit4",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
jni_libs: [
|
||||
"libdexmakerjvmtiagent",
|
||||
|
||||
@@ -30,6 +30,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
@@ -38,6 +39,8 @@ import androidx.core.os.bundleOf
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import com.android.settingslib.spaprivileged.model.app.userId
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
@@ -140,7 +143,7 @@ class AppAllServicesPreferenceTest {
|
||||
|
||||
setContent()
|
||||
|
||||
composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(SUMMARY))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,6 +152,7 @@ class AppAllServicesPreferenceTest {
|
||||
|
||||
setContent()
|
||||
composeTestRule.onRoot().performClick()
|
||||
composeTestRule.delay()
|
||||
|
||||
val intentCaptor = ArgumentCaptor.forClass(Intent::class.java)
|
||||
verify(context).startActivityAsUser(intentCaptor.capture(), eq(APP.userHandle))
|
||||
|
||||
@@ -31,8 +31,8 @@ import androidx.compose.ui.test.onRoot
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.testutils.delay
|
||||
import com.android.settingslib.applications.AppUtils
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import org.junit.After
|
||||
|
||||
@@ -30,7 +30,6 @@ import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.printToLog
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
@@ -39,9 +38,9 @@ import com.android.settings.R
|
||||
import com.android.settings.Utils
|
||||
import com.android.settings.applications.appinfo.AppInfoDashboardFragment
|
||||
import com.android.settings.datausage.AppDataUsage
|
||||
import com.android.settings.testutils.waitUntilExists
|
||||
import com.android.settingslib.net.NetworkCycleDataForUid
|
||||
import com.android.settingslib.net.NetworkCycleDataForUidLoader
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@@ -134,9 +133,7 @@ class AppDataUsagePreferenceTest {
|
||||
|
||||
setContent()
|
||||
|
||||
composeTestRule.onRoot().printToLog("AAA")
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.no_data_usage))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(context.getString(R.string.no_data_usage)))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -61,7 +61,7 @@ class AppDisableButtonTest {
|
||||
private lateinit var devicePolicyManager: DevicePolicyManager
|
||||
|
||||
private val fakeFeatureFactory = FakeFeatureFactory()
|
||||
private val appFeatureProvider = fakeFeatureFactory.applicationFeatureProvider
|
||||
private val appFeatureProvider = fakeFeatureFactory.mockApplicationFeatureProvider
|
||||
|
||||
private lateinit var appDisableButton: AppDisableButton
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Utils
|
||||
import com.android.settings.applications.AppStoreUtil
|
||||
import com.android.settings.testutils.waitUntilExists
|
||||
import com.android.settingslib.applications.AppUtils
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import com.android.settingslib.spaprivileged.framework.common.userManager
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import org.junit.After
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
@@ -36,6 +37,8 @@ import com.android.settings.applications.AppInfoBase
|
||||
import com.android.settings.applications.AppLocaleUtil
|
||||
import com.android.settings.applications.appinfo.AppLocaleDetails
|
||||
import com.android.settings.localepicker.AppLocalePickerActivity
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
@@ -103,15 +106,16 @@ class AppLocalePreferenceTest {
|
||||
|
||||
composeTestRule.onNodeWithText(context.getString(R.string.app_locale_preference_title))
|
||||
.assertIsDisplayed()
|
||||
composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(SUMMARY))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenCanDisplayLocalUi_click_startsActivity() {
|
||||
fun whenCanDisplayLocalUi_click_startActivity() {
|
||||
doNothing().`when`(context).startActivityAsUser(any(), any())
|
||||
|
||||
setContent()
|
||||
composeTestRule.onRoot().performClick()
|
||||
composeTestRule.delay()
|
||||
|
||||
val intentCaptor = ArgumentCaptor.forClass(Intent::class.java)
|
||||
verify(context).startActivityAsUser(intentCaptor.capture(), eq(APP.userHandle))
|
||||
|
||||
@@ -29,18 +29,14 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotEnabled
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.printToLog
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.R
|
||||
import com.android.settings.testutils.waitUntilExists
|
||||
import com.android.settingslib.applications.AppUtils
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spaprivileged.model.app.userHandle
|
||||
import com.android.settingslib.spaprivileged.model.app.userId
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
@@ -49,7 +45,6 @@ import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.any
|
||||
import org.mockito.Mockito.eq
|
||||
@@ -135,6 +130,7 @@ class AppSettingsPreferenceTest {
|
||||
|
||||
setContent()
|
||||
composeTestRule.onRoot().performClick()
|
||||
composeTestRule.delay()
|
||||
|
||||
val intentCaptor = ArgumentCaptor.forClass(Intent::class.java)
|
||||
verify(context).startActivityAsUser(intentCaptor.capture(), eq(APP.userHandle))
|
||||
|
||||
@@ -63,7 +63,7 @@ class AppTimeSpentPreferenceTest {
|
||||
private lateinit var packageManager: PackageManager
|
||||
|
||||
private val fakeFeatureFactory = FakeFeatureFactory()
|
||||
private val appFeatureProvider = fakeFeatureFactory.applicationFeatureProvider
|
||||
private val appFeatureProvider = fakeFeatureFactory.mockApplicationFeatureProvider
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
||||
@@ -24,10 +24,6 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
@@ -37,7 +33,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.R
|
||||
import com.android.settings.Utils
|
||||
import com.android.settings.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.onDialogText
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
@@ -141,18 +138,14 @@ class InstantAppDomainsPreferenceTest {
|
||||
composeTestRule.onRoot().performClick()
|
||||
composeTestRule.delay()
|
||||
|
||||
assertDialogHasText(context.getString(R.string.app_launch_supported_domain_urls_title))
|
||||
assertDialogHasText("abc")
|
||||
assertDialogHasText("def")
|
||||
composeTestRule.onDialogText(
|
||||
context.getString(R.string.app_launch_supported_domain_urls_title)
|
||||
).assertIsDisplayed()
|
||||
composeTestRule.onDialogText("abc").assertIsDisplayed()
|
||||
composeTestRule.onDialogText("def").assertIsDisplayed()
|
||||
}
|
||||
|
||||
private fun assertDialogHasText(text: String) {
|
||||
composeTestRule.onAllNodes(hasAnyAncestor(isDialog()))
|
||||
.filterToOne(hasText(text))
|
||||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
private fun setContent(app:ApplicationInfo = INSTANT_APP) {
|
||||
private fun setContent(app: ApplicationInfo = INSTANT_APP) {
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
InstantAppDomainsPreference(app)
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsEnabled
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.hasText
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.onRoot
|
||||
@@ -34,6 +35,8 @@ import com.android.dx.mockito.inline.extended.ExtendedMockito
|
||||
import com.android.settings.R
|
||||
import com.android.settings.applications.appinfo.AppInfoDashboardFragment
|
||||
import com.android.settings.applications.specialaccess.interactacrossprofiles.InteractAcrossProfilesDetails
|
||||
import com.android.settingslib.spa.testutils.delay
|
||||
import com.android.settingslib.spa.testutils.waitUntilExists
|
||||
import com.android.settingslib.spaprivileged.framework.common.crossProfileApps
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
@@ -110,7 +113,7 @@ class InteractAcrossProfilesDetailsPreferenceTest {
|
||||
|
||||
setContent()
|
||||
|
||||
composeTestRule.onNodeWithText(SUMMARY).assertIsDisplayed()
|
||||
composeTestRule.waitUntilExists(hasText(SUMMARY))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,6 +122,7 @@ class InteractAcrossProfilesDetailsPreferenceTest {
|
||||
|
||||
setContent()
|
||||
composeTestRule.onRoot().performClick()
|
||||
composeTestRule.delay()
|
||||
|
||||
ExtendedMockito.verify {
|
||||
AppInfoDashboardFragment.startAppInfoFragment(
|
||||
|
||||
@@ -1,33 +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.testutils
|
||||
|
||||
import androidx.compose.ui.test.ComposeTimeoutException
|
||||
import androidx.compose.ui.test.SemanticsMatcher
|
||||
import androidx.compose.ui.test.junit4.ComposeContentTestRule
|
||||
|
||||
/** Blocks until the found a semantics node that match the given condition. */
|
||||
fun ComposeContentTestRule.waitUntilExists(matcher: SemanticsMatcher) = waitUntil {
|
||||
onAllNodes(matcher).fetchSemanticsNodes().isNotEmpty()
|
||||
}
|
||||
|
||||
/** Blocks until the timeout is reached. */
|
||||
fun ComposeContentTestRule.delay(timeoutMillis: Long = 1_000) = try {
|
||||
waitUntil(timeoutMillis) { false }
|
||||
} catch (_: ComposeTimeoutException) {
|
||||
// Expected
|
||||
}
|
||||
@@ -51,7 +51,9 @@ import org.mockito.Mockito.mock
|
||||
|
||||
class FakeFeatureFactory : FeatureFactory() {
|
||||
|
||||
val applicationFeatureProvider: ApplicationFeatureProvider =
|
||||
private val mockMetricsFeatureProvider: MetricsFeatureProvider =
|
||||
mock(MetricsFeatureProvider::class.java)
|
||||
val mockApplicationFeatureProvider: ApplicationFeatureProvider =
|
||||
mock(ApplicationFeatureProvider::class.java)
|
||||
|
||||
init {
|
||||
@@ -70,9 +72,7 @@ class FakeFeatureFactory : FeatureFactory() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getMetricsFeatureProvider(): MetricsFeatureProvider {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
override fun getMetricsFeatureProvider(): MetricsFeatureProvider = mockMetricsFeatureProvider
|
||||
|
||||
override fun getPowerUsageFeatureProvider(context: Context?): PowerUsageFeatureProvider {
|
||||
TODO("Not yet implemented")
|
||||
@@ -96,7 +96,7 @@ class FakeFeatureFactory : FeatureFactory() {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getApplicationFeatureProvider(context: Context?) = applicationFeatureProvider
|
||||
override fun getApplicationFeatureProvider(context: Context?) = mockApplicationFeatureProvider
|
||||
|
||||
override fun getLocaleFeatureProvider(): LocaleFeatureProvider {
|
||||
TODO("Not yet implemented")
|
||||
|
||||
1
tests/unit/src/com/android/settings/biometrics2/OWNERS
Normal file
1
tests/unit/src/com/android/settings/biometrics2/OWNERS
Normal file
@@ -0,0 +1 @@
|
||||
include /src/com/android/settings/biometrics/OWNERS
|
||||
Reference in New Issue
Block a user