Merge "Remove dead code"
diff --git a/api/current.txt b/api/current.txt
index 5b5bd24..5931b31 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -42407,7 +42407,7 @@
}
public final class SubscriptionPlan implements android.os.Parcelable {
- method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+ method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
method public int describeContents();
method public int getDataLimitBehavior();
method public long getDataLimitBytes();
@@ -42429,9 +42429,7 @@
public static class SubscriptionPlan.Builder {
method public android.telephony.SubscriptionPlan build();
method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+ method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/api/system-current.txt b/api/system-current.txt
index 76a71cd..0bcb1c2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5191,7 +5191,7 @@
}
public final class SubscriptionPlan implements android.os.Parcelable {
- method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+ method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
method public int describeContents();
method public int getDataLimitBehavior();
method public long getDataLimitBytes();
@@ -5213,9 +5213,10 @@
public static class SubscriptionPlan.Builder {
method public android.telephony.SubscriptionPlan build();
method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
- method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+ method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
+ method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
+ method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
+ method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/api/test-current.txt b/api/test-current.txt
index f9402e4..d5b1399 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -492,6 +492,11 @@
method public int getProgramId();
}
+ public final class PlaybackParams implements android.os.Parcelable {
+ method public int getAudioStretchMode();
+ method public android.media.PlaybackParams setAudioStretchMode(int);
+ }
+
public static final class VolumeShaper.Configuration.Builder {
method public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 46d1264..5113fd0 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1145,6 +1145,21 @@
SUPPRESSED_EFFECT_NOTIFICATION_LIST
};
+ private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
+ SUPPRESSED_EFFECT_SCREEN_OFF,
+ SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
+ SUPPRESSED_EFFECT_LIGHTS,
+ SUPPRESSED_EFFECT_AMBIENT,
+ };
+
+ private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
+ SUPPRESSED_EFFECT_SCREEN_ON,
+ SUPPRESSED_EFFECT_PEEK,
+ SUPPRESSED_EFFECT_STATUS_BAR,
+ SUPPRESSED_EFFECT_BADGE,
+ SUPPRESSED_EFFECT_NOTIFICATION_LIST
+ };
+
/**
* Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
* Bitmask of SUPPRESSED_EFFECT_* constants.
@@ -1297,6 +1312,32 @@
return true;
}
+ /**
+ * @hide
+ */
+ public static boolean areAnyScreenOffEffectsSuppressed(int effects) {
+ for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) {
+ final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i];
+ if ((effects & effect) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @hide
+ */
+ public static boolean areAnyScreenOnEffectsSuppressed(int effects) {
+ for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) {
+ final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i];
+ if ((effects & effect) != 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static String suppressedEffectsToString(int effects) {
if (effects <= 0) return "";
final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 9f3df37..f7908b6 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -51,7 +51,6 @@
import android.util.EventLog;
import android.util.Log;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.MimeIconUtils;
import com.android.internal.util.Preconditions;
@@ -602,6 +601,8 @@
try {
return provider.getType(url);
} catch (RemoteException e) {
+ // Arbitrary and not worth documenting, as Activity
+ // Manager will kill this process shortly anyway.
return null;
} catch (java.lang.Exception e) {
Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
@@ -620,9 +621,7 @@
ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
return type;
} catch (RemoteException e) {
- // Arbitrary and not worth documenting, as Activity
- // Manager will kill this process shortly anyway.
- return null;
+ throw e.rethrowFromSystemServer();
} catch (java.lang.Exception e) {
Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
return null;
@@ -1964,6 +1963,7 @@
getContentService().registerContentObserver(uri, notifyForDescendents,
observer.getContentObserver(), userHandle, mTargetSdkVersion);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -1982,6 +1982,7 @@
contentObserver);
}
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2089,6 +2090,7 @@
syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0,
userHandle, mTargetSdkVersion);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2105,6 +2107,7 @@
observer != null && observer.deliverSelfNotifications(), flags,
userHandle, mTargetSdkVersion);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2126,6 +2129,7 @@
ContentProvider.getUriWithoutUserId(uri), modeFlags, /* toPackage= */ null,
resolveUserId(uri));
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2141,6 +2145,7 @@
ContentProvider.getUriWithoutUserId(uri), modeFlags, toPackage,
resolveUserId(uri));
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2160,6 +2165,7 @@
ContentProvider.getUriWithoutUserId(uri), modeFlags, /* toPackage= */ null,
resolveUserId(uri));
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2178,7 +2184,7 @@
return ActivityManager.getService()
.getPersistedUriPermissions(mPackageName, true).getList();
} catch (RemoteException e) {
- throw new RuntimeException("Activity manager has died", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2194,7 +2200,7 @@
return ActivityManager.getService()
.getPersistedUriPermissions(mPackageName, false).getList();
} catch (RemoteException e) {
- throw new RuntimeException("Activity manager has died", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2273,7 +2279,7 @@
try {
getContentService().syncAsUser(request, userId);
} catch(RemoteException e) {
- // Shouldn't happen.
+ throw e.rethrowFromSystemServer();
}
}
@@ -2285,7 +2291,7 @@
try {
getContentService().sync(request);
} catch(RemoteException e) {
- // Shouldn't happen.
+ throw e.rethrowFromSystemServer();
}
}
@@ -2349,6 +2355,7 @@
try {
getContentService().cancelSync(account, authority, null);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2360,6 +2367,7 @@
try {
getContentService().cancelSyncAsUser(account, authority, null, userId);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
}
@@ -2371,7 +2379,7 @@
try {
return getContentService().getSyncAdapterTypes();
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2383,7 +2391,7 @@
try {
return getContentService().getSyncAdapterTypesAsUser(userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2397,8 +2405,8 @@
try {
return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
} catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
}
- return ArrayUtils.emptyArray(String.class);
}
/**
@@ -2414,7 +2422,7 @@
try {
return getContentService().getSyncAutomatically(account, authority);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2427,7 +2435,7 @@
try {
return getContentService().getSyncAutomaticallyAsUser(account, authority, userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2453,8 +2461,7 @@
try {
getContentService().setSyncAutomaticallyAsUser(account, authority, sync, userId);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -2500,8 +2507,7 @@
try {
getContentService().addPeriodicSync(account, authority, extras, pollFrequency);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -2540,7 +2546,7 @@
try {
getContentService().removePeriodicSync(account, authority, extras);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2564,8 +2570,7 @@
try {
getContentService().cancelRequest(request);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -2582,7 +2587,7 @@
try {
return getContentService().getPeriodicSyncs(account, authority, null);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2596,7 +2601,7 @@
try {
return getContentService().getIsSyncable(account, authority);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2609,7 +2614,7 @@
try {
return getContentService().getIsSyncableAsUser(account, authority, userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2623,8 +2628,7 @@
try {
getContentService().setIsSyncable(account, authority, syncable);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -2640,7 +2644,7 @@
try {
return getContentService().getMasterSyncAutomatically();
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2652,7 +2656,7 @@
try {
return getContentService().getMasterSyncAutomaticallyAsUser(userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2676,8 +2680,7 @@
try {
getContentService().setMasterSyncAutomaticallyAsUser(sync, userId);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -2701,7 +2704,7 @@
try {
return getContentService().isSyncActive(account, authority, null);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2727,7 +2730,7 @@
}
return syncs.get(0);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2744,7 +2747,7 @@
try {
return getContentService().getCurrentSyncs();
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2756,7 +2759,7 @@
try {
return getContentService().getCurrentSyncsAsUser(userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2771,7 +2774,7 @@
try {
return getContentService().getSyncStatus(account, authority, null);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2784,7 +2787,7 @@
try {
return getContentService().getSyncStatusAsUser(account, authority, null, userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2809,7 +2812,7 @@
try {
return getContentService().isSyncPendingAsUser(account, authority, null, userId);
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2841,7 +2844,7 @@
getContentService().addStatusChangeListener(mask, observer);
return observer;
} catch (RemoteException e) {
- throw new RuntimeException("the ContentService should always be reachable", e);
+ throw e.rethrowFromSystemServer();
}
}
@@ -2856,8 +2859,7 @@
try {
getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle);
} catch (RemoteException e) {
- // exception ignored; if this is thrown then it means the runtime is in the midst of
- // being restarted
+ throw e.rethrowFromSystemServer();
}
}
@@ -3027,9 +3029,7 @@
return sContentService;
}
IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
- if (false) Log.v("ContentService", "default service binder = " + b);
sContentService = IContentService.Stub.asInterface(b);
- if (false) Log.v("ContentService", "default service = " + sContentService);
return sContentService;
}
@@ -3038,7 +3038,7 @@
return mPackageName;
}
- private static IContentService sContentService;
+ private static volatile IContentService sContentService;
private final Context mContext;
final String mPackageName;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d734aa3..6e952c0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6137,7 +6137,9 @@
* signed. This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
* since it takes into account the possibility of signing certificate rotation, except in the
* case of packages that are signed by multiple certificates, for which signing certificate
- * rotation is not supported.
+ * rotation is not supported. This method is analogous to using {@code getPackageInfo} with
+ * {@code GET_SIGNING_CERTIFICATES} and then searching through the resulting {@code
+ * signingCertificateHistory} field to see if the desired certificate is present.
*
* @param packageName package whose signing certificates to check
* @param certificate signing certificate for which to search
@@ -6151,13 +6153,19 @@
}
/**
- * Searches the set of signing certificates by which the given uid has proven to have been
- * signed. This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
+ * Searches the set of signing certificates by which the package(s) for the given uid has proven
+ * to have been signed. For multiple packages sharing the same uid, this will return the
+ * signing certificates found in the signing history of the "newest" package, where "newest"
+ * indicates the package with the newest signing certificate in the shared uid group. This
+ * method should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
* since it takes into account the possibility of signing certificate rotation, except in the
* case of packages that are signed by multiple certificates, for which signing certificate
- * rotation is not supported.
+ * rotation is not supported. This method is analogous to using {@code getPackagesForUid}
+ * followed by {@code getPackageInfo} with {@code GET_SIGNING_CERTIFICATES}, selecting the
+ * {@code PackageInfo} of the newest-signed bpackage , and finally searching through the
+ * resulting {@code signingCertificateHistory} field to see if the desired certificate is there.
*
- * @param uid package whose signing certificates to check
+ * @param uid uid whose signing certificates to check
* @param certificate signing certificate for which to search
* @param type representation of the {@code certificate}
* @return true if this package was or is signed by exactly the certificate {@code certificate}
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 1a28732..e84c85e 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -19,7 +19,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.BackupUtils;
-import android.util.Pair;
+import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.util.Preconditions;
@@ -136,7 +136,7 @@
return 0;
}
- public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+ public Iterator<Range<ZonedDateTime>> cycleIterator() {
return cycleRule.cycleIterator();
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index bf6b7e0..6546c39 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -31,6 +31,7 @@
import android.os.UserHandle;
import android.util.DebugUtils;
import android.util.Pair;
+import android.util.Range;
import com.google.android.collect.Sets;
@@ -258,8 +259,21 @@
}
/** {@hide} */
+ @Deprecated
public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
- return policy.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
+ return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public Pair<ZonedDateTime, ZonedDateTime> next() {
+ final Range<ZonedDateTime> r = it.next();
+ return Pair.create(r.getLower(), r.getUpper());
+ }
+ };
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 770ffc9..b644c1d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7384,6 +7384,17 @@
BOOLEAN_VALIDATOR;
/**
+ * Whether the swipe up gesture to switch apps should be enabled.
+ *
+ * @hide
+ */
+ public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED =
+ "swipe_up_to_switch_apps_enabled";
+
+ private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR =
+ BOOLEAN_VALIDATOR;
+
+ /**
* Whether or not the smart camera lift trigger that launches the camera when the user moves
* the phone into a position for taking photos should be enabled.
*
@@ -7894,6 +7905,7 @@
NIGHT_DISPLAY_AUTO_MODE,
SYNC_PARENT_SOUNDS,
CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+ SWIPE_UP_TO_SWITCH_APPS_ENABLED,
CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
SYSTEM_NAVIGATION_KEYS_ENABLED,
QS_TILES,
@@ -8027,6 +8039,8 @@
VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR);
VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR);
+ VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED,
+ SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR);
VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR);
VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED,
@@ -8938,6 +8952,20 @@
/** {@hide} */
public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
+ /** {@hide} */
+ public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
+ /** {@hide} */
+ public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
+ /** {@hide} */
+ public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
+ /** {@hide} */
+ public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
+ /** {@hide} */
+ public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH = "netpolicy_quota_frac_multipath";
+
+ /** {@hide} */
+ public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
+
/**
* User preference for which network(s) should be used. Only the
* connectivity service should touch this.
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 3830b7a..daecea7 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1487,14 +1487,18 @@
/**
* Returns a description of the current do not disturb settings from config.
* - If turned on manually and end time is known, returns end time.
+ * - If turned on manually and end time is on forever until turned off, return null if
+ * describeForeverCondition is false, else return String describing indefinite behavior
* - If turned on by an automatic rule, returns the automatic rule name.
* - If on due to an app, returns the app name.
* - If there's a combination of rules/apps that trigger, then shows the one that will
* last the longest if applicable.
- * @return null if do not disturb is off.
+ * @return null if DND is off or describeForeverCondition is false and
+ * DND is on forever (until turned off)
*/
- public static String getDescription(Context context, boolean zenOn, ZenModeConfig config) {
- if (!zenOn) {
+ public static String getDescription(Context context, boolean zenOn, ZenModeConfig config,
+ boolean describeForeverCondition) {
+ if (!zenOn || config == null) {
return null;
}
@@ -1513,8 +1517,11 @@
} else {
if (id == null) {
// Do not disturb manually triggered to remain on forever until turned off
- // No subtext
- return null;
+ if (describeForeverCondition) {
+ return context.getString(R.string.zen_mode_forever);
+ } else {
+ return null;
+ }
} else {
latestEndTime = tryParseCountdownConditionId(id);
if (latestEndTime > 0) {
diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java
index 9f115eb..975ad48 100644
--- a/core/java/android/util/RecurrenceRule.java
+++ b/core/java/android/util/RecurrenceRule.java
@@ -158,7 +158,7 @@
&& period.getDays() == 0;
}
- public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+ public Iterator<Range<ZonedDateTime>> cycleIterator() {
if (period != null) {
return new RecurringIterator();
} else {
@@ -166,7 +166,7 @@
}
}
- private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+ private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> {
boolean hasNext;
public NonrecurringIterator() {
@@ -179,13 +179,13 @@
}
@Override
- public Pair<ZonedDateTime, ZonedDateTime> next() {
+ public Range<ZonedDateTime> next() {
hasNext = false;
- return new Pair<>(start, end);
+ return new Range<>(start, end);
}
}
- private class RecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+ private class RecurringIterator implements Iterator<Range<ZonedDateTime>> {
int i;
ZonedDateTime cycleStart;
ZonedDateTime cycleEnd;
@@ -231,12 +231,12 @@
}
@Override
- public Pair<ZonedDateTime, ZonedDateTime> next() {
+ public Range<ZonedDateTime> next() {
if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
- Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd);
+ Range<ZonedDateTime> r = new Range<>(cycleStart, cycleEnd);
i--;
updateCycle();
- return p;
+ return r;
}
}
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index f0f30a0..372362f 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -503,6 +503,14 @@
/**
* @hide
+ * @return {@code true} if the IME is a trusted system component (e.g. pre-installed)
+ */
+ public boolean isSystem() {
+ return (mService.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+
+ /**
+ * @hide
*/
public boolean isAuxiliaryIme() {
return mIsAuxIme;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 9a082ec..ddba477 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -129,16 +129,16 @@
}
// ----------------------------------------------------------------------
- public static boolean isSystemIme(InputMethodInfo inputMethod) {
- return (inputMethod.getServiceInfo().applicationInfo.flags
- & ApplicationInfo.FLAG_SYSTEM) != 0;
+ @Deprecated
+ public static boolean isSystemIme(@NonNull InputMethodInfo inputMethod) {
+ return inputMethod.isSystem();
}
public static boolean isSystemImeThatHasSubtypeOf(final InputMethodInfo imi,
final Context context, final boolean checkDefaultAttribute,
@Nullable final Locale requiredLocale, final boolean checkCountry,
final String requiredSubtypeMode) {
- if (!isSystemIme(imi)) {
+ if (!imi.isSystem()) {
return false;
}
if (checkDefaultAttribute && !imi.isDefault(context)) {
@@ -182,7 +182,7 @@
private static boolean isSystemAuxilialyImeThatHasAutomaticSubtype(final InputMethodInfo imi,
final Context context, final boolean checkDefaultAttribute) {
- if (!isSystemIme(imi)) {
+ if (!imi.isSystem()) {
return false;
}
if (checkDefaultAttribute && !imi.isDefault(context)) {
@@ -435,12 +435,11 @@
if (imi.isAuxiliaryIme()) {
continue;
}
- if (InputMethodUtils.isSystemIme(imi)
- && containsSubtypeOf(imi, ENGLISH_LOCALE, false /* checkCountry */,
- SUBTYPE_MODE_KEYBOARD)) {
+ if (imi.isSystem() && containsSubtypeOf(
+ imi, ENGLISH_LOCALE, false /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
return imi;
}
- if (firstFoundSystemIme < 0 && InputMethodUtils.isSystemIme(imi)) {
+ if (firstFoundSystemIme < 0 && imi.isSystem()) {
firstFoundSystemIme = i;
}
}
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 3de8c39..237efd8 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -213,6 +213,13 @@
optional SettingProto keyguard_slice_uri = 29;
optional SettingProto last_setup_shown = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ message Launcher {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto swipe_up_to_switch_apps_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Launcher launcher = 70;
+
message Location {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -479,5 +486,5 @@
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 70;
+ // Next tag = 71;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index da15506..c5ab2e6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -487,6 +487,7 @@
<protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
<protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
<protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
+ <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" />
<protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
<protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8443a67..4ce89c9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -974,6 +974,9 @@
-->
<integer name="config_longPressOnBackBehavior">0</integer>
+ <!-- Allows activities to be launched on a long press on power during device setup. -->
+ <bool name="config_allowStartActivityForLongPressOnPowerInSetup">false</bool>
+
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index f8659e2..d722961 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -128,6 +128,9 @@
<style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
<style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Material.TextView.ListSeparator"/>
<style name="Widget.DeviceDefault.TimePicker" parent="Widget.Material.TimePicker"/>
+ <style name="Widget.DeviceDefault.Toolbar" parent="Widget.Material.Toolbar">
+ <item name="titleTextAppearance">@style/TextAppearance.DeviceDefault.Widget.Toolbar.Title</item>
+ </style>
<style name="Widget.DeviceDefault.Light" parent="Widget.Material.Light"/>
<style name="Widget.DeviceDefault.Light.Button" parent="Widget.Material.Light.Button"/>
@@ -186,7 +189,9 @@
<style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Material.Light.ActionBar.TabView"/>
<style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Material.Light.ActionBar.TabText"/>
<style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Material.Light.ActionBar.TabBar"/>
- <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Material.Light.ActionBar.Solid"/>
+ <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Material.Light.ActionBar.Solid">
+ <item name="titleTextStyle">@style/TextAppearance.DeviceDefault.Widget.ActionBar.Title</item>
+ </style>
<!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
<style name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" parent="Widget.Holo.Light.ActionBar.Solid.Inverse"/>
<!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
@@ -242,7 +247,9 @@
<style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Material.Widget.PopupMenu"/>
<style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Material.Widget.PopupMenu.Large"/>
<style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Material.Widget.PopupMenu.Small"/>
- <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title"/>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title">
+ <item name="fontFamily">@string/config_headlineFontFamilyMedium</item>
+ </style>
<style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Widget.ActionBar.Subtitle"/>
<style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Material.Widget.ActionMode.Title"/>
<style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Widget.ActionMode.Subtitle"/>
@@ -261,6 +268,7 @@
<!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
<style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse"/>
<style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Material.Widget.ActionBar.Menu"/>
+ <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Title" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Title" />
<!-- Preference Styles -->
<style name="Preference.DeviceDefault" parent="Preference.Material"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5856648..ce7f1ff 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -434,6 +434,7 @@
<java-symbol type="integer" name="config_veryLongPressOnPowerBehavior" />
<java-symbol type="integer" name="config_veryLongPressTimeout" />
<java-symbol type="integer" name="config_longPressOnBackBehavior" />
+ <java-symbol type="bool" name="config_allowStartActivityForLongPressOnPowerInSetup" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
<java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
<java-symbol type="integer" name="config_max_pan_devices" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index cf7b3b6..fd6cc95 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -181,6 +181,9 @@
<item name="actionBarStyle">@style/Widget.DeviceDefault.ActionBar.Solid</item>
<item name="actionModePopupWindowStyle">@style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
<item name="buttonBarStyle">@style/DeviceDefault.ButtonBar</item>
<item name="segmentedButtonStyle">@style/DeviceDefault.SegmentedButton</item>
@@ -233,6 +236,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar. This theme
@@ -257,6 +263,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -283,6 +292,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -308,6 +320,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -341,6 +356,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -365,6 +383,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -388,6 +409,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -412,6 +436,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -452,6 +479,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -477,6 +507,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -500,6 +533,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -525,6 +561,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -549,6 +588,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -573,6 +615,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault style for input methods, which is used by the
@@ -597,6 +642,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault style for input methods, which is used by the
@@ -621,6 +669,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -645,6 +696,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
@@ -667,6 +721,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -689,6 +746,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -822,6 +882,9 @@
<item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item>
<item name="actionModePopupWindowStyle">@style/Widget.DeviceDefault.Light.PopupWindow.ActionMode</item>
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
<item name="buttonBarStyle">@style/DeviceDefault.Light.ButtonBar</item>
<item name="segmentedButtonStyle">@style/DeviceDefault.Light.SegmentedButton</item>
@@ -869,6 +932,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -892,6 +958,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -916,6 +985,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -942,6 +1014,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -967,6 +1042,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -998,6 +1076,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -1025,6 +1106,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -1051,6 +1135,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -1078,6 +1165,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1131,6 +1221,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -1159,6 +1252,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -1185,6 +1281,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -1210,6 +1309,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -1234,6 +1336,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
@@ -1256,6 +1361,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -1278,11 +1386,15 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for a window that should look like the Settings app. -->
<style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings">
<!-- action bar -->
+ <item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item>
<item name="actionBarTheme">@style/ThemeOverlay.DeviceDefault.ActionBar.Accent</item>
<item name="popupTheme">@style/ThemeOverlay.DeviceDefault.Popup.Light</item>
@@ -1313,6 +1425,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- @hide DeviceDefault theme for a window that should use Settings theme colors
@@ -1337,6 +1452,9 @@
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
<!-- volume background -->
<item name="panelColorBackground">@color/primary_material_light</item>
</style>
@@ -1352,6 +1470,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -1376,6 +1497,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.Material.Settings.Dialog">
@@ -1402,6 +1526,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Settings.DialogWhenLarge" parent="Theme.Material.Settings.DialogWhenLarge">
@@ -1428,6 +1555,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -1454,6 +1584,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -1488,6 +1621,9 @@
<!-- Progress bar attributes -->
<item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
<item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+ <!-- Toolbar attributes -->
+ <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
</style>
<!-- DeviceDefault theme for the default system theme. -->
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d75a476..613ab6d 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -303,6 +303,12 @@
Settings.Global.NETSTATS_UID_TAG_DELETE_AGE,
Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES,
Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE,
+ Settings.Global.NETPOLICY_QUOTA_ENABLED,
+ Settings.Global.NETPOLICY_QUOTA_UNLIMITED,
+ Settings.Global.NETPOLICY_QUOTA_LIMITED,
+ Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS,
+ Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH,
+ Settings.Global.NETPOLICY_OVERRIDE_ENABLED,
Settings.Global.NETWORK_AVOID_BAD_WIFI,
Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES,
Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE,
diff --git a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
index 42b6048..39d492d 100644
--- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
+++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
@@ -57,13 +57,13 @@
assertTrue(r.isMonthly());
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
- assertEquals(Pair.create(
+ assertEquals(new Range<>(
ZonedDateTime.parse("2015-11-14T00:00:00.00Z"),
ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next());
assertTrue(it.hasNext());
- assertEquals(Pair.create(
+ assertEquals(new Range<>(
ZonedDateTime.parse("2015-10-14T00:00:00.00Z"),
ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next());
}
@@ -77,13 +77,13 @@
assertFalse(r.isMonthly());
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
- assertEquals(Pair.create(
+ assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-17T00:11:00.00Z"),
ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next());
assertTrue(it.hasNext());
- assertEquals(Pair.create(
+ assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-14T00:11:00.00Z"),
ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next());
assertFalse(it.hasNext());
@@ -98,9 +98,9 @@
assertFalse(r.isMonthly());
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertTrue(it.hasNext());
- assertEquals(Pair.create(
+ assertEquals(new Range<>(
ZonedDateTime.parse("2010-11-14T00:11:00.000Z"),
ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next());
assertFalse(it.hasNext());
@@ -112,7 +112,7 @@
assertFalse(r.isMonthly());
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
assertFalse(it.hasNext());
}
@@ -122,22 +122,22 @@
ZonedDateTime.parse("2030-01-31T00:00:00.000Z"),
Period.ofMonths(1));
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
ZonedDateTime lastStart = null;
int months = 0;
while (it.hasNext()) {
- final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
+ final Range<ZonedDateTime> cycle = it.next();
// Make sure cycle has reasonable length
- final long length = cycle.second.toEpochSecond() - cycle.first.toEpochSecond();
+ final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond();
assertTrue(cycle + " must be more than 4 weeks", length >= 2419200);
assertTrue(cycle + " must be less than 5 weeks", length <= 3024000);
// Make sure we have no gaps
if (lastStart != null) {
- assertEquals(lastStart, cycle.second);
+ assertEquals(lastStart, cycle.getUpper());
}
- lastStart = cycle.first;
+ lastStart = cycle.getLower();
months++;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 20c22b7..18dd97f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -738,6 +738,23 @@
/**
* Creates a typeface object that best matches the specified existing typeface and the specified
* weight and italic style
+ * <p>Below are numerical values and corresponding common weight names.</p>
+ * <table>
+ * <thead>
+ * <tr><th>Value</th><th>Common weight name</th></tr>
+ * </thead>
+ * <tbody>
+ * <tr><td>100</td><td>Thin</td></tr>
+ * <tr><td>200</td><td>Extra Light</td></tr>
+ * <tr><td>300</td><td>Light</td></tr>
+ * <tr><td>400</td><td>Normal</td></tr>
+ * <tr><td>500</td><td>Medium</td></tr>
+ * <tr><td>600</td><td>Semi Bold</td></tr>
+ * <tr><td>700</td><td>Bold</td></tr>
+ * <tr><td>800</td><td>Extra Bold</td></tr>
+ * <tr><td>900</td><td>Black</td></tr>
+ * </tbody>
+ * </table>
*
* <p>
* This method is thread safe.
@@ -749,6 +766,9 @@
* @param italic {@code true} if italic style is desired to be drawn. Otherwise, {@code false}
* @return A {@link Typeface} object for drawing specified weight and italic style. Never
* returns {@code null}
+ *
+ * @see #getWeight()
+ * @see #isItalic()
*/
public static @NonNull Typeface create(@Nullable Typeface family,
@IntRange(from = 1, to = 1000) int weight, boolean italic) {
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 0a6c45b..7b14322 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -36,6 +36,7 @@
bool Properties::skipEmptyFrames = true;
bool Properties::useBufferAge = true;
bool Properties::enablePartialUpdates = true;
+bool Properties::usePresentTime = true;
DebugLevel Properties::debugLevel = kDebugDisabled;
OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
@@ -135,6 +136,7 @@
skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true);
useBufferAge = property_get_bool(PROPERTY_USE_BUFFER_AGE, true);
enablePartialUpdates = property_get_bool(PROPERTY_ENABLE_PARTIAL_UPDATES, true);
+ usePresentTime = property_get_bool(PROPERTY_USE_PRESENT_TIME, true);
filterOutTestOverhead = property_get_bool(PROPERTY_FILTER_TEST_OVERHEAD, false);
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 764c502..1a0bdfd 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -151,6 +151,12 @@
*/
#define PROPERTY_ENABLE_PARTIAL_UPDATES "debug.hwui.use_partial_updates"
+/**
+ * Setting this to "false" will disable the use of the EGL_ANDROID_presentation_time extension
+ * and prevents more precise control over swap behavior & timings.
+ */
+#define PROPERTY_USE_PRESENT_TIME "debug.hwui.use_present_time"
+
#define PROPERTY_FILTER_TEST_OVERHEAD "debug.hwui.filter_test_overhead"
/**
@@ -220,6 +226,7 @@
static bool skipEmptyFrames;
static bool useBufferAge;
static bool enablePartialUpdates;
+ static bool usePresentTime;
// TODO: Move somewhere else?
static constexpr float textGamma = 1.45f;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 0e4b6f9..d983200 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -17,6 +17,7 @@
#include "CanvasContext.h"
#include <GpuMemoryTracker.h>
+#include "../Properties.h"
#include "AnimationContext.h"
#include "Caches.h"
#include "EglManager.h"
@@ -33,7 +34,6 @@
#include "renderstate/Stencil.h"
#include "utils/GLUtils.h"
#include "utils/TimeUtils.h"
-#include "../Properties.h"
#include <cutils/properties.h>
#include <private/hwui/DrawGlInfo.h>
@@ -190,6 +190,7 @@
if (hasSurface) {
mHaveNewSurface = true;
mSwapHistory.clear();
+ updateBufferCount();
} else {
mRenderThread.removeFrameCallback(this);
}
@@ -423,6 +424,9 @@
waitOnFences();
+ frame.setPresentTime(mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+ (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)));
+
bool requireSwap = false;
bool didSwap =
mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -668,6 +672,26 @@
return mFrameNumber;
}
+void overrideBufferCount(const sp<Surface>& surface, int bufferCount) {
+ struct SurfaceExposer : Surface {
+ using Surface::setBufferCount;
+ };
+ // Protected is just a sign, not a cop
+ ((*surface.get()).*&SurfaceExposer::setBufferCount)(bufferCount);
+}
+
+void CanvasContext::updateBufferCount() {
+ overrideBufferCount(mNativeSurface, 3 + mRenderAheadDepth);
+}
+
+void CanvasContext::setRenderAheadDepth(int renderAhead) {
+ if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+ return;
+ }
+ mRenderAheadDepth = renderAhead;
+ updateBufferCount();
+}
+
SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
if (frame.width() != mLastFrameWidth || frame.height() != mLastFrameHeight) {
// can't rely on prior content of window if viewport size changes
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index aaef85a..930498af3 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -78,7 +78,7 @@
bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator,
ErrorHandler* errorHandler) {
return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut,
- errorHandler);
+ errorHandler);
}
/**
@@ -188,6 +188,8 @@
IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
+ void setRenderAheadDepth(int renderAhead);
+
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -200,6 +202,7 @@
void freePrefetchedLayers();
bool isSwapChainStuffed();
+ void updateBufferCount();
SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
@@ -225,6 +228,7 @@
RingBuffer<SwapHistory, 3> mSwapHistory;
int64_t mFrameNumber = -1;
+ int mRenderAheadDepth = 0;
// last vsync for a dropped frame due to stuffed queue
nsecs_t mLastDropVsync = 0;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 778e768..5b0e281 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -103,9 +103,8 @@
// Even if we aren't drawing this vsync pulse the next frame number will still be accurate
if (CC_UNLIKELY(callback)) {
- context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
- callback(frameNr);
- });
+ context->enqueueFrameWork(
+ [ callback, frameNr = context->getFrameNumber() ]() { callback(frameNr); });
}
if (CC_LIKELY(canDrawThisFrame)) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 6e239e3..3a49beb 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -83,6 +83,7 @@
bool glColorSpace = false;
bool scRGB = false;
bool contextPriority = false;
+ bool presentTime = false;
} EglExtensions;
EglManager::EglManager(RenderThread& thread)
@@ -170,6 +171,7 @@
EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
#endif
EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
+ EglExtensions.presentTime = extensions.has("EGL_ANDROID_presentation_time");
}
bool EglManager::hasEglContext() {
@@ -242,7 +244,7 @@
&numConfigs) ||
numConfigs != 1) {
ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
- eglErrorString());
+ eglErrorString());
EglExtensions.pixelFormatFloat = false;
}
}
@@ -437,6 +439,13 @@
fence();
}
+ if (EglExtensions.presentTime && Properties::usePresentTime) {
+ if (!eglPresentationTimeANDROID(mEglDisplay, frame.mSurface, frame.mPresentTime)) {
+ LOG_ALWAYS_FATAL("Failed to set presentation time on surface %p, error=%s",
+ (void*)frame.mSurface, eglErrorString());
+ }
+ }
+
EGLint rects[4];
frame.map(screenDirty, rects);
eglSwapBuffersWithDamageKHR(mEglDisplay, frame.mSurface, rects, screenDirty.isEmpty() ? 0 : 1);
diff --git a/libs/hwui/renderthread/Frame.h b/libs/hwui/renderthread/Frame.h
index d266faa..03cf95d 100644
--- a/libs/hwui/renderthread/Frame.h
+++ b/libs/hwui/renderthread/Frame.h
@@ -37,6 +37,8 @@
// for what this means
int32_t bufferAge() const { return mBufferAge; }
+ void setPresentTime(int64_t presentTime) { mPresentTime = presentTime; }
+
private:
Frame() {}
friend class EglManager;
@@ -44,6 +46,7 @@
int32_t mWidth;
int32_t mHeight;
int32_t mBufferAge;
+ int64_t mPresentTime;
EGLSurface mSurface;
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index 876af47..1925808 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -22,8 +22,8 @@
#include "GlLayer.h"
#include "OpenGLReadback.h"
#include "ProfileRenderer.h"
-#include "renderstate/RenderState.h"
#include "TreeInfo.h"
+#include "renderstate/RenderState.h"
#include <cutils/properties.h>
#include <strings.h>
@@ -203,8 +203,7 @@
bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
const DamageAccumulator& damageAccumulator,
- bool wideColorGamut,
- ErrorHandler* errorHandler) {
+ bool wideColorGamut, ErrorHandler* errorHandler) {
RenderState& renderState = mRenderThread.renderState();
OffscreenBufferPool& layerPool = renderState.layerPool();
bool transformUpdateNeeded = false;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 39dcde0..a1a2bad 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -286,6 +286,12 @@
});
}
+void RenderProxy::setRenderAheadDepth(int renderAhead) {
+ mRenderThread.queue().post([ context = mContext, renderAhead ]() {
+ context->setRenderAheadDepth(renderAhead);
+ });
+}
+
int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
SkBitmap* bitmap) {
auto& thread = RenderThread::getInstance();
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 433adeb..ca20755 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -117,7 +117,23 @@
ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
- ANDROID_API long getDroppedFrameReportCount();
+
+ /**
+ * Sets a render-ahead depth on the backing renderer. This will increase latency by
+ * <swapInterval> * renderAhead and increase memory usage by (3 + renderAhead) * <resolution>.
+ * In return the renderer will be less susceptible to jitter, resulting in a smoother animation.
+ *
+ * Not recommended to use in response to anything touch driven, but for canned animations
+ * where latency is not a concern careful use may be beneficial.
+ *
+ * Note that when increasing this there will be a frame gap of N frames where N is
+ * renderAhead - <current renderAhead>. When decreasing this if there are any pending
+ * frames they will retain their prior renderAhead value, so it will take a few frames
+ * for the decrease to flush through.
+ *
+ * @param renderAhead How far to render ahead, must be in the range [0..2]
+ */
+ ANDROID_API void setRenderAheadDepth(int renderAhead);
ANDROID_API static int copySurfaceInto(sp<Surface>& surface, int left, int top, int right,
int bottom, SkBitmap* bitmap);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 6a2a025..4b154e6 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -25,8 +25,8 @@
#include "hwui/Bitmap.h"
#include "pipeline/skia/SkiaOpenGLPipeline.h"
#include "pipeline/skia/SkiaOpenGLReadback.h"
-#include "pipeline/skia/SkiaVulkanReadback.h"
#include "pipeline/skia/SkiaVulkanPipeline.h"
+#include "pipeline/skia/SkiaVulkanReadback.h"
#include "renderstate/RenderState.h"
#include "renderthread/OpenGLPipeline.h"
#include "utils/FatVector.h"
@@ -93,14 +93,11 @@
DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {}
virtual void requestNextVsync() override {
- mRenderThread->queue().postDelayed(16_ms, [this]() {
- mRenderThread->drainDisplayEventQueue();
- });
+ mRenderThread->queue().postDelayed(16_ms,
+ [this]() { mRenderThread->drainDisplayEventQueue(); });
}
- virtual nsecs_t latestVsyncEvent() override {
- return systemTime(CLOCK_MONOTONIC);
- }
+ virtual nsecs_t latestVsyncEvent() override { return systemTime(CLOCK_MONOTONIC); }
private:
RenderThread* mRenderThread;
@@ -147,13 +144,13 @@
auto receiver = std::make_unique<DisplayEventReceiver>();
status_t status = receiver->initCheck();
LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
- "Initialization of DisplayEventReceiver "
- "failed with status: %d",
- status);
+ "Initialization of DisplayEventReceiver "
+ "failed with status: %d",
+ status);
// Register the FD
mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT,
- RenderThread::displayEventReceiverCallback, this);
+ RenderThread::displayEventReceiverCallback, this);
mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver));
} else {
mVsyncSource = new DummyVsyncSource(this);
diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h
index 91022cf..74a039b 100644
--- a/libs/hwui/tests/common/TestScene.h
+++ b/libs/hwui/tests/common/TestScene.h
@@ -38,6 +38,7 @@
int count = 0;
int reportFrametimeWeight = 0;
bool renderOffscreen = true;
+ int renderAhead = 0;
};
template <class T>
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 9428f53..854a449 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -153,6 +153,12 @@
proxy->resetProfileInfo();
proxy->fence();
+ if (opts.renderAhead) {
+ // Need to let the queue drain to see render-ahead in action.
+ usleep(33000);
+ }
+ proxy->setRenderAheadDepth(opts.renderAhead);
+
ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight);
nsecs_t start = systemTime(CLOCK_MONOTONIC);
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index a56b1dd..072719b 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -67,6 +67,7 @@
are offscreen rendered
--benchmark_format Set output format. Possible values are tabular, json, csv
--renderer=TYPE Sets the render pipeline to use. May be opengl, skiagl, or skiavk
+ --render-ahead=NUM Sets how far to render-ahead. Must be 0 (default), 1, or 2.
)");
}
@@ -172,6 +173,7 @@
Onscreen,
Offscreen,
Renderer,
+ RenderAhead,
};
}
@@ -187,6 +189,7 @@
{"onscreen", no_argument, nullptr, LongOpts::Onscreen},
{"offscreen", no_argument, nullptr, LongOpts::Offscreen},
{"renderer", required_argument, nullptr, LongOpts::Renderer},
+ {"render-ahead", required_argument, nullptr, LongOpts::RenderAhead},
{0, 0, 0, 0}};
static const char* SHORT_OPTIONS = "c:r:h";
@@ -285,6 +288,16 @@
gOpts.renderOffscreen = true;
break;
+ case LongOpts::RenderAhead:
+ if (!optarg) {
+ error = true;
+ }
+ gOpts.renderAhead = atoi(optarg);
+ if (gOpts.renderAhead < 0 || gOpts.renderAhead > 2) {
+ error = true;
+ }
+ break;
+
case 'h':
printHelp();
exit(EXIT_SUCCESS);
diff --git a/media/java/android/media/PlaybackParams.java b/media/java/android/media/PlaybackParams.java
index 938a953..b85e4d0 100644
--- a/media/java/android/media/PlaybackParams.java
+++ b/media/java/android/media/PlaybackParams.java
@@ -17,6 +17,7 @@
package android.media;
import android.annotation.IntDef;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -151,6 +152,7 @@
* @param audioStretchMode
* @return this <code>PlaybackParams</code> instance.
*/
+ @TestApi
public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) {
mAudioStretchMode = audioStretchMode;
mSet |= SET_AUDIO_STRETCH_MODE;
@@ -163,6 +165,7 @@
* @return audio stretch mode
* @throws IllegalStateException if the audio stretch mode is not set.
*/
+ @TestApi
public @AudioStretchMode int getAudioStretchMode() {
if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) {
throw new IllegalStateException("audio stretch mode not set");
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings.xml b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
index 245e3b7..1086106 100644
--- a/packages/SettingsLib/res/layout/preference_category_material_settings.xml
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
@@ -50,6 +50,7 @@
android:layout_marginTop="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:textAppearance="@android:style/TextAppearance.Material.Body2"
android:textAlignment="viewStart"
android:textColor="?android:attr/colorAccent"
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 7b09ef7..cf4261c 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -33,6 +33,8 @@
<dimen name="user_spinner_item_height">56dp</dimen>
<dimen name="two_target_pref_small_icon_size">24dp</dimen>
+ <dimen name="two_target_pref_medium_icon_size">32dp</dimen>
+
<!-- Lock icon for preferences locked by admin -->
<dimen name="restricted_icon_size">16dp</dimen>
<dimen name="restricted_icon_padding">4dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java b/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
index 8b39f60..02b68d8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
@@ -16,6 +16,7 @@
package com.android.settingslib;
+import android.annotation.IntDef;
import android.content.Context;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;
@@ -24,10 +25,24 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
public class TwoTargetPreference extends Preference {
- private boolean mUseSmallIcon;
+ @IntDef({ICON_SIZE_DEFAULT, ICON_SIZE_MEDIUM, ICON_SIZE_SMALL})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IconSize {
+ }
+
+ public static final int ICON_SIZE_DEFAULT = 0;
+ public static final int ICON_SIZE_MEDIUM = 1;
+ public static final int ICON_SIZE_SMALL = 2;
+
+ @IconSize
+ private int mIconSize;
private int mSmallIconSize;
+ private int mMediumIconSize;
public TwoTargetPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
@@ -54,22 +69,30 @@
setLayoutResource(R.layout.preference_two_target);
mSmallIconSize = context.getResources().getDimensionPixelSize(
R.dimen.two_target_pref_small_icon_size);
+ mMediumIconSize = context.getResources().getDimensionPixelSize(
+ R.dimen.two_target_pref_medium_icon_size);
final int secondTargetResId = getSecondTargetResId();
if (secondTargetResId != 0) {
setWidgetLayoutResource(secondTargetResId);
}
}
- public void setUseSmallIcon(boolean useSmallIcon) {
- mUseSmallIcon = useSmallIcon;
+ public void setIconSize(@IconSize int iconSize) {
+ mIconSize = iconSize;
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
- if (mUseSmallIcon) {
- ImageView icon = holder.itemView.findViewById(android.R.id.icon);
- icon.setLayoutParams(new LinearLayout.LayoutParams(mSmallIconSize, mSmallIconSize));
+ final ImageView icon = holder.itemView.findViewById(android.R.id.icon);
+ switch (mIconSize) {
+ case ICON_SIZE_SMALL:
+ icon.setLayoutParams(new LinearLayout.LayoutParams(mSmallIconSize, mSmallIconSize));
+ break;
+ case ICON_SIZE_MEDIUM:
+ icon.setLayoutParams(
+ new LinearLayout.LayoutParams(mMediumIconSize, mMediumIconSize));
+ break;
}
final View divider = holder.findViewById(R.id.two_target_divider);
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 835ff07..f7b16f8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -148,15 +148,32 @@
Secure.putInt(context.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
}
+ /**
+ * Don't show the automatic battery suggestion notification in the future.
+ */
public static void suppressAutoBatterySaver(Context context) {
Secure.putInt(context.getContentResolver(),
Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 1);
}
- public static void scheduleAutoBatterySaver(Context context, int level) {
+ /**
+ * Set the automatic battery saver trigger level to {@code level}.
+ */
+ public static void setAutoBatterySaverTriggerLevel(Context context, int level) {
+ if (level > 0) {
+ suppressAutoBatterySaver(context);
+ }
+ Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level);
+ }
+
+ /**
+ * Set the automatic battery saver trigger level to {@code level}, but only when
+ * automatic battery saver isn't enabled yet.
+ */
+ public static void ensureAutoBatterySaver(Context context, int level) {
if (Global.getInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)
== 0) {
- Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level);
+ setAutoBatterySaverTriggerLevel(context, level);
}
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
index 55be137..e63bdd6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
@@ -35,7 +35,6 @@
import android.view.inputmethod.InputMethodSubtype;
import com.android.internal.app.LocaleHelper;
-import com.android.internal.inputmethod.InputMethodUtils;
import java.util.HashMap;
import java.util.HashSet;
@@ -176,7 +175,7 @@
((TwoStatePreference) pref).isChecked()
: enabledIMEsAndSubtypesMap.containsKey(imiId);
final boolean isCurrentInputMethod = imiId.equals(currentInputMethodId);
- final boolean systemIme = InputMethodUtils.isSystemIme(imi);
+ final boolean systemIme = imi.isSystem();
if ((!hasHardKeyboard && InputMethodSettingValuesWrapper.getInstance(
context.getActivity()).isAlwaysCheckedIme(imi, context.getActivity()))
|| isImeChecked) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
index 5e25f51..649a864 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -35,7 +35,6 @@
import android.widget.Toast;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.inputmethod.InputMethodUtils;
import com.android.settingslib.R;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedSwitchPreference;
@@ -124,7 +123,7 @@
setIntent(intent);
}
mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
- mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
+ mHasPriorityInSorting = imi.isSystem()
&& mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
setOnPreferenceClickListener(this);
setOnPreferenceChangeListener(this);
@@ -153,7 +152,7 @@
setCheckedInternal(false);
return false;
}
- if (InputMethodUtils.isSystemIme(mImi)) {
+ if (mImi.isSystem()) {
// Enable a system IME. No need to show a security warning dialog,
// but we might need to prompt if it's not Direct Boot aware.
// TV doesn't doesn't need to worry about this, but other platforms should show
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
index fac50bd..554fb35 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
@@ -129,7 +129,7 @@
return enabledValidSystemNonAuxAsciiCapableImeCount <= 1
&& !(enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabled)
- && InputMethodUtils.isSystemIme(imi)
+ && imi.isSystem()
&& isValidSystemNonAuxAsciiCapableIme(imi, context);
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
index c5e93f0..480143a7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
@@ -16,6 +16,9 @@
package com.android.settingslib;
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_DEFAULT;
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_SMALL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
@@ -75,8 +78,8 @@
}
@Test
- public void bind_smallIcon_shouldUseSmallIcon() {
- mPreference.setUseSmallIcon(true);
+ public void bind_smallIcon_shouldUseSmallIconSize() {
+ mPreference.setIconSize(ICON_SIZE_SMALL);
mPreference.onBindViewHolder(mViewHolder);
@@ -91,8 +94,24 @@
}
@Test
- public void bind_normalIcon_shouldUseNormalIcon() {
- mPreference.setUseSmallIcon(false);
+ public void bind_mediumIcon_shouldUseMediumIconSize() {
+ mPreference.setIconSize(ICON_SIZE_MEDIUM);
+
+ mPreference.onBindViewHolder(mViewHolder);
+
+ final int size = mContext.getResources().getDimensionPixelSize(
+ R.dimen.two_target_pref_medium_icon_size);
+ final LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mViewHolder
+ .findViewById(android.R.id.icon)
+ .getLayoutParams();
+
+ assertThat(layoutParams.width).isEqualTo(size);
+ assertThat(layoutParams.height).isEqualTo(size);
+ }
+
+ @Test
+ public void bind_defaultIcon_shouldUseDefaultIconSize() {
+ mPreference.setIconSize(ICON_SIZE_DEFAULT);
mPreference.onBindViewHolder(mViewHolder);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index b33df30..ba5a2c5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -16,7 +16,9 @@
package com.android.settingslib.fuelgauge;
+import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
@@ -28,6 +30,7 @@
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
+import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
@@ -41,6 +44,9 @@
@RunWith(SettingsLibRobolectricTestRunner.class)
public class BatterySaverUtilsTest {
+ final int BATTERY_SAVER_THRESHOLD_1 = 15;
+ final int BATTERY_SAVER_THRESHOLD_2 = 20;
+
@Mock
Context mMockContext;
@@ -149,4 +155,37 @@
assertEquals(-2,
Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
}
+
+ @Test
+ public void testEnsureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() throws Exception {
+ Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
+
+ BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_1);
+
+ assertThat(Secure.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+ .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+
+ // Once a positive number is set, ensureAutoBatterySaver() won't overwrite it.
+ BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_2);
+ assertThat(Secure.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+ .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+ }
+
+ @Test
+ public void testSetAutoBatterySaverTriggerLevel_setSuppressSuggestion() throws Exception {
+ Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
+ Secure.putString(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, "null");
+
+ BatterySaverUtils.setAutoBatterySaverTriggerLevel(mMockContext, 0);
+ assertThat(Global.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+ .isEqualTo(0);
+ assertThat(Secure.getInt(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, -1))
+ .isEqualTo(-1); // not set.
+
+ BatterySaverUtils.setAutoBatterySaverTriggerLevel(mMockContext, BATTERY_SAVER_THRESHOLD_1 );
+ assertThat( Global.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+ .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+ assertThat(Secure.getInt(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, -1))
+ .isEqualTo(1);
+ }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 67053d8..a2263b4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2231,6 +2231,12 @@
Settings.Secure.WAKE_GESTURE_ENABLED,
SecureSettingsProto.WAKE_GESTURE_ENABLED);
+ final long launcherToken = p.start(SecureSettingsProto.LAUNCHER);
+ dumpSetting(s, p,
+ Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED,
+ SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+ p.end(launcherToken);
+
// Please insert new settings using the same order as in SecureSettingsProto.
p.end(token);
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
index 18301a8..02be457 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
@@ -40,7 +40,7 @@
android:id="@+id/home"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
android:id="@+id/home"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
index 9ff16a2..d568d0d 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar.xml
@@ -38,7 +38,7 @@
android:id="@+id/home"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
index b0488ae..4ba6c06 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
@@ -38,7 +38,7 @@
android:id="@+id/home"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
index 99bd23c..91ba026 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
@@ -40,7 +40,7 @@
android:id="@+id/home"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
android:id="@+id/home"
android:layout_height="wrap_content"
android:layout_width="match_parent"
- systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+ systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
android:src="@drawable/car_ic_overview"
android:background="?android:attr/selectableItemBackground"
android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index e4ea08e..b5d48b4 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -51,12 +51,10 @@
<ImageButton
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:layout_gravity="center"
android:paddingStart="12dp"
android:paddingEnd="24dp"
- android:paddingTop="16dp"
- android:paddingBottom="16dp"
android:id="@+id/remote_input_send"
android:src="@drawable/ic_send"
android:contentDescription="@*android:string/ime_action_send"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
index 6fa7db3..32e4bbf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
@@ -18,23 +18,24 @@
import android.app.AppGlobals;
import android.content.ComponentName;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.RemoteException;
-import java.util.ArrayList;
import java.util.List;
public class PackageManagerWrapper {
- private static final String TAG = "PackageManagerWrapper";
-
private static final PackageManagerWrapper sInstance = new PackageManagerWrapper();
private static final IPackageManager mIPackageManager = AppGlobals.getPackageManager();
+ public static final String ACTION_PREFERRED_ACTIVITY_CHANGED =
+ Intent.ACTION_PREFERRED_ACTIVITY_CHANGED;
+
public static PackageManagerWrapper getInstance() {
return sInstance;
}
@@ -53,40 +54,15 @@
}
/**
- * @return true if the packageName belongs to the current preferred home app on the device.
- *
- * If will also return false if there are multiple home apps and the user has not picked any
- * preferred home, in which case the user would see a disambiguation screen on going to home.
+ * Report the set of 'Home' activity candidates, plus (if any) which of them
+ * is the current "always use this one" setting.
*/
- public boolean isDefaultHomeActivity(String packageName) {
- List<ResolveInfo> allHomeCandidates = new ArrayList<>();
- ComponentName home;
+ public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
try {
- home = mIPackageManager.getHomeActivities(allHomeCandidates);
+ return mIPackageManager.getHomeActivities(allHomeCandidates);
} catch (RemoteException e) {
e.printStackTrace();
- return false;
+ return null;
}
-
- if (home != null && packageName.equals(home.getPackageName())) {
- return true;
- }
-
- // Find the launcher with the highest priority and return that component if there are no
- // other home activity with the same priority.
- int lastPriority = Integer.MIN_VALUE;
- ComponentName lastComponent = null;
- final int size = allHomeCandidates.size();
- for (int i = 0; i < size; i++) {
- final ResolveInfo ri = allHomeCandidates.get(i);
- if (ri.priority > lastPriority) {
- lastComponent = ri.activityInfo.getComponentName();
- lastPriority = ri.priority;
- } else if (ri.priority == lastPriority) {
- // Two components found with same priority.
- lastComponent = null;
- }
- }
- return lastComponent != null && packageName.equals(lastComponent.getPackageName());
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index a70b358..40ce69b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -514,7 +514,7 @@
autoTriggerThreshold = 15;
}
- BatterySaverUtils.scheduleAutoBatterySaver(mContext, autoTriggerThreshold);
+ BatterySaverUtils.ensureAutoBatterySaver(mContext, autoTriggerThreshold);
showAutoSaverEnabledConfirmation();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 28917ab..f7cbee6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -210,7 +210,7 @@
state.slash.isSlashed = !state.value;
state.label = getTileLabel();
state.secondaryLabel = ZenModeConfig.getDescription(mContext,zen != Global.ZEN_MODE_OFF,
- mController.getConfig());
+ mController.getConfig(), false);
state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
switch (zen) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 75bc955..30e9afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -21,7 +21,6 @@
import android.annotation.TargetApi;
import android.app.ActivityManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -62,6 +61,7 @@
private static final String TAG = "RecentsOnboarding";
private static final boolean RESET_PREFS_FOR_DEBUG = false;
+ private static final boolean ONBOARDING_ENABLED = false;
private static final long SHOW_DELAY_MS = 500;
private static final long SHOW_HIDE_DURATION_MS = 300;
// Don't show the onboarding until the user has launched this number of apps.
@@ -184,6 +184,9 @@
}
public void onConnectedToLauncher() {
+ if (!ONBOARDING_ENABLED) {
+ return;
+ }
boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
if (!mTaskListenerRegistered && !alreadySeenRecentsOnboarding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index b81e9af..29c2edc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -26,6 +26,7 @@
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.MotionEvent;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
@@ -1631,6 +1632,42 @@
return null;
}
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ float y = ev.getY();
+ // We still want to distribute touch events to the remote input even if it's outside the
+ // view boundary. We're therefore manually dispatching these events to the remote view
+ RemoteInputView riv = getRemoteInputForView(getViewForVisibleType(mVisibleType));
+ if (riv != null && riv.getVisibility() == VISIBLE) {
+ int inputStart = mUnrestrictedContentHeight - riv.getHeight();
+ if (y <= mUnrestrictedContentHeight && y >= inputStart) {
+ ev.offsetLocation(0, -inputStart);
+ return riv.dispatchTouchEvent(ev);
+ }
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ /**
+ * Overridden to make sure touches to the reply action bar actually go through to this view
+ */
+ @Override
+ public boolean pointInView(float localX, float localY, float slop) {
+ float top = mClipTopAmount;
+ float bottom = mUnrestrictedContentHeight;
+ return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
+ localY < (bottom + slop);
+ }
+
+ private RemoteInputView getRemoteInputForView(View child) {
+ if (child == mExpandedChild) {
+ return mExpandedRemoteInput;
+ } else if (child == mHeadsUpChild) {
+ return mHeadsUpRemoteInput;
+ }
+ return null;
+ }
+
public int getExpandHeight() {
int viewType = VISIBLE_TYPE_EXPANDED;
if (mExpandedChild == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index e248db4..ec243fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -24,8 +24,8 @@
private String mLongIntent;
private boolean mBroadcastIntent;
private boolean mSelected = false;
- private float mSelectedAlpha;
- private float mUnselectedAlpha;
+ private float mSelectedAlpha = 1f;
+ private float mUnselectedAlpha = 1f;
private int mSelectedIconResourceId;
private int mIconResourceId;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3dbac51..2c335a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -196,6 +196,9 @@
}
mState = ScrimState.UNINITIALIZED;
+ mScrimBehind.setDefaultFocusHighlightEnabled(false);
+ mScrimInFront.setDefaultFocusHighlightEnabled(false);
+
updateScrims();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 7987bfd..46b6c4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1428,13 +1428,13 @@
}
public void addQsTile(ComponentName tile) {
- if (mQSPanel.getHost() != null) {
+ if (mQSPanel != null && mQSPanel.getHost() != null) {
mQSPanel.getHost().addTile(tile);
}
}
public void remQsTile(ComponentName tile) {
- if (mQSPanel.getHost() != null) {
+ if (mQSPanel != null && mQSPanel.getHost() != null) {
mQSPanel.getHost().removeTile(tile);
}
}
@@ -3899,7 +3899,11 @@
}
public boolean onBackPressed() {
- if (mStatusBarKeyguardViewManager.onBackPressed()) {
+ boolean isScrimmedBouncer = mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
+ if (mStatusBarKeyguardViewManager.onBackPressed(isScrimmedBouncer /* hideImmediately */)) {
+ if (!isScrimmedBouncer) {
+ mNotificationPanel.expandWithoutQs();
+ }
return true;
}
if (mNotificationPanel.isQsExpanded()) {
@@ -4994,6 +4998,14 @@
@Override
public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
+ RemoteInputController controller = mRemoteInputManager.getController();
+ if (controller.isRemoteInputActive(row.getEntry())
+ && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
+ // We have an active remote input typed and the user clicked on the notification.
+ // this was probably unintentional, so we're closing the edit text instead.
+ controller.closeRemoteInputs();
+ return;
+ }
Notification notification = sbn.getNotification();
final PendingIntent intent = notification.contentIntent != null
? notification.contentIntent
@@ -5057,12 +5069,7 @@
Intent fillInIntent = null;
Entry entry = row.getEntry();
CharSequence remoteInputText = null;
- RemoteInputController controller = mRemoteInputManager.getController();
- if (controller.isRemoteInputActive(entry)) {
- remoteInputText = row.getActiveRemoteInputText();
- }
- if (TextUtils.isEmpty(remoteInputText)
- && !TextUtils.isEmpty(entry.remoteInputText)) {
+ if (!TextUtils.isEmpty(entry.remoteInputText)) {
remoteInputText = entry.remoteInputText;
}
if (!TextUtils.isEmpty(remoteInputText)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 2727b30..670c68f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -512,12 +512,15 @@
/**
* Notifies this manager that the back button has been pressed.
*
+ * @param hideImmediately Hide bouncer when {@code true}, keep it around otherwise.
+ * Non-scrimmed bouncers have a special animation tied to the expansion
+ * of the notification panel.
* @return whether the back press has been handled
*/
- public boolean onBackPressed() {
+ public boolean onBackPressed(boolean hideImmediately) {
if (mBouncer.isShowing()) {
mStatusBar.endAffordanceLaunch();
- reset(true /* hideBouncerWhenShowing */);
+ reset(hideImmediately);
return true;
}
return false;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 27c00c0..82129a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -469,6 +469,14 @@
ScrimState.AOD.getAnimateChange());
}
+ @Test
+ public void testViewsDontHaveFocusHighlight() {
+ Assert.assertFalse("Scrim shouldn't have focus highlight",
+ mScrimInFront.getDefaultFocusHighlightEnabled());
+ Assert.assertFalse("Scrim shouldn't have focus highlight",
+ mScrimBehind.getDefaultFocusHighlightEnabled());
+ }
+
/**
* Conserves old notification density after leaving state and coming back.
*
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0ee026e..739b716 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5578,6 +5578,11 @@
// OS: P
WIFI_SCANNING_NEEDED_DIALOG = 1373;
+ // OPEN: Settings > System > Gestures > Swipe up gesture
+ // CATEGORY: SETTINGS
+ // OS: P
+ SETTINGS_GESTURE_SWIPE_UP = 1374;
+
// ---- End P Constants, all P constants go above this line ----
// First Q constant in master goes here:
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index f678eed..325dabe 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1404,7 +1404,7 @@
private void resetDefaultImeLocked(Context context) {
// Do not reset the default (current) IME when it is a 3rd-party IME
- if (mCurMethodId != null && !InputMethodUtils.isSystemIme(mMethodMap.get(mCurMethodId))) {
+ if (mCurMethodId != null && !mMethodMap.get(mCurMethodId).isSystem()) {
return;
}
final List<InputMethodInfo> suitableImes = InputMethodUtils.getDefaultEnabledImes(
@@ -3068,7 +3068,7 @@
: mCurrentSubtype.getLocale();
for (int i = 0; i < N; ++i) {
final InputMethodInfo imi = enabled.get(i);
- if (imi.getSubtypeCount() > 0 && InputMethodUtils.isSystemIme(imi)) {
+ if (imi.getSubtypeCount() > 0 && imi.isSystem()) {
InputMethodSubtype keyboardSubtype =
InputMethodUtils.findLastResortApplicableSubtypeLocked(mRes,
InputMethodUtils.getSubtypes(imi),
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 3868ea6..906a6a3 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -57,6 +57,7 @@
import android.telephony.TelephonyManager;
import android.util.DebugUtils;
import android.util.Pair;
+import android.util.Range;
import android.util.Slog;
import com.android.internal.R;
@@ -266,9 +267,9 @@
}
private long getRemainingDailyBudget(long limitBytes,
- Pair<ZonedDateTime, ZonedDateTime> cycle) {
- final long start = cycle.first.toInstant().toEpochMilli();
- final long end = cycle.second.toInstant().toEpochMilli();
+ Range<ZonedDateTime> cycle) {
+ final long start = cycle.getLower().toInstant().toEpochMilli();
+ final long end = cycle.getUpper().toInstant().toEpochMilli();
final long totalBytes = getNetworkTotalBytes(start, end);
final long remainingBytes = totalBytes == -1 ? 0 : Math.max(0, limitBytes - totalBytes);
// 1 + ((end - now - 1) / millisInDay with integers is equivalent to:
@@ -389,7 +390,7 @@
private static boolean hasActiveCycle(NetworkPolicy policy) {
return policy.hasCycle() && policy.lastLimitSnooze <
- policy.cycleIterator().next().first.toInstant().toEpochMilli();
+ policy.cycleIterator().next().getLower().toInstant().toEpochMilli();
}
// Only ever updated on the handler thread. Accessed from other binder threads to retrieve
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index b7bbb3b..e3d0bdd 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -79,7 +79,7 @@
*/
public final class ContentService extends IContentService.Stub {
static final String TAG = "ContentService";
- static final boolean DEBUG = true;
+ static final boolean DEBUG = false;
public static class Lifecycle extends SystemService {
private ContentService mService;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 224d085..98f69d1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -70,6 +70,12 @@
import static android.net.NetworkTemplate.MATCH_WIFI;
import static android.net.NetworkTemplate.buildTemplateMobileAll;
import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -115,6 +121,7 @@
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -188,6 +195,7 @@
import android.util.DataUnit;
import android.util.Log;
import android.util.Pair;
+import android.util.Range;
import android.util.RecurrenceRule;
import android.util.Slog;
import android.util.SparseArray;
@@ -351,6 +359,11 @@
*/
private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
+ private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
+ private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
+ private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
+ private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
+
private static final int MSG_RULES_CHANGED = 1;
private static final int MSG_METERED_IFACES_CHANGED = 2;
private static final int MSG_LIMIT_REACHED = 5;
@@ -1739,10 +1752,18 @@
}
mMeteredIfaces = newMeteredIfaces;
+ final ContentResolver cr = mContext.getContentResolver();
+ final boolean quotaEnabled = Settings.Global.getInt(cr,
+ NETPOLICY_QUOTA_ENABLED, 1) != 0;
+ final long quotaUnlimited = Settings.Global.getLong(cr,
+ NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
+ final float quotaLimited = Settings.Global.getFloat(cr,
+ NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
+
// Finally, calculate our opportunistic quotas
- // TODO: add experiments support to disable or tweak ratios
mSubscriptionOpportunisticQuota.clear();
for (NetworkState state : states) {
+ if (!quotaEnabled) continue;
if (state.network == null) continue;
final int subId = getSubIdLocked(state.network);
final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
@@ -1754,14 +1775,14 @@
quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
} else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
// Unlimited data; let's use 20MiB/day (600MiB/month)
- quotaBytes = DataUnit.MEBIBYTES.toBytes(20);
+ quotaBytes = quotaUnlimited;
} else {
// Limited data; let's only use 10% of remaining budget
- final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next();
- final long start = cycle.first.toInstant().toEpochMilli();
- final long end = cycle.second.toInstant().toEpochMilli();
+ final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
+ final long start = cycle.getLower().toInstant().toEpochMilli();
+ final long end = cycle.getUpper().toInstant().toEpochMilli();
final Instant now = mClock.instant();
- final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone())
+ final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
.truncatedTo(ChronoUnit.DAYS)
.toInstant().toEpochMilli();
final long totalBytes = getTotalBytes(
@@ -1772,7 +1793,7 @@
final long remainingDays =
1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
- quotaBytes = Math.max(0, (remainingBytes / remainingDays) / 10);
+ quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
}
mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
@@ -3048,11 +3069,17 @@
}
}
- mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
- overrideMask, overrideValue, subId));
- if (timeoutMillis > 0) {
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
- overrideMask, 0, subId), timeoutMillis);
+ // Only allow overrides when feature is enabled. However, we always
+ // allow disabling of overrides for safety reasons.
+ final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+ NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
+ if (overrideEnabled || overrideValue == 0) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
+ overrideMask, overrideValue, subId));
+ if (timeoutMillis > 0) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
+ overrideMask, 0, subId), timeoutMillis);
+ }
}
}
@@ -4695,11 +4722,24 @@
@Override
public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
+ final long quotaBytes;
synchronized (mNetworkPoliciesSecondLock) {
- // TODO: handle splitting quota between use-cases
- return mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
+ quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
OPPORTUNISTIC_QUOTA_UNKNOWN);
}
+ if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
+ return OPPORTUNISTIC_QUOTA_UNKNOWN;
+ }
+
+ if (quotaType == QUOTA_TYPE_JOBS) {
+ return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
+ NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
+ } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
+ return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
+ NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
+ } else {
+ return OPPORTUNISTIC_QUOTA_UNKNOWN;
+ }
}
@Override
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 2ef754e..ab52523 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -47,7 +47,7 @@
import android.util.AtomicFile;
import android.util.IntArray;
import android.util.MathUtils;
-import android.util.Pair;
+import android.util.Range;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -266,11 +266,11 @@
long collectEnd = end;
if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
while (it.hasNext()) {
- final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
- final long cycleStart = cycle.first.toInstant().toEpochMilli();
- final long cycleEnd = cycle.second.toInstant().toEpochMilli();
+ final Range<ZonedDateTime> cycle = it.next();
+ final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
+ final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
augmentStart = cycleStart;
collectStart = Long.min(collectStart, augmentStart);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cf7dfd0..79f80e6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -618,6 +618,7 @@
boolean mTranslucentDecorEnabled = true;
boolean mUseTvRouting;
int mVeryLongPressTimeout;
+ boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
private boolean mHandleVolumeKeysInWM;
@@ -1622,7 +1623,11 @@
: mKeyguardDelegate.isShowing();
if (!keyguardActive) {
Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
- startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+ if (mAllowStartActivityForLongPressOnPowerDuringSetup) {
+ mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+ } else {
+ startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+ }
}
break;
}
@@ -2134,6 +2139,8 @@
com.android.internal.R.integer.config_shortPressOnSleepBehavior);
mVeryLongPressTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_veryLongPressTimeout);
+ mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup);
mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
@@ -8661,6 +8668,9 @@
pw.print("mShortPressOnWindowBehavior=");
pw.println(shortPressOnWindowBehaviorToString(mShortPressOnWindowBehavior));
pw.print(prefix);
+ pw.print("mAllowStartActivityForLongPressOnPowerDuringSetup=");
+ pw.println(mAllowStartActivityForLongPressOnPowerDuringSetup);
+ pw.print(prefix);
pw.print("mHasSoftInput="); pw.print(mHasSoftInput);
pw.print(" mDismissImeOnBackKeyPressed="); pw.println(mDismissImeOnBackKeyPressed);
pw.print(prefix);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index e8f4545..318b3d2 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -51,6 +51,7 @@
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
+import com.android.internal.annotations.VisibleForTesting;
import com.google.android.collect.Sets;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -290,8 +291,10 @@
mService.mWindowPlacerLocked.performSurfacePlacement();
}
- private void addAnimation(Task task, boolean isRecentTaskInvisible) {
+ @VisibleForTesting
+ AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
if (DEBUG) Log.d(TAG, "addAnimation(" + task.getName() + ")");
+ // TODO: Refactor this to use the task's animator
final SurfaceAnimator anim = new SurfaceAnimator(task, null /* animationFinishedCallback */,
mService);
final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task,
@@ -299,6 +302,15 @@
anim.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
task.commitPendingTransaction();
mPendingAnimations.add(taskAdapter);
+ return taskAdapter;
+ }
+
+ @VisibleForTesting
+ void removeAnimation(TaskAnimationAdapter taskAdapter) {
+ if (DEBUG) Log.d(TAG, "removeAnimation(" + taskAdapter.mTask.getName() + ")");
+ taskAdapter.mTask.setCanAffectSystemUiFlags(true);
+ taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter);
+ mPendingAnimations.remove(taskAdapter);
}
void startAnimation() {
@@ -311,12 +323,21 @@
try {
final ArrayList<RemoteAnimationTarget> appAnimations = new ArrayList<>();
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
- final RemoteAnimationTarget target =
- mPendingAnimations.get(i).createRemoteAnimationApp();
+ final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
+ final RemoteAnimationTarget target = taskAdapter.createRemoteAnimationApp();
if (target != null) {
appAnimations.add(target);
+ } else {
+ removeAnimation(taskAdapter);
}
}
+
+ // Skip the animation if there is nothing to animate
+ if (appAnimations.isEmpty()) {
+ cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
+ return;
+ }
+
final RemoteAnimationTarget[] appTargets = appAnimations.toArray(
new RemoteAnimationTarget[appAnimations.size()]);
mPendingStart = false;
@@ -365,14 +386,12 @@
if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations="
+ mPendingAnimations.size());
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
- final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
- adapter.mTask.setCanAffectSystemUiFlags(true);
+ final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
- adapter.mTask.dontAnimateDimExit();
+ taskAdapter.mTask.dontAnimateDimExit();
}
- adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
+ removeAnimation(taskAdapter);
}
- mPendingAnimations.clear();
mRunner.asBinder().unlinkToDeath(this, 0);
// Clear associated input consumers
@@ -457,7 +476,8 @@
return false;
}
- private class TaskAnimationAdapter implements AnimationAdapter {
+ @VisibleForTesting
+ class TaskAnimationAdapter implements AnimationAdapter {
private final Task mTask;
private SurfaceControl mCapturedLeash;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index d31d550..dc47821 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -37,9 +37,12 @@
import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
+import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
import static android.text.format.Time.TIMEZONE_UTC;
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
@@ -118,7 +121,7 @@
import android.text.format.Time;
import android.util.DataUnit;
import android.util.Log;
-import android.util.Pair;
+import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.telephony.PhoneConstants;
@@ -818,11 +821,11 @@
private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
ZoneId.systemDefault());
- final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = policy.cycleIterator();
+ final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
while (it.hasNext()) {
- final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
- if (cycle.first.toInstant().toEpochMilli() < currentTime) {
- return cycle.first.toInstant().toEpochMilli();
+ final Range<ZonedDateTime> cycle = it.next();
+ if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
+ return cycle.getLower().toInstant().toEpochMilli();
}
}
throw new IllegalStateException(
@@ -832,7 +835,7 @@
private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
ZoneId.systemDefault());
- return policy.cycleIterator().next().second.toInstant().toEpochMilli();
+ return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
}
@Test
@@ -1484,6 +1487,102 @@
true);
}
+ @Test
+ public void testOpportunisticQuota() throws Exception {
+ final Network net = new Network(TEST_NET_ID);
+ final NetworkPolicyManagerInternal internal = LocalServices
+ .getService(NetworkPolicyManagerInternal.class);
+
+ // Create a place to store fake usage
+ final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+ final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
+ when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
+ .thenAnswer(new Answer<Long>() {
+ @Override
+ public Long answer(InvocationOnMock invocation) throws Throwable {
+ final NetworkStatsHistory.Entry entry = history.getValues(
+ invocation.getArgument(1), invocation.getArgument(2), null);
+ return entry.rxBytes + entry.txBytes;
+ }
+ });
+ when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+ .thenAnswer(new Answer<NetworkStats>() {
+ @Override
+ public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+ return stats;
+ }
+ });
+
+ // Get active mobile network in place
+ expectMobileDefaults();
+ mService.updateNetworks();
+
+ // We're 20% through the month (6 days)
+ final long start = parseTime("2015-11-01T00:00Z");
+ final long end = parseTime("2015-11-07T00:00Z");
+ setCurrentTimeMillis(end);
+
+ // Get some data usage in place
+ history.clear();
+ history.recordData(start, end,
+ new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
+
+ // No data plan
+ {
+ reset(mTelephonyManager, mNetworkManager, mNotifManager);
+ expectMobileDefaults();
+
+ mService.updateNetworks();
+
+ // No quotas
+ assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+ assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+ }
+
+ // Limited data plan
+ {
+ final SubscriptionPlan plan = SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
+ .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED)
+ .build();
+ mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+ mServiceContext.getOpPackageName());
+
+ reset(mTelephonyManager, mNetworkManager, mNotifManager);
+ expectMobileDefaults();
+
+ mService.updateNetworks();
+
+ // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
+ // for quota split equally between two types gives 3MB.
+ assertEquals(DataUnit.MEGABYTES.toBytes(3),
+ internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+ assertEquals(DataUnit.MEGABYTES.toBytes(3),
+ internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+ }
+
+ // Unlimited data plan
+ {
+ final SubscriptionPlan plan = SubscriptionPlan.Builder
+ .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
+ .setDataLimit(BYTES_UNLIMITED, LIMIT_BEHAVIOR_DISABLED)
+ .build();
+ mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+ mServiceContext.getOpPackageName());
+
+ reset(mTelephonyManager, mNetworkManager, mNotifManager);
+ expectMobileDefaults();
+
+ mService.updateNetworks();
+
+ // 20MB/day, split equally between two types gives 10MB.
+ assertEquals(DataUnit.MEBIBYTES.toBytes(10),
+ internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+ assertEquals(DataUnit.MEBIBYTES.toBytes(10),
+ internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+ }
+ }
+
private ApplicationInfo buildApplicationInfo(String label) {
final ApplicationInfo ai = new ApplicationInfo();
ai.nonLocalizedLabel = label;
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
new file mode 100644
index 0000000..fbf6691
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 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.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.os.Binder;
+import android.os.IInterface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IRecentsAnimationRunner;
+import android.view.SurfaceControl;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentsAnimationControllerTest extends WindowTestsBase {
+
+ @Mock SurfaceControl mMockLeash;
+ @Mock SurfaceControl.Transaction mMockTransaction;
+ @Mock OnAnimationFinishedCallback mFinishedCallback;
+ @Mock IRecentsAnimationRunner mMockRunner;
+ @Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks;
+ private RecentsAnimationController mController;
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ MockitoAnnotations.initMocks(this);
+ when(mMockRunner.asBinder()).thenReturn(new Binder());
+ mController = new RecentsAnimationController(sWm, mMockRunner, mAnimationCallbacks,
+ DEFAULT_DISPLAY);
+ }
+
+ @Test
+ public void testRemovedBeforeStarted_expectCanceled() throws Exception {
+ final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
+ false /* isRecentTaskInvisible */);
+ adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+
+ // Remove the app window so that the animation target can not be created
+ appWindow.removeImmediately();
+ mController.startAnimation();
+
+ // Verify that the finish callback to reparent the leash is called
+ verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+ // Verify the animation canceled callback to the app was made
+ verify(mMockRunner).onAnimationCanceled();
+ verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+ }
+
+ private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
+ verify(binder, atLeast(0)).asBinder();
+ verifyNoMoreInteractions(binder);
+ }
+}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 754fe68..a9389be 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -477,6 +477,9 @@
* <p>
* Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
* the user is interested in.
+ * <p>
+ * Receivers should protect themselves by checking that the sender holds the
+ * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@SystemApi
@@ -1719,6 +1722,8 @@
* </ul>
*
* @param subId the subscriber this relationship applies to
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
*/
@SystemApi
public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
@@ -1744,10 +1749,13 @@
* {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
* </ul>
*
- * @param subId the subscriber this relationship applies to
+ * @param subId the subscriber this relationship applies to. An empty list
+ * may be sent to clear any existing plans.
* @param plans the list of plans. The first plan is always the primary and
* most important plan. Any additional plans are secondary and
* may not be displayed or used by decision making logic.
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
*/
@SystemApi
public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
@@ -1788,6 +1796,8 @@
* be automatically cleared, or {@code 0} to leave in the
* requested state until explicitly cleared, or the next reboot,
* whichever happens first.
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
*/
@SystemApi
public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
@@ -1822,6 +1832,8 @@
* be automatically cleared, or {@code 0} to leave in the
* requested state until explicitly cleared, or the next reboot,
* whichever happens first.
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
*/
@SystemApi
public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index 4ffb70b..ef2a364 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -24,7 +24,7 @@
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Pair;
+import android.util.Range;
import android.util.RecurrenceRule;
import com.android.internal.util.Preconditions;
@@ -209,7 +209,7 @@
* any recurrence rules. The iterator starts from the currently active cycle
* and walks backwards through time.
*/
- public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+ public Iterator<Range<ZonedDateTime>> cycleIterator() {
return cycleRule.cycleIterator();
}
@@ -227,6 +227,9 @@
/**
* Start defining a {@link SubscriptionPlan} that covers a very specific
* window of time, and never automatically recurs.
+ *
+ * @param start The exact time at which the plan starts.
+ * @param end The exact time at which the plan ends.
*/
public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) {
if (!end.isAfter(start)) {
@@ -237,28 +240,40 @@
}
/**
- * Start defining a {@link SubscriptionPlan} that will recur
- * automatically every month. It will always recur on the same day of a
- * particular month. When a particular month ends before the defined
- * recurrence day, the plan will recur on the last instant of that
- * month.
+ * Start defining a {@link SubscriptionPlan} that starts at a specific
+ * time, and automatically recurs after each specific period of time,
+ * repeating indefinitely.
+ * <p>
+ * When the given period is set to exactly one month, the plan will
+ * always recur on the day of the month defined by
+ * {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends
+ * before this day, the plan will recur on the last possible instant of
+ * that month.
+ *
+ * @param start The exact time at which the plan starts.
+ * @param period The period after which the plan automatically recurs.
*/
+ public static Builder createRecurring(ZonedDateTime start, Period period) {
+ return new Builder(start, null, period);
+ }
+
+ /** {@hide} */
+ @SystemApi
+ @Deprecated
public static Builder createRecurringMonthly(ZonedDateTime start) {
return new Builder(start, null, Period.ofMonths(1));
}
- /**
- * Start defining a {@link SubscriptionPlan} that will recur
- * automatically every week.
- */
+ /** {@hide} */
+ @SystemApi
+ @Deprecated
public static Builder createRecurringWeekly(ZonedDateTime start) {
return new Builder(start, null, Period.ofDays(7));
}
- /**
- * Start defining a {@link SubscriptionPlan} that will recur
- * automatically every day.
- */
+ /** {@hide} */
+ @SystemApi
+ @Deprecated
public static Builder createRecurringDaily(ZonedDateTime start) {
return new Builder(start, null, Period.ofDays(1));
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 2f52c0a..dfb6e2c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -77,6 +77,11 @@
result = 31 * result + featureType;
return result;
}
+
+ @Override
+ public String toString() {
+ return "{s=" + slotId + ", f=" + featureType + "}";
+ }
}
/**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 687a6b7..bb771bb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -823,6 +823,16 @@
boolean isResolvingImsBinding();
/**
+ * @return true if the ImsService to bind to for the slot id specified was set, false otherwise.
+ */
+ boolean setImsService(int slotId, boolean isCarrierImsService, String packageName);
+
+ /**
+ * @return the package name of the carrier/device ImsService associated with this slot.
+ */
+ String getImsService(int slotId, boolean isCarrierImsService);
+
+ /**
* Set the network selection mode to automatic.
*
* @param subId the id of the subscription to update.