diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 321e5357c0e..3212d2f818d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1108,10 +1108,6 @@
android:label="@string/wallpaper_settings_fragment_title"
android:icon="@drawable/ic_wallpaper"
android:exported="true">
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
+ android:resource="@string/wallpaper_suggestion_title"/>
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9693707e5b1..6e869f892c9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -2967,7 +2967,7 @@
1440p QHD+
- Full resolution uses more of your battery. Switching to full resolution may cause some apps to restart.
+ Full resolution uses more of your battery. Switching your resolution may cause some apps to restart.
Colors
diff --git a/res/values/themes_suw.xml b/res/values/themes_suw.xml
index 79adbd8a408..07232a3b1e4 100644
--- a/res/values/themes_suw.xml
+++ b/res/values/themes_suw.xml
@@ -133,6 +133,43 @@
- @style/LockPatternStyle
+
+
+
+
@@ -238,6 +275,7 @@
+
diff --git a/src/com/android/settings/DefaultRingtonePreference.java b/src/com/android/settings/DefaultRingtonePreference.java
index 824a5a05dc1..9bf626c9898 100644
--- a/src/com/android/settings/DefaultRingtonePreference.java
+++ b/src/com/android/settings/DefaultRingtonePreference.java
@@ -51,7 +51,7 @@ public class DefaultRingtonePreference extends RingtonePreference {
return;
}
- String mimeType = getContext().getContentResolver().getType(ringtoneUri);
+ String mimeType = mUserContext.getContentResolver().getType(ringtoneUri);
if (mimeType == null) {
Log.e(TAG, "onSaveRingtone for URI:" + ringtoneUri
+ " ignored: failure to find mimeType (no access from this context?)");
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index bb217a0d20a..1a9bdc742fe 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -466,6 +466,15 @@ public class SettingsActivity extends SettingsBaseActivity
return false;
}
+ // If the activity's launch mode is "singleInstance", it can't be embedded in Settings since
+ // it will be created in a new task.
+ ActivityInfo info = intent.resolveActivityInfo(getPackageManager(),
+ PackageManager.MATCH_DEFAULT_ONLY);
+ if (info.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
+ Log.w(LOG_TAG, "launchMode: singleInstance");
+ return false;
+ }
+
if (intent.getBooleanExtra(EXTRA_IS_FROM_SLICE, false)) {
// Slice deep link starts the Intent using SubSettingLauncher. Returns true to show
// 2-pane deep link.
diff --git a/src/com/android/settings/SetupWizardUtils.java b/src/com/android/settings/SetupWizardUtils.java
index e0e9073a220..25e91598f3b 100644
--- a/src/com/android/settings/SetupWizardUtils.java
+++ b/src/com/android/settings/SetupWizardUtils.java
@@ -48,9 +48,9 @@ public class SetupWizardUtils {
if (WizardManagerHelper.isAnySetupWizard(intent)) {
if (ThemeHelper.isSetupWizardDayNightEnabled(context)) {
switch (theme) {
- // TODO(b/233032365): Create glif v4 theme for this case.
case ThemeHelper.THEME_GLIF_V4_LIGHT:
case ThemeHelper.THEME_GLIF_V4:
+ return R.style.GlifV4Theme_DayNight;
case ThemeHelper.THEME_GLIF_V3_LIGHT:
case ThemeHelper.THEME_GLIF_V3:
return R.style.GlifV3Theme_DayNight;
@@ -63,11 +63,12 @@ public class SetupWizardUtils {
}
} else {
switch (theme) {
- // TODO(b/233032365): Create glif v4 theme for this case.
case ThemeHelper.THEME_GLIF_V4_LIGHT:
+ return R.style.GlifV4Theme_Light;
+ case ThemeHelper.THEME_GLIF_V4:
+ return R.style.GlifV4Theme;
case ThemeHelper.THEME_GLIF_V3_LIGHT:
return R.style.GlifV3Theme_Light;
- case ThemeHelper.THEME_GLIF_V4:
case ThemeHelper.THEME_GLIF_V3:
return R.style.GlifV3Theme;
case ThemeHelper.THEME_GLIF_V2_LIGHT:
@@ -82,9 +83,9 @@ public class SetupWizardUtils {
}
} else {
switch (theme) {
- // TODO(b/233032365): Create glif v4 theme for this case.
case ThemeHelper.THEME_GLIF_V4_LIGHT:
case ThemeHelper.THEME_GLIF_V4:
+ return R.style.GlifV4Theme;
case ThemeHelper.THEME_GLIF_V3_LIGHT:
case ThemeHelper.THEME_GLIF_V3:
return R.style.GlifV3Theme;
diff --git a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
index f0b332904de..e3c577b189e 100644
--- a/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/HibernationSwitchPreferenceController.java
@@ -33,13 +33,9 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.permission.PermissionControllerManager;
import android.provider.DeviceConfig;
-import android.text.TextUtils;
import android.util.Slog;
import androidx.annotation.NonNull;
-import androidx.lifecycle.Lifecycle;
-import androidx.lifecycle.LifecycleObserver;
-import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.Preference;
import androidx.preference.SwitchPreference;
@@ -49,8 +45,7 @@ import com.google.common.annotations.VisibleForTesting;
* A PreferenceController handling the logic for exempting hibernation of app
*/
public final class HibernationSwitchPreferenceController extends AppInfoPreferenceControllerBase
- implements LifecycleObserver, AppOpsManager.OnOpChangedListener,
- Preference.OnPreferenceChangeListener {
+ implements Preference.OnPreferenceChangeListener {
private static final String TAG = "HibernationSwitchPrefController";
private String mPackageName;
private final AppOpsManager mAppOpsManager;
@@ -69,19 +64,6 @@ public final class HibernationSwitchPreferenceController extends AppInfoPreferen
mPermissionControllerManager = context.getSystemService(PermissionControllerManager.class);
}
- @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
- public void onResume() {
- if (mIsPackageSet) {
- mAppOpsManager.startWatchingMode(
- OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, mPackageName, this);
- }
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
- public void onPause() {
- mAppOpsManager.stopWatchingMode(this);
- }
-
@Override
public int getAvailabilityStatus() {
return isHibernationEnabled() && mIsPackageSet ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
@@ -148,14 +130,6 @@ public final class HibernationSwitchPreferenceController extends AppInfoPreferen
return mode == MODE_DEFAULT ? mIsPackageExemptByDefault : mode != MODE_ALLOWED;
}
- @Override
- public void onOpChanged(String op, String packageName) {
- if (OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED.equals(op)
- && TextUtils.equals(mPackageName, packageName)) {
- updateState(mPreference);
- }
- }
-
@Override
public boolean onPreferenceChange(Preference preference, Object isChecked) {
try {
diff --git a/src/com/android/settings/datausage/AppDataUsage.java b/src/com/android/settings/datausage/AppDataUsage.java
index f0d27997ff8..d57a2a18f79 100644
--- a/src/com/android/settings/datausage/AppDataUsage.java
+++ b/src/com/android/settings/datausage/AppDataUsage.java
@@ -40,6 +40,8 @@ import androidx.loader.content.Loader;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceCategory;
+import androidx.recyclerview.widget.DefaultItemAnimator;
+import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
import com.android.settings.applications.AppInfoBase;
@@ -105,6 +107,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
private Context mContext;
private ArrayList mCycles;
private long mSelectedCycle;
+ private boolean mIsLoading;
@Override
public void onCreate(Bundle icicle) {
@@ -226,6 +229,16 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
@Override
public void onResume() {
super.onResume();
+ // No animations will occur before:
+ // - LOADER_APP_USAGE_DATA initially updates the cycle
+ // - updatePrefs() initially updates the preference visibility
+ // This is mainly for the cycle spinner, because when the page is entered from the
+ // AppInfoDashboardFragment, there is no way to know whether the cycle data is available
+ // before finished the async loading.
+ // The animator will be set back if any page updates happens after loading, in
+ // setBackPreferenceListAnimatorIfLoaded().
+ mIsLoading = true;
+ getListView().setItemAnimator(null);
if (mDataSaverBackend != null) {
mDataSaverBackend.addListener(this);
}
@@ -297,7 +310,25 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
}
}
+ /**
+ * Sets back the preference list's animator if the loading is finished.
+ *
+ * The preference list's animator was temporarily removed before loading in onResume().
+ * When need to update the preference visibility in this page after the loading, adding the
+ * animator back to keeping the usual animations.
+ */
+ private void setBackPreferenceListAnimatorIfLoaded() {
+ if (mIsLoading) {
+ return;
+ }
+ RecyclerView recyclerView = getListView();
+ if (recyclerView.getItemAnimator() == null) {
+ recyclerView.setItemAnimator(new DefaultItemAnimator());
+ }
+ }
+
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
+ setBackPreferenceListAnimatorIfLoaded();
final EnforcedAdmin admin = RestrictedLockUtilsInternal.checkIfMeteredDataRestricted(
mContext, mPackageName, UserHandle.getUserId(mAppItem.key));
if (mRestrictBackground != null) {
@@ -448,6 +479,7 @@ public class AppDataUsage extends DataUsageBaseFragment implements OnPreferenceC
} else {
bindData(0 /* position */);
}
+ mIsLoading = false;
}
@Override
diff --git a/src/com/android/settings/datausage/AppDataUsagePreference.java b/src/com/android/settings/datausage/AppDataUsagePreference.java
index 3025a49bb6c..28058198d1a 100644
--- a/src/com/android/settings/datausage/AppDataUsagePreference.java
+++ b/src/com/android/settings/datausage/AppDataUsagePreference.java
@@ -20,6 +20,7 @@ import android.widget.ProgressBar;
import androidx.preference.PreferenceViewHolder;
+import com.android.settings.R;
import com.android.settingslib.AppItem;
import com.android.settingslib.net.UidDetail;
import com.android.settingslib.net.UidDetailProvider;
@@ -49,6 +50,9 @@ public class AppDataUsagePreference extends AppPreference {
if (mDetail != null) {
setAppInfo();
} else {
+ // Set a placeholder title before starting to fetch real title, this is necessary
+ // to avoid preference height change.
+ setTitle(R.string.summary_placeholder);
ThreadUtils.postOnBackgroundThread(() -> {
mDetail = provider.getUidDetail(mItem.key, true /* blocking */);
ThreadUtils.postOnMainThread(() -> setAppInfo());
diff --git a/src/com/android/settings/network/UiccSlotUtil.java b/src/com/android/settings/network/UiccSlotUtil.java
index 813b9d6826d..c9c52cb5c99 100644
--- a/src/com/android/settings/network/UiccSlotUtil.java
+++ b/src/com/android/settings/network/UiccSlotUtil.java
@@ -193,7 +193,7 @@ public class UiccSlotUtil {
if (slotInfo == null) {
return false;
}
- return !slotInfo.isRemovable();
+ return slotInfo.getIsEuicc();
})
.findFirst().orElse(-1);
diff --git a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
index 14431ee5e69..483d74638a7 100644
--- a/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
+++ b/tests/robotests/src/com/android/settings/datausage/AppDataUsageTest.java
@@ -48,6 +48,7 @@ import androidx.fragment.app.FragmentActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen;
+import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.applications.AppInfoBase;
import com.android.settings.testutils.FakeFeatureFactory;
@@ -240,6 +241,7 @@ public class AppDataUsageTest {
ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
+ when(mFragment.getListView()).thenReturn(mock(RecyclerView.class));
ShadowRestrictedLockUtilsInternal.setRestricted(true);
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
diff --git a/tests/unit/src/com/android/settings/DefaultRingtonePreferenceTest.java b/tests/unit/src/com/android/settings/DefaultRingtonePreferenceTest.java
index b9dea0167b5..7877684dce6 100644
--- a/tests/unit/src/com/android/settings/DefaultRingtonePreferenceTest.java
+++ b/tests/unit/src/com/android/settings/DefaultRingtonePreferenceTest.java
@@ -59,6 +59,7 @@ public class DefaultRingtonePreferenceTest {
when(mDefaultRingtonePreference.getRingtoneType())
.thenReturn(RingtoneManager.TYPE_RINGTONE);
mDefaultRingtonePreference.setUserId(1);
+ mDefaultRingtonePreference.mUserContext = context;
}
@Test
diff --git a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
index 2cf984558be..5aa73eaa308 100644
--- a/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
+++ b/tests/unit/src/com/android/settings/network/UiccSlotUtilTest.java
@@ -92,6 +92,14 @@ public class UiccSlotUtilTest {
assertThat(testSlot).isEqualTo(0);
}
+ @Test
+ public void getEsimSlotId_twoSimSlotsDeviceAndRemovableEsimIsSlot1_returnTheCorrectEsimSlot() {
+ when(mTelephonyManager.getUiccSlotsInfo()).thenReturn(
+ twoSimSlotsDeviceActivePsimActiveRemovableEsim());
+ int testSlot = UiccSlotUtil.getEsimSlotId(mContext);
+
+ assertThat(testSlot).isEqualTo(1);
+ }
@Test
public void getEsimSlotId_twoSimSlotsDeviceAndEsimIsSlot1_returnTheCorrectEsimSlot() {
@@ -729,6 +737,12 @@ public class UiccSlotUtilTest {
createUiccSlotInfo(true, false, 1, true)};
}
+ private UiccSlotInfo[] twoSimSlotsDeviceActivePsimActiveRemovableEsim() {
+ return new UiccSlotInfo[]{
+ createUiccSlotInfo(false, true, 0, true),
+ createUiccSlotInfo(true, true, 1, true)};
+ }
+
private UiccSlotInfo[] twoSimSlotsDeviceActiveEsimActivePsim() {
return new UiccSlotInfo[]{
createUiccSlotInfo(true, false, 0, true),