Merge "Revert "Replace RemoteCallback with AndroidFuture in PermControler""
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
index 6b09a9f..ee4e1e4 100644
--- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
+++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java
@@ -485,8 +485,9 @@
});
final IPackageInstaller installer = AppGlobals.getPackageManager().getPackageInstaller();
- installer.installExistingPackage(packageName, 0, PackageManager.INSTALL_REASON_UNKNOWN,
- sender, userId);
+ installer.installExistingPackage(packageName,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null);
try {
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
diff --git a/api/current.txt b/api/current.txt
index 35c6f45..a3af2ba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -220,12 +220,6 @@
public static final class R.attr {
ctor public R.attr();
- field public static final int __removed1 = 16844185; // 0x1010599
- field public static final int __removed2 = 16844186; // 0x101059a
- field public static final int __removed3 = 16844187; // 0x101059b
- field public static final int __removed4 = 16844188; // 0x101059c
- field public static final int __removed5 = 16844189; // 0x101059d
- field public static final int __removed6 = 16844182; // 0x1010596
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
@@ -284,7 +278,7 @@
field public static final int alertDialogTheme = 16843529; // 0x1010309
field public static final int alignmentMode = 16843642; // 0x101037a
field public static final int allContactsName = 16843468; // 0x10102cc
- field public static final int allowAudioPlaybackCapture = 16844199; // 0x10105a7
+ field public static final int allowAudioPlaybackCapture = 16844289; // 0x1010601
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
field public static final int allowEmbedded = 16843765; // 0x10103f5
@@ -572,8 +566,8 @@
field public static final int endX = 16844050; // 0x1010512
field public static final int endY = 16844051; // 0x1010513
field @Deprecated public static final int endYear = 16843133; // 0x101017d
- field public static final int enforceNavigationBarContrast = 16844203; // 0x10105ab
- field public static final int enforceStatusBarContrast = 16844202; // 0x10105aa
+ field public static final int enforceNavigationBarContrast = 16844293; // 0x1010605
+ field public static final int enforceStatusBarContrast = 16844292; // 0x1010604
field public static final int enterFadeDuration = 16843532; // 0x101030c
field public static final int entries = 16842930; // 0x10100b2
field public static final int entryValues = 16843256; // 0x10101f8
@@ -646,10 +640,10 @@
field public static final int footerDividersEnabled = 16843311; // 0x101022f
field public static final int forceDarkAllowed = 16844172; // 0x101058c
field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521
- field public static final int forceUriPermissions = 16844197; // 0x10105a5
+ field public static final int forceUriPermissions = 16844191; // 0x101059f
field public static final int foreground = 16843017; // 0x1010109
field public static final int foregroundGravity = 16843264; // 0x1010200
- field public static final int foregroundServiceType = 16844191; // 0x101059f
+ field public static final int foregroundServiceType = 16844185; // 0x1010599
field public static final int foregroundTint = 16843885; // 0x101046d
field public static final int foregroundTintMode = 16843886; // 0x101046e
field public static final int format = 16843013; // 0x1010105
@@ -707,7 +701,7 @@
field public static final int hapticFeedbackEnabled = 16843358; // 0x101025e
field public static final int hardwareAccelerated = 16843475; // 0x10102d3
field public static final int hasCode = 16842764; // 0x101000c
- field public static final int hasFragileUserData = 16844192; // 0x10105a0
+ field public static final int hasFragileUserData = 16844186; // 0x101059a
field @Deprecated public static final int headerAmPmTextAppearance = 16843936; // 0x10104a0
field public static final int headerBackground = 16843055; // 0x101012f
field @Deprecated public static final int headerDayOfMonthTextAppearance = 16843927; // 0x1010497
@@ -735,7 +729,7 @@
field public static final int iconTintMode = 16844127; // 0x101055f
field public static final int iconifiedByDefault = 16843514; // 0x10102fa
field public static final int id = 16842960; // 0x10100d0
- field public static final int identifier = 16844204; // 0x10105ac
+ field public static final int identifier = 16844294; // 0x1010606
field public static final int ignoreGravity = 16843263; // 0x10101ff
field public static final int imageButtonStyle = 16842866; // 0x1010072
field public static final int imageWellStyle = 16842867; // 0x1010073
@@ -767,7 +761,7 @@
field public static final int indicatorRight = 16843022; // 0x101010e
field public static final int indicatorStart = 16843729; // 0x10103d1
field public static final int inflatedId = 16842995; // 0x10100f3
- field public static final int inheritShowWhenLocked = 16844194; // 0x10105a2
+ field public static final int inheritShowWhenLocked = 16844188; // 0x101059c
field public static final int initOrder = 16842778; // 0x101001a
field public static final int initialKeyguardLayout = 16843714; // 0x10103c2
field public static final int initialLayout = 16843345; // 0x1010251
@@ -944,7 +938,7 @@
field public static final int menuCategory = 16843230; // 0x10101de
field public static final int mimeType = 16842790; // 0x1010026
field public static final int min = 16844089; // 0x1010539
- field public static final int minAspectRatio = 16844193; // 0x10105a1
+ field public static final int minAspectRatio = 16844187; // 0x101059b
field public static final int minDate = 16843583; // 0x101033f
field public static final int minEms = 16843098; // 0x101015a
field public static final int minHeight = 16843072; // 0x1010140
@@ -1125,7 +1119,7 @@
field public static final int reqKeyboardType = 16843304; // 0x1010228
field public static final int reqNavigation = 16843306; // 0x101022a
field public static final int reqTouchScreen = 16843303; // 0x1010227
- field public static final int requestLegacyExternalStorage = 16844201; // 0x10105a9
+ field public static final int requestLegacyExternalStorage = 16844291; // 0x1010603
field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
field public static final int required = 16843406; // 0x101028e
field public static final int requiredAccountType = 16843734; // 0x10103d6
@@ -1204,7 +1198,7 @@
field public static final int secondaryProgress = 16843064; // 0x1010138
field public static final int secondaryProgressTint = 16843879; // 0x1010467
field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
- field public static final int secureElementName = 16844200; // 0x10105a8
+ field public static final int secureElementName = 16844290; // 0x1010602
field public static final int seekBarStyle = 16842875; // 0x101007b
field public static final int segmentedButtonStyle = 16843568; // 0x1010330
field public static final int selectAllOnFocus = 16843102; // 0x101015e
@@ -1213,7 +1207,7 @@
field public static final int selectableItemBackgroundBorderless = 16843868; // 0x101045c
field @Deprecated public static final int selectedDateVerticalBar = 16843591; // 0x1010347
field @Deprecated public static final int selectedWeekBackgroundColor = 16843586; // 0x1010342
- field public static final int selectionDividerHeight = 16844190; // 0x101059e
+ field public static final int selectionDividerHeight = 16844184; // 0x1010598
field public static final int sessionService = 16843837; // 0x101043d
field public static final int settingsActivity = 16843301; // 0x1010225
field public static final int settingsSliceUri = 16844179; // 0x1010593
@@ -1332,7 +1326,7 @@
field public static final int supportsAssist = 16844016; // 0x10104f0
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
- field public static final int supportsMultipleDisplays = 16844183; // 0x1010597
+ field public static final int supportsMultipleDisplays = 16844182; // 0x1010596
field public static final int supportsPictureInPicture = 16844023; // 0x10104f7
field public static final int supportsRtl = 16843695; // 0x10103af
field public static final int supportsSwitchingToNextInputMethod = 16843755; // 0x10103eb
@@ -1513,9 +1507,9 @@
field public static final int unselectedAlpha = 16843278; // 0x101020e
field public static final int updatePeriodMillis = 16843344; // 0x1010250
field public static final int use32bitAbi = 16844053; // 0x1010515
- field public static final int useAppZygote = 16844184; // 0x1010598
+ field public static final int useAppZygote = 16844183; // 0x1010597
field public static final int useDefaultMargins = 16843641; // 0x1010379
- field public static final int useEmbeddedDex = 16844196; // 0x10105a4
+ field public static final int useEmbeddedDex = 16844190; // 0x101059e
field public static final int useIntrinsicSizeAsMinimum = 16843536; // 0x1010310
field public static final int useLevel = 16843167; // 0x101019f
field public static final int userVisible = 16843409; // 0x1010291
@@ -1627,7 +1621,7 @@
field @Deprecated public static final int yearListSelectorColor = 16843930; // 0x101049a
field public static final int yesNoPreferenceStyle = 16842896; // 0x1010090
field public static final int zAdjustment = 16843201; // 0x10101c1
- field public static final int zygotePreloadName = 16844195; // 0x10105a3
+ field public static final int zygotePreloadName = 16844189; // 0x101059d
}
public static final class R.bool {
@@ -34167,7 +34161,7 @@
field public static final int O = 26; // 0x1a
field public static final int O_MR1 = 27; // 0x1b
field public static final int P = 28; // 0x1c
- field public static final int Q = 10000; // 0x2710
+ field public static final int Q = 29; // 0x1d
}
public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
@@ -56254,12 +56248,10 @@
method public int getWindowLayoutType();
method public boolean isAboveAnchor();
method public boolean isAttachedInDecor();
- method @Deprecated public boolean isClipToScreenEnabled();
method public boolean isClippedToScreen();
method public boolean isClippingEnabled();
method public boolean isFocusable();
method public boolean isLaidOutInScreen();
- method @Deprecated public boolean isLayoutInScreenEnabled();
method public boolean isOutsideTouchable();
method public boolean isShowing();
method public boolean isSplitTouchEnabled();
@@ -56268,7 +56260,6 @@
method public void setAnimationStyle(int);
method public void setAttachedInDecor(boolean);
method public void setBackgroundDrawable(android.graphics.drawable.Drawable);
- method @Deprecated public void setClipToScreenEnabled(boolean);
method public void setClippingEnabled(boolean);
method public void setContentView(android.view.View);
method public void setElevation(float);
@@ -56281,7 +56272,6 @@
method public void setInputMethodMode(int);
method public void setIsClippedToScreen(boolean);
method public void setIsLaidOutInScreen(boolean);
- method @Deprecated public void setLayoutInScreenEnabled(boolean);
method public void setOnDismissListener(android.widget.PopupWindow.OnDismissListener);
method public void setOutsideTouchable(boolean);
method public void setOverlapAnchor(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index 72cb92c..7713070 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -699,6 +699,13 @@
method protected <T extends android.view.View> T findViewWithTagTraversal(Object);
}
+ public class PopupWindow {
+ method @Deprecated public boolean isClipToScreenEnabled();
+ method @Deprecated public boolean isLayoutInScreenEnabled();
+ method @Deprecated public void setClipToScreenEnabled(boolean);
+ method @Deprecated public void setLayoutInScreenEnabled(boolean);
+ }
+
@android.widget.RemoteViews.RemoteView public class TextView extends android.view.View implements android.view.ViewTreeObserver.OnPreDrawListener {
method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
diff --git a/api/system-current.txt b/api/system-current.txt
index bae7f82..f074e39 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -218,7 +218,7 @@
}
public static final class R.attr {
- field public static final int allowClearUserDataOnFailedRestore = 16844198; // 0x10105a6
+ field public static final int allowClearUserDataOnFailedRestore = 16844288; // 0x1010600
field public static final int isVrOnly = 16844152; // 0x1010578
field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
@@ -317,7 +317,6 @@
public class AppOpsManager {
method @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public void getHistoricalOps(@NonNull android.app.AppOpsManager.HistoricalOpsRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.AppOpsManager.HistoricalOps>);
method public static String[] getOpStrs();
- method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable int[]);
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
method public static int opToDefaultMode(@NonNull String);
@@ -936,8 +935,6 @@
method public int restorePackage(String, android.app.backup.RestoreObserver);
method public int restorePackages(long, @Nullable android.app.backup.RestoreObserver, @NonNull java.util.Set<java.lang.String>, @Nullable android.app.backup.BackupManagerMonitor);
method public int restorePackages(long, @Nullable android.app.backup.RestoreObserver, @NonNull java.util.Set<java.lang.String>);
- method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor, String[]);
- method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, String[]);
}
public class RestoreSet implements android.os.Parcelable {
@@ -1092,14 +1089,11 @@
}
public static final class AppTarget.Builder {
- ctor @Deprecated public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId);
ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull String, @NonNull android.os.UserHandle);
ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo);
method @NonNull public android.app.prediction.AppTarget build();
method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String);
method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int);
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
}
public final class AppTargetEvent implements android.os.Parcelable {
@@ -1602,9 +1596,6 @@
method public static void forceSafeLabels();
method @Deprecated @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager);
method @NonNull public CharSequence loadSafeLabel(@NonNull android.content.pm.PackageManager, @FloatRange(from=0) float, int);
- field @Deprecated public static final int SAFE_LABEL_FLAG_FIRST_LINE = 4; // 0x4
- field @Deprecated public static final int SAFE_LABEL_FLAG_SINGLE_LINE = 2; // 0x2
- field @Deprecated public static final int SAFE_LABEL_FLAG_TRIM = 1; // 0x1
}
public abstract class PackageManager {
@@ -7104,7 +7095,6 @@
method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean isInEmergencyCall();
method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
- method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(@Nullable String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUserSelectedOutgoingPhoneAccount(@Nullable android.telecom.PhoneAccountHandle);
field public static final String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
field public static final String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 8f71122..5802f6c 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -9,6 +9,10 @@
package android.app {
+ public class AppOpsManager {
+ method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable int[]);
+ }
+
public class Notification implements android.os.Parcelable {
method public static Class<? extends android.app.Notification.Style> getNotificationStyleClass(String);
}
@@ -28,6 +32,25 @@
}
+package android.app.backup {
+
+ public class RestoreSession {
+ method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, android.app.backup.BackupManagerMonitor, String[]);
+ method @Deprecated public int restoreSome(long, android.app.backup.RestoreObserver, String[]);
+ }
+
+}
+
+package android.app.prediction {
+
+ public static final class AppTarget.Builder {
+ ctor @Deprecated public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId);
+ method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
+ method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
+ }
+
+}
+
package android.content {
public class Intent implements java.lang.Cloneable android.os.Parcelable {
@@ -60,6 +83,16 @@
}
+package android.content.pm {
+
+ public class PackageItemInfo {
+ field @Deprecated public static final int SAFE_LABEL_FLAG_FIRST_LINE = 4; // 0x4
+ field @Deprecated public static final int SAFE_LABEL_FLAG_SINGLE_LINE = 2; // 0x2
+ field @Deprecated public static final int SAFE_LABEL_FLAG_TRIM = 1; // 0x1
+ }
+
+}
+
package android.hardware.hdmi {
public final class HdmiControlManager {
@@ -158,6 +191,14 @@
}
+package android.telecom {
+
+ public class TelecomManager {
+ method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(@Nullable String);
+ }
+
+}
+
package android.telephony {
public class TelephonyManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index 26320ed..842024c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -520,8 +520,6 @@
method @NonNull public android.app.prediction.AppTarget build();
method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String);
method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int);
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
- method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
}
public final class AppTargetEvent implements android.os.Parcelable {
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 83a5708..ef0aac7 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -1,4 +1,13 @@
// Signature format: 2.0
+package android.app.prediction {
+
+ public static final class AppTarget.Builder {
+ method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
+ method @Deprecated @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
+ }
+
+}
+
package android.provider {
public final class DeviceConfig {
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index ec02b12..4e0a8eb 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -611,11 +611,8 @@
void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
-
const int64_t timeNs = getElapsedRealtimeNs();
// Do not write to disk if we already have in the last few seconds.
- // This is to avoid overwriting files that would have the same name if we
- // write twice in the same second.
if (static_cast<unsigned long long> (timeNs) <
mLastActiveMetricsWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) {
ALOGI("Statsd skipping writing active metrics to disk. Already wrote data in last %d seconds",
@@ -625,13 +622,7 @@
mLastActiveMetricsWriteNs = timeNs;
ProtoOutputStream proto;
- for (const auto& pair : mMetricsManagers) {
- const sp<MetricsManager>& metricsManager = pair.second;
- uint64_t configToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
- FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
- metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, &proto);
- proto.end(configToken);
- }
+ WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, DEVICE_SHUTDOWN, &proto);
string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
StorageManager::deleteFile(file_name.c_str());
@@ -644,9 +635,24 @@
proto.flush(fd.get());
}
+void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream(
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ WriteActiveConfigsToProtoOutputStreamLocked(currentTimeNs, reason, proto);
+}
+
+void StatsLogProcessor::WriteActiveConfigsToProtoOutputStreamLocked(
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
+ for (const auto& pair : mMetricsManagers) {
+ const sp<MetricsManager>& metricsManager = pair.second;
+ uint64_t configToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_ACTIVE_CONFIG_LIST_CONFIG);
+ metricsManager->writeActiveConfigToProtoOutputStream(currentTimeNs, reason, proto);
+ proto->end(configToken);
+ }
+}
void StatsLogProcessor::LoadActiveConfigsFromDisk() {
std::lock_guard<std::mutex> lock(mMetricsMutex);
-
string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
if (-1 == fd) {
@@ -670,6 +676,19 @@
StorageManager::deleteFile(file_name.c_str());
return;
}
+ // Passing in mTimeBaseNs only works as long as we only load from disk is when statsd starts.
+ SetConfigsActiveStateLocked(activeConfigList, mTimeBaseNs);
+ StorageManager::deleteFile(file_name.c_str());
+}
+
+void StatsLogProcessor::SetConfigsActiveState(const ActiveConfigList& activeConfigList,
+ int64_t currentTimeNs) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ SetConfigsActiveStateLocked(activeConfigList, currentTimeNs);
+}
+
+void StatsLogProcessor::SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
+ int64_t currentTimeNs) {
for (int i = 0; i < activeConfigList.config_size(); i++) {
const auto& config = activeConfigList.config(i);
ConfigKey key(config.uid(), config.id());
@@ -679,11 +698,9 @@
continue;
}
VLOG("Setting active config %s", key.ToString().c_str());
- it->second->loadActiveConfig(config, mTimeBaseNs);
+ it->second->loadActiveConfig(config, currentTimeNs);
}
VLOG("Successfully loaded %d active configs.", activeConfigList.config_size());
-
- StorageManager::deleteFile(file_name.c_str());
}
void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 0dc597b..92aa425 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -31,17 +31,6 @@
namespace os {
namespace statsd {
-// Keep this in sync with DumpReportReason enum in stats_log.proto
-enum DumpReportReason {
- DEVICE_SHUTDOWN = 1,
- CONFIG_UPDATED = 2,
- CONFIG_REMOVED = 3,
- GET_DATA_CALLED = 4,
- ADB_DUMP = 5,
- CONFIG_RESET = 6,
- STATSCOMPANION_DIED = 7,
- TERMINATION_SIGNAL_RECEIVED = 8
-};
class StatsLogProcessor : public ConfigListener {
public:
@@ -92,9 +81,16 @@
/* Persist configs containing metrics with active activations to disk. */
void SaveActiveConfigsToDisk(int64_t currentTimeNs);
+ /* Writes the current active status/ttl for all configs and metrics to ProtoOutputStream. */
+ void WriteActiveConfigsToProtoOutputStream(
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
+
/* Load configs containing metrics with active activations from disk. */
void LoadActiveConfigsFromDisk();
+ /* Sets the active status/ttl for all configs and metrics to the status in ActiveConfigList. */
+ void SetConfigsActiveState(const ActiveConfigList& activeConfigList, int64_t currentTimeNs);
+
// Reset all configs.
void resetConfigs();
@@ -158,6 +154,12 @@
void GetActiveConfigsLocked(const int uid, vector<int64_t>& outActiveConfigs);
+ void WriteActiveConfigsToProtoOutputStreamLocked(
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
+
+ void SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
+ int64_t currentTimeNs);
+
void WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
const DumpLatency dumpLatency);
void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
@@ -224,6 +226,7 @@
FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
FRIEND_TEST(StatsLogProcessorTest,
TestActivationOnBootMultipleActivationsDifferentActivationTypes);
+ FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 623a1f2..8191d37 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1478,8 +1478,21 @@
StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec());
if (mProcessor != nullptr) {
ALOGW("Reset statsd upon system server restarts.");
+ int64_t systemServerRestartNs = getElapsedRealtimeNs();
+ ProtoOutputStream proto;
+ mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
+ STATSCOMPANION_DIED, &proto);
+
mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST);
mProcessor->resetConfigs();
+
+ std::string serializedActiveConfigs;
+ if (proto.serializeToString(&serializedActiveConfigs)) {
+ ActiveConfigList activeConfigs;
+ if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
+ mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
+ }
+ }
}
mAnomalyAlarmMonitor->setStatsCompanionService(nullptr);
mPeriodicAlarmMonitor->setStatsCompanionService(nullptr);
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 936f7db..a4e6d7f 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -427,6 +427,7 @@
std::shared_ptr<LogEventQueue> mEventQueue;
+ FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
FRIEND_TEST(StatsServiceTest, TestAddConfig_simple);
FRIEND_TEST(StatsServiceTest, TestAddConfig_empty);
FRIEND_TEST(StatsServiceTest, TestAddConfig_invalid);
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
index ef8e50b..9929833 100644
--- a/cmds/statsd/src/active_config_list.proto
+++ b/cmds/statsd/src/active_config_list.proto
@@ -26,7 +26,18 @@
// Time left in activation. When this proto is loaded after device boot,
// the activation should be set to active for this duration.
+ // This field will only be set when the state is ACTIVE
optional int64 remaining_ttl_nanos = 2;
+
+ enum State {
+ UNNKNOWN = 0;
+ // This metric should activate for remaining_ttl_nanos when we load the activations.
+ ACTIVE = 1;
+ // When we load the activations, this metric should activate on next boot for the tll
+ // specified in the config.
+ ACTIVATE_ON_BOOT = 2;
+ }
+ optional State state = 3;
}
message ActiveMetric {
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index 9ad7f09..d913427 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -19,6 +19,7 @@
#include "MetricProducer.h"
using android::util::FIELD_COUNT_REPEATED;
+using android::util::FIELD_TYPE_ENUM;
using android::util::FIELD_TYPE_INT32;
using android::util::FIELD_TYPE_INT64;
using android::util::FIELD_TYPE_MESSAGE;
@@ -37,6 +38,7 @@
// for ActiveEventActivation
const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_ATOM_MATCHER_INDEX = 1;
const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS = 2;
+const int FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE = 3;
void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
if (!mIsActive) {
@@ -165,17 +167,21 @@
continue;
}
auto& activation = it->second;
- // We don't want to change the ttl for future activations, so we set the start_ns
- // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
- activation->start_ns =
- currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
- activation->state = ActivationState::kActive;
- mIsActive = true;
+ if (activeEventActivation.state() == ActiveEventActivation::ACTIVE) {
+ // We don't want to change the ttl for future activations, so we set the start_ns
+ // such that start_ns + ttl_ns == currentTimeNs + remaining_ttl_nanos
+ activation->start_ns =
+ currentTimeNs + activeEventActivation.remaining_ttl_nanos() - activation->ttl_ns;
+ activation->state = ActivationState::kActive;
+ mIsActive = true;
+ } else if (activeEventActivation.state() == ActiveEventActivation::ACTIVATE_ON_BOOT) {
+ activation->state = ActivationState::kActiveOnBoot;
+ }
}
}
void MetricProducer::writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, ProtoOutputStream* proto) {
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_METRIC_ID, (long long)mMetricId);
for (auto& it : mEventActivationMap) {
const int atom_matcher_index = it.first;
@@ -196,9 +202,22 @@
activation->start_ns + activation->ttl_ns - currentTimeNs;
proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
(long long)remainingTtlNs);
+ proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
+ ActiveEventActivation::ACTIVE);
+
} else if (ActivationState::kActiveOnBoot == activation->state) {
- proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
- (long long)activation->ttl_ns);
+ if (reason == DEVICE_SHUTDOWN || reason == TERMINATION_SIGNAL_RECEIVED) {
+ proto->write(
+ FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_EVENT_ACTIVATION_REMAINING_TTL_NANOS,
+ (long long)activation->ttl_ns);
+ proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
+ ActiveEventActivation::ACTIVE);
+ } else if (reason == STATSCOMPANION_DIED) {
+ // We are saving because of system server death, not due to a device shutdown.
+ // Next time we load, we do not want to activate metrics that activate on boot.
+ proto->write(FIELD_TYPE_ENUM | FIELD_ID_ACTIVE_EVENT_ACTIVATION_STATE,
+ ActiveEventActivation::ACTIVATE_ON_BOOT);
+ }
}
proto->end(activationToken);
}
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index ec3484c..3ddbef4 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -35,6 +35,18 @@
namespace os {
namespace statsd {
+// Keep this in sync with DumpReportReason enum in stats_log.proto
+enum DumpReportReason {
+ DEVICE_SHUTDOWN = 1,
+ CONFIG_UPDATED = 2,
+ CONFIG_REMOVED = 3,
+ GET_DATA_CALLED = 4,
+ ADB_DUMP = 5,
+ CONFIG_RESET = 6,
+ STATSCOMPANION_DIED = 7,
+ TERMINATION_SIGNAL_RECEIVED = 8
+};
+
// If the metric has no activation requirement, it will be active once the metric producer is
// created.
// If the metric needs to be activated by atoms, the metric producer will start
@@ -244,7 +256,7 @@
void flushIfExpire(int64_t elapsedTimestampNs);
void writeActiveMetricToProtoOutputStream(
- int64_t currentTimeNs, ProtoOutputStream* proto);
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
protected:
virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
@@ -268,8 +280,6 @@
return mIsActive;
}
- void prepActiveForBootIfNecessaryLocked(int64_t currentTimeNs);
-
void loadActiveMetricLocked(const ActiveMetric& activeMetric, int64_t currentTimeNs);
virtual void prepareFirstBucketLocked() {};
@@ -412,6 +422,7 @@
FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
FRIEND_TEST(StatsLogProcessorTest,
TestActivationOnBootMultipleActivationsDifferentActivationTypes);
+ FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 947f377..207a7dd 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -528,14 +528,14 @@
}
void MetricsManager::writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, ProtoOutputStream* proto) {
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
proto->write(FIELD_TYPE_INT64 | FIELD_ID_ACTIVE_CONFIG_ID, (long long)mConfigKey.GetId());
proto->write(FIELD_TYPE_INT32 | FIELD_ID_ACTIVE_CONFIG_UID, mConfigKey.GetUid());
for (int metricIndex : mMetricIndexesWithActivation) {
const auto& metric = mAllMetricProducers[metricIndex];
const uint64_t metricToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
FIELD_ID_ACTIVE_CONFIG_METRIC);
- metric->writeActiveMetricToProtoOutputStream(currentTimeNs, proto);
+ metric->writeActiveMetricToProtoOutputStream(currentTimeNs, reason, proto);
proto->end(metricToken);
}
}
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 818131e..da3be06 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -141,7 +141,7 @@
void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs);
void writeActiveConfigToProtoOutputStream(
- int64_t currentTimeNs, ProtoOutputStream* proto);
+ int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto);
private:
// For test only.
@@ -290,6 +290,7 @@
FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations);
FRIEND_TEST(StatsLogProcessorTest,
TestActivationOnBootMultipleActivationsDifferentActivationTypes);
+ FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart);
};
} // namespace statsd
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 4e419b6..a2fd9d4 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -330,6 +330,8 @@
// Class name of the incident report receiver.
optional string receiver_cls = 4;
+
+ optional string alert_description = 5;
}
message PerfettoDetails {
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
index ff1cb4f..f2c6f1a 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
@@ -36,12 +36,14 @@
using android::util::ProtoOutputStream;
using std::vector;
-using util::FIELD_TYPE_MESSAGE;
using util::FIELD_TYPE_INT32;
using util::FIELD_TYPE_INT64;
+using util::FIELD_TYPE_MESSAGE;
+using util::FIELD_TYPE_STRING;
// field ids in IncidentHeaderProto
const int FIELD_ID_ALERT_ID = 1;
+const int FIELD_ID_REASON = 2;
const int FIELD_ID_CONFIG_KEY = 3;
const int FIELD_ID_CONFIG_KEY_UID = 1;
const int FIELD_ID_CONFIG_KEY_ID = 2;
@@ -57,9 +59,11 @@
namespace {
void getProtoData(const int64_t& rule_id, int64_t metricId, const MetricDimensionKey& dimensionKey,
- int64_t metricValue, const ConfigKey& configKey, vector<uint8_t>* protoData) {
+ int64_t metricValue, const ConfigKey& configKey, const string& reason,
+ vector<uint8_t>* protoData) {
ProtoOutputStream headerProto;
headerProto.write(FIELD_TYPE_INT64 | FIELD_ID_ALERT_ID, (long long)rule_id);
+ headerProto.write(FIELD_TYPE_STRING | FIELD_ID_REASON, reason);
uint64_t token =
headerProto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
headerProto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_KEY_UID, configKey.GetUid());
@@ -142,7 +146,8 @@
IncidentReportArgs incidentReport;
vector<uint8_t> protoData;
- getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey, &protoData);
+ getProtoData(rule_id, metricId, dimensionKey, metricValue, configKey,
+ config.alert_description(), &protoData);
incidentReport.addHeader(protoData);
for (int i = 0; i < config.section_size(); i++) {
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 49b4e90..fe25a25 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -13,12 +13,14 @@
// limitations under the License.
#include "StatsLogProcessor.h"
+#include "StatsService.h"
#include "config/ConfigKey.h"
#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "guardrail/StatsdStats.h"
#include "logd/LogEvent.h"
#include "packages/UidMap.h"
+#include "storage/StorageManager.h"
#include "statslog.h"
#include <gmock/gmock.h>
@@ -97,7 +99,8 @@
ConfigKey key(100, 12345);
EXPECT_CALL(mockMetricsManager, byteSize())
.Times(1)
- .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * .95)));
+ .WillRepeatedly(::testing::Return(int(
+ StatsdStats::kMaxMetricsBytesPerConfig * .95)));
// Expect only one broadcast despite always returning a size that should trigger broadcast.
p.flushIfNecessaryLocked(1, key, mockMetricsManager);
@@ -128,7 +131,7 @@
ConfigKey key(100, 12345);
EXPECT_CALL(mockMetricsManager, byteSize())
.Times(1)
- .WillRepeatedly(Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
+ .WillRepeatedly(::testing::Return(int(StatsdStats::kMaxMetricsBytesPerConfig * 1.2)));
EXPECT_CALL(mockMetricsManager, dropData(_)).Times(1);
@@ -1482,6 +1485,236 @@
// }}}---------------------------------------------------------------------------
}
+TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
+ int uid = 9876;
+ long configId = 12341;
+
+ // Create config with 3 metrics:
+ // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate.
+ // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate.
+ // Metric 3: Always active
+ StatsdConfig config1;
+ config1.set_id(configId);
+ config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
+ auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+ auto jobStartMatcher = CreateStartScheduledJobAtomMatcher();
+ auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher();
+ *config1.add_atom_matcher() = wakelockAcquireMatcher;
+ *config1.add_atom_matcher() = screenOnMatcher;
+ *config1.add_atom_matcher() = jobStartMatcher;
+ *config1.add_atom_matcher() = jobFinishMatcher;
+
+ long metricId1 = 1234561;
+ long metricId2 = 1234562;
+ long metricId3 = 1234563;
+
+ auto countMetric1 = config1.add_count_metric();
+ countMetric1->set_id(metricId1);
+ countMetric1->set_what(wakelockAcquireMatcher.id());
+ countMetric1->set_bucket(FIVE_MINUTES);
+
+ auto countMetric2 = config1.add_count_metric();
+ countMetric2->set_id(metricId2);
+ countMetric2->set_what(wakelockAcquireMatcher.id());
+ countMetric2->set_bucket(FIVE_MINUTES);
+
+ auto countMetric3 = config1.add_count_metric();
+ countMetric3->set_id(metricId3);
+ countMetric3->set_what(wakelockAcquireMatcher.id());
+ countMetric3->set_bucket(FIVE_MINUTES);
+
+ // Metric 1 activates on boot for wakelock acquire, immediately for screen on.
+ auto metric1Activation = config1.add_metric_activation();
+ metric1Activation->set_metric_id(metricId1);
+ auto metric1ActivationTrigger1 = metric1Activation->add_event_activation();
+ metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric1ActivationTrigger1->set_ttl_seconds(100);
+ metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
+ auto metric1ActivationTrigger2 = metric1Activation->add_event_activation();
+ metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id());
+ metric1ActivationTrigger2->set_ttl_seconds(200);
+ metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
+
+ // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish.
+ auto metric2Activation = config1.add_metric_activation();
+ metric2Activation->set_metric_id(metricId2);
+ auto metric2ActivationTrigger1 = metric2Activation->add_event_activation();
+ metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id());
+ metric2ActivationTrigger1->set_ttl_seconds(100);
+ metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT);
+ auto metric2ActivationTrigger2 = metric2Activation->add_event_activation();
+ metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id());
+ metric2ActivationTrigger2->set_ttl_seconds(200);
+ metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
+
+ // Send the config.
+ StatsService service(nullptr, nullptr);
+ string serialized = config1.SerializeAsString();
+ service.addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
+
+ // Make sure the config is stored on disk. Otherwise, we will not reset on system server death.
+ StatsdConfig tmpConfig;
+ ConfigKey cfgKey1(uid, configId);
+ EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig));
+
+ // Metric 1 is not active.
+ // Metric 2 is not active.
+ // Metric 3 is active.
+ // {{{---------------------------------------------------------------------------
+ sp<StatsLogProcessor> processor = service.mProcessor;
+ EXPECT_EQ(1, processor->mMetricsManagers.size());
+ auto it = processor->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager1 = it->second;
+ EXPECT_TRUE(metricsManager1->isActive());
+ EXPECT_EQ(3, metricsManager1->mAllMetricProducers.size());
+
+ auto& metricProducer1 = metricsManager1->mAllMetricProducers[0];
+ EXPECT_EQ(metricId1, metricProducer1->getMetricId());
+ EXPECT_FALSE(metricProducer1->isActive());
+
+ auto& metricProducer2 = metricsManager1->mAllMetricProducers[1];
+ EXPECT_EQ(metricId2, metricProducer2->getMetricId());
+ EXPECT_FALSE(metricProducer2->isActive());
+
+ auto& metricProducer3 = metricsManager1->mAllMetricProducers[2];
+ EXPECT_EQ(metricId3, metricProducer3->getMetricId());
+ EXPECT_TRUE(metricProducer3->isActive());
+
+ // Check event activations.
+ EXPECT_EQ(metricsManager1->mAllAtomMatchers.size(), 4);
+ EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(),
+ metric1ActivationTrigger1->atom_matcher_id());
+ const auto& activation1 = metricProducer1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
+ EXPECT_EQ(0, activation1->start_ns);
+ EXPECT_EQ(kNotActive, activation1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
+
+ EXPECT_EQ(metricsManager1->mAllAtomMatchers[1]->getId(),
+ metric1ActivationTrigger2->atom_matcher_id());
+ const auto& activation2 = metricProducer1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
+ EXPECT_EQ(0, activation2->start_ns);
+ EXPECT_EQ(kNotActive, activation2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
+
+ EXPECT_EQ(metricsManager1->mAllAtomMatchers[2]->getId(),
+ metric2ActivationTrigger1->atom_matcher_id());
+ const auto& activation3 = metricProducer2->mEventActivationMap.at(2);
+ EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns);
+ EXPECT_EQ(0, activation3->start_ns);
+ EXPECT_EQ(kNotActive, activation3->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType);
+
+ EXPECT_EQ(metricsManager1->mAllAtomMatchers[3]->getId(),
+ metric2ActivationTrigger2->atom_matcher_id());
+ const auto& activation4 = metricProducer2->mEventActivationMap.at(3);
+ EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns);
+ EXPECT_EQ(0, activation4->start_ns);
+ EXPECT_EQ(kNotActive, activation4->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType);
+ // }}}------------------------------------------------------------------------------
+
+ // Trigger Activation 1 for Metric 1. Should activate on boot.
+ // Trigger Activation 4 for Metric 2. Should activate immediately.
+ long configAddedTimeNs = metricsManager1->mLastReportTimeNs;
+ std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
+ auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 1 + configAddedTimeNs);
+ processor->OnLogEvent(event.get());
+
+ event = CreateFinishScheduledJobEvent(attributions1, "finish1", 2 + configAddedTimeNs);
+ processor->OnLogEvent(event.get());
+
+ // Metric 1 is not active; Activation 1 set to kActiveOnBoot
+ // Metric 2 is active. Activation 4 set to kActive
+ // Metric 3 is active.
+ // {{{---------------------------------------------------------------------------
+ EXPECT_FALSE(metricProducer1->isActive());
+ EXPECT_EQ(0, activation1->start_ns);
+ EXPECT_EQ(kActiveOnBoot, activation1->state);
+ EXPECT_EQ(0, activation2->start_ns);
+ EXPECT_EQ(kNotActive, activation2->state);
+
+ EXPECT_TRUE(metricProducer2->isActive());
+ EXPECT_EQ(0, activation3->start_ns);
+ EXPECT_EQ(kNotActive, activation3->state);
+ EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns);
+ EXPECT_EQ(kActive, activation4->state);
+
+ EXPECT_TRUE(metricProducer3->isActive());
+ // }}}-----------------------------------------------------------------------------
+
+ // Can't fake time with StatsService.
+ // Lets get a time close to the system server death time and make sure it's sane.
+ int64_t approximateSystemServerDeath = getElapsedRealtimeNs();
+ EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs);
+ EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs);
+
+ // System server dies.
+ service.binderDied(nullptr);
+
+ // We should have a new metrics manager. Lets get it and ensure activation status is restored.
+ // {{{---------------------------------------------------------------------------
+ EXPECT_EQ(1, processor->mMetricsManagers.size());
+ it = processor->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager2 = it->second;
+ EXPECT_TRUE(metricsManager2->isActive());
+ EXPECT_EQ(3, metricsManager2->mAllMetricProducers.size());
+
+ auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0];
+ EXPECT_EQ(metricId1, metricProducer1001->getMetricId());
+ EXPECT_FALSE(metricProducer1001->isActive());
+
+ auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1];
+ EXPECT_EQ(metricId2, metricProducer1002->getMetricId());
+ EXPECT_TRUE(metricProducer1002->isActive());
+
+ auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2];
+ EXPECT_EQ(metricId3, metricProducer1003->getMetricId());
+ EXPECT_TRUE(metricProducer1003->isActive());
+
+ // Check event activations.
+ // Activation 1 is kActiveOnBoot.
+ // Activation 2 and 3 are not active.
+ // Activation 4 is active.
+ EXPECT_EQ(metricsManager2->mAllAtomMatchers.size(), 4);
+ EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(),
+ metric1ActivationTrigger1->atom_matcher_id());
+ const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns);
+ EXPECT_EQ(0, activation1001->start_ns);
+ EXPECT_EQ(kActiveOnBoot, activation1001->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType);
+
+ EXPECT_EQ(metricsManager2->mAllAtomMatchers[1]->getId(),
+ metric1ActivationTrigger2->atom_matcher_id());
+ const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns);
+ EXPECT_EQ(0, activation1002->start_ns);
+ EXPECT_EQ(kNotActive, activation1002->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType);
+
+ EXPECT_EQ(metricsManager2->mAllAtomMatchers[2]->getId(),
+ metric2ActivationTrigger1->atom_matcher_id());
+ const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2);
+ EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns);
+ EXPECT_EQ(0, activation1003->start_ns);
+ EXPECT_EQ(kNotActive, activation1003->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType);
+
+ EXPECT_EQ(metricsManager2->mAllAtomMatchers[3]->getId(),
+ metric2ActivationTrigger2->atom_matcher_id());
+ const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3);
+ EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns);
+ EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns);
+ EXPECT_EQ(kActive, activation1004->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType);
+ // }}}------------------------------------------------------------------------------
+}
+
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 2fd1b65..ccfbd23 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -4355,6 +4355,7 @@
* {@link #getOpsForPackage(int, String, String...)})}.
*
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e3ef131..6761aab 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1953,8 +1953,8 @@
private int installExistingPackageAsUser(String packageName, int installReason, int userId)
throws NameNotFoundException {
try {
- int res = mPM.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/,
- installReason);
+ int res = mPM.installExistingPackageAsUser(packageName, userId,
+ INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, installReason, null);
if (res == INSTALL_FAILED_INVALID_URI) {
throw new NameNotFoundException("Package " + packageName + " doesn't exist");
}
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index 19f4335..9727621 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -636,6 +636,11 @@
public int hashCode() {
return Objects.hash(mEvent, mId);
}
+
+ /** @hide */
+ public boolean eventEquals(SecurityEvent other) {
+ return other != null && mEvent.equals(other.mEvent);
+ }
}
/**
* Retrieve all security logs and return immediately.
diff --git a/core/java/android/app/backup/RestoreSession.java b/core/java/android/app/backup/RestoreSession.java
index 084b13b..9336704 100644
--- a/core/java/android/app/backup/RestoreSession.java
+++ b/core/java/android/app/backup/RestoreSession.java
@@ -214,6 +214,7 @@
*
* @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver,
* BackupManagerMonitor, Set)} instead.
+ * @removed
*/
@Deprecated
public int restoreSome(long token, RestoreObserver observer, BackupManagerMonitor monitor,
@@ -240,6 +241,7 @@
*
* @deprecated use {@link RestoreSession#restorePackages(long, RestoreObserver, Set)}
* instead.
+ * @removed
*/
@Deprecated
public int restoreSome(long token, RestoreObserver observer, String[] packages) {
diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java
index 61e4569..147c500 100644
--- a/core/java/android/app/prediction/AppTarget.java
+++ b/core/java/android/app/prediction/AppTarget.java
@@ -206,6 +206,7 @@
/**
* @deprecated Use the other Builder constructors.
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
@@ -244,6 +245,7 @@
/**
* @deprecated Use the appropriate constructor.
+ * @removed
*/
@NonNull
@Deprecated
@@ -258,6 +260,7 @@
/**
* @deprecated Use the appropriate constructor.
+ * @removed
*/
@NonNull
@Deprecated
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 7fa4360..749a011 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -281,20 +281,13 @@
/**
* Gets application usage stats for the given time range, aggregated by the specified interval.
- * <p>The returned list will contain a {@link UsageStats} object for each package that
- * has data for an interval that is a subset of the time range given. To illustrate:</p>
- * <pre>
- * intervalType = INTERVAL_YEARLY
- * beginTime = 2013
- * endTime = 2015 (exclusive)
*
- * Results:
- * 2013 - com.example.alpha
- * 2013 - com.example.beta
- * 2014 - com.example.alpha
- * 2014 - com.example.beta
- * 2014 - com.example.charlie
- * </pre>
+ * <p>
+ * The returned list will contain one or more {@link UsageStats} objects for each package, with
+ * usage data that covers at least the given time range.
+ * Note: The begin and end times of the time range may be expanded to the nearest whole interval
+ * period.
+ * </p>
*
* <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
*
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 71242fb..7cdd268 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -820,6 +820,7 @@
private String setCallingPackage(String callingPackage) {
final String original = mCallingPackage.get();
mCallingPackage.set(callingPackage);
+ onCallingPackageChanged();
return original;
}
@@ -845,6 +846,15 @@
return pkg;
}
+ /** {@hide} */
+ public final @Nullable String getCallingPackageUnchecked() {
+ return mCallingPackage.get();
+ }
+
+ /** {@hide} */
+ public void onCallingPackageChanged() {
+ }
+
/**
* Opaque token representing the identity of an incoming IPC.
*/
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index 8e84079..b0b2c33 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -52,7 +52,7 @@
in IntentSender statusReceiver, int userId);
void installExistingPackage(String packageName, int installFlags, int installReason,
- in IntentSender statusReceiver, int userId);
+ in IntentSender statusReceiver, int userId, in List<String> whiteListedPermissions);
void setPermissionsResult(int sessionId, boolean accepted);
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6ab4657..a7eecd7 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -634,7 +634,7 @@
int getInstallLocation();
int installExistingPackageAsUser(String packageName, int userId, int installFlags,
- int installReason);
+ int installReason, in List<String> whiteListedPermissions);
void verifyPendingInstall(int id, int verificationCode);
void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 89eabc2..3cecd7f 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -627,6 +627,10 @@
* Install the given package, which already exists on the device, for the user for which this
* installer was created.
*
+ * <p>This will
+ * {@link PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set) whitelist
+ * all restricted permissions}.
+ *
* @param packageName The package to install.
* @param installReason Reason for install.
* @param statusReceiver Where to deliver the result.
@@ -639,8 +643,9 @@
@Nullable IntentSender statusReceiver) {
Preconditions.checkNotNull(packageName, "packageName cannot be null");
try {
- mInstaller.installExistingPackage(packageName, 0, installReason, statusReceiver,
- mUserId);
+ mInstaller.installExistingPackage(packageName,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS, installReason,
+ statusReceiver, mUserId, null);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index ff7b347..081c5ad 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -62,6 +62,7 @@
*
* @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_TRIM} instead
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
@@ -75,6 +76,7 @@
*
* @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_SINGLE_LINE} instead
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
@@ -88,6 +90,7 @@
*
* @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_FIRST_LINE} instead
* @hide
+ * @removed
*/
@Deprecated
@SystemApi
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index b0142ea..f662b61 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -98,7 +98,7 @@
* identifiers, while removable cameras have a unique identifier for each
* individual device, even if they are the same model.</p>
*
- * <p>This list doesn't contain physical cameras that can only used as part of a logical
+ * <p>This list doesn't contain physical cameras that can only be used as part of a logical
* multi-camera device.</p>
*
* @return The list of currently connected camera devices.
@@ -263,7 +263,7 @@
* immutable for a given camera.</p>
*
* <p>From API level 29, this function can also be used to query the capabilities of physical
- * cameras that can only be used as part of logical multi-camera. These cameras cannot not be
+ * cameras that can only be used as part of logical multi-camera. These cameras cannot be
* opened directly via {@link #openCamera}</p>
*
* @param cameraId The id of the camera device to query. This could be either a standalone
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9bfdb72..746c3ee 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -977,8 +977,7 @@
* to come. Con permiso, Capitan. The hall is rented, the orchestra
* engaged. It's now time to see if you can dance.</em>
*/
- public static final int Q = CUR_DEVELOPMENT;
-
+ public static final int Q = 29;
}
/** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/IncidentManager.java b/core/java/android/os/IncidentManager.java
index ed8d3f7..a94fd65 100644
--- a/core/java/android/os/IncidentManager.java
+++ b/core/java/android/os/IncidentManager.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -34,6 +35,7 @@
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Class to take an incident report.
@@ -248,6 +250,24 @@
public @NonNull String toString() {
return "PendingReport(" + getUri().toString() + ")";
}
+
+ /**
+ * @inheritDoc
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof PendingReport)) {
+ return false;
+ }
+ final PendingReport that = (PendingReport) obj;
+ return this.mUri.equals(that.mUri)
+ && this.mFlags == that.mFlags
+ && this.mRequestingPackage.equals(that.mRequestingPackage)
+ && this.mTimestamp == that.mTimestamp;
+ }
}
/**
@@ -355,21 +375,35 @@
}
/**
- * Listener for the status of an incident report being authroized or denied.
+ * Listener for the status of an incident report being authorized or denied.
*
* @see #requestAuthorization
* @see #cancelAuthorization
*/
public static class AuthListener {
+ Executor mExecutor;
+
IIncidentAuthListener.Stub mBinder = new IIncidentAuthListener.Stub() {
@Override
public void onReportApproved() {
- AuthListener.this.onReportApproved();
+ if (mExecutor != null) {
+ mExecutor.execute(() -> {
+ AuthListener.this.onReportApproved();
+ });
+ } else {
+ AuthListener.this.onReportApproved();
+ }
}
@Override
public void onReportDenied() {
- AuthListener.this.onReportDenied();
+ if (mExecutor != null) {
+ mExecutor.execute(() -> {
+ AuthListener.this.onReportDenied();
+ });
+ } else {
+ AuthListener.this.onReportDenied();
+ }
}
};
@@ -410,7 +444,23 @@
@RequiresPermission(android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL)
public void requestAuthorization(int callingUid, String callingPackage, int flags,
AuthListener listener) {
+ requestAuthorization(callingUid, callingPackage, flags,
+ mContext.getMainExecutor(), listener);
+ }
+
+ /**
+ * Request authorization of an incident report.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL)
+ public void requestAuthorization(int callingUid, @NonNull String callingPackage, int flags,
+ @NonNull @CallbackExecutor Executor executor, @NonNull AuthListener listener) {
try {
+ if (listener.mExecutor != null) {
+ throw new RuntimeException("Do not reuse AuthListener objects when calling"
+ + " requestAuthorization");
+ }
+ listener.mExecutor = executor;
getCompanionServiceLocked().authorizeReport(callingUid, callingPackage, null, null,
flags, listener.mBinder);
} catch (RemoteException ex) {
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 4ac4850..22ce39d 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -917,8 +917,17 @@
* @see #getDocumentId(Uri)
*/
public static Uri buildDocumentUri(String authority, String documentId) {
+ return getBaseDocumentUriBuilder(authority).appendPath(documentId).build();
+ }
+
+ /** {@hide} */
+ public static Uri buildBaseDocumentUri(String authority) {
+ return getBaseDocumentUriBuilder(authority).build();
+ }
+
+ private static Uri.Builder getBaseDocumentUriBuilder(String authority) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
- .authority(authority).appendPath(PATH_DOCUMENT).appendPath(documentId).build();
+ .authority(authority).appendPath(PATH_DOCUMENT);
}
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 7fdda5d..848dc1a 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -33,7 +33,6 @@
import android.graphics.RenderNode;
import android.os.Build;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.os.SystemClock;
import android.util.AttributeSet;
@@ -120,10 +119,11 @@
final Rect mScreenRect = new Rect();
SurfaceSession mSurfaceSession;
- SurfaceControlWithBackground mSurfaceControl;
+ SurfaceControl mSurfaceControl;
// In the case of format changes we switch out the surface in-place
// we need to preserve the old one until the new one has drawn.
- SurfaceControlWithBackground mDeferredDestroySurfaceControl;
+ SurfaceControl mDeferredDestroySurfaceControl;
+ SurfaceControl mBackgroundControl;
final Rect mTmpRect = new Rect();
final Configuration mConfiguration = new Configuration();
@@ -488,6 +488,29 @@
}
}
+ private void updateBackgroundVisibilityInTransaction(SurfaceControl viewRoot) {
+ if (mBackgroundControl == null) {
+ return;
+ }
+ if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
+ mBackgroundControl.show();
+ mBackgroundControl.setRelativeLayer(viewRoot, Integer.MIN_VALUE);
+ } else {
+ mBackgroundControl.hide();
+ }
+ }
+
+ private void releaseSurfaces() {
+ if (mSurfaceControl != null) {
+ mSurfaceControl.remove();
+ mSurfaceControl = null;
+ }
+ if (mBackgroundControl != null) {
+ mBackgroundControl.remove();
+ mBackgroundControl = null;
+ }
+ }
+
/** @hide */
protected void updateSurface() {
if (!mHaveFrame) {
@@ -554,14 +577,21 @@
updateOpaqueFlag();
final String name = "SurfaceView - " + viewRoot.getTitle().toString();
- mSurfaceControl = new SurfaceControlWithBackground(
- name,
- (mSurfaceFlags & SurfaceControl.OPAQUE) != 0,
- new SurfaceControl.Builder(mSurfaceSession)
- .setBufferSize(mSurfaceWidth, mSurfaceHeight)
- .setFormat(mFormat)
- .setParent(viewRoot.getSurfaceControl())
- .setFlags(mSurfaceFlags));
+ mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession)
+ .setName(name)
+ .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)
+ .setBufferSize(mSurfaceWidth, mSurfaceHeight)
+ .setFormat(mFormat)
+ .setParent(viewRoot.getSurfaceControl())
+ .setFlags(mSurfaceFlags)
+ .build();
+ mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession)
+ .setName("Background for -" + name)
+ .setOpaque(true)
+ .setColorLayer()
+ .setParent(mSurfaceControl)
+ .build();
+
} else if (mSurfaceControl == null) {
return;
}
@@ -578,11 +608,13 @@
SurfaceControl.openTransaction();
try {
mSurfaceControl.setLayer(mSubLayer);
+
if (mViewVisibility) {
mSurfaceControl.show();
} else {
mSurfaceControl.hide();
}
+ updateBackgroundVisibilityInTransaction(viewRoot.getSurfaceControl());
// While creating the surface, we will set it's initial
// geometry. Outside of that though, we should generally
@@ -668,7 +700,7 @@
}
if (creating) {
- mSurface.copyFrom(mSurfaceControl.mForegroundControl);
+ mSurface.copyFrom(mSurfaceControl);
}
if (sizeChanged && getContext().getApplicationInfo().targetSdkVersion
@@ -678,7 +710,7 @@
// existing {@link Surface} will be ignored when the size changes.
// Therefore, we must explicitly recreate the {@link Surface} in these
// cases.
- mSurface.createFrom(mSurfaceControl.mForegroundControl);
+ mSurface.createFrom(mSurfaceControl);
}
if (visible && mSurface.isValid()) {
@@ -725,8 +757,7 @@
if (mSurfaceControl != null && !mSurfaceCreated) {
mSurface.release();
- mSurfaceControl.remove();
- mSurfaceControl = null;
+ releaseSurfaces();
}
}
} catch (Exception ex) {
@@ -827,8 +858,7 @@
private void setParentSpaceRectangle(Rect position, long frameNumber) {
final ViewRootImpl viewRoot = getViewRootImpl();
- applySurfaceTransforms(mSurfaceControl.mForegroundControl, position, frameNumber);
- applySurfaceTransforms(mSurfaceControl.mBackgroundControl, position, frameNumber);
+ applySurfaceTransforms(mSurfaceControl, position, frameNumber);
applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,
frameNumber);
@@ -893,13 +923,10 @@
if (frameNumber > 0) {
final ViewRootImpl viewRoot = getViewRootImpl();
- mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mForegroundControl, viewRoot.mSurface,
- frameNumber);
- mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mBackgroundControl, viewRoot.mSurface,
+ mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
frameNumber);
}
- mRtTransaction.hide(mSurfaceControl.mForegroundControl);
- mRtTransaction.hide(mSurfaceControl.mBackgroundControl);
+ mRtTransaction.hide(mSurfaceControl);
mRtTransaction.apply();
}
};
@@ -946,7 +973,19 @@
* @hide
*/
public void setResizeBackgroundColor(int bgColor) {
- mSurfaceControl.setBackgroundColor(bgColor);
+ if (mBackgroundControl == null) {
+ return;
+ }
+
+ final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f,
+ Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f };
+
+ SurfaceControl.openTransaction();
+ try {
+ mBackgroundControl.setColor(colorComponents);
+ } finally {
+ SurfaceControl.closeTransaction();
+ }
}
@UnsupportedAppUsage
@@ -1130,134 +1169,6 @@
* @return The SurfaceControl for this SurfaceView.
*/
public SurfaceControl getSurfaceControl() {
- return mSurfaceControl.mForegroundControl;
- }
-
- class SurfaceControlWithBackground {
- SurfaceControl mForegroundControl;
- SurfaceControl mBackgroundControl;
- private boolean mOpaque = true;
- public boolean mVisible = false;
-
- public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b)
- throws Exception {
- mForegroundControl = b.setName(name).build();
- mBackgroundControl = b.setName("Background for -" + name)
- // Unset the buffer size of the background color layer.
- .setBufferSize(0, 0)
- .setColorLayer()
- .build();
-
- mOpaque = opaque;
- }
-
- public void setAlpha(float alpha) {
- mForegroundControl.setAlpha(alpha);
- mBackgroundControl.setAlpha(alpha);
- }
-
- public void setLayer(int zorder) {
- mForegroundControl.setLayer(zorder);
- // -3 is below all other child layers as SurfaceView never goes below -2
- mBackgroundControl.setLayer(-3);
- }
-
- public void setPosition(float x, float y) {
- mForegroundControl.setPosition(x, y);
- mBackgroundControl.setPosition(x, y);
- }
-
- public void setBufferSize(int w, int h) {
- mForegroundControl.setBufferSize(w, h);
- // The background surface is a color layer so we do not set a size.
- }
-
- public void setWindowCrop(Rect crop) {
- mForegroundControl.setWindowCrop(crop);
- mBackgroundControl.setWindowCrop(crop);
- }
-
- public void setWindowCrop(int width, int height) {
- mForegroundControl.setWindowCrop(width, height);
- mBackgroundControl.setWindowCrop(width, height);
- }
-
- public void setLayerStack(int layerStack) {
- mForegroundControl.setLayerStack(layerStack);
- mBackgroundControl.setLayerStack(layerStack);
- }
-
- public void setOpaque(boolean isOpaque) {
- mForegroundControl.setOpaque(isOpaque);
- mOpaque = isOpaque;
- updateBackgroundVisibility();
- }
-
- public void setSecure(boolean isSecure) {
- mForegroundControl.setSecure(isSecure);
- }
-
- public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- mForegroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
- mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy);
- }
-
- public void hide() {
- mForegroundControl.hide();
- mVisible = false;
- updateBackgroundVisibility();
- }
-
- public void show() {
- mForegroundControl.show();
- mVisible = true;
- updateBackgroundVisibility();
- }
-
- public void remove() {
- mForegroundControl.remove();
- mBackgroundControl.remove();
- }
-
- public void release() {
- mForegroundControl.release();
- mBackgroundControl.release();
- }
-
- public void setTransparentRegionHint(Region region) {
- mForegroundControl.setTransparentRegionHint(region);
- mBackgroundControl.setTransparentRegionHint(region);
- }
-
- public void deferTransactionUntil(IBinder handle, long frame) {
- mForegroundControl.deferTransactionUntil(handle, frame);
- mBackgroundControl.deferTransactionUntil(handle, frame);
- }
-
- public void deferTransactionUntil(Surface barrier, long frame) {
- mForegroundControl.deferTransactionUntil(barrier, frame);
- mBackgroundControl.deferTransactionUntil(barrier, frame);
- }
-
- /** Set the color to fill the background with. */
- private void setBackgroundColor(int bgColor) {
- final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f,
- Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f };
-
- SurfaceControl.openTransaction();
- try {
- mBackgroundControl.setColor(colorComponents);
- } finally {
- SurfaceControl.closeTransaction();
- }
- }
-
- void updateBackgroundVisibility() {
- if (mOpaque && mVisible) {
- mBackgroundControl.show();
- } else {
- mBackgroundControl.hide();
- }
- }
+ return mSurfaceControl;
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a444953..3590c34 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9527,18 +9527,15 @@
* <pre>
* ContentCaptureSession mainSession = rootView.getContentCaptureSession();
* mainSession.setContentCaptureContext(ContentCaptureContext.forLocusId(Uri.parse(myUrl));
- * <pre>
+ * </pre>
*
* <p>Then if the page had an {@code IFRAME}, you would create a new session for it:
*
- * <p>For example, if your activity is associated with a web domain, you could create a session
- * {@code onCreate()} and associate it with the root view of the activity:
- *
* <pre>
* ContentCaptureSession iframeSession = mainSession.createContentCaptureSession(
* ContentCaptureContext.forLocusId(Uri.parse(iframeUrl)));
* iframeView.setContentCaptureSession(iframeSession);
- * <pre>
+ * </pre>
*
* @param contentCaptureSession a session created by
* {@link ContentCaptureSession#createContentCaptureSession(
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index f9f2625..975d481 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -41,8 +41,8 @@
import java.util.Random;
/**
- * Session used to notify a system-provided Content Capture service about events associated with
- * views.
+ * Session used when the Android a system-provided content capture service
+ * about events associated with views.
*/
public abstract class ContentCaptureSession implements AutoCloseable {
diff --git a/core/java/android/view/contentcapture/DataRemovalRequest.java b/core/java/android/view/contentcapture/DataRemovalRequest.java
index 8deabe1..f403dac 100644
--- a/core/java/android/view/contentcapture/DataRemovalRequest.java
+++ b/core/java/android/view/contentcapture/DataRemovalRequest.java
@@ -31,8 +31,11 @@
import java.util.List;
/**
- * Class used by apps to request the Content Capture service to remove data associated with
+ * Class used by apps to request the content capture service to remove data associated with
* {@link LocusId LocusIds}.
+ *
+ * <p>An app which has tagged data with a LocusId can therefore delete them later. This is intended
+ * to let apps propagate deletions of user data into the operating system.
*/
public final class DataRemovalRequest implements Parcelable {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 20fc0b1..3779779 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -887,6 +887,7 @@
*
* @return true if popup will be clipped to the screen instead of the window, false otherwise
* @deprecated Use {@link #isClippedToScreen()} instead
+ * @removed
*/
@Deprecated
public boolean isClipToScreenEnabled() {
@@ -901,6 +902,7 @@
* the {@link #update()} methods.</p>
*
* @deprecated Use {@link #setIsClippedToScreen(boolean)} instead
+ * @removed
*/
@Deprecated
public void setClipToScreenEnabled(boolean enabled) {
@@ -988,6 +990,7 @@
* @return true if the window will always be positioned in screen coordinates.
*
* @deprecated Use {@link #isLaidOutInScreen()} instead
+ * @removed
*/
@Deprecated
public boolean isLayoutInScreenEnabled() {
@@ -1001,6 +1004,7 @@
*
* @param enabled true if the popup should always be positioned in screen coordinates
* @deprecated Use {@link #setIsLaidOutInScreen(boolean)} instead
+ * @removed
*/
@Deprecated
public void setLayoutInScreenEnabled(boolean enabled) {
diff --git a/core/res/res/layout/autofill_save.xml b/core/res/res/layout/autofill_save.xml
index d903524..d4c3565 100644
--- a/core/res/res/layout/autofill_save.xml
+++ b/core/res/res/layout/autofill_save.xml
@@ -26,17 +26,17 @@
android:id="@+id/autofill_save"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="32dp"
- android:paddingTop="16dp"
- android:elevation="32dp"
+ android:layout_marginTop="@dimen/autofill_save_outer_top_margin"
+ android:paddingTop="@dimen/autofill_save_outer_top_padding"
+ android:elevation="@dimen/autofill_elevation"
android:background="?android:attr/colorBackground"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
+ android:paddingStart="@dimen/autofill_save_inner_padding"
+ android:paddingEnd="@dimen/autofill_save_inner_padding"
android:orientation="vertical">
<LinearLayout
@@ -47,17 +47,16 @@
<ImageView
android:id="@+id/autofill_save_icon"
android:scaleType="fitStart"
- android:layout_width="24dp"
- android:layout_height="24dp"/>
+ android:layout_width="@dimen/autofill_save_icon_size"
+ android:layout_height="@dimen/autofill_save_icon_size"/>
<TextView
android:id="@+id/autofill_save_title"
- android:paddingStart="8dp"
+ android:paddingStart="@dimen/autofill_save_title_start_padding"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/autofill_save_title"
- android:textSize="16sp"
- android:textColor="?android:attr/textColorPrimary"
+ android:textAppearance="@style/TextAppearance.DeviceDefault.Subhead"
android:layout_weight="1">
</TextView>
@@ -67,7 +66,7 @@
android:id="@+id/autofill_save_custom_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="4dp"
+ android:layout_marginTop="@dimen/autofill_save_scroll_view_top_margin"
android:visibility="gone"/>
</LinearLayout>
@@ -76,7 +75,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
- android:padding="16dp"
+ android:padding="@dimen/autofill_save_button_bar_padding"
android:clipToPadding="false"
android:layout_weight="1"
android:orientation="horizontal">
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 167e672..6f11432 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -73,6 +73,11 @@
<dimen name="navigation_bar_width_car_mode">96dp</dimen>
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">22dip</dimen>
+ <!-- Desired size of system icons in status bar. -->
+ <dimen name="status_bar_system_icon_size">15dp</dimen>
+ <!-- Intrinsic size of most system icons in status bar. This is the default value that
+ is used if a Drawable reports an intrinsic size of 0. -->
+ <dimen name="status_bar_system_icon_intrinsic_size">17dp</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
@@ -668,6 +673,16 @@
<dimen name="autofill_dataset_picker_max_width">90%</dimen>
<dimen name="autofill_dataset_picker_max_height">90%</dimen>
+ <!-- Autofill save dialog padding -->
+ <dimen name="autofill_save_outer_top_margin">32dp</dimen>
+ <dimen name="autofill_save_outer_top_padding">16dp</dimen>
+ <dimen name="autofill_elevation">32dp</dimen>
+ <dimen name="autofill_save_inner_padding">16dp</dimen>
+ <dimen name="autofill_save_icon_size">24dp</dimen>
+ <dimen name="autofill_save_title_start_padding">8dp</dimen>
+ <dimen name="autofill_save_scroll_view_top_margin">4dp</dimen>
+ <dimen name="autofill_save_button_bar_padding">16dp</dimen>
+
<!-- Max height of the the autofill save custom subtitle as a fraction of the screen width/height -->
<dimen name="autofill_save_custom_subtitle_max_height">20%</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 33bc341..fb54566 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2889,6 +2889,99 @@
<!-- ===============================================================
Resources added in version Q of the platform
+ =============================================================== -->
+ <eat-comment />
+
+ <public type="attr" name="packageType" id="0x01010587" />
+ <public type="attr" name="opticalInsetLeft" id="0x01010588" />
+ <public type="attr" name="opticalInsetTop" id="0x01010589" />
+ <public type="attr" name="opticalInsetRight" id="0x0101058a" />
+ <public type="attr" name="opticalInsetBottom" id="0x0101058b" />
+ <public type="attr" name="forceDarkAllowed" id="0x0101058c" />
+ <!-- @hide @SystemApi -->
+ <public type="attr" name="supportsAmbientMode" id="0x0101058d" />
+ <!-- @hide For use by platform and tools only. Developers should not specify this value. -->
+ <public type="attr" name="usesNonSdkApi" id="0x0101058e" />
+ <public type="attr" name="nonInteractiveUiTimeout" id="0x0101058f" />
+ <public type="attr" name="isLightTheme" id="0x01010590" />
+ <public type="attr" name="isSplitRequired" id="0x01010591" />
+ <public type="attr" name="textLocale" id="0x01010592" />
+ <public type="attr" name="settingsSliceUri" id="0x01010593" />
+ <public type="attr" name="shell" id="0x01010594" />
+ <public type="attr" name="interactiveUiTimeout" id="0x01010595" />
+ <public type="attr" name="supportsMultipleDisplays" id="0x01010596" />
+ <public type="attr" name="useAppZygote" id="0x01010597" />
+ <public type="attr" name="selectionDividerHeight" id="0x01010598" />
+ <public type="attr" name="foregroundServiceType" id="0x01010599" />
+ <public type="attr" name="hasFragileUserData" id="0x0101059a" />
+ <public type="attr" name="minAspectRatio" id="0x0101059b" />
+ <public type="attr" name="inheritShowWhenLocked" id="0x0101059c" />
+ <public type="attr" name="zygotePreloadName" id="0x0101059d" />
+ <public type="attr" name="useEmbeddedDex" id="0x0101059e" />
+ <public type="attr" name="forceUriPermissions" id="0x0101059f" />
+ <!-- @hide @SystemApi -->
+ <public type="attr" name="allowClearUserDataOnFailedRestore" id="0x01010600" />
+ <public type="attr" name="allowAudioPlaybackCapture" id="0x01010601" />
+ <public type="attr" name="secureElementName" id="0x01010602" />
+ <public type="attr" name="requestLegacyExternalStorage" id="0x01010603" />
+ <public type="attr" name="enforceStatusBarContrast" id="0x01010604" />
+ <public type="attr" name="enforceNavigationBarContrast" id="0x01010605" />
+ <public type="attr" name="identifier" id="0x01010606" />
+
+ <!-- @hide @SystemApi -->
+ <public type="drawable" name="ic_info" id="0x010800b4" />
+
+ <!-- @hide @SystemApi -->
+ <public type="style" name="Theme.DeviceDefault.DocumentsUI" id="0x010302e2" />
+ <public type="style" name="Theme.DeviceDefault.DayNight" id="0x010302e3" />
+ <public type="style" name="ThemeOverlay.DeviceDefault.Accent.DayNight" id="0x010302e4" />
+
+ <public type="id" name="accessibilityActionPageUp" id="0x01020046" />
+ <public type="id" name="accessibilityActionPageDown" id="0x01020047" />
+ <public type="id" name="accessibilityActionPageLeft" id="0x01020048" />
+ <public type="id" name="accessibilityActionPageRight" id="0x01020049" />
+
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_helpPackageNameKey" id="0x0104001b" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_helpPackageNameValue" id="0x0104001c" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_helpIntentExtraKey" id="0x0104001d" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_helpIntentNameKey" id="0x0104001e" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_feedbackIntentExtraKey" id="0x0104001f" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_feedbackIntentNameKey" id="0x01040020" />
+ <!-- @hide @SystemApi @TestApi -->
+ <public type="string" name="config_defaultAssistant" id="0x01040021" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_defaultBrowser" id="0x01040022" />
+ <!-- @hide @SystemApi @TestApi -->
+ <public type="string" name="config_defaultDialer" id="0x01040023" />
+ <!-- @hide @SystemApi -->
+ <public type="string" name="config_defaultSms" id="0x01040024" />
+
+ <!-- @hide @SystemApi -->
+ <public type="bool" name="config_sendPackageName" id="0x01110000" />
+ <!-- @hide @SystemApi -->
+ <public type="bool" name="config_showDefaultAssistant" id="0x01110001" />
+ <!-- @hide @SystemApi -->
+ <public type="bool" name="config_showDefaultEmergency" id="0x01110002" />
+ <!-- @hide @SystemApi -->
+ <public type="bool" name="config_showDefaultHome" id="0x01110003" />
+ <!-- @hide @TestApi -->
+ <public type="bool" name="config_perDisplayFocusEnabled" id="0x01110004" />
+
+ <!-- @hide @SystemApi -->
+ <public type="dimen" name="config_restrictedIconSize" id="0x01050007" />
+
+ <!-- @hide @SystemApi -->
+ <public type="color" name="system_notification_accent_color" id="0x0106001c" />
+
+
+ <!-- ===============================================================
+ Resources added in version R of the platform
NOTE: add <public> elements within a <public-group> like so:
@@ -2904,113 +2997,28 @@
=============================================================== -->
<eat-comment />
- <public-group type="attr" first-id="0x01010587">
- <public name="packageType" />
- <public name="opticalInsetLeft" />
- <public name="opticalInsetTop" />
- <public name="opticalInsetRight" />
- <public name="opticalInsetBottom" />
- <public name="forceDarkAllowed" />
- <!-- @hide @SystemApi -->
- <public name="supportsAmbientMode" />
- <!-- @hide For use by platform and tools only. Developers should not specify this value. -->
- <public name="usesNonSdkApi" />
- <public name="nonInteractiveUiTimeout" />
- <public name="isLightTheme" />
- <public name="isSplitRequired" />
- <public name="textLocale" />
- <public name="settingsSliceUri" />
- <public name="shell" />
- <public name="interactiveUiTimeout" />
- <public name="__removed6" />
- <public name="supportsMultipleDisplays" />
- <public name="useAppZygote" />
- <public name="__removed1" />
- <public name="__removed2" />
- <public name="__removed3" />
- <public name="__removed4" />
- <public name="__removed5" />
- <public name="selectionDividerHeight" />
- <public name="foregroundServiceType" />
- <public name="hasFragileUserData" />
- <public name="minAspectRatio" />
- <public name="inheritShowWhenLocked" />
- <public name="zygotePreloadName" />
- <public name="useEmbeddedDex" />
- <public name="forceUriPermissions" />
- <!-- @hide @SystemApi -->
- <public name="allowClearUserDataOnFailedRestore"/>
- <public name="allowAudioPlaybackCapture"/>
- <public name="secureElementName" />
- <public name="requestLegacyExternalStorage"/>
- <public name="enforceStatusBarContrast" />
- <public name="enforceNavigationBarContrast" />
- <public name="identifier" />
+ <public-group type="attr" first-id="0x01010607">
</public-group>
- <public-group type="drawable" first-id="0x010800b4">
- <!-- @hide @SystemApi -->
- <public name="ic_info" />
+ <public-group type="drawable" first-id="0x010800b5">
</public-group>
- <public-group type="style" first-id="0x010302e2">
- <!-- @hide @SystemApi -->
- <public name="Theme.DeviceDefault.DocumentsUI" />
- <public name="Theme.DeviceDefault.DayNight" />
- <public name="ThemeOverlay.DeviceDefault.Accent.DayNight" />
+ <public-group type="style" first-id="0x010302e5">
</public-group>
- <public-group type="id" first-id="0x01020046">
- <public name="accessibilityActionPageUp" />
- <public name="accessibilityActionPageDown" />
- <public name="accessibilityActionPageLeft" />
- <public name="accessibilityActionPageRight" />
+ <public-group type="id" first-id="0x0102004a">
</public-group>
- <public-group type="string" first-id="0x0104001b">
- <!-- @hide @SystemApi -->
- <public name="config_helpPackageNameKey" />
- <!-- @hide @SystemApi -->
- <public name="config_helpPackageNameValue" />
- <!-- @hide @SystemApi -->
- <public name="config_helpIntentExtraKey" />
- <!-- @hide @SystemApi -->
- <public name="config_helpIntentNameKey" />
- <!-- @hide @SystemApi -->
- <public name="config_feedbackIntentExtraKey" />
- <!-- @hide @SystemApi -->
- <public name="config_feedbackIntentNameKey" />
- <!-- @hide @SystemApi @TestApi -->
- <public name="config_defaultAssistant" />
- <!-- @hide @SystemApi -->
- <public name="config_defaultBrowser" />
- <!-- @hide @SystemApi @TestApi -->
- <public name="config_defaultDialer" />
- <!-- @hide @SystemApi -->
- <public name="config_defaultSms" />
+ <public-group type="string" first-id="0x01040025">
</public-group>
- <public-group type="bool" first-id="0x01110000">
- <!-- @hide @SystemApi -->
- <public name="config_sendPackageName" />
- <!-- @hide @SystemApi -->
- <public name="config_showDefaultAssistant" />
- <!-- @hide @SystemApi -->
- <public name="config_showDefaultEmergency" />
- <!-- @hide @SystemApi -->
- <public name="config_showDefaultHome" />
- <!-- @hide @TestApi -->
- <public name="config_perDisplayFocusEnabled" />
+ <public-group type="bool" first-id="0x01110005">
</public-group>
- <public-group type="dimen" first-id="0x01050007">
- <!-- @hide @SystemApi -->
- <public name="config_restrictedIconSize" />
+ <public-group type="dimen" first-id="0x01050008">
</public-group>
- <public-group type="color" first-id="0x0106001c">
- <!-- @hide @SystemApi -->
- <public name="system_notification_accent_color" />
+ <public-group type="color" first-id="0x0106001d">
</public-group>
<!-- ===============================================================
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7de6ca5..37678dd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1561,7 +1561,7 @@
<!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=69] -->
<string name="face_error_hw_not_available">Can\u2019t verify face. Hardware not available.</string>
<!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
- <string name="face_error_timeout">Face timeout reached. Try again.</string>
+ <string name="face_error_timeout">Try face authentication again.</string>
<!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=69] -->
<string name="face_error_no_space">Can\u2019t store new face data. Delete an old one first.</string>
<!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1ef2eb4..3a348f0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2279,6 +2279,8 @@
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
<java-symbol type="dimen" name="status_bar_icon_size" />
+ <java-symbol type="dimen" name="status_bar_system_icon_size" />
+ <java-symbol type="dimen" name="status_bar_system_icon_intrinsic_size" />
<java-symbol type="drawable" name="list_selector_pressed_holo_dark" />
<java-symbol type="drawable" name="scrubber_control_disabled_holo" />
<java-symbol type="drawable" name="scrubber_control_selector_holo" />
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 8551234..f326ce8 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -153,8 +153,7 @@
mNativeSurface = nullptr;
}
- if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f &&
- !mFixedRenderAhead) {
+ if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f) {
mFixedRenderAhead = false;
mRenderAheadCapacity = 1;
} else {
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index 360e8d3..60d0318 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -123,6 +123,7 @@
size_t size(); // Get the size of the serialized protobuf.
sp<ProtoReader> data(); // Get the reader apis of the data.
bool flush(int fd); // Flush data directly to a file descriptor.
+ bool serializeToString(std::string* out); // Serializes the proto to a string.
/**
* Clears the ProtoOutputStream so the buffer can be reused instead of deallocation/allocation again.
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index ccbb83b..98a68c6 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -448,6 +448,23 @@
return true;
}
+bool
+ProtoOutputStream::serializeToString(std::string* out)
+{
+ if (out == nullptr) return false;
+ if (!compact()) return false;
+
+
+ sp<ProtoReader> reader = mBuffer->read();
+ out->reserve(reader->size());
+ while (reader->hasNext()) {
+ out->append(static_cast<const char*>(static_cast<const void*>(reader->readBuffer())),
+ reader->currentToRead());
+ reader->move(reader->currentToRead());
+ }
+ return true;
+}
+
sp<ProtoReader>
ProtoOutputStream::data()
{
diff --git a/libs/protoutil/tests/EncodedBuffer_test.cpp b/libs/protoutil/tests/EncodedBuffer_test.cpp
index 398af60..f895154 100644
--- a/libs/protoutil/tests/EncodedBuffer_test.cpp
+++ b/libs/protoutil/tests/EncodedBuffer_test.cpp
@@ -29,101 +29,101 @@
}
TEST(EncodedBufferTest, WriteSimple) {
- EncodedBuffer buffer(TEST_CHUNK_SIZE);
- EXPECT_EQ(buffer.size(), 0UL);
- expectPointer(buffer.wp(), 0);
- EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_SIZE);
+ sp<EncodedBuffer> buffer = new EncodedBuffer(TEST_CHUNK_SIZE);
+ EXPECT_EQ(buffer->size(), 0UL);
+ expectPointer(buffer->wp(), 0);
+ EXPECT_EQ(buffer->currentToWrite(), TEST_CHUNK_SIZE);
for (size_t i = 0; i < TEST_CHUNK_HALF_SIZE; i++) {
- buffer.writeRawByte(50 + i);
+ buffer->writeRawByte(50 + i);
}
- EXPECT_EQ(buffer.size(), TEST_CHUNK_HALF_SIZE);
- expectPointer(buffer.wp(), TEST_CHUNK_HALF_SIZE);
- EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_HALF_SIZE);
+ EXPECT_EQ(buffer->size(), TEST_CHUNK_HALF_SIZE);
+ expectPointer(buffer->wp(), TEST_CHUNK_HALF_SIZE);
+ EXPECT_EQ(buffer->currentToWrite(), TEST_CHUNK_HALF_SIZE);
for (size_t i = 0; i < TEST_CHUNK_SIZE; i++) {
- buffer.writeRawByte(80 + i);
+ buffer->writeRawByte(80 + i);
}
- EXPECT_EQ(buffer.size(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
- expectPointer(buffer.wp(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
- EXPECT_EQ(buffer.currentToWrite(), TEST_CHUNK_HALF_SIZE);
+ EXPECT_EQ(buffer->size(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
+ expectPointer(buffer->wp(), TEST_CHUNK_SIZE + TEST_CHUNK_HALF_SIZE);
+ EXPECT_EQ(buffer->currentToWrite(), TEST_CHUNK_HALF_SIZE);
// verifies the buffer's data
- expectPointer(buffer.ep(), 0);
+ expectPointer(buffer->ep(), 0);
for (size_t i = 0; i < TEST_CHUNK_HALF_SIZE; i++) {
- EXPECT_EQ(buffer.readRawByte(), 50 + i);
+ EXPECT_EQ(buffer->readRawByte(), 50 + i);
}
for (size_t i = 0; i < TEST_CHUNK_SIZE; i++) {
- EXPECT_EQ(buffer.readRawByte(), 80 + i);
+ EXPECT_EQ(buffer->readRawByte(), 80 + i);
}
// clears the buffer
- buffer.clear();
- EXPECT_EQ(buffer.size(), 0UL);
- expectPointer(buffer.wp(), 0);
+ buffer->clear();
+ EXPECT_EQ(buffer->size(), 0UL);
+ expectPointer(buffer->wp(), 0);
}
TEST(EncodedBufferTest, WriteVarint) {
- EncodedBuffer buffer(TEST_CHUNK_SIZE);
+ sp<EncodedBuffer> buffer = new EncodedBuffer(TEST_CHUNK_SIZE);
size_t expected_buffer_size = 0;
- EXPECT_EQ(buffer.writeRawVarint32(13), 1);
+ EXPECT_EQ(buffer->writeRawVarint32(13), 1);
expected_buffer_size += 1;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
- EXPECT_EQ(buffer.writeRawVarint32(UINT32_C(-1)), 5);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
+ EXPECT_EQ(buffer->writeRawVarint32(UINT32_C(-1)), 5);
expected_buffer_size += 5;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
- EXPECT_EQ(buffer.writeRawVarint64(200), 2);
+ EXPECT_EQ(buffer->writeRawVarint64(200), 2);
expected_buffer_size += 2;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
- EXPECT_EQ(buffer.writeRawVarint64(UINT64_C(-1)), 10);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
+ EXPECT_EQ(buffer->writeRawVarint64(UINT64_C(-1)), 10);
expected_buffer_size += 10;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
- buffer.writeRawFixed32(UINT32_C(-1));
+ buffer->writeRawFixed32(UINT32_C(-1));
expected_buffer_size += 4;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
- buffer.writeRawFixed64(UINT64_C(-1));
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
+ buffer->writeRawFixed64(UINT64_C(-1));
expected_buffer_size += 8;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
- EXPECT_EQ(buffer.writeHeader(32, 2), 2);
+ EXPECT_EQ(buffer->writeHeader(32, 2), 2);
expected_buffer_size += 2;
- EXPECT_EQ(buffer.size(), expected_buffer_size);
+ EXPECT_EQ(buffer->size(), expected_buffer_size);
// verify data are correctly written to the buffer.
- expectPointer(buffer.ep(), 0);
- EXPECT_EQ(buffer.readRawVarint(), UINT32_C(13));
- EXPECT_EQ(buffer.readRawVarint(), UINT32_C(-1));
- EXPECT_EQ(buffer.readRawVarint(), UINT64_C(200));
- EXPECT_EQ(buffer.readRawVarint(), UINT64_C(-1));
- EXPECT_EQ(buffer.readRawFixed32(), UINT32_C(-1));
- EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(-1));
- EXPECT_EQ(buffer.readRawVarint(), UINT64_C((32 << 3) + 2));
- expectPointer(buffer.ep(), expected_buffer_size);
+ expectPointer(buffer->ep(), 0);
+ EXPECT_EQ(buffer->readRawVarint(), UINT32_C(13));
+ EXPECT_EQ(buffer->readRawVarint(), UINT32_C(-1));
+ EXPECT_EQ(buffer->readRawVarint(), UINT64_C(200));
+ EXPECT_EQ(buffer->readRawVarint(), UINT64_C(-1));
+ EXPECT_EQ(buffer->readRawFixed32(), UINT32_C(-1));
+ EXPECT_EQ(buffer->readRawFixed64(), UINT64_C(-1));
+ EXPECT_EQ(buffer->readRawVarint(), UINT64_C((32 << 3) + 2));
+ expectPointer(buffer->ep(), expected_buffer_size);
}
TEST(EncodedBufferTest, Edit) {
- EncodedBuffer buffer(TEST_CHUNK_SIZE);
- buffer.writeRawFixed64(0xdeadbeefdeadbeef);
- EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0xdeadbeefdeadbeef));
+ sp<EncodedBuffer> buffer = new EncodedBuffer(TEST_CHUNK_SIZE);
+ buffer->writeRawFixed64(0xdeadbeefdeadbeef);
+ EXPECT_EQ(buffer->readRawFixed64(), UINT64_C(0xdeadbeefdeadbeef));
- buffer.editRawFixed32(4, 0x12345678);
+ buffer->editRawFixed32(4, 0x12345678);
// fixed 64 is little endian order.
- buffer.ep()->rewind(); // rewind ep for readRawFixed64 from 0
- EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0x12345678deadbeef));
+ buffer->ep()->rewind(); // rewind ep for readRawFixed64 from 0
+ EXPECT_EQ(buffer->readRawFixed64(), UINT64_C(0x12345678deadbeef));
- buffer.wp()->rewind();
- expectPointer(buffer.wp(), 0);
- buffer.copy(4, 3);
- buffer.ep()->rewind(); // rewind ep for readRawFixed64 from 0
- EXPECT_EQ(buffer.readRawFixed64(), UINT64_C(0x12345678de345678));
+ buffer->wp()->rewind();
+ expectPointer(buffer->wp(), 0);
+ buffer->copy(4, 3);
+ buffer->ep()->rewind(); // rewind ep for readRawFixed64 from 0
+ EXPECT_EQ(buffer->readRawFixed64(), UINT64_C(0x12345678de345678));
}
TEST(EncodedBufferTest, ReadSimple) {
- EncodedBuffer buffer(TEST_CHUNK_SIZE);
+ sp<EncodedBuffer> buffer = new EncodedBuffer(TEST_CHUNK_SIZE);
for (size_t i = 0; i < TEST_CHUNK_3X_SIZE; i++) {
- buffer.writeRawByte(i);
+ buffer->writeRawByte(i);
}
- sp<ProtoReader> reader1 = buffer.read();
+ sp<ProtoReader> reader1 = buffer->read();
EXPECT_EQ(reader1->size(), TEST_CHUNK_3X_SIZE);
EXPECT_EQ(reader1->bytesRead(), 0);
@@ -132,7 +132,7 @@
}
EXPECT_EQ(reader1->bytesRead(), TEST_CHUNK_3X_SIZE);
- sp<ProtoReader> reader2 = buffer.read();
+ sp<ProtoReader> reader2 = buffer->read();
uint8_t val = 0;
while (reader2->hasNext()) {
EXPECT_EQ(reader2->next(), val);
@@ -143,10 +143,10 @@
}
TEST(EncodedBufferTest, ReadVarint) {
- EncodedBuffer buffer;
+ sp<EncodedBuffer> buffer = new EncodedBuffer();
uint64_t val = UINT64_C(1522865904593);
- size_t len = buffer.writeRawVarint64(val);
- sp<ProtoReader> reader = buffer.read();
+ size_t len = buffer->writeRawVarint64(val);
+ sp<ProtoReader> reader = buffer->read();
EXPECT_EQ(reader->size(), len);
EXPECT_EQ(reader->readRawVarint(), val);
}
diff --git a/libs/protoutil/tests/ProtoOutputStream_test.cpp b/libs/protoutil/tests/ProtoOutputStream_test.cpp
index 9d357f3..6282fd5 100644
--- a/libs/protoutil/tests/ProtoOutputStream_test.cpp
+++ b/libs/protoutil/tests/ProtoOutputStream_test.cpp
@@ -88,6 +88,50 @@
EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
}
+TEST(ProtoOutputStreamTest, SerializeToStringPrimitives) {
+ std::string s = "hello";
+ const char b[5] = { 'a', 'p', 'p', 'l', 'e' };
+
+ ProtoOutputStream proto;
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | PrimitiveProto::kValInt32FieldNumber, 123));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT64 | PrimitiveProto::kValInt64FieldNumber, -1LL));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_FLOAT | PrimitiveProto::kValFloatFieldNumber, -23.5f));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_DOUBLE | PrimitiveProto::kValDoubleFieldNumber, 324.5));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_UINT32 | PrimitiveProto::kValUint32FieldNumber, 3424));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_UINT64 | PrimitiveProto::kValUint64FieldNumber, 57LL));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED32 | PrimitiveProto::kValFixed32FieldNumber, -20));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_FIXED64 | PrimitiveProto::kValFixed64FieldNumber, -37LL));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, true));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | PrimitiveProto::kValStringFieldNumber, s));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | PrimitiveProto::kValBytesFieldNumber, b, 5));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED32 | PrimitiveProto::kValSfixed32FieldNumber, 63));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_SFIXED64 | PrimitiveProto::kValSfixed64FieldNumber, -54));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_SINT32 | PrimitiveProto::kValSint32FieldNumber, -533));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_SINT64 | PrimitiveProto::kValSint64FieldNumber, -61224762453LL));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 2));
+
+ PrimitiveProto primitives;
+ std::string serialized;
+ ASSERT_TRUE(proto.serializeToString(&serialized));
+ ASSERT_TRUE(primitives.ParseFromString(serialized));
+ EXPECT_EQ(primitives.val_int32(), 123);
+ EXPECT_EQ(primitives.val_int64(), -1);
+ EXPECT_EQ(primitives.val_float(), -23.5f);
+ EXPECT_EQ(primitives.val_double(), 324.5f);
+ EXPECT_EQ(primitives.val_uint32(), 3424);
+ EXPECT_EQ(primitives.val_uint64(), 57);
+ EXPECT_EQ(primitives.val_fixed32(), -20);
+ EXPECT_EQ(primitives.val_fixed64(), -37);
+ EXPECT_EQ(primitives.val_bool(), true);
+ EXPECT_THAT(primitives.val_string(), StrEq(s.c_str()));
+ EXPECT_THAT(primitives.val_bytes(), StrEq("apple"));
+ EXPECT_EQ(primitives.val_sfixed32(), 63);
+ EXPECT_EQ(primitives.val_sfixed64(), -54);
+ EXPECT_EQ(primitives.val_sint32(), -533);
+ EXPECT_EQ(primitives.val_sint64(), -61224762453LL);
+ EXPECT_EQ(primitives.val_enum(), PrimitiveProto_Count_TWO);
+}
+
TEST(ProtoOutputStreamTest, Complex) {
std::string name1 = "cat";
std::string name2 = "dog";
@@ -127,6 +171,47 @@
EXPECT_THAT(log2.data(), StrEq("food"));
}
+TEST(ProtoOutputStreamTest, SerializeToStringComplex) {
+ std::string name1 = "cat";
+ std::string name2 = "dog";
+ const char data1[6] = { 'f', 'u', 'n', 'n', 'y', '!' };
+ const char data2[4] = { 'f', 'o', 'o', 'd' };
+
+ ProtoOutputStream proto;
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 23));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 101));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, -72));
+ uint64_t token1 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 12));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name1));
+ // specify the length to test the write(id, bytes, length) function.
+ EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data1, 5));
+ proto.end(token1);
+ uint64_t token2 = proto.start(FIELD_TYPE_MESSAGE | ComplexProto::kLogsFieldNumber);
+ EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::Log::kIdFieldNumber, 98));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_STRING | ComplexProto::Log::kNameFieldNumber, name2));
+ EXPECT_TRUE(proto.write(FIELD_TYPE_BYTES | ComplexProto::Log::kDataFieldNumber, data2, 4));
+ proto.end(token2);
+
+ ComplexProto complex;
+ std::string serialized;
+ ASSERT_TRUE(proto.serializeToString(&serialized));
+ ASSERT_TRUE(complex.ParseFromString(serialized));
+ EXPECT_EQ(complex.ints_size(), 3);
+ EXPECT_EQ(complex.ints(0), 23);
+ EXPECT_EQ(complex.ints(1), 101);
+ EXPECT_EQ(complex.ints(2), -72);
+ EXPECT_EQ(complex.logs_size(), 2);
+ ComplexProto::Log log1 = complex.logs(0);
+ EXPECT_EQ(log1.id(), 12);
+ EXPECT_THAT(log1.name(), StrEq(name1.c_str()));
+ EXPECT_THAT(log1.data(), StrEq("funny")); // should not contain '!'
+ ComplexProto::Log log2 = complex.logs(1);
+ EXPECT_EQ(log2.id(), 98);
+ EXPECT_THAT(log2.name(), StrEq(name2.c_str()));
+ EXPECT_THAT(log2.data(), StrEq("food"));
+}
+
TEST(ProtoOutputStreamTest, Reusability) {
ProtoOutputStream proto;
EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 32));
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 68c0a22..435d8d7 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -509,35 +509,16 @@
* @return The position of the {@link Uri}, or -1 if it cannot be found.
*/
public int getRingtonePosition(Uri ringtoneUri) {
-
if (ringtoneUri == null) return -1;
+ final long ringtoneId = ContentUris.parseId(ringtoneUri);
final Cursor cursor = getCursor();
- final int cursorCount = cursor.getCount();
-
- if (!cursor.moveToFirst()) {
- return -1;
- }
-
- // Only create Uri objects when the actual URI changes
- Uri currentUri = null;
- String previousUriString = null;
- for (int i = 0; i < cursorCount; i++) {
- String uriString = cursor.getString(URI_COLUMN_INDEX);
- if (currentUri == null || !uriString.equals(previousUriString)) {
- currentUri = Uri.parse(uriString);
+ cursor.moveToPosition(-1);
+ while (cursor.moveToNext()) {
+ if (ringtoneId == cursor.getLong(ID_COLUMN_INDEX)) {
+ return cursor.getPosition();
}
-
- if (ringtoneUri.equals(ContentUris.withAppendedId(currentUri, cursor
- .getLong(ID_COLUMN_INDEX)))) {
- return i;
- }
-
- cursor.move(1);
-
- previousUriString = uriString;
}
-
return -1;
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index f5dab01..9b6ab06 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -314,6 +314,7 @@
public void showKeyguard() {
super.showKeyguard();
updateNavBarForKeyguardContent();
+ dismissKeyguardWhenUserSwitcherNotDisplayed();
}
/**
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 43d7d8f..e731b45 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -70,6 +70,10 @@
private static final String TAG = "DynSystemInstallationService";
+
+ // TODO (b/131866826): This is currently for test only. Will move this to System API.
+ static final String KEY_ENABLE_WHEN_COMPLETED = "KEY_ENABLE_WHEN_COMPLETED";
+
/*
* Intent actions
*/
@@ -122,6 +126,9 @@
private long mInstalledSize;
private boolean mJustCancelledByUser;
+ // This is for testing only now
+ private boolean mEnableWhenCompleted;
+
private InstallationAsyncTask mInstallTask;
@@ -178,6 +185,11 @@
public void onResult(int result, Throwable detail) {
if (result == RESULT_OK) {
postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED, null);
+
+ // For testing: enable DSU and restart the device when install completed
+ if (mEnableWhenCompleted) {
+ executeRebootToDynSystemCommand();
+ }
return;
}
@@ -224,6 +236,7 @@
String url = intent.getDataString();
mSystemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0);
mUserdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0);
+ mEnableWhenCompleted = intent.getBooleanExtra(KEY_ENABLE_WHEN_COMPLETED, false);
mInstallTask = new InstallationAsyncTask(
url, mSystemSize, mUserdataSize, this, mDynSystem, this);
@@ -275,7 +288,7 @@
private void executeRebootToDynSystemCommand() {
boolean enabled = false;
- if (mInstallTask != null && mInstallTask.getStatus() == FINISHED) {
+ if (mInstallTask != null && mInstallTask.getResult() == RESULT_OK) {
enabled = mInstallTask.commit();
} else if (isDynamicSystemInstalled()) {
enabled = mDynSystem.setEnable(true);
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java
index b1c09381..8a2948b 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/VerificationActivity.java
@@ -92,6 +92,8 @@
Uri url = callingIntent.getData();
long systemSize = callingIntent.getLongExtra(KEY_SYSTEM_SIZE, 0);
long userdataSize = callingIntent.getLongExtra(KEY_USERDATA_SIZE, 0);
+ boolean enableWhenCompleted = callingIntent.getBooleanExtra(
+ DynamicSystemInstallationService.KEY_ENABLE_WHEN_COMPLETED, false);
sVerifiedUrl = url.toString();
@@ -101,6 +103,8 @@
intent.setAction(DynamicSystemClient.ACTION_START_INSTALL);
intent.putExtra(KEY_SYSTEM_SIZE, systemSize);
intent.putExtra(KEY_USERDATA_SIZE, userdataSize);
+ intent.putExtra(
+ DynamicSystemInstallationService.KEY_ENABLE_WHEN_COMPLETED, enableWhenCompleted);
Log.d(TAG, "Starting Installation Service");
startServiceAsUser(intent, UserHandle.SYSTEM);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 1d351a5..9a95288 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -826,11 +826,22 @@
}
/**
- * @return resource for string that discribes the connection state of this device.
- * case 1: idle or playing media, show "Active" on the only one A2DP active device.
- * case 2: in phone call, show "Active" on the only one HFP active device
+ * Return full summary that describes connection state of this device
+ *
+ * @see #getConnectionSummary(boolean shortSummary)
*/
public String getConnectionSummary() {
+ return getConnectionSummary(false /* shortSummary */);
+ }
+
+ /**
+ * Return summary that describes connection state of this device. Summary depends on:
+ * 1. Whether device has battery info
+ * 2. Whether device is in active usage(or in phone call)
+ *
+ * @param shortSummary {@code true} if need to return short version summary
+ */
+ public String getConnectionSummary(boolean shortSummary) {
boolean profileConnected = false; // Updated as long as BluetoothProfile is connected
boolean a2dpConnected = true; // A2DP is connected
boolean hfpConnected = true; // HFP is connected
@@ -909,9 +920,9 @@
if ((mIsActiveDeviceHearingAid)
|| (mIsActiveDeviceHeadset && isOnCall)
|| (mIsActiveDeviceA2dp && !isOnCall)) {
- if (isTwsBatteryAvailable(leftBattery, rightBattery)) {
+ if (isTwsBatteryAvailable(leftBattery, rightBattery) && !shortSummary) {
stringRes = R.string.bluetooth_active_battery_level_untethered;
- } else if (batteryLevelPercentageString != null) {
+ } else if (batteryLevelPercentageString != null && !shortSummary) {
stringRes = R.string.bluetooth_active_battery_level;
} else {
stringRes = R.string.bluetooth_active_no_battery_level;
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
index ec8bb80..4941f7e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -117,7 +117,8 @@
if (info == null || !info.enabled
|| (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier(),
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_UNKNOWN, null);
if (DEBUG) {
Log.d(TAG, "Installing " + packageName);
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
index e840a4b..b216a2a 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
@@ -16,15 +16,14 @@
package com.android.settingslib.users;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.nullable;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.appwidget.AppWidgetManager;
import android.content.Context;
@@ -43,6 +42,7 @@
import android.os.UserManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.inputmethod.InputMethodInfo;
+
import com.android.settingslib.BaseTest;
import org.mockito.ArgumentMatcher;
@@ -146,7 +146,8 @@
mHelper.applyUserAppsStates(mockListener);
verify(mIpm, times(1)).installExistingPackageAsUser("app1", testUserId,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_UNKNOWN, null);
verify(mIpm, times(1)).setApplicationHiddenSettingAsUser("app2", false, testUserId);
verify(mockListener).onDisableUiForPackage("app2");
verify(mPm, times(1)).deletePackageAsUser(eq("app3"),
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index c0a1f11..93dcbfe 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -192,6 +192,27 @@
}
@Test
+ public void getConnectionSummary_shortSummary_returnShortSummary() {
+ // Test without battery level
+ // Set A2DP profile to be connected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
+ assertThat(mCachedDevice.getConnectionSummary(true /* shortSummary */)).isNull();
+
+ // Set device as Active for A2DP and test connection state summary
+ mCachedDevice.onActiveDeviceChanged(true, BluetoothProfile.A2DP);
+ assertThat(mCachedDevice.getConnectionSummary(true /* shortSummary */)).isEqualTo("Active");
+
+ // Test with battery level
+ mBatteryLevel = 10;
+ assertThat(mCachedDevice.getConnectionSummary(true /* shortSummary */)).isEqualTo(
+ "Active");
+
+ // Set A2DP profile to be disconnected and test connection state summary
+ updateProfileStatus(mA2dpProfile, BluetoothProfile.STATE_DISCONNECTED);
+ assertThat(mCachedDevice.getConnectionSummary()).isNull();
+ }
+
+ @Test
public void getConnectionSummary_testA2dpBatteryInactive_returnBattery() {
// Arrange:
// 1. Profile: {A2DP, CONNECTED, Inactive}
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml
index 86b103d..4619430 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml
@@ -6,16 +6,15 @@
android:layout_height="match_parent"
android:orientation="horizontal"
android:theme="@style/qs_theme"
- android:gravity="right"
+ android:gravity="right | center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingRight="@dimen/global_actions_grid_container_shadow_offset"
android:layout_marginRight="@dimen/global_actions_grid_container_negative_shadow_offset"
>
<LinearLayout
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:gravity="top|right"
android:orientation="vertical"
android:layout_marginRight="@dimen/global_actions_grid_container_bottom_margin"
android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
index 4c3fcc0..4ece03b 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
@@ -6,16 +6,15 @@
android:layout_height="match_parent"
android:orientation="horizontal"
android:theme="@style/qs_theme"
- android:gravity="left"
+ android:gravity="left | center_vertical"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingLeft="@dimen/global_actions_grid_container_shadow_offset"
android:layout_marginLeft="@dimen/global_actions_grid_container_negative_shadow_offset"
>
<LinearLayout
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:gravity="bottom|left"
android:padding="0dp"
android:orientation="vertical"
android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml
index 43e6b49..3928062 100644
--- a/packages/SystemUI/res/layout/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid.xml
@@ -6,7 +6,7 @@
android:layout_height="match_parent"
android:orientation="horizontal"
android:theme="@style/qs_theme"
- android:gravity="bottom"
+ android:gravity="bottom | center_horizontal"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
@@ -14,8 +14,7 @@
>
<LinearLayout
android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:gravity="bottom | right"
+ android:layout_width="wrap_content"
android:layoutDirection="ltr"
android:clipChildren="false"
android:clipToPadding="false"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 6dbc385..e00e5f2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -41,10 +41,10 @@
<!-- Size of the nav bar edge panels, should be greater to the
edge sensitivity + the drag threshold -->
- <dimen name="navigation_edge_panel_width">76dp</dimen>
+ <dimen name="navigation_edge_panel_width">70dp</dimen>
<!-- Padding at the end of the navigation panel to allow the arrow not to be clipped off -->
- <dimen name="navigation_edge_panel_padding">24dp</dimen>
- <dimen name="navigation_edge_panel_height">84dp</dimen>
+ <dimen name="navigation_edge_panel_padding">8dp</dimen>
+ <dimen name="navigation_edge_panel_height">96dp</dimen>
<!-- The threshold to drag to trigger the edge action -->
<dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
<!-- The minimum display position of the arrow on the screen -->
@@ -89,7 +89,7 @@
<dimen name="status_bar_wifi_signal_spacer_width">2.5dp</dimen>
<!-- Size of the view displaying the wifi signal icon in the status bar. -->
- <dimen name="status_bar_wifi_signal_size">15dp</dimen>
+ <dimen name="status_bar_wifi_signal_size">@*android:dimen/status_bar_system_icon_size</dimen>
<!-- Spacing before the airplane mode icon if there are any icons preceding it. -->
<dimen name="status_bar_airplane_spacer_width">4dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 55499da..0e91e41 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -68,6 +68,9 @@
private final AppearAnimationUtils mAppearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtils;
private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
+ private final int[] mTmpPosition = new int[2];
+ private final Rect mTempRect = new Rect();
+ private final Rect mLockPatternScreenBounds = new Rect();
private CountDownTimer mCountdownTimer = null;
private LockPatternUtils mLockPatternUtils;
@@ -92,7 +95,6 @@
mLockPatternView.clearPattern();
}
};
- private Rect mTempRect = new Rect();
@VisibleForTesting
KeyguardMessageArea mSecurityMessageDisplay;
private View mEcaView;
@@ -199,6 +201,15 @@
}
@Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed, l, t, r, b);
+ mLockPatternView.getLocationOnScreen(mTmpPosition);
+ mLockPatternScreenBounds.set(mTmpPosition[0], mTmpPosition[1],
+ mTmpPosition[0] + mLockPatternView.getWidth(),
+ mTmpPosition[1] + mLockPatternView.getHeight());
+ }
+
+ @Override
public void reset() {
// reset lock pattern
mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
@@ -233,9 +244,7 @@
@Override
public boolean disallowInterceptTouch(MotionEvent event) {
- mTempRect.set(mLockPatternView.getLeft(), mLockPatternView.getTop(),
- mLockPatternView.getRight(), mLockPatternView.getBottom());
- return mTempRect.contains((int) event.getX(), (int) event.getY());
+ return mLockPatternScreenBounds.contains((int) event.getRawX(), (int) event.getRawY());
}
/** TODO: hook this up */
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index 45c19ad..e66a8fa 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -31,7 +31,9 @@
import android.view.WindowManager;
import com.android.internal.os.SomeArgs;
+import com.android.systemui.Dependency;
import com.android.systemui.SystemUI;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.CommandQueue;
/**
@@ -58,6 +60,7 @@
private IBiometricServiceReceiverInternal mReceiver;
private boolean mDialogShowing;
private Callback mCallback = new Callback();
+ private WakefulnessLifecycle mWakefulnessLifecycle;
private Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
@@ -133,6 +136,16 @@
}
}
+ final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+ @Override
+ public void onStartedGoingToSleep() {
+ if (mDialogShowing) {
+ if (DEBUG) Log.d(TAG, "User canceled due to screen off");
+ mHandler.obtainMessage(MSG_USER_CANCELED).sendToTarget();
+ }
+ }
+ };
+
@Override
public void start() {
final PackageManager pm = mContext.getPackageManager();
@@ -141,6 +154,8 @@
|| pm.hasSystemFeature(PackageManager.FEATURE_IRIS)) {
getComponent(CommandQueue.class).addCallback(this);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+ mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
+ mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index 8aad0f8..f60e95e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -18,6 +18,9 @@
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.view.LayoutInflater;
@@ -37,6 +40,7 @@
private final String mKey;
private final String mGroupId;
+ private String mAppName;
private final BubbleExpandedView.OnBubbleBlockedListener mListener;
private boolean mInflated;
@@ -45,6 +49,7 @@
BubbleExpandedView expandedView;
private long mLastUpdated;
private long mLastAccessed;
+ private PackageManager mPm;
public static String groupId(NotificationEntry entry) {
UserHandle user = entry.notification.getUser();
@@ -53,16 +58,33 @@
/** Used in tests when no UI is required. */
@VisibleForTesting(visibility = PRIVATE)
- Bubble(NotificationEntry e) {
- this (e, null);
+ Bubble(Context context, NotificationEntry e) {
+ this (context, e, null);
}
- Bubble(NotificationEntry e, BubbleExpandedView.OnBubbleBlockedListener listener) {
+ Bubble(Context context, NotificationEntry e,
+ BubbleExpandedView.OnBubbleBlockedListener listener) {
entry = e;
mKey = e.key;
mLastUpdated = e.notification.getPostTime();
mGroupId = groupId(e);
mListener = listener;
+
+ mPm = context.getPackageManager();
+ ApplicationInfo info;
+ try {
+ info = mPm.getApplicationInfo(
+ entry.notification.getPackageName(),
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE);
+ if (info != null) {
+ mAppName = String.valueOf(mPm.getApplicationLabel(info));
+ }
+ } catch (PackageManager.NameNotFoundException unused) {
+ mAppName = entry.notification.getPackageName();
+ }
}
public String getKey() {
@@ -77,6 +99,10 @@
return entry.notification.getPackageName();
}
+ public String getAppName() {
+ return mAppName;
+ }
+
boolean isInflated() {
return mInflated;
}
@@ -97,9 +123,9 @@
expandedView = (BubbleExpandedView) inflater.inflate(
R.layout.bubble_expanded_view, stackView, false /* attachToRoot */);
- expandedView.setEntry(entry, stackView);
-
+ expandedView.setEntry(entry, stackView, mAppName);
expandedView.setOnBlockedListener(mListener);
+
mInflated = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 48edf67..dcc0419 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -40,6 +40,7 @@
import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.app.Notification;
+import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
@@ -193,7 +194,7 @@
if (shouldCollapse) {
collapseStack();
}
- updateVisibility();
+ updateStack();
}
}
@@ -381,6 +382,10 @@
* @param notif the notification associated with this bubble.
*/
void updateBubble(NotificationEntry notif) {
+ // If this is an interruptive notif, mark that it's interrupted
+ if (notif.importance >= NotificationManager.IMPORTANCE_HIGH) {
+ notif.setInterruption();
+ }
mBubbleData.notificationEntryUpdated(notif);
}
@@ -534,10 +539,11 @@
}
}
+ // Runs on state change.
@Override
public void apply() {
mNotificationEntryManager.updateNotifications();
- updateVisibility();
+ updateStack();
if (DEBUG) {
Log.d(TAG, "[BubbleData]");
@@ -554,34 +560,31 @@
};
/**
- * Lets any listeners know if bubble state has changed.
+ * Updates the visibility of the bubbles based on current state.
+ * Does not un-bubble, just hides or un-hides. Notifies any
+ * {@link BubbleStateChangeListener}s of visibility changes.
+ * Updates stack description for TalkBack focus.
*/
- private void updateBubblesShowing() {
+ public void updateStack() {
if (mStackView == null) {
return;
}
-
- boolean hadBubbles = mStatusBarWindowController.getBubblesShowing();
- boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE;
- mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
- if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) {
- mStateChangeListener.onHasBubblesChanged(hasBubblesShowing);
- }
- }
-
- /**
- * Updates the visibility of the bubbles based on current state.
- * Does not un-bubble, just hides or un-hides. Will notify any
- * {@link BubbleStateChangeListener}s if visibility changes.
- */
- public void updateVisibility() {
if (mStatusBarStateListener.getCurrentState() == SHADE && hasBubbles()) {
// Bubbles only appear in unlocked shade
mStackView.setVisibility(hasBubbles() ? VISIBLE : INVISIBLE);
} else if (mStackView != null) {
mStackView.setVisibility(INVISIBLE);
}
- updateBubblesShowing();
+
+ // Let listeners know if bubble state changed.
+ boolean hadBubbles = mStatusBarWindowController.getBubblesShowing();
+ boolean hasBubblesShowing = hasBubbles() && mStackView.getVisibility() == VISIBLE;
+ mStatusBarWindowController.setBubblesShowing(hasBubblesShowing);
+ if (mStateChangeListener != null && hadBubbles != hasBubblesShowing) {
+ mStateChangeListener.onHasBubblesChanged(hasBubblesShowing);
+ }
+
+ mStackView.updateContentDescription();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 9156e06..1858244 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -178,7 +178,7 @@
Bubble bubble = getBubbleWithKey(entry.key);
if (bubble == null) {
// Create a new bubble
- bubble = new Bubble(entry, this::onBubbleBlocked);
+ bubble = new Bubble(mContext, entry, this::onBubbleBlocked);
doAdd(bubble);
trim();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 39867c3..fa137a1 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -244,9 +244,10 @@
/**
* Sets the notification entry used to populate this view.
*/
- public void setEntry(NotificationEntry entry, BubbleStackView stackView) {
+ public void setEntry(NotificationEntry entry, BubbleStackView stackView, String appName) {
mStackView = stackView;
mEntry = entry;
+ mAppName = appName;
ApplicationInfo info;
try {
@@ -257,12 +258,10 @@
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_DIRECT_BOOT_AWARE);
if (info != null) {
- mAppName = String.valueOf(mPm.getApplicationLabel(info));
mAppIcon = mPm.getApplicationIcon(info);
}
} catch (PackageManager.NameNotFoundException e) {
- // Ahh... just use package name
- mAppName = entry.notification.getPackageName();
+ // Do nothing.
}
if (mAppIcon == null) {
mAppIcon = mPm.getDefaultActivityIcon();
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 4fef157..4ad3a33 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -23,6 +23,7 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.NonNull;
+import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.ColorMatrix;
@@ -553,6 +554,43 @@
return false;
}
+ /**
+ * Update content description for a11y TalkBack.
+ */
+ public void updateContentDescription() {
+ if (mBubbleData.getBubbles().isEmpty()) {
+ return;
+ }
+ Bubble topBubble = mBubbleData.getBubbles().get(0);
+ String appName = topBubble.getAppName();
+ Notification notification = topBubble.entry.notification.getNotification();
+ CharSequence titleCharSeq = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
+ String titleStr = getResources().getString(R.string.stream_notification);
+ if (titleCharSeq != null) {
+ titleStr = titleCharSeq.toString();
+ }
+ int moreCount = mBubbleContainer.getChildCount() - 1;
+
+ // Example: Title from app name.
+ String singleDescription = getResources().getString(
+ R.string.bubble_content_description_single, titleStr, appName);
+
+ // Example: Title from app name and 4 more.
+ String stackDescription = getResources().getString(
+ R.string.bubble_content_description_stack, titleStr, appName, moreCount);
+
+ if (mIsExpanded) {
+ // TODO(b/129522932) - update content description for each bubble in expanded view.
+ } else {
+ // Collapsed stack.
+ if (moreCount > 0) {
+ mBubbleContainer.setContentDescription(stackDescription);
+ } else {
+ mBubbleContainer.setContentDescription(singleDescription);
+ }
+ }
+ }
+
private void updateSystemGestureExcludeRects() {
// Exclude the region occupied by the first BubbleView in the stack
Rect excludeZone = mSystemGestureExclusionRects.get(0);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 4590470..35b8d203 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -30,6 +30,7 @@
import android.icu.text.DateFormat;
import android.icu.text.DisplayContext;
import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Handler;
import android.os.Trace;
@@ -57,6 +58,7 @@
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
import java.util.Date;
+import java.util.HashSet;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
@@ -98,6 +100,7 @@
private final Date mCurrentTime = new Date();
private final Handler mHandler;
private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
+ private final HashSet<Integer> mMediaInvisibleStates;
private ZenModeController mZenModeController;
private String mDatePattern;
private DateFormat mDateFormat;
@@ -113,6 +116,7 @@
private StatusBarStateController mStatusBarStateController;
protected MediaMetadata mMediaMetaData;
protected boolean mDozing;
+ private boolean mMediaIsVisible;
/**
* Receiver responsible for time ticking and updating the date format.
@@ -169,6 +173,11 @@
mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI);
mDndUri = Uri.parse(KEYGUARD_DND_URI);
mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
+
+ mMediaInvisibleStates = new HashSet<>();
+ mMediaInvisibleStates.add(PlaybackState.STATE_NONE);
+ mMediaInvisibleStates.add(PlaybackState.STATE_STOPPED);
+ mMediaInvisibleStates.add(PlaybackState.STATE_PAUSED);
}
/**
@@ -209,31 +218,33 @@
}
protected boolean needsMediaLocked() {
- return mMediaMetaData != null && mDozing;
+ return mMediaMetaData != null && mMediaIsVisible && mDozing;
}
protected void addMediaLocked(ListBuilder listBuilder) {
- if (mMediaMetaData != null) {
- CharSequence title = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_TITLE);
- if (TextUtils.isEmpty(title)) {
- title = getContext().getResources().getString(R.string.music_controls_no_title);
+ if (mMediaMetaData == null) {
+ return;
+ }
+
+ CharSequence title = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_TITLE);
+ if (TextUtils.isEmpty(title)) {
+ title = getContext().getResources().getString(R.string.music_controls_no_title);
+ }
+ listBuilder.setHeader(new ListBuilder.HeaderBuilder(mHeaderUri).setTitle(title));
+
+ CharSequence album = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_ARTIST);
+ if (!TextUtils.isEmpty(album)) {
+ RowBuilder albumBuilder = new RowBuilder(mMediaUri);
+ albumBuilder.setTitle(album);
+
+ Icon mediaIcon = mMediaManager == null ? null : mMediaManager.getMediaIcon();
+ IconCompat mediaIconCompat = mediaIcon == null ? null
+ : IconCompat.createFromIcon(getContext(), mediaIcon);
+ if (mediaIconCompat != null) {
+ albumBuilder.addEndItem(mediaIconCompat, ListBuilder.ICON_IMAGE);
}
- listBuilder.setHeader(new ListBuilder.HeaderBuilder(mHeaderUri).setTitle(title));
- CharSequence album = mMediaMetaData.getText(MediaMetadata.METADATA_KEY_ARTIST);
- if (!TextUtils.isEmpty(album)) {
- RowBuilder albumBuilder = new RowBuilder(mMediaUri);
- albumBuilder.setTitle(album);
-
- Icon mediaIcon = mMediaManager == null ? null : mMediaManager.getMediaIcon();
- IconCompat mediaIconCompat = mediaIcon == null ? null
- : IconCompat.createFromIcon(getContext(), mediaIcon);
- if (mediaIconCompat != null) {
- albumBuilder.addEndItem(mediaIconCompat, ListBuilder.ICON_IMAGE);
- }
-
- listBuilder.addRow(albumBuilder);
- }
+ listBuilder.addRow(albumBuilder);
}
}
@@ -411,9 +422,14 @@
* @param metadata New metadata.
*/
@Override
- public void onMetadataChanged(MediaMetadata metadata) {
+ public void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state) {
synchronized (this) {
+ boolean nextVisible = !mMediaInvisibleStates.contains(state);
+ if (nextVisible == mMediaIsVisible && metadata == mMediaMetaData) {
+ return;
+ }
mMediaMetaData = metadata;
+ mMediaIsVisible = nextVisible;
}
notifyChange();
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
index af2b767..a9fe54b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivity.java
@@ -21,7 +21,6 @@
import android.annotation.ColorInt;
import android.annotation.UserIdInt;
import android.app.Activity;
-import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.PendingIntent;
@@ -32,9 +31,7 @@
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.UserHandle;
-import android.util.Log;
import android.view.View;
import com.android.internal.annotations.VisibleForTesting;
@@ -56,7 +53,9 @@
*/
static final String EXTRA_TASK_DESCRIPTION =
"com.android.systemui.keyguard.extra.TASK_DESCRIPTION";
-
+
+ private static final int REQUEST_CODE_CONFIRM_CREDENTIALS = 1;
+
/**
* Cached keyguard manager instance populated by {@link #getKeyguardManager}.
* @see KeyguardManager
@@ -111,7 +110,6 @@
@Override
public void onBackPressed() {
// Ignore back presses.
- return;
}
@Override
@@ -151,26 +149,26 @@
PendingIntent.FLAG_ONE_SHOT |
PendingIntent.FLAG_IMMUTABLE, options.toBundle());
- credential.putExtra(Intent.EXTRA_INTENT, target.getIntentSender());
- try {
- ActivityManager.getService().startConfirmDeviceCredentialIntent(credential,
- getChallengeOptions().toBundle());
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to start confirm credential intent", e);
+ if (target != null) {
+ credential.putExtra(Intent.EXTRA_INTENT, target.getIntentSender());
+ }
+
+ startActivityForResult(credential, REQUEST_CODE_CONFIRM_CREDENTIALS);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE_CONFIRM_CREDENTIALS && resultCode != RESULT_OK) {
+ // The user dismissed the challenge, don't show it again.
+ goToHomeScreen();
}
}
- private ActivityOptions getChallengeOptions() {
- // If we are taking up the whole screen, just use the default animation of clipping the
- // credentials activity into the entire foreground.
- if (!isInMultiWindowMode()) {
- return ActivityOptions.makeBasic();
- }
-
- // Otherwise, animate the transition from this part of the screen to fullscreen
- // using our own decor as the starting position.
- final View view = getWindow().getDecorView();
- return ActivityOptions.makeScaleUpAnimation(view, 0, 0, view.getWidth(), view.getHeight());
+ private void goToHomeScreen() {
+ final Intent homeIntent = new Intent(Intent.ACTION_MAIN);
+ homeIntent.addCategory(Intent.CATEGORY_HOME);
+ homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(homeIntent);
}
private KeyguardManager getKeyguardManager() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index b9e0c60..75ef185 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -150,8 +150,8 @@
if (state != null) {
if (!isPlaybackActive(state.getState())) {
clearCurrentMediaNotification();
- dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */);
}
+ dispatchUpdateMediaMetaData(true /* changed */, true /* allowAnimation */);
}
}
@@ -242,7 +242,8 @@
public void addCallback(MediaListener callback) {
mMediaListeners.add(callback);
- callback.onMetadataChanged(mMediaMetadata);
+ callback.onMetadataOrStateChanged(mMediaMetadata,
+ getMediaControllerPlaybackState(mMediaController));
}
public void removeCallback(MediaListener callback) {
@@ -357,9 +358,10 @@
if (mPresenter != null) {
mPresenter.updateMediaMetaData(changed, allowEnterAnimation);
}
+ @PlaybackState.State int state = getMediaControllerPlaybackState(mMediaController);
ArrayList<MediaListener> callbacks = new ArrayList<>(mMediaListeners);
for (int i = 0; i < callbacks.size(); i++) {
- callbacks.get(i).onMetadataChanged(mMediaMetadata);
+ callbacks.get(i).onMetadataOrStateChanged(mMediaMetadata, state);
}
}
@@ -698,6 +700,12 @@
}
public interface MediaListener {
- void onMetadataChanged(MediaMetadata metadata);
+ /**
+ * Called whenever there's new metadata or playback state.
+ * @param metadata Current metadata.
+ * @param state Current playback state
+ * @see PlaybackState.State
+ */
+ void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 033c4fb..6552fe6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -40,7 +40,6 @@
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.util.FloatProperty;
import android.util.Log;
import android.util.Property;
@@ -72,12 +71,12 @@
/**
* Status icons are currently drawn with the intention of being 17dp tall, but we
* want to scale them (in a way that doesn't require an asset dump) down 2dp. So
- * 17dp * (15 / 17) = 15dp, the new height.
+ * 17dp * (15 / 17) = 15dp, the new height. After the first call to {@link #reloadDimens} all
+ * values will be in px.
*/
- private static final float SYSTEM_ICON_DESIRED_HEIGHT = 15f;
- private static final float SYSTEM_ICON_INTRINSIC_HEIGHT = 17f;
- private static final float SYSTEM_ICON_SCALE =
- SYSTEM_ICON_DESIRED_HEIGHT / SYSTEM_ICON_INTRINSIC_HEIGHT;
+ private float mSystemIconDesiredHeight = 15f;
+ private float mSystemIconIntrinsicHeight = 17f;
+ private float mSystemIconDefaultScale = mSystemIconDesiredHeight / mSystemIconIntrinsicHeight;
private final int ANIMATION_DURATION_FAST = 100;
public static final int STATE_ICON = 0;
@@ -209,21 +208,20 @@
// Makes sure that all icons are scaled to the same height (15dp). If we cannot get a height
// for the icon, it uses the default SCALE (15f / 17f) which is the old behavior
private void updateIconScaleForSystemIcons() {
- float iconHeight = getIconHeightInDps();
+ float iconHeight = getIconHeight();
if (iconHeight != 0) {
- mIconScale = SYSTEM_ICON_DESIRED_HEIGHT / iconHeight;
+ mIconScale = mSystemIconDesiredHeight / iconHeight;
} else {
- mIconScale = SYSTEM_ICON_SCALE;
+ mIconScale = mSystemIconDefaultScale;
}
}
- private float getIconHeightInDps() {
+ private float getIconHeight() {
Drawable d = getDrawable();
if (d != null) {
- return ((float) getDrawable().getIntrinsicHeight() * DisplayMetrics.DENSITY_DEFAULT)
- / mDensity;
+ return (float) getDrawable().getIntrinsicHeight();
} else {
- return SYSTEM_ICON_INTRINSIC_HEIGHT;
+ return mSystemIconIntrinsicHeight;
}
}
@@ -265,6 +263,11 @@
if (applyRadius) {
mDotRadius = mStaticDotRadius;
}
+ mSystemIconDesiredHeight = res.getDimension(
+ com.android.internal.R.dimen.status_bar_system_icon_size);
+ mSystemIconIntrinsicHeight = res.getDimension(
+ com.android.internal.R.dimen.status_bar_system_icon_intrinsic_size);
+ mSystemIconDefaultScale = mSystemIconDesiredHeight / mSystemIconIntrinsicHeight;
}
public void setNotification(StatusBarNotification notification) {
@@ -272,6 +275,7 @@
if (notification != null) {
setContentDescription(notification.getNotification());
}
+ maybeUpdateIconScaleDimens();
}
public StatusBarIconView(Context context, AttributeSet attrs) {
@@ -280,7 +284,7 @@
mBlocked = false;
mAlwaysScaleIcon = true;
reloadDimens();
- updateIconScaleForNotifications();
+ maybeUpdateIconScaleDimens();
mDensity = context.getResources().getDisplayMetrics().densityDpi;
}
@@ -854,7 +858,7 @@
public void setDark(boolean dark, boolean fade, long delay) {
mDozer.setIntensityDark(f -> {
mDarkAmount = f;
- updateIconScaleForNotifications();
+ maybeUpdateIconScaleDimens();
updateDecorColor();
updateIconColor();
updateAllowAnimation();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index f93c5f0..a3e3426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -46,6 +46,7 @@
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
import javax.inject.Inject;
@@ -71,6 +72,7 @@
private final AccessibilityController mAccessibilityController;
private final DockManager mDockManager;
private final Handler mMainHandler;
+ private final KeyguardMonitor mKeyguardMonitor;
private int mLastState = 0;
private boolean mTransientBiometricsError;
@@ -91,7 +93,16 @@
private int mIconRes;
private boolean mWasPulsingOnThisFrame;
private boolean mWakeAndUnlockRunning;
+ private boolean mKeyguardShowing;
+ private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
+ new KeyguardMonitor.Callback() {
+ @Override
+ public void onKeyguardShowingChanged() {
+ mKeyguardShowing = mKeyguardMonitor.isShowing();
+ update(false /* force */);
+ }
+ };
private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
private final DockManager.DockEventListener mDockEventListener =
new DockManager.DockEventListener() {
@@ -150,6 +161,7 @@
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
AccessibilityController accessibilityController,
+ KeyguardMonitor keyguardMonitor,
@Nullable DockManager dockManager,
@Named(MAIN_HANDLER_NAME) Handler mainHandler) {
super(context, attrs);
@@ -159,6 +171,7 @@
mAccessibilityController = accessibilityController;
mConfigurationController = configurationController;
mStatusBarStateController = statusBarStateController;
+ mKeyguardMonitor = keyguardMonitor;
mDockManager = dockManager;
mMainHandler = mainHandler;
}
@@ -168,6 +181,7 @@
super.onAttachedToWindow();
mStatusBarStateController.addCallback(this);
mConfigurationController.addCallback(this);
+ mKeyguardMonitor.addCallback(mKeyguardMonitorCallback);
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
mUnlockMethodCache.addListener(this);
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
@@ -183,6 +197,7 @@
mStatusBarStateController.removeCallback(this);
mConfigurationController.removeCallback(this);
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
+ mKeyguardMonitor.removeCallback(mKeyguardMonitorCallback);
mUnlockMethodCache.removeListener(this);
if (mDockManager != null) {
mDockManager.removeListener(mDockEventListener);
@@ -379,7 +394,7 @@
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
if (mTransientBiometricsError) {
return STATE_BIOMETRICS_ERROR;
- } else if (mUnlockMethodCache.canSkipBouncer() && !mSimLocked) {
+ } else if ((mUnlockMethodCache.canSkipBouncer() || !mKeyguardShowing) && !mSimLocked) {
return STATE_LOCK_OPEN;
} else if (updateMonitor.isFaceDetectionRunning()) {
return STATE_SCANNING_FACE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
index 4603ba6..4f223c3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -25,6 +25,7 @@
import android.graphics.Rect;
import android.os.SystemClock;
import android.os.VibrationEffect;
+import android.util.DisplayMetrics;
import android.util.MathUtils;
import android.view.ContextThemeWrapper;
import android.view.MotionEvent;
@@ -47,14 +48,14 @@
public class NavigationBarEdgePanel extends View {
- private static final long COLOR_ANIMATION_DURATION_MS = 100;
- private static final long DISAPPEAR_FADE_ANIMATION_DURATION_MS = 140;
+ private static final long COLOR_ANIMATION_DURATION_MS = 120;
+ private static final long DISAPPEAR_FADE_ANIMATION_DURATION_MS = 80;
private static final long DISAPPEAR_ARROW_ANIMATION_DURATION_MS = 100;
/**
- * The minimum time required since the first vibration effect to receive a second one
+ * The time required since the first vibration effect to automatically trigger a click
*/
- private static final int MIN_TIME_BETWEEN_EFFECTS_MS = 120;
+ private static final int GESTURE_DURATION_FOR_CLICK_MS = 400;
/**
* The size of the protection of the arrow in px. Only used if this is not background protected
@@ -79,7 +80,7 @@
/**
* The angle that is added per 1000 px speed to the angle of the leg
*/
- private static final int ARROW_ANGLE_ADDED_PER_1000_SPEED = 8;
+ private static final int ARROW_ANGLE_ADDED_PER_1000_SPEED = 4;
/**
* The maximum angle offset allowed due to speed
@@ -92,15 +93,15 @@
private static final float ARROW_THICKNESS_DP = 2.5f;
/**
- * The amount of rubber banding we do for the horizontal translation beyond the base translation
+ * The amount of rubber banding we do for the vertical translation
*/
- private static final int RUBBER_BAND_AMOUNT = 10;
+ private static final int RUBBER_BAND_AMOUNT = 15;
/**
* The interpolator used to rubberband
*/
private static final Interpolator RUBBER_BAND_INTERPOLATOR
- = new PathInterpolator(1.0f / RUBBER_BAND_AMOUNT, 1.0f, 1.0f, 1.0f);
+ = new PathInterpolator(1.0f / 5.0f, 1.0f, 1.0f, 1.0f);
/**
* The amount of rubber banding we do for the translation before base translation
@@ -189,6 +190,7 @@
private int mCurrentArrowColor;
private float mDisappearAmount;
private long mVibrationTime;
+ private int mScreenSize;
private DynamicAnimation.OnAnimationEndListener mSetGoneEndListener
= new DynamicAnimation.OnAnimationEndListener() {
@@ -281,9 +283,8 @@
mAngleAnimation =
new SpringAnimation(this, CURRENT_ANGLE);
mAngleAppearForce = new SpringForce()
- .setStiffness(SpringForce.STIFFNESS_LOW)
- .setDampingRatio(0.4f)
- .setFinalPosition(ARROW_ANGLE_WHEN_EXTENDED_DEGREES);
+ .setStiffness(500)
+ .setDampingRatio(0.5f);
mAngleDisappearForce = new SpringForce()
.setStiffness(SpringForce.STIFFNESS_MEDIUM)
.setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY)
@@ -447,13 +448,14 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- // TODO: read the gesture length from the nav controller.
mMaxTranslation = getWidth() - mArrowPaddingEnd;
}
private void loadDimens() {
mArrowPaddingEnd = getContext().getResources().getDimensionPixelSize(
R.dimen.navigation_edge_panel_padding);
+ DisplayMetrics metrics = getResources().getDisplayMetrics();
+ mScreenSize = Math.min(metrics.widthPixels, metrics.heightPixels);
}
private void updateArrowDirection() {
@@ -510,7 +512,7 @@
if (!mArrowsPointLeft) {
x = -x;
}
- float extent = 1.0f - mDisappearAmount;
+ float extent = MathUtils.lerp(1.0f, 0.75f, mDisappearAmount);
x = x * extent;
y = y * extent;
mArrowPath.reset();
@@ -529,27 +531,29 @@
}
private void triggerBack() {
- if (SystemClock.uptimeMillis() - mVibrationTime >= MIN_TIME_BETWEEN_EFFECTS_MS) {
- mVibratorHelper.vibrate(VibrationEffect.EFFECT_CLICK);
- }
mVelocityTracker.computeCurrentVelocity(1000);
// Only do the extra translation if we're not already flinging
- boolean doExtraTranslation = Math.abs(mVelocityTracker.getXVelocity()) < 1000;
- if (doExtraTranslation) {
- setDesiredTranslation(mDesiredTranslation + dp(16), true /* animate */);
+ boolean isSlow = Math.abs(mVelocityTracker.getXVelocity()) < 500;
+ if (isSlow
+ || SystemClock.uptimeMillis() - mVibrationTime >= GESTURE_DURATION_FOR_CLICK_MS) {
+ mVibratorHelper.vibrate(VibrationEffect.EFFECT_CLICK);
}
// Let's also snap the angle a bit
- if (mAngleOffset < -4) {
- mAngleOffset = Math.max(-16, mAngleOffset - 16);
+ if (mAngleOffset > -4) {
+ mAngleOffset = Math.max(-8, mAngleOffset - 8);
updateAngle(true /* animated */);
}
// Finally, after the translation, animate back and disappear the arrow
Runnable translationEnd = () -> {
- setTriggerBack(false /* false */, true /* animate */);
+ // let's snap it back
+ mAngleOffset = Math.max(0, mAngleOffset + 8);
+ updateAngle(true /* animated */);
+
mTranslationAnimation.setSpring(mTriggerBackSpring);
- setDesiredTranslation(0, true /* animated */);
+ // Translate the arrow back a bit to make for a nice transition
+ setDesiredTranslation(mDesiredTranslation - dp(32), true /* animated */);
animate().alpha(0f).setDuration(DISAPPEAR_FADE_ANIMATION_DURATION_MS)
.withEndAction(() -> setVisibility(GONE));
mArrowDisappearAnimation.start();
@@ -584,6 +588,7 @@
setTriggerBack(false /* triggerBack */, false /* animated */);
setDesiredTranslation(0, false /* animated */);
setCurrentTranslation(0);
+ updateAngle(false /* animate */);
mPreviousTouchTranslation = 0;
mTotalTouchDelta = 0;
mVibrationTime = 0;
@@ -621,7 +626,7 @@
// Let's make sure we only go to the baseextend and apply rubberbanding afterwards
if (touchTranslation > mBaseTranslation) {
float diff = touchTranslation - mBaseTranslation;
- float progress = MathUtils.saturate(diff / (mBaseTranslation * RUBBER_BAND_AMOUNT));
+ float progress = MathUtils.saturate(diff / (mScreenSize - mBaseTranslation));
progress = RUBBER_BAND_INTERPOLATOR.getInterpolation(progress)
* (mMaxTranslation - mBaseTranslation);
touchTranslation = mBaseTranslation + progress;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index 9e0aff0..3b3336b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -107,6 +107,8 @@
@Override
public void setAutoDim(boolean autoDim) {
+ // Ensure we aren't in gestural nav if we are triggering auto dim
+ if (autoDim && NavBarTintController.isEnabled(mView.getContext(), mNavBarMode)) return;
if (mAutoDim == autoDim) return;
mAutoDim = autoDim;
applyLightsOut(true, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
index d59319e..2b0bb21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RegionSamplingHelper.java
@@ -27,6 +27,7 @@
import android.view.CompositionSamplingListener;
import android.view.SurfaceControl;
import android.view.View;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import com.android.systemui.R;
@@ -153,8 +154,12 @@
boolean isSamplingEnabled = mSamplingEnabled && !mSamplingRequestBounds.isEmpty()
&& (mSampledView.isAttachedToWindow() || mFirstSamplingAfterStart);
if (isSamplingEnabled) {
- SurfaceControl stopLayerControl = mSampledView.getViewRootImpl().getSurfaceControl();
- if (!stopLayerControl.isValid()) {
+ ViewRootImpl viewRootImpl = mSampledView.getViewRootImpl();
+ SurfaceControl stopLayerControl = null;
+ if (viewRootImpl != null) {
+ stopLayerControl = viewRootImpl.getSurfaceControl();
+ }
+ if (stopLayerControl == null || !stopLayerControl.isValid()) {
if (!mWaitingOnDraw) {
mWaitingOnDraw = true;
// The view might be attached but we haven't drawn yet, so wait until the
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
index 33b2e6e..364a0f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleDataTest.java
@@ -103,13 +103,13 @@
mEntryB3 = createBubbleEntry(1, "b3", "package.b");
mEntryC1 = createBubbleEntry(1, "c1", "package.c");
- mBubbleA1 = new Bubble(mEntryA1);
- mBubbleA2 = new Bubble(mEntryA2);
- mBubbleA3 = new Bubble(mEntryA3);
- mBubbleB1 = new Bubble(mEntryB1);
- mBubbleB2 = new Bubble(mEntryB2);
- mBubbleB3 = new Bubble(mEntryB3);
- mBubbleC1 = new Bubble(mEntryC1);
+ mBubbleA1 = new Bubble(mContext, mEntryA1);
+ mBubbleA2 = new Bubble(mContext, mEntryA2);
+ mBubbleA3 = new Bubble(mContext, mEntryA3);
+ mBubbleB1 = new Bubble(mContext, mEntryB1);
+ mBubbleB2 = new Bubble(mContext, mEntryB2);
+ mBubbleB3 = new Bubble(mContext, mEntryB3);
+ mBubbleC1 = new Bubble(mContext, mEntryC1);
mBubbleData = new BubbleData(getContext());
@@ -803,4 +803,4 @@
private static <T> List<T> listOf(T... a) {
return ImmutableList.copyOf(a);
}
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index c534de7..355e260 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -29,6 +29,7 @@
import android.app.AlarmManager;
import android.content.ContentResolver;
import android.media.MediaMetadata;
+import android.media.session.PlaybackState;
import android.net.Uri;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
@@ -105,7 +106,7 @@
MediaMetadata metadata = mock(MediaMetadata.class);
when(metadata.getText(any())).thenReturn("metadata");
mProvider.onDozingChanged(true);
- mProvider.onMetadataChanged(metadata);
+ mProvider.onMetadataOrStateChanged(metadata, PlaybackState.STATE_PLAYING);
mProvider.onBindSlice(mProvider.getUri());
verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE));
verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_ARTIST));
@@ -170,7 +171,7 @@
public void onMetadataChanged_updatesSlice() {
mProvider.onDozingChanged(true);
reset(mContentResolver);
- mProvider.onMetadataChanged(mock(MediaMetadata.class));
+ mProvider.onMetadataOrStateChanged(mock(MediaMetadata.class), PlaybackState.STATE_PLAYING);
verify(mContentResolver).notifyChange(eq(mProvider.getUri()), eq(null));
// Hides after waking up
@@ -181,7 +182,7 @@
@Test
public void onDozingChanged_updatesSliceIfMedia() {
- mProvider.onMetadataChanged(mock(MediaMetadata.class));
+ mProvider.onMetadataOrStateChanged(mock(MediaMetadata.class), PlaybackState.STATE_PLAYING);
reset(mContentResolver);
// Show media when dozing
mProvider.onDozingChanged(true);
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 72899f6..cb61259 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1138,8 +1138,8 @@
? clampPositive(whenElapsed + a.windowLength)
: maxTriggerTime(nowElapsed, whenElapsed, a.repeatInterval);
}
- a.whenElapsed = whenElapsed;
- a.maxWhenElapsed = maxElapsed;
+ a.expectedWhenElapsed = a.whenElapsed = whenElapsed;
+ a.expectedMaxWhenElapsed = a.maxWhenElapsed = maxElapsed;
setImplLocked(a, true, doValidate);
}
@@ -1243,7 +1243,7 @@
alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
// Also schedule its next recurrence
final long delta = alarm.count * alarm.repeatInterval;
- final long nextElapsed = alarm.whenElapsed + delta;
+ final long nextElapsed = alarm.expectedWhenElapsed + delta;
setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true,
@@ -3596,10 +3596,9 @@
// this adjustment will be zero if we're late by
// less than one full repeat interval
alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
-
// Also schedule its next recurrence
final long delta = alarm.count * alarm.repeatInterval;
- final long nextElapsed = alarm.whenElapsed + delta;
+ final long nextElapsed = alarm.expectedWhenElapsed + delta;
setImplLocked(alarm.type, alarm.when + delta, nextElapsed, alarm.windowLength,
maxTriggerTime(nowELAPSED, nextElapsed, alarm.repeatInterval),
alarm.repeatInterval, alarm.operation, null, null, alarm.flags, true,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d886c8d..0f7ca7f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -735,11 +735,11 @@
* <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
* method.
*/
- void put(int key, ProcessRecord value) {
+ void put(ProcessRecord app) {
synchronized (this) {
- mPidMap.put(key, value);
+ mPidMap.put(app.pid, app);
}
- mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
+ mAtmInternal.onProcessMapped(app.pid, app.getWindowProcessController());
}
/**
@@ -747,11 +747,18 @@
* <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
* method.
*/
- void remove(int pid) {
+ void remove(ProcessRecord app) {
+ boolean removed = false;
synchronized (this) {
- mPidMap.remove(pid);
+ final ProcessRecord existingApp = mPidMap.get(app.pid);
+ if (existingApp != null && existingApp.startSeq == app.startSeq) {
+ mPidMap.remove(app.pid);
+ removed = true;
+ }
}
- mAtmInternal.onProcessUnMapped(pid);
+ if (removed) {
+ mAtmInternal.onProcessUnMapped(app.pid);
+ }
}
/**
@@ -759,17 +766,18 @@
* <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
* method.
*/
- boolean removeIfNoThread(int pid) {
+ boolean removeIfNoThread(ProcessRecord app) {
boolean removed = false;
synchronized (this) {
- final ProcessRecord app = get(pid);
- if (app != null && app.thread == null) {
- mPidMap.remove(pid);
+ final ProcessRecord existingApp = get(app.pid);
+ if (existingApp != null && existingApp.startSeq == app.startSeq
+ && app.thread == null) {
+ mPidMap.remove(app.pid);
removed = true;
}
}
if (removed) {
- mAtmInternal.onProcessUnMapped(pid);
+ mAtmInternal.onProcessUnMapped(app.pid);
}
return removed;
}
@@ -1970,7 +1978,7 @@
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
- mPidsSelfLocked.put(app.pid, app);
+ mPidsSelfLocked.put(app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE);
}
@@ -4586,7 +4594,7 @@
@GuardedBy("this")
private final void processStartTimedOutLocked(ProcessRecord app) {
final int pid = app.pid;
- boolean gone = mPidsSelfLocked.removeIfNoThread(pid);
+ boolean gone = mPidsSelfLocked.removeIfNoThread(app);
if (gone) {
Slog.w(TAG, "Process " + app + " failed to attach");
@@ -4643,6 +4651,26 @@
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
+ if (app != null && (app.startUid != callingUid || app.startSeq != startSeq)) {
+ String processName = null;
+ final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
+ if (pending != null) {
+ processName = pending.processName;
+ }
+ final String msg = "attachApplicationLocked process:" + processName
+ + " startSeq:" + startSeq
+ + " pid:" + pid
+ + " belongs to another existing app:" + app.processName
+ + " startSeq:" + app.startSeq;
+ Slog.wtf(TAG, msg);
+ // SafetyNet logging for b/131105245.
+ EventLog.writeEvent(0x534e4554, "131105245", app.startUid, msg);
+ // If there is already an app occupying that pid that hasn't been cleaned up
+ cleanUpApplicationRecordLocked(app, false, false, -1,
+ true /*replacingPid*/);
+ mPidsSelfLocked.remove(app);
+ app = null;
+ }
} else {
app = null;
}
@@ -4651,7 +4679,7 @@
// update the internal state.
if (app == null && startSeq > 0) {
final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
- if (pending != null && pending.startUid == callingUid
+ if (pending != null && pending.startUid == callingUid && pending.startSeq == startSeq
&& mProcessList.handleProcessStartedLocked(pending, pid, pending
.isUsingWrapper(),
startSeq, true)) {
@@ -13627,7 +13655,7 @@
return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
- mPidsSelfLocked.remove(app.pid);
+ mPidsSelfLocked.remove(app);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index b394eea..dc94c1e 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1445,10 +1445,11 @@
long startTime = SystemClock.elapsedRealtime();
if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
checkSlow(startTime, "startProcess: removing from pids map");
- mService.mPidsSelfLocked.remove(app.pid);
+ mService.mPidsSelfLocked.remove(app);
mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
checkSlow(startTime, "startProcess: done removing from pids map");
app.setPid(0);
+ app.startSeq = 0;
}
if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
@@ -1656,6 +1657,14 @@
app.killedByAm = false;
app.removed = false;
app.killed = false;
+ if (app.startSeq != 0) {
+ Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
+ + " with non-zero startSeq:" + app.startSeq);
+ }
+ if (app.pid != 0) {
+ Slog.wtf(TAG, "startProcessLocked processName:" + app.processName
+ + " with non-zero pid:" + app.pid);
+ }
final long startSeq = app.startSeq = ++mProcStartSeqCounter;
app.setStartParams(uid, hostingRecord, seInfo, startTime);
app.setUsingWrapper(invokeWith != null
@@ -2063,12 +2072,15 @@
// If there is already an app occupying that pid that hasn't been cleaned up
if (oldApp != null && !app.isolated) {
// Clean up anything relating to this pid first
- Slog.w(TAG, "Reusing pid " + pid
- + " while app is still mapped to it");
+ Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName
+ + " startSeq:" + app.startSeq
+ + " pid:" + pid
+ + " belongs to another existing app:" + oldApp.processName
+ + " startSeq:" + oldApp.startSeq);
mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
- mService.mPidsSelfLocked.put(pid, app);
+ mService.mPidsSelfLocked.put(app);
synchronized (mService.mPidsSelfLocked) {
if (!procAttached) {
Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
@@ -2241,7 +2253,7 @@
.pendingStart)) {
int pid = app.pid;
if (pid > 0) {
- mService.mPidsSelfLocked.remove(pid);
+ mService.mPidsSelfLocked.remove(app);
mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index b9a6a10..db17f83 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -475,7 +475,7 @@
DEFAULT_KEYGUARD_ENABLED ? 1 : 0 /* default */,
userId) != 0);
- if (userId == ActivityManager.getCurrentUser()) {
+ if (userId == ActivityManager.getCurrentUser() && !selfChange) {
notifyEnabledOnKeyguardCallbacks(userId);
}
} else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) {
@@ -494,17 +494,25 @@
}
boolean getFaceEnabledOnKeyguard() {
- return mFaceEnabledOnKeyguard.getOrDefault(
- ActivityManager.getCurrentUser(), DEFAULT_KEYGUARD_ENABLED);
+ final int user = ActivityManager.getCurrentUser();
+ if (!mFaceEnabledOnKeyguard.containsKey(user)) {
+ onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED, user);
+ }
+ return mFaceEnabledOnKeyguard.get(user);
}
boolean getFaceEnabledForApps(int userId) {
+ if (!mFaceEnabledForApps.containsKey(userId)) {
+ onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED, userId);
+ }
return mFaceEnabledForApps.getOrDefault(userId, DEFAULT_APP_ENABLED);
}
boolean getFaceAlwaysRequireConfirmation(int userId) {
- return mFaceAlwaysRequireConfirmation
- .getOrDefault(userId, DEFAULT_ALWAYS_REQUIRE_CONFIRMATION);
+ if (!mFaceAlwaysRequireConfirmation.containsKey(userId)) {
+ onChange(true /* selfChange */, FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION, userId);
+ }
+ return mFaceAlwaysRequireConfirmation.get(userId);
}
void notifyEnabledOnKeyguardCallbacks(int userId) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4f85941..13b4ab9 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -23,6 +23,7 @@
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
import static android.app.Notification.FLAG_NO_CLEAR;
import static android.app.Notification.FLAG_ONGOING_EVENT;
+import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED;
@@ -1031,12 +1032,19 @@
final StatusBarNotification n = r.sbn;
final int callingUid = n.getUid();
final String pkg = n.getPackageName();
+ final boolean wasBubble = r.getNotification().isBubbleNotification();
if (isBubble && isNotificationAppropriateToBubble(r, pkg, callingUid,
null /* oldEntry */)) {
r.getNotification().flags |= FLAG_BUBBLE;
} else {
r.getNotification().flags &= ~FLAG_BUBBLE;
}
+ if (wasBubble != r.getNotification().isBubbleNotification()) {
+ // Add the "alert only once" flag so that the notification won't HUN
+ // unnecessarily just because the bubble flag was changed.
+ r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
+ mListeners.notifyPostedLocked(r, r);
+ }
}
}
}
@@ -5732,7 +5740,7 @@
}
// Suppressed because it's a silent update
final Notification notification = record.getNotification();
- if (record.isUpdate && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
+ if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) {
return false;
}
// Suppressed because another notification in its group handles alerting
@@ -5751,7 +5759,7 @@
boolean shouldMuteNotificationLocked(final NotificationRecord record) {
// Suppressed because it's a silent update
final Notification notification = record.getNotification();
- if (record.isUpdate && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0) {
+ if (record.isUpdate && (notification.flags & FLAG_ONLY_ALERT_ONCE) != 0) {
return true;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index 7ee167a..99f5839 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -120,42 +120,65 @@
return 1;
}
}
- final String packageName = getNextArg();
+ final String packageName = getNextArg();
+ if (packageName != null) {
+ List<OverlayInfo> overlaysForTarget = mInterface.getOverlayInfosForTarget(
+ packageName, userId);
+
+ // If the package is not targeted by any overlays, check if the package is an overlay.
+ if (overlaysForTarget.isEmpty()) {
+ final OverlayInfo info = mInterface.getOverlayInfo(packageName, userId);
+ if (info != null) {
+ printListOverlay(out, info);
+ }
+ return 0;
+ }
+
+ out.println(packageName);
+
+ // Print the overlays for the target.
+ final int n = overlaysForTarget.size();
+ for (int i = 0; i < n; i++) {
+ printListOverlay(out, overlaysForTarget.get(i));
+ }
+
+ return 0;
+ }
+
+ // Print all overlays grouped by target package name.
final Map<String, List<OverlayInfo>> allOverlays = mInterface.getAllOverlays(userId);
for (final String targetPackageName : allOverlays.keySet()) {
- if (targetPackageName.equals(packageName)) {
- out.println(targetPackageName);
- }
+ out.println(targetPackageName);
+
List<OverlayInfo> overlaysForTarget = allOverlays.get(targetPackageName);
final int n = overlaysForTarget.size();
for (int i = 0; i < n; i++) {
- final OverlayInfo oi = overlaysForTarget.get(i);
- if (!targetPackageName.equals(packageName) && !oi.packageName.equals(packageName)) {
- continue;
- }
- String status;
- switch (oi.state) {
- case OverlayInfo.STATE_ENABLED_STATIC:
- case OverlayInfo.STATE_ENABLED:
- status = "[x]";
- break;
- case OverlayInfo.STATE_DISABLED:
- status = "[ ]";
- break;
- default:
- status = "---";
- break;
- }
- out.println(String.format("%s %s", status, oi.packageName));
+ printListOverlay(out, overlaysForTarget.get(i));
}
- if (targetPackageName.equals(packageName)) {
- out.println();
- }
+ out.println();
}
+
return 0;
}
+ private void printListOverlay(PrintWriter out, OverlayInfo oi) {
+ String status;
+ switch (oi.state) {
+ case OverlayInfo.STATE_ENABLED_STATIC:
+ case OverlayInfo.STATE_ENABLED:
+ status = "[x]";
+ break;
+ case OverlayInfo.STATE_DISABLED:
+ status = "[ ]";
+ break;
+ default:
+ status = "---";
+ break;
+ }
+ out.println(String.format("%s %s", status, oi.packageName));
+ }
+
private int runEnableDisable(final boolean enable) throws RemoteException {
final PrintWriter err = getErrPrintWriter();
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 35f2149..bd88594 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -854,9 +854,9 @@
@Override
public void installExistingPackage(String packageName, int installFlags, int installReason,
- IntentSender statusReceiver, int userId) {
+ IntentSender statusReceiver, int userId, List<String> whiteListedPermissions) {
mPm.installExistingPackageAsUser(packageName, userId, installFlags, installReason,
- statusReceiver);
+ whiteListedPermissions, statusReceiver);
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 36b7637..06bbd74 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -13414,8 +13414,9 @@
installExistingPackageAsUser(
packageName,
userId,
- 0 /*installFlags*/,
- PackageManager.INSTALL_REASON_DEVICE_SETUP);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_DEVICE_SETUP,
+ null);
return true;
}
@@ -13503,15 +13504,19 @@
*/
@Override
public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
- int installReason) {
- return installExistingPackageAsUser(packageName, userId, installFlags, installReason, null);
+ int installReason, List<String> whiteListedPermissions) {
+ return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
+ whiteListedPermissions, null);
}
- int installExistingPackageAsUser(String packageName, int userId, int installFlags,
- int installReason, IntentSender intentSender) {
+ int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
+ @PackageManager.InstallFlags int installFlags,
+ @PackageManager.InstallReason int installReason,
+ @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
if (DEBUG_INSTALL) {
Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
- + " installFlags=" + installFlags + " installReason=" + installReason);
+ + " installFlags=" + installFlags + " installReason=" + installReason
+ + " whiteListedPermissions=" + whiteListedPermissions);
}
final int callingUid = Binder.getCallingUid();
@@ -13574,6 +13579,13 @@
}
if (installed) {
+ if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
+ != 0 && pkgSetting.pkg != null) {
+ whiteListedPermissions = pkgSetting.pkg.requestedPermissions;
+ }
+ setWhitelistedRestrictedPermissions(packageName, whiteListedPermissions,
+ PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
+
if (pkgSetting.pkg != null) {
synchronized (mInstallLock) {
// We don't need to freeze for a brand new install
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index d9a608d..f5c8049 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1162,7 +1162,7 @@
private int runInstallExisting() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
int userId = UserHandle.USER_SYSTEM;
- int installFlags = 0;
+ int installFlags = PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
String opt;
boolean waitTillComplete = false;
while ((opt = getNextOption()) != null) {
@@ -1182,6 +1182,9 @@
case "--wait":
waitTillComplete = true;
break;
+ case "--restrict-permissions":
+ installFlags &= ~PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
+ break;
default:
pw.println("Error: Unknown option: " + opt);
return 1;
@@ -1201,7 +1204,7 @@
final IPackageInstaller installer = mInterface.getPackageInstaller();
pw.println("Installing package " + packageName + " for user: " + userId);
installer.installExistingPackage(packageName, installFlags, installReason,
- receiver.getIntentSender(), userId);
+ receiver.getIntentSender(), userId, null);
final Intent result = receiver.getResult();
final int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
PackageInstaller.STATUS_FAILURE);
@@ -1210,7 +1213,7 @@
}
final int res = mInterface.installExistingPackageAsUser(packageName, userId,
- installFlags, installReason);
+ installFlags, installReason, null);
if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
throw new NameNotFoundException("Package " + packageName + " doesn't exist");
}
@@ -2370,7 +2373,11 @@
private InstallParams makeInstallParams() {
final SessionParams sessionParams = new SessionParams(SessionParams.MODE_FULL_INSTALL);
final InstallParams params = new InstallParams();
+
params.sessionParams = sessionParams;
+ // Whitelist all permissions by default
+ sessionParams.installFlags |= PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS;
+
String opt;
boolean replaceExisting = true;
while ((opt = getNextOption()) != null) {
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index fe0b9a6..b7e18c3 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -537,6 +537,7 @@
Slog.d(TAG, "doAutoBatterySaverLocked: mBootCompleted=" + mBootCompleted
+ " mSettingsLoaded=" + mSettingsLoaded
+ " mBatteryStatusSet=" + mBatteryStatusSet
+ + " mState=" + mState
+ " mIsBatteryLevelLow=" + mIsBatteryLevelLow
+ " mIsPowered=" + mIsPowered
+ " mSettingAutomaticBatterySaver=" + mSettingAutomaticBatterySaver
@@ -689,9 +690,9 @@
final boolean isStickyDisabled =
mBatterySaverStickyBehaviourDisabled || !mSettingBatterySaverEnabledSticky;
if (isStickyDisabled || shouldTurnOffSticky) {
+ mState = STATE_OFF;
setStickyActive(false);
triggerStickyDisabledNotification();
- mState = STATE_OFF;
} else if (!mIsPowered) {
// Re-enable BS.
enableBatterySaverLocked(/*enable*/ true, /*manual*/ true,
@@ -797,7 +798,8 @@
Intent.ACTION_POWER_USAGE_SUMMARY));
}
- private void triggerStickyDisabledNotification() {
+ @VisibleForTesting
+ void triggerStickyDisabledNotification() {
NotificationManager manager = mContext.getSystemService(NotificationManager.class);
ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID,
R.string.battery_saver_notification_channel_name);
diff --git a/services/core/java/com/android/server/updates/ConversationActionsInstallReceiver.java b/services/core/java/com/android/server/updates/ConversationActionsInstallReceiver.java
index 7310af3..bbe534e 100644
--- a/services/core/java/com/android/server/updates/ConversationActionsInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/ConversationActionsInstallReceiver.java
@@ -25,4 +25,9 @@
"metadata/actions_suggestions",
"version");
}
+
+ @Override
+ protected boolean verifyVersion(int current, int alternative) {
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/updates/LangIdInstallReceiver.java b/services/core/java/com/android/server/updates/LangIdInstallReceiver.java
index 05dad21..ecfa3aa 100644
--- a/services/core/java/com/android/server/updates/LangIdInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/LangIdInstallReceiver.java
@@ -25,4 +25,9 @@
"metadata/lang_id",
"version");
}
+
+ @Override
+ protected boolean verifyVersion(int current, int alternative) {
+ return true;
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1344727..66b305e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1085,6 +1085,22 @@
if (root == this) {
task.setRootProcess(proc);
}
+ // Override the process configuration to match the display where the first activity in
+ // the process was launched. This can help with compat issues on secondary displays when
+ // apps use Application to obtain configuration or metrics instead of Activity.
+ final ActivityDisplay display = getDisplay();
+ if (display == null || display.mDisplayId == INVALID_DISPLAY) {
+ return;
+ }
+ if (!proc.hasActivities() && display.mDisplayId != DEFAULT_DISPLAY) {
+ proc.registerDisplayConfigurationListenerLocked(display);
+ } else if (display.mDisplayId == DEFAULT_DISPLAY) {
+ // Once an activity is launched on default display - stop listening for other displays
+ // configurations to maintain compatibility with previous platform releases. E.g. when
+ // an activity is launched in a Bubble and then moved to default screen, we should match
+ // the global device config.
+ proc.unregisterDisplayConfigurationListenerLocked();
+ }
}
boolean hasProcess() {
@@ -3233,7 +3249,7 @@
// Update last reported values.
final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
- setLastReportedConfiguration(mAtmService.getGlobalConfiguration(), newMergedOverrideConfig);
+ setLastReportedConfiguration(getProcessGlobalConfiguration(), newMergedOverrideConfig);
if (mState == INITIALIZING) {
// No need to relaunch or schedule new config for activity that hasn't been launched
@@ -3342,6 +3358,14 @@
return true;
}
+ /** Get process configuration, or global config if the process is not set. */
+ private Configuration getProcessGlobalConfiguration() {
+ if (app != null) {
+ return app.getConfiguration();
+ }
+ return mAtmService.getGlobalConfiguration();
+ }
+
/**
* When assessing a configuration change, decide if the changes flags and the new configurations
* should cause the Activity to relaunch.
@@ -3449,7 +3473,7 @@
mStackSupervisor.activityRelaunchingLocked(this);
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
- new MergedConfiguration(mAtmService.getGlobalConfiguration(),
+ new MergedConfiguration(getProcessGlobalConfiguration(),
getMergedOverrideConfiguration()),
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 1cdb49d..9d08e10 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -280,13 +280,6 @@
mActivityOptions = ActivityOptions.makeBasic();
}
- ActivityRecord homeActivityRecord = mRootActivityContainer.getDefaultDisplayHomeActivity();
- if (homeActivityRecord != null && homeActivityRecord.getTaskRecord() != null) {
- // Showing credential confirmation activity in home task to avoid stopping
- // multi-windowed mode after showing the full-screen credential confirmation activity.
- mActivityOptions.setLaunchTaskId(homeActivityRecord.getTaskRecord().taskId);
- }
-
final UserInfo parent = mUserManager.getProfileParent(mUserId);
mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id, 0, mRealCallingUid);
mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null /*profilerInfo*/);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 89962a5..772e5e6 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -39,7 +39,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -6892,15 +6891,9 @@
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
- intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
- FLAG_ACTIVITY_TASK_ON_HOME);
- ActivityOptions activityOptions = options != null
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+ final ActivityOptions activityOptions = options != null
? new ActivityOptions(options) : ActivityOptions.makeBasic();
- final ActivityRecord homeActivity =
- mRootActivityContainer.getDefaultDisplayHomeActivity();
- if (homeActivity != null) {
- activityOptions.setLaunchTaskId(homeActivity.getTaskRecord().taskId);
- }
mContext.startActivityAsUser(intent, activityOptions.toBundle(),
UserHandle.CURRENT);
} finally {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index ecbecba..3d7e50d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -2782,6 +2782,7 @@
protected void onAnimationFinished() {
super.onAnimationFinished();
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#onAnimationFinished");
mTransit = TRANSIT_UNSET;
mTransitFlags = 0;
mNeedsZBoost = false;
@@ -2816,6 +2817,7 @@
scheduleAnimation();
mActivityRecord.onAnimationFinished();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
@Override
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index ef2a21d..b30da5e 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -819,7 +819,7 @@
} catch (Settings.SettingNotFoundException e) {
// Log to SafetyNet for b/127605586
android.util.EventLog.writeEvent(0x534e4554, "127605586", -1, "");
- return mLockPatternUtils.isSecure(USER_CURRENT);
+ return getLockPatternUtils().isSecure(USER_CURRENT);
}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ab5e071..d838691 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -319,7 +319,8 @@
* Sets the bounds animation target bounds ahead of an animation. This can't currently be done
* in onAnimationStart() since that is started on the UiThread.
*/
- void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds, boolean toFullscreen) {
+ private void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds,
+ boolean toFullscreen) {
mBoundsAnimatingRequested = true;
mBoundsAnimatingToFullscreen = toFullscreen;
if (destBounds != null) {
@@ -329,7 +330,11 @@
}
if (sourceHintBounds != null) {
mBoundsAnimationSourceHintBounds.set(sourceHintBounds);
- } else {
+ } else if (!mBoundsAnimating) {
+ // If the bounds are already animating, we don't want to reset the source hint. This is
+ // because the source hint is sent when starting the animation from the client that
+ // requested to enter pip. Other requests can adjust the pip bounds during an animation,
+ // but could accidentally reset the source hint bounds.
mBoundsAnimationSourceHintBounds.setEmpty();
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 12b62b9..5fc3997 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -439,7 +439,10 @@
@Override
protected ConfigurationContainer getParent() {
- return null;
+ // Returning RootActivityContainer as the parent, so that this process controller always
+ // has full configuration and overrides (e.g. from display) are always added on top of
+ // global config.
+ return mAtm.mRootActivityContainer;
}
@HotPath(caller = HotPath.PROCESS_CHANGE)
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 5ef184a..c35e866 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3104,7 +3104,7 @@
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
+ ": " + mWindowFrames.mCompatFrame);
final MergedConfiguration mergedConfiguration =
- new MergedConfiguration(mWmService.mRoot.getConfiguration(),
+ new MergedConfiguration(getProcessGlobalConfiguration(),
getMergedOverrideConfiguration());
setLastReportedMergedConfiguration(mergedConfiguration);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 22231c0..e2e9c42 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -9680,7 +9680,8 @@
// Install the profile owner if not present.
if (!mIPackageManager.isPackageAvailable(adminPkg, userHandle)) {
mIPackageManager.installExistingPackageAsUser(adminPkg, userHandle,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY, null);
}
} catch (RemoteException e) {
// Does not happen, same process
@@ -10176,7 +10177,8 @@
// Install the app.
mIPackageManager.installExistingPackageAsUser(packageName, userId,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY, null);
if (isDemo) {
// Ensure the app is also ENABLED for demo users.
mIPackageManager.setApplicationEnabledSetting(packageName,
@@ -10230,7 +10232,8 @@
if (isSystemApp(mIPackageManager, packageName, parentUserId)) {
numberOfAppsInstalled++;
mIPackageManager.installExistingPackageAsUser(packageName, userId,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY, null);
} else {
Slog.d(LOG_TAG, "Not enabling " + packageName + " since is not a"
+ " system app");
@@ -10289,9 +10292,9 @@
}
// Install the package.
- result = mIPackageManager
- .installExistingPackageAsUser(packageName, callingUserId,
- 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY)
+ result = mIPackageManager.installExistingPackageAsUser(packageName, callingUserId,
+ PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
+ PackageManager.INSTALL_REASON_POLICY, null)
== PackageManager.INSTALL_SUCCEEDED;
} catch (RemoteException re) {
// shouldn't happen
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
index fb34913..1ab3b98 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
@@ -349,7 +349,7 @@
lastPos++;
} else {
// Two events have the same timestamp, check if they are the same.
- if (lastEvent.equals(curEvent)) {
+ if (lastEvent.eventEquals(curEvent)) {
// Actual overlap, just skip the event.
if (DEBUG) Slog.d(TAG, "Skipped dup event with timestamp: " + lastNanos);
} else {
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 6517303..77e2517 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -43,6 +43,8 @@
import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
import static com.android.server.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
+import static com.android.server.AlarmManagerService.IS_WAKEUP_MASK;
+import static com.android.server.AlarmManagerService.TIME_CHANGED_MASK;
import static com.android.server.AlarmManagerService.WORKING_INDEX;
import static org.junit.Assert.assertEquals;
@@ -126,13 +128,15 @@
private MockitoSession mMockingSession;
private Injector mInjector;
private volatile long mNowElapsedTest;
+ private volatile long mNowRtcTest;
@GuardedBy("mTestTimer")
private TestTimer mTestTimer = new TestTimer();
static class TestTimer {
private long mElapsed;
boolean mExpired;
- int mType;
+ private int mType;
+ private int mFlags; // Flags used to decide what needs to be evaluated.
synchronized long getElapsed() {
return mElapsed;
@@ -147,7 +151,16 @@
return mType;
}
+ synchronized int getFlags() {
+ return mFlags;
+ }
+
synchronized void expire() throws InterruptedException {
+ expire(IS_WAKEUP_MASK); // Default: evaluate eligibility of all alarms
+ }
+
+ synchronized void expire(int flags) throws InterruptedException {
+ mFlags = flags;
mExpired = true;
notifyAll();
// Now wait for the alarm thread to finish execution.
@@ -181,7 +194,7 @@
}
mTestTimer.mExpired = false;
}
- return AlarmManagerService.IS_WAKEUP_MASK; // Doesn't matter, just evaluate.
+ return mTestTimer.getFlags();
}
@Override
@@ -215,6 +228,11 @@
}
@Override
+ long getCurrentTimeMillis() {
+ return mNowRtcTest;
+ }
+
+ @Override
AlarmManagerService.ClockReceiver getClockReceiver(AlarmManagerService service) {
return mClockReceiver;
}
@@ -340,7 +358,7 @@
}
@Test
- public void testSingleAlarmSet() {
+ public void singleElapsedAlarmSet() {
final long triggerTime = mNowElapsedTest + 5000;
final PendingIntent alarmPi = getNewMockPendingIntent();
setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi);
@@ -348,6 +366,33 @@
}
@Test
+ public void singleRtcAlarmSet() {
+ mNowElapsedTest = 54;
+ mNowRtcTest = 1243; // arbitrary values of time
+ final long triggerRtc = mNowRtcTest + 5000;
+ final PendingIntent alarmPi = getNewMockPendingIntent();
+ setTestAlarm(RTC_WAKEUP, triggerRtc, alarmPi);
+ final long triggerElapsed = triggerRtc - (mNowRtcTest - mNowElapsedTest);
+ assertEquals(triggerElapsed, mTestTimer.getElapsed());
+ }
+
+ @Test
+ public void timeChangeMovesRtcAlarm() throws Exception {
+ mNowElapsedTest = 42;
+ mNowRtcTest = 4123; // arbitrary values of time
+ final long triggerRtc = mNowRtcTest + 5000;
+ final PendingIntent alarmPi = getNewMockPendingIntent();
+ setTestAlarm(RTC_WAKEUP, triggerRtc, alarmPi);
+ final long triggerElapsed1 = mTestTimer.getElapsed();
+ final long timeDelta = -123;
+ mNowRtcTest += timeDelta;
+ mTestTimer.expire(TIME_CHANGED_MASK);
+ final long triggerElapsed2 = mTestTimer.getElapsed();
+ assertEquals("Invalid movement of triggerElapsed following time change", triggerElapsed2,
+ triggerElapsed1 - timeDelta);
+ }
+
+ @Test
public void testSingleAlarmExpiration() throws Exception {
final long triggerTime = mNowElapsedTest + 5000;
final PendingIntent alarmPi = getNewMockPendingIntent();
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 212d2a8..a8faa54 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -15,6 +15,10 @@
*/
package com.android.server.power.batterysaver;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.inOrder;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@@ -22,6 +26,8 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.NotificationManager;
@@ -37,6 +43,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InOrder;
import java.util.HashMap;
import java.util.Objects;
@@ -201,6 +208,8 @@
mDevice = new Device();
mTarget = new TestableBatterySaverStateMachine();
+ spyOn(mTarget);
+ doNothing().when(mTarget).triggerStickyDisabledNotification();
mDevice.pushBatteryStatus();
mTarget.onBootCompleted();
@@ -423,7 +432,7 @@
assertEquals(70, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
- // Bump ump the threshold.
+ // Bump up the threshold.
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 70);
mDevice.setBatteryLevel(mPersistedState.batteryLevel);
@@ -545,6 +554,8 @@
@Test
public void testAutoBatterySaver_withSticky_withAutoOffEnabled() {
+ InOrder inOrder = inOrder(mTarget);
+
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 1);
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90);
@@ -569,6 +580,7 @@
assertEquals(true, mDevice.batterySaverEnabled); // Stays on.
assertEquals(95, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
// Scenario 2: User turns BS on manually above the threshold then charges device. BS
// shouldn't turn back on.
@@ -584,6 +596,7 @@
assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
assertEquals(97, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ inOrder.verify(mTarget).triggerStickyDisabledNotification();
// Scenario 3: User turns BS on manually above the threshold. Device drains below
// threshold and then charged to below threshold. Sticky BS should activate.
@@ -612,6 +625,7 @@
assertEquals(true, mDevice.batterySaverEnabled);
assertEquals(30, mPersistedState.batteryLevel);
assertEquals(true, mPersistedState.batteryLow);
+ inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
// Scenario 4: User turns BS on manually above the threshold. Device drains below
// threshold and is eventually charged to above threshold. Sticky BS should turn off.
@@ -627,6 +641,7 @@
assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
assertEquals(90, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ inOrder.verify(mTarget).triggerStickyDisabledNotification();
// Scenario 5: User turns BS on manually below threshold and charges to below threshold.
// Sticky BS should activate.
@@ -654,6 +669,7 @@
assertEquals(true, mDevice.batterySaverEnabled); // Sticky BS still on.
assertEquals(80, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ inOrder.verify(mTarget, never()).triggerStickyDisabledNotification();
// Scenario 6: User turns BS on manually below threshold and eventually charges to above
// threshold. Sticky BS should turn off.
@@ -665,6 +681,7 @@
assertEquals(false, mDevice.batterySaverEnabled);
assertEquals(95, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ inOrder.verify(mTarget).triggerStickyDisabledNotification();
// Scenario 7: User turns BS on above threshold and then reboots device. Sticky BS
// shouldn't activate.
@@ -676,6 +693,8 @@
assertEquals(false, mDevice.batterySaverEnabled);
assertEquals(93, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ // initDevice() changes the mTarget reference, so inOrder is invalid here.
+ verify(mTarget).triggerStickyDisabledNotification();
// Scenario 8: User turns BS on below threshold and then reboots device without charging.
// Sticky BS should activate.
@@ -690,6 +709,8 @@
assertEquals(true, mDevice.batterySaverEnabled);
assertEquals(75, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ // initDevice() changes the mTarget reference, so inOrder is invalid here.
+ verify(mTarget, never()).triggerStickyDisabledNotification();
// Scenario 9: User turns BS on below threshold and then reboots device after charging
// above threshold. Sticky BS shouldn't activate.
@@ -702,6 +723,8 @@
assertEquals(false, mDevice.batterySaverEnabled);
assertEquals(100, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ // initDevice() changes the mTarget reference, so inOrder is invalid here.
+ verify(mTarget).triggerStickyDisabledNotification();
// Scenario 10: Somehow autoDisableLevel is set to a value below lowPowerModeTriggerLevel
// and then user enables manually above both thresholds, discharges below
@@ -738,6 +761,8 @@
assertEquals(true, mDevice.batterySaverEnabled);
assertEquals(65, mPersistedState.batteryLevel);
assertEquals(true, mPersistedState.batteryLow);
+ // initDevice() changes the mTarget reference, so inOrder is invalid here.
+ verify(mTarget, never()).triggerStickyDisabledNotification();
}
@Test
@@ -780,6 +805,7 @@
assertEquals(false, mDevice.batterySaverEnabled); // Sticky BS no longer enabled.
assertEquals(95, mPersistedState.batteryLevel);
assertEquals(false, mPersistedState.batteryLow);
+ verify(mTarget).triggerStickyDisabledNotification();
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index d2332bf..3661e89 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -22,6 +22,7 @@
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
+import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -119,7 +120,6 @@
import android.service.notification.Adjustment;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
-import android.service.notification.NotifyingApp;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenPolicy;
import android.test.suitebuilder.annotation.SmallTest;
@@ -165,10 +165,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.function.Consumer;
@SmallTest
@@ -5012,6 +5010,9 @@
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
+ // Reset as this is called when the notif is first sent
+ reset(mListeners);
+
// First we were a bubble
StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsBefore.length);
@@ -5021,10 +5022,13 @@
mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false);
waitForIdle();
- // Now we are not a bubble
- StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
- assertEquals(1, notifsAfter.length);
- assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
+ // Make sure we are not a bubble / reported as such to listeners
+ ArgumentCaptor<NotificationRecord> captor =
+ ArgumentCaptor.forClass(NotificationRecord.class);
+ verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
+
+ assertEquals((captor.getValue().getNotification().flags & FLAG_BUBBLE), 0);
+ assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
}
@Test
@@ -5054,14 +5058,20 @@
when(mActivityManager.getPackageImportance(nr.sbn.getPackageName())).thenReturn(
IMPORTANCE_FOREGROUND);
+ // Reset as this is called when the notif is first sent
+ reset(mListeners);
+
// Notify we are now a bubble
mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true);
waitForIdle();
- // Make sure we are a bubble
- StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
- assertEquals(1, notifsAfter.length);
- assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
+ // Make sure we are a bubble / reported as such to listeners
+ ArgumentCaptor<NotificationRecord> captor =
+ ArgumentCaptor.forClass(NotificationRecord.class);
+ verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
+
+ assertTrue((captor.getValue().getNotification().flags & FLAG_BUBBLE) != 0);
+ assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
}
@Test
@@ -5082,6 +5092,9 @@
nr.sbn.getId(), nr.sbn.getNotification(), nr.sbn.getUserId());
waitForIdle();
+ // Reset as this is called when the notif is first sent
+ reset(mListeners);
+
// Would be a normal notification because wouldn't have met requirements to bubble
StatusBarNotification[] notifsBefore = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsBefore.length);
@@ -5095,6 +5108,7 @@
StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsAfter.length);
assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
+ verify(mListeners, times(0)).notifyPostedLocked(any(), any());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 11a177a..f8fd64a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_90;
@@ -38,6 +40,7 @@
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_INVISIBLE;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIND_TRANSLUCENT;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -56,10 +59,10 @@
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
-import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.util.MergedConfiguration;
import android.util.MutableBoolean;
+import android.view.DisplayInfo;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner.Stub;
import android.view.RemoteAnimationAdapter;
@@ -598,6 +601,67 @@
assertNull(mActivity.pendingOptions);
}
+ @Test
+ public void testSetProcessOverridesConfig() {
+ final ActivityRecord defaultDisplayActivity =
+ createActivityOnDisplay(true /* defaultDisplay */, null /* process */);
+ assertFalse(defaultDisplayActivity.app.registeredForDisplayConfigChanges());
+
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
+ assertTrue(secondaryDisplayActivity.app.registeredForDisplayConfigChanges());
+ assertEquals(secondaryDisplayActivity.getDisplay().getResolvedOverrideConfiguration(),
+ secondaryDisplayActivity.app.getRequestedOverrideConfiguration());
+
+ assertNotEquals(defaultDisplayActivity.getConfiguration(),
+ secondaryDisplayActivity.getConfiguration());
+ }
+
+ @Test
+ public void testSetProcessDoesntOverrideConfigIfAnotherActivityPresent() {
+ final ActivityRecord defaultDisplayActivity =
+ createActivityOnDisplay(true /* defaultDisplay */, null /* process */);
+ assertFalse(defaultDisplayActivity.app.registeredForDisplayConfigChanges());
+
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, defaultDisplayActivity.app);
+ assertFalse(secondaryDisplayActivity.app.registeredForDisplayConfigChanges());
+ }
+
+ @Test
+ public void testActivityOnDefaultDisplayClearsProcessOverride() {
+ final ActivityRecord secondaryDisplayActivity =
+ createActivityOnDisplay(false /* defaultDisplay */, null /* process */);
+ assertTrue(secondaryDisplayActivity.app.registeredForDisplayConfigChanges());
+
+ final ActivityRecord defaultDisplayActivity =
+ createActivityOnDisplay(true /* defaultDisplay */,
+ secondaryDisplayActivity.app);
+ assertFalse(defaultDisplayActivity.app.registeredForDisplayConfigChanges());
+ assertFalse(secondaryDisplayActivity.app.registeredForDisplayConfigChanges());
+ }
+
+ /**
+ * Creates an activity on display. For non-default display request it will also create a new
+ * display with custom DisplayInfo.
+ */
+ private ActivityRecord createActivityOnDisplay(boolean defaultDisplay,
+ WindowProcessController process) {
+ final ActivityDisplay display;
+ if (defaultDisplay) {
+ display = mRootActivityContainer.getDefaultDisplay();
+ } else {
+ final DisplayInfo info = new DisplayInfo();
+ info.logicalWidth = 100;
+ info.logicalHeight = 100;
+ display = addNewActivityDisplayAt(info, POSITION_TOP);
+ }
+ final TestActivityStack stack = display.createStack(WINDOWING_MODE_UNDEFINED,
+ ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ return new ActivityBuilder(mService).setTask(task).setUseProcess(process).build();
+ }
+
/** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
private void prepareFixedAspectRatioUnresizableActivity() {
setupDisplayContentForCompatDisplayInsets();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 53b0add..d8c0de7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -195,6 +195,7 @@
private ActivityStack mStack;
private int mActivityFlags;
private int mLaunchMode;
+ private WindowProcessController mWpc;
ActivityBuilder(ActivityTaskManagerService service) {
mService = service;
@@ -245,6 +246,11 @@
return this;
}
+ ActivityBuilder setUseProcess(WindowProcessController wpc) {
+ mWpc = wpc;
+ return this;
+ }
+
ActivityRecord build() {
if (mComponent == null) {
final int id = sCurrentActivityId++;
@@ -290,12 +296,18 @@
mTaskRecord.addActivityToTop(activity);
}
- final WindowProcessController wpc = new WindowProcessController(mService,
- mService.mContext.getApplicationInfo(), "name", 12345,
- UserHandle.getUserId(12345), mock(Object.class),
- mock(WindowProcessListener.class));
- wpc.setThread(mock(IApplicationThread.class));
+ final WindowProcessController wpc;
+ if (mWpc != null) {
+ wpc = mWpc;
+ } else {
+ wpc = new WindowProcessController(mService,
+ mService.mContext.getApplicationInfo(), "name", 12345,
+ UserHandle.getUserId(12345), mock(Object.class),
+ mock(WindowProcessListener.class));
+ wpc.setThread(mock(IApplicationThread.class));
+ }
activity.setProcess(wpc);
+ wpc.addActivityIfNeeded(activity);
return activity;
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
index fe45411..8528954 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -153,7 +153,6 @@
@FlakyTest(bugId = 131005232)
public void testLandscapeSeascapeRotationByApp() {
// Some plumbing to get the service ready for rotation updates.
- mWm.mDisplayReady = true;
mWm.mDisplayEnabled = true;
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
@@ -186,7 +185,6 @@
@Test
public void testLandscapeSeascapeRotationByPolicy() {
// Some plumbing to get the service ready for rotation updates.
- mWm.mDisplayReady = true;
mWm.mDisplayEnabled = true;
final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
@@ -379,6 +377,7 @@
}
@Test
+ @FlakyTest(bugId = 131176283)
public void testCreateRemoveStartingWindow() {
mToken.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 366acea..427a929 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -41,6 +41,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.database.ContentObserver;
import android.hardware.display.DisplayManagerInternal;
import android.net.Uri;
@@ -175,6 +176,12 @@
// Display creation is driven by the ActivityManagerService via
// ActivityStackSupervisor. We emulate those steps here.
mWindowManagerService.mRoot.createDisplayContent(display, mock(ActivityDisplay.class));
+ mWindowManagerService.displayReady();
+
+ final Configuration defaultDisplayConfig =
+ mWindowManagerService.computeNewConfiguration(DEFAULT_DISPLAY);
+ doReturn(defaultDisplayConfig).when(atms).getGlobalConfiguration();
+ doReturn(defaultDisplayConfig).when(atms).getGlobalConfigurationForPid(anyInt());
mMockTracker.stopTracking();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index a7c84a1..7b8fba0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -26,7 +26,9 @@
import static org.mockito.Mockito.mock;
import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
import android.platform.test.annotations.Presubmit;
+import android.view.DisplayInfo;
import org.junit.Test;
@@ -78,6 +80,26 @@
assertEquals(INVALID_DISPLAY, wpc.getDisplayId());
}
+ @Test
+ public void testConfigurationForSecondaryScreen() {
+ final WindowProcessController wpc = new WindowProcessController(
+ mService, mock(ApplicationInfo.class), null, 0, -1, null, null);
+ //By default, the process should not listen to any display.
+ assertEquals(INVALID_DISPLAY, wpc.getDisplayId());
+
+ // Register to a new display as a listener.
+ final DisplayInfo info = new DisplayInfo();
+ info.logicalWidth = 100;
+ info.logicalHeight = 100;
+ TestActivityDisplay display = addNewActivityDisplayAt(info, WindowContainer.POSITION_TOP);
+ wpc.registerDisplayConfigurationListenerLocked(display);
+
+ assertEquals(display.mDisplayId, wpc.getDisplayId());
+ final Configuration expectedConfig = mService.mRootActivityContainer.getConfiguration();
+ expectedConfig.updateFrom(display.getConfiguration());
+ assertEquals(expectedConfig, wpc.getConfiguration());
+ }
+
private TestActivityDisplay createTestActivityDisplayInContainer() {
final TestActivityDisplay testActivityDisplay = createNewActivityDisplay();
mRootActivityContainer.addChild(testActivityDisplay, POSITION_TOP);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index 3a702cb9..de28b5f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -154,7 +154,6 @@
context.getDisplay().getDisplayInfo(mDisplayInfo);
mDisplayContent = createNewDisplay();
mWm.mDisplayEnabled = true;
- mWm.mDisplayReady = true;
// Set-up some common windows.
mCommonWindows = new HashSet<>();
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index eefaf47..be4729a 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1249,6 +1249,7 @@
* @deprecated Use
* {@link android.app.role.RoleManager#addRoleHolderAsUser(String, String, int, UserHandle,
* Executor, java.util.function.Consumer)} instead.
+ * @removed
*/
@SystemApi
@Deprecated
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 14ae689..9d732ba 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -18,6 +18,7 @@
import android.annotation.IntRange;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
@@ -46,7 +47,7 @@
private int mRssi; // in dBm [-113, -51] or UNAVAILABLE
@UnsupportedAppUsage
private int mBitErrorRate; // bit error rate (0-7, 99) TS 27.007 8.5 or UNAVAILABLE
- @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private int mTimingAdvance; // range from 0-219 or CellInfo.UNAVAILABLE if unknown
private int mLevel;
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 1551ce3..984d8f7 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -337,7 +337,7 @@
* Reference: 3GPP TS 36.104 5.4.3 */
private int mLteEarfcnRsrpBoost = 0;
- private List<NetworkRegistrationInfo> mNetworkRegistrationInfos = new ArrayList<>();
+ private final List<NetworkRegistrationInfo> mNetworkRegistrationInfos = new ArrayList<>();
private String mOperatorAlphaLongRaw;
private String mOperatorAlphaShortRaw;
@@ -420,8 +420,10 @@
mCellBandwidths = s.mCellBandwidths == null ? null :
Arrays.copyOf(s.mCellBandwidths, s.mCellBandwidths.length);
mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
- mNetworkRegistrationInfos = s.mNetworkRegistrationInfos == null ? null :
- s.getNetworkRegistrationInfoList();
+ synchronized (mNetworkRegistrationInfos) {
+ mNetworkRegistrationInfos.clear();
+ mNetworkRegistrationInfos.addAll(s.getNetworkRegistrationInfoList());
+ }
mNrFrequencyRange = s.mNrFrequencyRange;
mOperatorAlphaLongRaw = s.mOperatorAlphaLongRaw;
mOperatorAlphaShortRaw = s.mOperatorAlphaShortRaw;
@@ -453,8 +455,9 @@
mCdmaEriIconMode = in.readInt();
mIsEmergencyOnly = in.readInt() != 0;
mLteEarfcnRsrpBoost = in.readInt();
- mNetworkRegistrationInfos = new ArrayList<>();
- in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader());
+ synchronized (mNetworkRegistrationInfos) {
+ in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader());
+ }
mChannelNumber = in.readInt();
mCellBandwidths = in.createIntArray();
mNrFrequencyRange = in.readInt();
@@ -481,7 +484,9 @@
out.writeInt(mCdmaEriIconMode);
out.writeInt(mIsEmergencyOnly ? 1 : 0);
out.writeInt(mLteEarfcnRsrpBoost);
- out.writeList(mNetworkRegistrationInfos);
+ synchronized (mNetworkRegistrationInfos) {
+ out.writeList(mNetworkRegistrationInfos);
+ }
out.writeInt(mChannelNumber);
out.writeIntArray(mCellBandwidths);
out.writeInt(mNrFrequencyRange);
@@ -823,31 +828,33 @@
@Override
public int hashCode() {
- return Objects.hash(
- mVoiceRegState,
- mDataRegState,
- mChannelNumber,
- Arrays.hashCode(mCellBandwidths),
- mVoiceOperatorAlphaLong,
- mVoiceOperatorAlphaShort,
- mVoiceOperatorNumeric,
- mDataOperatorAlphaLong,
- mDataOperatorAlphaShort,
- mDataOperatorNumeric,
- mIsManualNetworkSelection,
- mCssIndicator,
- mNetworkId,
- mSystemId,
- mCdmaRoamingIndicator,
- mCdmaDefaultRoamingIndicator,
- mCdmaEriIconIndex,
- mCdmaEriIconMode,
- mIsEmergencyOnly,
- mLteEarfcnRsrpBoost,
- mNetworkRegistrationInfos,
- mNrFrequencyRange,
- mOperatorAlphaLongRaw,
- mOperatorAlphaShortRaw);
+ synchronized (mNetworkRegistrationInfos) {
+ return Objects.hash(
+ mVoiceRegState,
+ mDataRegState,
+ mChannelNumber,
+ Arrays.hashCode(mCellBandwidths),
+ mVoiceOperatorAlphaLong,
+ mVoiceOperatorAlphaShort,
+ mVoiceOperatorNumeric,
+ mDataOperatorAlphaLong,
+ mDataOperatorAlphaShort,
+ mDataOperatorNumeric,
+ mIsManualNetworkSelection,
+ mCssIndicator,
+ mNetworkId,
+ mSystemId,
+ mCdmaRoamingIndicator,
+ mCdmaDefaultRoamingIndicator,
+ mCdmaEriIconIndex,
+ mCdmaEriIconMode,
+ mIsEmergencyOnly,
+ mLteEarfcnRsrpBoost,
+ mNetworkRegistrationInfos,
+ mNrFrequencyRange,
+ mOperatorAlphaLongRaw,
+ mOperatorAlphaShortRaw);
+ }
}
@Override
@@ -855,30 +862,31 @@
if (!(o instanceof ServiceState)) return false;
ServiceState s = (ServiceState) o;
- return mVoiceRegState == s.mVoiceRegState
- && mDataRegState == s.mDataRegState
- && mIsManualNetworkSelection == s.mIsManualNetworkSelection
- && mChannelNumber == s.mChannelNumber
- && Arrays.equals(mCellBandwidths, s.mCellBandwidths)
- && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
- && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort)
- && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric)
- && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
- && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
- && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
- && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
- && equalsHandlesNulls(mNetworkId, s.mNetworkId)
- && equalsHandlesNulls(mSystemId, s.mSystemId)
- && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
- && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
- s.mCdmaDefaultRoamingIndicator)
- && mIsEmergencyOnly == s.mIsEmergencyOnly
- && equalsHandlesNulls(mOperatorAlphaLongRaw, s.mOperatorAlphaLongRaw)
- && equalsHandlesNulls(mOperatorAlphaShortRaw, s.mOperatorAlphaShortRaw)
- && (mNetworkRegistrationInfos == null
- ? s.mNetworkRegistrationInfos == null : s.mNetworkRegistrationInfos != null
- && mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos))
- && mNrFrequencyRange == s.mNrFrequencyRange;
+ synchronized (mNetworkRegistrationInfos) {
+ return mVoiceRegState == s.mVoiceRegState
+ && mDataRegState == s.mDataRegState
+ && mIsManualNetworkSelection == s.mIsManualNetworkSelection
+ && mChannelNumber == s.mChannelNumber
+ && Arrays.equals(mCellBandwidths, s.mCellBandwidths)
+ && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
+ && equalsHandlesNulls(mVoiceOperatorAlphaShort, s.mVoiceOperatorAlphaShort)
+ && equalsHandlesNulls(mVoiceOperatorNumeric, s.mVoiceOperatorNumeric)
+ && equalsHandlesNulls(mDataOperatorAlphaLong, s.mDataOperatorAlphaLong)
+ && equalsHandlesNulls(mDataOperatorAlphaShort, s.mDataOperatorAlphaShort)
+ && equalsHandlesNulls(mDataOperatorNumeric, s.mDataOperatorNumeric)
+ && equalsHandlesNulls(mCssIndicator, s.mCssIndicator)
+ && equalsHandlesNulls(mNetworkId, s.mNetworkId)
+ && equalsHandlesNulls(mSystemId, s.mSystemId)
+ && equalsHandlesNulls(mCdmaRoamingIndicator, s.mCdmaRoamingIndicator)
+ && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
+ s.mCdmaDefaultRoamingIndicator)
+ && mIsEmergencyOnly == s.mIsEmergencyOnly
+ && equalsHandlesNulls(mOperatorAlphaLongRaw, s.mOperatorAlphaLongRaw)
+ && equalsHandlesNulls(mOperatorAlphaShortRaw, s.mOperatorAlphaShortRaw)
+ && mNetworkRegistrationInfos.size() == s.mNetworkRegistrationInfos.size()
+ && mNetworkRegistrationInfos.containsAll(s.mNetworkRegistrationInfos)
+ && mNrFrequencyRange == s.mNrFrequencyRange;
+ }
}
/**
@@ -1005,36 +1013,38 @@
@Override
public String toString() {
- return new StringBuilder().append("{mVoiceRegState=").append(mVoiceRegState)
- .append("(" + rilServiceStateToString(mVoiceRegState) + ")")
- .append(", mDataRegState=").append(mDataRegState)
- .append("(" + rilServiceStateToString(mDataRegState) + ")")
- .append(", mChannelNumber=").append(mChannelNumber)
- .append(", duplexMode()=").append(getDuplexMode())
- .append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths))
- .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong)
- .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort)
- .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong)
- .append(", mDataOperatorAlphaShort=").append(mDataOperatorAlphaShort)
- .append(", isManualNetworkSelection=").append(mIsManualNetworkSelection)
- .append(mIsManualNetworkSelection ? "(manual)" : "(automatic)")
- .append(", getRilVoiceRadioTechnology=").append(getRilVoiceRadioTechnology())
- .append("(" + rilRadioTechnologyToString(getRilVoiceRadioTechnology()) + ")")
- .append(", getRilDataRadioTechnology=").append(getRilDataRadioTechnology())
- .append("(" + rilRadioTechnologyToString(getRilDataRadioTechnology()) + ")")
- .append(", mCssIndicator=").append(mCssIndicator ? "supported" : "unsupported")
- .append(", mNetworkId=").append(mNetworkId)
- .append(", mSystemId=").append(mSystemId)
- .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator)
- .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator)
- .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
- .append(", isUsingCarrierAggregation=").append(isUsingCarrierAggregation())
- .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
- .append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
- .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
- .append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw)
- .append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw)
- .append("}").toString();
+ synchronized (mNetworkRegistrationInfos) {
+ return new StringBuilder().append("{mVoiceRegState=").append(mVoiceRegState)
+ .append("(" + rilServiceStateToString(mVoiceRegState) + ")")
+ .append(", mDataRegState=").append(mDataRegState)
+ .append("(" + rilServiceStateToString(mDataRegState) + ")")
+ .append(", mChannelNumber=").append(mChannelNumber)
+ .append(", duplexMode()=").append(getDuplexMode())
+ .append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths))
+ .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong)
+ .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort)
+ .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong)
+ .append(", mDataOperatorAlphaShort=").append(mDataOperatorAlphaShort)
+ .append(", isManualNetworkSelection=").append(mIsManualNetworkSelection)
+ .append(mIsManualNetworkSelection ? "(manual)" : "(automatic)")
+ .append(", getRilVoiceRadioTechnology=").append(getRilVoiceRadioTechnology())
+ .append("(" + rilRadioTechnologyToString(getRilVoiceRadioTechnology()) + ")")
+ .append(", getRilDataRadioTechnology=").append(getRilDataRadioTechnology())
+ .append("(" + rilRadioTechnologyToString(getRilDataRadioTechnology()) + ")")
+ .append(", mCssIndicator=").append(mCssIndicator ? "supported" : "unsupported")
+ .append(", mNetworkId=").append(mNetworkId)
+ .append(", mSystemId=").append(mSystemId)
+ .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator)
+ .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator)
+ .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
+ .append(", isUsingCarrierAggregation=").append(isUsingCarrierAggregation())
+ .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
+ .append(", mNetworkRegistrationInfos=").append(mNetworkRegistrationInfos)
+ .append(", mNrFrequencyRange=").append(mNrFrequencyRange)
+ .append(", mOperatorAlphaLongRaw=").append(mOperatorAlphaLongRaw)
+ .append(", mOperatorAlphaShortRaw=").append(mOperatorAlphaShortRaw)
+ .append("}").toString();
+ }
}
private void init() {
@@ -1060,17 +1070,19 @@
mIsEmergencyOnly = false;
mLteEarfcnRsrpBoost = 0;
mNrFrequencyRange = FREQUENCY_RANGE_UNKNOWN;
- mNetworkRegistrationInfos.clear();
- addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
- .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
- .build());
- addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
- .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
- .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
- .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
- .build());
+ synchronized (mNetworkRegistrationInfos) {
+ mNetworkRegistrationInfos.clear();
+ addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
+ .build());
+ addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
+ .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
+ .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+ .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN)
+ .build());
+ }
mOperatorAlphaLongRaw = null;
mOperatorAlphaShortRaw = null;
}
@@ -1913,10 +1925,13 @@
*/
public ServiceState sanitizeLocationInfo(boolean removeCoarseLocation) {
ServiceState state = new ServiceState(this);
- if (state.mNetworkRegistrationInfos != null) {
- state.mNetworkRegistrationInfos = state.mNetworkRegistrationInfos.stream()
- .map(NetworkRegistrationInfo::sanitizeLocationInfo)
- .collect(Collectors.toList());
+ synchronized (state.mNetworkRegistrationInfos) {
+ List<NetworkRegistrationInfo> networkRegistrationInfos =
+ state.mNetworkRegistrationInfos.stream()
+ .map(NetworkRegistrationInfo::sanitizeLocationInfo)
+ .collect(Collectors.toList());
+ state.mNetworkRegistrationInfos.clear();
+ state.mNetworkRegistrationInfos.addAll(networkRegistrationInfos);
}
if (!removeCoarseLocation) return state;
diff --git a/tools/aapt/SdkConstants.h b/tools/aapt/SdkConstants.h
index c1fcf5c..27ffcdf 100644
--- a/tools/aapt/SdkConstants.h
+++ b/tools/aapt/SdkConstants.h
@@ -44,6 +44,7 @@
SDK_O = 26,
SDK_O_MR1 = 27,
SDK_P = 28,
+ SDK_Q = 29,
};
#endif // H_AAPT_SDK_CONSTANTS
diff --git a/tools/aapt2/SdkConstants.h b/tools/aapt2/SdkConstants.h
index adb034a..a00d978 100644
--- a/tools/aapt2/SdkConstants.h
+++ b/tools/aapt2/SdkConstants.h
@@ -54,6 +54,7 @@
SDK_O = 26,
SDK_O_MR1 = 27,
SDK_P = 28,
+ SDK_Q = 29,
};
ApiVersion FindAttributeSdkLevel(const ResourceId& id);
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index f191f6c..6683e2a 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -490,11 +490,6 @@
def flag_sequence(territory_code):
return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
-UNSUPPORTED_FLAGS = frozenset({
- flag_sequence('BL'), flag_sequence('BQ'), flag_sequence('MQ'),
- flag_sequence('RE'), flag_sequence('TF'),
-})
-
EQUIVALENT_FLAGS = {
flag_sequence('BV'): flag_sequence('NO'),
flag_sequence('CP'): flag_sequence('FR'),
@@ -600,9 +595,6 @@
for first, second in SAME_FLAG_MAPPINGS:
equivalent_emoji[first] = second
- # Remove unsupported flags
- all_sequences.difference_update(UNSUPPORTED_FLAGS)
-
# Add all tag characters used in flags
sequence_pieces.update(range(0xE0030, 0xE0039 + 1))
sequence_pieces.update(range(0xE0061, 0xE007A + 1))