Snap for 11931036 from b2f88a16c9
to 24Q3-release
Change-Id: Idc4b8b4ba05bc76bfccb88d20940a2fface5aa30
This commit is contained in:
24
res/drawable/ic_private_space_edu_icon.xml
Normal file
24
res/drawable/ic_private_space_edu_icon.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path android:fillColor="@android:color/white"
|
||||
android:pathData="M791,905L700,814Q651,846 595.5,863Q540,880 480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,420 97,364.5Q114,309 146,260L55,169L112,112L848,848L791,905ZM480,800Q523,800 563.5,789Q604,778 642,756L204,318Q182,356 171,396.5Q160,437 160,480Q160,613 253.5,706.5Q347,800 480,800ZM814,700L756,642Q778,604 789,563.5Q800,523 800,480Q800,347 706.5,253.5Q613,160 480,160Q437,160 396.5,171Q356,182 318,204L260,146Q309,114 364.5,97Q420,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,540 863,595.5Q846,651 814,700ZM537,423L537,423Q537,423 537,423Q537,423 537,423Q537,423 537,423Q537,423 537,423Q537,423 537,423Q537,423 537,423ZM423,537Q423,537 423,537Q423,537 423,537L423,537Q423,537 423,537Q423,537 423,537Q423,537 423,537Q423,537 423,537Z"/>
|
||||
</vector>
|
@@ -20,6 +20,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
@@ -54,7 +55,8 @@
|
||||
<ImageView
|
||||
android:id="@+id/bt_battery_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/bluetooth_header_battery_content_description" />
|
||||
<TextView
|
||||
android:id="@+id/bt_battery_summary"
|
||||
style="@style/TextAppearance.EntityHeaderSummary"
|
||||
|
@@ -81,6 +81,23 @@
|
||||
android:layout_toRightOf="@+id/appsIcon"
|
||||
android:text="@string/private_space_install_apps_text"/>
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
style="@style/PrivateSpaceSetupSubHeaderStyle"
|
||||
android:text="@string/private_space_keep_in_mind_text"/>
|
||||
<RelativeLayout
|
||||
style="@style/PrivateSpaceSetupBulletPointLayoutStyle"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<ImageView
|
||||
android:id="@+id/eduIcon"
|
||||
style="@style/PrivateSpaceBulletPointIconStyle"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/ic_private_space_edu_icon" />
|
||||
<TextView
|
||||
style="@style/PrivateSpaceBulletPointTextFontStyle"
|
||||
android:layout_toRightOf="@+id/eduIcon"
|
||||
android:text="@string/private_space_apps_stopped_text"/>
|
||||
</RelativeLayout>
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="16dp"/>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -732,7 +732,7 @@
|
||||
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_face_enroll_introduction_cancel">Cancel</string>
|
||||
<!-- Button text to cancel enrollment [CHAR LIMIT=30] -->
|
||||
<string name="security_settings_face_enroll_introduction_no_thanks">No thanks</string>
|
||||
<string name="security_settings_face_enroll_introduction_no_thanks">Not now</string>
|
||||
<!-- Button text to start enrollment [CHAR LIMIT=30] -->
|
||||
<string name="security_settings_face_enroll_introduction_agree">I agree</string>
|
||||
<!-- Button text to scroll to the end of a scrollview. [CHAR LIMIT=30] -->
|
||||
@@ -861,7 +861,7 @@
|
||||
<!-- Button text to cancel enrollment from the introduction [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_cancel">Cancel</string>
|
||||
<!-- Button text to cancel enrollment [CHAR LIMIT=30] -->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_no_thanks">No thanks</string>
|
||||
<string name="security_settings_fingerprint_enroll_introduction_no_thanks">Not now</string>
|
||||
<!-- Button text to agree the consent and continue to the next screen from the introduction [CHAR LIMIT=22] -->
|
||||
<string name="security_settings_fingerprint_enroll_introduction_agree">I agree</string>
|
||||
<!-- Title of dialog shown when the user tries to skip setting up fingerprint after adding lock screen during initial setup. [CHAR LIMIT=30] -->
|
||||
@@ -1345,15 +1345,21 @@
|
||||
<!-- Summary for the private space setup education screen. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_hide_apps_summary">Hide or lock private apps in a separate space. Use a dedicated Google Account for extra security.</string>
|
||||
<!-- Text shown in private space setup screen which explains how the private space works [CHAR LIMIT=50] -->
|
||||
<string name="private_space_setup_sub_header">Set up your private space</string>
|
||||
<string name="private_space_setup_sub_header">How it works</string>
|
||||
<!-- Text shown in private space setup screen which explains private space can be accessed from bottom of all apps list. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_separate_account_text"><b>Choose a Google Account for your space</b>\nUsing a dedicated account helps to stop synced files, photos, and emails appearing outside your space</string>
|
||||
<string name="private_space_separate_account_text"><b>Create a Google Account for your space</b>\nIf you use a dedicated account, it helps to stop synced files, photos, and emails appearing outside your space</string>
|
||||
<!-- Text shown in private space setup screen which explains private space apps are protected by a lock. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_protected_lock_text"><b>Set a lock</b>\nLock your space to stop other people opening it</string>
|
||||
<!-- Text shown in private space setup screen which explains notifications from private space apps will not be shown when private space is locked. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_install_apps_text"><b>Install apps</b>\nYour private space has its own Play Store so you can install apps easily.</string>
|
||||
<string name="private_space_install_apps_text"><b>Install apps</b>\nInstall apps that you want to keep private in your space</string>
|
||||
<!-- Category name "Keep in mind" [CHAR_LIMIT=40] -->
|
||||
<string name="private_space_keep_in_mind_text">Keep in mind</string>
|
||||
<!-- Text shown in private space setup screen which explains that apps in private space are stopped when private space is locked. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_apps_stopped_text"><b>Apps stop when you lock your space</b>\nWhen you lock your space, apps in your space are stopped and you won\u2019t receive notifications from them</string>
|
||||
<!-- This is info text to help explain in private space setup screen that the permissions granted to private space apps will not be shown in settings when private space is locked. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_apps_permission_text">Apps in your private space won\'t appear in permission manager, privacy dashboard, and other settings when your private space is locked.\n\nYour private space can\'t be restored to a new device. You\'ll need to set up another private space if you want to use it on another device.\n\nAnyone that connects your device to a computer or installs malicious apps on your device may be able to access your private space.</string>
|
||||
<string name="private_space_apps_permission_text">Apps in your private space won\'t appear in permission manager, privacy dashboard, and other settings when your private space is locked.\n\nYour private space can\'t be moved to a new device. You\'ll need to set up another private space if you want to use it on another device.\n\nAnyone that connects your device to a computer or installs harmful apps on your device may be able to access your private space.</string>
|
||||
<!-- This is footer text in private space settings page to help explain that when private space is locked the apps are stopped, the permissions granted to private space apps will not be shown in settings. [CHAR LIMIT=NONE] -->
|
||||
<string name="private_space_settings_footer_text">When you lock your space, apps in your private space are stopped and you won\u2019t receive notifications from them.\n\nApps in your private space won\'t appear in permission manager, privacy dashboard, and other settings when private space is locked.\n\nYour private space can\'t be restored to a new device. You\u2019ll need to set up another space if you want to use it on another device.\n\nAnyone that connects your device to a computer or installs malicious apps on your device may be able to access your private space.</string>
|
||||
<!-- Private space footer link content description [CHAR LIMIT=40] -->
|
||||
<string name="private_space_learn_more_text">Learn more about private space</string>
|
||||
<string name="private_space_learn_more_url" translatable="false">https://support.google.com/android?p=private_space</string>
|
||||
@@ -2360,6 +2366,8 @@
|
||||
<!-- Wifi Network Details -->
|
||||
<!-- Wifi details title-->
|
||||
<string name="wifi_details_title">Network details</string>
|
||||
<!-- WEP network less secure warning title -->
|
||||
<string name="wep_network_less_secure_warning_title">This network uses an older security protocol called WEP, which is less secure</string>
|
||||
<!-- Wifi details preference title to display router IP subnet mask -->
|
||||
<string name="wifi_details_subnet_mask">Subnet mask</string>
|
||||
<!-- Server name title-->
|
||||
@@ -8720,7 +8728,7 @@
|
||||
<string name="notif_listener_more_settings">More settings</string>
|
||||
<string name="notif_listener_more_settings_desc">More settings are available inside this app</string>
|
||||
|
||||
<!-- Title for Polite Notifications setting [CHAR LIMIT=30]-->
|
||||
<!-- Title for Polite Notifications setting [CHAR LIMIT=45]-->
|
||||
<string name="notification_polite_title">Cooldown</string>
|
||||
<string name="notification_polite_main_control_title">Use Cooldown</string>
|
||||
<string name="notification_polite_description">When you get many notifications within a short time span, your device will minimize sound interruptions and pop-ups on the screen. Calls, alarms, and priority conversations will still alert as notmal, and all delivered notifications are easy to find in the Shade.</string>
|
||||
@@ -12052,6 +12060,8 @@
|
||||
<string name="bluetooth_right_name">Right</string>
|
||||
<!-- Title for middle bluetooth device. [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_middle_name">Case</string>
|
||||
<!-- Content description for battery icon in bluetooth header. [CHAR LIMIT=NONE] -->
|
||||
<string name="bluetooth_header_battery_content_description">Battery</string>
|
||||
|
||||
<!-- Default title for the settings panel [CHAR LIMIT=NONE] -->
|
||||
<string name="settings_panel_title">Settings Panel</string>
|
||||
|
@@ -77,7 +77,7 @@
|
||||
|
||||
<com.android.settingslib.widget.FooterPreference
|
||||
android:key="private_space_footer"
|
||||
android:title="@string/private_space_apps_permission_text"
|
||||
android:title="@string/private_space_settings_footer_text"
|
||||
android:selectable="false"
|
||||
settings:searchable="false"
|
||||
settings:controller="com.android.settings.privatespace.PrivateSpaceFooterPreferenceController"/>
|
||||
|
@@ -32,14 +32,12 @@ import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.pm.ShortcutManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Flags;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Settings.CreateShortcutActivity;
|
||||
import com.android.settings.activityembedding.ActivityEmbeddingUtils;
|
||||
import com.android.settings.homepage.DeepLinkHomepageActivity;
|
||||
import com.android.settings.search.SearchStateReceiver;
|
||||
@@ -49,7 +47,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Listens to {@link Intent.ACTION_PRE_BOOT_COMPLETED} and {@link Intent.ACTION_USER_INITIALIZED}
|
||||
* Listens to {@link Intent.ACTION_PRE_BOOT_COMPLETED} and {@link Intent.ACTION_USER_INITIALIZE}
|
||||
* performs setup steps for a managed profile (disables the launcher icon of the Settings app,
|
||||
* adds cross-profile intent filters for the appropriate Settings activities), disables the
|
||||
* webview setting for non-admin users, updates the intent flags for any existing shortcuts and
|
||||
@@ -68,7 +66,6 @@ public class SettingsInitialize extends BroadcastReceiver {
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
managedProfileSetup(context, pm, broadcast, userInfo);
|
||||
cloneProfileSetup(context, pm, userInfo);
|
||||
privateProfileSetup(context, pm, userInfo);
|
||||
webviewSettingSetup(context, pm, userInfo);
|
||||
ThreadUtils.postOnBackgroundThread(() -> refreshExistingShortcuts(context));
|
||||
enableTwoPaneDeepLinkActivityIfNecessary(pm, context);
|
||||
@@ -106,7 +103,7 @@ public class SettingsInitialize extends BroadcastReceiver {
|
||||
}
|
||||
}
|
||||
|
||||
disableComponentsToHideSettings(context, pm);
|
||||
Utils.disableComponentsToHideSettings(context, pm);
|
||||
}
|
||||
|
||||
private void cloneProfileSetup(Context context, PackageManager pm, UserInfo userInfo) {
|
||||
@@ -114,31 +111,7 @@ public class SettingsInitialize extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
disableComponentsToHideSettings(context, pm);
|
||||
}
|
||||
|
||||
private void privateProfileSetup(Context context, PackageManager pm, UserInfo userInfo) {
|
||||
if (Flags.allowPrivateProfile()
|
||||
&& android.multiuser.Flags.enablePrivateSpaceFeatures()) {
|
||||
if (userInfo == null || !userInfo.isPrivateProfile()) {
|
||||
return;
|
||||
}
|
||||
|
||||
disableComponentsToHideSettings(context, pm);
|
||||
}
|
||||
}
|
||||
|
||||
private void disableComponentsToHideSettings(Context context, PackageManager pm) {
|
||||
// Disable settings app launcher icon
|
||||
disableComponent(pm, new ComponentName(context, Settings.class));
|
||||
|
||||
//Disable Shortcut picker
|
||||
disableComponent(pm, new ComponentName(context, CreateShortcutActivity.class));
|
||||
}
|
||||
|
||||
private void disableComponent(PackageManager pm, ComponentName componentName) {
|
||||
pm.setComponentEnabledSetting(componentName,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||
Utils.disableComponentsToHideSettings(context, pm);
|
||||
}
|
||||
|
||||
// Disable WebView Setting if the current user is not an admin
|
||||
|
@@ -1464,4 +1464,22 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the launcher icon and shortcut picker component for the Settings app corresponding
|
||||
* to the context user.
|
||||
*/
|
||||
public static void disableComponentsToHideSettings(@NonNull Context context,
|
||||
@NonNull PackageManager pm) {
|
||||
// Disable settings app launcher icon
|
||||
disableComponent(pm, new ComponentName(context, Settings.class));
|
||||
|
||||
//Disable Shortcut picker
|
||||
disableComponent(pm, new ComponentName(context, Settings.CreateShortcutActivity.class));
|
||||
}
|
||||
|
||||
private static void disableComponent(PackageManager pm, ComponentName componentName) {
|
||||
pm.setComponentEnabledSetting(componentName,
|
||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
}
|
||||
|
@@ -33,6 +33,10 @@ import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.collection.ArraySet;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceClickListener;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
@@ -46,6 +50,8 @@ import com.android.settings.utils.LocalClassLoaderContextThemeWrapper;
|
||||
import com.android.settingslib.accounts.AuthenticatorHelper;
|
||||
import com.android.settingslib.core.instrumentation.Instrumentable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class to load the preference screen to be added to the settings page for the specific account
|
||||
* type as specified in the account-authenticator.
|
||||
@@ -83,6 +89,7 @@ public class AccountTypePreferenceLoader {
|
||||
try {
|
||||
desc = mAuthenticatorHelper.getAccountTypeDescription(accountType);
|
||||
if (desc != null && desc.accountPreferencesId != 0) {
|
||||
Set<String> fragmentAllowList = generateFragmentAllowlist(parent);
|
||||
// Load the context of the target package, then apply the
|
||||
// base Settings theme (no references to local resources)
|
||||
// and create a context theme wrapper so that we get the
|
||||
@@ -99,6 +106,12 @@ public class AccountTypePreferenceLoader {
|
||||
themedCtx.getTheme().setTo(baseTheme);
|
||||
prefs = mFragment.getPreferenceManager().inflateFromResource(themedCtx,
|
||||
desc.accountPreferencesId, parent);
|
||||
// Ignore Fragments provided dynamically, as these are coming from external
|
||||
// applications which must not have access to internal Settings' fragments.
|
||||
// These preferences are rendered into Settings, so they also won't have access
|
||||
// to their own Fragments, meaning there is no acceptable usage of
|
||||
// android:fragment here.
|
||||
filterBlockedFragments(prefs, fragmentAllowList);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName);
|
||||
@@ -186,6 +199,48 @@ public class AccountTypePreferenceLoader {
|
||||
}
|
||||
}
|
||||
|
||||
// Build allowlist from existing Fragments in PreferenceGroup
|
||||
@VisibleForTesting
|
||||
Set<String> generateFragmentAllowlist(@Nullable PreferenceGroup prefs) {
|
||||
Set<String> fragmentAllowList = new ArraySet<>();
|
||||
if (prefs == null) {
|
||||
return fragmentAllowList;
|
||||
}
|
||||
|
||||
for (int i = 0; i < prefs.getPreferenceCount(); i++) {
|
||||
Preference pref = prefs.getPreference(i);
|
||||
if (pref instanceof PreferenceGroup) {
|
||||
fragmentAllowList.addAll(generateFragmentAllowlist((PreferenceGroup) pref));
|
||||
}
|
||||
|
||||
String fragmentName = pref.getFragment();
|
||||
if (!TextUtils.isEmpty(fragmentName)) {
|
||||
fragmentAllowList.add(fragmentName);
|
||||
}
|
||||
}
|
||||
return fragmentAllowList;
|
||||
}
|
||||
|
||||
// Block clicks on any Preference with android:fragment that is not contained in the allowlist
|
||||
@VisibleForTesting
|
||||
void filterBlockedFragments(@Nullable PreferenceGroup prefs,
|
||||
@NonNull Set<String> allowedFragments) {
|
||||
if (prefs == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < prefs.getPreferenceCount(); i++) {
|
||||
Preference pref = prefs.getPreference(i);
|
||||
if (pref instanceof PreferenceGroup) {
|
||||
filterBlockedFragments((PreferenceGroup) pref, allowedFragments);
|
||||
}
|
||||
|
||||
String fragmentName = pref.getFragment();
|
||||
if (fragmentName != null && !allowedFragments.contains(fragmentName)) {
|
||||
pref.setOnPreferenceClickListener(preference -> true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the supplied Intent is safe. A safe intent is one that is
|
||||
* will launch a exported=true activity or owned by the same uid as the
|
||||
|
@@ -33,6 +33,7 @@ import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
|
||||
import com.android.settings.fuelgauge.batteryusage.AppOptModeSharedPreferencesUtils;
|
||||
import com.android.settingslib.datastore.DataChangeReason;
|
||||
import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
|
||||
|
||||
@@ -138,7 +139,8 @@ public class BatteryOptimizeUtils {
|
||||
/** Resets optimization mode for all applications. */
|
||||
public static void resetAppOptimizationMode(
|
||||
Context context, IPackageManager ipm, AppOpsManager aom) {
|
||||
resetAppOptimizationMode(
|
||||
AppOptModeSharedPreferencesUtils.clearAll(context);
|
||||
resetAppOptimizationModeInternal(
|
||||
context,
|
||||
ipm,
|
||||
aom,
|
||||
@@ -219,7 +221,7 @@ public class BatteryOptimizeUtils {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void resetAppOptimizationMode(
|
||||
static void resetAppOptimizationModeInternal(
|
||||
Context context,
|
||||
IPackageManager ipm,
|
||||
AppOpsManager aom,
|
||||
|
@@ -41,6 +41,13 @@ object AppOptModeSharedPreferencesUtils {
|
||||
fun getAllEvents(context: Context): List<AppOptimizationModeEvent> =
|
||||
synchronized(appOptimizationModeLock) { getAppOptModeEventsMap(context).values.toList() }
|
||||
|
||||
/** Removes all app optimization mode events. */
|
||||
@JvmStatic
|
||||
fun clearAll(context: Context) =
|
||||
synchronized(appOptimizationModeLock) {
|
||||
getSharedPreferences(context).edit().clear().apply()
|
||||
}
|
||||
|
||||
/** Updates the app optimization mode event data. */
|
||||
@JvmStatic
|
||||
fun updateAppOptModeExpiration(
|
||||
|
@@ -58,6 +58,7 @@ public class KeyboardSettingsPreferenceController extends BasePreferenceControll
|
||||
intent.putExtra(
|
||||
Settings.EXTRA_INPUT_DEVICE_IDENTIFIER,
|
||||
hardKeyboardDeviceInfo.mDeviceIdentifier);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||
mContext.startActivity(intent);
|
||||
break;
|
||||
}
|
||||
|
@@ -99,8 +99,6 @@ import java.util.Optional;
|
||||
|
||||
/**
|
||||
* UI for Mobile network and Wi-Fi network settings.
|
||||
*
|
||||
* TODO(b/167474581): Define the intent android.settings.NETWORK_PROVIDER_SETTINGS in Settings.java.
|
||||
*/
|
||||
@SearchIndexable
|
||||
public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
@@ -108,9 +106,6 @@ public class NetworkProviderSettings extends RestrictedSettingsFragment
|
||||
WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener,
|
||||
AirplaneModeEnabler.OnAirplaneModeChangedListener, InternetUpdater.InternetChangeListener {
|
||||
|
||||
public static final String ACTION_NETWORK_PROVIDER_SETTINGS =
|
||||
"android.settings.NETWORK_PROVIDER_SETTINGS";
|
||||
|
||||
private static final String TAG = "NetworkProviderSettings";
|
||||
// IDs of context menu
|
||||
static final int MENU_ID_CONNECT = Menu.FIRST + 1;
|
||||
|
@@ -56,6 +56,8 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import kotlin.Unit;
|
||||
|
||||
import kotlinx.coroutines.Job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -96,6 +98,8 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
private AtomicBoolean mShouldFilterOutSatellitePlmn = new AtomicBoolean();
|
||||
|
||||
private NetworkScanRepository mNetworkScanRepository;
|
||||
@Nullable
|
||||
private Job mNetworkScanJob = null;
|
||||
|
||||
private NetworkSelectRepository mNetworkSelectRepository;
|
||||
|
||||
@@ -213,13 +217,14 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
|
||||
private void launchNetworkScan() {
|
||||
setProgressBarVisible(true);
|
||||
mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(), (networkScanResult) -> {
|
||||
if (isPreferenceScreenEnabled()) {
|
||||
scanResultHandler(networkScanResult);
|
||||
}
|
||||
mNetworkScanJob = mNetworkScanRepository.launchNetworkScan(getViewLifecycleOwner(),
|
||||
(networkScanResult) -> {
|
||||
if (isPreferenceScreenEnabled()) {
|
||||
scanResultHandler(networkScanResult);
|
||||
}
|
||||
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,6 +250,12 @@ public class NetworkSelectSettings extends DashboardFragment {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need stop network scan before manual select network.
|
||||
if (mNetworkScanJob != null) {
|
||||
mNetworkScanJob.cancel(null);
|
||||
mNetworkScanJob = null;
|
||||
}
|
||||
|
||||
// Refresh the last selected item in case users reselect network.
|
||||
clearPreferenceSummary();
|
||||
if (mSelectedPreference != null) {
|
||||
|
@@ -52,9 +52,8 @@ class NetworkScanRepository(private val context: Context, subId: Int) {
|
||||
private val telephonyManager = context.telephonyManager(subId)
|
||||
|
||||
/** TODO: Move this to UI layer, when UI layer migrated to Kotlin. */
|
||||
fun launchNetworkScan(lifecycleOwner: LifecycleOwner, onResult: (NetworkScanResult) -> Unit) {
|
||||
fun launchNetworkScan(lifecycleOwner: LifecycleOwner, onResult: (NetworkScanResult) -> Unit) =
|
||||
networkScanFlow().collectLatestWithLifecycle(lifecycleOwner, action = onResult)
|
||||
}
|
||||
|
||||
data class CellInfoScanKey(
|
||||
val title: String?,
|
||||
@@ -101,7 +100,10 @@ class NetworkScanRepository(private val context: Context, subId: Int) {
|
||||
callback,
|
||||
)
|
||||
|
||||
awaitClose { networkScan.stopScan() }
|
||||
awaitClose {
|
||||
networkScan.stopScan()
|
||||
Log.d(TAG, "network scan stopped")
|
||||
}
|
||||
}.conflate().onEach { Log.d(TAG, "networkScanFlow: $it") }.flowOn(Dispatchers.Default)
|
||||
|
||||
/** Create network scan for allowed network types. */
|
||||
|
@@ -80,8 +80,10 @@ public class BubblePreference extends Preference implements RadioGroup.OnChecked
|
||||
}
|
||||
|
||||
public void setSelectedVisibility(boolean visible) {
|
||||
mSelectedVisible = visible;
|
||||
notifyChanged();
|
||||
if (mSelectedVisible != visible) {
|
||||
mSelectedVisible = visible;
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -31,6 +31,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentSender;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.Flags;
|
||||
import android.os.UserHandle;
|
||||
@@ -44,6 +45,7 @@ import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.settings.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -129,6 +131,7 @@ public class PrivateSpaceMaintainer {
|
||||
resetPrivateSpaceSettings();
|
||||
setUserSetupComplete();
|
||||
setSkipFirstUseHints();
|
||||
disableComponentsToHidePrivateSpaceSettings();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -356,6 +359,24 @@ public class PrivateSpaceMaintainer {
|
||||
1, mUserHandle.getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the launcher icon and shortcut picker component for the Settings app instance
|
||||
* inside the private space
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
private void disableComponentsToHidePrivateSpaceSettings() {
|
||||
if (mUserHandle == null) {
|
||||
Log.e(TAG, "User handle null while hiding settings icon");
|
||||
return;
|
||||
}
|
||||
|
||||
Context privateSpaceUserContext = mContext.createContextAsUser(mUserHandle, /* flags */ 0);
|
||||
PackageManager packageManager = privateSpaceUserContext.getPackageManager();
|
||||
|
||||
Log.d(TAG, "Hiding settings app launcher icon for " + mUserHandle);
|
||||
Utils.disableComponentsToHideSettings(privateSpaceUserContext, packageManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the SKIP_FIRST_USE_HINTS for private profile so that the first launch of an app in
|
||||
* private space will not display introductory hints.
|
||||
|
@@ -22,7 +22,6 @@ import android.app.AppOpsManager
|
||||
import android.app.AppOpsManager.MODE_DEFAULT
|
||||
import android.content.Context
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.os.Process
|
||||
import android.os.UserManager
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.android.settings.R
|
||||
@@ -92,10 +91,8 @@ class InstallUnknownAppsListModel(private val context: Context) :
|
||||
private fun isChangeable(
|
||||
record: InstallUnknownAppsRecord,
|
||||
potentialPackageNames: Set<String>,
|
||||
) =
|
||||
record.app.uid != Process.SYSTEM_UID && record.app.uid != Process.ROOT_UID &&
|
||||
(record.appOpsController.getMode() != MODE_DEFAULT ||
|
||||
record.app.packageName in potentialPackageNames)
|
||||
) = record.appOpsController.getMode() != MODE_DEFAULT ||
|
||||
record.app.packageName in potentialPackageNames
|
||||
|
||||
private fun getPotentialPackageNames(userId: Int): Set<String> =
|
||||
AppGlobals.getPackageManager()
|
||||
|
@@ -22,6 +22,7 @@ import static android.net.wifi.SoftApConfiguration.BAND_5GHZ;
|
||||
import static android.net.wifi.SoftApConfiguration.BAND_6GHZ;
|
||||
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_OPEN;
|
||||
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE;
|
||||
import static android.net.wifi.SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION;
|
||||
import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP;
|
||||
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
|
||||
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
|
||||
@@ -343,16 +344,23 @@ public class WifiHotspotRepository {
|
||||
log("setSpeedType(), setPassphrase(SECURITY_TYPE_WPA3_SAE)");
|
||||
configBuilder.setPassphrase(generatePassword(config), SECURITY_TYPE_WPA3_SAE);
|
||||
}
|
||||
} else if (speedType == SPEED_5GHZ) {
|
||||
log("setSpeedType(), setBand(BAND_2GHZ_5GHZ)");
|
||||
configBuilder.setBand(BAND_2GHZ_5GHZ);
|
||||
} else if (mIsDualBand) {
|
||||
log("setSpeedType(), setBands(BAND_2GHZ + BAND_2GHZ_5GHZ)");
|
||||
int[] bands = {BAND_2GHZ, BAND_2GHZ_5GHZ};
|
||||
configBuilder.setBands(bands);
|
||||
} else {
|
||||
log("setSpeedType(), setBand(BAND_2GHZ)");
|
||||
configBuilder.setBand(BAND_2GHZ);
|
||||
if (speedType == SPEED_5GHZ) {
|
||||
log("setSpeedType(), setBand(BAND_2GHZ_5GHZ)");
|
||||
configBuilder.setBand(BAND_2GHZ_5GHZ);
|
||||
} else if (mIsDualBand) {
|
||||
log("setSpeedType(), setBands(BAND_2GHZ + BAND_2GHZ_5GHZ)");
|
||||
int[] bands = {BAND_2GHZ, BAND_2GHZ_5GHZ};
|
||||
configBuilder.setBands(bands);
|
||||
} else {
|
||||
log("setSpeedType(), setBand(BAND_2GHZ)");
|
||||
configBuilder.setBand(BAND_2GHZ);
|
||||
}
|
||||
// Set the security type back to WPA2/WPA3 if we're moving from 6GHz to something else.
|
||||
if ((config.getBand() & BAND_6GHZ) != 0) {
|
||||
configBuilder.setPassphrase(
|
||||
generatePassword(config), SECURITY_TYPE_WPA3_SAE_TRANSITION);
|
||||
}
|
||||
}
|
||||
setSoftApConfiguration(configBuilder.build());
|
||||
}
|
||||
|
62
tests/Enable16KbTests/Android.bp
Normal file
62
tests/Enable16KbTests/Android.bp
Normal file
@@ -0,0 +1,62 @@
|
||||
// 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 {
|
||||
default_applicable_licenses: ["packages_apps_Settings_license"],
|
||||
default_team: "trendy_team_android_kernel",
|
||||
}
|
||||
|
||||
android_test_helper_app {
|
||||
name: "test_16kb_app",
|
||||
srcs: ["test_16kb_app/src/**/*.java"],
|
||||
manifest: "test_16kb_app/test_16kb_app.xml",
|
||||
static_libs: [
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.uiautomator_uiautomator",
|
||||
"platform-test-annotations",
|
||||
"settings-helper",
|
||||
"sysui-helper",
|
||||
"truth",
|
||||
"flag-junit",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
test_suites: ["general-tests"],
|
||||
libs: [
|
||||
"android.test.runner",
|
||||
"android.test.base",
|
||||
],
|
||||
}
|
||||
|
||||
java_test_host {
|
||||
name: "Enable16KbTest",
|
||||
// Include all test java files
|
||||
srcs: ["src/**/*.java"],
|
||||
static_libs: [
|
||||
"junit",
|
||||
"platform-test-annotations",
|
||||
"truth",
|
||||
],
|
||||
libs: [
|
||||
"tradefed",
|
||||
"compatibility-host-util",
|
||||
"compatibility-tradefed",
|
||||
],
|
||||
data: [
|
||||
":test_16kb_app",
|
||||
],
|
||||
test_suites: ["general-tests"],
|
||||
test_config: "AndroidTest.xml",
|
||||
}
|
45
tests/Enable16KbTests/AndroidTest.xml
Normal file
45
tests/Enable16KbTests/AndroidTest.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<configuration description="Runs 16K developer option test.">
|
||||
<option name="test-suite-tag" value="apct"/>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="test-file-name" value="test_16kb_app.apk" />
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
|
||||
<option name="force-root" value="false" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
|
||||
<option name="jar" value="Enable16KbTest.jar" />
|
||||
</test>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
|
||||
<!-- Unlock screen -->
|
||||
<option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
|
||||
<!-- Dismiss keyguard, in case it's set as "Swipe to unlock" -->
|
||||
<option name="run-command" value="wm dismiss-keyguard" />
|
||||
<!-- Collapse notifications -->
|
||||
<option name="run-command" value="cmd statusbar collapse" />
|
||||
<!-- dismiss all system dialogs before launch test -->
|
||||
<option name="run-command" value="am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS" />
|
||||
</target_preparer>
|
||||
|
||||
</configuration>
|
122
tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java
Normal file
122
tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
import android.platform.test.annotations.AppModeFull;
|
||||
|
||||
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
|
||||
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
|
||||
import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
|
||||
import com.android.tradefed.util.RunUtil;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.StringReader;
|
||||
|
||||
@RunWith(DeviceJUnit4ClassRunner.class)
|
||||
public class Enable16KbTest extends BaseHostJUnit4Test {
|
||||
private static final String TEST_APP_NAME = "test_16kb_app.apk";
|
||||
|
||||
private static final String APP_PACKAGE = "com.android.settings.development.test";
|
||||
|
||||
private static final String TEST_NAME = "Enable16KbDeviceTest";
|
||||
|
||||
private static final String SWITCH_TO_EXT4 = "enable16k_switchToExt4";
|
||||
|
||||
private static final String SWITCH_TO_16KB = "enable16k_switchTo16Kb";
|
||||
|
||||
private static final String SWITCH_TO_4KB = "enable16k_switchTo4Kb";
|
||||
private static final String DISABLE_DEV_OPTION = "enable16k_disableDeveloperOption";
|
||||
|
||||
@Test
|
||||
@AppModeFull
|
||||
public void enable16KbToggle() throws Exception {
|
||||
assertTrue(isPackageInstalled(APP_PACKAGE));
|
||||
|
||||
// Check if developer option is enabled otherwise exit
|
||||
getDevice().enableAdbRoot();
|
||||
String result = getDevice().getProperty("ro.product.build.16k_page.enabled");
|
||||
assumeTrue("true".equals(result));
|
||||
|
||||
// This test can be run on OEM unlocked device only as unlocking bootloader requires
|
||||
// manual intervention.
|
||||
result = getDevice().getProperty("ro.boot.flash.locked");
|
||||
assumeTrue("0".equals(result));
|
||||
|
||||
getDevice().executeShellCommand("am start -a com.android.setupwizard.FOUR_CORNER_EXIT");
|
||||
|
||||
// Enables developer option and switch to ext4
|
||||
runTestAndWait(SWITCH_TO_EXT4);
|
||||
|
||||
getDevice().enableAdbRoot();
|
||||
getDevice().executeShellCommand("am start -a com.android.setupwizard.FOUR_CORNER_EXIT");
|
||||
assertTrue(verifyExt4());
|
||||
|
||||
// Device will wiped. need to install test package again.
|
||||
installTestApp();
|
||||
|
||||
// Enable developer option and switch to 16kb kernel and Check page size
|
||||
runTestAndWait(SWITCH_TO_16KB);
|
||||
result = getDevice().executeShellCommand("getconf PAGE_SIZE");
|
||||
assertEquals("16384", result.strip());
|
||||
|
||||
// switch back to 4kb kernel and check page size
|
||||
runTestAndWait(SWITCH_TO_4KB);
|
||||
result = getDevice().executeShellCommand("getconf PAGE_SIZE");
|
||||
assertEquals("4096", result.strip());
|
||||
|
||||
// Verify that developer options can't be turned off
|
||||
runDeviceTests(APP_PACKAGE, APP_PACKAGE + "." + TEST_NAME, DISABLE_DEV_OPTION);
|
||||
}
|
||||
|
||||
private void installTestApp() throws Exception {
|
||||
DeviceTestRunOptions options = new DeviceTestRunOptions(null /* unused */);
|
||||
options.setApkFileName(TEST_APP_NAME);
|
||||
options.setInstallArgs("-r");
|
||||
installPackage(options);
|
||||
assertTrue(isPackageInstalled(APP_PACKAGE));
|
||||
}
|
||||
|
||||
private void runTestAndWait(String testMethodName) throws Exception {
|
||||
runDeviceTests(APP_PACKAGE, APP_PACKAGE + "." + TEST_NAME, testMethodName);
|
||||
// Device is either formatting or applying update. It usually takes 3 minutes to boot.
|
||||
RunUtil.getDefault().sleep(180000);
|
||||
// Wait for 2 mins device to be online againg
|
||||
getDevice().waitForDeviceOnline(120000);
|
||||
}
|
||||
|
||||
private boolean verifyExt4() throws Exception {
|
||||
String result = getDevice().executeShellCommand("cat /proc/mounts");
|
||||
BufferedReader br = new BufferedReader(new StringReader(result));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
final String[] fields = line.split(" ");
|
||||
final String partition = fields[1];
|
||||
final String fsType = fields[2];
|
||||
if (partition.equals("/data") && fsType.equals("ext4")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.development.test;
|
||||
|
||||
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.provider.Settings;
|
||||
import android.system.helpers.SettingsHelper;
|
||||
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import androidx.test.uiautomator.By;
|
||||
import androidx.test.uiautomator.BySelector;
|
||||
import androidx.test.uiautomator.Direction;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObject2;
|
||||
import androidx.test.uiautomator.Until;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class Enable16KbDeviceTest {
|
||||
private static final long TIMEOUT = 2000;
|
||||
|
||||
private static final String ENABLE_16K_TOGGLE = "Boot with 16KB page size";
|
||||
private static final String BUILD_NUMBER = "Build number";
|
||||
private static final String USE_DEVELOPER_OPTIONS = "Use developer options";
|
||||
private static final String EXT4_CONFIRMATION = "Erase all data";
|
||||
private static final String EXT4_TITLE = "Reformat device to ext4? (required for 16KB mode)";
|
||||
private static final String TOGGLE_16K_TITLE = "Switch from 4KB mode to 16KB mode";
|
||||
private static final String TOGGLE_4K_TITLE = "Switch from 16KB mode to 4KB mode";
|
||||
private static final String ANDROID_WIDGET_SCROLLVIEW = "android.widget.ScrollView";
|
||||
private static final String OKAY = "OK";
|
||||
private static final String NOTIFICATION_TITLE_4K = "Using 4KB page-agnostic mode";
|
||||
private static final String NOTIFICATION_TITLE_16K = "Using 16KB page-agnostic mode";
|
||||
|
||||
private Context mContext;
|
||||
private UiDevice mDevice;
|
||||
private SettingsHelper mHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mContext = getInstrumentation().getTargetContext();
|
||||
mDevice = UiDevice.getInstance(getInstrumentation());
|
||||
mHelper = SettingsHelper.getInstance();
|
||||
try {
|
||||
mDevice.setOrientationNatural();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException("failed to freeze device orientation", e);
|
||||
}
|
||||
|
||||
mDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
|
||||
mDevice.executeShellCommand("wm dismiss-keyguard");
|
||||
}
|
||||
|
||||
private void unlockDeveloperOptions() throws Exception {
|
||||
SettingsHelper.launchSettingsPage(mContext, Settings.ACTION_DEVICE_INFO_SETTINGS);
|
||||
// Click 7 times on build number to unlock the dev options
|
||||
for (int i = 0; i < 7; i++) {
|
||||
mHelper.clickSetting(BUILD_NUMBER);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable16k_switchToExt4() throws Exception {
|
||||
unlockDeveloperOptions();
|
||||
SettingsHelper.launchSettingsPage(
|
||||
mContext, Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
clickOnObject(By.text(ENABLE_16K_TOGGLE));
|
||||
|
||||
// Verify that ext4 toggle is visible
|
||||
verifyTextOnScreen(EXT4_TITLE);
|
||||
|
||||
mDevice.wait(Until.findObject(By.text(EXT4_CONFIRMATION)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable16k_switchTo16Kb() throws Exception {
|
||||
// Device will be in 4kb mode
|
||||
openPersistentNotification(NOTIFICATION_TITLE_4K);
|
||||
unlockDeveloperOptions();
|
||||
SettingsHelper.launchSettingsPage(
|
||||
mContext, Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
|
||||
clickOnObject(By.text(ENABLE_16K_TOGGLE));
|
||||
// Verify that text is displayed to switch to 16kb
|
||||
verifyTextOnScreen(TOGGLE_16K_TITLE);
|
||||
|
||||
mDevice.wait(Until.findObject(By.text(OKAY)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable16k_switchTo4Kb() throws Exception {
|
||||
// Device will be in 16kb mode
|
||||
openPersistentNotification(NOTIFICATION_TITLE_16K);
|
||||
SettingsHelper.launchSettingsPage(
|
||||
mContext, Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
|
||||
clickOnObject(By.text(ENABLE_16K_TOGGLE));
|
||||
// Verify that text is displayed to switch to 4kb
|
||||
verifyTextOnScreen(TOGGLE_4K_TITLE);
|
||||
|
||||
mDevice.wait(Until.findObject(By.text(OKAY)), TIMEOUT).click();
|
||||
}
|
||||
|
||||
private void clickOnObject(BySelector target) {
|
||||
mDevice.waitForWindowUpdate(null, TIMEOUT);
|
||||
UiObject2 scrollView =
|
||||
mDevice.wait(
|
||||
Until.findObject(By.scrollable(true).clazz(ANDROID_WIDGET_SCROLLVIEW)),
|
||||
TIMEOUT);
|
||||
UiObject2 targetObject = scrollTo(scrollView, target, Direction.DOWN);
|
||||
assertTrue(targetObject != null);
|
||||
targetObject.click();
|
||||
}
|
||||
|
||||
private UiObject2 scrollTo(UiObject2 scrollable, BySelector target, Direction direction) {
|
||||
while (!mDevice.hasObject(target) && scrollable.scroll(direction, 1.0f)) {
|
||||
// continue
|
||||
}
|
||||
if (!mDevice.hasObject(target)) {
|
||||
scrollable.scroll(direction, 1.0f);
|
||||
}
|
||||
return mDevice.findObject(target);
|
||||
}
|
||||
|
||||
private void verifyTextOnScreen(String displayedText) {
|
||||
UiObject2 targetObject = mDevice.wait(Until.findObject(By.text(displayedText)), TIMEOUT);
|
||||
assertTrue(targetObject != null);
|
||||
}
|
||||
|
||||
private void openPersistentNotification(String title) {
|
||||
mDevice.openNotification();
|
||||
verifyTextOnScreen(title);
|
||||
mDevice.wait(Until.findObject(By.text(title)), TIMEOUT).click();
|
||||
mDevice.waitForWindowUpdate(null, TIMEOUT);
|
||||
verifyTextOnScreen(title);
|
||||
mDevice.wait(Until.findObject(By.text(OKAY)), TIMEOUT).click();
|
||||
mDevice.waitForWindowUpdate(null, TIMEOUT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable16k_disableDeveloperOption() throws Exception {
|
||||
// Device will be in 4KB mode when this test will be run
|
||||
SettingsHelper.launchSettingsPage(
|
||||
mContext, Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
|
||||
mDevice.wait(Until.findObject(By.text(USE_DEVELOPER_OPTIONS)), TIMEOUT).click();
|
||||
verifyTextOnScreen(NOTIFICATION_TITLE_4K);
|
||||
mDevice.wait(Until.findObject(By.text(OKAY)), TIMEOUT).click();
|
||||
}
|
||||
}
|
27
tests/Enable16KbTests/test_16kb_app/test_16kb_app.xml
Normal file
27
tests/Enable16KbTests/test_16kb_app/test_16kb_app.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.settings.development.test"
|
||||
android:sharedUserId="android.uid.systemui">
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner"/>
|
||||
</application>
|
||||
<instrumentation
|
||||
android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="com.android.settings.development.test"/>
|
||||
</manifest>
|
@@ -12,8 +12,8 @@ package {
|
||||
android_app {
|
||||
name: "SettingsRoboTestStub",
|
||||
defaults: [
|
||||
"SettingsLibDefaults",
|
||||
"SettingsLib-search-defaults",
|
||||
"SettingsLibDefaults",
|
||||
],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
@@ -23,18 +23,18 @@ android_app {
|
||||
|
||||
static_libs: [
|
||||
"Settings-core",
|
||||
"androidx.fragment_fragment-testing",
|
||||
"frameworks-base-testutils",
|
||||
"androidx.fragment_fragment",
|
||||
"androidx.fragment_fragment-testing",
|
||||
"androidx.lifecycle_lifecycle-runtime-testing",
|
||||
"frameworks-base-testutils",
|
||||
"kotlinx_coroutines_test",
|
||||
],
|
||||
|
||||
aaptflags: ["--extra-packages com.android.settings"],
|
||||
|
||||
libs: [
|
||||
"telephony-common",
|
||||
"ims-common",
|
||||
"telephony-common",
|
||||
],
|
||||
uses_libs: ["org.apache.http.legacy"],
|
||||
optional_uses_libs: [
|
||||
@@ -47,36 +47,64 @@ android_app {
|
||||
android_robolectric_test {
|
||||
name: "SettingsRoboTests",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.kt",
|
||||
"src/com/android/settings/*.java",
|
||||
"src/com/android/settings/accessibility/**/*.java",
|
||||
"src/com/android/settings/accounts/**/*.java",
|
||||
"src/com/android/settings/applications/**/*.java",
|
||||
"src/com/android/settings/backup/**/*.java",
|
||||
"src/com/android/settings/bluetooth/**/*.java",
|
||||
"src/com/android/settings/bluetooth/**/*.kt",
|
||||
"src/com/android/settings/bugreporthandler/**/*.java",
|
||||
"src/com/android/settings/communal/**/*.java",
|
||||
"src/com/android/settings/connecteddevice/**/*.java",
|
||||
//"src/com/android/settings/core/**/*.java",
|
||||
"src/com/android/settings/dashboard/**/*.java",
|
||||
"src/com/android/settings/datausage/**/*.java",
|
||||
"src/com/android/settings/datetime/**/*.java",
|
||||
"src/com/android/settings/deletionhelper/**/*.java",
|
||||
//"src/com/android/settings/development/**/*.java",
|
||||
"src/com/android/settings/deviceinfo/**/*.java",
|
||||
"src/com/android/settings/devicelock/**/*.java",
|
||||
"src/com/android/settings/display/**/*.java",
|
||||
"src/com/android/settings/dream/**/*.java",
|
||||
"src/com/android/settings/emergency/**/*.java",
|
||||
"src/com/android/settings/enterprise/**/*.java",
|
||||
"src/com/android/settings/flashlight/**/*.java",
|
||||
"src/com/android/settings/fuelgauge/**/*.java",
|
||||
"src/com/android/settings/gestures/**/*.java",
|
||||
//"src/com/android/settings/homepage/**/*.java",
|
||||
"src/com/android/settings/inputmethod/**/*.java",
|
||||
"src/com/android/settings/network/ShadowServiceManagerExtend.java",
|
||||
"src/com/android/settings/search/DatabaseIndexingUtils.java",
|
||||
"src/com/android/settings/testutils/**/*.java",
|
||||
],
|
||||
|
||||
// test_suites attribute is not needed. This module will be configured in ATP GCL file.
|
||||
|
||||
static_libs: [
|
||||
"Robolectric_shadows_androidx_fragment_upstream",
|
||||
"Settings_robolectric_meta_service_file",
|
||||
"SettingsLib-robo-testutils",
|
||||
"Settings-robo-testutils",
|
||||
"Settings-testutils2",
|
||||
"SettingsLib-robo-testutils",
|
||||
"Settings_robolectric_meta_service_file",
|
||||
"aconfig_settings_flags_lib",
|
||||
"android.webkit.flags-aconfig-java",
|
||||
"androidx.test.core",
|
||||
"androidx.test.espresso.core",
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.test.rules",
|
||||
"androidx.test.runner",
|
||||
"com_android_server_accessibility_flags_lib",
|
||||
"flag-junit",
|
||||
"flag-junit-base",
|
||||
"aconfig_settings_flags_lib",
|
||||
"platform-test-annotations",
|
||||
"Settings-testutils2",
|
||||
"notification_flags_lib",
|
||||
"com_android_server_accessibility_flags_lib",
|
||||
"platform-test-annotations",
|
||||
"testables",
|
||||
],
|
||||
|
||||
libs: [
|
||||
"ims-common",
|
||||
"android.test.mock",
|
||||
"ims-common",
|
||||
],
|
||||
|
||||
java_resource_dirs: [
|
||||
|
@@ -16,9 +16,13 @@
|
||||
|
||||
package com.android.settings.accounts;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -30,6 +34,7 @@ import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.collection.ArraySet;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragmentCompat;
|
||||
import androidx.preference.PreferenceGroup;
|
||||
@@ -51,9 +56,13 @@ import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
ShadowAccountManager.class,
|
||||
ShadowContentResolver.class,
|
||||
})
|
||||
public class AccountTypePreferenceLoaderTest {
|
||||
|
||||
@@ -63,6 +72,8 @@ public class AccountTypePreferenceLoaderTest {
|
||||
private PreferenceFragmentCompat mPreferenceFragment;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
@Mock
|
||||
private PreferenceManager mManager;
|
||||
|
||||
private Context mContext;
|
||||
private Account mAccount;
|
||||
@@ -91,18 +102,16 @@ public class AccountTypePreferenceLoaderTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {ShadowAccountManager.class, ShadowContentResolver.class})
|
||||
public void updatePreferenceIntents_shouldRunRecursively() {
|
||||
final PreferenceManager preferenceManager = mock(PreferenceManager.class);
|
||||
// Top level
|
||||
PreferenceGroup prefRoot = spy(new PreferenceScreen(mContext, null));
|
||||
when(prefRoot.getPreferenceManager()).thenReturn(preferenceManager);
|
||||
when(prefRoot.getPreferenceManager()).thenReturn(mManager);
|
||||
Preference pref1 = mock(Preference.class);
|
||||
PreferenceGroup prefGroup2 = spy(new PreferenceScreen(mContext, null));
|
||||
when(prefGroup2.getPreferenceManager()).thenReturn(preferenceManager);
|
||||
when(prefGroup2.getPreferenceManager()).thenReturn(mManager);
|
||||
Preference pref3 = mock(Preference.class);
|
||||
PreferenceGroup prefGroup4 = spy(new PreferenceScreen(mContext, null));
|
||||
when(prefGroup4.getPreferenceManager()).thenReturn(preferenceManager);
|
||||
when(prefGroup4.getPreferenceManager()).thenReturn(mManager);
|
||||
prefRoot.addPreference(pref1);
|
||||
prefRoot.addPreference(prefGroup2);
|
||||
prefRoot.addPreference(pref3);
|
||||
@@ -114,7 +123,7 @@ public class AccountTypePreferenceLoaderTest {
|
||||
prefGroup2.addPreference(pref21);
|
||||
prefGroup2.addPreference(pref22);
|
||||
PreferenceGroup prefGroup41 = spy(new PreferenceScreen(mContext, null));
|
||||
when(prefGroup41.getPreferenceManager()).thenReturn(preferenceManager);
|
||||
when(prefGroup41.getPreferenceManager()).thenReturn(mManager);
|
||||
Preference pref42 = mock(Preference.class);
|
||||
prefGroup4.addPreference(prefGroup41);
|
||||
prefGroup4.addPreference(pref42);
|
||||
@@ -132,4 +141,113 @@ public class AccountTypePreferenceLoaderTest {
|
||||
verify(mPrefLoader).updatePreferenceIntents(prefGroup4, acctType, mAccount);
|
||||
verify(mPrefLoader).updatePreferenceIntents(prefGroup41, acctType, mAccount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateFragmentAllowlist_nullPrefGroup_emptyList() {
|
||||
Set<String> allowed = mPrefLoader.generateFragmentAllowlist(null);
|
||||
|
||||
assertThat(allowed).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateFragmentAllowlist_simpleGroupNoFragment_emptyList() {
|
||||
Preference pref = new Preference(mContext);
|
||||
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mManager);
|
||||
screen.addPreference(pref);
|
||||
|
||||
Set<String> allowed = mPrefLoader.generateFragmentAllowlist(screen);
|
||||
|
||||
assertThat(allowed).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateFragmentAllowlist_simpleGroupOneFragment_populatedList() {
|
||||
Preference pref = new Preference(mContext);
|
||||
pref.setFragment("test");
|
||||
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mManager);
|
||||
screen.addPreference(pref);
|
||||
|
||||
Set<String> allowed = mPrefLoader.generateFragmentAllowlist(screen);
|
||||
|
||||
assertThat(allowed).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateFragmentAllowlist_nestedGroupWithFragments_populatedList() {
|
||||
Preference pref = new Preference(mContext);
|
||||
pref.setFragment("test");
|
||||
PreferenceScreen nested = spy(new PreferenceScreen(mContext, null));
|
||||
PreferenceScreen parent = spy(new PreferenceScreen(mContext, null));
|
||||
when(nested.getPreferenceManager()).thenReturn(mManager);
|
||||
when(parent.getPreferenceManager()).thenReturn(mManager);
|
||||
parent.addPreference(nested);
|
||||
nested.addPreference(pref);
|
||||
|
||||
Set<String> allowed = mPrefLoader.generateFragmentAllowlist(parent);
|
||||
|
||||
assertThat(allowed).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterBlockedFragments_nullPrefGroup_noop() {
|
||||
// verify no NPE
|
||||
mPrefLoader.filterBlockedFragments(null, new ArraySet<>());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterBlockedFragments_simplePrefGroupNoFragment_noop() {
|
||||
Preference pref = spy(new Preference(mContext));
|
||||
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mManager);
|
||||
screen.addPreference(pref);
|
||||
|
||||
mPrefLoader.filterBlockedFragments(screen, new ArraySet<>());
|
||||
|
||||
verify(screen, never()).setOnPreferenceClickListener(any());
|
||||
verify(pref, never()).setOnPreferenceClickListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterBlockedFragments_simplePrefGroupWithAllowedFragment_noop() {
|
||||
Preference pref = spy(new Preference(mContext));
|
||||
pref.setFragment("test");
|
||||
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mManager);
|
||||
screen.addPreference(pref);
|
||||
|
||||
mPrefLoader.filterBlockedFragments(screen, Set.of("test"));
|
||||
|
||||
verify(screen, never()).setOnPreferenceClickListener(any());
|
||||
verify(pref, never()).setOnPreferenceClickListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterBlockedFragments_simplePrefGroupNoMatchFragment_overrideClick() {
|
||||
Preference pref = spy(new Preference(mContext));
|
||||
pref.setFragment("test");
|
||||
PreferenceScreen screen = spy(new PreferenceScreen(mContext, null));
|
||||
when(screen.getPreferenceManager()).thenReturn(mManager);
|
||||
screen.addPreference(pref);
|
||||
|
||||
mPrefLoader.filterBlockedFragments(screen, new ArraySet<>());
|
||||
|
||||
verify(pref).setOnPreferenceClickListener(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterBlockedFragments_nestedPrefGroupWithNoMatchFragment_overrideClick() {
|
||||
Preference pref = spy(new Preference(mContext));
|
||||
pref.setFragment("test");
|
||||
PreferenceScreen nested = spy(new PreferenceScreen(mContext, null));
|
||||
PreferenceScreen parent = spy(new PreferenceScreen(mContext, null));
|
||||
when(nested.getPreferenceManager()).thenReturn(mManager);
|
||||
when(parent.getPreferenceManager()).thenReturn(mManager);
|
||||
parent.addPreference(nested);
|
||||
nested.addPreference(pref);
|
||||
|
||||
mPrefLoader.filterBlockedFragments(parent, Set.of("nomatch", "other"));
|
||||
verify(pref).setOnPreferenceClickListener(any());
|
||||
}
|
||||
}
|
||||
|
@@ -272,7 +272,7 @@ public class BatteryOptimizeUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetAppOptimizationMode_Optimized_verifyAction() throws Exception {
|
||||
public void testResetAppOptimizationModeInternal_Optimized_verifyAction() throws Exception {
|
||||
runTestForResetWithMode(
|
||||
AppOpsManager.MODE_ALLOWED, /* allowListed */
|
||||
false,
|
||||
@@ -287,7 +287,8 @@ public class BatteryOptimizeUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetAppOptimizationMode_SystemOrDefault_verifyAction() throws Exception {
|
||||
public void testResetAppOptimizationModeInternal_SystemOrDefault_verifyAction()
|
||||
throws Exception {
|
||||
runTestForResetWithMode(
|
||||
AppOpsManager.MODE_ALLOWED, /* allowListed */
|
||||
true,
|
||||
@@ -304,7 +305,7 @@ public class BatteryOptimizeUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetAppOptimizationMode_Restricted_verifyAction() throws Exception {
|
||||
public void testResetAppOptimizationModeInternal_Restricted_verifyAction() throws Exception {
|
||||
runTestForResetWithMode(
|
||||
AppOpsManager.MODE_IGNORED, /* allowListed */
|
||||
false,
|
||||
@@ -315,7 +316,7 @@ public class BatteryOptimizeUtilsTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResetAppOptimizationMode_Unrestricted_verifyAction() throws Exception {
|
||||
public void testResetAppOptimizationModeInternal_Unrestricted_verifyAction() throws Exception {
|
||||
runTestForResetWithMode(
|
||||
AppOpsManager.MODE_ALLOWED, /* allowListed */
|
||||
true,
|
||||
@@ -346,7 +347,7 @@ public class BatteryOptimizeUtilsTest {
|
||||
doReturn(isSystemOrDefaultApp).when(mMockBackend).isSysAllowlisted(anyString());
|
||||
doReturn(isSystemOrDefaultApp).when(mMockBackend).isDefaultActiveApp(anyString(), anyInt());
|
||||
|
||||
BatteryOptimizeUtils.resetAppOptimizationMode(
|
||||
BatteryOptimizeUtils.resetAppOptimizationModeInternal(
|
||||
mContext,
|
||||
mMockIPackageManager,
|
||||
mMockAppOpsManager,
|
||||
|
@@ -18,6 +18,7 @@ package com.android.settings.fuelgauge.batteryusage
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeUtils
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_OPTIMIZED
|
||||
@@ -26,6 +27,7 @@ import com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNKNOWN
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeUtils.MODE_UNRESTRICTED
|
||||
import com.android.settings.fuelgauge.batteryusage.AppOptModeSharedPreferencesUtils.UNLIMITED_EXPIRE_TIME
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
@@ -39,9 +41,8 @@ import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.Spy
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AppOptModeSharedPreferencesUtilsTest {
|
||||
@get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@@ -52,7 +53,12 @@ class AppOptModeSharedPreferencesUtilsTest {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
AppOptModeSharedPreferencesUtils.deleteAppOptimizationModeEventByUid(context, UID)
|
||||
AppOptModeSharedPreferencesUtils.clearAll(context)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
AppOptModeSharedPreferencesUtils.clearAll(context)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,6 +66,16 @@ class AppOptModeSharedPreferencesUtilsTest {
|
||||
assertThat(AppOptModeSharedPreferencesUtils.getAllEvents(context)).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearAll_withData_verifyCleared() {
|
||||
insertAppOptModeEventForTest(expirationTime = 1000L)
|
||||
assertThat(AppOptModeSharedPreferencesUtils.getAllEvents(context)).hasSize(1)
|
||||
|
||||
AppOptModeSharedPreferencesUtils.clearAll(context)
|
||||
|
||||
assertThat(AppOptModeSharedPreferencesUtils.getAllEvents(context)).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun updateAppOptModeExpirationInternal_withExpirationTime_verifyData() {
|
||||
insertAppOptModeEventForTest(expirationTime = 1000L)
|
@@ -43,6 +43,7 @@ import android.net.ConnectivityManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
@@ -390,7 +391,7 @@ public class ProviderModelSliceTest {
|
||||
}
|
||||
|
||||
private PendingIntent getPrimaryAction() {
|
||||
final Intent intent = new Intent("android.settings.NETWORK_PROVIDER_SETTINGS")
|
||||
final Intent intent = new Intent(Settings.ACTION_NETWORK_PROVIDER_SETTINGS)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
return PendingIntent.getActivity(mContext, 0 /* requestCode */,
|
||||
intent, PendingIntent.FLAG_IMMUTABLE /* flags */);
|
||||
|
@@ -33,8 +33,10 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.IActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Flags;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
@@ -432,6 +434,36 @@ public class PrivateSpaceMaintainerTest {
|
||||
assertThat(getSecureSkipFirstUseHints()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPrivateSpace_psDoesNotExist_setsPrivateSpaceSettingsComponentDisabled() {
|
||||
mSetFlagsRule.enableFlags(
|
||||
android.multiuser.Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES);
|
||||
assumeTrue(mContext.getSystemService(UserManager.class).canAddPrivateProfile());
|
||||
PrivateSpaceMaintainer privateSpaceMaintainer =
|
||||
PrivateSpaceMaintainer.getInstance(mContext);
|
||||
privateSpaceMaintainer.createPrivateSpace();
|
||||
assertThat(privateSpaceMaintainer.getPrivateProfileHandle()).isNotNull();
|
||||
Context privateSpaceUserContext = mContext.createContextAsUser(
|
||||
privateSpaceMaintainer.getPrivateProfileHandle(),
|
||||
/* flags */ 0);
|
||||
|
||||
// Assert that private space settings launcher app icon is disabled
|
||||
ComponentName settingsComponentName = new ComponentName(privateSpaceUserContext,
|
||||
com.android.settings.Settings.class);
|
||||
int settingsComponentEnabledSetting = privateSpaceUserContext.getPackageManager()
|
||||
.getComponentEnabledSetting(settingsComponentName);
|
||||
assertThat(settingsComponentEnabledSetting)
|
||||
.isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
|
||||
|
||||
// Assert that private space settings create shortcut activity is disabled
|
||||
ComponentName shortcutPickerComponentName = new ComponentName(privateSpaceUserContext,
|
||||
com.android.settings.Settings.CreateShortcutActivity.class);
|
||||
int settingsShortcutPickerEnabledSetting = privateSpaceUserContext.getPackageManager()
|
||||
.getComponentEnabledSetting(shortcutPickerComponentName);
|
||||
assertThat(settingsShortcutPickerEnabledSetting)
|
||||
.isEqualTo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPrivateSpace_pSExists_doesNotChangeSkipFirstUseHints() {
|
||||
mSetFlagsRule.enableFlags(
|
||||
|
@@ -497,6 +497,8 @@ public class WifiHotspotRepositoryTest {
|
||||
SparseIntArray channels = mSoftApConfigCaptor.getValue().getChannels();
|
||||
assertThat(channels.get(BAND_2GHZ, CHANNEL_NOT_FOUND)).isNotEqualTo(CHANNEL_NOT_FOUND);
|
||||
assertThat(channels.get(BAND_2GHZ_5GHZ, CHANNEL_NOT_FOUND)).isNotEqualTo(CHANNEL_NOT_FOUND);
|
||||
assertThat(mSoftApConfigCaptor.getValue().getSecurityType())
|
||||
.isEqualTo(SECURITY_TYPE_WPA3_SAE_TRANSITION);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Reference in New Issue
Block a user