Merge "Remove dead code"
diff --git a/Android.bp b/Android.bp
index 2de1a6c..77a273c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -766,6 +766,24 @@
dxflags: ["--core-library"],
}
+// ==== java proto host library ==============================
+java_library_host {
+ name: "platformprotos",
+ srcs: [
+ "cmds/am/proto/instrumentation_data.proto",
+ "core/proto/**/*.proto",
+ "libs/incident/proto/**/*.proto",
+ "cmds/statsd/src/**/*.proto",
+ ],
+ proto: {
+ include_dirs: ["external/protobuf/src"],
+ type: "full",
+ },
+ errorprone: {
+ javacflags: ["-Xep:MissingOverride:OFF"], // b/72714520
+ },
+}
+
// ==== c++ proto device library ==============================
cc_library {
name: "libplatformprotos",
diff --git a/Android.mk b/Android.mk
index c68eb46..031809c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -670,23 +670,6 @@
include $(BUILD_DROIDDOC)
-# ==== java proto host library ==============================
-include $(CLEAR_VARS)
-LOCAL_MODULE := platformprotos
-LOCAL_PROTOC_OPTIMIZE_TYPE := full
-LOCAL_PROTOC_FLAGS := \
- -Iexternal/protobuf/src
-LOCAL_SOURCE_FILES_ALL_GENERATED := true
-LOCAL_SRC_FILES := \
- cmds/am/proto/instrumentation_data.proto \
- cmds/statsd/src/perfetto/perfetto_config.proto \
- $(call all-proto-files-under, core/proto) \
- $(call all-proto-files-under, libs/incident/proto) \
- $(call all-proto-files-under, cmds/statsd/src)
-# b/72714520
-LOCAL_ERROR_PRONE_FLAGS := -Xep:MissingOverride:OFF
-include $(BUILD_HOST_JAVA_LIBRARY)
-
# ==== java proto device library (for test only) ==============================
include $(CLEAR_VARS)
LOCAL_MODULE := platformprotosnano
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 2e949c5..9e172e7 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -244,6 +244,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/core/java/android/os/storage/*)
$(call add-clean-step, rm -rf $(OUT_DIR)/host/common/obj/JAVA_LIBRARIES/platformprotos_intermediates)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/statsdprotolite_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 9d8db31..7787c1bfc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -70142,7 +70142,7 @@
method public java.util.regex.Matcher reset();
method public java.util.regex.Matcher reset(java.lang.CharSequence);
method public int start();
- method public int start(int) throws java.lang.IllegalStateException;
+ method public int start(int);
method public int start(java.lang.String);
method public java.util.regex.MatchResult toMatchResult();
method public java.util.regex.Matcher useAnchoringBounds(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index 1b7ec9b..6850f8f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -538,6 +538,7 @@
method public long getAvailableRestoreToken(java.lang.String);
method public android.content.Intent getConfigurationIntent(java.lang.String);
method public java.lang.String getCurrentTransport();
+ method public android.content.ComponentName getCurrentTransportComponent();
method public android.content.Intent getDataManagementIntent(java.lang.String);
method public java.lang.String getDataManagementLabel(java.lang.String);
method public java.lang.String getDestinationString(java.lang.String);
diff --git a/api/test-current.txt b/api/test-current.txt
index 54604a5..79a8d44 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -244,6 +244,7 @@
package android.content.pm {
public class ActivityInfo extends android.content.pm.ComponentInfo implements android.os.Parcelable {
+ method public static boolean isTranslucentOrFloating(android.content.res.TypedArray);
field public static final int RESIZE_MODE_RESIZEABLE = 2; // 0x2
}
diff --git a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
index 37b7acf..8683ca1 100644
--- a/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
+++ b/cmds/requestsync/src/com/android/commands/requestsync/RequestSync.java
@@ -211,10 +211,10 @@
mExtras.putBoolean(key, Boolean.valueOf(value));
} else if (opt.equals("-f") || opt.equals("--foreground")) {
- mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE;
+ mExemptionFlag = ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET;
} else if (opt.equals("-F") || opt.equals("--top")) {
- mExemptionFlag = ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP;
+ mExemptionFlag = ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP;
} else {
System.err.println("Error: Unknown option: " + opt);
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 3172281..b11e843 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -182,8 +182,7 @@
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
if (display == NULL) {
fprintf(stderr, "Unable to get handle for display %d\n", displayId);
- // b/36066697: Avoid running static destructors.
- _exit(1);
+ return 1;
}
Vector<DisplayInfo> configs;
@@ -192,8 +191,7 @@
if (static_cast<size_t>(activeConfig) >= configs.size()) {
fprintf(stderr, "Active config %d not inside configs (size %zu)\n",
activeConfig, configs.size());
- // b/36066697: Avoid running static destructors.
- _exit(1);
+ return 1;
}
uint8_t displayOrientation = configs[activeConfig].orientation;
uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
@@ -204,14 +202,14 @@
&outBuffer);
if (result != NO_ERROR) {
close(fd);
- _exit(1);
+ return 1;
}
result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
if (base == NULL) {
close(fd);
- _exit(1);
+ return 1;
}
w = outBuffer->getWidth();
@@ -256,6 +254,5 @@
munmap((void *)mapbase, mapsize);
}
- // b/36066697: Avoid running static destructors.
- _exit(0);
+ return 0;
}
\ No newline at end of file
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 091268e..5268ba2 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -141,10 +141,14 @@
LOCAL_MODULE_CLASS := EXECUTABLES
-# Enable sanitizer and allow very verbose printing on eng builds
+# Enable sanitizer ONLY on eng builds.
ifeq ($(TARGET_BUILD_VARIANT),eng)
LOCAL_CLANG := true
LOCAL_SANITIZE := address
+endif
+
+# Add a flag to enable stats log printing from statsd on debug builds.
+ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += \
-DVERY_VERBOSE_PRINTING
endif
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index e7f1caf..1378ce5 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -152,7 +152,7 @@
if (is_create) {
mUidMap->assignIsolatedUid(isolated_uid, parent_uid);
} else {
- mUidMap->removeIsolatedUid(isolated_uid, parent_uid);
+ mUidMap->removeIsolatedUid(isolated_uid);
}
} else {
ALOGE("Failed to parse uid in the isolated uid change event.");
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index ab9c7e8..ca3786a 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -1484,6 +1484,7 @@
message IsolatedUidChanged {
// The host UID. Generally, we should attribute metrics from the isolated uid to the host uid.
// NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
+ // This field is ignored when event == REMOVED.
optional int32 parent_uid = 1;
optional int32 isolated_uid = 2;
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index fff909c..be94725 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -272,7 +272,7 @@
mIsolatedUidMap[isolatedUid] = parentUid;
}
-void UidMap::removeIsolatedUid(int isolatedUid, int parentUid) {
+void UidMap::removeIsolatedUid(int isolatedUid) {
lock_guard<mutex> lock(mIsolatedMutex);
auto it = mIsolatedUidMap.find(isolatedUid);
diff --git a/cmds/statsd/src/packages/UidMap.h b/cmds/statsd/src/packages/UidMap.h
index 5e42cd1..514eec7 100644
--- a/cmds/statsd/src/packages/UidMap.h
+++ b/cmds/statsd/src/packages/UidMap.h
@@ -119,7 +119,7 @@
void OnConfigRemoved(const ConfigKey& key);
void assignIsolatedUid(int isolatedUid, int parentUid);
- void removeIsolatedUid(int isolatedUid, int parentUid);
+ void removeIsolatedUid(int isolatedUid);
// Returns the host uid if it exists. Otherwise, returns the same uid that was passed-in.
virtual int getHostUidOrSelf(int uid) const;
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index 218d52a..79bed52 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -305,10 +305,10 @@
EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyB), 2LL);
EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 16, bucket16, {keyB}, {keyA, keyC, keyD}));
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
detectAndDeclareAnomalies(anomalyTracker, 16, bucket16, eventTimestamp2);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 15L);
checkRefractoryTimes(anomalyTracker, eventTimestamp2, refractoryPeriodSec,
{{keyA, -1}, {keyB, eventTimestamp2}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
@@ -366,7 +366,7 @@
EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyC), 1LL);
EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 25, bucket25, {}, {keyA, keyB, keyC, keyD}));
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 24L);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
detectAndDeclareAnomalies(anomalyTracker, 25, bucket25, eventTimestamp5);
checkRefractoryTimes(anomalyTracker, eventTimestamp5, refractoryPeriodSec,
{{keyA, -1}, {keyB, eventTimestamp4}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
@@ -374,14 +374,14 @@
// Add past bucket #25
anomalyTracker.addPastBucket(bucket25, 25);
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 25L);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 1UL);
EXPECT_EQ(anomalyTracker.getSumOverPastBuckets(keyD), 1LL);
EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {},
{keyA, keyB, keyC, keyD, keyE}));
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
{{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, -1}});
@@ -390,9 +390,9 @@
EXPECT_TRUE(detectAnomaliesPass(anomalyTracker, 28, bucket28, {keyE},
{keyA, keyB, keyC, keyD}));
EXPECT_EQ(anomalyTracker.mMostRecentBucketNum, 27L);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
detectAndDeclareAnomalies(anomalyTracker, 28, bucket28, eventTimestamp6 + 7);
- // TODO: after detectAnomaly fix: EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
+ EXPECT_EQ(anomalyTracker.mSumOverPastBuckets.size(), 0UL);
checkRefractoryTimes(anomalyTracker, eventTimestamp6, refractoryPeriodSec,
{{keyA, -1}, {keyB, -1}, {keyC, -1}, {keyD, -1}, {keyE, eventTimestamp6 + 7}});
}
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 8db7de3..67d60fa 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -261,6 +261,7 @@
Landroid/app/ActivityThread;->mPackages:Landroid/util/ArrayMap;
Landroid/app/ActivityThread;->mPendingConfiguration:Landroid/content/res/Configuration;
Landroid/app/ActivityThread;->mProviderMap:Landroid/util/ArrayMap;
+Landroid/app/ActivityThread;->mProviderRefCountMap:Landroid/util/ArrayMap;
Landroid/app/ActivityThread;->mResourcePackages:Landroid/util/ArrayMap;
Landroid/app/ActivityThread;->mResourcesManager:Landroid/app/ResourcesManager;
Landroid/app/ActivityThread;->mServices:Landroid/util/ArrayMap;
@@ -737,6 +738,7 @@
Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
Landroid/app/IWallpaperManager;->getWallpaperInfo(I)Landroid/app/WallpaperInfo;
Landroid/app/IWallpaperManager;->getWidthHint()I
+Landroid/app/IWallpaperManager;->hasNamedWallpaper(Ljava/lang/String;)Z
Landroid/app/IWallpaperManager;->setWallpaperComponent(Landroid/content/ComponentName;)V
Landroid/app/IWallpaperManagerCallback$Stub;-><init>()V
Landroid/app/IWallpaperManagerCallback;->onWallpaperChanged()V
@@ -905,9 +907,14 @@
Landroid/app/SearchManager;->launchAssist(Landroid/os/Bundle;)V
Landroid/app/SearchManager;->mSearchDialog:Landroid/app/SearchDialog;
Landroid/app/SearchManager;->startSearch(Ljava/lang/String;ZLandroid/content/ComponentName;Landroid/os/Bundle;ZLandroid/graphics/Rect;)V
+Landroid/app/servertransaction/ActivityResultItem;->mResultInfoList:Ljava/util/List;
+Landroid/app/servertransaction/ClientTransaction;->getActivityToken()Landroid/os/IBinder;
+Landroid/app/servertransaction/ClientTransaction;->getCallbacks()Ljava/util/List;
+Landroid/app/servertransaction/ClientTransaction;->getLifecycleStateRequest()Landroid/app/servertransaction/ActivityLifecycleItem;
Landroid/app/servertransaction/ClientTransaction;->mActivityCallbacks:Ljava/util/List;
Landroid/app/servertransaction/LaunchActivityItem;->mInfo:Landroid/content/pm/ActivityInfo;
Landroid/app/servertransaction/LaunchActivityItem;->mIntent:Landroid/content/Intent;
+Landroid/app/servertransaction/NewIntentItem;->mIntents:Ljava/util/List;
Landroid/app/Service;->attach(Landroid/content/Context;Landroid/app/ActivityThread;Ljava/lang/String;Landroid/os/IBinder;Landroid/app/Application;Ljava/lang/Object;)V
Landroid/app/Service;->mActivityManager:Landroid/app/IActivityManager;
Landroid/app/Service;->mApplication:Landroid/app/Application;
@@ -919,6 +926,7 @@
Landroid/app/ServiceConnectionLeaked;-><init>(Ljava/lang/String;)V
Landroid/app/SharedPreferencesImpl;-><init>(Ljava/io/File;I)V
Landroid/app/SharedPreferencesImpl;->mFile:Ljava/io/File;
+Landroid/app/SharedPreferencesImpl;->startLoadFromDisk()V
Landroid/app/SharedPreferencesImpl;->startReloadIfChangedUnexpectedly()V
Landroid/app/StatusBarManager;-><init>(Landroid/content/Context;)V
Landroid/app/StatusBarManager;->collapsePanels()V
@@ -1691,6 +1699,12 @@
Landroid/content/pm/PackageParser$ProviderIntentInfo;->provider:Landroid/content/pm/PackageParser$Provider;
Landroid/content/pm/PackageParser$Service;->info:Landroid/content/pm/ServiceInfo;
Landroid/content/pm/PackageParser$ServiceIntentInfo;->service:Landroid/content/pm/PackageParser$Service;
+Landroid/content/pm/PackageParser$SigningDetails$Builder;-><init>()V
+Landroid/content/pm/PackageParser$SigningDetails$Builder;->build()Landroid/content/pm/PackageParser$SigningDetails;
+Landroid/content/pm/PackageParser$SigningDetails$Builder;->setPastSigningCertificates([Landroid/content/pm/Signature;)Landroid/content/pm/PackageParser$SigningDetails$Builder;
+Landroid/content/pm/PackageParser$SigningDetails$Builder;->setPastSigningCertificatesFlags([I)Landroid/content/pm/PackageParser$SigningDetails$Builder;
+Landroid/content/pm/PackageParser$SigningDetails$Builder;->setSignatures([Landroid/content/pm/Signature;)Landroid/content/pm/PackageParser$SigningDetails$Builder;
+Landroid/content/pm/PackageParser$SigningDetails$Builder;->setSignatureSchemeVersion(I)Landroid/content/pm/PackageParser$SigningDetails$Builder;
Landroid/content/pm/PackageParser$SigningDetails;->signatures:[Landroid/content/pm/Signature;
Landroid/content/pm/PackageParser;-><init>()V
Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Ljava/io/File;Z)V
@@ -2199,6 +2213,8 @@
Landroid/graphics/FontFamily;->addFontFromAssetManager(Landroid/content/res/AssetManager;Ljava/lang/String;IZIII[Landroid/graphics/fonts/FontVariationAxis;)Z
Landroid/graphics/FontFamily;->addFontFromBuffer(Ljava/nio/ByteBuffer;I[Landroid/graphics/fonts/FontVariationAxis;II)Z
Landroid/graphics/FontFamily;->freeze()Z
+Landroid/graphics/FontFamily;->mNativePtr:J
+Landroid/graphics/FontListParser;->parse(Ljava/io/InputStream;)Landroid/text/FontConfig;
Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
Landroid/graphics/fonts/FontVariationAxis;->mTag:I
Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
@@ -2336,6 +2352,7 @@
Landroid/hardware/camera2/CameraCharacteristics;->LED_AVAILABLE_LEDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
Landroid/hardware/camera2/CameraCharacteristics;->LENS_INFO_SHADING_MAP_SIZE:Landroid/hardware/camera2/CameraCharacteristics$Key;
Landroid/hardware/camera2/CameraCharacteristics;->LOGICAL_MULTI_CAMERA_PHYSICAL_IDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
+Landroid/hardware/camera2/CameraCharacteristics;->mProperties:Landroid/hardware/camera2/impl/CameraMetadataNative;
Landroid/hardware/camera2/CameraCharacteristics;->QUIRKS_USE_PARTIAL_RESULT:Landroid/hardware/camera2/CameraCharacteristics$Key;
Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_CHARACTERISTICS_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
@@ -2392,6 +2409,9 @@
Landroid/hardware/camera2/CaptureResult;->TONEMAP_CURVE_RED:Landroid/hardware/camera2/CaptureResult$Key;
Landroid/hardware/camera2/impl/CameraMetadataNative$Key;->getTag()I
Landroid/hardware/camera2/impl/CameraMetadataNative;->mMetadataPtr:J
+Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeGetTagFromKeyLocal(Ljava/lang/String;)I
+Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeGetTypeFromTagLocal(I)I
+Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeReadValues(I)[B
Landroid/hardware/camera2/utils/SurfaceUtils;->getSurfaceSize(Landroid/view/Surface;)Landroid/util/Size;
Landroid/hardware/camera2/utils/TypeReference;-><init>()V
Landroid/hardware/camera2/utils/TypeReference;->createSpecializedTypeReference(Ljava/lang/reflect/Type;)Landroid/hardware/camera2/utils/TypeReference;
@@ -3738,6 +3758,7 @@
Landroid/os/BatteryStats$Timer;-><init>()V
Landroid/os/BatteryStats$Timer;->getTotalTimeLocked(JI)J
Landroid/os/BatteryStats$Uid$Pkg$Serv;->getLaunches(I)I
+Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStarts(I)I
Landroid/os/BatteryStats$Uid$Pkg$Serv;->getStartTime(JI)J
Landroid/os/BatteryStats$Uid$Pkg;-><init>()V
Landroid/os/BatteryStats$Uid$Pkg;->getServiceStats()Landroid/util/ArrayMap;
@@ -3772,12 +3793,20 @@
Landroid/os/BatteryStats$Uid;->getWifiMulticastTime(JI)J
Landroid/os/BatteryStats$Uid;->getWifiScanTime(JI)J
Landroid/os/BatteryStats;-><init>()V
+Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J
Landroid/os/BatteryStats;->computeBatteryTimeRemaining(J)J
Landroid/os/BatteryStats;->computeBatteryUptime(JI)J
Landroid/os/BatteryStats;->computeChargeTimeRemaining(J)J
+Landroid/os/BatteryStats;->getBatteryUptime(J)J
+Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J
Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J
Landroid/os/BatteryStats;->getNetworkActivityBytes(II)J
+Landroid/os/BatteryStats;->getPhoneOnTime(JI)J
+Landroid/os/BatteryStats;->getPhoneSignalStrengthTime(IJI)J
+Landroid/os/BatteryStats;->getScreenBrightnessTime(IJI)J
+Landroid/os/BatteryStats;->getScreenOnTime(JI)J
Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
+Landroid/os/BatteryStats;->getWifiOnTime(JI)J
Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
Landroid/os/BatteryStats;->NUM_SCREEN_BRIGHTNESS_BINS:I
Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z
@@ -5060,6 +5089,7 @@
Landroid/service/wallpaper/WallpaperService$Engine;->mPendingXOffset:F
Landroid/service/wallpaper/WallpaperService$Engine;->setFixedSizeAllowed(Z)V
Landroid/service/wallpaper/WallpaperService;->MSG_WINDOW_RESIZED:I
+Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V
Landroid/speech/tts/TextToSpeech;->getCurrentEngine()Ljava/lang/String;
Landroid/speech/tts/TextToSpeech;->mConnectingServiceConnection:Landroid/speech/tts/TextToSpeech$Connection;
Landroid/speech/tts/TextToSpeech;->mCurrentEngine:Ljava/lang/String;
@@ -5235,6 +5265,7 @@
Landroid/telephony/PhoneNumberUtils;->MIN_MATCH:I
Landroid/telephony/PhoneNumberUtils;->ttsSpanAsPhoneNumber(Ljava/lang/CharSequence;)Ljava/lang/CharSequence;
Landroid/telephony/PhoneStateListener;-><init>(Landroid/os/Looper;)V
+Landroid/telephony/PhoneStateListener;->callback:Lcom/android/internal/telephony/IPhoneStateListener;
Landroid/telephony/PhoneStateListener;->LISTEN_PRECISE_CALL_STATE:I
Landroid/telephony/PhoneStateListener;->mSubId:Ljava/lang/Integer;
Landroid/telephony/PhoneStateListener;->onDataConnectionRealTimeInfoChanged(Landroid/telephony/DataConnectionRealTimeInfo;)V
@@ -5376,6 +5407,7 @@
Landroid/telephony/SmsMessage;->setSubId(I)V
Landroid/telephony/SmsMessage;->useCdmaFormatForMoSms()Z
Landroid/telephony/SmsMessage;->useCdmaFormatForMoSms(I)Z
+Landroid/telephony/SubscriptionInfo;->getNameSource()I
Landroid/telephony/SubscriptionManager;-><init>(Landroid/content/Context;)V
Landroid/telephony/SubscriptionManager;->CONTENT_URI:Landroid/net/Uri;
Landroid/telephony/SubscriptionManager;->DEFAULT_SUBSCRIPTION_ID:I
@@ -5410,6 +5442,8 @@
Landroid/telephony/TelephonyManager;->getDeviceSoftwareVersion(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getGroupIdLevel1(I)Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getIccAuthentication(IIILjava/lang/String;)Ljava/lang/String;
+Landroid/telephony/TelephonyManager;->getImsConfig(II)Landroid/telephony/ims/aidl/IImsConfig;
+Landroid/telephony/TelephonyManager;->getImsRegistration(II)Landroid/telephony/ims/aidl/IImsRegistration;
Landroid/telephony/TelephonyManager;->getIsimImpi()Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getIsimImpu()[Ljava/lang/String;
Landroid/telephony/TelephonyManager;->getIsimPcscf()[Ljava/lang/String;
@@ -5492,6 +5526,14 @@
Landroid/text/DynamicLayout;->getNumberOfBlocks()I
Landroid/text/DynamicLayout;->setIndexFirstChangedBlock(I)V
Landroid/text/DynamicLayout;->sStaticLayout:Landroid/text/StaticLayout;
+Landroid/text/FontConfig$Family;->getFonts()[Landroid/text/FontConfig$Font;
+Landroid/text/FontConfig$Family;->getName()Ljava/lang/String;
+Landroid/text/FontConfig$Family;->getVariant()I
+Landroid/text/FontConfig$Font;->getAxes()[Landroid/graphics/fonts/FontVariationAxis;
+Landroid/text/FontConfig$Font;->getTtcIndex()I
+Landroid/text/FontConfig$Font;->getWeight()I
+Landroid/text/FontConfig$Font;->isItalic()Z
+Landroid/text/FontConfig;->getFamilies()[Landroid/text/FontConfig$Family;
Landroid/text/format/DateFormat;->getTimeFormatString(Landroid/content/Context;)Ljava/lang/String;
Landroid/text/format/DateFormat;->getTimeFormatString(Landroid/content/Context;I)Ljava/lang/String;
Landroid/text/format/DateFormat;->hasDesignator(Ljava/lang/CharSequence;C)Z
@@ -5790,6 +5832,7 @@
Landroid/view/animation/TranslateAnimation;->mToYValue:F
Landroid/view/animation/TranslateYAnimation;-><init>(IFIF)V
Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V
Landroid/view/Choreographer$CallbackRecord;->run(J)V
Landroid/view/Choreographer;->doFrame(JI)V
@@ -7354,6 +7397,7 @@
Lcom/android/internal/app/AlertController;->setMessage(Ljava/lang/CharSequence;)V
Lcom/android/internal/app/AlertController;->setTitle(Ljava/lang/CharSequence;)V
Lcom/android/internal/app/AlertController;->setView(Landroid/view/View;)V
+Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->setMode(IILjava/lang/String;I)V
@@ -8128,6 +8172,7 @@
Lcom/android/internal/telephony/ISms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ISms;
Lcom/android/internal/telephony/ISub$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/ISub$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ISub;
+Lcom/android/internal/telephony/ISub;->getActiveSubIdList()[I
Lcom/android/internal/telephony/ISub;->getDefaultDataSubId()I
Lcom/android/internal/telephony/ISub;->getDefaultSubId()I
Lcom/android/internal/telephony/ISub;->setDefaultDataSubId(I)V
@@ -8950,6 +8995,20 @@
Lorg/apache/http/conn/ssl/SSLSocketFactory;->sslcontext:Ljavax/net/ssl/SSLContext;
Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
+Lorg/ccil/cowan/tagsoup/ElementType;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
+Lorg/ccil/cowan/tagsoup/ElementType;->theFlags:I
+Lorg/ccil/cowan/tagsoup/ElementType;->theLocalName:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/ElementType;->theMemberOf:I
+Lorg/ccil/cowan/tagsoup/ElementType;->theModel:I
+Lorg/ccil/cowan/tagsoup/ElementType;->theName:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType;
+Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
+Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap;
+Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap;
+Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Schema;->theRoot:Lorg/ccil/cowan/tagsoup/ElementType;
+Lorg/ccil/cowan/tagsoup/Schema;->theURI:Ljava/lang/String;
Lorg/json/JSONArray;->values:Ljava/util/List;
Lorg/json/JSONArray;->writeTo(Lorg/json/JSONStringer;)V
Lorg/json/JSONObject;->append(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
@@ -8983,6 +9042,10 @@
Lorg/w3c/dom/traversal/NodeFilter;->acceptNode(Lorg/w3c/dom/Node;)S
Lorg/w3c/dom/traversal/NodeIterator;->detach()V
Lorg/w3c/dom/traversal/NodeIterator;->nextNode()Lorg/w3c/dom/Node;
+Lorg/xml/sax/ext/Attributes2Impl;->declared:[Z
+Lorg/xml/sax/ext/Attributes2Impl;->specified:[Z
+Lorg/xml/sax/ext/Locator2Impl;->encoding:Ljava/lang/String;
+Lorg/xml/sax/ext/Locator2Impl;->version:Ljava/lang/String;
Lorg/xml/sax/helpers/AttributesImpl;->badIndex(I)V
Lorg/xml/sax/helpers/AttributesImpl;->data:[Ljava/lang/String;
Lorg/xml/sax/helpers/AttributesImpl;->ensureCapacity(I)V
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 494ea39..37bf21a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -939,7 +939,8 @@
}
public void setHttpProxy(String host, String port, String exclList, Uri pacFileUrl) {
- final ConnectivityManager cm = ConnectivityManager.from(getSystemContext());
+ final ConnectivityManager cm = ConnectivityManager.from(
+ getApplication() != null ? getApplication() : getSystemContext());
final Network network = cm.getBoundNetworkForProcess();
if (network != null) {
Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 7ddf006..973ca12 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1557,6 +1557,7 @@
private final long[] mRejectTimes;
private final int mDuration;
private final int mProxyUid;
+ private final boolean mRunning;
private final String mProxyPackageName;
public OpEntry(int op, int mode, long time, long rejectTime, int duration,
@@ -1568,12 +1569,13 @@
mTimes[0] = time;
mRejectTimes[0] = rejectTime;
mDuration = duration;
+ mRunning = duration == -1;
mProxyUid = proxyUid;
mProxyPackageName = proxyPackage;
}
public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
- int proxyUid, String proxyPackage) {
+ boolean running, int proxyUid, String proxyPackage) {
mOp = op;
mMode = mode;
mTimes = new long[_NUM_UID_STATE];
@@ -1581,10 +1583,16 @@
System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
mDuration = duration;
+ mRunning = running;
mProxyUid = proxyUid;
mProxyPackageName = proxyPackage;
}
+ public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
+ int proxyUid, String proxyPackage) {
+ this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage);
+ }
+
public int getOp() {
return mOp;
}
@@ -1634,7 +1642,7 @@
}
public boolean isRunning() {
- return mDuration == -1;
+ return mRunning;
}
public int getDuration() {
@@ -1661,6 +1669,7 @@
dest.writeLongArray(mTimes);
dest.writeLongArray(mRejectTimes);
dest.writeInt(mDuration);
+ dest.writeBoolean(mRunning);
dest.writeInt(mProxyUid);
dest.writeString(mProxyPackageName);
}
@@ -1671,6 +1680,7 @@
mTimes = source.createLongArray();
mRejectTimes = source.createLongArray();
mDuration = source.readInt();
+ mRunning = source.readBoolean();
mProxyUid = source.readInt();
mProxyPackageName = source.readString();
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c2ac923..d2338f8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6603,22 +6603,33 @@
* Helper class for generating large-format notifications that include multiple back-and-forth
* messages of varying types between any number of people.
*
- * <br>
+ * <p>
* If the platform does not provide large-format notifications, this method has no effect. The
* user will always see the normal notification view.
- * <br>
- * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior, like
- * so:
+ *
+ * <p>
+ * If the app is targeting Android P and above, it is required to use the {@link Person}
+ * class in order to get an optimal rendering of the notification and its avatars. For
+ * conversations involving multiple people, the app should also make sure that it marks the
+ * conversation as a group with {@link #setGroupConversation(boolean)}.
+ *
+ * <p>
+ * This class is a "rebuilder": It attaches to a Builder object and modifies its behavior.
+ * Here's an example of how this may be used:
* <pre class="prettyprint">
*
+ * Person user = new Person.Builder().setIcon(userIcon).setName(userName).build();
+ * MessagingStyle style = new MessagingStyle(user)
+ * .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getPerson())
+ * .addMessage(messages[2].getText(), messages[2].getTime(), messages[2].getPerson())
+ * .setGroupConversation(hasMultiplePeople());
+ *
* Notification noti = new Notification.Builder()
- * .setContentTitle("2 new messages wtih " + sender.toString())
+ * .setContentTitle("2 new messages with " + sender.toString())
* .setContentText(subject)
* .setSmallIcon(R.drawable.new_message)
* .setLargeIcon(aBitmap)
- * .setStyle(new Notification.MessagingStyle(resources.getString(R.string.reply_name))
- * .addMessage(messages[0].getText(), messages[0].getTime(), messages[0].getSender())
- * .addMessage(messages[1].getText(), messages[1].getTime(), messages[1].getSender()))
+ * .setStyle(style)
* .build();
* </pre>
*/
@@ -6828,7 +6839,9 @@
}
/**
- * Sets whether this conversation notification represents a group.
+ * Sets whether this conversation notification represents a group. If the app is targeting
+ * Android P, this is required if the app wants to display the largeIcon set with
+ * {@link Notification.Builder#setLargeIcon(Bitmap)}, otherwise it will be hidden.
*
* @param isGroupConversation {@code true} if the conversation represents a group,
* {@code false} otherwise.
@@ -7050,12 +7063,21 @@
CharSequence conversationTitle = !TextUtils.isEmpty(super.mBigContentTitle)
? super.mBigContentTitle
: mConversationTitle;
- boolean isOneToOne = TextUtils.isEmpty(conversationTitle);
+ boolean atLeastP = mBuilder.mContext.getApplicationInfo().targetSdkVersion
+ >= Build.VERSION_CODES.P;
+ boolean isOneToOne;
CharSequence nameReplacement = null;
- if (hasOnlyWhiteSpaceSenders()) {
- isOneToOne = true;
- nameReplacement = conversationTitle;
- conversationTitle = null;
+ Icon avatarReplacement = null;
+ if (!atLeastP) {
+ isOneToOne = TextUtils.isEmpty(conversationTitle);
+ avatarReplacement = mBuilder.mN.mLargeIcon;
+ if (hasOnlyWhiteSpaceSenders()) {
+ isOneToOne = true;
+ nameReplacement = conversationTitle;
+ conversationTitle = null;
+ }
+ } else {
+ isOneToOne = !isGroupConversation();
}
TemplateBindResult bindResult = new TemplateBindResult();
RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(
@@ -7078,8 +7100,8 @@
mBuilder.getSecondaryTextColor());
contentView.setBoolean(R.id.status_bar_latest_event_content, "setDisplayImagesAtEnd",
displayImagesAtEnd);
- contentView.setIcon(R.id.status_bar_latest_event_content, "setLargeIcon",
- mBuilder.mN.mLargeIcon);
+ contentView.setIcon(R.id.status_bar_latest_event_content, "setAvatarReplacement",
+ avatarReplacement);
contentView.setCharSequence(R.id.status_bar_latest_event_content, "setNameReplacement",
nameReplacement);
contentView.setBoolean(R.id.status_bar_latest_event_content, "setIsOneToOne",
diff --git a/core/java/android/app/WallpaperColors.java b/core/java/android/app/WallpaperColors.java
index 2d007ad..60e8a12 100644
--- a/core/java/android/app/WallpaperColors.java
+++ b/core/java/android/app/WallpaperColors.java
@@ -144,13 +144,6 @@
* @param bitmap Source where to extract from.
*/
public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap) {
- return fromBitmap(bitmap, false /* computeHints */);
- }
-
- /**
- * @hide
- */
- public static WallpaperColors fromBitmap(@NonNull Bitmap bitmap, boolean computeHints) {
if (bitmap == null) {
throw new IllegalArgumentException("Bitmap can't be null");
}
@@ -200,7 +193,7 @@
}
}
- int hints = computeHints ? calculateDarkHints(bitmap) : 0;
+ int hints = calculateDarkHints(bitmap);
if (shouldRecycle) {
bitmap.recycle();
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index b5186fb..e7ae32d 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -255,7 +255,7 @@
/**
* @deprecated Since Android P app can no longer request restoring of its backup.
*
- * <p>Restore the calling application from backup. The data will be restored from the
+ * Restore the calling application from backup. The data will be restored from the
* current backup dataset if the application has stored data there, or from
* the dataset used during the last full device setup operation if the current
* backup dataset has no matching data. If no backup data exists for this application
@@ -282,7 +282,7 @@
/**
* @deprecated Since Android P app can no longer request restoring of its backup.
*
- * <p>Restore the calling application from backup. The data will be restored from the
+ * Restore the calling application from backup. The data will be restored from the
* current backup dataset if the application has stored data there, or from
* the dataset used during the last full device setup operation if the current
* backup dataset has no matching data. If no backup data exists for this application
@@ -443,6 +443,27 @@
}
/**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BACKUP)
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ checkServiceBinder();
+ if (sService != null) {
+ try {
+ return sService.getCurrentTransportComponent();
+ } catch (RemoteException e) {
+ Log.e(TAG, "getCurrentTransportComponent() couldn't connect");
+ }
+ }
+ return null;
+ }
+
+ /**
* Request a list of all available backup transports' names.
*
* @hide
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index f3ca746..1c55d8a 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -244,8 +244,6 @@
* {@code null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}.
* @throws SecurityException If the UID of the calling process differs from the package UID of
* {@code transportComponent} or if the caller does NOT have BACKUP permission.
- *
- * @hide
*/
void updateTransportAttributes(in ComponentName transportComponent, in String name,
in Intent configurationIntent, in String currentDestinationString,
@@ -257,6 +255,13 @@
*/
String getCurrentTransport();
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered. Callers must
+ * hold the android.permission.BACKUP permission to use this method.
+ */
+ ComponentName getCurrentTransportComponent();
+
/**
* Request a list of all available backup transports' names. Callers must
* hold the android.permission.BACKUP permission to use this method.
@@ -296,8 +301,6 @@
* the transport's name that is returned by {@link BackupTransport#name()}.
* @param listener A listener object to get a callback on the transport being selected. It may
* be {@code null}.
- *
- * @hide
*/
void selectBackupTransportAsync(in ComponentName transport, ISelectBackupTransportCallback listener);
@@ -364,7 +367,6 @@
* @param result In the case of a full backup measure operation, the estimated
* total file size that would result from the operation. Unused in all other
* cases.
- * {@hide}
*/
void opComplete(int token, long result);
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index 5e75841..4c22c94 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -15,6 +15,8 @@
*/
package android.app.slice;
+import static android.app.slice.Slice.SUBTYPE_COLOR;
+
import android.annotation.NonNull;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -29,6 +31,7 @@
import android.content.pm.ProviderInfo;
import android.database.ContentObserver;
import android.database.Cursor;
+import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -39,6 +42,8 @@
import android.os.StrictMode.ThreadPolicy;
import android.util.ArraySet;
import android.util.Log;
+import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import java.util.ArrayList;
import java.util.Arrays;
@@ -472,12 +477,25 @@
}
Slice.Builder parent = new Slice.Builder(sliceUri);
Slice.Builder childAction = new Slice.Builder(parent)
+ .addIcon(Icon.createWithResource(context,
+ com.android.internal.R.drawable.ic_permission), null,
+ Collections.emptyList())
.addHints(Arrays.asList(Slice.HINT_TITLE, Slice.HINT_SHORTCUT))
.addAction(action, new Slice.Builder(parent).build(), null);
+ TypedValue tv = new TypedValue();
+ new ContextThemeWrapper(context, android.R.style.Theme_DeviceDefault_Light)
+ .getTheme().resolveAttribute(android.R.attr.colorAccent, tv, true);
+ int deviceDefaultAccent = tv.data;
+
parent.addSubSlice(new Slice.Builder(sliceUri.buildUpon().appendPath("permission").build())
+ .addIcon(Icon.createWithResource(context,
+ com.android.internal.R.drawable.ic_arrow_forward), null,
+ Collections.emptyList())
.addText(getPermissionString(context, callingPackage), null,
Collections.emptyList())
+ .addInt(deviceDefaultAccent, SUBTYPE_COLOR,
+ Collections.emptyList())
.addSubSlice(childAction.build(), null)
.build(), null);
return parent.addHints(Arrays.asList(Slice.HINT_PERMISSION_REQUEST)).build();
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index 503ca6c..3e90af3 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -399,16 +399,20 @@
* {@hide}
*/
public UsageEvents(Parcel in) {
- mEventCount = in.readInt();
- mIndex = in.readInt();
+ byte[] bytes = in.readBlob();
+ Parcel data = Parcel.obtain();
+ data.unmarshall(bytes, 0, bytes.length);
+ data.setDataPosition(0);
+ mEventCount = data.readInt();
+ mIndex = data.readInt();
if (mEventCount > 0) {
- mStringPool = in.createStringArray();
+ mStringPool = data.createStringArray();
- final int listByteLength = in.readInt();
- final int positionInParcel = in.readInt();
+ final int listByteLength = data.readInt();
+ final int positionInParcel = data.readInt();
mParcel = Parcel.obtain();
mParcel.setDataPosition(0);
- mParcel.appendFrom(in, in.dataPosition(), listByteLength);
+ mParcel.appendFrom(data, data.dataPosition(), listByteLength);
mParcel.setDataSize(mParcel.dataPosition());
mParcel.setDataPosition(positionInParcel);
}
@@ -586,10 +590,11 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mEventCount);
- dest.writeInt(mIndex);
+ Parcel data = Parcel.obtain();
+ data.writeInt(mEventCount);
+ data.writeInt(mIndex);
if (mEventCount > 0) {
- dest.writeStringArray(mStringPool);
+ data.writeStringArray(mStringPool);
if (mEventsToWrite != null) {
// Write out the events
@@ -604,31 +609,34 @@
final int listByteLength = p.dataPosition();
// Write the total length of the data.
- dest.writeInt(listByteLength);
+ data.writeInt(listByteLength);
// Write our current position into the data.
- dest.writeInt(0);
+ data.writeInt(0);
// Write the data.
- dest.appendFrom(p, 0, listByteLength);
+ data.appendFrom(p, 0, listByteLength);
} finally {
p.recycle();
}
} else if (mParcel != null) {
// Write the total length of the data.
- dest.writeInt(mParcel.dataSize());
+ data.writeInt(mParcel.dataSize());
// Write out current position into the data.
- dest.writeInt(mParcel.dataPosition());
+ data.writeInt(mParcel.dataPosition());
// Write the data.
- dest.appendFrom(mParcel, 0, mParcel.dataSize());
+ data.appendFrom(mParcel, 0, mParcel.dataSize());
} else {
throw new IllegalStateException(
"Either mParcel or mEventsToWrite must not be null");
}
}
+ // Data can be too large for a transact. Write the data as a Blob, which will be written to
+ // ashmem if too large.
+ dest.writeBlob(data.marshall());
}
public static final Creator<UsageEvents> CREATOR = new Creator<UsageEvents>() {
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 1b07784..72d209a 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -184,7 +184,11 @@
/** @hide */
public static final int REASON_SUB_USAGE_SLICE_PINNED_PRIV = 0x000A;
/** @hide */
- public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000B;
+ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE = 0x000B;
+ /** @hide */
+ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE = 0x000C;
+ /** @hide */
+ public static final int REASON_SUB_USAGE_EXEMPTED_SYNC_START = 0x000D;
/** @hide */
public static final int REASON_SUB_PREDICTED_RESTORED = 0x0001;
@@ -669,13 +673,19 @@
sb.append("-sa");
break;
case REASON_SUB_USAGE_SLICE_PINNED:
- sb.append("slp");
+ sb.append("-lp");
break;
case REASON_SUB_USAGE_SLICE_PINNED_PRIV:
- sb.append("slpp");
+ sb.append("-lv");
+ break;
+ case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE:
+ sb.append("-en");
+ break;
+ case REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE:
+ sb.append("-ed");
break;
case REASON_SUB_USAGE_EXEMPTED_SYNC_START:
- sb.append("es");
+ sb.append("-es");
break;
}
break;
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index b8628a4..1a656ab 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -245,7 +245,15 @@
int numDeferredJobs, long timeSinceLastJobRun);
/**
- * Report a sync that was scheduled by an active app is about to be executed.
+ * Report a sync is scheduled by a foreground app.
+ *
+ * @param packageName name of the package that owns the sync adapter.
+ * @param userId which user the app is associated with
+ */
+ public abstract void reportExemptedSyncScheduled(String packageName, @UserIdInt int userId);
+
+ /**
+ * Report a sync that was scheduled by a foreground app is about to be executed.
*
* @param packageName name of the package that owns the sync adapter.
* @param userId which user the app is associated with
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index f7908b6..32a6743 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -520,27 +520,36 @@
public static final int SYNC_EXEMPTION_NONE = 0;
/**
- * When executing a sync with this exemption, we'll put the target app in the ACTIVE bucket
- * for 10 minutes. This will allow the sync adapter to schedule/run further syncs and jobs.
+ * Exemption given to a sync request made by a foreground app (including
+ * PROCESS_STATE_IMPORTANT_FOREGROUND).
*
- * Note this will still *not* let RARE apps to run syncs, because they still won't get network
- * connection.
+ * At the schedule time, we promote the sync adapter app for a higher bucket:
+ * - If the device is not dozing (so the sync will start right away)
+ * promote to ACTIVE for 1 hour.
+ * - If the device is dozing (so the sync *won't* start right away),
+ * promote to WORKING_SET for 4 hours, so it'll get a higher chance to be started once the
+ * device comes out of doze.
+ * - When the sync actually starts, we promote the sync adapter app to ACTIVE for 10 minutes,
+ * so it can schedule and start more syncs without getting throttled, even when the first
+ * operation was canceled and now we're retrying.
+ *
+ *
* @hide
*/
- public static final int SYNC_EXEMPTION_ACTIVE = 1;
+ public static final int SYNC_EXEMPTION_PROMOTE_BUCKET = 1;
/**
- * In addition to {@link #SYNC_EXEMPTION_ACTIVE}, we put the sync adapter app in the
+ * In addition to {@link #SYNC_EXEMPTION_PROMOTE_BUCKET}, we put the sync adapter app in the
* temp whitelist for 10 minutes, so that even RARE apps can run syncs right away.
* @hide
*/
- public static final int SYNC_EXEMPTION_ACTIVE_WITH_TEMP = 2;
+ public static final int SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP = 2;
/** @hide */
@IntDef(flag = false, prefix = { "SYNC_EXEMPTION_" }, value = {
SYNC_EXEMPTION_NONE,
- SYNC_EXEMPTION_ACTIVE,
- SYNC_EXEMPTION_ACTIVE_WITH_TEMP,
+ SYNC_EXEMPTION_PROMOTE_BUCKET,
+ SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SyncExemption {}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 1461711..0e91a29 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1188,6 +1188,7 @@
* Determines whether the {@link Activity} is considered translucent or floating.
* @hide
*/
+ @TestApi
public static boolean isTranslucentOrFloating(TypedArray attributes) {
final boolean isTranslucent =
attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c988fa9..03e600e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -598,6 +598,8 @@
boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
+ boolean setSystemAppInstallState(String packageName, boolean installed, int userId);
+
IPackageInstaller getPackageInstaller();
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 69bc353..aa0cacb 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -147,6 +147,7 @@
GET_DISABLED_COMPONENTS,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
+ MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PackageInfoFlags {}
@@ -164,6 +165,7 @@
MATCH_STATIC_SHARED_LIBRARIES,
GET_DISABLED_UNTIL_USED_COMPONENTS,
GET_UNINSTALLED_PACKAGES,
+ MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ApplicationInfoFlags {}
@@ -521,6 +523,12 @@
public static final int MATCH_DEBUG_TRIAGED_MISSING = 0x10000000;
/**
+ * Internal flag used to indicate that a package is a hidden system app.
+ * @hide
+ */
+ public static final int MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS = 0x20000000;
+
+ /**
* Flag for {@link #addCrossProfileIntentFilter}: if this flag is set: when
* resolving an intent that matches the {@code CrossProfileIntentFilter},
* the current profile will be skipped. Only activities in the target user
@@ -1656,7 +1664,8 @@
/**
* Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device includes at least one form of audio
- * output, such as speakers, audio jack or streaming over bluetooth
+ * output, as defined in the Android Compatibility Definition Document (CDD)
+ * <a href="https://source.android.com/compatibility/android-cdd#7_8_audio">section 7.8 Audio</a>.
*/
@SdkConstant(SdkConstantType.FEATURE)
public static final String FEATURE_AUDIO_OUTPUT = "android.hardware.audio.output";
@@ -4845,7 +4854,8 @@
* on the system for other users, also install it for the specified user.
* @hide
*/
- @RequiresPermission(anyOf = {
+ @RequiresPermission(anyOf = {
+ Manifest.permission.INSTALL_EXISTING_PACKAGES,
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.INTERACT_ACROSS_USERS_FULL})
public abstract int installExistingPackageAsUser(String packageName, @UserIdInt int userId)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 2da2cb4..b8eb074 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -639,11 +639,19 @@
*/
private static boolean checkUseInstalledOrHidden(int flags, PackageUserState state,
ApplicationInfo appInfo) {
+ // Returns false if the package is hidden system app until installed.
+ if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
+ && !state.installed
+ && appInfo != null && appInfo.isSystemApp()) {
+ return false;
+ }
+
// If available for the target user, or trying to match uninstalled packages and it's
// a system app.
return state.isAvailable(flags)
|| (appInfo != null && appInfo.isSystemApp()
- && (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0);
+ && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
+ || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
}
public static boolean isAvailable(PackageUserState state) {
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 4279b19..87c64cd 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -81,6 +81,15 @@
*
* @hide
*/
+ public Key(String name, String fallbackName, Class<T> type) {
+ mKey = new CameraMetadataNative.Key<T>(name, fallbackName, type);
+ }
+
+ /**
+ * Visible for testing and vendor extensions only.
+ *
+ * @hide
+ */
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 262de15..1275a85 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -813,6 +813,10 @@
/**
* <p>The camera device is a logical camera backed by two or more physical cameras that are
* also exposed to the application.</p>
+ * <p>Camera application shouldn't assume that there are at most 1 rear camera and 1 front
+ * camera in the system. For an application that switches between front and back cameras,
+ * the recommendation is to switch between the first rear camera and the first front
+ * camera in the list of supported camera devices.</p>
* <p>This capability requires the camera device to support the following:</p>
* <ul>
* <li>This camera device must list the following static metadata entries in {@link android.hardware.camera2.CameraCharacteristics }:<ul>
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index c156616..6439338 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -87,6 +87,15 @@
*
* @hide
*/
+ public Key(String name, String fallbackName, Class<T> type) {
+ mKey = new CameraMetadataNative.Key<T>(name, fallbackName, type);
+ }
+
+ /**
+ * Visible for testing and vendor extensions only.
+ *
+ * @hide
+ */
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index e4b1339..4baf263 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -84,6 +84,7 @@
private final Class<T> mType;
private final TypeReference<T> mTypeReference;
private final String mName;
+ private final String mFallbackName;
private final int mHash;
/**
@@ -96,6 +97,7 @@
throw new NullPointerException("Type needs to be non-null");
}
mName = name;
+ mFallbackName = null;
mType = type;
mVendorId = vendorId;
mTypeReference = TypeReference.createSpecializedTypeReference(type);
@@ -103,6 +105,22 @@
}
/**
+ * @hide
+ */
+ public Key(String name, String fallbackName, Class<T> type) {
+ if (name == null) {
+ throw new NullPointerException("Key needs a valid name");
+ } else if (type == null) {
+ throw new NullPointerException("Type needs to be non-null");
+ }
+ mName = name;
+ mFallbackName = fallbackName;
+ mType = type;
+ mTypeReference = TypeReference.createSpecializedTypeReference(type);
+ mHash = mName.hashCode() ^ mTypeReference.hashCode();
+ }
+
+ /**
* Visible for testing only.
*
* <p>Use the CameraCharacteristics.Key, CaptureResult.Key, or CaptureRequest.Key
@@ -115,6 +133,7 @@
throw new NullPointerException("Type needs to be non-null");
}
mName = name;
+ mFallbackName = null;
mType = type;
mTypeReference = TypeReference.createSpecializedTypeReference(type);
mHash = mName.hashCode() ^ mTypeReference.hashCode();
@@ -134,6 +153,7 @@
throw new NullPointerException("TypeReference needs to be non-null");
}
mName = name;
+ mFallbackName = null;
mType = (Class<T>)typeReference.getRawType();
mTypeReference = typeReference;
mHash = mName.hashCode() ^ mTypeReference.hashCode();
@@ -494,7 +514,16 @@
int tag = nativeGetTagFromKeyLocal(key.getName());
byte[] values = readValues(tag);
if (values == null) {
- return null;
+ // If the key returns null, use the fallback key if exists.
+ // This is to support old key names for the newly published keys.
+ if (key.mFallbackName == null) {
+ return null;
+ }
+ tag = nativeGetTagFromKeyLocal(key.mFallbackName);
+ values = readValues(tag);
+ if (values == null) {
+ return null;
+ }
}
int nativeType = nativeGetTypeFromTagLocal(tag);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index f0dd262..edf9bc1 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -1100,6 +1100,8 @@
public interface NonMonotonicObserver<C> {
public void foundNonMonotonic(
NetworkStats left, int leftIndex, NetworkStats right, int rightIndex, C cookie);
+ public void foundNonMonotonic(
+ NetworkStats stats, int statsIndex, C cookie);
}
/**
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 5890d98..7e7d617 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -138,6 +138,15 @@
}
/**
+ * Dump proxy debug information.
+ *
+ * @hide
+ */
+ public static void dumpProxyDebugInfo() {
+ BinderProxy.dumpProxyDebugInfo();
+ }
+
+ /**
* Check if binder transaction tracing is enabled.
*
* @hide
@@ -942,8 +951,7 @@
// about to crash.
final int totalUnclearedSize = unclearedSize();
if (totalUnclearedSize >= CRASH_AT_SIZE) {
- dumpProxyInterfaceCounts();
- dumpPerUidProxyCounts();
+ dumpProxyDebugInfo();
Runtime.getRuntime().gc();
throw new AssertionError("Binder ProxyMap has too many entries: "
+ totalSize + " (total), " + totalUnclearedSize + " (uncleared), "
@@ -1028,6 +1036,14 @@
private static ProxyMap sProxyMap = new ProxyMap();
/**
+ * @hide
+ */
+ public static void dumpProxyDebugInfo() {
+ sProxyMap.dumpProxyInterfaceCounts();
+ sProxyMap.dumpPerUidProxyCounts();
+ }
+
+ /**
* Return a BinderProxy for IBinder.
* This method is thread-hostile! The (native) caller serializes getInstance() calls using
* gProxyLock.
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index f1f6f41..d2d8f1e 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -72,12 +72,23 @@
public @interface VibrationIntensity{}
private final String mPackageName;
+ // The default vibration intensity level for haptic feedback.
+ @VibrationIntensity
+ private final int mDefaultHapticFeedbackIntensity;
+ // The default vibration intensity level for notifications.
+ @VibrationIntensity
+ private final int mDefaultNotificationVibrationIntensity;
/**
* @hide to prevent subclassing from outside of the framework
*/
public Vibrator() {
mPackageName = ActivityThread.currentPackageName();
+ final Context ctx = ActivityThread.currentActivityThread().getSystemContext();
+ mDefaultHapticFeedbackIntensity = loadDefaultIntensity(ctx,
+ com.android.internal.R.integer.config_defaultHapticFeedbackIntensity);
+ mDefaultNotificationVibrationIntensity = loadDefaultIntensity(ctx,
+ com.android.internal.R.integer.config_defaultNotificationVibrationIntensity);
}
/**
@@ -85,6 +96,14 @@
*/
protected Vibrator(Context context) {
mPackageName = context.getOpPackageName();
+ mDefaultHapticFeedbackIntensity = loadDefaultIntensity(context,
+ com.android.internal.R.integer.config_defaultHapticFeedbackIntensity);
+ mDefaultNotificationVibrationIntensity = loadDefaultIntensity(context,
+ com.android.internal.R.integer.config_defaultNotificationVibrationIntensity);
+ }
+
+ private int loadDefaultIntensity(Context ctx, int resId) {
+ return ctx != null ? ctx.getResources().getInteger(resId) : VIBRATION_INTENSITY_MEDIUM;
}
/**
@@ -92,7 +111,7 @@
* @hide
*/
public int getDefaultHapticFeedbackIntensity() {
- return VIBRATION_INTENSITY_MEDIUM;
+ return mDefaultHapticFeedbackIntensity;
}
/**
@@ -100,7 +119,7 @@
* @hide
*/
public int getDefaultNotificationVibrationIntensity() {
- return VIBRATION_INTENSITY_HIGH;
+ return mDefaultNotificationVibrationIntensity;
}
/**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 6994033..021e72f 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -467,6 +467,35 @@
}
/**
+ * Attempt to retrieve the PID of the zygote serving the given abi.
+ */
+ public int getZygotePid(String abi) {
+ try {
+ synchronized (mLock) {
+ ZygoteState state = openZygoteSocketIfNeeded(abi);
+
+ // Each query starts with the argument count (1 in this case)
+ state.writer.write("1");
+ // ... followed by a new-line.
+ state.writer.newLine();
+ // ... followed by our only argument.
+ state.writer.write("--get-pid");
+ state.writer.newLine();
+ state.writer.flush();
+
+ // The response is a length prefixed stream of ASCII bytes.
+ int numBytes = state.inputStream.readInt();
+ byte[] bytes = new byte[numBytes];
+ state.inputStream.readFully(bytes);
+
+ return Integer.parseInt(new String(bytes, StandardCharsets.US_ASCII));
+ }
+ } catch (Exception ex) {
+ throw new RuntimeException("Failure retrieving pid", ex);
+ }
+ }
+
+ /**
* Push hidden API blacklisting exemptions into the zygote process(es).
*
* <p>The list of exemptions will take affect for all new processes forked from the zygote after
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fe77dc4..67778d3 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7520,6 +7520,21 @@
public static final int CAMERA_LIFT_TRIGGER_ENABLED_DEFAULT = 1;
/**
+ * Whether or not the flashlight (camera torch mode) is available required to turn
+ * on flashlight.
+ *
+ * @hide
+ */
+ public static final String FLASHLIGHT_AVAILABLE = "flashlight_available";
+
+ /**
+ * Whether or not flashlight is enabled.
+ *
+ * @hide
+ */
+ public static final String FLASHLIGHT_ENABLED = "flashlight_enabled";
+
+ /**
* Whether the assist gesture should be enabled.
*
* @hide
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 105cd38..0257891 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -70,7 +70,7 @@
assertNotCalled();
mCalled = true;
try {
- mCallback.onFailure(message);
+ mCallback.onFailure(mRequestId, message);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
diff --git a/core/java/android/service/autofill/IFillCallback.aidl b/core/java/android/service/autofill/IFillCallback.aidl
index 2bb3e9a..1bad1d7 100644
--- a/core/java/android/service/autofill/IFillCallback.aidl
+++ b/core/java/android/service/autofill/IFillCallback.aidl
@@ -28,5 +28,5 @@
interface IFillCallback {
void onCancellable(in ICancellationSignal cancellation);
void onSuccess(in FillResponse response);
- void onFailure(CharSequence message);
+ void onFailure(int requestId, CharSequence message);
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 9371319..ce334ae 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -38,10 +38,10 @@
static {
DEFAULT_FLAGS = new HashMap<>();
DEFAULT_FLAGS.put("settings_battery_display_app_list", "false");
- DEFAULT_FLAGS.put("settings_about_phone_v2", "true");
DEFAULT_FLAGS.put("settings_bluetooth_while_driving", "false");
DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
+ DEFAULT_FLAGS.put("settings_systemui_theme", "true");
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 8a7d004..7944319 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5060,9 +5060,9 @@
child.assignParent(this);
} else {
child.mParent = this;
- if (child.hasUnhandledKeyListener()) {
- incrementChildUnhandledKeyListeners();
- }
+ }
+ if (child.hasUnhandledKeyListener()) {
+ incrementChildUnhandledKeyListeners();
}
final boolean childHasFocus = child.hasFocus();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 364a4a5..d34b92b 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -76,7 +76,6 @@
import android.util.MergedConfiguration;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import android.util.TypedValue;
import android.view.Surface.OutOfResourcesException;
@@ -1626,6 +1625,8 @@
contentInsets.top + outsets.top, contentInsets.right + outsets.right,
contentInsets.bottom + outsets.bottom);
}
+ contentInsets = ensureInsetsNonNegative(contentInsets, "content");
+ stableInsets = ensureInsetsNonNegative(stableInsets, "stable");
mLastWindowInsets = new WindowInsets(contentInsets,
null /* windowDecorInsets */, stableInsets,
mContext.getResources().getConfiguration().isScreenRound(),
@@ -1634,6 +1635,17 @@
return mLastWindowInsets;
}
+ private Rect ensureInsetsNonNegative(Rect insets, String kind) {
+ if (insets.left < 0 || insets.top < 0 || insets.right < 0 || insets.bottom < 0) {
+ Log.wtf(mTag, "Negative " + kind + "Insets: " + insets + ", mFirst=" + mFirst);
+ return new Rect(Math.max(0, insets.left),
+ Math.max(0, insets.top),
+ Math.max(0, insets.right),
+ Math.max(0, insets.bottom));
+ }
+ return insets;
+ }
+
void dispatchApplyInsets(View host) {
WindowInsets insets = getWindowInsets(true /* forceConstruct */);
final boolean dispatchCutout = (mWindowAttributes.layoutInDisplayCutoutMode
@@ -4972,10 +4984,7 @@
private int processKeyEvent(QueuedInputEvent q) {
final KeyEvent event = (KeyEvent)q.mEvent;
- mUnhandledKeyManager.mDispatched = false;
-
- if (mUnhandledKeyManager.hasFocus()
- && mUnhandledKeyManager.dispatchUnique(mView, event)) {
+ if (mUnhandledKeyManager.preViewDispatch(event)) {
return FINISH_HANDLED;
}
@@ -4988,7 +4997,10 @@
return FINISH_NOT_HANDLED;
}
- if (mUnhandledKeyManager.dispatchUnique(mView, event)) {
+ // This dispatch is for windows that don't have a Window.Callback. Otherwise,
+ // the Window.Callback usually will have already called this (see
+ // DecorView.superDispatchKeyEvent) leaving this call a no-op.
+ if (mUnhandledKeyManager.dispatch(mView, event)) {
return FINISH_HANDLED;
}
@@ -7026,6 +7038,10 @@
stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
}
+ if (q.mEvent instanceof KeyEvent) {
+ mUnhandledKeyManager.preDispatch((KeyEvent) q.mEvent);
+ }
+
if (stage != null) {
handleWindowFocusChanged();
stage.deliver(q);
@@ -7794,7 +7810,7 @@
* @param event
* @return {@code true} if the event was handled, {@code false} otherwise.
*/
- public boolean dispatchKeyFallbackEvent(KeyEvent event) {
+ public boolean dispatchUnhandledKeyEvent(KeyEvent event) {
return mUnhandledKeyManager.dispatch(mView, event);
}
@@ -8386,35 +8402,74 @@
}
private static class UnhandledKeyManager {
-
// This is used to ensure that unhandled events are only dispatched once. We attempt
// to dispatch more than once in order to achieve a certain order. Specifically, if we
// are in an Activity or Dialog (and have a Window.Callback), the unhandled events should
- // be dispatched after the view hierarchy, but before the Activity. However, if we aren't
+ // be dispatched after the view hierarchy, but before the Callback. However, if we aren't
// in an activity, we still want unhandled keys to be dispatched.
- boolean mDispatched = false;
+ private boolean mDispatched = true;
- SparseBooleanArray mCapturedKeys = new SparseBooleanArray();
- WeakReference<View> mCurrentReceiver = null;
+ // Keeps track of which Views have unhandled key focus for which keys. This doesn't
+ // include modifiers.
+ private final SparseArray<WeakReference<View>> mCapturedKeys = new SparseArray<>();
- private void updateCaptureState(KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- mCapturedKeys.append(event.getKeyCode(), true);
+ // The current receiver. This value is transient and used between the pre-dispatch and
+ // pre-view phase to ensure that other input-stages don't interfere with tracking.
+ private WeakReference<View> mCurrentReceiver = null;
+
+ boolean dispatch(View root, KeyEvent event) {
+ if (mDispatched) {
+ return false;
}
+ View consumer;
+ try {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "UnhandledKeyEvent dispatch");
+ mDispatched = true;
+
+ consumer = root.dispatchUnhandledKeyEvent(event);
+
+ // If an unhandled listener handles one, then keep track of it so that the
+ // consuming view is first to receive its repeats and release as well.
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ int keycode = event.getKeyCode();
+ if (consumer != null && !KeyEvent.isModifierKey(keycode)) {
+ mCapturedKeys.put(keycode, new WeakReference<>(consumer));
+ }
+ }
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ return consumer != null;
+ }
+
+ /**
+ * Called before the event gets dispatched to anything
+ */
+ void preDispatch(KeyEvent event) {
+ // Always clean-up 'up' events since it's possible for earlier dispatch stages to
+ // consume them without consuming the corresponding 'down' event.
+ mCurrentReceiver = null;
if (event.getAction() == KeyEvent.ACTION_UP) {
- mCapturedKeys.delete(event.getKeyCode());
+ int idx = mCapturedKeys.indexOfKey(event.getKeyCode());
+ if (idx >= 0) {
+ mCurrentReceiver = mCapturedKeys.valueAt(idx);
+ mCapturedKeys.removeAt(idx);
+ }
}
}
- boolean dispatch(View root, KeyEvent event) {
- Trace.traceBegin(Trace.TRACE_TAG_VIEW, "KeyFallback dispatch");
- mDispatched = true;
-
- updateCaptureState(event);
-
+ /**
+ * Called before the event gets dispatched to the view hierarchy
+ * @return {@code true} if an unhandled handler has focus and consumed the event
+ */
+ boolean preViewDispatch(KeyEvent event) {
+ mDispatched = false;
+ if (mCurrentReceiver == null) {
+ mCurrentReceiver = mCapturedKeys.get(event.getKeyCode());
+ }
if (mCurrentReceiver != null) {
View target = mCurrentReceiver.get();
- if (mCapturedKeys.size() == 0) {
+ if (event.getAction() == KeyEvent.ACTION_UP) {
mCurrentReceiver = null;
}
if (target != null && target.isAttachedToWindow()) {
@@ -8423,24 +8478,7 @@
// consume anyways so that we don't feed uncaptured key events to other views
return true;
}
-
- View consumer = root.dispatchUnhandledKeyEvent(event);
- if (consumer != null) {
- mCurrentReceiver = new WeakReference<>(consumer);
- }
- Trace.traceEnd(Trace.TRACE_TAG_VIEW);
- return consumer != null;
- }
-
- boolean hasFocus() {
- return mCurrentReceiver != null;
- }
-
- boolean dispatchUnique(View root, KeyEvent event) {
- if (mDispatched) {
- return false;
- }
- return dispatch(root, event);
+ return false;
}
}
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 4c7dc11..7555fff 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1899,10 +1899,20 @@
}
private LogMaker newLog(int category) {
- return new LogMaker(category)
- .setPackageName(mContext.getPackageName())
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE,
- isCompatibilityModeEnabledLocked() ? 1 : 0);
+ final LogMaker log = new LogMaker(category)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, mSessionId);
+
+ if (isCompatibilityModeEnabledLocked()) {
+ log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1);
+ }
+ final AutofillClient client = getClient();
+ if (client == null) {
+ // Client should never be null here, but it doesn't hurt to check...
+ log.setPackageName(mContext.getPackageName());
+ } else {
+ log.setComponentName(client.autofillClientGetComponentName());
+ }
+ return log;
}
/**
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index aee0aa7..dc1194b 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -120,7 +120,7 @@
synchronized (mLock) {
if (mSettings == null) {
mSettings = TextClassificationConstants.loadFromString(Settings.Global.getString(
- mContext.getApplicationContext().getContentResolver(),
+ getApplicationContext().getContentResolver(),
Settings.Global.TEXT_CLASSIFIER_CONSTANTS));
}
return mSettings;
@@ -186,8 +186,8 @@
protected void finalize() throws Throwable {
try {
// Note that fields could be null if the constructor threw.
- if (mContext != null && mSettingsObserver != null) {
- mContext.getApplicationContext().getContentResolver()
+ if (mSettingsObserver != null) {
+ getApplicationContext().getContentResolver()
.unregisterContentObserver(mSettingsObserver);
}
} finally {
@@ -240,6 +240,12 @@
}
}
+ Context getApplicationContext() {
+ return mContext.getApplicationContext() != null
+ ? mContext.getApplicationContext()
+ : mContext;
+ }
+
/** @hide */
public static TextClassificationConstants getSettings(Context context) {
Preconditions.checkNotNull(context);
@@ -261,7 +267,7 @@
SettingsObserver(TextClassificationManager tcm) {
super(null);
mTcm = new WeakReference<>(tcm);
- tcm.mContext.getApplicationContext().getContentResolver().registerContentObserver(
+ tcm.getApplicationContext().getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
false /* notifyForDescendants */,
this);
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index d22b1e6..6cb0eaa 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -285,10 +285,14 @@
final Layout layout = mTextView.getLayout();
final Runnable onAnimationEndCallback = () -> {
- if (result.mStart >= 0 && result.mEnd <= getText(mTextView).length()
+ final SelectionResult startSelectionResult;
+ if (result != null && result.mStart >= 0 && result.mEnd <= getText(mTextView).length()
&& result.mStart <= result.mEnd) {
- startSelectionActionMode(result);
+ startSelectionResult = result;
+ } else {
+ startSelectionResult = null;
}
+ startSelectionActionMode(startSelectionResult);
};
// TODO do not trigger the animation if the change included only non-printable characters
final boolean didSelectionChange =
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 2940079..9171959 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -156,9 +156,12 @@
if (activeServiceSupportsAssistGesture()) {
return getActiveServiceComponentName();
}
-
- Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(false);
+ final SearchManager searchManager =
+ (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
+ if (searchManager == null) {
+ return null;
+ }
+ final Intent intent = searchManager.getAssistIntent(false);
PackageManager pm = mContext.getPackageManager();
ResolveInfo info = pm.resolveActivityAsUser(intent, PackageManager.MATCH_DEFAULT_ONLY,
userId);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 571878d..4f567d2 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -76,6 +76,7 @@
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.ResolverActivity;
import com.android.internal.app.ResolverActivity.TargetInfo;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -932,7 +933,7 @@
public static final int TARGET_SERVICE = 1;
public static final int TARGET_STANDARD = 2;
- private static final int MAX_SERVICE_TARGETS = 8;
+ private static final int MAX_SERVICE_TARGETS = 4;
private static final int MAX_TARGETS_PER_SERVICE = 4;
private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
@@ -1189,123 +1190,20 @@
}
}
- static class RowScale {
- private static final int DURATION = 400;
-
- float mScale;
- ChooserRowAdapter mAdapter;
- private final ObjectAnimator mAnimator;
-
- public static final FloatProperty<RowScale> PROPERTY =
- new FloatProperty<RowScale>("scale") {
- @Override
- public void setValue(RowScale object, float value) {
- object.mScale = value;
- object.mAdapter.notifyDataSetChanged();
- }
-
- @Override
- public Float get(RowScale object) {
- return object.mScale;
- }
- };
-
- public RowScale(@NonNull ChooserRowAdapter adapter, float from, float to) {
- mAdapter = adapter;
- mScale = from;
- if (from == to) {
- mAnimator = null;
- return;
- }
-
- mAnimator = ObjectAnimator.ofFloat(this, PROPERTY, from, to)
- .setDuration(DURATION);
- mAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- mAdapter.onAnimationStart();
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- mAdapter.onAnimationEnd();
- }
- });
- }
-
- public RowScale setInterpolator(Interpolator interpolator) {
- if (mAnimator != null) {
- mAnimator.setInterpolator(interpolator);
- }
- return this;
- }
-
- public float get() {
- return mScale;
- }
-
- public void startAnimation() {
- if (mAnimator != null) {
- mAnimator.start();
- }
- }
-
- public void cancelAnimation() {
- if (mAnimator != null) {
- mAnimator.cancel();
- }
- }
- }
-
class ChooserRowAdapter extends BaseAdapter {
private ChooserListAdapter mChooserListAdapter;
private final LayoutInflater mLayoutInflater;
private final int mColumnCount = 4;
- private RowScale[] mServiceTargetScale;
- private final Interpolator mInterpolator;
private int mAnimationCount = 0;
public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
mChooserListAdapter = wrappedAdapter;
mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
- mInterpolator = AnimationUtils.loadInterpolator(ChooserActivity.this,
- android.R.interpolator.decelerate_quint);
-
wrappedAdapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
super.onChanged();
- final int rcount = getServiceTargetRowCount();
- if (mServiceTargetScale == null
- || mServiceTargetScale.length != rcount) {
- RowScale[] old = mServiceTargetScale;
- int oldRCount = old != null ? old.length : 0;
- mServiceTargetScale = new RowScale[rcount];
- if (old != null && rcount > 0) {
- System.arraycopy(old, 0, mServiceTargetScale, 0,
- Math.min(old.length, rcount));
- }
-
- for (int i = rcount; i < oldRCount; i++) {
- old[i].cancelAnimation();
- }
-
- for (int i = oldRCount; i < rcount; i++) {
- final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
- .setInterpolator(mInterpolator);
- mServiceTargetScale[i] = rs;
- }
-
- // Start the animations in a separate loop.
- // The process of starting animations will result in
- // binding views to set up initial values, and we must
- // have ALL of the new RowScale objects created above before
- // we get started.
- for (int i = oldRCount; i < rcount; i++) {
- mServiceTargetScale[i].startAnimation();
- }
- }
-
notifyDataSetChanged();
}
@@ -1313,39 +1211,10 @@
public void onInvalidated() {
super.onInvalidated();
notifyDataSetInvalidated();
- if (mServiceTargetScale != null) {
- for (RowScale rs : mServiceTargetScale) {
- rs.cancelAnimation();
- }
- }
}
});
}
- private float getRowScale(int rowPosition) {
- final int start = getCallerTargetRowCount();
- final int end = start + getServiceTargetRowCount();
- if (rowPosition >= start && rowPosition < end) {
- return mServiceTargetScale[rowPosition - start].get();
- }
- return 1.f;
- }
-
- public void onAnimationStart() {
- final boolean lock = mAnimationCount == 0;
- mAnimationCount++;
- if (lock) {
- mResolverDrawerLayout.setDismissLocked(true);
- }
- }
-
- public void onAnimationEnd() {
- mAnimationCount--;
- if (mAnimationCount == 0) {
- mResolverDrawerLayout.setDismissLocked(false);
- }
- }
-
@Override
public int getCount() {
return (int) (
@@ -1360,9 +1229,9 @@
(float) mChooserListAdapter.getCallerTargetCount() / mColumnCount);
}
+ // There can be at most one row of service targets.
public int getServiceTargetRowCount() {
- return (int) Math.ceil(
- (float) mChooserListAdapter.getServiceTargetCount() / mColumnCount);
+ return (int) mChooserListAdapter.getServiceTargetCount() == 0 ? 0 : 1;
}
@Override
@@ -1485,8 +1354,7 @@
}
final int oldHeight = holder.row.getLayoutParams().height;
- holder.row.getLayoutParams().height = Math.max(1,
- (int) (holder.measuredRowHeight * getRowScale(rowPosition)));
+ holder.row.getLayoutParams().height = Math.max(1, holder.measuredRowHeight);
if (holder.row.getLayoutParams().height != oldHeight) {
holder.row.requestLayout();
}
@@ -1728,7 +1596,7 @@
final View v = mChooserRowAdapter.getView(pos, mCachedView, mListView);
int height = ((RowViewHolder) (v.getTag())).measuredRowHeight;
- offset += (int) (height * mChooserRowAdapter.getRowScale(pos));
+ offset += (int) (height);
if (vt >= 0) {
mCachedViewType = vt;
diff --git a/core/java/com/android/internal/app/ColorDisplayController.java b/core/java/com/android/internal/app/ColorDisplayController.java
index 6cc964b..ba6cf26 100644
--- a/core/java/com/android/internal/app/ColorDisplayController.java
+++ b/core/java/com/android/internal/app/ColorDisplayController.java
@@ -335,7 +335,7 @@
if (colorTemperature == -1) {
if (DEBUG) {
Slog.d(TAG, "Using default value for setting: "
- + Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE);
+ + Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE);
}
colorTemperature = getDefaultColorTemperature();
}
@@ -358,7 +358,7 @@
*/
public boolean setColorTemperature(int colorTemperature) {
return Secure.putIntForUser(mContext.getContentResolver(),
- Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, colorTemperature, mUserId);
+ Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, colorTemperature, mUserId);
}
/**
@@ -367,10 +367,10 @@
* See com.android.server.display.DisplayTransformManager.
*/
private @ColorMode int getCurrentColorModeFromSystemProperties() {
- int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0);
+ final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0);
if (displayColorSetting == 0) {
return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation"))
- ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
+ ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
} else if (displayColorSetting == 1) {
return COLOR_MODE_SATURATED;
} else if (displayColorSetting == 2) {
@@ -381,16 +381,13 @@
}
private boolean isColorModeAvailable(@ColorMode int colorMode) {
- // SATURATED is always allowed
- if (colorMode == COLOR_MODE_SATURATED) {
- return true;
- }
-
final int[] availableColorModes = mContext.getResources().getIntArray(
R.array.config_availableColorModes);
- for (int mode : availableColorModes) {
- if (mode == colorMode) {
- return true;
+ if (availableColorModes != null) {
+ for (int mode : availableColorModes) {
+ if (mode == colorMode) {
+ return true;
+ }
}
}
return false;
@@ -401,14 +398,18 @@
*/
public int getColorMode() {
if (getAccessibilityTransformActivated()) {
- return COLOR_MODE_SATURATED;
+ if (isColorModeAvailable(COLOR_MODE_SATURATED)) {
+ return COLOR_MODE_SATURATED;
+ } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
+ return COLOR_MODE_AUTOMATIC;
+ }
}
int colorMode = System.getIntForUser(mContext.getContentResolver(),
- System.DISPLAY_COLOR_MODE, -1, mUserId);
+ System.DISPLAY_COLOR_MODE, -1, mUserId);
if (colorMode == -1) {
- // There still might be a legacy system property controlling color mode that we need to
- // respect.
+ // There might be a system property controlling color mode that we need to respect; if
+ // not, this will set a suitable default.
colorMode = getCurrentColorModeFromSystemProperties();
}
@@ -418,10 +419,13 @@
if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) {
colorMode = COLOR_MODE_NATURAL;
} else if (colorMode == COLOR_MODE_SATURATED
- && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
+ && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
colorMode = COLOR_MODE_AUTOMATIC;
- } else {
+ } else if (colorMode == COLOR_MODE_AUTOMATIC
+ && isColorModeAvailable(COLOR_MODE_SATURATED)) {
colorMode = COLOR_MODE_SATURATED;
+ } else {
+ colorMode = -1;
}
}
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index f42a195..a8edfb6 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -60,7 +60,7 @@
if (resolvedInfo != null && resolvedInfo.activityInfo != null
&& requiredPermission.equals(resolvedInfo.activityInfo.permission)) {
moreDetailsIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, suspendedPackage)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return moreDetailsIntent;
}
return null;
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index b49aace..a6b29c5 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -409,10 +409,9 @@
}
mBluetoothPowerCalculator.reset();
- if (mSensorPowerCalculator == null) {
- mSensorPowerCalculator = new SensorPowerCalculator(mPowerProfile,
- (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE));
- }
+ mSensorPowerCalculator = new SensorPowerCalculator(mPowerProfile,
+ (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE),
+ mStats, rawRealtimeUs, statsType);
mSensorPowerCalculator.reset();
if (mCameraPowerCalculator == null) {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4cc91ec..c354634 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4029,8 +4029,6 @@
public void addIsolatedUidLocked(int isolatedUid, int appUid) {
mIsolatedUids.put(isolatedUid, appUid);
- StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, appUid, isolatedUid,
- StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
final Uid u = getUidStatsLocked(appUid);
u.addIsolatedUid(isolatedUid);
}
@@ -4054,9 +4052,6 @@
*/
@GuardedBy("this")
public void removeIsolatedUidLocked(int isolatedUid) {
- StatsLog.write(
- StatsLog.ISOLATED_UID_CHANGED, mIsolatedUids.get(isolatedUid, -1),
- isolatedUid, StatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
final int idx = mIsolatedUids.indexOfKey(isolatedUid);
if (idx >= 0) {
final int ownerUid = mIsolatedUids.valueAt(idx);
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index 8586d76..9e8f06d 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -50,11 +50,33 @@
}
public MobileRadioPowerCalculator(PowerProfile profile, BatteryStats stats) {
- mPowerRadioOn = profile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE);
- for (int i = 0; i < mPowerBins.length; i++) {
- mPowerBins[i] = profile.getAveragePower(PowerProfile.POWER_RADIO_ON, i);
+ double temp =
+ profile.getAveragePowerOrDefault(PowerProfile.POWER_RADIO_ACTIVE, -1);
+ if (temp != -1) {
+ mPowerRadioOn = temp;
+ } else {
+ double sum = 0;
+ sum += profile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_RX);
+ for (int i = 0; i < mPowerBins.length; i++) {
+ sum += profile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_TX, i);
+ }
+ mPowerRadioOn = sum / (mPowerBins.length + 1);
}
- mPowerScan = profile.getAveragePower(PowerProfile.POWER_RADIO_SCANNING);
+
+ temp = profile.getAveragePowerOrDefault(PowerProfile.POWER_RADIO_ON, -1);
+ if (temp != -1 ) {
+ for (int i = 0; i < mPowerBins.length; i++) {
+ mPowerBins[i] = profile.getAveragePower(PowerProfile.POWER_RADIO_ON, i);
+ }
+ } else {
+ double idle = profile.getAveragePower(PowerProfile.POWER_MODEM_CONTROLLER_IDLE);
+ mPowerBins[0] = idle * 25 / 180;
+ for (int i = 1; i < mPowerBins.length; i++) {
+ mPowerBins[i] = Math.max(1, idle / 256);
+ }
+ }
+
+ mPowerScan = profile.getAveragePowerOrDefault(PowerProfile.POWER_RADIO_SCANNING, 0);
mStats = stats;
}
diff --git a/core/java/com/android/internal/os/SensorPowerCalculator.java b/core/java/com/android/internal/os/SensorPowerCalculator.java
index c98639b..04cb49a 100644
--- a/core/java/com/android/internal/os/SensorPowerCalculator.java
+++ b/core/java/com/android/internal/os/SensorPowerCalculator.java
@@ -20,20 +20,23 @@
import android.os.BatteryStats;
import android.util.SparseArray;
+import com.android.internal.location.gnssmetrics.GnssMetrics;
+
import java.util.List;
public class SensorPowerCalculator extends PowerCalculator {
private final List<Sensor> mSensors;
- private final double mGpsPowerOn;
+ private final double mGpsPower;
- public SensorPowerCalculator(PowerProfile profile, SensorManager sensorManager) {
+ public SensorPowerCalculator(PowerProfile profile, SensorManager sensorManager,
+ BatteryStats stats, long rawRealtimeUs, int statsType) {
mSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
- mGpsPowerOn = profile.getAveragePower(PowerProfile.POWER_GPS_ON);
+ mGpsPower = getAverageGpsPower(profile, stats, rawRealtimeUs, statsType);
}
@Override
public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
- long rawUptimeUs, int statsType) {
+ long rawUptimeUs, int statsType) {
// Process Sensor usage
final SparseArray<? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
final int NSE = sensorStats.size();
@@ -42,10 +45,11 @@
final int sensorHandle = sensorStats.keyAt(ise);
final BatteryStats.Timer timer = sensor.getSensorTime();
final long sensorTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
+
switch (sensorHandle) {
case BatteryStats.Uid.Sensor.GPS:
app.gpsTimeMs = sensorTime;
- app.gpsPowerMah = (app.gpsTimeMs * mGpsPowerOn) / (1000*60*60);
+ app.gpsPowerMah = (app.gpsTimeMs * mGpsPower) / (1000*60*60);
break;
default:
final int sensorsCount = mSensors.size();
@@ -60,4 +64,26 @@
}
}
}
+
+ private double getAverageGpsPower(PowerProfile profile, BatteryStats stats, long rawRealtimeUs,
+ int statsType) {
+ double averagePower =
+ profile.getAveragePowerOrDefault(PowerProfile.POWER_GPS_ON, -1);
+ if (averagePower != -1) {
+ return averagePower;
+ }
+ averagePower = 0;
+ long totalTime = 0;
+ double totalPower = 0;
+ for (int i = 0; i < GnssMetrics.NUM_GPS_SIGNAL_QUALITY_LEVELS; i++) {
+ long timePerLevel = stats.getGpsSignalQualityTime(i, rawRealtimeUs, statsType);
+ totalTime += timePerLevel;
+ totalPower += profile.getAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, i)
+ * timePerLevel;
+ }
+ if (totalTime != 0) {
+ averagePower = totalPower / totalTime;
+ }
+ return averagePower;
+ }
}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index f537e3e..12761b9 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -150,6 +150,11 @@
return null;
}
+ if (parsedArgs.pidQuery) {
+ handlePidQuery();
+ return null;
+ }
+
if (parsedArgs.preloadDefault) {
handlePreload();
return null;
@@ -271,6 +276,17 @@
}
}
+ private void handlePidQuery() {
+ try {
+ String pidString = String.valueOf(Process.myPid());
+ final byte[] pidStringBytes = pidString.getBytes(StandardCharsets.US_ASCII);
+ mSocketOutStream.writeInt(pidStringBytes.length);
+ mSocketOutStream.write(pidStringBytes);
+ } catch (IOException ioe) {
+ throw new IllegalStateException("Error writing to command socket", ioe);
+ }
+ }
+
/**
* Preloads resources if the zygote is in lazily preload mode. Writes the result of the
* preload operation; {@code 0} when a preload was initiated due to this request and {@code 1}
@@ -469,6 +485,11 @@
boolean startChildZygote;
/**
+ * Whether the current arguments constitute a request for the zygote's PID.
+ */
+ boolean pidQuery;
+
+ /**
* Exemptions from API blacklisting. These are sent to the pre-forked zygote at boot time,
* or when they change, via --set-api-blacklist-exemptions.
*/
@@ -622,6 +643,8 @@
mountExternal = Zygote.MOUNT_EXTERNAL_WRITE;
} else if (arg.equals("--query-abi-list")) {
abiListQuery = true;
+ } else if (arg.equals("--get-pid")) {
+ pidQuery = true;
} else if (arg.startsWith("--instruction-set=")) {
instructionSet = arg.substring(arg.indexOf('=') + 1);
} else if (arg.startsWith("--app-data-dir=")) {
@@ -656,7 +679,7 @@
}
}
- if (abiListQuery) {
+ if (abiListQuery || pidQuery) {
if (args.length - curArg > 0) {
throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 9ea17d6..4697266 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -436,7 +436,7 @@
return true;
}
- return (getViewRootImpl() != null) && getViewRootImpl().dispatchKeyFallbackEvent(event);
+ return (getViewRootImpl() != null) && getViewRootImpl().dispatchUnhandledKeyEvent(event);
}
public boolean superDispatchKeyShortcutEvent(KeyEvent event) {
diff --git a/core/java/com/android/internal/widget/MessagingGroup.java b/core/java/com/android/internal/widget/MessagingGroup.java
index d135040..c9a9161 100644
--- a/core/java/com/android/internal/widget/MessagingGroup.java
+++ b/core/java/com/android/internal/widget/MessagingGroup.java
@@ -100,7 +100,6 @@
super.onFinishInflate();
mMessageContainer = findViewById(R.id.group_message_container);
mSenderName = findViewById(R.id.message_name);
- mSenderName.addOnLayoutChangeListener(MessagingLayout.MESSAGING_PROPERTY_ANIMATOR);
mAvatarView = findViewById(R.id.message_icon);
mImageContainer = findViewById(R.id.messaging_group_icon_container);
mSendingSpinner = findViewById(R.id.messaging_group_sending_progress);
@@ -190,73 +189,66 @@
}
public void removeMessage(MessagingMessage messagingMessage) {
- ViewGroup messageParent = (ViewGroup) messagingMessage.getView().getParent();
- messageParent.removeView(messagingMessage.getView());
+ View view = messagingMessage.getView();
+ boolean wasShown = view.isShown();
+ ViewGroup messageParent = (ViewGroup) view.getParent();
+ if (messageParent == null) {
+ return;
+ }
+ messageParent.removeView(view);
Runnable recycleRunnable = () -> {
- messageParent.removeTransientView(messagingMessage.getView());
+ messageParent.removeTransientView(view);
messagingMessage.recycle();
- if (mMessageContainer.getChildCount() == 0
- && mMessageContainer.getTransientViewCount() == 0
- && mImageContainer.getChildCount() == 0) {
- ViewParent parent = getParent();
- if (parent instanceof ViewGroup) {
- ((ViewGroup) parent).removeView(MessagingGroup.this);
- }
- setAvatar(null);
- mAvatarView.setAlpha(1.0f);
- mAvatarView.setTranslationY(0.0f);
- mSenderName.setAlpha(1.0f);
- mSenderName.setTranslationY(0.0f);
- mIsolatedMessage = null;
- mMessages = null;
- sInstancePool.release(MessagingGroup.this);
- }
};
- if (isShown()) {
- messageParent.addTransientView(messagingMessage.getView(), 0);
- performRemoveAnimation(messagingMessage.getView(), recycleRunnable);
- if (mMessageContainer.getChildCount() == 0
- && mImageContainer.getChildCount() == 0) {
- removeGroupAnimated(null);
- }
+ if (wasShown && !MessagingLinearLayout.isGone(view)) {
+ messageParent.addTransientView(view, 0);
+ performRemoveAnimation(view, recycleRunnable);
} else {
recycleRunnable.run();
}
-
}
- private void removeGroupAnimated(Runnable endAction) {
- performRemoveAnimation(mAvatarView, null);
- performRemoveAnimation(mSenderName, null);
- boolean endActionTriggered = false;
- for (int i = mMessageContainer.getChildCount() - 1; i >= 0; i--) {
- View child = mMessageContainer.getChildAt(i);
- if (child.getVisibility() == View.GONE) {
- continue;
- }
- final ViewGroup.LayoutParams lp = child.getLayoutParams();
- if (lp instanceof MessagingLinearLayout.LayoutParams
- && ((MessagingLinearLayout.LayoutParams) lp).hide
- && !((MessagingLinearLayout.LayoutParams) lp).visibleBefore) {
- continue;
- }
- Runnable childEndAction = endActionTriggered ? null : endAction;
- performRemoveAnimation(child, childEndAction);
- endActionTriggered = true;
- }
+ public void recycle() {
if (mIsolatedMessage != null) {
- performRemoveAnimation(mIsolatedMessage, !endActionTriggered ? endAction : null);
- endActionTriggered = true;
+ mImageContainer.removeView(mIsolatedMessage);
}
- if (!endActionTriggered && endAction != null) {
- endAction.run();
+ for (int i = 0; i < mMessages.size(); i++) {
+ MessagingMessage message = mMessages.get(i);
+ mMessageContainer.removeView(message.getView());
+ message.recycle();
}
+ setAvatar(null);
+ mAvatarView.setAlpha(1.0f);
+ mAvatarView.setTranslationY(0.0f);
+ mSenderName.setAlpha(1.0f);
+ mSenderName.setTranslationY(0.0f);
+ setAlpha(1.0f);
+ mIsolatedMessage = null;
+ mMessages = null;
+ mAddedMessages.clear();
+ mFirstLayout = true;
+ MessagingPropertyAnimator.recycle(this);
+ sInstancePool.release(MessagingGroup.this);
+ }
+
+ public void removeGroupAnimated(Runnable endAction) {
+ performRemoveAnimation(this, () -> {
+ setAlpha(1.0f);
+ MessagingPropertyAnimator.setToLaidOutPosition(this);
+ if (endAction != null) {
+ endAction.run();
+ }
+ });
}
public void performRemoveAnimation(View message, Runnable endAction) {
- MessagingPropertyAnimator.fadeOut(message, endAction);
- MessagingPropertyAnimator.startLocalTranslationTo(message,
- (int) (-getHeight() * 0.5f), MessagingLayout.FAST_OUT_LINEAR_IN);
+ performRemoveAnimation(message, -message.getHeight(), endAction);
+ }
+
+ private void performRemoveAnimation(View view, int disappearTranslation, Runnable endAction) {
+ MessagingPropertyAnimator.startLocalTranslationTo(view, disappearTranslation,
+ MessagingLayout.FAST_OUT_LINEAR_IN);
+ MessagingPropertyAnimator.fadeOut(view, endAction);
}
public CharSequence getSenderName() {
@@ -341,6 +333,11 @@
}
}
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
public Icon getAvatarSymbolIfMatching(CharSequence avatarName, String avatarSymbol,
int layoutColor) {
if (mAvatarName.equals(avatarName) && mAvatarSymbol.equals(avatarSymbol)
@@ -458,6 +455,7 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!mAddedMessages.isEmpty()) {
+ final boolean firstLayout = mFirstLayout;
getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
@@ -466,7 +464,7 @@
continue;
}
MessagingPropertyAnimator.fadeIn(message.getView());
- if (!mFirstLayout) {
+ if (!firstLayout) {
MessagingPropertyAnimator.startLocalTranslationFrom(message.getView(),
message.getView().getHeight(),
MessagingLayout.LINEAR_OUT_SLOW_IN);
diff --git a/core/java/com/android/internal/widget/MessagingImageMessage.java b/core/java/com/android/internal/widget/MessagingImageMessage.java
index 9db74e8..607a3a9 100644
--- a/core/java/com/android/internal/widget/MessagingImageMessage.java
+++ b/core/java/com/android/internal/widget/MessagingImageMessage.java
@@ -170,8 +170,6 @@
public void recycle() {
MessagingMessage.super.recycle();
- setAlpha(1.0f);
- setTranslationY(0);
setImageBitmap(null);
mDrawable = null;
sInstancePool.release(this);
diff --git a/core/java/com/android/internal/widget/MessagingLayout.java b/core/java/com/android/internal/widget/MessagingLayout.java
index d468ce3..0fd6109 100644
--- a/core/java/com/android/internal/widget/MessagingLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLayout.java
@@ -82,7 +82,7 @@
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint mTextPaint = new Paint();
private CharSequence mConversationTitle;
- private Icon mLargeIcon;
+ private Icon mAvatarReplacement;
private boolean mIsOneToOne;
private ArrayList<MessagingGroup> mAddedGroups = new ArrayList<>();
private Person mUser;
@@ -125,8 +125,8 @@
}
@RemotableViewMethod
- public void setLargeIcon(Icon icon) {
- mLargeIcon = icon;
+ public void setAvatarReplacement(Icon icon) {
+ mAvatarReplacement = icon;
}
@RemotableViewMethod
@@ -180,8 +180,13 @@
List<MessagingMessage> historicMessages = createMessages(newHistoricMessages,
true /* isHistoric */);
List<MessagingMessage> messages = createMessages(newMessages, false /* isHistoric */);
+
+ ArrayList<MessagingGroup> oldGroups = new ArrayList<>(mGroups);
addMessagesToGroups(historicMessages, messages, showSpinner);
+ // Let's first check which groups were removed altogether and remove them in one animation
+ removeGroups(oldGroups);
+
// Let's remove the remaining messages
mMessages.forEach(REMOVE_MESSAGE);
mHistoricMessages.forEach(REMOVE_MESSAGE);
@@ -193,6 +198,31 @@
updateTitleAndNamesDisplay();
}
+ private void removeGroups(ArrayList<MessagingGroup> oldGroups) {
+ int size = oldGroups.size();
+ for (int i = 0; i < size; i++) {
+ MessagingGroup group = oldGroups.get(i);
+ if (!mGroups.contains(group)) {
+ List<MessagingMessage> messages = group.getMessages();
+ Runnable endRunnable = () -> {
+ mMessagingLinearLayout.removeTransientView(group);
+ group.recycle();
+ };
+
+ boolean wasShown = group.isShown();
+ mMessagingLinearLayout.removeView(group);
+ if (wasShown && !MessagingLinearLayout.isGone(group)) {
+ mMessagingLinearLayout.addTransientView(group, 0);
+ group.removeGroupAnimated(endRunnable);
+ } else {
+ endRunnable.run();
+ }
+ mMessages.removeAll(messages);
+ mHistoricMessages.removeAll(messages);
+ }
+ }
+ }
+
private void updateTitleAndNamesDisplay() {
ArrayMap<CharSequence, String> uniqueNames = new ArrayMap<>();
ArrayMap<Character, CharSequence> uniqueCharacters = new ArrayMap<>();
@@ -228,7 +258,7 @@
boolean isOwnMessage = group.getSender() == mUser;
CharSequence senderName = group.getSenderName();
if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)
- || (mIsOneToOne && mLargeIcon != null && !isOwnMessage)) {
+ || (mIsOneToOne && mAvatarReplacement != null && !isOwnMessage)) {
continue;
}
String symbol = uniqueNames.get(senderName);
@@ -246,8 +276,8 @@
if (!group.needsGeneratedAvatar() || TextUtils.isEmpty(senderName)) {
continue;
}
- if (mIsOneToOne && mLargeIcon != null && group.getSender() != mUser) {
- group.setAvatar(mLargeIcon);
+ if (mIsOneToOne && mAvatarReplacement != null && group.getSender() != mUser) {
+ group.setAvatar(mAvatarReplacement);
} else {
Icon cachedIcon = cachedAvatars.get(senderName);
if (cachedIcon == null) {
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index 991e3e7..64b1f24 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -163,15 +163,6 @@
}
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
MessagingChild messagingChild = (MessagingChild) child;
- if (lp.hide) {
- if (shown && lp.visibleBefore) {
- messagingChild.hideAnimated();
- }
- lp.visibleBefore = false;
- continue;
- } else {
- lp.visibleBefore = true;
- }
final int childWidth = child.getMeasuredWidth();
final int childHeight = child.getMeasuredHeight();
@@ -182,6 +173,19 @@
} else {
childLeft = paddingLeft + lp.leftMargin;
}
+ if (lp.hide) {
+ if (shown && lp.visibleBefore) {
+ // We still want to lay out the child to have great animations
+ child.layout(childLeft, childTop, childLeft + childWidth,
+ childTop + lp.lastVisibleHeight);
+ messagingChild.hideAnimated();
+ }
+ lp.visibleBefore = false;
+ continue;
+ } else {
+ lp.visibleBefore = true;
+ lp.lastVisibleHeight = childHeight;
+ }
if (!first) {
childTop += mSpacing;
@@ -228,6 +232,18 @@
return copy;
}
+ public static boolean isGone(View view) {
+ if (view.getVisibility() == View.GONE) {
+ return true;
+ }
+ final ViewGroup.LayoutParams lp = view.getLayoutParams();
+ if (lp instanceof MessagingLinearLayout.LayoutParams
+ && ((MessagingLinearLayout.LayoutParams) lp).hide) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Sets how many lines should be displayed at most
*/
@@ -263,6 +279,7 @@
public boolean hide = false;
public boolean visibleBefore = false;
+ public int lastVisibleHeight;
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
diff --git a/core/java/com/android/internal/widget/MessagingMessage.java b/core/java/com/android/internal/widget/MessagingMessage.java
index ffcb503..74d0aae 100644
--- a/core/java/com/android/internal/widget/MessagingMessage.java
+++ b/core/java/com/android/internal/widget/MessagingMessage.java
@@ -124,8 +124,7 @@
@Override
default void hideAnimated() {
setIsHidingAnimated(true);
- getGroup().performRemoveAnimation(getState().getHostView(),
- () -> setIsHidingAnimated(false));
+ getGroup().performRemoveAnimation(getView(), () -> setIsHidingAnimated(false));
}
default boolean hasOverlappingRendering() {
@@ -133,7 +132,7 @@
}
default void recycle() {
- getState().reset();
+ getState().recycle();
}
default View getView() {
diff --git a/core/java/com/android/internal/widget/MessagingMessageState.java b/core/java/com/android/internal/widget/MessagingMessageState.java
index ac62472..1ba2b51 100644
--- a/core/java/com/android/internal/widget/MessagingMessageState.java
+++ b/core/java/com/android/internal/widget/MessagingMessageState.java
@@ -72,7 +72,10 @@
return mHostView;
}
- public void reset() {
+ public void recycle() {
+ mHostView.setAlpha(1.0f);
+ mHostView.setTranslationY(0);
+ MessagingPropertyAnimator.recycle(mHostView);
mIsHidingAnimated = false;
mIsHistoric = false;
mGroup = null;
diff --git a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
index 7c3ab7f..7703cb0 100644
--- a/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
+++ b/core/java/com/android/internal/widget/MessagingPropertyAnimator.java
@@ -31,111 +31,125 @@
* A listener that automatically starts animations when the layout bounds change.
*/
public class MessagingPropertyAnimator implements View.OnLayoutChangeListener {
- static final long APPEAR_ANIMATION_LENGTH = 210;
+ private static final long APPEAR_ANIMATION_LENGTH = 210;
private static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
- private static final int TAG_LOCAL_TRANSLATION_ANIMATOR = R.id.tag_local_translation_y_animator;
- private static final int TAG_LOCAL_TRANSLATION_Y = R.id.tag_local_translation_y;
+ private static final int TAG_TOP_ANIMATOR = R.id.tag_top_animator;
+ private static final int TAG_TOP = R.id.tag_top_override;
private static final int TAG_LAYOUT_TOP = R.id.tag_layout_top;
+ private static final int TAG_FIRST_LAYOUT = R.id.tag_is_first_layout;
private static final int TAG_ALPHA_ANIMATOR = R.id.tag_alpha_animator;
private static final ViewClippingUtil.ClippingParameters CLIPPING_PARAMETERS =
view -> view.getId() == com.android.internal.R.id.notification_messaging;
- private static final IntProperty<View> LOCAL_TRANSLATION_Y =
- new IntProperty<View>("localTranslationY") {
+ private static final IntProperty<View> TOP =
+ new IntProperty<View>("top") {
@Override
public void setValue(View object, int value) {
- setLocalTranslationY(object, value);
+ setTop(object, value);
}
@Override
public Integer get(View object) {
- return getLocalTranslationY(object);
+ return getTop(object);
}
};
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
int oldTop, int oldRight, int oldBottom) {
- int oldHeight = oldBottom - oldTop;
- Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
- if (layoutTop != null) {
- oldTop = layoutTop;
- }
- int topChange = oldTop - top;
- if (oldHeight == 0 || topChange == 0 || !v.isShown() || isGone(v)) {
- // First layout
+ setLayoutTop(v, top);
+ if (isFirstLayout(v)) {
+ setFirstLayout(v, false /* first */);
+ setTop(v, top);
return;
}
- if (layoutTop != null) {
- v.setTagInternal(TAG_LAYOUT_TOP, top);
- }
- int newHeight = bottom - top;
- int heightDifference = oldHeight - newHeight;
- // Only add the difference if the height changes and it's getting smaller
- heightDifference = Math.max(heightDifference, 0);
- startLocalTranslationFrom(v, topChange + heightDifference + getLocalTranslationY(v));
+ startTopAnimation(v, getTop(v), top, MessagingLayout.FAST_OUT_SLOW_IN);
}
- private boolean isGone(View view) {
- if (view.getVisibility() == View.GONE) {
- return true;
- }
- final ViewGroup.LayoutParams lp = view.getLayoutParams();
- if (lp instanceof MessagingLinearLayout.LayoutParams
- && ((MessagingLinearLayout.LayoutParams) lp).hide) {
- return true;
- }
- return false;
- }
-
- public static void startLocalTranslationFrom(View v, int startTranslation) {
- startLocalTranslationFrom(v, startTranslation, MessagingLayout.FAST_OUT_SLOW_IN);
- }
-
- public static void startLocalTranslationFrom(View v, int startTranslation,
- Interpolator interpolator) {
- startLocalTranslation(v, startTranslation, 0, interpolator);
- }
-
- public static void startLocalTranslationTo(View v, int endTranslation,
- Interpolator interpolator) {
- startLocalTranslation(v, getLocalTranslationY(v), endTranslation, interpolator);
- }
-
- public static int getLocalTranslationY(View v) {
- Integer tag = (Integer) v.getTag(TAG_LOCAL_TRANSLATION_Y);
+ private static boolean isFirstLayout(View view) {
+ Boolean tag = (Boolean) view.getTag(TAG_FIRST_LAYOUT);
if (tag == null) {
- return 0;
+ return true;
}
return tag;
}
- private static void setLocalTranslationY(View v, int value) {
- v.setTagInternal(TAG_LOCAL_TRANSLATION_Y, value);
+ public static void recycle(View view) {
+ setFirstLayout(view, true /* first */);
+ }
+
+ private static void setFirstLayout(View view, boolean first) {
+ view.setTagInternal(TAG_FIRST_LAYOUT, first);
+ }
+
+ private static void setLayoutTop(View view, int top) {
+ view.setTagInternal(TAG_LAYOUT_TOP, top);
+ }
+
+ public static int getLayoutTop(View view) {
+ Integer tag = (Integer) view.getTag(TAG_LAYOUT_TOP);
+ if (tag == null) {
+ return getTop(view);
+ }
+ return tag;
+ }
+
+ /**
+ * Start a translation animation from a start offset to the laid out location
+ * @param view The view to animate
+ * @param startTranslation The starting translation to start from.
+ * @param interpolator The interpolator to use.
+ */
+ public static void startLocalTranslationFrom(View view, int startTranslation,
+ Interpolator interpolator) {
+ startTopAnimation(view, getTop(view) + startTranslation, getLayoutTop(view), interpolator);
+ }
+
+ /**
+ * Start a translation animation from a start offset to the laid out location
+ * @param view The view to animate
+ * @param endTranslation The end translation to go to.
+ * @param interpolator The interpolator to use.
+ */
+ public static void startLocalTranslationTo(View view, int endTranslation,
+ Interpolator interpolator) {
+ int top = getTop(view);
+ startTopAnimation(view, top, top + endTranslation, interpolator);
+ }
+
+ public static int getTop(View v) {
+ Integer tag = (Integer) v.getTag(TAG_TOP);
+ if (tag == null) {
+ return v.getTop();
+ }
+ return tag;
+ }
+
+ private static void setTop(View v, int value) {
+ v.setTagInternal(TAG_TOP, value);
updateTopAndBottom(v);
}
private static void updateTopAndBottom(View v) {
- int layoutTop = (int) v.getTag(TAG_LAYOUT_TOP);
- int localTranslation = getLocalTranslationY(v);
+ int top = getTop(v);
int height = v.getHeight();
- v.setTop(layoutTop + localTranslation);
- v.setBottom(layoutTop + height + localTranslation);
+ v.setTop(top);
+ v.setBottom(height + top);
}
- private static void startLocalTranslation(final View v, int start, int end,
+ private static void startTopAnimation(final View v, int start, int end,
Interpolator interpolator) {
- ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR);
+ ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_TOP_ANIMATOR);
if (existing != null) {
existing.cancel();
}
- ObjectAnimator animator = ObjectAnimator.ofInt(v, LOCAL_TRANSLATION_Y, start, end);
- Integer layoutTop = (Integer) v.getTag(TAG_LAYOUT_TOP);
- if (layoutTop == null) {
- layoutTop = v.getTop();
- v.setTagInternal(TAG_LAYOUT_TOP, layoutTop);
+ if (!v.isShown() || start == end
+ || (MessagingLinearLayout.isGone(v) && !isHidingAnimated(v))) {
+ setTop(v, end);
+ return;
}
- setLocalTranslationY(v, start);
+ ObjectAnimator animator = ObjectAnimator.ofInt(v, TOP, start, end);
+ setTop(v, start);
animator.setInterpolator(interpolator);
animator.setDuration(APPEAR_ANIMATION_LENGTH);
animator.addListener(new AnimatorListenerAdapter() {
@@ -143,12 +157,8 @@
@Override
public void onAnimationEnd(Animator animation) {
- v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, null);
+ v.setTagInternal(TAG_TOP_ANIMATOR, null);
setClippingDeactivated(v, false);
- if (!mCancelled) {
- setLocalTranslationY(v, 0);
- v.setTagInternal(TAG_LAYOUT_TOP, null);
- }
}
@Override
@@ -157,10 +167,17 @@
}
});
setClippingDeactivated(v, true);
- v.setTagInternal(TAG_LOCAL_TRANSLATION_ANIMATOR, animator);
+ v.setTagInternal(TAG_TOP_ANIMATOR, animator);
animator.start();
}
+ private static boolean isHidingAnimated(View v) {
+ if (v instanceof MessagingLinearLayout.MessagingChild) {
+ return ((MessagingLinearLayout.MessagingChild) v).isHidingAnimated();
+ }
+ return false;
+ }
+
public static void fadeIn(final View v) {
ObjectAnimator existing = (ObjectAnimator) v.getTag(TAG_ALPHA_ANIMATOR);
if (existing != null) {
@@ -199,6 +216,13 @@
if (existing != null) {
existing.cancel();
}
+ if (!view.isShown() || (MessagingLinearLayout.isGone(view) && !isHidingAnimated(view))) {
+ view.setAlpha(0.0f);
+ if (endAction != null) {
+ endAction.run();
+ }
+ return;
+ }
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA,
view.getAlpha(), 0.0f);
animator.setInterpolator(ALPHA_OUT);
@@ -224,10 +248,14 @@
}
public static boolean isAnimatingTranslation(View v) {
- return v.getTag(TAG_LOCAL_TRANSLATION_ANIMATOR) != null;
+ return v.getTag(TAG_TOP_ANIMATOR) != null;
}
public static boolean isAnimatingAlpha(View v) {
return v.getTag(TAG_ALPHA_ANIMATOR) != null;
}
+
+ public static void setToLaidOutPosition(View view) {
+ setTop(view, getLayoutTop(view));
+ }
}
diff --git a/core/java/com/android/internal/widget/MessagingTextMessage.java b/core/java/com/android/internal/widget/MessagingTextMessage.java
index 219116e..4081a86 100644
--- a/core/java/com/android/internal/widget/MessagingTextMessage.java
+++ b/core/java/com/android/internal/widget/MessagingTextMessage.java
@@ -92,8 +92,6 @@
public void recycle() {
MessagingMessage.super.recycle();
- setAlpha(1.0f);
- setTranslationY(0);
sInstancePool.release(this);
}
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 7352324..e5aea97 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -62,7 +62,7 @@
}
bool valid() {
- return mBitmap;
+ return mBitmap != nullptr;
}
Bitmap& bitmap() {
@@ -851,10 +851,9 @@
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Bitmap_destruct));
}
-static jboolean Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
+static void Bitmap_recycle(JNIEnv* env, jobject, jlong bitmapHandle) {
LocalScopedBitmap bitmap(bitmapHandle);
bitmap->freePixels();
- return JNI_TRUE;
}
static void Bitmap_reconfigure(JNIEnv* env, jobject clazz, jlong bitmapHandle,
@@ -1600,7 +1599,7 @@
{ "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;",
(void*)Bitmap_copyAshmemConfig },
{ "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer },
- { "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
+ { "nativeRecycle", "(J)V", (void*)Bitmap_recycle },
{ "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure },
{ "nativeCompress", "(JIILjava/io/OutputStream;[B)Z",
(void*)Bitmap_compress },
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index c7ad2a4..fb571df 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -44,9 +44,9 @@
struct NativeFamilyBuilder {
NativeFamilyBuilder(uint32_t langId, int variant)
- : langId(langId), variant(static_cast<minikin::FontFamily::Variant>(variant)) {}
+ : langId(langId), variant(static_cast<minikin::FamilyVariant>(variant)) {}
uint32_t langId;
- minikin::FontFamily::Variant variant;
+ minikin::FamilyVariant variant;
std::vector<minikin::Font> fonts;
std::vector<minikin::FontVariation> axes;
};
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 0933e98..5d65aee 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -355,11 +355,6 @@
bitmap::toBitmap(env, bitmap).getSkBitmap(outBitmap);
}
-SkPixelRef* GraphicsJNI::refSkPixelRef(JNIEnv* env, jobject jbitmap) {
- android::Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
- bitmap.ref();
- return &bitmap;
-}
SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
ALOG_ASSERT(env);
if (NULL == jconfig) {
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index dcb81fa..7825f1d 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -63,7 +63,6 @@
static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
- static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
/*
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index e9c2e7a..d391de7 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -44,6 +44,7 @@
#include <minikin/GraphemeBreak.h>
#include <minikin/LocaleList.h>
#include <minikin/Measurement.h>
+#include <minikin/MinikinPaint.h>
#include <unicode/utf16.h>
#include <cassert>
@@ -594,7 +595,7 @@
// restore the original settings.
paint->setTextSkewX(saveSkewX);
paint->setFakeBoldText(savefakeBold);
- if (paint->getFamilyVariant() == minikin::FontFamily::Variant::ELEGANT) {
+ if (paint->getFamilyVariant() == minikin::FamilyVariant::ELEGANT) {
SkScalar size = paint->getTextSize();
metrics->fTop = -size * kElegantTop / 2048;
metrics->fBottom = -size * kElegantBottom / 2048;
@@ -893,13 +894,13 @@
static jboolean isElegantTextHeight(jlong paintHandle) {
Paint* obj = reinterpret_cast<Paint*>(paintHandle);
- return obj->getFamilyVariant() == minikin::FontFamily::Variant::ELEGANT;
+ return obj->getFamilyVariant() == minikin::FamilyVariant::ELEGANT;
}
static void setElegantTextHeight(jlong paintHandle, jboolean aa) {
Paint* obj = reinterpret_cast<Paint*>(paintHandle);
obj->setFamilyVariant(
- aa ? minikin::FontFamily::Variant::ELEGANT : minikin::FontFamily::Variant::DEFAULT);
+ aa ? minikin::FamilyVariant::ELEGANT : minikin::FamilyVariant::DEFAULT);
}
static jfloat getTextSize(jlong paintHandle) {
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 567bb07..a794b7b 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1770,20 +1770,79 @@
status_t err = OK;
// Set up rectilinear distortion correction
- camera_metadata_entry entry3 =
- results.find(ANDROID_LENS_RADIAL_DISTORTION);
+ float distortion[6] {1.f, 0.f, 0.f, 0.f, 0.f, 0.f};
+ bool gotDistortion = false;
+
camera_metadata_entry entry4 =
results.find(ANDROID_LENS_INTRINSIC_CALIBRATION);
- if (entry3.count == 6 && entry4.count == 5) {
+ if (entry4.count == 5) {
float cx = entry4.data.f[/*c_x*/2];
float cy = entry4.data.f[/*c_y*/3];
- err = builder.addWarpRectilinearForMetadata(entry3.data.f, preWidth, preHeight, cx,
- cy);
- if (err != OK) {
- ALOGE("%s: Could not add distortion correction.", __FUNCTION__);
- jniThrowRuntimeException(env, "failed to add distortion correction.");
- return nullptr;
+ // Assuming f_x = f_y, or at least close enough.
+ // Also assuming s = 0, or at least close enough.
+ float f = entry4.data.f[/*f_x*/0];
+
+ camera_metadata_entry entry3 =
+ results.find(ANDROID_LENS_DISTORTION);
+ if (entry3.count == 5) {
+ gotDistortion = true;
+ float m_x = std::fmaxf(preWidth - cx, cx);
+ float m_y = std::fmaxf(preHeight - cy, cy);
+ float m_sq = m_x*m_x + m_y*m_y;
+ float m = sqrtf(m_sq); // distance to farthest corner from optical center
+ float f_sq = f * f;
+ // Conversion factors from Camera2 K factors for new LENS_DISTORTION field
+ // to DNG spec.
+ //
+ // Camera2 / OpenCV assume distortion is applied in a space where focal length
+ // is factored out, while DNG assumes a normalized space where the distance
+ // from optical center to the farthest corner is 1.
+ // Scale from camera2 to DNG spec accordingly.
+ // distortion[0] is always 1 with the new LENS_DISTORTION field.
+ const double convCoeff[5] = {
+ m_sq / f_sq,
+ pow(m_sq, 2) / pow(f_sq, 2),
+ pow(m_sq, 3) / pow(f_sq, 3),
+ m / f,
+ m / f
+ };
+ for (size_t i = 0; i < entry3.count; i++) {
+ distortion[i+1] = convCoeff[i] * entry3.data.f[i];
+ }
+ } else {
+ entry3 = results.find(ANDROID_LENS_RADIAL_DISTORTION);
+ if (entry3.count == 6) {
+ gotDistortion = true;
+ // Conversion factors from Camera2 K factors to DNG spec. K factors:
+ //
+ // Note: these are necessary because our unit system assumes a
+ // normalized max radius of sqrt(2), whereas the DNG spec's
+ // WarpRectilinear opcode assumes a normalized max radius of 1.
+ // Thus, each K coefficient must include the domain scaling
+ // factor (the DNG domain is scaled by sqrt(2) to emulate the
+ // domain used by the Camera2 specification).
+ const double convCoeff[6] = {
+ sqrt(2),
+ 2 * sqrt(2),
+ 4 * sqrt(2),
+ 8 * sqrt(2),
+ 2,
+ 2
+ };
+ for (size_t i = 0; i < entry3.count; i++) {
+ distortion[i] = entry3.data.f[i] * convCoeff[i];
+ }
+ }
+ }
+ if (gotDistortion) {
+ err = builder.addWarpRectilinearForMetadata(distortion, preWidth, preHeight, cx,
+ cy);
+ if (err != OK) {
+ ALOGE("%s: Could not add distortion correction.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to add distortion correction.");
+ return nullptr;
+ }
}
}
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index d7d8228..a72363c 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -1294,11 +1294,8 @@
handle = (audio_patch_handle_t)env->GetIntField(jPatchHandle, gAudioHandleFields.mId);
}
- struct audio_patch nPatch;
+ struct audio_patch nPatch = { .id = handle };
- nPatch.id = handle;
- nPatch.num_sources = 0;
- nPatch.num_sinks = 0;
jobject jSource = NULL;
jobject jSink = NULL;
@@ -1584,7 +1581,7 @@
if (!env->IsInstanceOf(jAudioPortConfig, gAudioPortConfigClass)) {
return AUDIO_JAVA_BAD_VALUE;
}
- struct audio_port_config nAudioPortConfig;
+ struct audio_port_config nAudioPortConfig = {};
jint jStatus = convertAudioPortConfigToNative(env, &nAudioPortConfig, jAudioPortConfig, true);
if (jStatus != AUDIO_JAVA_SUCCESS) {
return jStatus;
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index 418e15b..9d24588 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -117,6 +117,7 @@
optional bool visible = 4;
optional bool front_of_task = 5;
optional int32 proc_id = 6;
+ optional bool translucent = 7;
}
message KeyguardControllerProto {
diff --git a/core/proto/android/server/forceappstandbytracker.proto b/core/proto/android/server/forceappstandbytracker.proto
index 1113d6a..8c71b0b 100644
--- a/core/proto/android/server/forceappstandbytracker.proto
+++ b/core/proto/android/server/forceappstandbytracker.proto
@@ -25,7 +25,7 @@
// Dump from com.android.server.ForceAppStandbyTracker.
//
-// Next ID: 12
+// Next ID: 13
message ForceAppStandbyTrackerProto {
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -41,6 +41,9 @@
// App ids that are in power-save whitelist.
repeated int32 power_save_whitelist_app_ids = 3;
+ // App ids that are in power-save user whitelist.
+ repeated int32 power_save_user_whitelist_app_ids = 12;
+
// App ids that are in temporary power-save whitelist.
repeated int32 temp_power_save_whitelist_app_ids = 4;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 642f4ed..1b41f99 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -850,7 +850,7 @@
<!-- Used for permissions that are associated telephony features. -->
<permission-group android:name="android.permission-group.CALL_LOG"
- android:icon="@drawable/perm_group_phone_calls"
+ android:icon="@drawable/perm_group_call_log"
android:label="@string/permgrouplab_calllog"
android:description="@string/permgroupdesc_calllog"
android:request="@string/permgrouprequest_calllog"
@@ -3024,6 +3024,15 @@
<permission android:name="android.permission.INSTALL_PACKAGE_UPDATES"
android:protectionLevel="signature|privileged" />
+ <!-- Allows an application to install existing system packages. This is a limited
+ version of {@link android.Manifest.permission#INSTALL_PACKAGES}.
+ <p>Not for use by third-party applications.
+ TODO(b/80204953): remove this permission once we have a long-term solution.
+ @hide
+ -->
+ <permission android:name="com.android.permission.INSTALL_EXISTING_PACKAGES"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows an application to clear user data.
<p>Not for use by third-party applications
@hide
diff --git a/core/res/res/drawable/ic_arrow_forward.xml b/core/res/res/drawable/ic_arrow_forward.xml
new file mode 100644
index 0000000..f108570
--- /dev/null
+++ b/core/res/res/drawable/ic_arrow_forward.xml
@@ -0,0 +1,24 @@
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12.0,4.0l-1.41,1.41L16.17,11.0L4.0,11.0l0.0,2.0l12.17,0.0l-5.58,5.59L12.0,20.0l8.0,-8.0z"/>
+</vector>
diff --git a/core/res/res/drawable/ic_permission.xml b/core/res/res/drawable/ic_permission.xml
new file mode 100644
index 0000000..0052350
--- /dev/null
+++ b/core/res/res/drawable/ic_permission.xml
@@ -0,0 +1,26 @@
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="16.0"
+ android:viewportHeight="16.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="
+ M9.0,12l-2.0,0.0l0.0,-2.0l2.0,0.0l0.0,2.0z
+ m0.0,-4.0l-2.0,0.0l0.0,-4.0l2.0,0.0l0.0,4.0z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_call_log.xml b/core/res/res/drawable/perm_group_call_log.xml
new file mode 100644
index 0000000..0dfdbee
--- /dev/null
+++ b/core/res/res/drawable/perm_group_call_log.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M16.01,14.48l-2.62,2.62c-2.75,-1.49 -5.01,-3.75 -6.5,-6.5l2.62,-2.62c0.24,-0.24 0.34,-0.58 0.27,-0.9L9.13,3.82c-0.09,-0.47 -0.5,-0.8 -0.98,-0.8L4,3.01c-0.56,0 -1.03,0.47 -1,1.03c0.17,2.91 1.04,5.63 2.43,8.01c1.57,2.69 3.81,4.93 6.5,6.5c2.38,1.39 5.1,2.26 8.01,2.43c0.56,0.03 1.03,-0.44 1.03,-1v-4.15c0,-0.48 -0.34,-0.89 -0.8,-0.98l-3.26,-0.65C16.58,14.14 16.24,14.24 16.01,14.48z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,8h10V6H12V8zM12,4h10V2H12V4zM22,10H12v2h10V10z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_camera.xml b/core/res/res/drawable/perm_group_camera.xml
index 61903a5..db7833f 100644
--- a/core/res/res/drawable/perm_group_camera.xml
+++ b/core/res/res/drawable/perm_group_camera.xml
@@ -22,10 +22,8 @@
<path
android:fillColor="#000000"
- android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" />
+ android:pathData="M20,5h-3.17L15,3H9L7.17,5H4C2.9,5 2,5.9 2,7v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM20,19H4V7h16V19z"/>
<path
android:fillColor="#000000"
- android:pathData="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1 0 2-.9
-2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5
-5-2.24 5-5 5z" />
-</vector>
\ No newline at end of file
+ android:pathData="M12,9c-2.21,0 -4,1.79 -4,4c0,2.21 1.79,4 4,4s4,-1.79 4,-4C16,10.79 14.21,9 12,9z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_contacts.xml b/core/res/res/drawable/perm_group_contacts.xml
index 8f9dc3e..b834a27 100644
--- a/core/res/res/drawable/perm_group_contacts.xml
+++ b/core/res/res/drawable/perm_group_contacts.xml
@@ -22,8 +22,14 @@
<path
android:fillColor="#000000"
- android:pathData="M20 0H4v2h16V0zM4 24h16v-2H4v2zM20 4H4c-1.1 0-2 .9-2 2v12c0 1.1 .9 2 2 2h16c1.1
-0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 2.75c1.24 0 2.25 1.01 2.25 2.25s-1.01 2.25-2.25
-2.25S9.75 10.24 9.75 9 10.76 6.75 12 6.75zM17 17H7v-1.5c0-1.67 3.33-2.5 5-2.5s5
-.83 5 2.5V17z" />
-</vector>
\ No newline at end of file
+ android:pathData="M4,1h16v2h-16z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4,21h16v2h-16z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,5H4C2.9,5 2,5.9 2,7v10c0,1.1 0.9,2 2,2h2h12h2c1.1,0 2,-0.9 2,-2V7C22,5.9 21.1,5 20,5zM8.21,17c0.7,-0.47 2.46,-1 3.79,-1s3.09,0.53 3.79,1H8.21zM20,17h-2c0,-1.99 -4,-3 -6,-3s-6,1.01 -6,3H4V7h16V17z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,13.5c1.66,0 3,-1.34 3,-3c0,-1.66 -1.34,-3 -3,-3s-3,1.34 -3,3C9,12.16 10.34,13.5 12,13.5zM12,9.5c0.55,0 1,0.45 1,1s-0.45,1 -1,1s-1,-0.45 -1,-1S11.45,9.5 12,9.5z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_location.xml b/core/res/res/drawable/perm_group_location.xml
index cc1ec90..a7fa524 100644
--- a/core/res/res/drawable/perm_group_location.xml
+++ b/core/res/res/drawable/perm_group_location.xml
@@ -22,6 +22,8 @@
<path
android:fillColor="#000000"
- android:pathData="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0
-9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" />
-</vector>
\ No newline at end of file
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_microphone.xml b/core/res/res/drawable/perm_group_microphone.xml
index d494e67..9b532c1 100644
--- a/core/res/res/drawable/perm_group_microphone.xml
+++ b/core/res/res/drawable/perm_group_microphone.xml
@@ -22,7 +22,8 @@
<path
android:fillColor="#000000"
- android:pathData="M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3
-3 3zm5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6
-6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72h-1.7z" />
-</vector>
\ No newline at end of file
+ android:pathData="M12,14c1.66,0 3,-1.34 3,-3V5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6C9,12.66 10.34,14 12,14zM11,5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v6c0,0.55 -0.45,1 -1,1s-1,-0.45 -1,-1V5z"/>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M17,11c0,2.76 -2.24,5 -5,5s-5,-2.24 -5,-5H5c0,3.53 2.61,6.43 6,6.92V21h2v-3.08c3.39,-0.49 6,-3.39 6,-6.92H17z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_sms.xml b/core/res/res/drawable/perm_group_sms.xml
index 47bca19e..ebcf3d1 100644
--- a/core/res/res/drawable/perm_group_sms.xml
+++ b/core/res/res/drawable/perm_group_sms.xml
@@ -22,6 +22,5 @@
<path
android:fillColor="#000000"
- android:pathData="M20 2H4c-1.1 0-1.99 .9 -1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zM9
-11H7V9h2v2zm4 0h-2V9h2v2zm4 0h-2V9h2v2z" />
-</vector>
\ No newline at end of file
+ android:pathData="M20,2H4C2.9,2 2,2.9 2,4v18l4.75,-4h14C21.1,18 22,17.1 22,16V4C22,2.9 21.1,2 20,2zM20,16H4V4h16V16zM9,11H7V9h2V11zM17,11h-2V9h2V11zM13,11h-2V9h2V11z"/>
+</vector>
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 1ff1693..4b8965b 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -22,6 +22,5 @@
<path
android:fillColor="#000000"
- android:pathData="M10 4H4c-1.1 0-1.99 .9 -1.99 2L2 18c0 1.1 .9 2 2 2h16c1.1 0 2-.9
-2-2V8c0-1.1-.9-2-2-2h-8l-2-2z" />
-</vector>
\ No newline at end of file
+ android:pathData="M20,6h-8l-2,-2H4C2.9,4 2.01,4.9 2.01,6L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8C22,6.9 21.1,6 20,6zM20,18H4V8h16V18z"/>
+</vector>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b0ecb3e..c856ed8 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1108,6 +1108,15 @@
<string-array translatable="false" name="config_ringtoneEffectUris">
</string-array>
+ <!-- The default intensity level for haptic feedback. See
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY more details on the constant values and
+ meanings. -->
+ <integer name="config_defaultHapticFeedbackIntensity">2</integer>
+ <!-- The default intensity level for notification vibrations. See
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY more details on the constant values and
+ meanings. -->
+ <integer name="config_defaultNotificationVibrationIntensity">2</integer>
+
<bool name="config_use_strict_phone_number_comparation">false</bool>
<!-- Display low battery warning when battery level dips to this value.
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 47d04ed..bf7e068 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -140,15 +140,18 @@
<!-- Accessibility action identifier for {@link android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction#ACTION_MOVE_WINDOW}. -->
<item type="id" name="accessibilityActionMoveWindow" />
- <!-- A tag used to save an animator in local y translation -->
- <item type="id" name="tag_local_translation_y_animator" />
+ <!-- A tag used to save an animator in top -->
+ <item type="id" name="tag_top_animator" />
- <!-- A tag used to save the local translation y -->
- <item type="id" name="tag_local_translation_y" />
+ <!-- A tag used to save the current top override -->
+ <item type="id" name="tag_top_override" />
<!-- A tag used to save the original top of a view -->
<item type="id" name="tag_layout_top" />
+ <!-- A tag used to save whether a view was laid out before -->
+ <item type="id" name="tag_is_first_layout" />
+
<!-- A tag used to save an animator in alpha -->
<item type="id" name="tag_alpha_animator" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3c5159c..8f469b0 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3362,7 +3362,7 @@
<string name="locale_replacement">""</string>
<!-- Title of the pop-up dialog in which the user switches keyboard, also known as input method. -->
- <string name="select_input_method">Change keyboard</string>
+ <string name="select_input_method">Choose input method</string>
<!-- Summary text of a toggle switch to enable/disable use of the IME while a physical
keyboard is connected -->
<string name="show_ime">Keep it on screen while physical keyboard is active</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 42aad6a..833228b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3260,9 +3260,10 @@
<java-symbol type="id" name="message_name" />
<java-symbol type="id" name="message_icon" />
<java-symbol type="id" name="group_message_container" />
- <java-symbol type="id" name="tag_local_translation_y_animator" />
- <java-symbol type="id" name="tag_local_translation_y" />
+ <java-symbol type="id" name="tag_top_animator" />
+ <java-symbol type="id" name="tag_top_override" />
<java-symbol type="id" name="tag_layout_top" />
+ <java-symbol type="id" name="tag_is_first_layout" />
<java-symbol type="id" name="tag_alpha_animator" />
<java-symbol type="id" name="clip_children_set_tag" />
<java-symbol type="id" name="clip_to_padding_tag" />
@@ -3389,4 +3390,9 @@
<java-symbol type="attr" name="opticalInsetBottom" />
<java-symbol type="drawable" name="ic_lock_lockdown" />
+ <java-symbol type="drawable" name="ic_arrow_forward" />
+ <java-symbol type="drawable" name="ic_permission" />
+
+ <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
+ <java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
</resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 51049fe..3d9e7d2 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -617,7 +617,9 @@
Settings.Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT,
Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
Settings.Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION,
- Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE);
+ Settings.Secure.PACKAGES_TO_CLEAR_DATA_BEFORE_FULL_RESTORE,
+ Settings.Secure.FLASHLIGHT_AVAILABLE,
+ Settings.Secure.FLASHLIGHT_ENABLED);
@Test
public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
new file mode 100644
index 0000000..c8e46fc
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ViewRootImplTest {
+
+ private Context mContext;
+ private ViewRootImplAccessor mViewRootImpl;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mViewRootImpl = new ViewRootImplAccessor(
+ new ViewRootImpl(mContext, mContext.getDisplay()));
+ });
+ }
+
+ @Test
+ public void negativeInsets_areSetToZero() throws Exception {
+ mViewRootImpl.getAttachInfo().getContentInsets().set(-10, -20, -30 , -40);
+ mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40);
+ final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+ assertThat(insets.getSystemWindowInsets(), equalTo(new Rect()));
+ assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+ insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect()));
+ }
+
+ @Test
+ public void negativeInsets_areSetToZero_positiveAreLeftAsIs() throws Exception {
+ mViewRootImpl.getAttachInfo().getContentInsets().set(-10, 20, -30 , 40);
+ mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40);
+ final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+ assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40)));
+ assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+ insets.getStableInsetRight(), insets.getStableInsetBottom()),
+ equalTo(new Rect(10, 0, 30, 0)));
+ }
+
+ @Test
+ public void positiveInsets_areLeftAsIs() throws Exception {
+ mViewRootImpl.getAttachInfo().getContentInsets().set(10, 20, 30 , 40);
+ mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40);
+ final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
+
+ assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40)));
+ assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
+ insets.getStableInsetRight(), insets.getStableInsetBottom()),
+ equalTo(new Rect(10, 20, 30, 40)));
+ }
+
+ private static class ViewRootImplAccessor {
+
+ private final ViewRootImpl mViewRootImpl;
+
+ ViewRootImplAccessor(ViewRootImpl viewRootImpl) {
+ mViewRootImpl = viewRootImpl;
+ }
+
+ public ViewRootImpl get() {
+ return mViewRootImpl;
+ }
+
+ AttachInfoAccessor getAttachInfo() throws Exception {
+ return new AttachInfoAccessor(
+ getField(mViewRootImpl, ViewRootImpl.class.getDeclaredField("mAttachInfo")));
+ }
+
+ WindowInsets getWindowInsets(boolean forceConstruct) throws Exception {
+ return (WindowInsets) invokeMethod(mViewRootImpl,
+ ViewRootImpl.class.getDeclaredMethod("getWindowInsets", boolean.class),
+ forceConstruct);
+ }
+
+ class AttachInfoAccessor {
+
+ private final Class<?> mClass;
+ private final Object mAttachInfo;
+
+ AttachInfoAccessor(Object attachInfo) throws Exception {
+ mAttachInfo = attachInfo;
+ mClass = ViewRootImpl.class.getClassLoader().loadClass(
+ "android.view.View$AttachInfo");
+ }
+
+ Rect getContentInsets() throws Exception {
+ return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mContentInsets"));
+ }
+
+ Rect getStableInsets() throws Exception {
+ return (Rect) getField(mAttachInfo, mClass.getDeclaredField("mStableInsets"));
+ }
+ }
+
+ private static Object getField(Object o, Field field) throws Exception {
+ field.setAccessible(true);
+ return field.get(o);
+ }
+
+ private static Object invokeMethod(Object o, Method method, Object... args)
+ throws Exception {
+ method.setAccessible(true);
+ return method.invoke(o, args);
+ }
+ }
+}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index a6cbd49..df84a4c 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -186,8 +186,6 @@
file="/system/framework/android.test.mock.jar" />
<library name="android.test.runner"
file="/system/framework/android.test.runner.jar" />
- <library name="javax.obex"
- file="/system/framework/javax.obex.jar" />
<!-- These are the standard packages that are white-listed to always have internet
access while in power save mode, even if they aren't in the foreground. -->
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index d6c119f..0ff958f 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -344,14 +344,9 @@
* there are no more references to this bitmap.
*/
public void recycle() {
- if (!mRecycled && mNativePtr != 0) {
- if (nativeRecycle(mNativePtr)) {
- // return value indicates whether native pixel object was actually recycled.
- // false indicates that it is still in use at the native level and these
- // objects should not be collected now. They will be collected later when the
- // Bitmap itself is collected.
- mNinePatchChunk = null;
- }
+ if (!mRecycled) {
+ nativeRecycle(mNativePtr);
+ mNinePatchChunk = null;
mRecycled = true;
}
}
@@ -2052,7 +2047,7 @@
private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig);
private static native long nativeGetNativeFinalizer();
- private static native boolean nativeRecycle(long nativeBitmap);
+ private static native void nativeRecycle(long nativeBitmap);
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
int config, boolean isPremultiplied);
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index a52263c..0022c93 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -22,6 +22,11 @@
#include <SkTypeface.h>
#include <log/log.h>
+#include <minikin/Font.h>
+#include <minikin/MinikinExtent.h>
+#include <minikin/MinikinPaint.h>
+#include <minikin/MinikinRect.h>
+
namespace android {
MinikinFontSkia::MinikinFontSkia(sk_sp<SkTypeface> typeface, const void* fontData, size_t fontSize,
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index 002f759..31d3c0d 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -25,6 +25,7 @@
#include <string>
#include <minikin/FontFamily.h>
+#include <minikin/FamilyVariant.h>
namespace android {
@@ -73,9 +74,9 @@
uint32_t getMinikinLocaleListId() const { return mMinikinLocaleListId; }
- void setFamilyVariant(minikin::FontFamily::Variant variant) { mFamilyVariant = variant; }
+ void setFamilyVariant(minikin::FamilyVariant variant) { mFamilyVariant = variant; }
- minikin::FontFamily::Variant getFamilyVariant() const { return mFamilyVariant; }
+ minikin::FamilyVariant getFamilyVariant() const { return mFamilyVariant; }
void setHyphenEdit(uint32_t hyphen) { mHyphenEdit = hyphen; }
@@ -90,7 +91,7 @@
float mWordSpacing = 0;
std::string mFontFeatureSettings;
uint32_t mMinikinLocaleListId;
- minikin::FontFamily::Variant mFamilyVariant;
+ minikin::FamilyVariant mFamilyVariant;
uint32_t mHyphenEdit = 0;
// The native Typeface object has the same lifetime of the Java Typeface
// object. The Java Paint object holds a strong reference to the Java Typeface
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index ae9c475..29cc890 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -24,7 +24,7 @@
, mWordSpacing(0)
, mFontFeatureSettings()
, mMinikinLocaleListId(0)
- , mFamilyVariant(minikin::FontFamily::Variant::DEFAULT) {}
+ , mFamilyVariant(minikin::FamilyVariant::DEFAULT) {}
Paint::Paint(const Paint& paint)
: SkPaint(paint)
@@ -42,7 +42,7 @@
, mWordSpacing(0)
, mFontFeatureSettings()
, mMinikinLocaleListId(0)
- , mFamilyVariant(minikin::FontFamily::Variant::DEFAULT) {}
+ , mFamilyVariant(minikin::FamilyVariant::DEFAULT) {}
Paint::~Paint() {}
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index 7b69b63..08f8da8 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -77,13 +77,20 @@
// apply a simple clip with a scissor or a complex clip with a stencil
SkRegion clipRegion;
canvas->temporary_internal_getRgnClip(&clipRegion);
+ canvas->flush();
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, info.width, info.height);
if (CC_UNLIKELY(clipRegion.isComplex())) {
+ //TODO: move stencil clear and canvas flush to SkAndroidFrameworkUtils::clipWithStencil
glDisable(GL_SCISSOR_TEST);
glStencilMask(0x1);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
+ // GL ops get inserted here if previous flush is missing, which could dirty the stencil
bool stencilWritten = SkAndroidFrameworkUtils::clipWithStencil(canvas);
- canvas->flush();
+ canvas->flush(); //need this flush for the single op that draws into the stencil
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, info.width, info.height);
if (stencilWritten) {
glStencilMask(0x1);
glStencilFunc(GL_EQUAL, 0x1, 0x1);
@@ -94,11 +101,9 @@
glDisable(GL_STENCIL_TEST);
}
} else if (clipRegion.isEmpty()) {
- canvas->flush();
glDisable(GL_STENCIL_TEST);
glDisable(GL_SCISSOR_TEST);
} else {
- canvas->flush();
glDisable(GL_STENCIL_TEST);
glEnable(GL_SCISSOR_TEST);
setScissor(info.height, clipRegion.getBounds());
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 00ba7130..14d31b2 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -114,7 +114,7 @@
}
}
- return layerImage;
+ return layerImage != nullptr;
}
}; // namespace skiapipeline
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index f210eea..196b886 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3940,6 +3940,7 @@
* @param device Bluetooth device connected/disconnected
* @param state new connection state (BluetoothProfile.STATE_xxx)
* @param profile profile for the A2DP device
+ * @param a2dpVolume New volume for the connecting device. Does nothing if disconnecting.
* (either {@link android.bluetooth.BluetoothProfile.A2DP} or
* {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
* @param suppressNoisyIntent if true the
@@ -3949,12 +3950,13 @@
* {@hide}
*/
public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- BluetoothDevice device, int state, int profile, boolean suppressNoisyIntent) {
+ BluetoothDevice device, int state, int profile,
+ boolean suppressNoisyIntent, int a2dpVolume) {
final IAudioService service = getService();
int delay = 0;
try {
delay = service.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device,
- state, profile, suppressNoisyIntent);
+ state, profile, suppressNoisyIntent, a2dpVolume);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -4718,7 +4720,7 @@
NativeEventHandlerDelegate delegate =
new NativeEventHandlerDelegate(callback, handler);
mDeviceCallbacks.put(callback, delegate);
- broadcastDeviceListChange(delegate.getHandler());
+ broadcastDeviceListChange_sync(delegate.getHandler());
}
}
}
@@ -4837,9 +4839,9 @@
/**
* Internal method to compute and generate add/remove messages and then send to any
- * registered callbacks.
+ * registered callbacks. Must be called synchronized on mDeviceCallbacks.
*/
- private void broadcastDeviceListChange(Handler handler) {
+ private void broadcastDeviceListChange_sync(Handler handler) {
int status;
// Get the new current set of ports
@@ -4861,20 +4863,18 @@
AudioDeviceInfo[] removed_devices =
calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL);
if (added_devices.length != 0 || removed_devices.length != 0) {
- synchronized (mDeviceCallbacks) {
- for (int i = 0; i < mDeviceCallbacks.size(); i++) {
- handler = mDeviceCallbacks.valueAt(i).getHandler();
- if (handler != null) {
- if (removed_devices.length != 0) {
- handler.sendMessage(Message.obtain(handler,
- MSG_DEVICES_DEVICES_REMOVED,
- removed_devices));
- }
- if (added_devices.length != 0) {
- handler.sendMessage(Message.obtain(handler,
- MSG_DEVICES_DEVICES_ADDED,
- added_devices));
- }
+ for (int i = 0; i < mDeviceCallbacks.size(); i++) {
+ handler = mDeviceCallbacks.valueAt(i).getHandler();
+ if (handler != null) {
+ if (removed_devices.length != 0) {
+ handler.sendMessage(Message.obtain(handler,
+ MSG_DEVICES_DEVICES_REMOVED,
+ removed_devices));
+ }
+ if (added_devices.length != 0) {
+ handler.sendMessage(Message.obtain(handler,
+ MSG_DEVICES_DEVICES_ADDED,
+ added_devices));
}
}
}
@@ -4890,7 +4890,9 @@
private class OnAmPortUpdateListener implements AudioManager.OnAudioPortUpdateListener {
static final String TAG = "OnAmPortUpdateListener";
public void onAudioPortListUpdate(AudioPort[] portList) {
- broadcastDeviceListChange(null);
+ synchronized (mDeviceCallbacks) {
+ broadcastDeviceListChange_sync(null);
+ }
}
/**
@@ -4904,7 +4906,9 @@
* Callback method called when the mediaserver dies
*/
public void onServiceDied() {
- broadcastDeviceListChange(null);
+ synchronized (mDeviceCallbacks) {
+ broadcastDeviceListChange_sync(null);
+ }
}
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 4af8850..569db16 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -211,7 +211,7 @@
oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);
int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
- int state, int profile, boolean suppressNoisyIntent);
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
oneway void setFocusRequestResultFromExtPolicy(in AudioFocusInfo afi, int requestResult,
in IAudioPolicyCallback pcb);
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 02bf4e34..2207a2a 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2545,6 +2545,10 @@
pattern = newPattern;
}
+ private void setPattern(int blocksToEncrypt, int blocksToSkip) {
+ pattern = new Pattern(blocksToEncrypt, blocksToSkip);
+ }
+
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index fefa1ed..0dddaf5 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -952,7 +952,8 @@
// Find a filename. Throws FileNotFoundException if none can be found.
final File outFile = Utils.getUniqueExternalFile(mContext, subdirectory,
- Utils.getFileDisplayNameFromUri(mContext, fileUri), mimeType);
+ FileUtils.buildValidFatFilename(Utils.getFileDisplayNameFromUri(mContext, fileUri)),
+ mimeType);
// Copy contents to external ringtone storage. Throws IOException if the copy fails.
try (final InputStream input = mContext.getContentResolver().openInputStream(fileUri);
diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index 6d1bd45..ca7ab7e 100644
--- a/media/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
@@ -541,7 +541,8 @@
throw new IllegalStateException("This should be called inside of onGetRoot or"
+ " onLoadChildren or onLoadItem methods");
}
- return new RemoteUserInfo(mCurConnection.pkg, mCurConnection.pid, mCurConnection.uid);
+ return new RemoteUserInfo(mCurConnection.pkg, mCurConnection.pid, mCurConnection.uid,
+ mCurConnection.callbacks.asBinder());
}
/**
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 16f6284..3490ff8 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -742,7 +742,12 @@
void JMediaCodec::setVideoScalingMode(int mode) {
if (mSurfaceTextureClient != NULL) {
+ // this works for components that queue to surface
native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
+ // also signal via param for components that queue to IGBP
+ sp<AMessage> msg = new AMessage;
+ msg->setInt32("android._video-scaling", mode);
+ (void)mCodec->setParameters(msg);
}
}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index a855526..15957c6 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -52,6 +52,7 @@
jfieldID context;
jmethodID cryptoInfoSetID;
+ jmethodID cryptoInfoSetPatternID;
};
static fields_t gFields;
@@ -654,6 +655,16 @@
ivObj,
mode);
+ int32_t encryptedByteBlock = 0, skipByteBlock = 0;
+ meta->findInt32(kKeyEncryptedByteBlock, &encryptedByteBlock);
+ meta->findInt32(kKeySkipByteBlock, &skipByteBlock);
+
+ env->CallVoidMethod(
+ cryptoInfoObj,
+ gFields.cryptoInfoSetPatternID,
+ encryptedByteBlock,
+ skipByteBlock);
+
return JNI_TRUE;
}
@@ -669,6 +680,9 @@
gFields.cryptoInfoSetID =
env->GetMethodID(clazz, "set", "(I[I[I[B[BI)V");
+
+ gFields.cryptoInfoSetPatternID =
+ env->GetMethodID(clazz, "setPattern", "(II)V");
}
static void android_media_MediaExtractor_native_setup(
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index eda22d5..5dd01b0 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -384,6 +384,9 @@
process_media_player_call(
env, thiz, mp->getBufferingSettings(&settings),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getBufferingSettings:{%s}", settings.toString().string());
return bp.asJobject(env, gBufferingParamsFields);
@@ -555,6 +558,9 @@
process_media_player_call(
env, thiz, mp->getPlaybackSettings(&audioRate),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getPlaybackSettings: %f %f %d %d",
audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
@@ -623,6 +629,9 @@
process_media_player_call(
env, thiz, mp->getSyncSettings(&scp.sync, &scp.frameRate),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getSyncSettings: %d %d %f %f",
scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 918a375..6546cf0 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -495,6 +495,9 @@
process_media_player_call(
env, thiz, mp->getBufferingSettings(&settings),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getBufferingSettings:{%s}", settings.toString().string());
return bp.asJobject(env, gBufferingParamsFields);
@@ -662,6 +665,9 @@
process_media_player_call(
env, thiz, mp->getPlaybackSettings(&audioRate),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getPlaybackSettings: %f %f %d %d",
audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
@@ -730,6 +736,9 @@
process_media_player_call(
env, thiz, mp->getSyncSettings(&scp.sync, &scp.frameRate),
"java/lang/IllegalStateException", "unexpected error");
+ if (env->ExceptionCheck()) {
+ return nullptr;
+ }
ALOGV("getSyncSettings: %d %d %f %f",
scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
new file mode 100644
index 0000000..3b25787
--- /dev/null
+++ b/media/lib/signer/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_sdk_library {
+ name: "com.android.mediadrm.signer",
+ srcs: ["java/**/*.java"],
+ api_packages: ["com.android.mediadrm.signer"],
+}
diff --git a/media/lib/signer/Android.mk b/media/lib/signer/Android.mk
deleted file mode 100644
index 54aa968..0000000
--- a/media/lib/signer/Android.mk
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH := $(call my-dir)
-
-# the mediadrm signer library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= com.android.mediadrm.signer
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-# ==== com.android.mediadrm.signer.xml lib def ========================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.android.mediadrm.signer.xml
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.mediadrm.signer.stubs-gen
-LOCAL_MODULE_CLASS := JAVA_LIBRARIES
-LOCAL_SRC_FILES := $(call all-java-files-under,java)
-LOCAL_DROIDDOC_STUB_OUT_DIR := $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/com.android.mediadrm.signer.stubs_intermediates/src
-LOCAL_DROIDDOC_OPTIONS:= \
- -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 \
- -stubpackages com.android.mediadrm.signer \
- -nodocs
-LOCAL_UNINSTALLABLE_MODULE := true
-include $(BUILD_DROIDDOC)
-com_android_mediadrm_signer_gen_stamp := $(full_target)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := com.android.mediadrm.signer.stubs
-LOCAL_SDK_VERSION := current
-LOCAL_SOURCE_FILES_ALL_GENERATED := true
-LOCAL_ADDITIONAL_DEPENDENCIES := $(com_android_mediadrm_signer_gen_stamp)
-com_android_mediadrm_signer_gen_stamp :=
-include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/media/lib/signer/api/current.txt b/media/lib/signer/api/current.txt
new file mode 100644
index 0000000..4aa912d
--- /dev/null
+++ b/media/lib/signer/api/current.txt
@@ -0,0 +1,21 @@
+package com.android.mediadrm.signer {
+
+ public final class MediaDrmSigner {
+ method public static com.android.mediadrm.signer.MediaDrmSigner.CertificateRequest getCertificateRequest(android.media.MediaDrm, int, java.lang.String);
+ method public static com.android.mediadrm.signer.MediaDrmSigner.Certificate provideCertificateResponse(android.media.MediaDrm, byte[]) throws android.media.DeniedByServerException;
+ method public static byte[] signRSA(android.media.MediaDrm, byte[], java.lang.String, byte[], byte[]);
+ field public static final int CERTIFICATE_TYPE_X509 = 1; // 0x1
+ }
+
+ public static final class MediaDrmSigner.Certificate {
+ method public byte[] getContent();
+ method public byte[] getWrappedPrivateKey();
+ }
+
+ public static final class MediaDrmSigner.CertificateRequest {
+ method public byte[] getData();
+ method public java.lang.String getDefaultUrl();
+ }
+
+}
+
diff --git a/media/lib/signer/api/removed.txt b/media/lib/signer/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/removed.txt
diff --git a/media/lib/signer/api/system-current.txt b/media/lib/signer/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/system-current.txt
diff --git a/media/lib/signer/api/system-removed.txt b/media/lib/signer/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/system-removed.txt
diff --git a/media/lib/signer/api/test-current.txt b/media/lib/signer/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/test-current.txt
diff --git a/media/lib/signer/api/test-removed.txt b/media/lib/signer/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/lib/signer/api/test-removed.txt
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 3185ea2..e50a3757 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -24,7 +24,7 @@
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
- <application>
+ <application android:networkSecurityConfig="@xml/network_security_config">
<uses-library android:name="android.test.runner" />
<activity android:label="@string/app_name"
android:name="MediaFrameworkTest"
diff --git a/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml
new file mode 100644
index 0000000..c15c09c
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/res/xml/network_security_config.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+ <base-config cleartextTrafficPermitted="true"/>
+</network-security-config>
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 0704e35..9426148 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -33,6 +33,7 @@
arch: {
arm: {
// TODO: This is to work around b/24465209. Remove after root cause is fixed
+ pack_relocations: false,
ldflags: ["-Wl,--hash-style=both"],
},
},
diff --git a/obex/Android.bp b/obex/Android.bp
new file mode 100644
index 0000000..6558eb3
--- /dev/null
+++ b/obex/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_sdk_library {
+ name: "javax.obex",
+ srcs: ["javax/**/*.java"],
+ api_packages: ["javax.obex"],
+}
diff --git a/obex/Android.mk b/obex/Android.mk
deleted file mode 100644
index e7c1fd3..0000000
--- a/obex/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE:= javax.obex
-
-include $(BUILD_JAVA_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE:= javax.obexstatic
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
\ No newline at end of file
diff --git a/obex/CleanSpec.mk b/obex/CleanSpec.mk
new file mode 100644
index 0000000..c104234
--- /dev/null
+++ b/obex/CleanSpec.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# runtime lib is renamed from javax.obex.jar to javax.obex.impl.jar
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/javax.obex.jar)
diff --git a/obex/api/current.txt b/obex/api/current.txt
new file mode 100644
index 0000000..1cd562f
--- /dev/null
+++ b/obex/api/current.txt
@@ -0,0 +1,12 @@
+package javax.obex {
+
+ public class ObexPacket {
+ method public static javax.obex.ObexPacket read(java.io.InputStream) throws java.io.IOException;
+ method public static javax.obex.ObexPacket read(int, java.io.InputStream) throws java.io.IOException;
+ field public int mHeaderId;
+ field public int mLength;
+ field public byte[] mPayload;
+ }
+
+}
+
diff --git a/obex/api/removed.txt b/obex/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/removed.txt
diff --git a/obex/api/system-current.txt b/obex/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/system-current.txt
diff --git a/obex/api/system-removed.txt b/obex/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/system-removed.txt
diff --git a/obex/api/test-current.txt b/obex/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/test-current.txt
diff --git a/obex/api/test-removed.txt b/obex/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/obex/api/test-removed.txt
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index db776c6..9f89d3c 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -16,6 +16,9 @@
package com.android.captiveportallogin;
+import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_PROBE_SPEC;
+import static android.net.captiveportal.CaptivePortalProbeSpec.HTTP_LOCATION_HEADER_NAME;
+
import android.app.Activity;
import android.app.LoadedApk;
import android.content.Context;
@@ -29,6 +32,7 @@
import android.net.NetworkRequest;
import android.net.Proxy;
import android.net.Uri;
+import android.net.captiveportal.CaptivePortalProbeSpec;
import android.net.dns.ResolvUtil;
import android.net.http.SslError;
import android.net.wifi.WifiInfo;
@@ -85,6 +89,7 @@
};
private URL mUrl;
+ private CaptivePortalProbeSpec mProbeSpec;
private String mUserAgent;
private Network mNetwork;
private CaptivePortal mCaptivePortal;
@@ -118,6 +123,14 @@
Log.d(TAG, String.format("onCreate for %s", mUrl.toString()));
}
+ final String spec = getIntent().getStringExtra(EXTRA_CAPTIVE_PORTAL_PROBE_SPEC);
+ try {
+ mProbeSpec = CaptivePortalProbeSpec.parseSpecOrNull(spec);
+ } catch (Exception e) {
+ // Make extra sure that invalid configurations do not cause crashes
+ mProbeSpec = null;
+ }
+
// Also initializes proxy system properties.
mCm.bindProcessToNetwork(mNetwork);
mCm.setProcessDefaultNetworkForHostResolution(
@@ -329,6 +342,7 @@
}
HttpURLConnection urlConnection = null;
int httpResponseCode = 500;
+ String locationHeader = null;
try {
urlConnection = (HttpURLConnection) network.openConnection(mUrl);
urlConnection.setInstanceFollowRedirects(false);
@@ -343,6 +357,7 @@
urlConnection.getInputStream();
httpResponseCode = urlConnection.getResponseCode();
+ locationHeader = urlConnection.getHeaderField(HTTP_LOCATION_HEADER_NAME);
if (DBG) {
Log.d(TAG, "probe at " + mUrl +
" ret=" + httpResponseCode +
@@ -353,13 +368,20 @@
} finally {
if (urlConnection != null) urlConnection.disconnect();
}
- if (httpResponseCode == 204) {
+ if (isDismissed(httpResponseCode, locationHeader, mProbeSpec)) {
done(Result.DISMISSED);
}
}
}).start();
}
+ private static boolean isDismissed(
+ int httpResponseCode, String locationHeader, CaptivePortalProbeSpec probeSpec) {
+ return (probeSpec != null)
+ ? probeSpec.getResult(httpResponseCode, locationHeader).isSuccessful()
+ : (httpResponseCode == 204);
+ }
+
private class MyWebViewClient extends WebViewClient {
private static final String INTERNAL_ASSETS = "file:///android_asset/";
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index 6186a78..e645adc 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -66,10 +66,11 @@
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# out/target/common/obj/APPS/CtsShimPriv_intermediates/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
@@ -111,10 +112,11 @@
LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# frameworks/base/packages/CtsShim/build/shim/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/res/drawable/ic_signal_location.xml b/packages/SettingsLib/res/drawable/ic_signal_location.xml
index 2f60580..1187093 100644
--- a/packages/SettingsLib/res/drawable/ic_signal_location.xml
+++ b/packages/SettingsLib/res/drawable/ic_signal_location.xml
@@ -19,11 +19,10 @@
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
- <group
- android:translateX="0.02"
- android:translateY="0.82">
- <path
- android:pathData="M12,2C8.13,2 5,5.13 5,9c0,4.17 4.42,9.92 6.24,12.11 0.4,0.48 1.13,0.48 1.53,0C14.58,18.92 19,13.17 19,9c0,-3.87 -3.13,-7 -7,-7zM12,11.5a2.5,2.5 0,0 1,0 -5,2.5 2.5,0 0,1 0,5z"
- android:fillColor="#FFFFFFFF"/>
- </group>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
</vector>
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
index ee24bd0..8a1c4ef 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/PowerWhitelistBackend.java
@@ -16,17 +16,22 @@
package com.android.settingslib.fuelgauge;
+import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.os.IDeviceIdleController;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.os.UserHandle;
-import androidx.annotation.VisibleForTesting;
+import android.telecom.DefaultDialerManager;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import com.android.internal.telephony.SmsApplication;
import com.android.internal.util.ArrayUtils;
+import androidx.annotation.VisibleForTesting;
+
/**
* Handles getting/changing the whitelist for the exceptions to battery saving features.
*/
@@ -38,19 +43,20 @@
private static PowerWhitelistBackend sInstance;
+ private final Context mAppContext;
private final IDeviceIdleController mDeviceIdleService;
private final ArraySet<String> mWhitelistedApps = new ArraySet<>();
private final ArraySet<String> mSysWhitelistedApps = new ArraySet<>();
private final ArraySet<String> mSysWhitelistedAppsExceptIdle = new ArraySet<>();
- public PowerWhitelistBackend() {
- mDeviceIdleService = IDeviceIdleController.Stub.asInterface(
- ServiceManager.getService(DEVICE_IDLE_SERVICE));
- refreshList();
+ public PowerWhitelistBackend(Context context) {
+ this(context, IDeviceIdleController.Stub.asInterface(
+ ServiceManager.getService(DEVICE_IDLE_SERVICE)));
}
@VisibleForTesting
- PowerWhitelistBackend(IDeviceIdleController deviceIdleService) {
+ PowerWhitelistBackend(Context context, IDeviceIdleController deviceIdleService) {
+ mAppContext = context.getApplicationContext();
mDeviceIdleService = deviceIdleService;
refreshList();
}
@@ -64,7 +70,27 @@
}
public boolean isWhitelisted(String pkg) {
- return mWhitelistedApps.contains(pkg);
+ if (mWhitelistedApps.contains(pkg)) {
+ return true;
+ }
+
+ // Additionally, check if pkg is default dialer/sms. They are considered essential apps and
+ // should be automatically whitelisted (otherwise user may be able to set restriction on
+ // them, leading to bad device behavior.)
+ if (!mAppContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return false;
+ }
+ final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(mAppContext,
+ true /* updateIfNeeded */);
+ if (defaultSms != null && TextUtils.equals(pkg, defaultSms.getPackageName())) {
+ return true;
+ }
+
+ final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mAppContext);
+ if (TextUtils.equals(pkg, defaultDialer)) {
+ return true;
+ }
+ return false;
}
public boolean isWhitelisted(String[] pkgs) {
@@ -120,16 +146,19 @@
mSysWhitelistedApps.clear();
mSysWhitelistedAppsExceptIdle.clear();
mWhitelistedApps.clear();
+ if (mDeviceIdleService == null) {
+ return;
+ }
try {
- String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
+ final String[] whitelistedApps = mDeviceIdleService.getFullPowerWhitelist();
for (String app : whitelistedApps) {
mWhitelistedApps.add(app);
}
- String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
+ final String[] sysWhitelistedApps = mDeviceIdleService.getSystemPowerWhitelist();
for (String app : sysWhitelistedApps) {
mSysWhitelistedApps.add(app);
}
- String[] sysWhitelistedAppsExceptIdle =
+ final String[] sysWhitelistedAppsExceptIdle =
mDeviceIdleService.getSystemPowerWhitelistExceptIdle();
for (String app : sysWhitelistedAppsExceptIdle) {
mSysWhitelistedAppsExceptIdle.add(app);
@@ -139,9 +168,9 @@
}
}
- public static PowerWhitelistBackend getInstance() {
+ public static PowerWhitelistBackend getInstance(Context context) {
if (sInstance == null) {
- sInstance = new PowerWhitelistBackend();
+ sInstance = new PowerWhitelistBackend(context);
}
return sInstance;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 13f00a1..e609a40 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -57,7 +57,7 @@
private int mLevel = -1;
private boolean mCharging;
private boolean mPowerSaveEnabled;
- private boolean mPowerSaveAsColorError = true;
+ protected boolean mPowerSaveAsColorError = true;
private boolean mShowPercent;
private static final boolean SINGLE_DIGIT_PERCENT = false;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
index 0af2c05..a23eebc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/PowerWhitelistBackendTest.java
@@ -23,35 +23,52 @@
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.IDeviceIdleController;
import com.android.settingslib.SettingsLibRobolectricTestRunner;
+import com.android.settingslib.testutils.shadow.ShadowDefaultDialerManager;
+import com.android.settingslib.testutils.shadow.ShadowSmsApplication;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
@RunWith(SettingsLibRobolectricTestRunner.class)
+@Config(shadows = {ShadowDefaultDialerManager.class, ShadowSmsApplication.class})
public class PowerWhitelistBackendTest {
private static final String PACKAGE_ONE = "com.example.packageone";
private static final String PACKAGE_TWO = "com.example.packagetwo";
- private PowerWhitelistBackend mPowerWhitelistBackend;
@Mock
private IDeviceIdleController mDeviceIdleService;
+ private PowerWhitelistBackend mPowerWhitelistBackend;
+ private ShadowPackageManager mPackageManager;
+ private Context mContext;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
doReturn(new String[] {}).when(mDeviceIdleService).getFullPowerWhitelist();
doReturn(new String[] {}).when(mDeviceIdleService).getSystemPowerWhitelist();
doReturn(new String[] {}).when(mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
doNothing().when(mDeviceIdleService).addPowerSaveWhitelistApp(anyString());
doNothing().when(mDeviceIdleService).removePowerSaveWhitelistApp(anyString());
- mPowerWhitelistBackend = new PowerWhitelistBackend(mDeviceIdleService);
+ mPackageManager = Shadow.extract(mContext.getPackageManager());
+ mPackageManager.setSystemFeature(PackageManager.FEATURE_TELEPHONY, true);
+
+ mPowerWhitelistBackend = new PowerWhitelistBackend(mContext, mDeviceIdleService);
}
@Test
@@ -61,8 +78,8 @@
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse();
+ assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
+ assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
mPowerWhitelistBackend.addApp(PACKAGE_TWO);
@@ -70,15 +87,15 @@
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isTrue();
assertThat(mPowerWhitelistBackend.isWhitelisted(
- new String[]{PACKAGE_ONE, PACKAGE_TWO})).isTrue();
+ new String[] {PACKAGE_ONE, PACKAGE_TWO})).isTrue();
mPowerWhitelistBackend.removeApp(PACKAGE_TWO);
verify(mDeviceIdleService, atLeastOnce()).removePowerSaveWhitelistApp(PACKAGE_TWO);
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isTrue();
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_ONE})).isTrue();
- assertThat(mPowerWhitelistBackend.isWhitelisted(new String[]{PACKAGE_TWO})).isFalse();
+ assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_ONE})).isTrue();
+ assertThat(mPowerWhitelistBackend.isWhitelisted(new String[] {PACKAGE_TWO})).isFalse();
mPowerWhitelistBackend.removeApp(PACKAGE_ONE);
@@ -86,7 +103,23 @@
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_ONE)).isFalse();
assertThat(mPowerWhitelistBackend.isWhitelisted(PACKAGE_TWO)).isFalse();
assertThat(mPowerWhitelistBackend.isWhitelisted(
- new String[]{PACKAGE_ONE, PACKAGE_TWO})).isFalse();
+ new String[] {PACKAGE_ONE, PACKAGE_TWO})).isFalse();
+ }
+
+ @Test
+ public void isWhitelisted_shouldWhitelistDefaultSms() {
+ final String testSms = "com.android.test.defaultsms";
+ ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver"));
+
+ assertThat(mPowerWhitelistBackend.isWhitelisted(testSms)).isTrue();
+ }
+
+ @Test
+ public void isWhitelisted_shouldWhitelistDefaultDialer() {
+ final String testDialer = "com.android.test.defaultdialer";
+ ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer);
+
+ assertThat(mPowerWhitelistBackend.isWhitelisted(testDialer)).isTrue();
}
@Test
@@ -101,7 +134,7 @@
@Test
public void testIsSystemWhitelistedExceptIdle_onePackage() throws Exception {
- doReturn(new String[]{PACKAGE_TWO}).when(
+ doReturn(new String[] {PACKAGE_TWO}).when(
mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
mPowerWhitelistBackend.refreshList();
@@ -111,7 +144,7 @@
@Test
public void testIsSystemWhitelistedExceptIdle_packageArray() throws Exception {
- doReturn(new String[]{PACKAGE_TWO}).when(
+ doReturn(new String[] {PACKAGE_TWO}).when(
mDeviceIdleService).getSystemPowerWhitelistExceptIdle();
mPowerWhitelistBackend.refreshList();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
new file mode 100644
index 0000000..f4afdb1
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowDefaultDialerManager.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.testutils.shadow;
+
+import android.content.Context;
+import android.telecom.DefaultDialerManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(DefaultDialerManager.class)
+public class ShadowDefaultDialerManager {
+
+ private static String sDefaultDailer;
+
+ @Resetter
+ public void reset() {
+ sDefaultDailer = null;
+ }
+
+ @Implementation
+ public static String getDefaultDialerApplication(Context context) {
+ return sDefaultDailer;
+ }
+
+ public static void setDefaultDialerApplication(String dialer) {
+ sDefaultDailer = dialer;
+ }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
new file mode 100644
index 0000000..dd7b007
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/testutils/shadow/ShadowSmsApplication.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.testutils.shadow;
+
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.internal.telephony.SmsApplication;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(SmsApplication.class)
+public class ShadowSmsApplication {
+
+ private static ComponentName sDefaultSmsApplication;
+
+ @Resetter
+ public void reset() {
+ sDefaultSmsApplication = null;
+ }
+
+ @Implementation
+ public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
+ return sDefaultSmsApplication;
+ }
+
+ public static void setDefaultSmsApplication(ComponentName cn) {
+ sDefaultSmsApplication = cn;
+ }
+}
\ No newline at end of file
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 28e8db9..e1a602b 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -214,4 +214,7 @@
<!-- Default for Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS -->
<string name="def_backup_agent_timeout_parameters"></string>
+
+ <!-- Default for Settings.System.VIBRATE_WHEN_RINGING -->
+ <bool name="def_vibrate_when_ringing">false</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 85bbd59..960d305 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2935,7 +2935,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 167;
+ private static final int SETTINGS_VERSION = 169;
private final int mUserId;
@@ -3792,6 +3792,34 @@
currentVersion = 167;
}
+ if (currentVersion == 167) {
+ // Version 167: by default, vibrate for wireless charging
+ final SettingsState globalSettings = getGlobalSettingsLocked();
+ final Setting currentSetting = globalSettings.getSettingLocked(
+ Global.CHARGING_VIBRATION_ENABLED);
+ if (currentSetting.isNull()) {
+ globalSettings.insertSettingLocked(
+ Global.CHARGING_VIBRATION_ENABLED, "1",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ currentVersion = 168;
+ }
+
+ if (currentVersion == 168) {
+ // Version 168: by default, vibrate for phone calls
+ final SettingsState systemSettings = getSystemSettingsLocked(userId);
+ final Setting currentSetting = systemSettings.getSettingLocked(
+ Settings.System.VIBRATE_WHEN_RINGING);
+ if (currentSetting.isNull()) {
+ systemSettings.insertSettingLocked(
+ Settings.System.VIBRATE_WHEN_RINGING,
+ getContext().getResources().getBoolean(
+ R.bool.def_vibrate_when_ringing) ? "1" : "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+ currentVersion = 169;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index a92df74..8eee0d5 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -211,6 +211,8 @@
<!-- Permission necessary to change car audio volume through CarAudioManager -->
<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
+ <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
+
<application
android:name=".SystemUIApplication"
android:persistent="true"
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index d628ca8..787f91e 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -53,6 +53,7 @@
<dimen name="widget_big_font_size">64dp</dimen>
<!-- Clock with header -->
<dimen name="widget_small_font_size">24dp</dimen>
+ <dimen name="widget_small_font_stroke">0.6dp</dimen>
<!-- Dash between clock and header -->
<dimen name="widget_separator_width">12dp</dimen>
<dimen name="widget_separator_thickness">1dp</dimen>
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
deleted file mode 100644
index aa9f6d4..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 0a6074b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 151caea..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 64bc40a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step.png
deleted file mode 100644
index d7f9449..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step_dark.png
deleted file mode 100644
index 7c65703..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index eea819a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index 504ceb7..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked.png
deleted file mode 100755
index 0622ddc..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index fb44f22a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
deleted file mode 100644
index 613afce..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index a665e23..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 8e7d8cb..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 456a68f..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
deleted file mode 100644
index 72b2b21..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index 4f65660..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index eb80426..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index c57face..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png
new file mode 100644
index 0000000..0899d35
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/qs_scrubber_track.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked.png
deleted file mode 100755
index c03ad20..0000000
--- a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index bbaab44..0000000
--- a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index fb854ec..0000000
--- a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 75d184a..0000000
--- a/packages/SystemUI/res/drawable-land-hdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked.png
deleted file mode 100755
index bfe2b4a..0000000
--- a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index dba0040..0000000
--- a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 9e0af28..0000000
--- a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 7c00bd5d..0000000
--- a/packages/SystemUI/res/drawable-land-xhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked.png
deleted file mode 100755
index 5ed0ee8..0000000
--- a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 2b64b80..0000000
--- a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 81b4466..0000000
--- a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 724aa9e..0000000
--- a/packages/SystemUI/res/drawable-land-xxhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked.png
deleted file mode 100755
index d181162..0000000
--- a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 151a3c0..0000000
--- a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 7ba0d1b..0000000
--- a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index a175ccb5..0000000
--- a/packages/SystemUI/res/drawable-land-xxxhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-land/ic_sysbar_docked.png
deleted file mode 100755
index 236b70a..0000000
--- a/packages/SystemUI/res/drawable-land/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-land/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-land/ic_sysbar_docked_dark.png
deleted file mode 100644
index 3456a97..0000000
--- a/packages/SystemUI/res/drawable-land/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 2fcfdde..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index 45ce1d4..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index 6da0c9e..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-hdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 48708a5..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index 71e8959..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index bb7ae26..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-mdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 74f9256..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index c3aea46..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-hdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 4de10b6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 470b3e2..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-mdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 965d2f5..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index e7137c6..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index a123262..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 03dec15..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 0a95ddd..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index e1ca853..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-sw900dp-xxxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 3d73184..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index 32b9ded..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index ed1949c7..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xhdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 786935d..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index 2d62a80..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index a52e5b1..0000000
--- a/packages/SystemUI/res/drawable-ldrtl-xxhdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 34a11df..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 5383215..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 1c1e78c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 3a22912..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step.png
deleted file mode 100644
index d888869..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step_dark.png
deleted file mode 100644
index dc3b25c..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index d4e5a94..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index 0e693f7..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked.png
deleted file mode 100755
index 93d1905..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index c7e4731..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
deleted file mode 100644
index 7c25fc5..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index d2949f3..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 0757799..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 4f07ec1..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
deleted file mode 100644
index 35e7af4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index 06e4c26..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 1ee9cf5..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 1c855c4..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png
new file mode 100644
index 0000000..2266449
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/qs_scrubber_track.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back.png
deleted file mode 100644
index 1e2c751..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 0520c49..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index fac2da8..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 3dc2b88..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked.png
deleted file mode 100644
index 63739b9..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 2ba5d5b..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home.png
deleted file mode 100644
index bb24c8b..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 62dc2d9..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu.png
deleted file mode 100644
index 711fd7a5..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index e718b7a..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent.png
deleted file mode 100644
index bbb00a0..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 469800a..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-hdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked.png
deleted file mode 100644
index 43f77c0..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 42863c6..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-hdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked.png
deleted file mode 100644
index 872af09..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index d9ec9d5..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-mdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked.png
deleted file mode 100644
index ea7ac93..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 8ee4e43..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked.png
deleted file mode 100644
index fe07f81..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index dfa8a97..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked.png
deleted file mode 100644
index 4193b21..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index d23abc7..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-land-xxxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 56c2638..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 8e56e9c..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index c3aa434..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 28a1465..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked.png
deleted file mode 100644
index 41a7209..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 0fc9677..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home.png
deleted file mode 100644
index faaef60..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 7b81eee..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu.png
deleted file mode 100644
index c8e40d0..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index a6483452..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 2612485..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 7f74521..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-mdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 3b831a3..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 8c99455..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 3c37782..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked.png
deleted file mode 100644
index b2baa09..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index b78dc9c..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home.png
deleted file mode 100644
index 37590a5..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 3a208aa..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu.png
deleted file mode 100644
index 4940d5c..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index 625ba45..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 7ad2a29..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 604397e..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 274e5df..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 6fb19ae..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked.png
deleted file mode 100644
index 49d2c3a..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index ac16895..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 216f2c7..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index e69a037..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_ime_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_ime_dark.png
deleted file mode 100644
index 65a4354..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu.png
deleted file mode 100644
index a8c2786..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index 8bddcd9..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index ca35888..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 38c5959..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back.png
deleted file mode 100644
index 4d23956..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index c6d7c98..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 74abc31..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 06c52aa..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked.png
deleted file mode 100644
index 89bed92..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 7660997..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 8d4f5f3..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 0d9ecc2..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu.png
deleted file mode 100644
index 83e96a2..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index d6bb8b1..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 636c0c1..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 298ef3a..0000000
--- a/packages/SystemUI/res/drawable-sw900dp-xxxhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
deleted file mode 100644
index 987aac5..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index 371a84d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 433e5a74..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 360ed77..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step.png
deleted file mode 100644
index ba5b457..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step_dark.png
deleted file mode 100644
index a55ea1d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_ime_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index 407ef28..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index 39cfbf2..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked.png
deleted file mode 100755
index 73ddde8..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 96cecc9..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
deleted file mode 100644
index 0e2a14d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 9ff9825..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index a7fd3a6..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index f2a1255..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
deleted file mode 100644
index 69a018d..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index e505f5e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
deleted file mode 100644
index f810704..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 472c55b..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png
new file mode 100644
index 0000000..3328add
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/qs_scrubber_track.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
deleted file mode 100644
index be03cbe..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index c04d650..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index b6b1615..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 0f6d206..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step.png
deleted file mode 100644
index 5a7eec6..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step_dark.png
deleted file mode 100644
index f7abb54..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_ime_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index a1f44dc..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index 175a9ae..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked.png
deleted file mode 100755
index 1e84732..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 58bf920..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
deleted file mode 100644
index f16aa48..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index f47533ec..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index 0fb93ca..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index 1052940..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
deleted file mode 100644
index a37ca5d..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index f299d97..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 109aeed..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index 84d6dc8..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png
new file mode 100644
index 0000000..ed651da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/qs_scrubber_track.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back.png
deleted file mode 100644
index a059704..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_dark.png
deleted file mode 100644
index d813bc7..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime.png
deleted file mode 100644
index 8f00a64..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_dark.png
deleted file mode 100644
index 30e8782..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step.png
deleted file mode 100644
index d13c730..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step_dark.png
deleted file mode 100644
index 31c602e..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_ime_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step.png
deleted file mode 100644
index ddbcb07..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step_dark.png
deleted file mode 100644
index ce91fcbb..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_back_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png
deleted file mode 100755
index ee3ffde..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked_dark.png
deleted file mode 100644
index 83fc662..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_docked_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home.png
deleted file mode 100644
index 194d39f..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_dark.png
deleted file mode 100644
index 71101a1..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step.png
deleted file mode 100644
index c606a58..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step_dark.png
deleted file mode 100644
index c2a5fef..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_home_quick_step_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_menu_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_menu_dark.png
deleted file mode 100644
index 4a477ad..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_menu_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent.png
deleted file mode 100644
index 046d850..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_dark.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_dark.png
deleted file mode 100644
index bc24c00..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_sysbar_recent_dark.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png
new file mode 100644
index 0000000..06e1202
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxxhdpi/qs_scrubber_track.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/car_add_circle_round.xml b/packages/SystemUI/res/drawable/car_add_circle_round.xml
index 5cf0c31..13c7dd1 100644
--- a/packages/SystemUI/res/drawable/car_add_circle_round.xml
+++ b/packages/SystemUI/res/drawable/car_add_circle_round.xml
@@ -1,4 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
diff --git a/packages/SystemUI/res/drawable/car_ic_add_white.xml b/packages/SystemUI/res/drawable/car_ic_add_white.xml
index f24771d..d681860 100644
--- a/packages/SystemUI/res/drawable/car_ic_add_white.xml
+++ b/packages/SystemUI/res/drawable/car_ic_add_white.xml
@@ -1,3 +1,17 @@
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="@dimen/car_touch_target_size"
android:height="@dimen/car_touch_target_size"
diff --git a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
index 6a7f18b..d5f8a2a 100644
--- a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
+++ b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
@@ -15,11 +15,11 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:pathData="M21,4H3C1.9,4 1,4.9 1,6v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2V6C23,4.9 22.1,4 21,4zM21,19H3V6h18V19zM9,8h2v2H9V8zM5,8h2v2H5V8zM8,16h8v1H8V16zM13,8h2v2h-2V8zM9,12h2v2H9V12zM5,12h2v2H5V12zM13,12h2v2h-2V12zM17,8h2v2h-2V8zM17,12h2v2h-2V12z"
+ android:pathData="M19,7h2v2h-2V7zM15,7h2v2h-2V7zM3,7h2v2H3V7zM7,7h2v2H7V7zM11,7h2v2h-2V7zM19,11h2v2h-2V11zM15,11h2v2h-2V11zM3,11h2v2H3V11zM7,11h2v2H7V11zM11,11h2v2h-2V11zM7,15h10v2H7V15z"
android:fillColor="?attr/singleToneColor"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml b/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
index fba45d1..9c24c2c 100644
--- a/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_auto_rotate.xml
@@ -18,44 +18,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="48dp"
android:width="48dp"
- android:viewportHeight="48"
- android:viewportWidth="48">
- <group
- android:name="device"
- android:translateX="24"
- android:translateY="24" >
- <group
- android:name="device_pivot"
- android:translateX="-24.15"
- android:translateY="-24.25" >
- <group
- android:name="device_0"
- android:translateX="24.14999"
- android:translateY="24.25" >
- <path
- android:name="device_merged"
- android:pathData="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
- android:fillColor="#FFFFFFFF" />
- </group>
- </group>
- </group>
- <group
- android:name="arrows"
- android:translateX="24"
- android:translateY="24" >
- <group
- android:name="arrows_pivot"
- android:translateX="-24.0798"
- android:translateY="-24.23" >
- <group
- android:name="arrows_0"
- android:translateX="12.2505"
- android:translateY="37.2145" >
- <path
- android:name="bottom_merged"
- android:pathData="M 20.7395019531,-31.9844970703 c 6.23999023438,2.83999633789 10.6999969482,8.7200012207 11.8399963379,15.7799987793 c 0.119995117188,0.699996948242 0.740005493164,1.2200012207 1.46099853516,1.2200012207 c 0.919998168945,0.0 1.6190032959,-0.84001159668 1.47900390625,-1.74000549316 c -1.75900268555,-10.3800048828 -9.75900268555,-19.1199951172 -22.5800018311,-20.1600036621 c -0.919998168945,-0.0800018310547 -1.43899536133,1.04000854492 -0.800003051758,1.70001220703 c 0.0,0.0 5.12100219727,5.11999511719 5.12100219727,5.11999511719 c 0.378997802734,0.380004882812 0.97900390625,0.380004882812 1.37899780273,0.020004272461 c 0.0,0.0 2.10000610352,-1.94000244141 2.10000610352,-1.94000244141 Z M 2.73950195312,6.01550292969 c -6.26000976562,-2.83999633789 -10.7200012207,-8.76000976562 -11.8399963379,-15.8600006104 c -0.118011474609,-0.667007446289 -0.702011108398,-1.15100097656 -1.38000488281,-1.13999938965 c -0.860000610352,0.0 -1.52000427246,0.759994506836 -1.38000488281,1.61999511719 c 1.54000854492,10.4000091553 9.5,19.2200012207 22.4199981689,20.2799987793 c 0.920013427734,0.0800018310547 1.44100952148,-1.03999328613 0.800003051758,-1.69999694824 c 0.0,0.0 -5.11999511719,-5.11999511719 -5.11999511719,-5.11999511719 c -0.380004882812,-0.376007080078 -0.988998413086,-0.385009765625 -1.38000488281,-0.0200042724609 c 0.0,0.0 -2.11999511719,1.94000244141 -2.11999511719,1.94000244141 Z"
- android:fillColor="#FFFFFFFF" />
- </group>
- </group>
- </group>
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12.72,23H11C5.49,23 1,18.51 1,13h2c0,3.78 2.63,6.95 6.15,7.79L8.13,19L9.87,18L12.72,23zM13,1h-1.72l2.85,5L15.87,5l-1.02,-1.79C18.37,4.05 21,7.22 21,11h2C23,5.49 18.51,1 13,1zM10.23,6L18,13.76L13.77,18L6,10.24L10.23,6C10.23,6 10.23,6 10.23,6M10.23,4C9.72,4 9.21,4.2 8.82,4.59L4.59,8.82c-0.78,0.78 -0.78,2.04 0,2.82l7.77,7.77c0.39,0.39 0.9,0.59 1.41,0.59c0.51,0 1.02,-0.2 1.41,-0.59l4.24,-4.24c0.78,-0.78 0.78,-2.04 0,-2.82l-7.77,-7.77C11.26,4.2 10.75,4 10.23,4L10.23,4z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
index 1603eba..8d569b2 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
@@ -14,12 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24">
+ android:width="21dp"
+ android:height="21dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
android:pathData="M20.5,6c-2.61,0.7 -5.67,1 -8.5,1S6.11,6.7 3.5,6L3,8c1.86,0.5 4,0.83 6,1v13h2v-6h2v6h2V9c2,-0.17 4.14,-0.5 6,-1L20.5,6zM12,6c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2s-2,0.9 -2,2S10.9,6 12,6z"
android:fillColor="?attr/singleToneColor"/>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back.xml b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
new file mode 100644
index 0000000..1448843
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M6.49,14.86c-0.66-0.39-0.66-1.34,0-1.73l6.02-3.53l5.89-3.46C19.11,5.73,20,6.26,20,7.1V14v6.9 c0,0.84-0.89,1.37-1.6,0.95l-5.89-3.46L6.49,14.86z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml b/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml
new file mode 100644
index 0000000..93b2f9c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+ <path
+ android:pathData="M16.78,10.03l-3.97,3.97l3.97,3.97l-1.06,1.06l-5.03,-5.03l5.03,-5.03z"
+ android:fillColor="?attr/singleToneColor" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_docked.xml b/packages/SystemUI/res/drawable/ic_sysbar_docked.xml
new file mode 100644
index 0000000..693835f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_docked.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M20.5,13h-13C6.67,13,6,12.33,6,11.5v-4C6,6.67,6.67,6,7.5,6h13C21.33,6,22,6.67,22,7.5v4 C22,12.33,21.33,13,20.5,13z" />
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M20.5,22h-13C6.67,22,6,21.33,6,20.5v-4C6,15.67,6.67,15,7.5,15h13c0.83,0,1.5,0.67,1.5,1.5v4 C22,21.33,21.33,22,20.5,22z" />
+</vector>
\ No newline at end of file
diff --git a/media/lib/signer/com.android.mediadrm.signer.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
similarity index 65%
rename from media/lib/signer/com.android.mediadrm.signer.xml
rename to packages/SystemUI/res/drawable/ic_sysbar_home.xml
index fd3a115..a960af7 100644
--- a/media/lib/signer/com.android.mediadrm.signer.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!--
+ Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -13,8 +14,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="oval"
+ android:useLevel="false">
-<permissions>
- <library name="com.android.mediadrm.signer"
- file="/system/framework/com.android.mediadrm.signer.jar" />
-</permissions>
+ <solid android:color="?attr/singleToneColor" />
+
+ <size
+ android:height="14dp"
+ android:width="14dp" />
+</shape>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_home_quick_step.xml b/packages/SystemUI/res/drawable/ic_sysbar_home_quick_step.xml
new file mode 100644
index 0000000..ba1236e
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home_quick_step.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M23,19H5c-2.76,0-5-2.24-5-5l0,0c0-2.76,2.24-5,5-5h18c2.76,0,5,2.24,5,5l0,0C28,16.76,25.76,19,23,19z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_menu.xml b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
new file mode 100644
index 0000000..d53c95b
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="21dp"
+ android:height="21dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M14,9.5c1.24,0,2.25-1.01,2.25-2.25S15.24,5,14,5s-2.25,1.01-2.25,2.25S12.76,9.5,14,9.5z M14,11.75 c-1.24,0-2.25,1.01-2.25,2.25s1.01,2.25,2.25,2.25s2.25-1.01,2.25-2.25S15.24,11.75,14,11.75z M14,18.5 c-1.24,0-2.25,1.01-2.25,2.25S12.76,23,14,23s2.25-1.01,2.25-2.25S15.24,18.5,14,18.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
new file mode 100644
index 0000000..6b038d1
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="28dp"
+ android:height="28dp"
+ android:viewportWidth="28"
+ android:viewportHeight="28">
+
+ <path
+ android:fillColor="?attr/singleToneColor"
+ android:pathData="M19.9,21.5H8.1c-0.88,0-1.6-0.72-1.6-1.6V8.1c0-0.88,0.72-1.6,1.6-1.6h11.8c0.88,0,1.6,0.72,1.6,1.6v11.8 C21.5,20.78,20.78,21.5,19.9,21.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
index 6c1ae99..2cd7883 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
@@ -17,14 +17,16 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector android:name="root"
- android:width="24dp"
- android:height="24dp"
+ android:width="21dp"
+ android:height="21dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
- <group android:name="icon" android:pivotX="12" android:pivotY="12">
+ <!-- Use scaleX to flip icon so arrows always point in the direction of motion -->
+ <group android:name="icon" android:pivotX="12" android:pivotY="12"
+ android:scaleX="?attr/rotateButtonScaleX">
<!-- Tint color to be set directly -->
<path android:fillColor="#FFFFFFFF"
- android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
+ android:pathData="M19,12c0,1.72 -0.63,3.3 -1.66,4.52l-1.44,-1.44C16.58,14.23 17,13.17 17,12c0,-2.76 -2.24,-5 -5,-5c-0.06,0 -0.11,0.01 -0.17,0.01l1.08,1.08L11.5,9.5L8,6l3.5,-3.5l1.41,1.42l-1.09,1.09C11.88,5.01 11.94,5 12,5C15.87,5 19,8.13 19,12zM12.5,14.51l-1.41,1.41l1.06,1.06C12.1,16.99 12.05,17 12,17c-2.76,0 -5,-2.24 -5,-5c0,-1.17 0.42,-2.23 1.09,-3.08L6.66,7.48C5.62,8.7 5,10.28 5,12c0,3.87 3.13,7 7,7c0.06,0 0.13,-0.01 0.19,-0.01v0l-1.1,1.1l1.41,1.41L16,18L12.5,14.51z"/>
</group>
</vector>
</aapt:attr>
diff --git a/packages/SystemUI/res/drawable/stat_sys_location.xml b/packages/SystemUI/res/drawable/stat_sys_location.xml
index 33ac5cd..bdb0b0c 100644
--- a/packages/SystemUI/res/drawable/stat_sys_location.xml
+++ b/packages/SystemUI/res/drawable/stat_sys_location.xml
@@ -19,11 +19,13 @@
<vector
android:width="17dp"
android:height="17dp"
- android:viewportWidth="48.0"
- android:viewportHeight="48.0">
-
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M24.0,4.0c-7.7,0.0 -14.0,6.3 -14.0,14.0c0.0,10.5 14.0,26.0 14.0,26.0s14.0,-15.5 14.0,-26.0C38.0,10.3 31.7,4.0 24.0,4.0zM24.0,23.0c-2.8,0.0 -5.0,-2.2 -5.0,-5.0s2.2,-5.0 5.0,-5.0c2.8,0.0 5.0,2.2 5.0,5.0S26.8,23.0 24.0,23.0z"/>
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13C19,5.13 15.87,2 12,2zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
</vector>
</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/back.xml b/packages/SystemUI/res/layout/back.xml
index 6843db9..4e8726b 100644
--- a/packages/SystemUI/res/layout/back.xml
+++ b/packages/SystemUI/res/layout/back.xml
@@ -22,10 +22,8 @@
android:layout_height="match_parent"
android:layout_weight="0"
systemui:keyCode="4"
- android:scaleType="fitCenter"
+ android:scaleType="center"
android:contentDescription="@string/accessibility_back"
- android:paddingTop="@dimen/home_padding"
- android:paddingBottom="@dimen/home_padding"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
new file mode 100644
index 0000000..94591e9
--- /dev/null
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/menu_container"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:importantForAccessibility="no"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ >
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/menu"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ systemui:keyCode="82"
+ systemui:playSound="false"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/ime_switcher"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_ime_switch_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/rotate_suggestion"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_rotate_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/accessibility_button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_accessibility_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/home.xml b/packages/SystemUI/res/layout/home.xml
index 7b67b79..9586327 100644
--- a/packages/SystemUI/res/layout/home.xml
+++ b/packages/SystemUI/res/layout/home.xml
@@ -21,10 +21,8 @@
android:layout_height="match_parent"
android:layout_weight="0"
systemui:keyCode="3"
- android:scaleType="fitCenter"
+ android:scaleType="center"
android:contentDescription="@string/accessibility_home"
- android:paddingTop="@dimen/home_padding"
- android:paddingBottom="@dimen/home_padding"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index d72021e..baaf699 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,16 +18,14 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/rounded_corner_content_padding"
- android:layout_marginEnd="@dimen/rounded_corner_content_padding"
- android:paddingStart="@dimen/nav_content_padding"
- android:paddingEnd="@dimen/nav_content_padding">
+ android:layout_height="match_parent">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:paddingStart="@dimen/rounded_corner_content_padding"
+ android:paddingEnd="@dimen/rounded_corner_content_padding"
android:clipChildren="false"
android:clipToPadding="false">
@@ -36,6 +34,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
+ android:paddingStart="@dimen/nav_content_padding"
+ android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
@@ -46,6 +46,8 @@
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
+ android:paddingStart="@dimen/nav_content_padding"
+ android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 0e17e5b5..6d5b7788 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,23 +18,26 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/rounded_corner_content_padding"
- android:layout_marginBottom="@dimen/rounded_corner_content_padding"
- android:paddingTop="8dp"
- android:paddingBottom="8dp">
+ android:layout_height="match_parent">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:paddingTop="@dimen/rounded_corner_content_padding"
+ android:paddingBottom="@dimen/rounded_corner_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false">
<com.android.systemui.statusbar.phone.ReverseLinearLayout
android:id="@+id/ends_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:clipChildren="false" />
+ android:paddingTop="@dimen/nav_content_padding"
+ android:paddingBottom="@dimen/nav_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
<com.android.systemui.statusbar.phone.ReverseLinearLayout
android:id="@+id/center_group"
@@ -42,7 +45,10 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- android:clipChildren="false" />
+ android:paddingTop="@dimen/nav_content_padding"
+ android:paddingBottom="@dimen/nav_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
</com.android.systemui.statusbar.phone.NearestTouchFrame>
diff --git a/packages/SystemUI/res/layout/recent_apps.xml b/packages/SystemUI/res/layout/recent_apps.xml
index 6b08cea..870bcf7 100644
--- a/packages/SystemUI/res/layout/recent_apps.xml
+++ b/packages/SystemUI/res/layout/recent_apps.xml
@@ -21,10 +21,8 @@
android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:layout_weight="0"
- android:scaleType="fitCenter"
+ android:scaleType="center"
android:contentDescription="@string/accessibility_recent"
- android:paddingTop="@dimen/home_padding"
- android:paddingBottom="@dimen/home_padding"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
/>
diff --git a/packages/SystemUI/res/layout/recents_onboarding.xml b/packages/SystemUI/res/layout/recents_onboarding.xml
index 093a7ce1..adf1e74 100644
--- a/packages/SystemUI/res/layout/recents_onboarding.xml
+++ b/packages/SystemUI/res/layout/recents_onboarding.xml
@@ -23,7 +23,7 @@
<LinearLayout
android:layout_width="wrap_content"
- android:layout_height="40dp"
+ android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingEnd="4dp"
android:background="@drawable/recents_onboarding_toast_rounded_background"
@@ -33,8 +33,9 @@
<TextView
android:id="@+id/onboarding_text"
- android:layout_width="wrap_content"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:layout_gravity="center_vertical"
android:textColor="@android:color/white"
android:textSize="16sp"/>
diff --git a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
index 7931dfe..8b56b68 100644
--- a/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_mobile_signal_group.xml
@@ -29,7 +29,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
- android:paddingStart="2dp"
android:orientation="horizontal" >
<FrameLayout
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index c70e829..e67bb60 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -93,7 +93,7 @@
android:layout_gravity="center"
android:contentDescription="@string/accessibility_volume_settings"
android:background="@drawable/ripple_drawable_20dp"
- android:tint="?android:attr/textColorHint"
+ android:tint="?android:attr/textColorSecondary"
android:soundEffectsEnabled="false" />
</FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/values-ldrtl/strings.xml b/packages/SystemUI/res/values-ldrtl/strings.xml
new file mode 100644
index 0000000..c93da69
--- /dev/null
+++ b/packages/SystemUI/res/values-ldrtl/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+ <!-- Recents: Text that shows above the navigation bar after launching several apps. [CHAR LIMIT=NONE] -->
+ <string name="recents_quick_scrub_onboarding">Drag left to quickly switch apps</string>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 923edc8..2dc6525 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -91,7 +91,4 @@
<!-- The offsets the tasks animate from when recents is launched while docking -->
<dimen name="recents_task_stack_animation_launched_while_docking_offset">192dp</dimen>
-
- <!-- Home button padding for sizing -->
- <dimen name="home_padding">0dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 2ce9bfc..3f63f22 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -141,5 +141,7 @@
<!-- Used to style rotate suggestion button AVD animations -->
<attr name="rotateButtonStartAngle" format="float" />
<attr name="rotateButtonEndAngle" format="float" />
+ <attr name="rotateButtonScaleX" format="float" />
+
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 3472477..975055c 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -104,6 +104,9 @@
<!-- The color of the navigation bar icons. Need to be in sync with ic_sysbar_* -->
<color name="navigation_bar_icon_color">#E5FFFFFF</color>
+ <!-- The shadow color for light navigation bar icons. -->
+ <color name="nav_key_button_shadow_color">#30000000</color>
+
<!-- Shadow color for the first pixels around the fake shadow for recents. -->
<color name="fake_shadow_start_color">#44000000</color>
@@ -122,9 +125,6 @@
<color name="light_mode_icon_color_dual_tone_background">#4dffffff</color>
<color name="light_mode_icon_color_dual_tone_fill">#ffffff</color>
- <color name="volume_settings_icon_color">#7fffffff</color>
- <color name="volume_slider_inactive">@*android:color/quaternary_device_default_settings</color>
-
<color name="docked_divider_background">#ff000000</color>
<color name="docked_divider_handle">#ffffff</color>
<drawable name="forced_resizable_background">#59000000</drawable>
@@ -138,7 +138,7 @@
<color name="remote_input_accent">#eeeeee</color>
<color name="quick_step_track_background_dark">#61000000</color>
- <color name="quick_step_track_background_light">#4DFFFFFF</color>
+ <color name="quick_step_track_background_light">#33FFFFFF</color>
<!-- Keyboard shortcuts colors -->
<color name="ksh_application_group_color">#fff44336</color>
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml
index cb3abb9..49bfb25 100644
--- a/packages/SystemUI/res/values/colors_car.xml
+++ b/packages/SystemUI/res/values/colors_car.xml
@@ -25,4 +25,7 @@
<color name="car_user_switcher_name_text_color">@color/car_body1_light</color>
<color name="car_user_switcher_add_user_background_color">@color/car_dark_blue_grey_600</color>
<color name="car_user_switcher_add_user_add_sign_color">@color/car_body1_light</color>
+
+ <!-- colors for volume dialog tint -->
+ <color name="car_volume_dialog_tint">@color/car_tint</color>
</resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index fb3601c..5c0d5dd 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -367,6 +367,7 @@
<!-- Nav bar button default ordering/layout -->
<string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
+ <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
<bool name="quick_settings_show_full_alarm">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 0c7c600..9a3bdf2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -201,7 +201,7 @@
<dimen name="status_bar_padding_start">6dp</dimen>
<!-- the padding on the end of the statusbar -->
- <dimen name="status_bar_padding_end">8dp</dimen>
+ <dimen name="status_bar_padding_end">6dp</dimen>
<!-- the radius of the overflow dot in the status bar -->
<dimen name="overflow_dot_radius">1dp</dimen>
@@ -867,6 +867,8 @@
<!-- The size of corner radius of the arrow in the onboarding toast. -->
<dimen name="recents_onboarding_toast_arrow_corner_radius">2dp</dimen>
+ <!-- The start margin of quick scrub onboarding toast. -->
+ <dimen name="recents_quick_scrub_onboarding_margin_start">8dp</dimen>
<!-- The min alpha to apply to a task affiliation group color. -->
<item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
@@ -938,11 +940,13 @@
<dimen name="rounded_corner_radius_bottom">0dp</dimen>
<dimen name="rounded_corner_content_padding">0dp</dimen>
<dimen name="nav_content_padding">0dp</dimen>
- <dimen name="nav_quick_scrub_track_edge_padding">42dp</dimen>
- <dimen name="nav_quick_scrub_track_thickness">2dp</dimen>
+ <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>
+ <dimen name="nav_quick_scrub_track_thickness">10dp</dimen>
- <!-- Home button padding for sizing -->
- <dimen name="home_padding">16dp</dimen>
+ <!-- Navigation bar shadow params. -->
+ <dimen name="nav_key_button_shadow_offset_x">0dp</dimen>
+ <dimen name="nav_key_button_shadow_offset_y">1dp</dimen>
+ <dimen name="nav_key_button_shadow_radius">0.5dp</dimen>
<!-- Smart reply button. Total height 48dp, visible height 32dp. -->
<dimen name="smart_reply_button_spacing">8dp</dimen>
@@ -1005,4 +1009,7 @@
<dimen name="logout_button_margin_bottom">12dp</dimen>
<dimen name="logout_button_corner_radius">2dp</dimen>
+ <!-- How much into a DisplayCutout's bounds we can go, on each side -->
+ <dimen name="display_cutout_margin_consumption">0px</dimen>
+
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index b3f4534..e4f5989 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -506,21 +506,25 @@
<style name="RotateButtonCCWStart0">
<item name="rotateButtonStartAngle">0</item>
<item name="rotateButtonEndAngle">-90</item>
+ <item name="rotateButtonScaleX">1</item>
</style>
<style name="RotateButtonCCWStart90">
<item name="rotateButtonStartAngle">90</item>
<item name="rotateButtonEndAngle">0</item>
+ <item name="rotateButtonScaleX">1</item>
</style>
<style name="RotateButtonCWStart0">
<item name="rotateButtonStartAngle">0</item>
<item name="rotateButtonEndAngle">90</item>
+ <item name="rotateButtonScaleX">-1</item>
</style>
<style name="RotateButtonCWStart90">
<item name="rotateButtonStartAngle">90</item>
<item name="rotateButtonEndAngle">180</item>
+ <item name="rotateButtonScaleX">-1</item>
</style>
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index 96ec232..cd831d1 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -37,16 +37,12 @@
return convertDpToPixel(10);
}
- public static int getQuickScrubDragSlopPx() {
- return convertDpToPixel(20);
- }
-
public static int getQuickStepTouchSlopPx() {
return convertDpToPixel(24);
}
public static int getQuickScrubTouchSlopPx() {
- return convertDpToPixel(35);
+ return convertDpToPixel(24);
}
@Retention(RetentionPolicy.SOURCE)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index b8776f7..5a84fa5 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -58,7 +58,7 @@
import androidx.slice.Slice;
import androidx.slice.SliceItem;
-import androidx.slice.SliceManager;
+import androidx.slice.SliceViewManager;
import androidx.slice.core.SliceQuery;
import androidx.slice.widget.ListContent;
import androidx.slice.widget.RowContent;
@@ -84,10 +84,9 @@
private LiveData<Slice> mLiveData;
private int mIconSize;
/**
- * Listener called whenever the view contents change.
- * Boolean will be true when the change happens animated.
+ * Runnable called whenever the view contents change.
*/
- private Consumer<Boolean> mContentChangeListener;
+ private Runnable mContentChangeListener;
private boolean mHasHeader;
private Slice mSlice;
private boolean mPulsing;
@@ -151,7 +150,9 @@
if (mPulsing || mSlice == null) {
mTitle.setVisibility(GONE);
mRow.setVisibility(GONE);
- mContentChangeListener.accept(getLayoutTransition() != null);
+ if (mContentChangeListener != null) {
+ mContentChangeListener.run();
+ }
return;
}
@@ -224,7 +225,7 @@
}
if (mContentChangeListener != null) {
- mContentChangeListener.accept(getLayoutTransition() != null);
+ mContentChangeListener.run();
}
}
@@ -311,11 +312,10 @@
}
/**
- * Listener that gets invoked every time the title or the row visibility changes.
- * Parameter will be {@code true} whenever the change happens animated.
+ * Runnable that gets invoked every time the title or the row visibility changes.
* @param contentChangeListener The listener.
*/
- public void setContentChangeListener(Consumer<Boolean> contentChangeListener) {
+ public void setContentChangeListener(Runnable contentChangeListener) {
mContentChangeListener = contentChangeListener;
}
@@ -374,7 +374,7 @@
}
public void refresh() {
- Slice slice = SliceManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
+ Slice slice = SliceViewManager.getInstance(getContext()).bindSlice(mKeyguardSliceUri);
onChanged(slice);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 585797a..c521d596 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
+import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
@@ -75,7 +76,6 @@
private float mDarkAmount = 0;
private int mTextColor;
private float mWidgetPadding;
- private boolean mAnimateLayout;
private int mLastLayoutHeight;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -179,10 +179,12 @@
mVisibleInDoze = Sets.newArraySet(mClockView, mKeyguardSlice);
mTextColor = mClockView.getCurrentTextColor();
+ int clockStroke = getResources().getDimensionPixelSize(R.dimen.widget_small_font_stroke);
+ mClockView.getPaint().setStrokeWidth(clockStroke);
mClockView.addOnLayoutChangeListener(this);
mClockSeparator.addOnLayoutChangeListener(this);
mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
- onSliceContentChanged(false /* animated */);
+ onSliceContentChanged();
boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
setEnableMarquee(shouldMarquee);
@@ -196,8 +198,7 @@
mClockView.setElegantTextHeight(false);
}
- private void onSliceContentChanged(boolean animated) {
- mAnimateLayout = animated;
+ private void onSliceContentChanged() {
boolean smallClock = mKeyguardSlice.hasHeader() || mPulsing;
float clockScale = smallClock ? mSmallClockScale : 1;
@@ -225,9 +226,12 @@
long duration = KeyguardSliceView.DEFAULT_ANIM_DURATION;
long delay = smallClock ? 0 : duration / 4;
+ boolean shouldAnimate = mKeyguardSlice.getLayoutTransition() != null
+ && mKeyguardSlice.getLayoutTransition().isRunning();
if (view == mClockView) {
float clockScale = smallClock ? mSmallClockScale : 1;
- if (mAnimateLayout) {
+ Paint.Style style = smallClock ? Paint.Style.FILL_AND_STROKE : Paint.Style.FILL;
+ if (shouldAnimate) {
mClockView.setY(oldTop + heightOffset);
mClockView.animate().cancel();
mClockView.animate()
@@ -238,16 +242,22 @@
.y(top)
.scaleX(clockScale)
.scaleY(clockScale)
+ .withEndAction(() -> {
+ mClockView.getPaint().setStyle(style);
+ mClockView.invalidate();
+ })
.start();
} else {
mClockView.setY(top);
mClockView.setScaleX(clockScale);
mClockView.setScaleY(clockScale);
+ mClockView.getPaint().setStyle(style);
+ mClockView.invalidate();
}
} else if (view == mClockSeparator) {
boolean hasSeparator = hasHeader && !mPulsing;
float alpha = hasSeparator ? 1 : 0;
- if (mAnimateLayout) {
+ if (shouldAnimate) {
boolean isAwake = mDarkAmount != 0;
mClockSeparator.setY(oldTop + heightOffset);
mClockSeparator.animate().cancel();
@@ -280,6 +290,8 @@
if (mClockView != null) {
mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
+ mClockView.getPaint().setStrokeWidth(
+ getResources().getDimensionPixelSize(R.dimen.widget_small_font_stroke));
}
if (mOwnerInfo != null) {
mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX,
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 42bd66a..9fc71c8 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -166,9 +166,7 @@
long token = Binder.clearCallingIdentity();
try {
mHandler.post(() -> {
- for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
- mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
- }
+ notifyBackButtonAlphaChanged(alpha, animate);
});
} finally {
Binder.restoreCallingIdentity(token);
@@ -355,10 +353,17 @@
mOverviewProxy.asBinder().unlinkToDeath(mOverviewServiceDeathRcpt, 0);
mContext.unbindService(mOverviewServiceConnection);
mOverviewProxy = null;
+ notifyBackButtonAlphaChanged(1f, false /* animate */);
notifyConnectionChanged();
}
}
+ private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
+ for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
+ mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
+ }
+ }
+
private void notifyConnectionChanged() {
for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
mConnectionCallbacks.get(i).onConnectionChanged(mOverviewProxy != null);
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index e91b320..21393e4 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -196,6 +196,9 @@
@Override
protected void onConfigurationChanged(Configuration newConfig) {
updateOrientation();
+ if (shouldDrawCutout() && mOverlay == null) {
+ setupDecorations();
+ }
}
protected void updateOrientation() {
@@ -207,10 +210,6 @@
updateLayoutParams();
updateViews();
}
-
- if (shouldDrawCutout() && mOverlay == null) {
- setupDecorations();
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index e6ea2d8..6d79066 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -14,6 +14,8 @@
package com.android.systemui;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
import android.app.Activity;
import android.app.AlertDialog;
import android.app.slice.SliceManager;
@@ -66,7 +68,9 @@
.setNegativeButton(R.string.slice_permission_deny, this)
.setPositiveButton(R.string.slice_permission_allow, this)
.setOnDismissListener(this)
- .show();
+ .create();
+ dialog.getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+ dialog.show();
TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1);
t1.setText(getString(R.string.slice_permission_text_1, app2));
TextView t2 = dialog.getWindow().getDecorView().findViewById(R.id.text2);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index 31d8cbb..ad84130 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -225,9 +225,10 @@
*/
boolean shouldDismissPip() {
Point displaySize = new Point();
- mContext.getDisplay().getSize(displaySize);
- if (mBounds.bottom > displaySize.y) {
- float offscreenFraction = (float) (mBounds.bottom - displaySize.y) / mBounds.height();
+ mContext.getDisplay().getRealSize(displaySize);
+ final int y = displaySize.y - mStableInsets.bottom;
+ if (mBounds.bottom > y) {
+ float offscreenFraction = (float) (mBounds.bottom - y) / mBounds.height();
return offscreenFraction >= DISMISS_OFFSCREEN_FRACTION;
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 7afa82a..100751c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -184,9 +184,15 @@
return;
}
boolean selected = mLastExpansion == 1f;
+
+ // Disable accessibility temporarily while we update selected state purely for the
+ // marquee. This will ensure that accessibility doesn't announce the TYPE_VIEW_SELECTED
+ // event on any of the children.
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
for (int i = 0; i < mPages.size(); i++) {
mPages.get(i).setSelected(i == getCurrentItem() ? selected : false);
}
+ setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO);
}
public void setPageListener(PageListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index 89f86c5..23e3f25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -110,7 +110,8 @@
@Override
public Drawable getDrawable(Context context) {
- BatterySaverDrawable b = new BatterySaverDrawable(context, 0);
+ BatterySaverDrawable b =
+ new BatterySaverDrawable(context, QSTileImpl.getColorForState(context, mState));
b.mState = mState;
final int pad = context.getResources()
.getDimensionPixelSize(R.dimen.qs_tile_divider_height);
@@ -130,11 +131,16 @@
setPowerSave(true);
setCharging(false);
setPowerSaveAsColorError(false);
+ mPowerSaveAsColorError = true;
+ mFramePaint.setColor(0);
+ mPowersavePaint.setColor(frameColor);
+ mFramePaint.setStrokeWidth(mPowersavePaint.getStrokeWidth());
+ mPlusPaint.setColor(frameColor);
}
@Override
protected int batteryColorForLevel(int level) {
- return QSTileImpl.getColorForState(mContext, mState);
+ return 0;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 6fcb1c1..7e4acc2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -123,10 +123,16 @@
*/
class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
+ private OverviewProxyService mOverviewProxyService;
+
+ public TaskStackListenerImpl() {
+ mOverviewProxyService = Dependency.get(OverviewProxyService.class);
+ }
+
@Override
public void onTaskStackChangedBackground() {
// Skip background preloading recents in SystemUI if the overview services is bound
- if (Dependency.get(OverviewProxyService.class).isEnabled()) {
+ if (mOverviewProxyService.isEnabled()) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index bcc33d2..8d8e206 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -48,7 +48,6 @@
import android.os.SystemProperties;
import android.os.UserManager;
import android.os.RemoteException;
-import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -163,8 +162,8 @@
if (mHasDismissedSwipeUpTip) {
int hasDimissedSwipeUpOnboardingCount =
getDismissedSwipeUpOnboardingCount();
- if (hasDimissedSwipeUpOnboardingCount > MAX_DISMISSAL_ON_SWIPE_UP_SHOW) {
- Log.d(TAG, "Should not be reached");
+ if (hasDimissedSwipeUpOnboardingCount
+ > MAX_DISMISSAL_ON_SWIPE_UP_SHOW) {
return;
}
final int swipeUpShowOnAppLauncherAfterDismiss =
@@ -174,7 +173,7 @@
: SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS_BACK_OFF;
mNumAppsLaunchedSinceSwipeUpTipDismiss++;
if (mNumAppsLaunchedSinceSwipeUpTipDismiss
- == swipeUpShowOnAppLauncherAfterDismiss) {
+ >= swipeUpShowOnAppLauncherAfterDismiss) {
mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
shouldLog = show(R.string.recents_swipe_up_onboarding);
}
@@ -189,7 +188,7 @@
if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
if (mHasDismissedQuickScrubTip) {
if (mOverviewOpenedCountSinceQuickScrubTipDismiss
- == QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+ >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
shouldLog = show(R.string.recents_quick_scrub_onboarding);
}
@@ -216,9 +215,9 @@
setHasSeenSwipeUpOnboarding(true);
}
if (fromHome) {
- setOpenedOverviewFromHomeCount(getOpenedOverviewFromHomeCount() + 1);
+ incrementOpenedOverviewFromHomeCount();
}
- setOpenedOverviewCount(getOpenedOverviewCount() + 1);
+ incrementOpenedOverviewCount();
if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
if (mHasDismissedQuickScrubTip) {
@@ -245,15 +244,12 @@
= new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
- Log.d(TAG, "View attached");
if (view == mLayout) {
mContext.registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
mLayoutAttachedToWindow = true;
if (view.getTag().equals(R.string.recents_swipe_up_onboarding)) {
- Log.d(TAG, "recents_swipe_up_onboarding tip attached");
mHasDismissedSwipeUpTip = false;
} else {
- Log.d(TAG, "recents_quick_scrub_onboarding tip attached");
mHasDismissedQuickScrubTip = false;
}
}
@@ -261,11 +257,9 @@
@Override
public void onViewDetachedFromWindow(View view) {
- Log.d(TAG, "View detached");
if (view == mLayout) {
mLayoutAttachedToWindow = false;
if (view.getTag().equals(R.string.recents_quick_scrub_onboarding)) {
- Log.d(TAG, "recents_quick_scrub_onboarding tip detached");
mHasDismissedQuickScrubTip = true;
if (hasDismissedQuickScrubOnboardingOnce()) {
// If user dismisses the quick scrub tip twice, we consider user has seen it
@@ -353,29 +347,23 @@
return;
}
- Log.d(TAG, "Connecting to launcher");
if (!mOverviewProxyListenerRegistered) {
- Log.d(TAG, "Registering mOverviewProxyListener");
mOverviewProxyService.addCallback(mOverviewProxyListener);
mOverviewProxyListenerRegistered = true;
}
if (!mTaskListenerRegistered) {
- Log.d(TAG, "Registering mTaskListener");
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskListener);
mTaskListenerRegistered = true;
}
}
public void onDisconnectedFromLauncher() {
- Log.d(TAG, "Disconnecting to launcher");
if (mOverviewProxyListenerRegistered) {
- Log.d(TAG, "Unregistering mOverviewProxyListener");
mOverviewProxyService.removeCallback(mOverviewProxyListener);
mOverviewProxyListenerRegistered = false;
}
if (mTaskListenerRegistered) {
- Log.d(TAG, "Unregistering mTaskListener");
ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskListener);
mTaskListenerRegistered = false;
}
@@ -403,11 +391,22 @@
// Only show in portrait.
int orientation = mContext.getResources().getConfiguration().orientation;
if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
- Log.d(TAG, "Show " + (stringRes == R.string.recents_swipe_up_onboarding
- ? "recents_swipe_up_onboarding" : "recents_quick_scrub_onboarding") + " tip");
mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
- mWindowManager.addView(mLayout, getWindowLayoutParams());
+ final int gravity;
+ final int x;
+ if (stringRes == R.string.recents_swipe_up_onboarding) {
+ gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
+ x = 0;
+ } else {
+ int layoutDirection =
+ mContext.getResources().getConfiguration().getLayoutDirection();
+ gravity = Gravity.BOTTOM | (layoutDirection == View.LAYOUT_DIRECTION_LTR
+ ? Gravity.LEFT : Gravity.RIGHT);
+ x = mContext.getResources().getDimensionPixelSize(
+ R.dimen.recents_quick_scrub_onboarding_margin_start);
+ }
+ mWindowManager.addView(mLayout, getWindowLayoutParams(gravity, x));
mLayout.setAlpha(0);
mLayout.animate()
.alpha(1f)
@@ -433,7 +432,6 @@
public void hide(boolean animate) {
if (mLayoutAttachedToWindow) {
- Log.d(TAG, "Hide tip, animated: " + animate);
if (animate) {
mLayout.animate()
.alpha(0f)
@@ -474,19 +472,19 @@
pw.println(" }");
}
- private WindowManager.LayoutParams getWindowLayoutParams() {
+ private WindowManager.LayoutParams getWindowLayoutParams(int gravity, int x) {
int flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
- 0, -mNavBarHeight / 2,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ x, -mNavBarHeight / 2,
WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
flags,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
lp.setTitle("RecentsOnboarding");
- lp.gravity = Gravity.BOTTOM;
+ lp.gravity = gravity;
return lp;
}
@@ -495,7 +493,6 @@
}
private void setHasSeenSwipeUpOnboarding(boolean hasSeenSwipeUpOnboarding) {
- Log.d(TAG, "setHasSeenSwipeUpOnboarding: " + hasSeenSwipeUpOnboarding);
Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING, hasSeenSwipeUpOnboarding);
if (hasSeenSwipeUpOnboarding && hasSeenQuickScrubOnboarding()) {
onDisconnectedFromLauncher();
@@ -507,7 +504,6 @@
}
private void setHasSeenQuickScrubOnboarding(boolean hasSeenQuickScrubOnboarding) {
- Log.d(TAG, "setHasSeenQuickScrubOnboarding: " + hasSeenQuickScrubOnboarding);
Prefs.putBoolean(mContext, HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING,
hasSeenQuickScrubOnboarding);
if (hasSeenQuickScrubOnboarding && hasSeenSwipeUpOnboarding()) {
@@ -520,7 +516,6 @@
}
private void setDismissedSwipeUpOnboardingCount(int dismissedSwipeUpOnboardingCount) {
- Log.d(TAG, "setDismissedSwipeUpOnboardingCount: " + dismissedSwipeUpOnboardingCount);
Prefs.putInt(mContext, DISMISSED_RECENTS_SWIPE_UP_ONBOARDING_COUNT,
dismissedSwipeUpOnboardingCount);
}
@@ -531,8 +526,6 @@
private void setHasDismissedQuickScrubOnboardingOnce(
boolean hasDismissedQuickScrubOnboardingOnce) {
- Log.d(TAG,
- "setHasDismissedQuickScrubOnboardingOnce: " + hasDismissedQuickScrubOnboardingOnce);
Prefs.putBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE,
hasDismissedQuickScrubOnboardingOnce);
}
@@ -541,8 +534,15 @@
return Prefs.getInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, 0);
}
+ private void incrementOpenedOverviewFromHomeCount() {
+ int openedOverviewFromHomeCount = getOpenedOverviewFromHomeCount();
+ if (openedOverviewFromHomeCount >= SWIPE_UP_SHOW_ON_OVERVIEW_OPENED_FROM_HOME_COUNT) {
+ return;
+ }
+ setOpenedOverviewFromHomeCount(openedOverviewFromHomeCount + 1);
+ }
+
private void setOpenedOverviewFromHomeCount(int openedOverviewFromHomeCount) {
- Log.d(TAG, "setOpenedOverviewFromHomeCount: " + openedOverviewFromHomeCount);
Prefs.putInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, openedOverviewFromHomeCount);
}
@@ -550,8 +550,15 @@
return Prefs.getInt(mContext, OVERVIEW_OPENED_COUNT, 0);
}
+ private void incrementOpenedOverviewCount() {
+ int openedOverviewCount = getOpenedOverviewCount();
+ if (openedOverviewCount >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+ return;
+ }
+ setOpenedOverviewCount(openedOverviewCount + 1);
+ }
+
private void setOpenedOverviewCount(int openedOverviewCount) {
- Log.d(TAG, "setOpenedOverviewCount: " + openedOverviewCount);
Prefs.putInt(mContext, OVERVIEW_OPENED_COUNT, openedOverviewCount);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
index 167df8c..481d54f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java
@@ -28,6 +28,7 @@
import android.os.Binder;
import android.os.RemoteException;
import android.util.DisplayMetrics;
+import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +41,7 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.statusbar.phone.NavigationBarView;
@@ -259,10 +261,16 @@
}
if (navigationBarView != null) {
+ int dualToneDarkTheme = Utils.getThemeAttr(getContext(), R.attr.darkIconTheme);
+ int dualToneLightTheme = Utils.getThemeAttr(getContext(), R.attr.lightIconTheme);
+ Context lightContext = new ContextThemeWrapper(getContext(), dualToneLightTheme);
+ Context darkContext = new ContextThemeWrapper(getContext(), dualToneDarkTheme);
((ImageView) mLayout.findViewById(R.id.screen_pinning_back_icon))
- .setImageDrawable(navigationBarView.getBackDrawable(mContext));
+ .setImageDrawable(navigationBarView.getBackDrawable(lightContext,
+ darkContext));
((ImageView) mLayout.findViewById(R.id.screen_pinning_home_icon))
- .setImageDrawable(navigationBarView.getHomeDrawable(mContext));
+ .setImageDrawable(navigationBarView.getHomeDrawable(lightContext,
+ darkContext));
}
((TextView) mLayout.findViewById(R.id.screen_pinning_description))
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 364ed80..6a38797 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -515,6 +515,13 @@
}
}
+ @Override
+ public void setDistanceToTopRoundness(float distanceToTopRoundness) {
+ super.setDistanceToTopRoundness(distanceToTopRoundness);
+ mBackgroundNormal.setDistanceToTopRoundness(distanceToTopRoundness);
+ mBackgroundDimmed.setDistanceToTopRoundness(distanceToTopRoundness);
+ }
+
/**
* Set an override tint color that is used for the background.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index d03da8f..d647e21 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -710,6 +710,8 @@
updateClickAndFocus();
if (mNotificationParent != null) {
setOverrideTintColor(NO_COLOR, 0.0f);
+ // Let's reset the distance to top roundness, as this isn't applied to group children
+ setDistanceToTopRoundness(NO_ROUNDNESS);
mNotificationParent.updateBackgroundForGroupState();
}
updateIconVisibilities();
@@ -2795,6 +2797,24 @@
}
@Override
+ public boolean topAmountNeedsClipping() {
+ if (isGroupExpanded()) {
+ return true;
+ }
+ if (isGroupExpansionChanging()) {
+ return true;
+ }
+ if (getShowingLayout().shouldClipToRounding(true /* topRounded */,
+ false /* bottomRounded */)) {
+ return true;
+ }
+ if (mGuts != null && mGuts.getAlpha() != 0.0f) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
protected boolean childNeedsClipping(View child) {
if (child instanceof NotificationContentView) {
NotificationContentView contentView = (NotificationContentView) child;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index 67268c0..edfa61b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -76,7 +76,7 @@
* it is moved. Otherwise, the translation is set on the {@code ExpandableOutlineView} itself.
*/
protected boolean mShouldTranslateContents;
- private boolean mClipRoundedToClipTopAmount;
+ private boolean mTopAmountRounded;
private float mDistanceToTopRoundness = -1;
private float mExtraWidthForClipping;
private int mMinimumHeightForClipping = 0;
@@ -85,7 +85,8 @@
@Override
public void getOutline(View view, Outline outline) {
if (!mCustomOutline && mCurrentTopRoundness == 0.0f
- && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners) {
+ && mCurrentBottomRoundness == 0.0f && !mAlwaysRoundBothCorners
+ && !mTopAmountRounded) {
int translation = mShouldTranslateContents ? (int) getTranslation() : 0;
int left = Math.max(translation, 0);
int top = mClipTopAmount + mBackgroundTop;
@@ -145,9 +146,9 @@
return EMPTY_PATH;
}
float topRoundness = mAlwaysRoundBothCorners
- ? mOutlineRadius : mCurrentTopRoundness * mOutlineRadius;
+ ? mOutlineRadius : getCurrentBackgroundRadiusTop();
float bottomRoundness = mAlwaysRoundBothCorners
- ? mOutlineRadius : mCurrentBottomRoundness * mOutlineRadius;
+ ? mOutlineRadius : getCurrentBackgroundRadiusBottom();
if (topRoundness + bottomRoundness > height) {
float overShoot = topRoundness + bottomRoundness - height;
topRoundness -= overShoot * mCurrentTopRoundness
@@ -203,7 +204,7 @@
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save();
Path intersectPath = null;
- if (mClipRoundedToClipTopAmount) {
+ if (mTopAmountRounded && topAmountNeedsClipping()) {
int left = (int) (- mExtraWidthForClipping / 2.0f);
int top = (int) (mClipTopAmount - mDistanceToTopRoundness);
int right = getWidth() + (int) (mExtraWidthForClipping + left);
@@ -248,9 +249,9 @@
public void setDistanceToTopRoundness(float distanceToTopRoundness) {
super.setDistanceToTopRoundness(distanceToTopRoundness);
if (distanceToTopRoundness != mDistanceToTopRoundness) {
- mClipRoundedToClipTopAmount = distanceToTopRoundness >= 0;
+ mTopAmountRounded = distanceToTopRoundness >= 0;
mDistanceToTopRoundness = distanceToTopRoundness;
- invalidate();
+ applyRoundness();
}
}
@@ -258,9 +259,12 @@
return false;
}
+ public boolean topAmountNeedsClipping() {
+ return true;
+ }
+
protected boolean isClippingNeeded() {
return mAlwaysRoundBothCorners || mCustomOutline || getTranslation() != 0 ;
-
}
private void initDimens() {
@@ -296,6 +300,11 @@
}
public float getCurrentBackgroundRadiusTop() {
+ // If this view is top amount notification view, it should always has round corners on top.
+ // It will be applied with applyRoundness()
+ if (mTopAmountRounded) {
+ return mOutlineRadius;
+ }
return mCurrentTopRoundness * mOutlineRadius;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 29c3ebd..ae8d844 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -36,6 +36,7 @@
*/
public abstract class ExpandableView extends FrameLayout {
+ public static final float NO_ROUNDNESS = -1;
protected OnHeightChangedListener mOnHeightChangedListener;
private int mActualHeight;
protected int mClipTopAmount;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index 0ff4dde..969e9d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -53,6 +53,9 @@
private int mDrawableAlpha = 255;
private boolean mIsPressedAllowed;
+ private boolean mTopAmountRounded;
+ private float mDistanceToTopRoundness;
+
public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
mDontModifyCorners = getResources().getBoolean(
@@ -74,6 +77,7 @@
private void draw(Canvas canvas, Drawable drawable) {
if (drawable != null) {
+ int top = mBackgroundTop;
int bottom = mActualHeight;
if (mBottomIsRounded && mBottomAmountClips && !mExpandAnimationRunning) {
bottom -= mClipBottomAmount;
@@ -84,7 +88,14 @@
left = (int) ((getWidth() - mActualWidth) / 2.0f);
right = (int) (left + mActualWidth);
}
- drawable.setBounds(left, mBackgroundTop, right, bottom);
+ if (mTopAmountRounded) {
+ int clipTop = (int) (mClipTopAmount - mDistanceToTopRoundness);
+ top += clipTop;
+ if (clipTop >= 0) {
+ bottom += clipTop;
+ }
+ }
+ drawable.setBounds(left, top, right, bottom);
drawable.draw(canvas);
}
}
@@ -165,6 +176,14 @@
invalidate();
}
+ public void setDistanceToTopRoundness(float distanceToTopRoundness) {
+ if (distanceToTopRoundness != mDistanceToTopRoundness) {
+ mTopAmountRounded = distanceToTopRoundness >= 0;
+ mDistanceToTopRoundness = distanceToTopRoundness;
+ invalidate();
+ }
+ }
+
@Override
public boolean hasOverlappingRendering() {
@@ -198,6 +217,9 @@
}
public void setRoundness(float topRoundness, float bottomRoundNess) {
+ if (topRoundness == mCornerRadii[0] && bottomRoundNess == mCornerRadii[4]) {
+ return;
+ }
mBottomIsRounded = bottomRoundNess != 0.0f;
mCornerRadii[0] = topRoundness;
mCornerRadii[1] = topRoundness;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index 03791c7..91a4dda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -182,6 +182,9 @@
}
}
if (mReplyAction != null) {
+ // Let's reset the view on update, assuming the new pending intent isn't cancelled
+ // anymore. The color filter automatically resets when it's updated.
+ mReplyAction.setEnabled(true);
performOnPendingIntentCancellation(mReplyAction, () -> {
if (mReplyAction != null && mReplyAction.isEnabled()) {
mReplyAction.setEnabled(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 8ede224..879ac92 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -16,11 +16,8 @@
package com.android.systemui.statusbar.notification;
-import android.util.ArraySet;
import android.util.Pools;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.ProgressBar;
@@ -411,7 +408,8 @@
mOwnPosition[1] -= (1.0f - mTransformedView.getScaleY()) * mTransformedView.getPivotY();
// Remove local translations
- mOwnPosition[1] -= MessagingPropertyAnimator.getLocalTranslationY(mTransformedView);
+ mOwnPosition[1] -= MessagingPropertyAnimator.getTop(mTransformedView)
+ - MessagingPropertyAnimator.getLayoutTop(mTransformedView);
return mOwnPosition;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 3c0b226..894ea62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -114,6 +114,10 @@
return mVisibility != null ? mVisibility : View.VISIBLE;
}
+ public boolean isVisible() {
+ return getVisibility() == View.VISIBLE;
+ }
+
public float getAlpha() {
return mAlpha != null ? mAlpha : 1;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index e2fec85..e096f3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -90,6 +90,11 @@
private ViewGroup mStatusIconArea;
private int mLayoutState = LAYOUT_NONE;
+ /**
+ * Draw this many pixels into the left/right side of the cutout to optimally use the space
+ */
+ private int mCutoutSideNudge = 0;
+
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -158,6 +163,8 @@
R.dimen.system_icons_switcher_hidden_expanded_margin);
mSystemIconsBaseMargin = res.getDimensionPixelSize(
R.dimen.system_icons_super_container_avatarless_margin_end);
+ mCutoutSideNudge = getResources().getDimensionPixelSize(
+ R.dimen.display_cutout_margin_consumption);
}
private void updateVisibilities() {
@@ -266,6 +273,8 @@
mCutoutSpace.setVisibility(View.VISIBLE);
RelativeLayout.LayoutParams lp = (LayoutParams) mCutoutSpace.getLayoutParams();
+ bounds.left = bounds.left + mCutoutSideNudge;
+ bounds.right = bounds.right - mCutoutSideNudge;
lp.width = bounds.width();
lp.height = bounds.height();
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index cfc8715..f9a540c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -1144,6 +1144,8 @@
mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS);
mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS);
mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS);
+ mRoot.postOnAnimationDelayed(mRipple, 3*RIPPLE_INTERVAL_MS);
+ mRoot.postOnAnimationDelayed(mRipple, 4*RIPPLE_INTERVAL_MS);
}
public void stop() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 4885c2f..e6f2c33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -34,11 +34,12 @@
import android.widget.Space;
import com.android.systemui.Dependency;
+import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
-import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -67,6 +68,7 @@
public static final String KEY = "key";
public static final String LEFT = "left";
public static final String RIGHT = "right";
+ public static final String CONTEXTUAL = "contextual";
public static final String GRAVITY_SEPARATOR = ";";
public static final String BUTTON_SEPARATOR = ",";
@@ -97,6 +99,9 @@
private View mLastLandscape;
private boolean mAlternativeOrder;
+ private boolean mUsingCustomLayout;
+
+ private OverviewProxyService mOverviewProxyService;
public NavigationBarInflaterView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -105,6 +110,7 @@
context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Mode displayMode = mDisplay.getMode();
isRot0Landscape = displayMode.getPhysicalWidth() > displayMode.getPhysicalHeight();
+ mOverviewProxyService = Dependency.get(OverviewProxyService.class);
}
private void createInflaters() {
@@ -136,7 +142,10 @@
}
protected String getDefaultLayout() {
- return mContext.getString(R.string.config_navBarLayout);
+ final int defaultResource = mOverviewProxyService.shouldShowSwipeUpUI()
+ ? R.string.config_navBarLayoutQuickstep
+ : R.string.config_navBarLayout;
+ return mContext.getString(defaultResource);
}
@Override
@@ -159,6 +168,7 @@
public void onTuningChanged(String key, String newValue) {
if (NAV_BAR_VIEWS.equals(key)) {
if (!Objects.equals(mCurrentLayout, newValue)) {
+ mUsingCustomLayout = newValue != null;
clearViews();
inflateLayout(newValue);
}
@@ -168,6 +178,18 @@
}
}
+ public void onLikelyDefaultLayoutChange() {
+ // Don't override custom layouts
+ if (mUsingCustomLayout) return;
+
+ // Reevaluate new layout
+ final String newValue = getDefaultLayout();
+ if (!Objects.equals(mCurrentLayout, newValue)) {
+ clearViews();
+ inflateLayout(newValue);
+ }
+ }
+
public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
mButtonDispatchers = buttonDispatchers;
for (int i = 0; i < buttonDispatchers.size(); i++) {
@@ -178,10 +200,12 @@
public void updateButtonDispatchersCurrentView() {
if (mButtonDispatchers != null) {
final int rotation = mDisplay.getRotation();
- final View view = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
- ? mRot0 : mRot90;
+ final boolean portrait = rotation == Surface.ROTATION_0
+ || rotation == Surface.ROTATION_180;
+ final View view = portrait ? mRot0 : mRot90;
for (int i = 0; i < mButtonDispatchers.size(); i++) {
- mButtonDispatchers.valueAt(i).setCurrentView(view);
+ final ButtonDispatcher dispatcher = mButtonDispatchers.valueAt(i);
+ dispatcher.setCurrentView(view);
}
}
}
@@ -288,8 +312,8 @@
addToDispatchers(v);
View lastView = landscape ? mLastLandscape : mLastPortrait;
View accessibilityView = v;
- if (v instanceof ReverseFrameLayout) {
- accessibilityView = ((ReverseFrameLayout) v).getChildAt(0);
+ if (v instanceof ReverseRelativeLayout) {
+ accessibilityView = ((ReverseRelativeLayout) v).getChildAt(0);
}
if (lastView != null) {
accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
@@ -307,21 +331,33 @@
if (sizeStr == null) return v;
if (sizeStr.contains(WEIGHT_SUFFIX)) {
+ // To support gravity, wrap in RelativeLayout and apply gravity to it.
+ // Children wanting to use gravity must be smaller then the frame.
float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
- FrameLayout frame = new ReverseFrameLayout(mContext);
+ ReverseRelativeLayout frame = new ReverseRelativeLayout(mContext);
LayoutParams childParams = new LayoutParams(v.getLayoutParams());
- if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
- childParams.gravity = Gravity.CENTER;
- } else {
- childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
- : (start ? Gravity.START : Gravity.END);
- }
+
+ // Compute gravity to apply
+ int gravity = (landscape) ? (start ? Gravity.TOP : Gravity.BOTTOM)
+ : (start ? Gravity.START : Gravity.END);
+ if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) gravity = Gravity.CENTER;
+
+ // Set default gravity, flipped if needed in reversed layouts (270 RTL and 90 LTR)
+ frame.setDefaultGravity(gravity);
+ frame.setGravity(gravity); // Apply gravity to root
+
frame.addView(v, childParams);
+
+ // Use weighting to set the width of the frame
frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+
+ // Ensure ripples can be drawn outside bounds
frame.setClipChildren(false);
frame.setClipToPadding(false);
+
return frame;
}
+
float size = Float.parseFloat(sizeStr);
ViewGroup.LayoutParams params = v.getLayoutParams();
params.width = (int) (params.width * size);
@@ -355,6 +391,8 @@
v = inflater.inflate(R.layout.nav_key_space, parent, false);
} else if (CLIPBOARD.equals(button)) {
v = inflater.inflate(R.layout.clipboard, parent, false);
+ } else if (CONTEXTUAL.equals(button)) {
+ v = inflater.inflate(R.layout.contextual, parent, false);
} else if (button.startsWith(KEY)) {
String uri = extractImage(button);
int code = extractKeycode(button);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 9261d2e..a3cba2d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -39,7 +39,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.os.RemoteException;
import android.os.SystemProperties;
import androidx.annotation.ColorInt;
import android.util.AttributeSet;
@@ -118,8 +117,9 @@
private Rect mRecentsButtonBounds = new Rect();
private Rect mRotationButtonBounds = new Rect();
private int[] mTmpPosition = new int[2];
+ private Rect mTmpRect = new Rect();
- private KeyButtonDrawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
+ private KeyButtonDrawable mBackIcon;
private KeyButtonDrawable mBackCarModeIcon, mBackLandCarModeIcon;
private KeyButtonDrawable mBackAltCarModeIcon, mBackAltLandCarModeIcon;
private KeyButtonDrawable mHomeDefaultIcon, mHomeCarModeIcon;
@@ -336,13 +336,14 @@
int x = (int) event.getX();
int y = (int) event.getY();
mDownHitTarget = HIT_TARGET_NONE;
- if (mBackButtonBounds.contains(x, y)) {
+ if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) {
mDownHitTarget = HIT_TARGET_BACK;
- } else if (mHomeButtonBounds.contains(x, y)) {
+ } else if (getHomeButton().isVisible() && mHomeButtonBounds.contains(x, y)) {
mDownHitTarget = HIT_TARGET_HOME;
- } else if (mRecentsButtonBounds.contains(x, y)) {
+ } else if (getRecentsButton().isVisible() && mRecentsButtonBounds.contains(x, y)) {
mDownHitTarget = HIT_TARGET_OVERVIEW;
- } else if (mRotationButtonBounds.contains(x, y)) {
+ } else if (getRotateSuggestionButton().isVisible()
+ && mRotationButtonBounds.contains(x, y)) {
mDownHitTarget = HIT_TARGET_ROTATION;
}
break;
@@ -453,6 +454,7 @@
&& ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
}
+ // TODO(b/80003212): change car mode icons to vector icons.
private void updateCarModeIcons(Context ctx) {
mBackCarModeIcon = getDrawable(ctx,
R.drawable.ic_sysbar_back_carmode, R.drawable.ic_sysbar_back_carmode);
@@ -469,33 +471,27 @@
}
private void updateIcons(Context ctx, Configuration oldConfig, Configuration newConfig) {
+ int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
+ int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
+ Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
+ Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
+
if (oldConfig.orientation != newConfig.orientation
|| oldConfig.densityDpi != newConfig.densityDpi) {
- mDockedIcon = getDrawable(ctx,
- R.drawable.ic_sysbar_docked, R.drawable.ic_sysbar_docked_dark);
- mHomeDefaultIcon = getHomeDrawable(ctx);
+ mDockedIcon = getDrawable(lightContext, darkContext, R.drawable.ic_sysbar_docked);
+ mHomeDefaultIcon = getHomeDrawable(lightContext, darkContext);
}
if (oldConfig.densityDpi != newConfig.densityDpi
|| oldConfig.getLayoutDirection() != newConfig.getLayoutDirection()) {
- mBackIcon = getBackDrawable(ctx);
- mBackLandIcon = mBackIcon;
- mBackAltIcon = getBackImeDrawable(ctx);
- mBackAltLandIcon = mBackAltIcon;
- mRecentIcon = getDrawable(ctx,
- R.drawable.ic_sysbar_recent, R.drawable.ic_sysbar_recent_dark);
- mMenuIcon = getDrawable(ctx, R.drawable.ic_sysbar_menu, R.drawable.ic_sysbar_menu_dark);
+ mBackIcon = getBackDrawable(lightContext, darkContext);
+ mRecentIcon = getDrawable(lightContext, darkContext, R.drawable.ic_sysbar_recent);
+ mMenuIcon = getDrawable(lightContext, darkContext, R.drawable.ic_sysbar_menu);
- int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
- int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
- Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
- Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
+ mAccessibilityIcon = getDrawable(lightContext, darkContext,
+ R.drawable.ic_sysbar_accessibility_button, false /* hasShadow */);
- mAccessibilityIcon = getDrawable(darkContext, lightContext,
- R.drawable.ic_sysbar_accessibility_button,
- R.drawable.ic_sysbar_accessibility_button);
-
- mImeIcon = getDrawable(darkContext, lightContext,
- R.drawable.ic_ime_switcher_default, R.drawable.ic_ime_switcher_default);
+ mImeIcon = getDrawable(lightContext, darkContext, R.drawable.ic_ime_switcher_default,
+ false /* hasShadow */);
updateRotateSuggestionButtonStyle(mRotateBtnStyle, false);
@@ -505,42 +501,58 @@
}
}
- public KeyButtonDrawable getBackDrawable(Context ctx) {
- return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_back,
- R.drawable.ic_sysbar_back_dark, R.drawable.ic_sysbar_back_quick_step,
- R.drawable.ic_sysbar_back_quick_step_dark);
+ public KeyButtonDrawable getBackDrawable(Context lightContext, Context darkContext) {
+ KeyButtonDrawable drawable = chooseNavigationIconDrawable(lightContext, darkContext,
+ R.drawable.ic_sysbar_back, R.drawable.ic_sysbar_back_quick_step);
+ orientBackButton(drawable);
+ return drawable;
}
- public KeyButtonDrawable getBackImeDrawable(Context ctx) {
- return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_back_ime,
- R.drawable.ic_sysbar_back_ime_dark, R.drawable.ic_sysbar_back_ime_quick_step,
- R.drawable.ic_sysbar_back_ime_quick_step_dark);
+ public KeyButtonDrawable getHomeDrawable(Context lightContext, Context darkContext) {
+ final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI();
+ KeyButtonDrawable drawable = quickStepEnabled
+ ? getDrawable(lightContext, darkContext, R.drawable.ic_sysbar_home_quick_step)
+ : getDrawable(lightContext, darkContext, R.drawable.ic_sysbar_home,
+ false /* hasShadow */);
+ orientHomeButton(drawable);
+ return drawable;
}
- public KeyButtonDrawable getHomeDrawable(Context ctx) {
- return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_home,
- R.drawable.ic_sysbar_home_dark, R.drawable.ic_sysbar_home_quick_step,
- R.drawable.ic_sysbar_home_quick_step_dark);
+ private void orientBackButton(KeyButtonDrawable drawable) {
+ final boolean useAltBack =
+ (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+ drawable.setRotation(useAltBack
+ ? -90 : (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) ? 180 : 0);
}
- private KeyButtonDrawable chooseNavigationIconDrawable(Context ctx, @DrawableRes int iconLight,
- @DrawableRes int iconDark, @DrawableRes int quickStepIconLight,
- @DrawableRes int quickStepIconDark) {
+ private void orientHomeButton(KeyButtonDrawable drawable) {
+ drawable.setRotation(mVertical ? 90 : 0);
+ }
+
+ private KeyButtonDrawable chooseNavigationIconDrawable(Context lightContext,
+ Context darkContext, @DrawableRes int icon, @DrawableRes int quickStepIcon) {
final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI();
return quickStepEnabled
- ? getDrawable(ctx, quickStepIconLight, quickStepIconDark)
- : getDrawable(ctx, iconLight, iconDark);
+ ? getDrawable(lightContext, darkContext, quickStepIcon)
+ : getDrawable(lightContext, darkContext, icon);
+ }
+
+ private KeyButtonDrawable getDrawable(Context lightContext, Context darkContext,
+ @DrawableRes int icon) {
+ return getDrawable(lightContext, darkContext, icon, true /* hasShadow */);
+ }
+
+ private KeyButtonDrawable getDrawable(Context lightContext, Context darkContext,
+ @DrawableRes int icon, boolean hasShadow) {
+ return KeyButtonDrawable.create(lightContext, lightContext.getDrawable(icon),
+ darkContext.getDrawable(icon), hasShadow);
}
private KeyButtonDrawable getDrawable(Context ctx, @DrawableRes int lightIcon,
@DrawableRes int darkIcon) {
- return getDrawable(ctx, ctx, lightIcon, darkIcon);
- }
-
- private KeyButtonDrawable getDrawable(Context darkContext, Context lightContext,
- @DrawableRes int lightIcon, @DrawableRes int darkIcon) {
- return KeyButtonDrawable.create(lightContext.getDrawable(lightIcon),
- darkContext.getDrawable(darkIcon));
+ // Legacy image icons using separate light and dark images will not support shadows
+ return KeyButtonDrawable.create(ctx, ctx.getDrawable(lightIcon),
+ ctx.getDrawable(darkIcon), false /* hasShadow */);
}
private TintedKeyButtonDrawable getDrawable(Context ctx, @DrawableRes int icon,
@@ -557,13 +569,13 @@
private KeyButtonDrawable getBackIconWithAlt(boolean carMode, boolean landscape) {
return landscape
- ? carMode ? mBackAltLandCarModeIcon : mBackAltLandIcon
- : carMode ? mBackAltCarModeIcon : mBackAltIcon;
+ ? carMode ? mBackAltLandCarModeIcon : mBackIcon
+ : carMode ? mBackAltCarModeIcon : mBackIcon;
}
private KeyButtonDrawable getBackIcon(boolean carMode, boolean landscape) {
return landscape
- ? carMode ? mBackLandCarModeIcon : mBackLandIcon
+ ? carMode ? mBackLandCarModeIcon : mBackIcon
: carMode ? mBackCarModeIcon : mBackIcon;
}
@@ -594,26 +606,28 @@
}
updateNavButtonIcons();
+ updateSlippery();
}
public void updateNavButtonIcons() {
// We have to replace or restore the back and home button icons when exiting or entering
// carmode, respectively. Recents are not available in CarMode in nav bar so change
// to recent icon is not required.
- KeyButtonDrawable backIcon
- = ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0)
- ? getBackIconWithAlt(mUseCarModeUi, mVertical)
- : getBackIcon(mUseCarModeUi, mVertical);
+ final boolean useAltBack =
+ (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
+ KeyButtonDrawable backIcon = useAltBack
+ ? getBackIconWithAlt(mUseCarModeUi, mVertical)
+ : getBackIcon(mUseCarModeUi, mVertical);
+ KeyButtonDrawable homeIcon = mUseCarModeUi ? mHomeCarModeIcon : mHomeDefaultIcon;
+ if (!mUseCarModeUi) {
+ orientBackButton(backIcon);
+ orientHomeButton(homeIcon);
+ }
+ getHomeButton().setImageDrawable(homeIcon);
getBackButton().setImageDrawable(backIcon);
updateRecentsIcon();
- if (mUseCarModeUi) {
- getHomeButton().setImageDrawable(mHomeCarModeIcon);
- } else {
- getHomeButton().setImageDrawable(mHomeDefaultIcon);
- }
-
// Update IME button visibility, a11y and rotate button always overrides the appearance
final boolean showImeButton =
!mShowAccessibilityButton &&
@@ -640,8 +654,7 @@
// Always disable recents when alternate car mode UI is active.
boolean disableRecent = mUseCarModeUi || !isOverviewEnabled();
- boolean disableBack = ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
- && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
+ boolean disableBack = ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack;
// When screen pinning, don't hide back and home when connected service or back and
// recents buttons when disconnected from launcher service in screen pinning mode,
@@ -735,6 +748,12 @@
public void updateStates() {
final boolean showSwipeUpUI = mOverviewProxyService.shouldShowSwipeUpUI();
+
+ if (mNavigationInflaterView != null) {
+ // Reinflate the navbar if needed, no-op unless the swipe up state changes
+ mNavigationInflaterView.onLikelyDefaultLayoutChange();
+ }
+
updateSlippery();
reloadNavIcons();
updateNavButtonIcons();
@@ -859,14 +878,27 @@
public boolean isRotateButtonVisible() { return mShowRotateButton; }
- public void setMenuContainerVisibility(boolean visible) {
- getMenuContainer().setAlpha(visible ? 1 : 0, true /* animate */);
+ /**
+ * @return the button at the given {@param x} and {@param y}.
+ */
+ ButtonDispatcher getButtonAtPosition(int x, int y) {
+ for (int i = 0; i < mButtonDispatchers.size(); i++) {
+ ButtonDispatcher button = mButtonDispatchers.valueAt(i);
+ View buttonView = button.getCurrentView();
+ if (buttonView != null) {
+ buttonView.getHitRect(mTmpRect);
+ offsetDescendantRectToMyCoords(buttonView, mTmpRect);
+ if (mTmpRect.contains(x, y)) {
+ return button;
+ }
+ }
+ }
+ return null;
}
@Override
public void onFinishInflate() {
- mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
- R.id.navigation_inflater);
+ mNavigationInflaterView = findViewById(R.id.navigation_inflater);
mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
@@ -945,6 +977,7 @@
}
private void updateRecentsIcon() {
+ mDockedIcon.setRotation(mDockedStackExists && mVertical ? 90 : 0);
getRecentsButton().setImageDrawable(mDockedStackExists ? mDockedIcon : mRecentIcon);
mBarTransitions.reapplyDarkIntensity();
}
@@ -1158,10 +1191,11 @@
+ " " + visibilityToString(getWindowVisibility())
+ (offscreen ? " OFFSCREEN!" : ""));
- pw.println(String.format(" mCurrentView: id=%s (%dx%d) %s",
+ pw.println(String.format(" mCurrentView: id=%s (%dx%d) %s %f",
getResourceName(getCurrentView().getId()),
getCurrentView().getWidth(), getCurrentView().getHeight(),
- visibilityToString(getCurrentView().getVisibility())));
+ visibilityToString(getCurrentView().getVisibility()),
+ getCurrentView().getAlpha()));
pw.println(String.format(" disabled=0x%08x vertical=%s menu=%s",
mDisabledFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 01582d0..5477f88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -74,6 +74,10 @@
private View mCutoutSpace;
@Nullable
private DisplayCutout mDisplayCutout;
+ /**
+ * Draw this many pixels into the left/right side of the cutout to optimally use the space
+ */
+ private int mCutoutSideNudge = 0;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -98,6 +102,8 @@
mBarTransitions.init();
mBattery = findViewById(R.id.battery);
mCutoutSpace = findViewById(R.id.cutout_space_view);
+
+ updateResources();
}
@Override
@@ -280,6 +286,9 @@
}
public void updateResources() {
+ mCutoutSideNudge = getResources().getDimensionPixelSize(
+ R.dimen.display_cutout_margin_consumption);
+
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.height = getResources().getDimensionPixelSize(
R.dimen.status_bar_height);
@@ -311,6 +320,8 @@
Rect bounds = new Rect();
boundsFromDirection(mDisplayCutout, Gravity.TOP, bounds);
+ bounds.left = bounds.left + mCutoutSideNudge;
+ bounds.right = bounds.right - mCutoutSideNudge;
lp.width = bounds.width();
lp.height = bounds.height();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 20852ff..ea1b980 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -16,20 +16,29 @@
package com.android.systemui.statusbar.phone;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+import static com.android.systemui.Interpolators.ALPHA_IN;
+import static com.android.systemui.Interpolators.ALPHA_OUT;
+import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
+import static com.android.systemui.OverviewProxyService.TAG_OPS;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.animation.PropertyValuesHolder;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
-import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.RemoteException;
+import android.util.FloatProperty;
import android.util.Log;
import android.util.Slog;
import android.view.MotionEvent;
@@ -45,12 +54,7 @@
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.utilities.Utilities;
import com.android.systemui.shared.system.NavigationBarCompat;
-
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
-import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
-import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
-import static com.android.systemui.OverviewProxyService.TAG_OPS;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
+import com.android.internal.graphics.ColorUtils;
/**
* Class to detect gestures on the navigation bar and implement quick scrub.
@@ -58,88 +62,100 @@
public class QuickStepController implements GestureHelper {
private static final String TAG = "QuickStepController";
- private static final int ANIM_DURATION_MS = 200;
+ private static final int ANIM_IN_DURATION_MS = 150;
+ private static final int ANIM_OUT_DURATION_MS = 134;
+ private static final float TRACK_SCALE = 0.95f;
private NavigationBarView mNavigationBarView;
private boolean mQuickScrubActive;
private boolean mAllowGestureDetection;
private boolean mQuickStepStarted;
- private float mDownOffset;
- private float mTranslation;
private int mTouchDownX;
private int mTouchDownY;
- private boolean mDragScrubActive;
private boolean mDragPositive;
private boolean mIsVertical;
private boolean mIsRTL;
private float mTrackAlpha;
+ private float mTrackScale = TRACK_SCALE;
private int mLightTrackColor;
private int mDarkTrackColor;
private float mDarkIntensity;
- private View mHomeButtonView;
+ private AnimatorSet mTrackAnimator;
+ private ButtonDispatcher mHitTarget;
+ private View mCurrentNavigationBarView;
private final Handler mHandler = new Handler();
- private final Interpolator mQuickScrubEndInterpolator = new DecelerateInterpolator();
private final Rect mTrackRect = new Rect();
- private final Paint mTrackPaint = new Paint();
+ private final Drawable mTrackDrawable;
private final OverviewProxyService mOverviewEventSender;
private final int mTrackThickness;
- private final int mTrackPadding;
- private final ValueAnimator mTrackAnimator;
- private final ValueAnimator mButtonAnimator;
- private final AnimatorSet mQuickScrubEndAnimator;
+ private final int mTrackEndPadding;
private final Context mContext;
private final Matrix mTransformGlobalMatrix = new Matrix();
private final Matrix mTransformLocalMatrix = new Matrix();
private final ArgbEvaluator mTrackColorEvaluator = new ArgbEvaluator();
- private final AnimatorUpdateListener mTrackAnimatorListener = valueAnimator -> {
- mTrackAlpha = (float) valueAnimator.getAnimatedValue();
- mNavigationBarView.invalidate();
+ private final FloatProperty<QuickStepController> mTrackAlphaProperty =
+ new FloatProperty<QuickStepController>("TrackAlpha") {
+ @Override
+ public void setValue(QuickStepController controller, float alpha) {
+ mTrackAlpha = alpha;
+ mNavigationBarView.invalidate();
+ }
+
+ @Override
+ public Float get(QuickStepController controller) {
+ return mTrackAlpha;
+ }
};
- private final AnimatorUpdateListener mButtonTranslationListener = animator -> {
- int pos = (int) animator.getAnimatedValue();
- if (!mQuickScrubActive) {
- pos = mDragPositive ? Math.min((int) mTranslation, pos) : Math.max((int) mTranslation, pos);
+ private final FloatProperty<QuickStepController> mTrackScaleProperty =
+ new FloatProperty<QuickStepController>("TrackScale") {
+ @Override
+ public void setValue(QuickStepController controller, float scale) {
+ mTrackScale = scale;
+ mNavigationBarView.invalidate();
}
- if (mIsVertical) {
- mHomeButtonView.setTranslationY(pos);
- } else {
- mHomeButtonView.setTranslationX(pos);
+
+ @Override
+ public Float get(QuickStepController controller) {
+ return mTrackScale;
+ }
+ };
+
+ private final FloatProperty<QuickStepController> mNavBarAlphaProperty =
+ new FloatProperty<QuickStepController>("NavBarAlpha") {
+ @Override
+ public void setValue(QuickStepController controller, float alpha) {
+ if (mCurrentNavigationBarView != null) {
+ mCurrentNavigationBarView.setAlpha(alpha);
+ }
+ }
+
+ @Override
+ public Float get(QuickStepController controller) {
+ if (mCurrentNavigationBarView != null) {
+ return mCurrentNavigationBarView.getAlpha();
+ }
+ return 1f;
}
};
private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- mQuickScrubActive = false;
- mDragScrubActive = false;
- mTranslation = 0;
- mQuickScrubEndAnimator.setCurrentPlayTime(mQuickScrubEndAnimator.getDuration());
- mHomeButtonView = null;
+ resetQuickScrub();
}
};
public QuickStepController(Context context) {
+ final Resources res = context.getResources();
mContext = context;
mOverviewEventSender = Dependency.get(OverviewProxyService.class);
- mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness);
- mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding);
- mTrackPaint.setAlpha(0);
-
- mTrackAnimator = ObjectAnimator.ofFloat();
- mTrackAnimator.addUpdateListener(mTrackAnimatorListener);
- mTrackAnimator.setFloatValues(0);
- mButtonAnimator = ObjectAnimator.ofInt();
- mButtonAnimator.addUpdateListener(mButtonTranslationListener);
- mButtonAnimator.setIntValues(0);
- mQuickScrubEndAnimator = new AnimatorSet();
- mQuickScrubEndAnimator.playTogether(mTrackAnimator, mButtonAnimator);
- mQuickScrubEndAnimator.setDuration(ANIM_DURATION_MS);
- mQuickScrubEndAnimator.addListener(mQuickScrubEndListener);
- mQuickScrubEndAnimator.setInterpolator(mQuickScrubEndInterpolator);
+ mTrackThickness = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_thickness);
+ mTrackEndPadding = res.getDimensionPixelSize(R.dimen.nav_quick_scrub_track_edge_padding);
+ mTrackDrawable = context.getDrawable(R.drawable.qs_scrubber_track).mutate();
}
public void setComponents(NavigationBarView navigationBarView) {
@@ -170,24 +186,28 @@
private boolean handleTouchEvent(MotionEvent event) {
if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled()
&& !mNavigationBarView.isQuickStepSwipeUpEnabled())) {
- mNavigationBarView.getHomeButton().setDelayTouchFeedback(false /* delay */);
return false;
}
mNavigationBarView.requestUnbufferedDispatch(event);
- final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
- final boolean homePressed = mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME;
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN: {
int x = (int) event.getX();
int y = (int) event.getY();
+
// End any existing quickscrub animations before starting the new transition
- if (mHomeButtonView != null) {
- mQuickScrubEndAnimator.end();
+ if (mTrackAnimator != null) {
+ mTrackAnimator.end();
+ mTrackAnimator = null;
}
- mHomeButtonView = homeButton.getCurrentView();
- homeButton.setDelayTouchFeedback(true /* delay */);
+
+ mCurrentNavigationBarView = mNavigationBarView.getCurrentView();
+ mHitTarget = mNavigationBarView.getButtonAtPosition(x, y);
+ if (mHitTarget != null) {
+ // Pre-emptively delay the touch feedback for the button that we just touched
+ mHitTarget.setDelayTouchFeedback(true);
+ }
mTouchDownX = x;
mTouchDownY = y;
mTransformGlobalMatrix.set(Matrix.IDENTITY_MATRIX);
@@ -199,7 +219,7 @@
break;
}
case MotionEvent.ACTION_MOVE: {
- if (mQuickStepStarted || !mAllowGestureDetection || mHomeButtonView == null){
+ if (mQuickStepStarted || !mAllowGestureDetection){
break;
}
int x = (int) event.getX();
@@ -207,7 +227,7 @@
int xDiff = Math.abs(x - mTouchDownX);
int yDiff = Math.abs(y - mTouchDownY);
- boolean exceededScrubTouchSlop, exceededSwipeUpTouchSlop, exceededScrubDragSlop;
+ boolean exceededScrubTouchSlop, exceededSwipeUpTouchSlop;
int pos, touchDown, offset, trackSize;
if (mIsVertical) {
@@ -215,8 +235,6 @@
yDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && yDiff > xDiff;
exceededSwipeUpTouchSlop =
xDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && xDiff > yDiff;
- exceededScrubDragSlop =
- yDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && yDiff > xDiff;
pos = y;
touchDown = mTouchDownY;
offset = pos - mTrackRect.top;
@@ -226,8 +244,6 @@
xDiff > NavigationBarCompat.getQuickScrubTouchSlopPx() && xDiff > yDiff;
exceededSwipeUpTouchSlop =
yDiff > NavigationBarCompat.getQuickStepTouchSlopPx() && yDiff > xDiff;
- exceededScrubDragSlop =
- xDiff > NavigationBarCompat.getQuickScrubDragSlopPx() && xDiff > yDiff;
pos = x;
touchDown = mTouchDownX;
offset = pos - mTrackRect.left;
@@ -242,8 +258,8 @@
break;
}
- // Do not handle quick scrub if disabled or hit target is not home button
- if (!homePressed || !mNavigationBarView.isQuickScrubEnabled()) {
+ // Do not handle quick scrub if disabled
+ if (!mNavigationBarView.isQuickScrubEnabled()) {
break;
}
@@ -253,41 +269,23 @@
final boolean allowDrag = !mDragPositive
? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
+ float scrubFraction = Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
if (allowDrag) {
- // Passing the drag slop is for visual feedback and will not initiate anything
- if (!mDragScrubActive && exceededScrubDragSlop) {
- mDownOffset = offset;
- mDragScrubActive = true;
- }
-
// Passing the drag slop then touch slop will start quick step
if (!mQuickScrubActive && exceededScrubTouchSlop) {
- homeButton.abortCurrentGesture();
startQuickScrub();
}
}
- if ((mQuickScrubActive || mDragScrubActive) && (mDragPositive && offset >= 0
+ if (mQuickScrubActive && (mDragPositive && offset >= 0
|| !mDragPositive && offset <= 0)) {
- mTranslation = !mDragPositive
- ? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
- : Utilities.clamp(offset - mDownOffset, 0, trackSize);
- if (mQuickScrubActive) {
- float scrubFraction =
- Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
- try {
- mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send progress of quick scrub.", e);
+ try {
+ mOverviewEventSender.getProxy().onQuickScrubProgress(scrubFraction);
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
}
- }
- if (mIsVertical) {
- mHomeButtonView.setTranslationY(mTranslation);
- } else {
- mHomeButtonView.setTranslationX(mTranslation);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send progress of quick scrub.", e);
}
}
break;
@@ -314,30 +312,41 @@
}
int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor,
mDarkTrackColor);
- mTrackPaint.setColor(color);
- mTrackPaint.setAlpha((int) (mTrackPaint.getAlpha() * mTrackAlpha));
- canvas.drawRect(mTrackRect, mTrackPaint);
+ int colorAlpha = ColorUtils.setAlphaComponent(color,
+ (int) (Color.alpha(color) * mTrackAlpha));
+ mTrackDrawable.setTint(colorAlpha);
+
+ // Scale the track, but apply the inverse scale from the nav bar
+ canvas.save();
+ canvas.scale(mTrackScale / mNavigationBarView.getScaleX(),
+ 1f / mNavigationBarView.getScaleY(),
+ mTrackRect.centerX(), mTrackRect.centerY());
+ mTrackDrawable.draw(canvas);
+ canvas.restore();
}
@Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
- final int width = (right - left) - mNavigationBarView.getPaddingEnd()
- - mNavigationBarView.getPaddingStart();
- final int height = (bottom - top) - mNavigationBarView.getPaddingBottom()
- - mNavigationBarView.getPaddingTop();
+ final int paddingLeft = mNavigationBarView.getPaddingLeft();
+ final int paddingTop = mNavigationBarView.getPaddingTop();
+ final int paddingRight = mNavigationBarView.getPaddingRight();
+ final int paddingBottom = mNavigationBarView.getPaddingBottom();
+ final int width = (right - left) - paddingRight - paddingLeft;
+ final int height = (bottom - top) - paddingBottom - paddingTop;
final int x1, x2, y1, y2;
if (mIsVertical) {
- x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingLeft();
+ x1 = (width - mTrackThickness) / 2 + paddingLeft;
x2 = x1 + mTrackThickness;
- y1 = mDragPositive ? height / 2 : mTrackPadding;
- y2 = y1 + height / 2 - mTrackPadding;
+ y1 = paddingTop + mTrackEndPadding;
+ y2 = y1 + height - 2 * mTrackEndPadding;
} else {
- y1 = (height - mTrackThickness) / 2 + mNavigationBarView.getPaddingTop();
+ y1 = (height - mTrackThickness) / 2 + paddingTop;
y2 = y1 + mTrackThickness;
- x1 = mDragPositive ? width / 2 : mTrackPadding;
- x2 = x1 + width / 2 - mTrackPadding;
+ x1 = mNavigationBarView.getPaddingStart() + mTrackEndPadding;
+ x2 = x1 + width - 2 * mTrackEndPadding;
}
mTrackRect.set(x1, y1, x2, y2);
+ mTrackDrawable.setBounds(mTrackRect);
}
@Override
@@ -386,24 +395,34 @@
event.transform(mTransformLocalMatrix);
}
mOverviewEventSender.notifyQuickStepStarted();
- mNavigationBarView.getHomeButton().abortCurrentGesture();
mHandler.removeCallbacksAndMessages(null);
- if (mDragScrubActive) {
+ if (mHitTarget != null) {
+ mHitTarget.abortCurrentGesture();
+ }
+
+ if (mQuickScrubActive) {
animateEnd();
}
}
private void startQuickScrub() {
- if (!mQuickScrubActive && mDragScrubActive) {
+ if (!mQuickScrubActive) {
mQuickScrubActive = true;
mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
- mTrackAnimator.setFloatValues(0, 1);
- mTrackAnimator.start();
- // Hide menu buttons on nav bar until quick scrub has ended
- mNavigationBarView.setMenuContainerVisibility(false /* visible */);
+ ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 1f),
+ PropertyValuesHolder.ofFloat(mTrackScaleProperty, 1f));
+ trackAnimator.setInterpolator(ALPHA_IN);
+ trackAnimator.setDuration(ANIM_IN_DURATION_MS);
+ ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 0f);
+ navBarAnimator.setInterpolator(ALPHA_OUT);
+ navBarAnimator.setDuration(ANIM_OUT_DURATION_MS);
+ mTrackAnimator = new AnimatorSet();
+ mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
+ mTrackAnimator.start();
try {
mOverviewEventSender.getProxy().onQuickScrubStart();
@@ -414,32 +433,58 @@
Log.e(TAG, "Failed to send start of quick scrub.", e);
}
mOverviewEventSender.notifyQuickScrubStarted();
+
+ if (mHitTarget != null) {
+ mHitTarget.abortCurrentGesture();
+ }
}
}
private void endQuickScrub(boolean animate) {
- if (mQuickScrubActive || mDragScrubActive) {
+ if (mQuickScrubActive) {
animateEnd();
-
- // Restore the nav bar menu buttons visibility
- mNavigationBarView.setMenuContainerVisibility(true /* visible */);
-
- if (mQuickScrubActive) {
- try {
- mOverviewEventSender.getProxy().onQuickScrubEnd();
- if (DEBUG_OVERVIEW_PROXY) {
- Log.d(TAG_OPS, "Quick Scrub End");
- }
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to send end of quick scrub.", e);
+ try {
+ mOverviewEventSender.getProxy().onQuickScrubEnd();
+ if (DEBUG_OVERVIEW_PROXY) {
+ Log.d(TAG_OPS, "Quick Scrub End");
}
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to send end of quick scrub.", e);
}
}
- if (mHomeButtonView != null && !animate) {
- mQuickScrubEndAnimator.end();
+ if (!animate) {
+ if (mTrackAnimator != null) {
+ mTrackAnimator.end();
+ mTrackAnimator = null;
+ }
}
}
+ private void animateEnd() {
+ if (mTrackAnimator != null) {
+ mTrackAnimator.cancel();
+ }
+
+ ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
+ PropertyValuesHolder.ofFloat(mTrackAlphaProperty, 0f),
+ PropertyValuesHolder.ofFloat(mTrackScaleProperty, TRACK_SCALE));
+ trackAnimator.setInterpolator(ALPHA_OUT);
+ trackAnimator.setDuration(ANIM_OUT_DURATION_MS);
+ ObjectAnimator navBarAnimator = ObjectAnimator.ofFloat(this, mNavBarAlphaProperty, 1f);
+ navBarAnimator.setInterpolator(ALPHA_IN);
+ navBarAnimator.setDuration(ANIM_IN_DURATION_MS);
+ mTrackAnimator = new AnimatorSet();
+ mTrackAnimator.playTogether(trackAnimator, navBarAnimator);
+ mTrackAnimator.addListener(mQuickScrubEndListener);
+ mTrackAnimator.start();
+ }
+
+ private void resetQuickScrub() {
+ mQuickScrubActive = false;
+ mAllowGestureDetection = false;
+ mCurrentNavigationBarView = null;
+ }
+
private boolean proxyMotionEvents(MotionEvent event) {
final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
event.transform(mTransformGlobalMatrix);
@@ -459,15 +504,4 @@
}
return false;
}
-
- private void animateEnd() {
- mButtonAnimator.setIntValues((int) mTranslation, 0);
- mTrackAnimator.setFloatValues(mTrackAlpha, 0);
- mQuickScrubEndAnimator.setCurrentPlayTime(0);
- mQuickScrubEndAnimator.start();
- }
-
- private int getDimensionPixelSize(Context context, @DimenRes int resId) {
- return context.getResources().getDimensionPixelSize(resId);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index bcbc345..d3ec187 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -17,10 +17,11 @@
import android.annotation.Nullable;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import java.util.ArrayList;
@@ -48,7 +49,7 @@
@Override
public void addView(View child) {
- reverseParams(child.getLayoutParams(), child);
+ reverseParams(child.getLayoutParams(), child, mIsLayoutReverse);
if (mIsLayoutReverse) {
super.addView(child, 0);
} else {
@@ -58,7 +59,7 @@
@Override
public void addView(View child, ViewGroup.LayoutParams params) {
- reverseParams(params, child);
+ reverseParams(params, child, mIsLayoutReverse);
if (mIsLayoutReverse) {
super.addView(child, 0, params);
} else {
@@ -94,15 +95,17 @@
}
removeAllViews();
for (int i = childCount - 1; i >= 0; i--) {
- super.addView(childList.get(i));
+ final View child = childList.get(i);
+ super.addView(child);
}
mIsLayoutReverse = isLayoutReverse;
}
}
- private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+ private static void reverseParams(ViewGroup.LayoutParams params, View child,
+ boolean isLayoutReverse) {
if (child instanceof Reversable) {
- ((Reversable) child).reverse();
+ ((Reversable) child).reverse(isLayoutReverse);
}
if (child.getPaddingLeft() == child.getPaddingRight()
&& child.getPaddingTop() == child.getPaddingBottom()) {
@@ -118,20 +121,48 @@
}
public interface Reversable {
- void reverse();
+ void reverse(boolean isLayoutReverse);
}
- public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+ public static class ReverseRelativeLayout extends RelativeLayout implements Reversable {
- public ReverseFrameLayout(Context context) {
+ public ReverseRelativeLayout(Context context) {
super(context);
}
@Override
- public void reverse() {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- reverseParams(child.getLayoutParams(), child);
+ public void reverse(boolean isLayoutReverse) {
+ updateGravity(isLayoutReverse);
+ reverseGroup(this, isLayoutReverse);
+ }
+
+ private int mDefaultGravity = Gravity.NO_GRAVITY;
+ public void setDefaultGravity(int gravity) {
+ mDefaultGravity = gravity;
+ }
+
+ public void updateGravity(boolean isLayoutReverse) {
+ // Flip gravity if top of bottom is used
+ if (mDefaultGravity != Gravity.TOP && mDefaultGravity != Gravity.BOTTOM) return;
+
+ // Use the default (intended for 270 LTR and 90 RTL) unless layout is otherwise
+ int gravityToApply = mDefaultGravity;
+ if (isLayoutReverse) {
+ gravityToApply = mDefaultGravity == Gravity.TOP ? Gravity.BOTTOM : Gravity.TOP;
+ }
+
+ if (getGravity() != gravityToApply) setGravity(gravityToApply);
+ }
+ }
+
+ private static void reverseGroup(ViewGroup group, boolean isLayoutReverse) {
+ for (int i = 0; i < group.getChildCount(); i++) {
+ final View child = group.getChildAt(i);
+ reverseParams(child.getLayoutParams(), child, isLayoutReverse);
+
+ // Recursively reverse all children
+ if (child instanceof ViewGroup) {
+ reverseGroup((ViewGroup) child, isLayoutReverse);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java
new file mode 100644
index 0000000..8311dfd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+
+import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
+import android.graphics.BlurMaskFilter.Blur;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+
+import com.android.systemui.R;
+
+/**
+ * A drawable which adds shadow around a child drawable.
+ */
+public class ShadowKeyDrawable extends Drawable {
+ private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+
+ private final ShadowDrawableState mState;
+
+ public ShadowKeyDrawable(Drawable d) {
+ this(d, new ShadowDrawableState());
+ }
+
+ private ShadowKeyDrawable(Drawable d, ShadowDrawableState state) {
+ mState = state;
+ if (d != null) {
+ mState.mBaseHeight = d.getIntrinsicHeight();
+ mState.mBaseWidth = d.getIntrinsicWidth();
+ mState.mChangingConfigurations = d.getChangingConfigurations();
+ mState.mChildState = d.getConstantState();
+ }
+ }
+
+ public void setRotation(float degrees) {
+ if (mState.mRotateDegrees != degrees) {
+ mState.mRotateDegrees = degrees;
+ mState.mLastDrawnBitmap = null;
+ invalidateSelf();
+ }
+ }
+
+ public void setShadowProperties(int x, int y, int size, int color) {
+ if (mState.mShadowOffsetX != x || mState.mShadowOffsetY != y
+ || mState.mShadowSize != size || mState.mShadowColor != color) {
+ mState.mShadowOffsetX = x;
+ mState.mShadowOffsetY = y;
+ mState.mShadowSize = size;
+ mState.mShadowColor = color;
+ mState.mLastDrawnBitmap = null;
+ invalidateSelf();
+ }
+ }
+
+ public float getRotation() {
+ return mState.mRotateDegrees;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ Rect bounds = getBounds();
+ if (bounds.isEmpty()) {
+ return;
+ }
+ if (mState.mLastDrawnBitmap == null) {
+ regenerateBitmapCache();
+ }
+ canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
+ }
+
+ @Override
+ public void setTint(int tintColor) {
+ super.setTint(tintColor);
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ mPaint.setAlpha(alpha);
+ invalidateSelf();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter colorFilter) {
+ mPaint.setColorFilter(colorFilter);
+ invalidateSelf();
+ }
+
+ @Override
+ public ConstantState getConstantState() {
+ return mState;
+ }
+
+ @Override
+ public int getOpacity() {
+ return PixelFormat.TRANSLUCENT;
+ }
+
+ @Override
+ public int getIntrinsicHeight() {
+ return mState.mBaseHeight;
+ }
+
+ @Override
+ public int getIntrinsicWidth() {
+ return mState.mBaseWidth;
+ }
+
+ @Override
+ public boolean canApplyTheme() {
+ return mState.canApplyTheme();
+ }
+
+ private void regenerateBitmapCache() {
+ final int width = getIntrinsicWidth();
+ final int height = getIntrinsicHeight();
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ canvas.save();
+ final float radians = (float) (mState.mRotateDegrees * Math.PI / 180);
+
+ // Rotate canvas before drawing original drawable if no shadow
+ if (mState.mShadowSize == 0) {
+ canvas.rotate(mState.mRotateDegrees, width / 2, height / 2);
+ }
+
+ // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
+ final Drawable d = mState.mChildState.newDrawable().mutate();
+ d.setBounds(0, 0, mState.mBaseWidth, mState.mBaseHeight);
+ d.draw(canvas);
+
+ if (mState.mShadowSize > 0) {
+ // Draws the shadow
+ Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, Blur.NORMAL));
+ int[] offset = new int[2];
+
+ final Bitmap shadow = bitmap.extractAlpha(paint, offset);
+
+ paint.setMaskFilter(null);
+ paint.setColor(mState.mShadowColor);
+ bitmap.eraseColor(Color.TRANSPARENT);
+
+ canvas.rotate(mState.mRotateDegrees, width / 2, height / 2);
+
+ final float shadowOffsetX = (float) (Math.sin(radians) * mState.mShadowOffsetY
+ + Math.cos(radians) * mState.mShadowOffsetX);
+ final float shadowOffsetY = (float) (Math.cos(radians) * mState.mShadowOffsetY
+ - Math.sin(radians) * mState.mShadowOffsetX);
+
+ canvas.drawBitmap(shadow, offset[0] + shadowOffsetX, offset[1] + shadowOffsetY, paint);
+ d.draw(canvas);
+ }
+
+ bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+ mState.mLastDrawnBitmap = bitmap;
+ canvas.restore();
+ }
+
+ private static class ShadowDrawableState extends ConstantState {
+ int mChangingConfigurations;
+ int mBaseWidth;
+ int mBaseHeight;
+ float mRotateDegrees;
+ int mShadowOffsetX;
+ int mShadowOffsetY;
+ int mShadowSize;
+ int mShadowColor;
+
+ Bitmap mLastDrawnBitmap;
+ ConstantState mChildState;
+
+ @Override
+ public Drawable newDrawable() {
+ return new ShadowKeyDrawable(null, this);
+ }
+
+ @Override
+ public int getChangingConfigurations() {
+ return mChangingConfigurations;
+ }
+
+ @Override
+ public boolean canApplyTheme() {
+ return true;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 4bda017..fe86378 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -174,11 +174,13 @@
|| mStatusBar.isFullScreenUserSwitcherState()) {
mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
} else if (mShowing && !mDozing) {
- mBouncer.setExpansion(expansion);
+ if (!isWakeAndUnlocking()) {
+ mBouncer.setExpansion(expansion);
+ }
if (expansion != KeyguardBouncer.EXPANSION_HIDDEN && tracking
&& mStatusBar.isKeyguardCurrentlySecure()
&& !mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
- mBouncer.show(false /* resetSecuritySelection */, false /* animated */);
+ mBouncer.show(false /* resetSecuritySelection */, false /* scrimmed */);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 7cd433a..384a6e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -148,16 +148,31 @@
boolean in = activityIn && mActivityEnabled && visible;
boolean out = activityOut && mActivityEnabled && visible;
- mWifiIconState.visible = visible;
- mWifiIconState.resId = statusIcon.icon;
- mWifiIconState.activityIn = in;
- mWifiIconState.activityOut = out;
- mWifiIconState.slot = mSlotWifi;
- mWifiIconState.airplaneSpacerVisible = mIsAirplaneMode;
- mWifiIconState.contentDescription = statusIcon.contentDescription;
+ WifiIconState newState = mWifiIconState.copy();
- if (mWifiIconState.visible && mWifiIconState.resId > 0) {
- mIconController.setSignalIcon(mSlotWifi, mWifiIconState.copy());
+ newState.visible = visible;
+ newState.resId = statusIcon.icon;
+ newState.activityIn = in;
+ newState.activityOut = out;
+ newState.slot = mSlotWifi;
+ newState.airplaneSpacerVisible = mIsAirplaneMode;
+ newState.contentDescription = statusIcon.contentDescription;
+
+ MobileIconState first = getFirstMobileState();
+ newState.signalSpacerVisible = first != null && first.typeId != 0;
+
+ updateWifiIconWithState(newState);
+ mWifiIconState = newState;
+ }
+
+ private void updateShowWifiSignalSpacer(WifiIconState state) {
+ MobileIconState first = getFirstMobileState();
+ state.signalSpacerVisible = first != null && first.typeId != 0;
+ }
+
+ private void updateWifiIconWithState(WifiIconState state) {
+ if (state.visible && state.resId > 0) {
+ mIconController.setSignalIcon(mSlotWifi, state);
mIconController.setIconVisibility(mSlotWifi, true);
} else {
mIconController.setIconVisibility(mSlotWifi, false);
@@ -173,6 +188,9 @@
return;
}
+ // Visibility of the data type indicator changed
+ boolean typeChanged = statusType != state.typeId && (statusType == 0 || state.typeId == 0);
+
state.visible = statusIcon.visible && !mBlockMobile;
state.strengthId = statusIcon.icon;
state.typeId = statusType;
@@ -184,6 +202,15 @@
// Always send a copy to maintain value type semantics
mIconController.setMobileIcons(mSlotMobile, MobileIconState.copyStates(mMobileStates));
+
+ if (typeChanged) {
+ WifiIconState wifiCopy = mWifiIconState.copy();
+ updateShowWifiSignalSpacer(wifiCopy);
+ if (!Objects.equals(wifiCopy, mWifiIconState)) {
+ updateWifiIconWithState(wifiCopy);
+ mWifiIconState = wifiCopy;
+ }
+ }
}
private MobileIconState getState(int subId) {
@@ -196,6 +223,14 @@
return null;
}
+ private MobileIconState getFirstMobileState() {
+ if (mMobileStates.size() > 0) {
+ return mMobileStates.get(0);
+ }
+
+ return null;
+ }
+
/**
* It is expected that a call to setSubs will be immediately followed by setMobileDataIndicators
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
index f0cfa2c..11fc408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightControllerImpl.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.policy;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
@@ -24,6 +25,8 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
+import android.provider.Settings;
+import android.provider.Settings.Secure;
import android.text.TextUtils;
import android.util.Log;
@@ -46,6 +49,9 @@
private static final int DISPATCH_CHANGED = 1;
private static final int DISPATCH_AVAILABILITY_CHANGED = 2;
+ private static final String ACTION_FLASHLIGHT_CHANGED =
+ "com.android.settings.flashlight.action.FLASHLIGHT_CHANGED";
+
private final CameraManager mCameraManager;
private final Context mContext;
/** Call {@link #ensureHandler()} before using */
@@ -206,6 +212,9 @@
public void onTorchModeUnavailable(String cameraId) {
if (TextUtils.equals(cameraId, mCameraId)) {
setCameraAvailable(false);
+ Settings.Secure.putInt(
+ mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 0);
+
}
}
@@ -214,6 +223,11 @@
if (TextUtils.equals(cameraId, mCameraId)) {
setCameraAvailable(true);
setTorchMode(enabled);
+ Settings.Secure.putInt(
+ mContext.getContentResolver(), Settings.Secure.FLASHLIGHT_AVAILABLE, 1);
+ Settings.Secure.putInt(
+ mContext.getContentResolver(), Secure.FLASHLIGHT_ENABLED, enabled ? 1 : 0);
+ mContext.sendBroadcast(new Intent(ACTION_FLASHLIGHT_CHANGED));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
index cce9d1c..1a85c47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonDrawable.java
@@ -17,10 +17,16 @@
package com.android.systemui.statusbar.policy;
import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.view.Gravity;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.ShadowKeyDrawable;
+
/**
* Drawable for {@link KeyButtonView}s which contains an asset for both normal mode and light
* navigation bar mode.
@@ -29,13 +35,24 @@
private final boolean mHasDarkDrawable;
- public static KeyButtonDrawable create(Drawable lightDrawable,
- @Nullable Drawable darkDrawable) {
+ public static KeyButtonDrawable create(Context lightContext, Drawable lightDrawable,
+ @Nullable Drawable darkDrawable, boolean hasShadow) {
if (darkDrawable != null) {
- return new KeyButtonDrawable(
- new Drawable[] { lightDrawable.mutate(), darkDrawable.mutate() });
+ ShadowKeyDrawable light = new ShadowKeyDrawable(lightDrawable.mutate());
+ ShadowKeyDrawable dark = new ShadowKeyDrawable(darkDrawable.mutate());
+ if (hasShadow) {
+ // Only apply the shadow on the light drawable
+ Resources res = lightContext.getResources();
+ int offsetX = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_x);
+ int offsetY = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_offset_y);
+ int radius = res.getDimensionPixelSize(R.dimen.nav_key_button_shadow_radius);
+ int color = lightContext.getColor(R.color.nav_key_button_shadow_color);
+ light.setShadowProperties(offsetX, offsetY, radius, color);
+ }
+ return new KeyButtonDrawable(new Drawable[] { light, dark });
} else {
- return new KeyButtonDrawable(new Drawable[] { lightDrawable.mutate() });
+ return new KeyButtonDrawable(new Drawable[] {
+ new ShadowKeyDrawable(lightDrawable.mutate()) });
}
}
@@ -57,4 +74,13 @@
getDrawable(1).setAlpha((int) (intensity * 255f));
invalidateSelf();
}
+
+ public void setRotation(float degrees) {
+ if (getDrawable(0) instanceof ShadowKeyDrawable) {
+ ((ShadowKeyDrawable) getDrawable(0)).setRotation(degrees);
+ }
+ if (mHasDarkDrawable && getDrawable(1) instanceof ShadowKeyDrawable) {
+ ((ShadowKeyDrawable) getDrawable(1)).setRotation(degrees);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 85cfde8..12b6f9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,6 +16,9 @@
package com.android.systemui.statusbar.policy;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
+
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -41,20 +44,14 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.ImageView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider.ButtonInterface;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.NavigationBarCompat;
-import static android.view.KeyEvent.KEYCODE_HOME;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
-import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
-
public class KeyButtonView extends ImageView implements ButtonInterface {
private static final String TAG = KeyButtonView.class.getSimpleName();
@@ -119,6 +116,7 @@
mRipple = new KeyButtonRipple(context, this);
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
setBackground(mRipple);
+ forceHasOverlappingRendering(false);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 4ec9ae8..b814478 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -565,10 +565,12 @@
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
- mRemoteInputView.mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false);
+ // When BACK key is pressed, this method would be invoked twice.
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK &&
+ event.getAction() == KeyEvent.ACTION_UP) {
+ defocusIfNeeded(true /* animate */);
}
- return super.dispatchKeyEvent(event);
+ return super.onKeyPreIme(keyCode, event);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java
index 4d33dec..30a5cc84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/TintedKeyButtonDrawable.java
@@ -21,6 +21,7 @@
import android.graphics.drawable.Drawable;
import com.android.internal.graphics.ColorUtils;
+import com.android.systemui.statusbar.phone.ShadowKeyDrawable;
/**
* Drawable for {@link KeyButtonView}s which contains a single asset and colors for light and dark
@@ -36,7 +37,8 @@
public static TintedKeyButtonDrawable create(Drawable drawable, @ColorInt int lightColor,
@ColorInt int darkColor) {
- return new TintedKeyButtonDrawable(new Drawable[] { drawable }, lightColor, darkColor);
+ return new TintedKeyButtonDrawable(new Drawable[] { drawable },
+ lightColor, darkColor);
}
private TintedKeyButtonDrawable(Drawable[] drawables, int lightColor, int darkColor){
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 794779d..7b9e711 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -388,6 +388,7 @@
return object.getDarkAmount();
}
};
+ private ObjectAnimator mDarkAmountAnimator;
private boolean mUsingLightTheme;
private boolean mQsExpanded;
private boolean mForwardScrollable;
@@ -760,7 +761,9 @@
}
private void updateClippingToTopRoundedCorner() {
- Float clipStart = (float) mTopPadding + mAmbientState.getExpandAnimationTopChange();
+ Float clipStart = (float) mTopPadding
+ + mStackTranslation
+ + mAmbientState.getExpandAnimationTopChange();
Float clipEnd = clipStart + mCornerRadius;
boolean first = true;
for (int i = 0; i < getChildCount(); i++) {
@@ -769,12 +772,12 @@
continue;
}
float start = child.getTranslationY();
- float end = start + Math.max(child.getActualHeight() - child.getClipBottomAmount(),
- 0);
+ float end = start + child.getActualHeight();
boolean clip = clipStart > start && clipStart < end
|| clipEnd >= start && clipEnd <= end;
clip &= !(first && mOwnScrollY == 0);
- child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0) : -1);
+ child.setDistanceToTopRoundness(clip ? Math.max(start - clipStart, 0)
+ : ExpandableView.NO_ROUNDNESS);
first = false;
}
}
@@ -3292,6 +3295,16 @@
if (!childWasSwipedOut) {
Rect clipBounds = child.getClipBounds();
childWasSwipedOut = clipBounds != null && clipBounds.height() == 0;
+
+ if (childWasSwipedOut && child instanceof ExpandableView) {
+ // Clean up any potential transient views if the child has already been swiped
+ // out, as we won't be animating it further (due to its height already being
+ // clipped to 0.
+ ViewGroup transientContainer = ((ExpandableView) child).getTransientContainer();
+ if (transientContainer != null) {
+ transientContainer.removeTransientView(child);
+ }
+ }
}
int animationType = childWasSwipedOut
? AnimationEvent.ANIMATION_TYPE_REMOVE_SWIPED_OUT
@@ -3390,7 +3403,7 @@
.animateY(mShelf));
ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex;
mAnimationEvents.add(ev);
- startBackgroundFade();
+ startDarkAmountAnimation();
}
mDarkNeedsAnimation = false;
}
@@ -3968,6 +3981,9 @@
mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation);
mNeedsAnimation = true;
} else {
+ if (mDarkAmountAnimator != null) {
+ mDarkAmountAnimator.cancel();
+ }
setDarkAmount(dark ? 1f : 0f);
updateBackground();
}
@@ -4012,12 +4028,22 @@
return mDarkAmount;
}
- private void startBackgroundFade() {
- ObjectAnimator fadeAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount,
+ private void startDarkAmountAnimation() {
+ ObjectAnimator darkAnimator = ObjectAnimator.ofFloat(this, DARK_AMOUNT, mDarkAmount,
mAmbientState.isDark() ? 1f : 0);
- fadeAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
- fadeAnimator.setInterpolator(Interpolators.ALPHA_IN);
- fadeAnimator.start();
+ darkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
+ darkAnimator.setInterpolator(Interpolators.ALPHA_IN);
+ darkAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mDarkAmountAnimator = null;
+ }
+ });
+ if (mDarkAmountAnimator != null) {
+ mDarkAmountAnimator.cancel();
+ }
+ mDarkAmountAnimator = darkAnimator;
+ mDarkAmountAnimator.start();
}
private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 8034345..bf962b8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -344,13 +344,17 @@
int supplementalIconId, @Nullable View.OnClickListener supplementalIconOnClickListener) {
SeekbarListItem listItem = new SeekbarListItem(mContext);
listItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
+ int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
listItem.setProgress(progress);
listItem.setOnSeekBarChangeListener(
new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId, mCarAudioManager));
- listItem.setPrimaryActionIcon(mContext.getResources().getDrawable(volumeItem.icon));
+ Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
+ primaryIcon.setTint(color);
+ listItem.setPrimaryActionIcon(primaryIcon);
if (supplementalIconId != 0) {
Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
+ supplementalIcon.setTint(color);
listItem.setSupplementalIcon(supplementalIcon, true,
supplementalIconOnClickListener);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 4588675..955939c 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -43,8 +43,10 @@
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
import android.graphics.drawable.ColorDrawable;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -90,6 +92,7 @@
import com.android.systemui.plugins.VolumeDialogController;
import com.android.systemui.plugins.VolumeDialogController.State;
import com.android.systemui.plugins.VolumeDialogController.StreamState;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -131,8 +134,10 @@
private final AccessibilityManagerWrapper mAccessibilityMgr;
private final Object mSafetyWarningLock = new Object();
private final Accessibility mAccessibility = new Accessibility();
- private final ColorStateList mActiveTint;
- private final ColorStateList mInactiveTint;
+ private ColorStateList mActiveTint;
+ private int mActiveAlpha;
+ private ColorStateList mInactiveTint;
+ private int mInactiveAlpha;
private boolean mShowing;
private boolean mShowA11yStream;
@@ -150,8 +155,6 @@
mController = Dependency.get(VolumeDialogController.class);
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
- mActiveTint = Utils.getColorAccent(mContext);
- mInactiveTint = loadColorStateList(R.color.volume_slider_inactive);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
}
@@ -224,6 +227,11 @@
return true;
});
+ mActiveTint = Utils.getColorAccent(mContext);
+ mActiveAlpha = Color.alpha(mActiveTint.getDefaultColor());
+ mInactiveTint = Utils.getColorAttr(mContext, android.R.attr.colorForeground);
+ mInactiveAlpha = getAlphaAttr(android.R.attr.secondaryContentAlpha);
+
mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows);
mRinger = mDialog.findViewById(R.id.ringer);
mRingerIcon = mRinger.findViewById(R.id.ringer_icon);
@@ -263,8 +271,11 @@
return mDialogView;
}
- private ColorStateList loadColorStateList(int colorResId) {
- return ColorStateList.valueOf(mContext.getColor(colorResId));
+ private int getAlphaAttr(int attr) {
+ TypedArray ta = mContext.obtainStyledAttributes(new int[]{attr});
+ float alpha = ta.getFloat(0, 0);
+ ta.recycle();
+ return (int) (alpha * 255);
}
private boolean isLandscape() {
@@ -890,12 +901,16 @@
if (isActive) {
row.slider.requestFocus();
}
- final ColorStateList tint = isActive && row.slider.isEnabled() ? mActiveTint
- : mInactiveTint;
+ boolean useActiveColoring = isActive && row.slider.isEnabled();
+ final ColorStateList tint = useActiveColoring ? mActiveTint : mInactiveTint;
+ final int alpha = useActiveColoring ? mActiveAlpha : mInactiveAlpha;
if (tint == row.cachedTint) return;
row.slider.setProgressTintList(tint);
row.slider.setThumbTintList(tint);
+ row.slider.setProgressBackgroundTintList(tint);
+ row.slider.setAlpha(((float) alpha) / 255);
row.icon.setImageTintList(tint);
+ row.icon.setImageAlpha(alpha);
row.cachedTint = tint;
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index 3a262c2..d2e8371 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -57,9 +57,7 @@
public void showSlice_notifiesListener() {
ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
AtomicBoolean notified = new AtomicBoolean();
- mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
- notified.set(true);
- });
+ mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
mKeyguardSliceView.onChanged(builder.build());
Assert.assertTrue("Listener should be notified about slice changes.",
notified.get());
@@ -68,9 +66,7 @@
@Test
public void showSlice_emptySliceNotifiesListener() {
AtomicBoolean notified = new AtomicBoolean();
- mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
- notified.set(true);
- });
+ mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
mKeyguardSliceView.onChanged(null);
Assert.assertTrue("Listener should be notified about slice changes.",
notified.get());
@@ -92,9 +88,7 @@
@Test
public void refresh_replacesSliceContentAndNotifiesListener() {
AtomicBoolean notified = new AtomicBoolean();
- mKeyguardSliceView.setContentChangeListener((hasHeader)-> {
- notified.set(true);
- });
+ mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
mKeyguardSliceView.refresh();
Assert.assertTrue("Listener should be notified about slice changes.",
notified.get());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 8340ab2..85135ac 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -16,14 +16,12 @@
package com.android.systemui.statusbar.phone;
-import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -170,6 +168,15 @@
verify(mBouncer, never()).setExpansion(eq(0.5f));
}
+ @Test
+ public void onPanelExpansionChanged_neverTranslatesBouncerWhenWakeAndUnlock() {
+ when(mFingerprintUnlockController.getMode())
+ .thenReturn(FingerprintUnlockController.MODE_WAKE_AND_UNLOCK);
+ mStatusBarKeyguardViewManager.onPanelExpansionChanged(KeyguardBouncer.EXPANSION_VISIBLE,
+ false /* tracking */);
+ verify(mBouncer, never()).setExpansion(anyFloat());
+ }
+
private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager {
public TestableStatusBarKeyguardViewManager(Context context,
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0ca4d9a..d2990de 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -205,6 +205,14 @@
HARDWARE_FAILURE_FINGERPRINT_TOO_MANY_DEAD_PIXELS = 5;
}
+ enum IoOperation {
+ IOOP_UNKNOWN = 0;
+ IOOP_READ = 1;
+ IOOP_WRITE = 2;
+ IOOP_UNMAP = 3;
+ IOOP_SYNC = 4;
+ }
+
// Known visual elements: views or controls.
enum View {
// Unknown view
@@ -3978,27 +3986,44 @@
// OS: O
APP_TRANSITION_IS_EPHEMERAL = 905;
- // An autofill session was started
+ // An autofill session was started.
+ // OS: O
// Package: Package of app that is autofilled
// NOTE: starting on OS MR1, it also added the following field:
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// NOTE: starting on OS P, it also added the following field:
- // Tag FIELD_FLAGS - Flags used to start the session
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFIL_FLAGS: flags used to start the session.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session started.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SESSION_STARTED = 906;
// An autofill request was processed by a service
- // Type TYPE_SUCCESS: The request succeeded
- // Type TYPE_FAILURE: The request failed
+ // Type TYPE_SUCCESS: service called FillCalback.onSuccess()
+ // Type TYPE_FAILURE: service called FillCallback.onFailure()
// Package: Package of app that is autofilled
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets returned in the response, or -1 if
- // the service returned a null response.
- // NOTE: starting on OS P, it also added:
- // Type TYPE_CLOSE: Service returned a null response.
+ // the service returned a null response
+ // NOTE: starting on OS P, it also added the following fields:
+ // TYPE_CLOSE: request timed out before service called a FillCallback method
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_REQUEST_ORDINAL: sequence number of the request inside a session; starts
+ // with 1.
+ // Tag FIELD_AUTOFILL_FLAGS: flags used to request autofill
+ // Tag FIELD_AUTOFILL_DURATION: how long it took (in ms) to show the autofill UI after a field
+ // was focused.
+ // Tag FIELD_AUTOFILL_AUTHENTICATION_STATUS: status of authenticated datasets or responses.
// Tag FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS: if service requested field classification,
- // number of entries field ids in the request.
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // number of entries field ids in the request.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: Prior to P, some of the fields above were logged by 5 different metrics:
+ // - AUTOFILL_UI_LATENCY
+ // - AUTOFILL_AUTHENTICATED;
+ // - AUTOFILL_DATASET_AUTHENTICATED
+ // - AUTOFILL_INVALID_AUTHENTICATION
+ // - AUTOFILL_INVALID_DATASET_AUTHENTICATION
AUTOFILL_REQUEST = 907;
// Tag of a field for a package of an autofill service
@@ -4015,9 +4040,11 @@
// Package: Package of app that was autofilled
// Tag FIELD_AUTOFILL_FILTERTEXT_LEN: The length of the filter text
// Tag FIELD_AUTOFILL_NUM_DATASETS: The number of datasets shown
- // NOTE: starting on OS P, it also added the following field:
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_FILL_UI = 910;
// Tag of a field for the length of the filter text
@@ -4026,16 +4053,17 @@
// An autofill authentication succeeded
// Package: Package of app that was autofilled
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS
AUTOFILL_AUTHENTICATED = 912;
// An activity was autofilled and all values could be applied
// Package: Package of app that is autofilled
// Tag FIELD_AUTOFILL_NUM_VALUES: Number of values that were suggested to be autofilled
// Tag FIELD_AUTOFILL_NUM_VIEWS_FILLED: Number of views that could be filled
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_DATASET_APPLIED = 913;
// Tag of a field for the number values to be filled in
@@ -4050,28 +4078,37 @@
// Type TYPE_ACTION: data was saved
// Package: Package of app that was autofilled
// Tag FIELD_AUTOFILL_NUM_IDS: The number of ids that are saved
- // NOTE: starting on OS P, it also added the following field:
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_UI = 916;
// Tag of a field for the number of saveable ids
FIELD_AUTOFILL_NUM_IDS = 917;
- // ACTION: An autofill service was reqiested to save data
+ // ACTION: An autofill service was requested to save data
// Type TYPE_SUCCESS: The request succeeded right away
// Type TYPE_OPEN: The request succeeded but the service launched an IntentSender
// Type TYPE_FAILURE: The request failed
// Package: Package of app that was autofilled
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_DATA_SAVE_REQUEST = 918;
// An auto-fill session was finished
+ // OS: O
// Package: Package of app that was autofilled
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_NUMBER_REQUESTS: number of requests made to the service (each request
+ // is logged by a separate AUTOFILL_REQUEST metric)
AUTOFILL_SESSION_FINISHED = 919;
// meta-event: a reader has checkpointed the log here.
@@ -4198,7 +4235,7 @@
// Tag FIELD_AUTOFILL_SERVICE: Package of the autofill service that processed the request
// TAG FIELD_AUTOFILL_FORGED_COMPONENT_NAME: Component name being forged
// NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_FORGED_COMPONENT_ATTEMPT = 948;
// FIELD - The component that an app tried tro forged.
@@ -4656,8 +4693,10 @@
// OS: O MR
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_PREVIOUS_LENGTH: the previous length of the value
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_VALUE_RESET = 1124;
// Tag of AUTOFILL_VALUE_RESET
@@ -4667,25 +4706,21 @@
// An autofill dataset authentication succeeded
// Package: Package of app that was autofilled
// OS: O MR
- // Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS
AUTOFILL_DATASET_AUTHENTICATED = 1126;
// An autofill service provided an invalid dataset authentication
// Package: Package of app that was autofilled
// OS: O MR
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS
AUTOFILL_INVALID_DATASET_AUTHENTICATION = 1127;
// An autofill service provided an invalid authentication extra
// Package: Package of app that was autofilled
// OS: O MR
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, this metric became a value for FIELD_AUTOFILL_AUTHENTICATION_STATUS
AUTOFILL_INVALID_AUTHENTICATION = 1128;
// An autofill service used a custom description (using RemoteViews) in the autofill save UI
@@ -4693,8 +4728,10 @@
// OS: O MR
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_CUSTOM_DESCRIPTION = 1129;
// FIELD - Type of save object passed by the service when the Save UI is shown
@@ -4706,8 +4743,10 @@
// OS: O MR
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_CUSTOM_SUBTITLE = 1131;
// User tapped a link in the custom description of the autofill save UI provided by an autofill service
@@ -4718,8 +4757,10 @@
// Type TYPE_FAILURE: The link could not launc an activity
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_LINK_TAPPED = 1132;
// Result of the validation on save when an autofill service provided a validator
@@ -4730,8 +4771,10 @@
// Type TYPE_DISMISS: The validation failed
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_SAVE_TYPE: Type of save object passed by the service
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_VALIDATION = 1133;
// Result of an operation in the autofill save UI after the user tapped a link in the custom description
@@ -4741,8 +4784,10 @@
// Type TYPE_OPEN: The autofill save UI was restored
// Type TYPE_DISMISS: The autofill save UI was destroyed
// Type TYPE_FAILURE: An invalid opperation was reported by the app's AutofillManager
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // NOTE: starting on OS P, it also added the following fields:
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_PENDING_SAVE_UI_OPERATION = 1134;
// Autofill service called API that disables itself
@@ -4750,13 +4795,12 @@
// OS: O MR
AUTOFILL_SERVICE_DISABLED_SELF = 1135;
+ // DEPRECATED - on P it was merged with AUTOFILL_REQUEST
// Reports how long it took to show the autofill UI after a field was focused
// Tag FIELD_AUTOFILL_DURATION: Duration in ms
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Package: Package of the autofill service
// OS: O MR
- // NOTE: starting on OS P, it also added the following field:
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_UI_LATENCY = 1136;
// Action: the snooze leave-behind was shown after the user clicked the snooze icon
@@ -4923,15 +4967,19 @@
// An autofill service explicitly defined which view should commit the autofill context
// Package: Package of app that is autofilled
// OS: P
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_EXPLICIT_SAVE_TRIGGER_DEFINITION = 1228;
// The autofill context was commited when the user clicked a view explicitly marked by the
// service as committing it
// Package: Package of app that is autofilled
// OS: P
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SAVE_EXPLICITLY_TRIGGERED = 1229;
// OPEN: Settings > Network & Internet > Mobile network > Wi-Fi calling
@@ -4944,7 +4992,8 @@
// OS: P
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SERVICE_DISABLED_APP = 1231;
// An autofill service asked to disable autofill for a given activity.
@@ -4953,7 +5002,8 @@
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_CLASS_NAME: Class name of the activity that is being disabled for autofill
// Tag FIELD_AUTOFILL_DURATION: duration (in ms) that autofill will be disabled
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_SERVICE_DISABLED_ACTIVITY = 1232;
// ACTION: Stop an app and turn on background check
@@ -5163,9 +5213,11 @@
// Package: Package of app that is autofilled
// Counter: number of matches found
// OS: P
+ // Tag FIELD_CLASS_NAME: Class name of the activity that is autofilled.
// Tag FIELD_AUTOFILL_SERVICE: Package of service that processed the request
// Tag FIELD_AUTOFILL_MATCH_SCORE: Average score of the matches, in the range of 0 to 100
- // Type FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
+ // Tag FIELD_AUTOFILL_SESSION_ID: id of the autofill session associated with this metric.
+ // Tag FIELD_AUTOFILL_COMPAT_MODE: package is being autofilled on compatibility mode.
AUTOFILL_FIELD_CLASSIFICATION_MATCHES = 1273;
// Tag used to report autofill field classification scores
@@ -5832,6 +5884,7 @@
ACTION_STORAGE_MIGRATE_LATER = 1413;
// Tag used to report whether an activity is being autofilled on compatibility mode.
+ // OS: P
FIELD_AUTOFILL_COMPAT_MODE = 1414;
// OPEN: Settings > Sound > Switch a2dp devices dialog
@@ -5931,8 +5984,7 @@
// ACTION: Battery health snapshot
// CATEGORY: OTHER
// OS: P
- // uses FIELD_END_BATTERY_PERCENT for batt %
- // uses FIELD_END_BATTERY_UA for instantaneous current load
+ // uses FIELD_END_BATTERY_PERCENT for instantaneous batt %
ACTION_BATTERY_HEALTH = 1433;
// FIELD: Battery health snapshot type - min daily voltage, resistance, etc.
@@ -5940,31 +5992,33 @@
// OS: P
FIELD_BATTERY_HEALTH_SNAPSHOT_TYPE = 1434;
- // FIELD: Battery temperature at snapshop.
+ // FIELD: Battery temperature at snapshot, in 1/10 deg C.
// CATEGORY: OTHER
// OS: P
- FIELD_BATTERY_TEMPERATURE = 1435;
+ FIELD_BATTERY_TEMPERATURE_DECI_C = 1435;
- // FIELD: Battery voltage at snapshot.
+ // FIELD: Battery voltage at snapshot, in microVolts.
// CATEGORY: OTHER
// OS: P
- FIELD_BATTERY_VOLTAGE = 1436;
+ FIELD_BATTERY_VOLTAGE_UV = 1436;
- // FIELD: Battery open circuit voltage at snapshot.
+ // FIELD: Battery open circuit voltage at snapshot, in microVolts.
// CATEGORY: OTHER
// OS: P
- FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE = 1437;
+ FIELD_BATTERY_OPEN_CIRCUIT_VOLTAGE_UV = 1437;
- // ACTION: Battery charge cycles
- // Number of times the battery has charged beyond a
+ // ACTION: Number of times the battery has charged beyond a
// fractional threshold of full capacity.
// CATEGORY: OTHER
// OS: P
ACTION_BATTERY_CHARGE_CYCLES = 1438;
- // FIELD: Battery charge cycles
- // Number of times the battery has charged beyond a
- // fractional threshold of full capacity.
+ // FIELD: BATTERY_CHARGE_CYCLES - Number of times the battery has charged
+ // beyond a fractional threshold of full
+ // capacity. A comma-separated string of
+ // buckets. If there are eight buckets,
+ // each bucket represents charging to n/8
+ // percent full.
// CATEGORY: OTHER
// OS: P
FIELD_BATTERY_CHARGE_CYCLES = 1439;
@@ -5980,6 +6034,88 @@
// OS: P
DIALOG_BLUETOOTH_DISABLE_A2DP_HW_OFFLOAD = 1441;
+ // ACTION: SLOW_IO - I/O operation took longer than threshold,
+ // reported aggregated per day when > 0.
+ // CATEGORY: OTHER
+ // OS: P
+ ACTION_SLOW_IO = 1442;
+
+ // FIELD: IO_OPERATION_TYPE - The IO Operation that caused the high latency.
+ // The value is an integer from the enum IoOperation.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_IO_OPERATION_TYPE = 1443;
+
+ // FIELD: IO_OPERATION_COUNT - Count of how many times this slow IO operation happened
+ // over the past 24hr (reported only if > 0).
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_IO_OPERATION_COUNT = 1444;
+
+ // ACTION: Speaker Imedance - last recorded speaker impedance.
+ // reported max once per 24hr.
+ // CATEGORY: OTHER
+ // OS: P
+ ACTION_SPEAKER_IMPEDANCE = 1445;
+
+ // FIELD: Speaker Impedance in milliohms.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_SPEAKER_IMPEDANCE_MILLIOHMS = 1446;
+
+ // FIELD: Speaker Location - identifies one of several speakers on a device.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_SPEAKER_LOCATION = 1447;
+
+ // FIELD: Instantaneous battery resistance in microohms.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_BATTERY_RESISTANCE_UOHMS = 1448;
+
+ // FIELD: Instantaneous battery current - in microamps.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_BATTERY_CURRENT_UA = 1449;
+
+ // FIELD: HARDWARE_LOCATION - Identifier for instance of a hardware type on a
+ // board.
+ // CATEGORY: OTHER
+ // OS: P
+ FIELD_HARDWARE_LOCATION = 1450;
+
+ // ACTION: BATTERY_CAUSED_SHUTDOWN - shutdown due to low battery, the
+ // action is logged after the subsequent boot.
+ // CATEGORY: OTHER
+ // OS: P
+ ACTION_BATTERY_CAUSED_SHUTDOWN = 1451;
+
+ // FIELD: Flags used on autofill-related metrics
+ // OS: P
+ FIELD_AUTOFILL_FLAGS = 1452;
+
+ // Tag used when the service returned an authenticated dataset or response.
+ // Used to replace the following individual metrics, which now are logged as the value of this
+ // field in the AUTOFILL_REQUEST metric:
+ // - AUTOFILL_AUTHENTICATED;
+ // - AUTOFILL_DATASET_AUTHENTICATED
+ // - AUTOFILL_INVALID_AUTHENTICATION
+ // - AUTOFILL_INVALID_DATASET_AUTHENTICATION
+ // OS: P
+ FIELD_AUTOFILL_AUTHENTICATION_STATUS = 1453;
+
+ // FIELD: Index of the autofill request inside of a session.
+ // OS: P
+ FIELD_AUTOFILL_REQUEST_ORDINAL = 1454;
+
+ // FIELD: Number of requests made to an autofill service during a session.
+ // OS: P
+ FIELD_AUTOFILL_NUMBER_REQUESTS = 1455;
+
+ // FIELD: Id of the autofill session associated with this metric.
+ // OS: P
+ FIELD_AUTOFILL_SESSION_ID = 1456;
+
// ---- End P Constants, all P constants go above this line ----
// First Q constant in master goes here:
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index bf9ccb8..72f11e0 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -619,6 +619,9 @@
// Number of RSSI polls with 'rssi'
optional int32 count = 2;
+
+ // Beacon frequency of the channel in MHz
+ optional int32 frequency = 3;
}
// Number of occurrences of a specific alert reason value
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index d97253e..1ccce17 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -537,11 +537,17 @@
final String callingPackage = packages != null ? packages[0] : "uid-" + callingUid;
Slog.w(TAG, "App (package=" + callingPackage + ", UID=" + callingUid
+ ") passed component (" + componentName + ") owned by UID " + packageUid);
- mMetricsLogger.write(
- Helper.newLogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT,
- callingPackage, getServicePackageName(), compatMode)
+
+ // NOTE: not using Helper.newLogMaker() because we don't have the session id
+ final LogMaker log = new LogMaker(MetricsEvent.AUTOFILL_FORGED_COMPONENT_ATTEMPT)
+ .setPackageName(callingPackage)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FORGED_COMPONENT_NAME,
- componentName == null ? "null" : componentName.flattenToShortString()));
+ componentName == null ? "null" : componentName.flattenToShortString());
+ if (compatMode) {
+ log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1);
+ }
+ mMetricsLogger.write(log);
throw new SecurityException("Invalid component: " + componentName);
}
@@ -780,10 +786,10 @@
@Nullable ArrayList<String> changedDatasetIds,
@Nullable ArrayList<AutofillId> manuallyFilledFieldIds,
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
- @NonNull String appPackageName, boolean compatMode) {
+ @NonNull ComponentName appComponentName, boolean compatMode) {
logContextCommittedLocked(sessionId, clientState, selectedDatasets, ignoredDatasets,
changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
- manuallyFilledDatasetIds, null, null, appPackageName, compatMode);
+ manuallyFilledDatasetIds, null, null, appComponentName, compatMode);
}
@GuardedBy("mLock")
@@ -796,7 +802,7 @@
@Nullable ArrayList<ArrayList<String>> manuallyFilledDatasetIds,
@Nullable ArrayList<AutofillId> detectedFieldIdsList,
@Nullable ArrayList<FieldClassification> detectedFieldClassificationsList,
- @NonNull String appPackageName, boolean compatMode) {
+ @NonNull ComponentName appComponentName, boolean compatMode) {
if (isValidEventLocked("logDatasetNotSelected()", sessionId)) {
if (sVerbose) {
Slog.v(TAG, "logContextCommitted() with FieldClassification: id=" + sessionId
@@ -807,6 +813,7 @@
+ ", manuallyFilledFieldIds=" + manuallyFilledFieldIds
+ ", detectedFieldIds=" + detectedFieldIdsList
+ ", detectedFieldClassifications=" + detectedFieldClassificationsList
+ + ", appComponentName=" + appComponentName.toShortString()
+ ", compatMode=" + compatMode);
}
AutofillId[] detectedFieldsIds = null;
@@ -834,7 +841,7 @@
final int averageScore = (int) ((totalScore * 100) / totalSize);
mMetricsLogger.write(Helper
.newLogMaker(MetricsEvent.AUTOFILL_FIELD_CLASSIFICATION_MATCHES,
- appPackageName, getServicePackageName(), compatMode)
+ appComponentName, getServicePackageName(), sessionId, compatMode)
.setCounterValue(numberFields)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_MATCH_SCORE,
averageScore));
@@ -889,9 +896,11 @@
}
mUserData = userData;
// Log it
- int numberFields = mUserData == null ? 0: mUserData.getCategoryIds().length;
- mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_USERDATA_UPDATED,
- getServicePackageName(), null)
+ final int numberFields = mUserData == null ? 0: mUserData.getCategoryIds().length;
+ // NOTE: contrary to most metrics, the service name is logged as the main package name
+ // here, not as MetricsEvent.FIELD_AUTOFILL_SERVICE
+ mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_USERDATA_UPDATED)
+ .setPackageName(getServicePackageName())
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_VALUES, numberFields));
}
}
@@ -1130,7 +1139,8 @@
/**
* Called by {@link Session} when service asked to disable autofill for an app.
*/
- void disableAutofillForApp(@NonNull String packageName, long duration, boolean compatMode) {
+ void disableAutofillForApp(@NonNull String packageName, long duration, int sessionId,
+ boolean compatMode) {
synchronized (mLock) {
if (mDisabledApps == null) {
mDisabledApps = new ArrayMap<>(1);
@@ -1143,7 +1153,7 @@
mDisabledApps.put(packageName, expiration);
int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration;
mMetricsLogger.write(Helper.newLogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_APP,
- packageName, getServicePackageName(), compatMode)
+ packageName, getServicePackageName(), sessionId, compatMode)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration));
}
}
@@ -1152,7 +1162,7 @@
* Called by {@link Session} when service asked to disable autofill an app.
*/
void disableAutofillForActivity(@NonNull ComponentName componentName, long duration,
- boolean compatMode) {
+ int sessionId, boolean compatMode) {
synchronized (mLock) {
if (mDisabledActivities == null) {
mDisabledActivities = new ArrayMap<>(1);
@@ -1163,14 +1173,20 @@
expiration = Long.MAX_VALUE;
}
mDisabledActivities.put(componentName, expiration);
- final int intDuration = duration > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) duration;
+ final int intDuration = duration > Integer.MAX_VALUE
+ ? Integer.MAX_VALUE
+ : (int) duration;
// NOTE: not using Helper.newLogMaker() because we're setting the componentName instead
// of package name
- mMetricsLogger.write(new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY)
+ final LogMaker log = new LogMaker(MetricsEvent.AUTOFILL_SERVICE_DISABLED_ACTIVITY)
.setComponentName(componentName)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, getServicePackageName())
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, intDuration)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0));
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, sessionId);
+ if (compatMode) {
+ log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1);
+ }
+ mMetricsLogger.write(log);
}
}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index f781013..cf310e9 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.app.assist.AssistStructure;
import android.app.assist.AssistStructure.ViewNode;
+import android.content.ComponentName;
import android.metrics.LogMaker;
import android.service.autofill.Dataset;
import android.util.ArrayMap;
@@ -109,20 +110,29 @@
}
@NonNull
- public static LogMaker newLogMaker(int category, String packageName,
- String servicePackageName) {
- final LogMaker log = new LogMaker(category).setPackageName(packageName);
- if (servicePackageName != null) {
- log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName);
+ private static LogMaker newLogMaker(int category, @NonNull String servicePackageName,
+ int sessionId, boolean compatMode) {
+ final LogMaker log = new LogMaker(category)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE, servicePackageName)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SESSION_ID, sessionId);
+ if (compatMode) {
+ log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, 1);
}
return log;
}
@NonNull
- public static LogMaker newLogMaker(int category, String packageName,
- String servicePackageName, boolean compatMode) {
- return newLogMaker(category, packageName, servicePackageName)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE, compatMode ? 1 : 0);
+ public static LogMaker newLogMaker(int category, @NonNull String packageName,
+ @NonNull String servicePackageName, int sessionId, boolean compatMode) {
+ return newLogMaker(category, servicePackageName, sessionId, compatMode)
+ .setPackageName(packageName);
+ }
+
+ @NonNull
+ public static LogMaker newLogMaker(int category, @NonNull ComponentName componentName,
+ @NonNull String servicePackageName, int sessionId, boolean compatMode) {
+ return newLogMaker(category, servicePackageName, sessionId, compatMode)
+ .setComponentName(componentName);
}
public static void printlnRedactedText(@NonNull PrintWriter pw, @Nullable CharSequence text) {
@@ -193,6 +203,18 @@
return urlBarNode;
}
+ /**
+ * Gets the value of a metric tag, or {@code 0} if not found or NaN.
+ */
+ static int getNumericValue(@NonNull LogMaker log, int tag) {
+ final Object value = log.getTaggedData(tag);
+ if (!(value instanceof Number)) {
+ return 0;
+ } else {
+ return ((Number) value).intValue();
+ }
+ }
+
private interface ViewNodeFilter {
boolean matches(ViewNode node);
}
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 4ded3fe..3e932e8 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -99,12 +99,14 @@
private PendingRequest mPendingRequest;
public interface FillServiceCallbacks {
- void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response,
+ void onFillRequestSuccess(int requestId, @Nullable FillResponse response,
+ @NonNull String servicePackageName, int requestFlags);
+ void onFillRequestFailure(int requestId, @Nullable CharSequence message,
@NonNull String servicePackageName);
- void onFillRequestFailure(@Nullable CharSequence message,
- @NonNull String servicePackageName);
+ void onFillRequestTimeout(int requestId, @NonNull String servicePackageName);
void onSaveRequestSuccess(@NonNull String servicePackageName,
@Nullable IntentSender intentSender);
+ // TODO(b/80093094): add timeout here too?
void onSaveRequestFailure(@Nullable CharSequence message,
@NonNull String servicePackageName);
void onServiceDied(RemoteFillService service);
@@ -301,21 +303,31 @@
mContext.unbindService(mServiceConnection);
}
- private void dispatchOnFillRequestSuccess(PendingRequest pendingRequest, int requestFlags,
- FillResponse response) {
+ private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest,
+ @Nullable FillResponse response, int requestFlags) {
mHandler.post(() -> {
if (handleResponseCallbackCommon(pendingRequest)) {
- mCallbacks.onFillRequestSuccess(requestFlags, response,
+ mCallbacks.onFillRequestSuccess(pendingRequest.mRequest.getId(), response,
+ mComponentName.getPackageName(), requestFlags);
+ }
+ });
+ }
+
+ private void dispatchOnFillRequestFailure(@NonNull PendingFillRequest pendingRequest,
+ @Nullable CharSequence message) {
+ mHandler.post(() -> {
+ if (handleResponseCallbackCommon(pendingRequest)) {
+ mCallbacks.onFillRequestFailure(pendingRequest.mRequest.getId(), message,
mComponentName.getPackageName());
}
});
}
- private void dispatchOnFillRequestFailure(PendingRequest pendingRequest,
- @Nullable CharSequence message) {
+ private void dispatchOnFillRequestTimeout(@NonNull PendingFillRequest pendingRequest) {
mHandler.post(() -> {
if (handleResponseCallbackCommon(pendingRequest)) {
- mCallbacks.onFillRequestFailure(message, mComponentName.getPackageName());
+ mCallbacks.onFillRequestTimeout(pendingRequest.mRequest.getId(),
+ mComponentName.getPackageName());
}
});
}
@@ -538,18 +550,18 @@
final RemoteFillService remoteService = getService();
if (remoteService != null) {
remoteService.dispatchOnFillRequestSuccess(PendingFillRequest.this,
- request.getFlags(), response);
+ response, request.getFlags());
}
}
@Override
- public void onFailure(CharSequence message) {
+ public void onFailure(int requestId, CharSequence message) {
if (!finish()) return;
final RemoteFillService remoteService = getService();
if (remoteService != null) {
- remoteService.dispatchOnFillRequestFailure(
- PendingFillRequest.this, message);
+ remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this,
+ message);
}
}
};
@@ -566,7 +578,7 @@
if (cancellation != null) {
remoteService.dispatchOnFillTimeout(cancellation);
}
- remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
+ remoteService.dispatchOnFillRequestTimeout(PendingFillRequest.this);
}
@Override
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 4b67bb1..09f4135 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -27,6 +27,7 @@
import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static com.android.server.autofill.Helper.getNumericValue;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sPartitionMaxCount;
import static com.android.server.autofill.Helper.sVerbose;
@@ -93,6 +94,7 @@
import com.android.server.autofill.ui.PendingUi;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -176,7 +178,7 @@
/**
* Contexts read from the app; they will be updated (sanitized, change values for save) before
- * sent to {@link AutofillService}. Ordered by the time they we read.
+ * sent to {@link AutofillService}. Ordered by the time they were read.
*/
@GuardedBy("mLock")
private ArrayList<FillContext> mContexts;
@@ -231,6 +233,12 @@
private final LocalLog mWtfHistory;
/**
+ * Map of {@link MetricsEvent#AUTOFILL_REQUEST} metrics, keyed by fill request id.
+ */
+ @GuardedBy("mLock")
+ private final SparseArray<LogMaker> mRequestLogs = new SparseArray<>(1);
+
+ /**
* Receiver of assist data from the app's {@link Activity}.
*/
private final IAssistDataReceiver mAssistReceiver = new IAssistDataReceiver.Stub() {
@@ -483,8 +491,18 @@
requestId = sIdCounter.getAndIncrement();
} while (requestId == INVALID_REQUEST_ID);
+ // Create a metrics log for the request
+ final int ordinal = mRequestLogs.size() + 1;
+ final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL, ordinal);
+ if (flags != 0) {
+ log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags);
+ }
+ mRequestLogs.put(requestId, log);
+
if (sVerbose) {
- Slog.v(TAG, "Requesting structure for requestId=" + requestId + ", flags=" + flags);
+ Slog.v(TAG, "Requesting structure for request #" + ordinal + " ,requestId="
+ + requestId + ", flags=" + flags);
}
// If the focus changes very quickly before the first request is returned each focus change
@@ -537,7 +555,7 @@
setClientLocked(client);
mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_STARTED)
- .addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_FLAGS, flags));
}
/**
@@ -604,21 +622,30 @@
// FillServiceCallbacks
@Override
- public void onFillRequestSuccess(int requestFlags, @Nullable FillResponse response,
- @NonNull String servicePackageName) {
+ public void onFillRequestSuccess(int requestId, @Nullable FillResponse response,
+ @NonNull String servicePackageName, int requestFlags) {
final AutofillId[] fieldClassificationIds;
+ final LogMaker requestLog;
+
synchronized (mLock) {
if (mDestroyed) {
Slog.w(TAG, "Call to Session#onFillRequestSuccess() rejected - session: "
+ id + " destroyed");
return;
}
+
+ requestLog = mRequestLogs.get(requestId);
+ if (requestLog != null) {
+ requestLog.setType(MetricsEvent.TYPE_SUCCESS);
+ } else {
+ Slog.w(TAG, "onFillRequestSuccess(): no request log for id " + requestId);
+ }
if (response == null) {
+ if (requestLog != null) {
+ requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1);
+ }
processNullResponseLocked(requestFlags);
- mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName)
- .setType(MetricsEvent.TYPE_SUCCESS)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS, -1));
return;
}
@@ -645,10 +672,11 @@
Slog.d(TAG, message.toString());
}
if ((flags & FillResponse.FLAG_DISABLE_ACTIVITY_ONLY) != 0) {
- mService.disableAutofillForActivity(mComponentName, disableDuration, mCompatMode);
+ mService.disableAutofillForActivity(mComponentName, disableDuration,
+ id, mCompatMode);
} else {
mService.disableAutofillForApp(mComponentName.getPackageName(), disableDuration,
- mCompatMode);
+ id, mCompatMode);
}
sessionFinishedState = AutofillManager.STATE_DISABLED_BY_SERVICE;
}
@@ -659,38 +687,54 @@
// Response is "empty" from an UI point of view, need to notify client.
notifyUnavailableToClient(sessionFinishedState);
}
+
+ if (requestLog != null) {
+ requestLog.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
+ response.getDatasets() == null ? 0 : response.getDatasets().size());
+ if (fieldClassificationIds != null) {
+ requestLog.addTaggedData(
+ MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS,
+ fieldClassificationIds.length);
+ }
+ }
+
synchronized (mLock) {
processResponseLocked(response, null, requestFlags);
}
-
- final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName)
- .setType(MetricsEvent.TYPE_SUCCESS)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
- response.getDatasets() == null ? 0 : response.getDatasets().size());
- if (fieldClassificationIds != null) {
- log.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS,
- fieldClassificationIds.length);
- }
- mMetricsLogger.write(log);
}
// FillServiceCallbacks
@Override
- public void onFillRequestFailure(@Nullable CharSequence message,
+ public void onFillRequestFailure(int requestId, @Nullable CharSequence message,
@NonNull String servicePackageName) {
+ onFillRequestFailureOrTimeout(requestId, false, message, servicePackageName);
+ }
+
+ // FillServiceCallbacks
+ @Override
+ public void onFillRequestTimeout(int requestId, @NonNull String servicePackageName) {
+ onFillRequestFailureOrTimeout(requestId, true, null, servicePackageName);
+ }
+
+ private void onFillRequestFailureOrTimeout(int requestId, boolean timedOut,
+ @Nullable CharSequence message, @NonNull String servicePackageName) {
synchronized (mLock) {
if (mDestroyed) {
- Slog.w(TAG, "Call to Session#onFillRequestFailure() rejected - session: "
- + id + " destroyed");
+ Slog.w(TAG, "Call to Session#onFillRequestFailureOrTimeout(req=" + requestId
+ + ") rejected - session: " + id + " destroyed");
return;
}
mService.resetLastResponse();
+ final LogMaker requestLog = mRequestLogs.get(requestId);
+ if (requestLog == null) {
+ Slog.w(TAG, "onFillRequestFailureOrTimeout(): no log for id " + requestId);
+ } else {
+ requestLog.setType(timedOut ? MetricsEvent.TYPE_CLOSE : MetricsEvent.TYPE_FAILURE);
+ }
}
- LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_REQUEST, servicePackageName)
- .setType(MetricsEvent.TYPE_FAILURE);
- mMetricsLogger.write(log);
-
- getUiForShowing().showError(message, this);
+ if (message != null) {
+ getUiForShowing().showError(message, this);
+ }
removeSelf();
}
@@ -973,11 +1017,12 @@
+ ", clientState=" + newClientState);
}
if (result instanceof FillResponse) {
- writeLog(MetricsEvent.AUTOFILL_AUTHENTICATED);
+ logAuthenticationStatusLocked(requestId, MetricsEvent.AUTOFILL_AUTHENTICATED);
replaceResponseLocked(authenticatedResponse, (FillResponse) result, newClientState);
} else if (result instanceof Dataset) {
if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
- writeLog(MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED);
+ logAuthenticationStatusLocked(requestId,
+ MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED);
if (newClientState != null) {
if (sDebug) Slog.d(TAG, "Updating client state from auth dataset");
mClientState = newClientState;
@@ -986,13 +1031,15 @@
authenticatedResponse.getDatasets().set(datasetIdx, dataset);
autoFill(requestId, datasetIdx, dataset, false);
} else {
- writeLog(MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION);
+ logAuthenticationStatusLocked(requestId,
+ MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION);
}
} else {
if (result != null) {
Slog.w(TAG, "service returned invalid auth type: " + result);
}
- writeLog(MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION);
+ logAuthenticationStatusLocked(requestId,
+ MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION);
processNullResponseLocked(0);
}
}
@@ -1253,7 +1300,7 @@
mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
ignoredDatasets, changedFieldIds, changedDatasetIds,
manuallyFilledFieldIds, manuallyFilledDatasetIds,
- mComponentName.getPackageName(), mCompatMode);
+ mComponentName, mCompatMode);
}
}
@@ -1308,7 +1355,7 @@
mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
ignoredDatasets, changedFieldIds, changedDatasetIds,
manuallyFilledFieldIds, manuallyFilledDatasetIds,
- mComponentName.getPackageName(), mCompatMode);
+ mComponentName, mCompatMode);
return;
}
final Scores scores = result.getParcelable(EXTRA_SCORES);
@@ -1373,7 +1420,7 @@
mService.logContextCommittedLocked(id, mClientState, mSelectedDatasetIds,
ignoredDatasets, changedFieldIds, changedDatasetIds, manuallyFilledFieldIds,
manuallyFilledDatasetIds, detectedFieldIds, detectedFieldClassifications,
- mComponentName.getPackageName(), mCompatMode);
+ mComponentName, mCompatMode);
});
fcStrategy.getScores(callback, algorithm, algorithmArgs, currentValues, userValues);
@@ -1404,7 +1451,7 @@
* the current values of all fields in the screen.
*/
if (saveInfo == null) {
- if (sVerbose) Slog.w(TAG, "showSaveLocked(): no saveInfo from service");
+ if (sVerbose) Slog.v(TAG, "showSaveLocked(): no saveInfo from service");
return true;
}
@@ -1603,8 +1650,7 @@
mPendingSaveUi = new PendingUi(mActivityToken, id, client);
getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(),
mService.getServicePackageName(), saveInfo, this,
- mComponentName.getPackageName(), this,
- mPendingSaveUi, mCompatMode);
+ mComponentName, this, mPendingSaveUi, mCompatMode);
if (client != null) {
try {
client.setSaveUiState(id, true);
@@ -2065,7 +2111,7 @@
}
@Override
- public void onFillReady(FillResponse response, AutofillId filledId,
+ public void onFillReady(@NonNull FillResponse response, @NonNull AutofillId filledId,
@Nullable AutofillValue value) {
synchronized (mLock) {
if (mDestroyed) {
@@ -2081,8 +2127,8 @@
}
getUiForShowing().showFillUi(filledId, response, filterText,
- mService.getServicePackageName(), mComponentName.getPackageName(),
- mService.getServiceLabel(), mService.getServiceIcon(), this, mCompatMode);
+ mService.getServicePackageName(), mComponentName,
+ mService.getServiceLabel(), mService.getServiceIcon(), this, id, mCompatMode);
synchronized (mLock) {
if (mUiShownTime == 0) {
@@ -2103,9 +2149,8 @@
TimeUtils.formatDuration(duration, historyLog);
mUiLatencyHistory.log(historyLog.toString());
- final LogMaker metricsLog = newLogMaker(MetricsEvent.AUTOFILL_UI_LATENCY)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_DURATION, duration);
- mMetricsLogger.write(metricsLog);
+ addTaggedDataToRequestLogLocked(response.getRequestId(),
+ MetricsEvent.FIELD_AUTOFILL_DURATION, duration);
}
}
}
@@ -2474,6 +2519,14 @@
TimeUtils.formatDuration(mUiShownTime - mStartTime, pw);
pw.println();
}
+ final int requestLogsSizes = mRequestLogs.size();
+ pw.print(prefix); pw.print("mSessionLogs: "); pw.println(requestLogsSizes);
+ for (int i = 0; i < requestLogsSizes; i++) {
+ final int requestId = mRequestLogs.keyAt(i);
+ final LogMaker log = mRequestLogs.valueAt(i);
+ pw.print(prefix2); pw.print('#'); pw.print(i); pw.print(": req=");
+ pw.print(requestId); pw.print(", log=" ); dumpRequestLog(pw, log); pw.println();
+ }
pw.print(prefix); pw.print("mResponses: ");
if (mResponses == null) {
pw.println("null");
@@ -2532,6 +2585,56 @@
mRemoteFillService.dump(prefix, pw);
}
+ private static void dumpRequestLog(@NonNull PrintWriter pw, @NonNull LogMaker log) {
+ pw.print("CAT="); pw.print(log.getCategory());
+ pw.print(", TYPE=");
+ final int type = log.getType();
+ switch (type) {
+ case MetricsEvent.TYPE_SUCCESS: pw.print("SUCCESS"); break;
+ case MetricsEvent.TYPE_FAILURE: pw.print("FAILURE"); break;
+ case MetricsEvent.TYPE_CLOSE: pw.print("CLOSE"); break;
+ default: pw.print("UNSUPPORTED");
+ }
+ pw.print('('); pw.print(type); pw.print(')');
+ pw.print(", PKG="); pw.print(log.getPackageName());
+ pw.print(", SERVICE="); pw.print(log
+ .getTaggedData(MetricsEvent.FIELD_AUTOFILL_SERVICE));
+ pw.print(", ORDINAL="); pw.print(log
+ .getTaggedData(MetricsEvent.FIELD_AUTOFILL_REQUEST_ORDINAL));
+ dumpNumericValue(pw, log, "FLAGS", MetricsEvent.FIELD_AUTOFILL_FLAGS);
+ dumpNumericValue(pw, log, "NUM_DATASETS", MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS);
+ dumpNumericValue(pw, log, "UI_LATENCY", MetricsEvent.FIELD_AUTOFILL_DURATION);
+ final int authStatus =
+ getNumericValue(log, MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS);
+ if (authStatus != 0) {
+ pw.print(", AUTH_STATUS=");
+ switch (authStatus) {
+ case MetricsEvent.AUTOFILL_AUTHENTICATED:
+ pw.print("AUTHENTICATED"); break;
+ case MetricsEvent.AUTOFILL_DATASET_AUTHENTICATED:
+ pw.print("DATASET_AUTHENTICATED"); break;
+ case MetricsEvent.AUTOFILL_INVALID_AUTHENTICATION:
+ pw.print("INVALID_AUTHENTICATION"); break;
+ case MetricsEvent.AUTOFILL_INVALID_DATASET_AUTHENTICATION:
+ pw.print("INVALID_DATASET_AUTHENTICATION"); break;
+ default: pw.print("UNSUPPORTED");
+ }
+ pw.print('('); pw.print(authStatus); pw.print(')');
+ }
+ dumpNumericValue(pw, log, "FC_IDS",
+ MetricsEvent.FIELD_AUTOFILL_NUM_FIELD_CLASSIFICATION_IDS);
+ dumpNumericValue(pw, log, "COMPAT_MODE",
+ MetricsEvent.FIELD_AUTOFILL_COMPAT_MODE);
+ }
+
+ private static void dumpNumericValue(@NonNull PrintWriter pw, @NonNull LogMaker log,
+ @NonNull String field, int tag) {
+ final int value = getNumericValue(log, tag);
+ if (value != 0) {
+ pw.print(", "); pw.print(field); pw.print('='); pw.print(value);
+ }
+ }
+
void autoFillApp(Dataset dataset) {
synchronized (mLock) {
if (mDestroyed) {
@@ -2610,7 +2713,19 @@
mUi.destroyAll(mPendingSaveUi, this, true);
mUi.clearCallback(this);
mDestroyed = true;
- writeLog(MetricsEvent.AUTOFILL_SESSION_FINISHED);
+
+ // Log metrics
+ final int totalRequests = mRequestLogs.size();
+ if (totalRequests > 0) {
+ if (sVerbose) Slog.v(TAG, "destroyLocked(): logging " + totalRequests + " requests");
+ for (int i = 0; i < totalRequests; i++) {
+ final LogMaker log = mRequestLogs.valueAt(i);
+ mMetricsLogger.write(log);
+ }
+ }
+ mMetricsLogger.write(newLogMaker(MetricsEvent.AUTOFILL_SESSION_FINISHED)
+ .addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUMBER_REQUESTS, totalRequests));
+
return mRemoteFillService;
}
@@ -2719,14 +2834,36 @@
}
private LogMaker newLogMaker(int category, String servicePackageName) {
- return Helper.newLogMaker(category, mComponentName.getPackageName(), servicePackageName,
- mCompatMode);
+ return Helper.newLogMaker(category, mComponentName, servicePackageName, id, mCompatMode);
}
private void writeLog(int category) {
mMetricsLogger.write(newLogMaker(category));
}
+ private void logAuthenticationStatusLocked(int requestId, int status) {
+ addTaggedDataToRequestLogLocked(requestId,
+ MetricsEvent.FIELD_AUTOFILL_AUTHENTICATION_STATUS, status);
+ }
+
+ private void addTaggedDataToRequestLogLocked(int requestId, int tag, @Nullable Object value) {
+ final LogMaker requestLog = mRequestLogs.get(requestId);
+ if (requestLog == null) {
+ Slog.w(TAG,
+ "addTaggedDataToRequestLogLocked(tag=" + tag + "): no log for id " + requestId);
+ return;
+ }
+ requestLog.addTaggedData(tag, value);
+ }
+
+ private static String requestLogToString(@NonNull LogMaker log) {
+ final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter(sw);
+ dumpRequestLog(pw, log);
+ pw.flush();
+ return sw.toString();
+ }
+
private void wtf(@Nullable Exception e, String fmt, Object...args) {
final String message = String.format(fmt, args);
mWtfHistory.log(message);
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index cff1a84..bb97e4a 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -19,6 +19,7 @@
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static com.android.server.autofill.Helper.sDebug;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Rect;
import android.service.autofill.FillResponse;
@@ -40,7 +41,7 @@
/**
* Called when the fill UI is ready to be shown for this view.
*/
- void onFillReady(FillResponse fillResponse, AutofillId focusedId,
+ void onFillReady(@NonNull FillResponse fillResponse, @NonNull AutofillId focusedId,
@Nullable AutofillValue value);
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 811d87be..c5e838a 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
import android.content.IntentSender;
import android.graphics.drawable.Drawable;
@@ -162,22 +163,25 @@
* @param response the current fill response
* @param filterText text of the view to be filled
* @param servicePackageName package name of the autofill service filling the activity
- * @param packageName package name of the activity that is filled
+ * @param componentName component name of the activity that is filled
* @param serviceLabel label of autofill service
* @param serviceIcon icon of autofill service
- * @param callback Identifier for the caller
+ * @param callback identifier for the caller
+ * @param sessionId id of the autofill session
+ * @param compatMode whether the app is being autofilled in compatibility mode.
*/
public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
@Nullable String filterText, @Nullable String servicePackageName,
- @NonNull String packageName, @NonNull CharSequence serviceLabel,
- @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback, boolean compatMode) {
+ @NonNull ComponentName componentName, @NonNull CharSequence serviceLabel,
+ @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback, int sessionId,
+ boolean compatMode) {
if (sDebug) {
final int size = filterText == null ? 0 : filterText.length();
Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars");
}
final LogMaker log = Helper
- .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, packageName, servicePackageName,
- compatMode)
+ .newLogMaker(MetricsEvent.AUTOFILL_FILL_UI, componentName, servicePackageName,
+ sessionId, compatMode)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_FILTERTEXT_LEN,
filterText == null ? 0 : filterText.length())
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_DATASETS,
@@ -262,17 +266,19 @@
*/
public void showSaveUi(@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
@Nullable String servicePackageName, @NonNull SaveInfo info,
- @NonNull ValueFinder valueFinder, @NonNull String packageName,
+ @NonNull ValueFinder valueFinder, @NonNull ComponentName componentName,
@NonNull AutoFillUiCallback callback, @NonNull PendingUi pendingSaveUi,
boolean compatMode) {
- if (sVerbose) Slog.v(TAG, "showSaveUi() for " + packageName + ": " + info);
+ if (sVerbose) {
+ Slog.v(TAG, "showSaveUi() for " + componentName.toShortString() + ": " + info);
+ }
int numIds = 0;
numIds += info.getRequiredIds() == null ? 0 : info.getRequiredIds().length;
numIds += info.getOptionalIds() == null ? 0 : info.getOptionalIds().length;
final LogMaker log = Helper
- .newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, packageName, servicePackageName,
- compatMode)
+ .newLogMaker(MetricsEvent.AUTOFILL_SAVE_UI, componentName, servicePackageName,
+ pendingSaveUi.sessionId, compatMode)
.addTaggedData(MetricsEvent.FIELD_AUTOFILL_NUM_IDS, numIds);
mHandler.post(() -> {
@@ -281,7 +287,7 @@
}
hideAllUiThread(callback);
mSaveUi = new SaveUi(mContext, pendingSaveUi, serviceLabel, serviceIcon,
- servicePackageName, packageName, info, valueFinder, mOverlayControl,
+ servicePackageName, componentName, info, valueFinder, mOverlayControl,
new SaveUi.OnSaveListener() {
@Override
public void onSave() {
@@ -409,7 +415,7 @@
if (pendingSaveUi != null && notifyClient) {
try {
if (sDebug) Slog.d(TAG, "destroySaveUiUiThread(): notifying client");
- pendingSaveUi.client.setSaveUiState(pendingSaveUi.id, false);
+ pendingSaveUi.client.setSaveUiState(pendingSaveUi.sessionId, false);
} catch (RemoteException e) {
Slog.e(TAG, "Error notifying client to set save UI state to hidden: " + e);
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/PendingUi.java b/services/autofill/java/com/android/server/autofill/ui/PendingUi.java
index d1dfb5c..091208b 100644
--- a/services/autofill/java/com/android/server/autofill/ui/PendingUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/PendingUi.java
@@ -35,7 +35,7 @@
private final IBinder mToken;
private int mState;
- public final int id;
+ public final int sessionId;
public final IAutoFillManagerClient client;
/**
@@ -43,10 +43,11 @@
*
* @param token token used to identify this pending UI.
*/
- public PendingUi(@NonNull IBinder token, int id, @NonNull IAutoFillManagerClient client) {
+ public PendingUi(@NonNull IBinder token, int sessionId,
+ @NonNull IAutoFillManagerClient client) {
mToken = token;
mState = STATE_CREATED;
- this.id = id;
+ this.sessionId = sessionId;
this.client = client;
}
@@ -81,7 +82,7 @@
@Override
public String toString() {
- return "PendingUi: [token=" + mToken + ", id=" + id + ", state="
+ return "PendingUi: [token=" + mToken + ", sessionId=" + sessionId + ", state="
+ DebugUtils.flagsToString(PendingUi.class, "STATE_", mState) + "]";
}
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index a5311b2..dc84498 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.app.Dialog;
import android.app.PendingIntent;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
@@ -133,14 +134,14 @@
private final CharSequence mSubTitle;
private final PendingUi mPendingUi;
private final String mServicePackageName;
- private final String mPackageName;
+ private final ComponentName mComponentName;
private final boolean mCompatMode;
private boolean mDestroyed;
SaveUi(@NonNull Context context, @NonNull PendingUi pendingUi,
@NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
- @Nullable String servicePackageName, @NonNull String packageName,
+ @Nullable String servicePackageName, @NonNull ComponentName componentName,
@NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
@NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
boolean compatMode) {
@@ -148,7 +149,7 @@
mListener = new OneTimeListener(listener);
mOverlayControl = overlayControl;
mServicePackageName = servicePackageName;
- mPackageName = packageName;
+ mComponentName = componentName;
mCompatMode = compatMode;
context = new ContextThemeWrapper(context, THEME_ID);
@@ -412,12 +413,12 @@
}
private LogMaker newLogMaker(int category, int saveType) {
- return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode)
- .addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType);
+ return newLogMaker(category).addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType);
}
private LogMaker newLogMaker(int category) {
- return Helper.newLogMaker(category, mPackageName, mServicePackageName, mCompatMode);
+ return Helper.newLogMaker(category, mComponentName, mServicePackageName,
+ mPendingUi.sessionId, mCompatMode);
}
private void writeLog(int category, int saveType) {
@@ -505,7 +506,7 @@
pw.print(prefix); pw.print("subtitle: "); pw.println(mSubTitle);
pw.print(prefix); pw.print("pendingUi: "); pw.println(mPendingUi);
pw.print(prefix); pw.print("service: "); pw.println(mServicePackageName);
- pw.print(prefix); pw.print("app: "); pw.println(mPackageName);
+ pw.print(prefix); pw.print("app: "); pw.println(mComponentName.toShortString());
pw.print(prefix); pw.print("compat mode: "); pw.println(mCompatMode);
final View view = mDialog.getWindow().getDecorView();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerConstants.java b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
index dd6e6ab..ec21961 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerConstants.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerConstants.java
@@ -32,7 +32,7 @@
* <p>The backup manager constants are encoded as a key value list separated by commas and stored as
* a Settings.Secure.
*/
-class BackupManagerConstants extends KeyValueSettingObserver {
+public class BackupManagerConstants extends KeyValueSettingObserver {
private static final String TAG = "BackupManagerConstants";
private static final String SETTING = Settings.Secure.BACKUP_MANAGER_CONSTANTS;
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index bd51af2..cd1bd67 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -353,6 +353,11 @@
mAlarmManager = alarmManager;
}
+ @VisibleForTesting
+ void setPowerManager(PowerManager powerManager) {
+ mPowerManager = powerManager;
+ }
+
public void setBackupManagerBinder(IBackupManager backupManagerBinder) {
mBackupManagerBinder = backupManagerBinder;
}
@@ -2410,25 +2415,30 @@
public void backupNow() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
- final PowerSaveState result =
- mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
- if (result.batterySaverEnabled) {
- if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
- KeyValueBackupJob.schedule(mContext, mConstants); // try again in several hours
- } else {
- if (DEBUG) Slog.v(TAG, "Scheduling immediate backup pass");
- synchronized (mQueueLock) {
- // Fire the intent that kicks off the whole shebang...
- try {
- mRunBackupIntent.send();
- } catch (PendingIntent.CanceledException e) {
- // should never happen
- Slog.e(TAG, "run-backup intent cancelled!");
- }
+ long oldId = Binder.clearCallingIdentity();
+ try {
+ final PowerSaveState result =
+ mPowerManager.getPowerSaveState(ServiceType.KEYVALUE_BACKUP);
+ if (result.batterySaverEnabled) {
+ if (DEBUG) Slog.v(TAG, "Not running backup while in battery save mode");
+ KeyValueBackupJob.schedule(mContext, mConstants); // try again in several hours
+ } else {
+ if (DEBUG) Slog.v(TAG, "Scheduling immediate backup pass");
+ synchronized (mQueueLock) {
+ // Fire the intent that kicks off the whole shebang...
+ try {
+ mRunBackupIntent.send();
+ } catch (PendingIntent.CanceledException e) {
+ // should never happen
+ Slog.e(TAG, "run-backup intent cancelled!");
+ }
- // ...and cancel any pending scheduled job, because we've just superseded it
- KeyValueBackupJob.cancel(mContext);
+ // ...and cancel any pending scheduled job, because we've just superseded it
+ KeyValueBackupJob.cancel(mContext);
+ }
}
+ } finally {
+ Binder.restoreCallingIdentity(oldId);
}
}
@@ -2901,6 +2911,25 @@
return currentTransport;
}
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered.
+ */
+ @Override
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.BACKUP, "getCurrentTransportComponent");
+ long oldId = Binder.clearCallingIdentity();
+ try {
+ return mTransportManager.getCurrentTransportComponent();
+ } catch (TransportNotRegisteredException e) {
+ return null;
+ } finally {
+ Binder.restoreCallingIdentity(oldId);
+ }
+ }
+
// Report all known, available backup transports
@Override
public String[] listAllTransports() {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
index aabe7f6..f2219a0 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -16,6 +16,7 @@
package com.android.server.backup;
+import android.annotation.Nullable;
import android.app.IBackupAgent;
import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
@@ -132,6 +133,10 @@
// Report the name of the currently active transport
String getCurrentTransport();
+ // Report the component name of the host service of the currently active transport
+ @Nullable
+ ComponentName getCurrentTransportComponent();
+
// Report all known, available backup transports
String[] listAllTransports();
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 2abeaa6..787d667 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -19,8 +19,8 @@
import android.annotation.Nullable;
import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
-import android.app.backup.IBackupObserver;
import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
@@ -341,6 +341,17 @@
return (svc != null) ? svc.getCurrentTransport() : null;
}
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or
+ * {@code null} if no transport selected or if the transport selected is not registered.
+ */
+ @Override
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ BackupManagerServiceInterface svc = mService;
+ return (svc != null) ? svc.getCurrentTransportComponent() : null;
+ }
+
@Override
public String[] listAllTransports() throws RemoteException {
BackupManagerServiceInterface svc = mService;
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index 64e24d8..ddce6bb 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -176,12 +176,30 @@
return mTransportWhitelist;
}
+ /** Returns the name of the selected transport or {@code null} if no transport selected. */
@Nullable
public String getCurrentTransportName() {
return mCurrentTransportName;
}
/**
+ * Returns the {@link ComponentName} of the host service of the selected transport or
+ * {@code null} if no transport selected.
+ *
+ * @throws TransportNotRegisteredException if the selected transport is not registered.
+ */
+ @Nullable
+ public ComponentName getCurrentTransportComponent()
+ throws TransportNotRegisteredException {
+ synchronized (mTransportLock) {
+ if (mCurrentTransportName == null) {
+ return null;
+ }
+ return getRegisteredTransportComponentOrThrowLocked(mCurrentTransportName);
+ }
+ }
+
+ /**
* Returns the transport name associated with {@code transportComponent}.
*
* @throws TransportNotRegisteredException if the transport is not registered.
@@ -325,6 +343,16 @@
}
@GuardedBy("mTransportLock")
+ private ComponentName getRegisteredTransportComponentOrThrowLocked(String transportName)
+ throws TransportNotRegisteredException {
+ ComponentName transportComponent = getRegisteredTransportComponentLocked(transportName);
+ if (transportComponent == null) {
+ throw new TransportNotRegisteredException(transportName);
+ }
+ return transportComponent;
+ }
+
+ @GuardedBy("mTransportLock")
private TransportDescription getRegisteredTransportDescriptionOrThrowLocked(
ComponentName transportComponent) throws TransportNotRegisteredException {
TransportDescription description =
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index a62d973..99912d9 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1788,7 +1788,7 @@
} else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
|| UserHandle.isSameApp(callingUid, mSystemUiUid)
|| ((mAppStateTracker != null)
- && mAppStateTracker.isUidPowerSaveWhitelisted(callingUid)))) {
+ && mAppStateTracker.isUidPowerSaveUserWhitelisted(callingUid)))) {
flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
}
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 3beebcb..aa86ea8 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -812,11 +812,12 @@
resOps = new ArrayList<>();
for (int j=0; j<pkgOps.size(); j++) {
Op curOp = pkgOps.valueAt(j);
- long duration = curOp.duration == -1
+ final boolean running = curOp.duration == -1;
+ long duration = running
? (elapsedNow - curOp.startRealtime)
: curOp.duration;
resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, (int) duration, curOp.proxyUid,
+ curOp.rejectTime, (int) duration, running, curOp.proxyUid,
curOp.proxyPackageName));
}
} else {
@@ -826,11 +827,12 @@
if (resOps == null) {
resOps = new ArrayList<>();
}
- long duration = curOp.duration == -1
+ final boolean running = curOp.duration == -1;
+ final long duration = running
? (elapsedNow - curOp.startRealtime)
: curOp.duration;
resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
- curOp.rejectTime, (int) duration, curOp.proxyUid,
+ curOp.rejectTime, (int) duration, running, curOp.proxyUid,
curOp.proxyPackageName));
}
}
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 9b001ce..3a7b5d6 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -117,6 +117,12 @@
@GuardedBy("mLock")
private int[] mPowerWhitelistedAllAppIds = new int[0];
+ /**
+ * User whitelisted apps in the device idle controller.
+ */
+ @GuardedBy("mLock")
+ private int[] mPowerWhitelistedUserAppIds = new int[0];
+
@GuardedBy("mLock")
private int[] mTempWhitelistedAppIds = mPowerWhitelistedAllAppIds;
@@ -983,13 +989,16 @@
* Called by device idle controller to update the power save whitelists.
*/
public void setPowerSaveWhitelistAppIds(
- int[] powerSaveWhitelistAllAppIdArray, int[] tempWhitelistAppIdArray) {
+ int[] powerSaveWhitelistExceptIdleAppIdArray,
+ int[] powerSaveWhitelistUserAppIdArray,
+ int[] tempWhitelistAppIdArray) {
synchronized (mLock) {
final int[] previousWhitelist = mPowerWhitelistedAllAppIds;
final int[] previousTempWhitelist = mTempWhitelistedAppIds;
- mPowerWhitelistedAllAppIds = powerSaveWhitelistAllAppIdArray;
+ mPowerWhitelistedAllAppIds = powerSaveWhitelistExceptIdleAppIdArray;
mTempWhitelistedAppIds = tempWhitelistAppIdArray;
+ mPowerWhitelistedUserAppIds = powerSaveWhitelistUserAppIdArray;
if (isAnyAppIdUnwhitelisted(previousWhitelist, mPowerWhitelistedAllAppIds)) {
mHandler.notifyAllUnwhitelisted();
@@ -1194,6 +1203,16 @@
}
/**
+ * @param uid the uid to check for
+ * @return whether a UID is in the user defined power-save whitelist or not.
+ */
+ public boolean isUidPowerSaveUserWhitelisted(int uid) {
+ synchronized (mLock) {
+ return ArrayUtils.contains(mPowerWhitelistedUserAppIds, UserHandle.getAppId(uid));
+ }
+ }
+
+ /**
* @return whether a UID is in the temp power-save whitelist or not.
*
* Note clients normally shouldn't need to access it. It's only for dumpsys.
@@ -1231,9 +1250,12 @@
pw.print("Foreground uids: ");
dumpUids(pw, mForegroundUids);
- pw.print("Whitelist appids: ");
+ pw.print("Except-idle + user whitelist appids: ");
pw.println(Arrays.toString(mPowerWhitelistedAllAppIds));
+ pw.print("User whitelist appids: ");
+ pw.println(Arrays.toString(mPowerWhitelistedUserAppIds));
+
pw.print("Temp whitelist appids: ");
pw.println(Arrays.toString(mTempWhitelistedAppIds));
@@ -1311,6 +1333,10 @@
proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_WHITELIST_APP_IDS, appId);
}
+ for (int appId : mPowerWhitelistedUserAppIds) {
+ proto.write(ForceAppStandbyTrackerProto.POWER_SAVE_USER_WHITELIST_APP_IDS, appId);
+ }
+
for (int appId : mTempWhitelistedAppIds) {
proto.write(ForceAppStandbyTrackerProto.TEMP_POWER_SAVE_WHITELIST_APP_IDS, appId);
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 48817d2..c83080e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2442,97 +2442,107 @@
}
}
+ // This is a no-op if it's called with a message designating a network that has
+ // already been destroyed, because its reference will not be found in the relevant
+ // maps.
private void handleAsyncChannelDisconnected(Message msg) {
NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
if (nai != null) {
- if (DBG) {
- log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
- }
- // A network agent has disconnected.
- // TODO - if we move the logic to the network agent (have them disconnect
- // because they lost all their requests or because their score isn't good)
- // then they would disconnect organically, report their new state and then
- // disconnect the channel.
- if (nai.networkInfo.isConnected()) {
- nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
- null, null);
- }
- final boolean wasDefault = isDefaultNetwork(nai);
- if (wasDefault) {
- mDefaultInetConditionPublished = 0;
- // Log default network disconnection before required book-keeping.
- // Let rematchAllNetworksAndRequests() below record a new default network event
- // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
- // whose timestamps tell how long it takes to recover a default network.
- long now = SystemClock.elapsedRealtime();
- metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
- }
- notifyIfacesChangedForNetworkStats();
- // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
- // by other networks that are already connected. Perhaps that can be done by
- // sending all CALLBACK_LOST messages (for requests, not listens) at the end
- // of rematchAllNetworksAndRequests
- notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
- mKeepaliveTracker.handleStopAllKeepalives(nai,
- ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
- for (String iface : nai.linkProperties.getAllInterfaceNames()) {
- // Disable wakeup packet monitoring for each interface.
- wakeupModifyInterface(iface, nai.networkCapabilities, false);
- }
- nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
- mNetworkAgentInfos.remove(msg.replyTo);
- nai.maybeStopClat();
- synchronized (mNetworkForNetId) {
- // Remove the NetworkAgent, but don't mark the netId as
- // available until we've told netd to delete it below.
- mNetworkForNetId.remove(nai.network.netId);
- }
- // Remove all previously satisfied requests.
- for (int i = 0; i < nai.numNetworkRequests(); i++) {
- NetworkRequest request = nai.requestAt(i);
- NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
- if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
- clearNetworkForRequest(request.requestId);
- sendUpdatedScoreToFactories(request, 0);
- }
- }
- nai.clearLingerState();
- if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
- removeDataActivityTracking(nai);
- notifyLockdownVpn(nai);
- ensureNetworkTransitionWakelock(nai.name());
- }
- mLegacyTypeTracker.remove(nai, wasDefault);
- if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
- updateAllVpnsCapabilities();
- }
- rematchAllNetworksAndRequests(null, 0);
- mLingerMonitor.noteDisconnect(nai);
- if (nai.created) {
- // Tell netd to clean up the configuration for this network
- // (routing rules, DNS, etc).
- // This may be slow as it requires a lot of netd shelling out to ip and
- // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
- // after we've rematched networks with requests which should make a potential
- // fallback network the default or requested a new network from the
- // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
- // long time.
- try {
- mNetd.removeNetwork(nai.network.netId);
- } catch (Exception e) {
- loge("Exception removing network: " + e);
- }
- mDnsManager.removeNetwork(nai.network);
- }
- synchronized (mNetworkForNetId) {
- mNetIdInUse.delete(nai.network.netId);
- }
+ disconnectAndDestroyNetwork(nai);
} else {
NetworkFactoryInfo nfi = mNetworkFactoryInfos.remove(msg.replyTo);
if (DBG && nfi != null) log("unregisterNetworkFactory for " + nfi.name);
}
}
+ // Destroys a network, remove references to it from the internal state managed by
+ // ConnectivityService, free its interfaces and clean up.
+ // Must be called on the Handler thread.
+ private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
+ if (DBG) {
+ log(nai.name() + " got DISCONNECTED, was satisfying " + nai.numNetworkRequests());
+ }
+ // A network agent has disconnected.
+ // TODO - if we move the logic to the network agent (have them disconnect
+ // because they lost all their requests or because their score isn't good)
+ // then they would disconnect organically, report their new state and then
+ // disconnect the channel.
+ if (nai.networkInfo.isConnected()) {
+ nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+ null, null);
+ }
+ final boolean wasDefault = isDefaultNetwork(nai);
+ if (wasDefault) {
+ mDefaultInetConditionPublished = 0;
+ // Log default network disconnection before required book-keeping.
+ // Let rematchAllNetworksAndRequests() below record a new default network event
+ // if there is a fallback. Taken together, the two form a X -> 0, 0 -> Y sequence
+ // whose timestamps tell how long it takes to recover a default network.
+ long now = SystemClock.elapsedRealtime();
+ metricsLogger().defaultNetworkMetrics().logDefaultNetworkEvent(now, null, nai);
+ }
+ notifyIfacesChangedForNetworkStats();
+ // TODO - we shouldn't send CALLBACK_LOST to requests that can be satisfied
+ // by other networks that are already connected. Perhaps that can be done by
+ // sending all CALLBACK_LOST messages (for requests, not listens) at the end
+ // of rematchAllNetworksAndRequests
+ notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
+ mKeepaliveTracker.handleStopAllKeepalives(nai,
+ ConnectivityManager.PacketKeepalive.ERROR_INVALID_NETWORK);
+ for (String iface : nai.linkProperties.getAllInterfaceNames()) {
+ // Disable wakeup packet monitoring for each interface.
+ wakeupModifyInterface(iface, nai.networkCapabilities, false);
+ }
+ nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
+ mNetworkAgentInfos.remove(nai.messenger);
+ nai.maybeStopClat();
+ synchronized (mNetworkForNetId) {
+ // Remove the NetworkAgent, but don't mark the netId as
+ // available until we've told netd to delete it below.
+ mNetworkForNetId.remove(nai.network.netId);
+ }
+ // Remove all previously satisfied requests.
+ for (int i = 0; i < nai.numNetworkRequests(); i++) {
+ NetworkRequest request = nai.requestAt(i);
+ NetworkAgentInfo currentNetwork = getNetworkForRequest(request.requestId);
+ if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
+ clearNetworkForRequest(request.requestId);
+ sendUpdatedScoreToFactories(request, 0);
+ }
+ }
+ nai.clearLingerState();
+ if (nai.isSatisfyingRequest(mDefaultRequest.requestId)) {
+ removeDataActivityTracking(nai);
+ notifyLockdownVpn(nai);
+ ensureNetworkTransitionWakelock(nai.name());
+ }
+ mLegacyTypeTracker.remove(nai, wasDefault);
+ if (!nai.networkCapabilities.hasTransport(TRANSPORT_VPN)) {
+ updateAllVpnsCapabilities();
+ }
+ rematchAllNetworksAndRequests(null, 0);
+ mLingerMonitor.noteDisconnect(nai);
+ if (nai.created) {
+ // Tell netd to clean up the configuration for this network
+ // (routing rules, DNS, etc).
+ // This may be slow as it requires a lot of netd shelling out to ip and
+ // ip[6]tables to flush routes and remove the incoming packet mark rule, so do it
+ // after we've rematched networks with requests which should make a potential
+ // fallback network the default or requested a new network from the
+ // NetworkFactories, so network traffic isn't interrupted for an unnecessarily
+ // long time.
+ try {
+ mNetd.removeNetwork(nai.network.netId);
+ } catch (Exception e) {
+ loge("Exception removing network: " + e);
+ }
+ mDnsManager.removeNetwork(nai.network);
+ }
+ synchronized (mNetworkForNetId) {
+ mNetIdInUse.delete(nai.network.netId);
+ }
+ }
+
// If this method proves to be too slow then we can maintain a separate
// pendingIntent => NetworkRequestInfo map.
// This method assumes that every non-null PendingIntent maps to exactly 1 NetworkRequestInfo.
@@ -5621,6 +5631,7 @@
}
updateUids(networkAgent, networkAgent.networkCapabilities, null);
}
+ disconnectAndDestroyNetwork(networkAgent);
} else if ((oldInfo != null && oldInfo.getState() == NetworkInfo.State.SUSPENDED) ||
state == NetworkInfo.State.SUSPENDED) {
// going into or coming out of SUSPEND: rescore and notify
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 74b4543..0f4702c 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -1540,7 +1540,7 @@
mLocalActivityManager.registerScreenObserver(mScreenObserver);
- passWhiteListToForceAppStandbyTrackerLocked();
+ passWhiteListsToForceAppStandbyTrackerLocked();
updateInteractivityLocked();
}
updateConnectivityState(null);
@@ -1631,7 +1631,7 @@
mPowerSaveWhitelistAppsExceptIdle, mPowerSaveWhitelistUserApps,
mPowerSaveWhitelistExceptIdleAppIds);
- passWhiteListToForceAppStandbyTrackerLocked();
+ passWhiteListsToForceAppStandbyTrackerLocked();
}
return true;
} catch (PackageManager.NameNotFoundException e) {
@@ -1650,7 +1650,7 @@
mPowerSaveWhitelistExceptIdleAppIds);
mPowerSaveWhitelistUserAppsExceptIdle.clear();
- passWhiteListToForceAppStandbyTrackerLocked();
+ passWhiteListsToForceAppStandbyTrackerLocked();
}
}
}
@@ -2589,7 +2589,7 @@
}
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
}
- passWhiteListToForceAppStandbyTrackerLocked();
+ passWhiteListsToForceAppStandbyTrackerLocked();
}
private void updateTempWhitelistAppIdsLocked(int appId, boolean adding) {
@@ -2615,7 +2615,7 @@
}
mLocalPowerManager.setDeviceIdleTempWhitelist(mTempWhitelistAppIdArray);
}
- passWhiteListToForceAppStandbyTrackerLocked();
+ passWhiteListsToForceAppStandbyTrackerLocked();
}
private void reportPowerSaveWhitelistChangedLocked() {
@@ -2630,9 +2630,10 @@
getContext().sendBroadcastAsUser(intent, UserHandle.SYSTEM);
}
- private void passWhiteListToForceAppStandbyTrackerLocked() {
+ private void passWhiteListsToForceAppStandbyTrackerLocked() {
mAppStateTracker.setPowerSaveWhitelistAppIds(
mPowerSaveWhitelistExceptIdleAppIdArray,
+ mPowerSaveWhitelistUserAppIdArray,
mTempWhitelistAppIdArray);
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 7b02a4f..c5ab932 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1950,7 +1950,8 @@
return "UpdateRecord[" + mProvider + " " + mReceiver.mIdentity.mPackageName
+ "(" + mReceiver.mIdentity.mUid + (mIsForegroundUid ? " foreground"
: " background")
- + ")" + " " + mRealRequest + "]";
+ + ")" + " " + mRealRequest + " "
+ + mReceiver.mWorkSource + "]";
}
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index ede870f..95e5518 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -76,17 +76,35 @@
private static final long[] DOUBLE_CLICK_EFFECT_FALLBACK_TIMINGS = { 0, 30, 100, 30 };
- private static final float GAMMA_SCALE_FACTOR_MINIMUM = 2.0f;
- private static final float GAMMA_SCALE_FACTOR_LOW = 1.5f;
- private static final float GAMMA_SCALE_FACTOR_HIGH = 0.5f;
- private static final float GAMMA_SCALE_FACTOR_NONE = 1.0f;
+ // Scale levels. Each level is defined as the delta between the current setting and the default
+ // intensity for that type of vibration (i.e. current - default).
+ private static final int SCALE_VERY_LOW = -2;
+ private static final int SCALE_LOW = -1;
+ private static final int SCALE_NONE = 0;
+ private static final int SCALE_HIGH = 1;
+ private static final int SCALE_VERY_HIGH = 2;
- private static final int MAX_AMPLITUDE_MINIMUM_INTENSITY = 168; // 2/3 * 255
- private static final int MAX_AMPLITUDE_LOW_INTENSITY = 192; // 3/4 * 255
+ // Gamma adjustments for scale levels.
+ private static final float SCALE_VERY_LOW_GAMMA = 2.0f;
+ private static final float SCALE_LOW_GAMMA = 1.5f;
+ private static final float SCALE_NONE_GAMMA = 1.0f;
+ private static final float SCALE_HIGH_GAMMA = 0.5f;
+ private static final float SCALE_VERY_HIGH_GAMMA = 0.25f;
+
+ // Max amplitudes for scale levels. If one is not listed, then the max amplitude is the default
+ // max amplitude.
+ private static final int SCALE_VERY_LOW_MAX_AMPLITUDE = 168; // 2/3 * 255
+ private static final int SCALE_LOW_MAX_AMPLITUDE = 192; // 3/4 * 255
// If a vibration is playing for longer than 5s, it's probably not haptic feedback.
private static final long MAX_HAPTIC_FEEDBACK_DURATION = 5000;
+
+ // A mapping from the intensity adjustment to the scaling to apply, where the intensity
+ // adjustment is defined as the delta between the default intensity level and the user selected
+ // intensity level. It's important that we apply the scaling on the delta between the two so
+ // that the default intensity level applies no scaling to application provided effects.
+ private final SparseArray<ScaleLevel> mScaleLevels;
private final LinkedList<VibrationInfo> mPreviousVibrations;
private final int mPreviousVibrationsLimit;
private final boolean mAllowPriorityVibrationsInLowPowerMode;
@@ -180,6 +198,8 @@
case VibrationEffect.EFFECT_DOUBLE_CLICK:
case VibrationEffect.EFFECT_HEAVY_CLICK:
case VibrationEffect.EFFECT_TICK:
+ case VibrationEffect.EFFECT_POP:
+ case VibrationEffect.EFFECT_THUD:
return true;
default:
Slog.w(TAG, "Unknown prebaked vibration effect, "
@@ -254,6 +274,25 @@
}
}
+ private static final class ScaleLevel {
+ public final float gamma;
+ public final int maxAmplitude;
+
+ public ScaleLevel(float gamma) {
+ this(gamma, VibrationEffect.MAX_AMPLITUDE);
+ }
+
+ public ScaleLevel(float gamma, int maxAmplitude) {
+ this.gamma = gamma;
+ this.maxAmplitude = maxAmplitude;
+ }
+
+ @Override
+ public String toString() {
+ return "ScaleLevel{gamma=" + gamma + ", maxAmplitude=" + maxAmplitude + "}";
+ }
+ }
+
VibratorService(Context context) {
vibratorInit();
// Reset the hardware to a default state, in case this is a runtime
@@ -295,11 +334,19 @@
VibrationEffect tickEffect = createEffectFromResource(
com.android.internal.R.array.config_clockTickVibePattern);
- mFallbackEffects = new SparseArray<VibrationEffect>();
+ mFallbackEffects = new SparseArray<>();
mFallbackEffects.put(VibrationEffect.EFFECT_CLICK, clickEffect);
mFallbackEffects.put(VibrationEffect.EFFECT_DOUBLE_CLICK, doubleClickEffect);
mFallbackEffects.put(VibrationEffect.EFFECT_TICK, tickEffect);
mFallbackEffects.put(VibrationEffect.EFFECT_HEAVY_CLICK, heavyClickEffect);
+
+ mScaleLevels = new SparseArray<>();
+ mScaleLevels.put(SCALE_VERY_LOW,
+ new ScaleLevel(SCALE_VERY_LOW_GAMMA, SCALE_VERY_LOW_MAX_AMPLITUDE));
+ mScaleLevels.put(SCALE_LOW, new ScaleLevel(SCALE_LOW_GAMMA, SCALE_LOW_MAX_AMPLITUDE));
+ mScaleLevels.put(SCALE_NONE, new ScaleLevel(SCALE_NONE_GAMMA));
+ mScaleLevels.put(SCALE_HIGH, new ScaleLevel(SCALE_HIGH_GAMMA));
+ mScaleLevels.put(SCALE_VERY_HIGH, new ScaleLevel(SCALE_VERY_HIGH_GAMMA));
}
private VibrationEffect createEffectFromResource(int resId) {
@@ -675,41 +722,35 @@
return;
}
- final float gamma;
- final int maxAmplitude;
+ final int defaultIntensity;
if (vib.isNotification() || vib.isRingtone()) {
- if (intensity == Vibrator.VIBRATION_INTENSITY_LOW) {
- gamma = GAMMA_SCALE_FACTOR_MINIMUM;
- maxAmplitude = MAX_AMPLITUDE_MINIMUM_INTENSITY;
- } else if (intensity == Vibrator.VIBRATION_INTENSITY_MEDIUM) {
- gamma = GAMMA_SCALE_FACTOR_LOW;
- maxAmplitude = MAX_AMPLITUDE_LOW_INTENSITY;
- } else {
- gamma = GAMMA_SCALE_FACTOR_NONE;
- maxAmplitude = VibrationEffect.MAX_AMPLITUDE;
- }
+ defaultIntensity = mVibrator.getDefaultNotificationVibrationIntensity();
+ } else if (vib.isHapticFeedback()) {
+ defaultIntensity = mVibrator.getDefaultHapticFeedbackIntensity();
} else {
- if (intensity == Vibrator.VIBRATION_INTENSITY_LOW) {
- gamma = GAMMA_SCALE_FACTOR_LOW;
- maxAmplitude = MAX_AMPLITUDE_LOW_INTENSITY;
- } else if (intensity == Vibrator.VIBRATION_INTENSITY_HIGH) {
- gamma = GAMMA_SCALE_FACTOR_HIGH;
- maxAmplitude = VibrationEffect.MAX_AMPLITUDE;
- } else {
- gamma = GAMMA_SCALE_FACTOR_NONE;
- maxAmplitude = VibrationEffect.MAX_AMPLITUDE;
- }
+ // If we don't know what kind of vibration we're playing then just skip scaling for
+ // now.
+ return;
+ }
+
+ final ScaleLevel scale = mScaleLevels.get(intensity - defaultIntensity);
+ if (scale == null) {
+ // We should have scaling levels for all cases, so not being able to scale because of a
+ // missing level is unexpected.
+ Slog.e(TAG, "No configured scaling level!"
+ + " (current=" + intensity + ", default= " + defaultIntensity + ")");
+ return;
}
VibrationEffect scaledEffect = null;
if (vib.effect instanceof VibrationEffect.OneShot) {
VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
oneShot = oneShot.resolve(mDefaultVibrationAmplitude);
- scaledEffect = oneShot.scale(gamma, maxAmplitude);
+ scaledEffect = oneShot.scale(scale.gamma, scale.maxAmplitude);
} else if (vib.effect instanceof VibrationEffect.Waveform) {
VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
waveform = waveform.resolve(mDefaultVibrationAmplitude);
- scaledEffect = waveform.scale(gamma, maxAmplitude);
+ scaledEffect = waveform.scale(scale.gamma, scale.maxAmplitude);
} else {
Slog.w(TAG, "Unable to apply intensity scaling, unknown VibrationEffect type");
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4c2a940..ca715b5 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -119,7 +119,7 @@
// How long the startForegroundService() grace period is to get around to
// calling startForeground() before we ANR + stop it.
- static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
+ static final int SERVICE_START_FOREGROUND_TIMEOUT = 10*1000;
final ActivityManagerService mAm;
@@ -501,6 +501,18 @@
}
}
+ // At this point we've applied allowed-to-start policy based on whether this was
+ // an ordinary startService() or a startForegroundService(). Now, only require that
+ // the app follow through on the startForegroundService() -> startForeground()
+ // contract if it actually targets O+.
+ if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
+ if (DEBUG_BACKGROUND_CHECK || DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG, "startForegroundService() but host targets "
+ + r.appInfo.targetSdkVersion + " - not requiring startForeground()");
+ }
+ fgRequired = false;
+ }
+
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
callingUid, r.packageName, service, service.getFlags(), null, r.userId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ee6fdf5..9bc5829 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -37,9 +37,7 @@
import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
import static android.app.ActivityManagerInternal.ASSIST_KEY_STRUCTURE;
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
-import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
import static android.app.AppOpsManager.OP_NONE;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -5128,6 +5126,7 @@
final ActivityRecord sourceRecord;
final int targetUid;
final String targetPackage;
+ final boolean isResolver;
synchronized (this) {
if (resultTo == null) {
throw new SecurityException("Must be called from an activity");
@@ -5165,6 +5164,7 @@
}
targetUid = sourceRecord.launchedFromUid;
targetPackage = sourceRecord.launchedFromPackage;
+ isResolver = sourceRecord.isResolverOrChildActivity();
}
if (userId == UserHandle.USER_NULL) {
@@ -5184,6 +5184,7 @@
.setActivityOptions(bOptions)
.setMayWait(userId)
.setIgnoreTargetSecurity(ignoreTargetSecurity)
+ .setFilterCallingUid(isResolver ? 0 /* system */ : targetUid)
.execute();
} catch (SecurityException e) {
// XXX need to figure out how to propagate to original app.
@@ -12924,6 +12925,8 @@
// about the process state of the isolated UID *before* it is registered with the
// owning application.
mBatteryStatsService.addIsolatedUid(uid, info.uid);
+ StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
+ StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
}
final ProcessRecord r = new ProcessRecord(this, stats, info, proc, uid);
if (!mBooted && !mBooting
@@ -15173,6 +15176,7 @@
public void onLimitReached(int uid) {
Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
+ Process.myUid());
+ Binder.dumpProxyDebugInfo();
if (uid == Process.SYSTEM_UID) {
Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
} else {
@@ -20416,7 +20420,7 @@
IPackageManager pm = AppGlobals.getPackageManager();
ApplicationInfo app = null;
try {
- app = pm.getApplicationInfo(packageName, 0, userId);
+ app = pm.getApplicationInfo(packageName, STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
// can't happen; package manager is process-local
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index d64b429..d456f62 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -115,6 +115,7 @@
import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
import static com.android.server.am.ActivityRecordProto.PROC_ID;
import static com.android.server.am.ActivityRecordProto.STATE;
+import static com.android.server.am.ActivityRecordProto.TRANSLUCENT;
import static com.android.server.am.ActivityRecordProto.VISIBLE;
import static com.android.server.policy.WindowManagerPolicy.NAV_BAR_LEFT;
import static com.android.server.wm.IdentifierProto.HASH_CODE;
@@ -826,6 +827,18 @@
return ResolverActivity.class.getName().equals(realActivity.getClassName());
}
+ boolean isResolverOrChildActivity() {
+ if (!"android".equals(packageName)) {
+ return false;
+ }
+ try {
+ return ResolverActivity.class.isAssignableFrom(
+ Object.class.getClassLoader().loadClass(realActivity.getClassName()));
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
ActivityRecord(ActivityManagerService _service, ProcessRecord _caller, int _launchedFromPid,
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration,
@@ -2400,11 +2413,16 @@
}
// Compute configuration based on max supported width and height.
- outBounds.set(0, 0, maxActivityWidth, maxActivityHeight);
- // Position the activity frame on the opposite side of the nav bar.
- final int navBarPosition = service.mWindowManager.getNavBarPosition();
- final int left = navBarPosition == NAV_BAR_LEFT ? appBounds.right - outBounds.width() : 0;
- outBounds.offsetTo(left, 0 /* top */);
+ // Also account for the left / top insets (e.g. from display cutouts), which will be clipped
+ // away later in StackWindowController.adjustConfigurationForBounds(). Otherwise, the app
+ // bounds would end up too small.
+ outBounds.set(0, 0, maxActivityWidth + appBounds.left, maxActivityHeight + appBounds.top);
+
+ if (service.mWindowManager.getNavBarPosition() == NAV_BAR_LEFT) {
+ // Position the activity frame on the opposite side of the nav bar.
+ outBounds.left = appBounds.right - maxActivityWidth;
+ outBounds.right = appBounds.right;
+ }
}
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
@@ -2968,6 +2986,7 @@
if (app != null) {
proto.write(PROC_ID, app.pid);
}
+ proto.write(TRANSLUCENT, !fullscreen);
proto.end(token);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index aaa5161..3ad461f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1360,7 +1360,9 @@
}
void goToSleep() {
- ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ // Ensure visibility without updating configuration, as activities are about to sleep.
+ ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */, !PRESERVE_WINDOWS,
+ false /* updateConfiguration */);
// Make sure any paused or stopped but visible activities are now sleeping.
// This ensures that the activity's onStop() is called.
@@ -1829,12 +1831,23 @@
}
/**
- * Make sure that all activities that need to be visible (that is, they
- * currently can be seen by the user) actually are.
+ * Make sure that all activities that need to be visible in the stack (that is, they
+ * currently can be seen by the user) actually are and update their configuration.
+ */
+ final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+ boolean preserveWindows) {
+ ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
+ true /* updateConfiguration */);
+ }
+
+ /**
+ * Ensure visibility with an option to also update the configuration of visible activities.
+ * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
+ * @see ActivityStackSupervisor#ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
*/
// TODO: Should be re-worked based on the fact that each task as a stack in most cases.
final void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
- boolean preserveWindows) {
+ boolean preserveWindows, boolean updateConfiguration) {
mTopActivityOccludesKeyguard = false;
mTopDismissingKeyguardActivity = null;
mStackSupervisor.getKeyguardController().beginActivityVisibilityUpdate();
@@ -1886,9 +1899,7 @@
+ " finishing=" + r.finishing + " state=" + r.getState());
// First: if this is not the current activity being started, make
// sure it matches the current configuration.
- if (r != starting) {
- // Ensure activity configuration ignoring stop state since we are
- // becoming visible.
+ if (r != starting && updateConfiguration) {
r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
true /* ignoreStopState */);
}
@@ -2608,25 +2619,16 @@
boolean notUpdated = true;
if (mStackSupervisor.isFocusedStack(this)) {
-
- // We have special rotation behavior when Keyguard is locked. Make sure all
- // activity visibilities are set correctly as well as the transition is updated
- // if needed to get the correct rotation behavior.
+ // We have special rotation behavior when here is some active activity that
+ // requests specific orientation or Keyguard is locked. Make sure all activity
+ // visibilities are set correctly as well as the transition is updated if needed
+ // to get the correct rotation behavior. Otherwise the following call to update
+ // the orientation may cause incorrect configurations delivered to client as a
+ // result of invisible window resize.
// TODO: Remove this once visibilities are set correctly immediately when
// starting an activity.
- if (mStackSupervisor.getKeyguardController().isKeyguardLocked()) {
- mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */,
- 0 /* configChanges */, false /* preserveWindows */);
- }
- final Configuration config = mWindowManager.updateOrientationFromAppTokens(
- mStackSupervisor.getDisplayOverrideConfiguration(mDisplayId),
- next.mayFreezeScreenLocked(next.app) ? next.appToken : null,
- mDisplayId);
- if (config != null) {
- next.frozenBeforeDestroy = true;
- }
- notUpdated = !mService.updateDisplayOverrideConfigurationLocked(config, next,
- false /* deferResume */, mDisplayId);
+ notUpdated = !mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
+ true /* markFrozenIfConfigChanged */, false /* deferResume */);
}
if (notUpdated) {
@@ -3834,7 +3836,8 @@
if (finishingActivityInNonFocusedStack) {
// Finishing activity that was in paused state and it was in not currently focused
// stack, need to make something visible in its place.
- mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+ mStackSupervisor.ensureVisibilityAndConfig(null, mDisplayId,
+ false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (activityRemoved) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index afad0b1..257d79d 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1409,15 +1409,11 @@
// manager with a new orientation. We don't care about that, because the activity is
// not currently running so we are just restarting it anyway.
if (checkConfig) {
- final int displayId = r.getDisplayId();
- final Configuration config = mWindowManager.updateOrientationFromAppTokens(
- getDisplayOverrideConfiguration(displayId),
- r.mayFreezeScreenLocked(app) ? r.appToken : null, displayId);
// Deferring resume here because we're going to launch new activity shortly.
// We don't want to perform a redundant launch of the same record while ensuring
// configurations and trying to resume top activity of focused stack.
- mService.updateDisplayOverrideConfigurationLocked(config, r, true /* deferResume */,
- displayId);
+ ensureVisibilityAndConfig(r, r.getDisplayId(),
+ false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */,
@@ -1630,6 +1626,31 @@
return true;
}
+ /**
+ * Ensure all activities visibility, update orientation and configuration.
+ */
+ boolean ensureVisibilityAndConfig(ActivityRecord r, int displayId,
+ boolean markFrozenIfConfigChanged, boolean deferResume) {
+ // First ensure visibility without updating the config just yet. We need this to know what
+ // activities are affecting configuration now.
+ ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
+ false /* preserveWindows */, false /* updateConfiguration */);
+
+ // Force-update the orientation from the WindowManager, since we need the true configuration
+ // to send to the client now.
+ final Configuration config = mWindowManager.updateOrientationFromAppTokens(
+ getDisplayOverrideConfiguration(displayId),
+ r != null && r.mayFreezeScreenLocked(r.app) ? r.appToken : null,
+ displayId, true /* forceUpdate */);
+ if (r != null && markFrozenIfConfigChanged && config != null) {
+ r.frozenBeforeDestroy = true;
+ }
+
+ // Update the configuration of the activities on the display.
+ return mService.updateDisplayOverrideConfigurationLocked(config, r,
+ deferResume, displayId);
+ }
+
private void logIfTransactionTooLarge(Intent intent, Bundle icicle) {
int extrasSize = 0;
if (intent != null) {
@@ -2554,6 +2575,10 @@
final int displayId = mTmpOrderedDisplayIds.get(i);
// If a display is registered in WM, it must also be available in AM.
final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
+ if (display == null) {
+ // Looks like the display no longer exists in the system...
+ continue;
+ }
for (int j = display.getChildCount() - 1; j >= 0; --j) {
final ActivityStack stack = display.getChildAt(j);
if (ignoreCurrent && stack == currentFocus) {
@@ -3643,8 +3668,21 @@
mHandler.obtainMessage(LAUNCH_TASK_BEHIND_COMPLETE, token).sendToTarget();
}
+ /**
+ * Make sure that all activities that need to be visible in the system actually are and update
+ * their configuration.
+ */
void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
boolean preserveWindows) {
+ ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
+ true /* updateConfiguration */);
+ }
+
+ /**
+ * @see #ensureActivitiesVisibleLocked(ActivityRecord, int, boolean)
+ */
+ void ensureActivitiesVisibleLocked(ActivityRecord starting, int configChanges,
+ boolean preserveWindows, boolean updateConfiguration) {
getKeyguardController().beginActivityVisibilityUpdate();
try {
// First the front stacks. In case any are not fullscreen and are in front of home.
@@ -3652,7 +3690,8 @@
final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getChildAt(stackNdx);
- stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows);
+ stack.ensureActivitiesVisibleLocked(starting, configChanges, preserveWindows,
+ updateConfiguration);
}
}
} finally {
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index bbdc924..a7c3200 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -37,6 +37,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
import android.view.RemoteAnimationAdapter;
@@ -340,7 +341,7 @@
// Collect information about the target of the Intent.
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, resolvedTypes[i], 0,
null, userId, ActivityStarter.computeResolveFilterUid(
- callingUid, realCallingUid));
+ callingUid, realCallingUid, UserHandle.USER_NULL));
// TODO: New, check if this is correct
aInfo = mService.getActivityInfoForUser(aInfo, userId);
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index ad434b4..73e3d33 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -312,6 +312,7 @@
Configuration globalConfig;
int userId;
WaitResult waitResult;
+ int filterCallingUid;
/**
* If set to {@code true}, allows this activity start to look into
@@ -367,6 +368,7 @@
mayWait = false;
avoidMoveToFront = false;
allowPendingRemoteAnimationRegistryLookup = true;
+ filterCallingUid = UserHandle.USER_NULL;
}
/**
@@ -404,6 +406,7 @@
avoidMoveToFront = request.avoidMoveToFront;
allowPendingRemoteAnimationRegistryLookup
= request.allowPendingRemoteAnimationRegistryLookup;
+ filterCallingUid = request.filterCallingUid;
}
}
@@ -792,7 +795,8 @@
callingPid = realCallingPid;
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
- computeResolveFilterUid(callingUid, realCallingUid));
+ computeResolveFilterUid(
+ callingUid, realCallingUid, mRequest.filterCallingUid));
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
@@ -984,7 +988,9 @@
}
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
- 0 /* matchFlags */, computeResolveFilterUid(callingUid, realCallingUid));
+ 0 /* matchFlags */,
+ computeResolveFilterUid(
+ callingUid, realCallingUid, mRequest.filterCallingUid));
if (rInfo == null) {
UserInfo userInfo = mSupervisor.getUserInfo(userId);
if (userInfo != null && userInfo.isManagedProfile()) {
@@ -1006,7 +1012,8 @@
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- computeResolveFilterUid(callingUid, realCallingUid));
+ computeResolveFilterUid(
+ callingUid, realCallingUid, mRequest.filterCallingUid));
}
}
}
@@ -1078,8 +1085,8 @@
callingPid = Binder.getCallingPid();
componentSpecified = true;
rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId,
- 0 /* matchFlags */, computeResolveFilterUid(callingUid,
- realCallingUid));
+ 0 /* matchFlags */, computeResolveFilterUid(
+ callingUid, realCallingUid, mRequest.filterCallingUid));
aInfo = rInfo != null ? rInfo.activityInfo : null;
if (aInfo != null) {
aInfo = mService.getActivityInfoForUser(aInfo, userId);
@@ -1173,10 +1180,14 @@
*
* @param customCallingUid The UID on whose behalf to make the call.
* @param actualCallingUid The UID actually making the call.
+ * @param filterCallingUid The UID to be used to filter for instant apps.
* @return The logical UID making the call.
*/
- static int computeResolveFilterUid(int customCallingUid, int actualCallingUid) {
- return customCallingUid >= 0 ? customCallingUid : actualCallingUid;
+ static int computeResolveFilterUid(int customCallingUid, int actualCallingUid,
+ int filterCallingUid) {
+ return filterCallingUid != UserHandle.USER_NULL
+ ? filterCallingUid
+ : (customCallingUid >= 0 ? customCallingUid : actualCallingUid);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
@@ -2562,6 +2573,11 @@
return this;
}
+ ActivityStarter setFilterCallingUid(int filterCallingUid) {
+ mRequest.filterCallingUid = filterCallingUid;
+ return this;
+ }
+
ActivityStarter setComponentSpecified(boolean componentSpecified) {
mRequest.componentSpecified = componentSpecified;
return this;
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 49fa902..094cf06 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -31,6 +31,7 @@
import android.telephony.TelephonyManager;
import android.util.IntArray;
import android.util.Slog;
+import android.util.StatsLog;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -367,6 +368,8 @@
// Clean up any UIDs if necessary.
synchronized (mStats) {
for (int uid : uidsToRemove) {
+ StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, -1, uid,
+ StatsLog.ISOLATED_UID_CHANGED__EVENT__REMOVED);
mStats.removeIsolatedUidLocked(uid);
}
mStats.clearPendingRemovedUids();
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 89ea251..9c0d4e0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -215,6 +215,10 @@
return mPlatformType == AudioSystem.PLATFORM_TELEVISION;
}
+ private boolean isPlatformAutomotive() {
+ return mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+
/** The controller for the volume UI. */
private final VolumeController mVolumeController = new VolumeController();
@@ -2380,8 +2384,11 @@
if (DEBUG_VOL) {
Log.d(TAG, String.format("Master mute %s, %d, user=%d", mute, flags, userId));
}
- if (mUseFixedVolume) {
- return; // If using fixed volume, we don't mute.
+ if (!isPlatformAutomotive() && mUseFixedVolume) {
+ // If using fixed volume, we don't mute.
+ // TODO: remove the isPlatformAutomotive check here.
+ // The isPlatformAutomotive check is added for safety but may not be necessary.
+ return;
}
if (getCurrentUserId() == userId) {
if (mute != AudioSystem.getMasterMute()) {
@@ -3312,6 +3319,9 @@
.append(Binder.getCallingPid()).toString();
synchronized (mBluetoothA2dpEnabledLock) {
+ if (mBluetoothA2dpEnabled == on) {
+ return;
+ }
mBluetoothA2dpEnabled = on;
sendMsg(mAudioHandler, MSG_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE,
AudioSystem.FOR_MEDIA,
@@ -3808,7 +3818,7 @@
queueMsgUnderWakeLock(mAudioHandler,
MSG_SET_A2DP_SINK_CONNECTION_STATE,
state,
- 0 /* arg2 unused */,
+ -1,
btDevice,
delay);
}
@@ -4654,22 +4664,22 @@
public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state, int profile)
{
return setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
- device, state, profile, false /* suppressNoisyIntent */);
+ device, state, profile, false /* suppressNoisyIntent */, -1 /* a2dpVolume */);
}
public int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice device,
- int state, int profile, boolean suppressNoisyIntent)
+ int state, int profile, boolean suppressNoisyIntent, int a2dpVolume)
{
if (mAudioHandler.hasMessages(MSG_SET_A2DP_SINK_CONNECTION_STATE, device)) {
return 0;
}
return setBluetoothA2dpDeviceConnectionStateInt(
- device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE);
+ device, state, profile, suppressNoisyIntent, AudioSystem.DEVICE_NONE, a2dpVolume);
}
public int setBluetoothA2dpDeviceConnectionStateInt(
BluetoothDevice device, int state, int profile, boolean suppressNoisyIntent,
- int musicDevice)
+ int musicDevice, int a2dpVolume)
{
int delay;
if (profile != BluetoothProfile.A2DP && profile != BluetoothProfile.A2DP_SINK) {
@@ -4687,7 +4697,7 @@
(profile == BluetoothProfile.A2DP ?
MSG_SET_A2DP_SINK_CONNECTION_STATE : MSG_SET_A2DP_SRC_CONNECTION_STATE),
state,
- 0 /* arg2 unused */,
+ a2dpVolume,
device,
delay);
}
@@ -5217,41 +5227,41 @@
}
}
- /** Handles internal volume messages in separate volume thread. */
- private class AudioHandler extends Handler {
+ private void setDeviceVolume(VolumeStreamState streamState, int device) {
- private void setDeviceVolume(VolumeStreamState streamState, int device) {
+ synchronized (VolumeStreamState.class) {
+ // Apply volume
+ streamState.applyDeviceVolume_syncVSS(device);
- synchronized (VolumeStreamState.class) {
- // Apply volume
- streamState.applyDeviceVolume_syncVSS(device);
-
- // Apply change to all streams using this one as alias
- int numStreamTypes = AudioSystem.getNumStreamTypes();
- for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (streamType != streamState.mStreamType &&
- mStreamVolumeAlias[streamType] == streamState.mStreamType) {
- // Make sure volume is also maxed out on A2DP device for aliased stream
- // that may have a different device selected
- int streamDevice = getDeviceForStream(streamType);
- if ((device != streamDevice) && mAvrcpAbsVolSupported &&
- ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
- mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
- }
- mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
+ // Apply change to all streams using this one as alias
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
+ if (streamType != streamState.mStreamType &&
+ mStreamVolumeAlias[streamType] == streamState.mStreamType) {
+ // Make sure volume is also maxed out on A2DP device for aliased stream
+ // that may have a different device selected
+ int streamDevice = getDeviceForStream(streamType);
+ if ((device != streamDevice) && mAvrcpAbsVolSupported &&
+ ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
}
+ mStreamStates[streamType].applyDeviceVolume_syncVSS(streamDevice);
}
}
- // Post a persist volume msg
- sendMsg(mAudioHandler,
- MSG_PERSIST_VOLUME,
- SENDMSG_QUEUE,
- device,
- 0,
- streamState,
- PERSIST_DELAY);
-
}
+ // Post a persist volume msg
+ sendMsg(mAudioHandler,
+ MSG_PERSIST_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ streamState,
+ PERSIST_DELAY);
+
+ }
+
+ /** Handles internal volume messages in separate volume thread. */
+ private class AudioHandler extends Handler {
private void setAllVolumes(VolumeStreamState streamState) {
@@ -5618,7 +5628,7 @@
break;
case MSG_SET_A2DP_SINK_CONNECTION_STATE:
- onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ onSetA2dpSinkConnectionState((BluetoothDevice)msg.obj, msg.arg1, msg.arg2);
mAudioEventWakeLock.release();
break;
@@ -5912,7 +5922,7 @@
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state)
+ private void onSetA2dpSinkConnectionState(BluetoothDevice btDevice, int state, int a2dpVolume)
{
if (DEBUG_DEVICES) {
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice+"state=" + state);
@@ -5957,6 +5967,14 @@
makeA2dpDeviceUnavailableNow(mDockAddress);
}
}
+ if (a2dpVolume != -1) {
+ VolumeStreamState streamState = mStreamStates[AudioSystem.STREAM_MUSIC];
+ // Convert index to internal representation in VolumeStreamState
+ a2dpVolume = a2dpVolume * 10;
+ streamState.setIndex(a2dpVolume, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ "onSetA2dpSinkConnectionState");
+ setDeviceVolume(streamState, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
+ }
makeA2dpDeviceAvailable(address, btDevice.getName(),
"onSetA2dpSinkConnectionState");
setCurrentAudioRouteName(btDevice.getAliasName());
@@ -6059,7 +6077,7 @@
// consistent with audio policy manager state
setBluetoothA2dpDeviceConnectionStateInt(
btDevice, BluetoothA2dp.STATE_DISCONNECTED, BluetoothProfile.A2DP,
- false /* suppressNoisyIntent */, musicDevice);
+ false /* suppressNoisyIntent */, musicDevice, -1 /* a2dpVolume */);
}
}
}
@@ -6069,6 +6087,9 @@
// address is not used for now, but may be used when multiple a2dp devices are supported
synchronized (mA2dpAvrcpLock) {
mAvrcpAbsVolSupported = support;
+ sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0,
+ mStreamStates[AudioSystem.STREAM_MUSIC], 0);
}
}
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index d7057f4..2c9a494 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1310,10 +1310,10 @@
: ActivityManager.PROCESS_STATE_NONEXISTENT;
if (procState <= ActivityManager.PROCESS_STATE_TOP) {
- return ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP;
+ return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP;
}
if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
- return ContentResolver.SYNC_EXEMPTION_ACTIVE;
+ return ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET;
}
return ContentResolver.SYNC_EXEMPTION_NONE;
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 33cf11b..0a640b8 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1656,7 +1656,7 @@
}
if (syncOperation.syncExemptionFlag
- == ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP) {
+ == ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP) {
DeviceIdleController.LocalService dic =
LocalServices.getService(DeviceIdleController.LocalService.class);
if (dic != null) {
@@ -1668,6 +1668,15 @@
}
}
+ if (syncOperation.isAppStandbyExempted()) {
+ final UsageStatsManagerInternal usmi = LocalServices.getService(
+ UsageStatsManagerInternal.class);
+ if (usmi != null) {
+ usmi.reportExemptedSyncScheduled(syncOperation.owningPackage,
+ UserHandle.getUserId(syncOperation.owningUid));
+ }
+ }
+
getJobScheduler().scheduleAsPackage(b.build(), syncOperation.owningPackage,
syncOperation.target.userId, syncOperation.wakeLockName());
}
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index d097563..25edf40 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -390,10 +390,10 @@
switch (syncExemptionFlag) {
case ContentResolver.SYNC_EXEMPTION_NONE:
break;
- case ContentResolver.SYNC_EXEMPTION_ACTIVE:
+ case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET:
sb.append(" STANDBY-EXEMPTED");
break;
- case ContentResolver.SYNC_EXEMPTION_ACTIVE_WITH_TEMP:
+ case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP:
sb.append(" STANDBY-EXEMPTED(TOP)");
break;
default:
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 6a343f8..11f0701 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -341,6 +341,7 @@
boolean initialization;
Bundle extras;
int reason;
+ int syncExemptionFlag;
}
public static class DayStats {
@@ -1142,6 +1143,7 @@
item.reason = op.reason;
item.extras = op.extras;
item.event = EVENT_START;
+ item.syncExemptionFlag = op.syncExemptionFlag;
mSyncHistory.add(0, item);
while (mSyncHistory.size() > MAX_HISTORY) {
mSyncHistory.remove(mSyncHistory.size()-1);
@@ -1262,6 +1264,20 @@
SyncManager.formatDurationHMS(event, elapsedTime);
event.append(" Reason=");
event.append(SyncOperation.reasonToString(null, item.reason));
+ if (item.syncExemptionFlag != ContentResolver.SYNC_EXEMPTION_NONE) {
+ event.append(" Exemption=");
+ switch (item.syncExemptionFlag) {
+ case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET:
+ event.append("fg");
+ break;
+ case ContentResolver.SYNC_EXEMPTION_PROMOTE_BUCKET_WITH_TEMP:
+ event.append("top");
+ break;
+ default:
+ event.append(item.syncExemptionFlag);
+ break;
+ }
+ }
event.append(" Extras=");
SyncOperation.extrasToStringBuilder(item.extras, event);
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index 213ec36..0b6786c 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -189,6 +189,13 @@
mController = new ColorDisplayController(getContext(), mCurrentUser);
mController.setListener(this);
+ // Set the color mode, if valid, and immediately apply the updated tint matrix based on the
+ // existing activated state. This ensures consistency of tint across the color mode change.
+ onDisplayColorModeChanged(mController.getColorMode());
+
+ // Reset the activated state.
+ mIsActivated = null;
+
setCoefficientMatrix(getContext(), DisplayTransformManager.needsLinearColorMatrix());
// Prepare color transformation matrix.
@@ -201,9 +208,6 @@
if (mIsActivated == null) {
onActivated(mController.isActivated());
}
-
- // Transition the screen to the current temperature.
- applyTint(false);
}
private void tearDown() {
@@ -223,8 +227,6 @@
mColorMatrixAnimator.end();
mColorMatrixAnimator = null;
}
-
- mIsActivated = null;
}
@Override
@@ -288,6 +290,10 @@
@Override
public void onDisplayColorModeChanged(int mode) {
+ if (mode == -1) {
+ return;
+ }
+
// Cancel the night display tint animator if it's running.
if (mColorMatrixAnimator != null) {
mColorMatrixAnimator.cancel();
@@ -297,7 +303,8 @@
setMatrix(mController.getColorTemperature(), mMatrixNight);
final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
- dtm.setColorMode(mode, mIsActivated ? mMatrixNight : MATRIX_IDENTITY);
+ dtm.setColorMode(mode, (mIsActivated != null && mIsActivated) ? mMatrixNight
+ : MATRIX_IDENTITY);
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 0cba76b..5681367 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -16,6 +16,7 @@
package com.android.server.hdmi;
+import android.annotation.Nullable;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.input.InputManager;
import android.os.Handler;
@@ -31,6 +32,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -249,11 +251,11 @@
case Constants.MESSAGE_SET_MENU_LANGUAGE:
return handleSetMenuLanguage(message);
case Constants.MESSAGE_GIVE_PHYSICAL_ADDRESS:
- return handleGivePhysicalAddress();
+ return handleGivePhysicalAddress(null);
case Constants.MESSAGE_GIVE_OSD_NAME:
return handleGiveOsdName(message);
case Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID:
- return handleGiveDeviceVendorId();
+ return handleGiveDeviceVendorId(null);
case Constants.MESSAGE_GET_CEC_VERSION:
return handleGetCecVersion(message);
case Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS:
@@ -325,23 +327,23 @@
}
@ServiceThreadOnly
- protected boolean handleGivePhysicalAddress() {
+ protected boolean handleGivePhysicalAddress(@Nullable SendMessageCallback callback) {
assertRunOnServiceThread();
int physicalAddress = mService.getPhysicalAddress();
HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
mAddress, physicalAddress, mDeviceType);
- mService.sendCecCommand(cecMessage);
+ mService.sendCecCommand(cecMessage, callback);
return true;
}
@ServiceThreadOnly
- protected boolean handleGiveDeviceVendorId() {
+ protected boolean handleGiveDeviceVendorId(@Nullable SendMessageCallback callback) {
assertRunOnServiceThread();
int vendorId = mService.getVendorId();
HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
mAddress, vendorId);
- mService.sendCecCommand(cecMessage);
+ mService.sendCecCommand(cecMessage, callback);
return true;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
index 8c00be5..4ad51de 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageValidator.java
@@ -22,7 +22,7 @@
/**
* A helper class to validates {@link HdmiCecMessage}.
*/
-public final class HdmiCecMessageValidator {
+public class HdmiCecMessageValidator {
private static final String TAG = "HdmiCecMessageValidator";
static final int OK = 0;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index ba6da05..a1753e5 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -68,6 +68,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
@@ -290,6 +291,9 @@
@Nullable
private PowerManager mPowerManager;
+ @Nullable
+ private Looper mIoLooper;
+
// Last input port before switching to the MHL port. Should switch back to this port
// when the mobile device sends the request one touch play with off.
// Gets invalidated if we go to other port/input.
@@ -383,13 +387,18 @@
@Override
public void onStart() {
- mIoThread.start();
+ if (mIoLooper == null) {
+ mIoThread.start();
+ mIoLooper = mIoThread.getLooper();
+ }
mPowerStatus = HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
mProhibitMode = false;
mHdmiControlEnabled = readBooleanSetting(Global.HDMI_CONTROL_ENABLED, true);
mMhlInputChangeEnabled = readBooleanSetting(Global.MHL_INPUT_SWITCHING_ENABLED, true);
- mCecController = HdmiCecController.create(this);
+ if (mCecController == null) {
+ mCecController = HdmiCecController.create(this);
+ }
if (mCecController != null) {
if (mHdmiControlEnabled) {
initializeCec(INITIATED_BY_BOOT_UP);
@@ -406,7 +415,9 @@
mMhlDevices = Collections.emptyList();
initPortInfo();
- mMessageValidator = new HdmiCecMessageValidator(this);
+ if (mMessageValidator == null) {
+ mMessageValidator = new HdmiCecMessageValidator(this);
+ }
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
if (mCecController != null) {
@@ -424,6 +435,11 @@
mMhlController.setOption(OPTION_MHL_SERVICE_CONTROL, ENABLED);
}
+ @VisibleForTesting
+ void setCecController(HdmiCecController cecController) {
+ mCecController = cecController;
+ }
+
@Override
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
@@ -747,8 +763,19 @@
*
* <p>Declared as package-private.
*/
+ @Nullable
Looper getIoLooper() {
- return mIoThread.getLooper();
+ return mIoLooper;
+ }
+
+ @VisibleForTesting
+ void setIoLooper(Looper ioLooper) {
+ mIoLooper = ioLooper;
+ }
+
+ @VisibleForTesting
+ void setMessageValidator(HdmiCecMessageValidator messageValidator) {
+ mMessageValidator = messageValidator;
}
/**
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index b213ee60..b90c12a 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1016,26 +1016,25 @@
locationListener = mFusedLocationListener;
}
- if (!locationManager.isProviderEnabled(provider)) {
- Log.w(TAG, "Unable to request location since " + provider
- + " provider does not exist or is not enabled.");
- return;
- }
-
Log.i(TAG,
String.format(
"GNSS HAL Requesting location updates from %s provider for %d millis.",
provider, durationMillis));
- locationManager.requestLocationUpdates(provider,
- LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
- locationListener, mHandler.getLooper());
- locationListener.numLocationUpdateRequest++;
- mHandler.postDelayed(() -> {
- if (--locationListener.numLocationUpdateRequest == 0) {
- Log.i(TAG, String.format("Removing location updates from %s provider.", provider));
- locationManager.removeUpdates(locationListener);
- }
- }, durationMillis);
+ try {
+ locationManager.requestLocationUpdates(provider,
+ LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
+ locationListener, mHandler.getLooper());
+ locationListener.numLocationUpdateRequest++;
+ mHandler.postDelayed(() -> {
+ if (--locationListener.numLocationUpdateRequest == 0) {
+ Log.i(TAG,
+ String.format("Removing location updates from %s provider.", provider));
+ locationManager.removeUpdates(locationListener);
+ }
+ }, durationMillis);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Unable to request location.", e);
+ }
}
private void injectBestLocation(Location location) {
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 1078f6e..36b04fc 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -2537,6 +2537,7 @@
* Returns a fixed pseudorandom byte string derived from the user's synthetic password.
* This is used to salt the password history hash to protect the hash against offline
* bruteforcing, since rederiving this value requires a successful authentication.
+ * If user is a managed profile with unified challenge, currentCredential is ignored.
*/
@Override
public byte[] getHashFactor(String currentCredential, int userId) throws RemoteException {
@@ -2544,6 +2545,14 @@
if (TextUtils.isEmpty(currentCredential)) {
currentCredential = null;
}
+ if (isManagedProfileWithUnifiedLock(userId)) {
+ try {
+ currentCredential = getDecryptedPasswordForTiedProfile(userId);
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to get work profile credential", e);
+ return null;
+ }
+ }
synchronized (mSpManager) {
if (!isSyntheticPasswordBasedCredentialLocked(userId)) {
Slog.w(TAG, "Synthetic password not enabled");
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 384efdd..a7df0e2 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -95,9 +95,8 @@
// State guarded by mLock.
private final Object mLock = new Object();
- private final SparseArray<UserRecord> mUserRecords = new SparseArray<UserRecord>();
- private final ArrayMap<IBinder, ClientRecord> mAllClientRecords =
- new ArrayMap<IBinder, ClientRecord>();
+ private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
+ private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<>();
private int mCurrentUserId = -1;
private final IAudioService mAudioService;
private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
@@ -106,7 +105,7 @@
private final IntArray mActivePlayerUidMinPriorityQueue = new IntArray();
private final BroadcastReceiver mReceiver = new MediaRouterServiceBroadcastReceiver();
- BluetoothDevice mBluetoothDevice;
+ BluetoothDevice mActiveBluetoothDevice;
int mAudioRouteMainType = AudioRoutesInfo.MAIN_SPEAKER;
boolean mGlobalBluetoothA2dpOn = false;
@@ -180,7 +179,8 @@
| AudioRoutesInfo.MAIN_HEADPHONES
| AudioRoutesInfo.MAIN_USB)) == 0) {
// headset was plugged out.
- mGlobalBluetoothA2dpOn = mBluetoothDevice != null;
+ mGlobalBluetoothA2dpOn = (newRoutes.bluetoothName != null
+ || mActiveBluetoothDevice != null);
} else {
// headset was plugged in.
mGlobalBluetoothA2dpOn = false;
@@ -197,7 +197,7 @@
Slog.w(TAG, "RemoteException in the audio service.");
}
- IntentFilter intentFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ IntentFilter intentFilter = new IntentFilter(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
context.registerReceiverAsUser(mReceiver, UserHandle.ALL, intentFilter, null, null);
}
@@ -406,12 +406,14 @@
void restoreBluetoothA2dp() {
try {
- boolean a2dpOn = false;
+ boolean a2dpOn;
+ BluetoothDevice btDevice;
synchronized (mLock) {
a2dpOn = mGlobalBluetoothA2dpOn;
+ btDevice = mActiveBluetoothDevice;
}
// We don't need to change a2dp status when bluetooth is not connected.
- if (mBluetoothDevice != null) {
+ if (btDevice != null) {
Slog.v(TAG, "restoreBluetoothA2dp(" + a2dpOn + ")");
mAudioService.setBluetoothA2dpOn(a2dpOn);
}
@@ -653,17 +655,11 @@
final class MediaRouterServiceBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
- int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
- BluetoothProfile.STATE_DISCONNECTED);
- if (state == BluetoothProfile.STATE_DISCONNECTED) {
- mGlobalBluetoothA2dpOn = false;
- mBluetoothDevice = null;
- } else if (state == BluetoothProfile.STATE_CONNECTED) {
- mGlobalBluetoothA2dpOn = true;
- mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- // To ensure that BT A2DP is on, call restoreBluetoothA2dp().
- restoreBluetoothA2dp();
+ if (intent.getAction().equals(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED)) {
+ BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+ synchronized (mLock) {
+ mActiveBluetoothDevice = btDevice;
+ mGlobalBluetoothA2dpOn = btDevice != null;
}
}
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsRecorder.java b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
index 4bee55e..a16dcf3 100644
--- a/services/core/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/core/java/com/android/server/net/NetworkStatsRecorder.java
@@ -241,6 +241,20 @@
NetworkStats.Entry entry = null;
for (int i = 0; i < delta.size(); i++) {
entry = delta.getValues(i, entry);
+
+ // As a last-ditch sanity check, report any negative values and
+ // clamp them so recording below doesn't croak.
+ if (entry.isNegative()) {
+ if (mObserver != null) {
+ mObserver.foundNonMonotonic(delta, i, mCookie);
+ }
+ entry.rxBytes = Math.max(entry.rxBytes, 0);
+ entry.rxPackets = Math.max(entry.rxPackets, 0);
+ entry.txBytes = Math.max(entry.txBytes, 0);
+ entry.txPackets = Math.max(entry.txPackets, 0);
+ entry.operations = Math.max(entry.operations, 0);
+ }
+
final NetworkIdentitySet ident = ifaceIdent.get(entry.iface);
if (ident == null) {
unknownIfaces.add(entry.iface);
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 3107241..60e9eaa 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -324,6 +324,7 @@
wakeLock, getDefaultClock(), TelephonyManager.getDefault(),
new DefaultNetworkStatsSettings(context), new NetworkStatsObservers(),
getDefaultSystemDir(), getDefaultBaseDir());
+ service.registerLocalService();
HandlerThread handlerThread = new HandlerThread(TAG);
Handler.Callback callback = new HandlerCallback(service);
@@ -333,6 +334,8 @@
return service;
}
+ // This must not be called outside of tests, even within the same package, as this constructor
+ // does not register the local service. Use the create() helper above.
@VisibleForTesting
NetworkStatsService(Context context, INetworkManagementService networkManager,
AlarmManager alarmManager, PowerManager.WakeLock wakeLock, Clock clock,
@@ -349,7 +352,9 @@
mSystemDir = checkNotNull(systemDir, "missing systemDir");
mBaseDir = checkNotNull(baseDir, "missing baseDir");
mUseBpfTrafficStats = new File("/sys/fs/bpf/traffic_uid_stats_map").exists();
+ }
+ private void registerLocalService() {
LocalServices.addService(NetworkStatsManagerInternal.class,
new NetworkStatsManagerInternalImpl());
}
@@ -1711,7 +1716,7 @@
@Override
public void foundNonMonotonic(NetworkStats left, int leftIndex, NetworkStats right,
int rightIndex, String cookie) {
- Log.w(TAG, "found non-monotonic values; saving to dropbox");
+ Log.w(TAG, "Found non-monotonic values; saving to dropbox");
// record error for debugging
final StringBuilder builder = new StringBuilder();
@@ -1720,9 +1725,21 @@
builder.append("left=").append(left).append('\n');
builder.append("right=").append(right).append('\n');
- final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
- Context.DROPBOX_SERVICE);
- dropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
+ mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+ builder.toString());
+ }
+
+ @Override
+ public void foundNonMonotonic(
+ NetworkStats stats, int statsIndex, String cookie) {
+ Log.w(TAG, "Found non-monotonic values; saving to dropbox");
+
+ final StringBuilder builder = new StringBuilder();
+ builder.append("Found non-monotonic " + cookie + " values at [" + statsIndex + "]\n");
+ builder.append("stats=").append(stats).append('\n');
+
+ mContext.getSystemService(DropBoxManager.class).addText(TAG_NETSTATS_ERROR,
+ builder.toString());
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 329284d..ba73c7e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -370,6 +370,7 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
/**
* Keep track of all those APKs everywhere.
@@ -2075,6 +2076,16 @@
installerPackageName, null /*finishedReceiver*/,
updateUserIds, instantUserIds);
}
+ // if the required verifier is defined, but, is not the installer of record
+ // for the package, it gets notified
+ final boolean notifyVerifier = mRequiredVerifierPackage != null
+ && !mRequiredVerifierPackage.equals(installerPackageName);
+ if (notifyVerifier) {
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
+ extras, 0 /*flags*/,
+ mRequiredVerifierPackage, null /*finishedReceiver*/,
+ updateUserIds, instantUserIds);
+ }
// Send replaced for users that don't see the package for the first time
if (update) {
@@ -2088,6 +2099,12 @@
installerPackageName, null /*finishedReceiver*/,
updateUserIds, instantUserIds);
}
+ if (notifyVerifier) {
+ sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
+ extras, 0 /*flags*/,
+ mRequiredVerifierPackage, null /*finishedReceiver*/,
+ updateUserIds, instantUserIds);
+ }
sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
null /*package*/, null /*extras*/, 0 /*flags*/,
packageName /*targetPackage*/,
@@ -8799,8 +8816,16 @@
if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
// The version of the application on the /system partition is less than or
- // equal to the version on the /data partition. Throw an exception and use
- // the application already installed on the /data partition.
+ // equal to the version on the /data partition. Even though the disabled system package
+ // is likely to be replaced by a version on the /data partition, we make assumptions
+ // that it's part of the mPackages collection during package manager initialization. So,
+ // add it to mPackages if there isn't already a package in the collection and then throw
+ // an exception to use the application already installed on the /data partition.
+ synchronized (mPackages) {
+ if (!mPackages.containsKey(pkg.packageName)) {
+ mPackages.put(pkg.packageName, pkg);
+ }
+ }
throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
+ pkg.codePath + " ignored: updated version " + pkgSetting.versionCode
+ " better than this " + pkg.getLongVersionCode());
@@ -13954,6 +13979,43 @@
return false;
}
+ @Override
+ public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
+ enforceSystemOrPhoneCaller("setSystemAppInstallState");
+ PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
+ // The target app should always be in system
+ if (pkgSetting == null || !pkgSetting.isSystem()) {
+ return false;
+ }
+ // Check if the install state is the same
+ if (pkgSetting.getInstalled(userId) == installed) {
+ return false;
+ }
+
+ long callingId = Binder.clearCallingIdentity();
+ try {
+ if (installed) {
+ // install the app from uninstalled state
+ installExistingPackageAsUser(
+ packageName,
+ userId,
+ 0 /*installFlags*/,
+ PackageManager.INSTALL_REASON_DEVICE_SETUP);
+ return true;
+ }
+
+ // uninstall the app from installed state
+ deletePackageVersioned(
+ new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
+ new LegacyPackageDeleteObserver(null).getBinder(),
+ userId,
+ PackageManager.DELETE_SYSTEM_APP);
+ return true;
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
int userId) {
final PackageRemovedInfo info = new PackageRemovedInfo(this);
@@ -14018,10 +14080,16 @@
@Override
public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
int installReason) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
- null);
- PackageSetting pkgSetting;
final int callingUid = Binder.getCallingUid();
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED
+ && mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Neither user " + callingUid + " nor current process has "
+ + android.Manifest.permission.INSTALL_PACKAGES + ".");
+ }
+ PackageSetting pkgSetting;
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
true /* requireFullPermission */, true /* checkShell */,
"installExistingPackage for user " + userId);
@@ -14270,28 +14338,50 @@
* @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission
* @param affectedUser The user for which the changes are taking place.
*/
- void unsuspendForSuspendingPackage(String packageName, int affectedUser) {
+ void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? sUserManager.getUserIds()
: new int[] {affectedUser};
for (int userId : userIds) {
- List<String> affectedPackages = new ArrayList<>();
- synchronized (mPackages) {
- for (PackageSetting ps : mSettings.mPackages.values()) {
- final PackageUserState pus = ps.readUserState(userId);
- if (pus.suspended && packageName.equals(pus.suspendingPackage)) {
- ps.setSuspended(false, null, null, null, null, userId);
- affectedPackages.add(ps.name);
- }
+ unsuspendForSuspendingPackages(packageName::equals, userId);
+ }
+ }
+
+ /**
+ * Immediately unsuspends any packages in the given users not suspended by the platform or root.
+ * To be called when a profile owner or a device owner is added.
+ *
+ * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
+ * synchronously
+ *
+ * @param userIds The users for which to unsuspend packages
+ */
+ void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) {
+ final int sz = userIds.size();
+ for (int i = 0; i < sz; i++) {
+ unsuspendForSuspendingPackages(
+ (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
+ userIds.valueAt(i));
+ }
+ }
+
+ private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) {
+ final List<String> affectedPackages = new ArrayList<>();
+ synchronized (mPackages) {
+ for (PackageSetting ps : mSettings.mPackages.values()) {
+ final PackageUserState pus = ps.readUserState(userId);
+ if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) {
+ ps.setSuspended(false, null, null, null, null, userId);
+ affectedPackages.add(ps.name);
}
}
- if (!affectedPackages.isEmpty()) {
- final String[] packageArray = affectedPackages.toArray(
- new String[affectedPackages.size()]);
- sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
- sendPackagesSuspendedForUser(packageArray, userId, false, null);
- // Write package restrictions immediately to avoid an inconsistent state.
- mSettings.writePackageRestrictionsLPr(userId);
- }
+ }
+ if (!affectedPackages.isEmpty()) {
+ final String[] packageArray = affectedPackages.toArray(
+ new String[affectedPackages.size()]);
+ sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
+ sendPackagesSuspendedForUser(packageArray, userId, false, null);
+ // Write package restrictions immediately to avoid an inconsistent state.
+ mSettings.writePackageRestrictionsLPr(userId);
}
}
@@ -17204,17 +17294,6 @@
+ "Persistent apps are not updateable.");
return;
}
- // Prevent apps from downgrading their targetSandbox.
- final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
- final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
- if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
- res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
- "Package " + pkg.packageName + " new target sandbox "
- + newTargetSandbox + " is incompatible with the previous value of"
- + oldTargetSandbox + ".");
- return;
- }
-
// Prevent installing of child packages
if (oldPackage.parentPackage != null) {
res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
@@ -23987,6 +24066,18 @@
SparseArray<String> profileOwnerPackages) {
mProtectedPackages.setDeviceAndProfileOwnerPackages(
deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
+
+ final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
+ if (deviceOwnerPackage != null) {
+ usersWithPoOrDo.add(deviceOwnerUserId);
+ }
+ final int sz = profileOwnerPackages.size();
+ for (int i = 0; i < sz; i++) {
+ if (profileOwnerPackages.valueAt(i) != null) {
+ usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
+ }
+ }
+ unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo);
}
@Override
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index aef8f07..781faa7 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6153,7 +6153,9 @@
sendSystemKeyToStatusBarAsync(event.getKeyCode());
TelecomManager telecomManager = getTelecommService();
- if (telecomManager != null) {
+ if (telecomManager != null && !mHandleVolumeKeysInWM) {
+ // When {@link #mHandleVolumeKeysInWM} is set, volume key events
+ // should be dispatched to WM.
if (telecomManager.isRinging()) {
// If an incoming call is ringing, either VOLUME key means
// "silence ringer". We handle these keys here, rather than
@@ -6647,6 +6649,8 @@
}
void launchVoiceAssistWithWakeLock() {
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
+
final Intent voiceIntent;
if (!keyguardOn()) {
voiceIntent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
@@ -6920,7 +6924,7 @@
} else {
if (DEBUG_WAKEUP) Slog.d(TAG,
"null mKeyguardDelegate: setting mKeyguardDrawComplete.");
- finishKeyguardDrawn();
+ mHandler.sendEmptyMessage(MSG_KEYGUARD_DRAWN_COMPLETE);
}
}
}
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
index 91ef3d4..ed2b79e 100644
--- a/services/core/java/com/android/server/power/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -392,7 +392,7 @@
mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true);
- mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, true);
+ mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, false);
// Get default value from Settings.Secure
final int defaultGpsMode = Settings.Secure.getInt(mContentResolver, SECURE_KEY_GPS_MODE,
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 2886126..547ab0e 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -557,7 +557,7 @@
if (cropFile != null) {
Bitmap bitmap = BitmapFactory.decodeFile(cropFile);
if (bitmap != null) {
- colors = WallpaperColors.fromBitmap(bitmap, true /* computeHints */);
+ colors = WallpaperColors.fromBitmap(bitmap);
bitmap.recycle();
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index e637df4..0ba5a56 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1297,7 +1297,7 @@
// going to the bottom. Allowing closing {@link AppWindowToken} to participate can lead to
// an Activity in another task being started in the wrong orientation during the transition.
if (!(sendingToBottom || mService.mClosingApps.contains(this))
- && (isVisible() || mService.mOpeningApps.contains(this) || isOnTop())) {
+ && (isVisible() || mService.mOpeningApps.contains(this))) {
return mOrientation;
}
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index b8431b1..65c8e96 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -22,7 +22,9 @@
import static com.android.server.wm.AnimationSpecProto.ALPHA;
import android.graphics.Rect;
+import android.util.Log;
import android.util.proto.ProtoOutputStream;
+import android.view.Surface;
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
@@ -171,14 +173,18 @@
*/
private DimState getDimState(WindowContainer container) {
if (mDimState == null) {
- final SurfaceControl ctl = makeDimLayer();
- mDimState = new DimState(ctl);
- /**
- * See documentation on {@link #dimAbove} to understand lifecycle management of Dim's
- * via state resetting for Dim's with containers.
- */
- if (container == null) {
- mDimState.mDontReset = true;
+ try {
+ final SurfaceControl ctl = makeDimLayer();
+ mDimState = new DimState(ctl);
+ /**
+ * See documentation on {@link #dimAbove} to understand lifecycle management of
+ * Dim's via state resetting for Dim's with containers.
+ */
+ if (container == null) {
+ mDimState.mDontReset = true;
+ }
+ } catch (Surface.OutOfResourcesException e) {
+ Log.w(TAG, "OutOfResourcesException creating dim surface");
}
}
@@ -189,6 +195,11 @@
private void dim(SurfaceControl.Transaction t, WindowContainer container, int relativeLayer,
float alpha) {
final DimState d = getDimState(container);
+
+ if (d == null) {
+ return;
+ }
+
if (container != null) {
// The dim method is called from WindowState.prepareSurfaces(), which is always called
// in the correct Z from lowest Z to highest. This ensures that the dim layer is always
@@ -208,10 +219,11 @@
* @param t A Transaction in which to finish the dim.
*/
void stopDim(SurfaceControl.Transaction t) {
- DimState d = getDimState(null);
- t.hide(d.mDimLayer);
- d.isVisible = false;
- d.mDontReset = false;
+ if (mDimState != null) {
+ t.hide(mDimState.mDimLayer);
+ mDimState.isVisible = false;
+ mDimState.mDontReset = false;
+ }
}
/**
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f3423c6..b59e728 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -944,33 +944,50 @@
/**
* Update rotation of the display.
*
- * Returns true if the rotation has been changed. In this case YOU MUST CALL
- * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
+ * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
+ * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
*/
boolean updateRotationUnchecked() {
- if (mService.mDeferredRotationPauseCount > 0) {
- // Rotation updates have been paused temporarily. Defer the update until
- // updates have been resumed.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
- return false;
- }
+ return updateRotationUnchecked(false /* forceUpdate */);
+ }
- ScreenRotationAnimation screenRotationAnimation =
- mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
- if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
- // Rotation updates cannot be performed while the previous rotation change
- // animation is still in progress. Skip this update. We will try updating
- // again after the animation is finished and the display is unfrozen.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
- return false;
- }
- if (mService.mDisplayFrozen) {
- // Even if the screen rotation animation has finished (e.g. isAnimating
- // returns false), there is still some time where we haven't yet unfrozen
- // the display. We also need to abort rotation here.
- if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
- "Deferring rotation, still finishing previous rotation");
- return false;
+ /**
+ * Update rotation of the display with an option to force the update.
+ * @param forceUpdate Force the rotation update. Sometimes in WM we might skip updating
+ * orientation because we're waiting for some rotation to finish or display
+ * to unfreeze, which results in configuration of the previously visible
+ * activity being applied to a newly visible one. Forcing the rotation
+ * update allows to workaround this issue.
+ * @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
+ * {@link WindowManagerService#sendNewConfiguration(int)} TO UNFREEZE THE SCREEN.
+ */
+ boolean updateRotationUnchecked(boolean forceUpdate) {
+ ScreenRotationAnimation screenRotationAnimation;
+ if (!forceUpdate) {
+ if (mService.mDeferredRotationPauseCount > 0) {
+ // Rotation updates have been paused temporarily. Defer the update until
+ // updates have been resumed.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, rotation is paused.");
+ return false;
+ }
+
+ screenRotationAnimation =
+ mService.mAnimator.getScreenRotationAnimationLocked(mDisplayId);
+ if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {
+ // Rotation updates cannot be performed while the previous rotation change
+ // animation is still in progress. Skip this update. We will try updating
+ // again after the animation is finished and the display is unfrozen.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Deferring rotation, animation in progress.");
+ return false;
+ }
+ if (mService.mDisplayFrozen) {
+ // Even if the screen rotation animation has finished (e.g. isAnimating
+ // returns false), there is still some time where we haven't yet unfrozen
+ // the display. We also need to abort rotation here.
+ if (DEBUG_ORIENTATION) Slog.v(TAG_WM,
+ "Deferring rotation, still finishing previous rotation");
+ return false;
+ }
}
if (!mService.mDisplayEnabled) {
@@ -992,7 +1009,7 @@
if (mayRotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
- if (seamlessRotated != null) {
+ if (seamlessRotated != null && !forceUpdate) {
// We can't rotate (seamlessly or not) while waiting for the last seamless rotation
// to complete (that is, waiting for windows to redraw). It's tempting to check
// w.mSeamlessRotationCount but that could be incorrect in the case of
diff --git a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
index 7211533..2bfff26 100644
--- a/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
+++ b/services/core/java/com/android/server/wm/SurfaceAnimationRunner.java
@@ -206,6 +206,9 @@
}
}
});
+ a.mAnim = anim;
+ mRunningAnimations.put(a.mLeash, a);
+
anim.start();
if (a.mAnimSpec.canSkipFirstFrame()) {
// If we can skip the first frame, we start one frame later.
@@ -215,8 +218,6 @@
// Immediately start the animation by manually applying an animation frame. Otherwise, the
// start time would only be set in the next frame, leading to a delay.
anim.doAnimationFrame(mChoreographer.getFrameTime());
- a.mAnim = anim;
- mRunningAnimations.put(a.mLeash, a);
}
private void applyTransformation(RunningAnimation a, Transaction t, long currentPlayTime) {
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index f73c2db..35e4092 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -29,6 +29,7 @@
import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP;
import android.annotation.IntDef;
+import android.app.IActivityManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Looper;
@@ -93,6 +94,7 @@
static final float MIN_ASPECT = 1.2f;
private final WindowManagerService mService;
+ private final IActivityManager mActivityManager;
private WindowPositionerEventReceiver mInputEventReceiver;
private Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
@@ -165,7 +167,7 @@
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"wm.TaskPositioner.resizeTask");
try {
- mService.mActivityManager.resizeTask(
+ mActivityManager.resizeTask(
mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER);
} catch (RemoteException e) {
}
@@ -198,7 +200,7 @@
if (wasResizing && !mTmpRect.equals(mWindowDragBounds)) {
// We were using fullscreen surface during resizing. Request
// resizeTask() one last time to restore surface to window size.
- mService.mActivityManager.resizeTask(
+ mActivityManager.resizeTask(
mTask.mTaskId, mWindowDragBounds, RESIZE_MODE_USER_FORCED);
}
} catch(RemoteException e) {}
@@ -216,9 +218,15 @@
}
}
+ @VisibleForTesting
+ TaskPositioner(WindowManagerService service, IActivityManager activityManager) {
+ mService = service;
+ mActivityManager = activityManager;
+ }
+
/** Use {@link #create(WindowManagerService)} instead **/
TaskPositioner(WindowManagerService service) {
- mService = service;
+ this(service, service.mActivityManager);
}
@VisibleForTesting
@@ -349,8 +357,7 @@
startDrag(resize, preserveOrientation, startX, startY, mTmpRect);
}
- @VisibleForTesting
- void startDrag(boolean resize, boolean preserveOrientation,
+ private void startDrag(boolean resize, boolean preserveOrientation,
float startX, float startY, Rect startBounds) {
mCtrlType = CTRL_NONE;
mStartDragX = startX;
@@ -394,7 +401,7 @@
// guaranteed to happen before subsequent drag resizes.
mService.mH.post(() -> {
try {
- mService.mActivityManager.resizeTask(
+ mActivityManager.resizeTask(
mTask.mTaskId, startBounds, RESIZE_MODE_USER_FORCED);
} catch (RemoteException e) {
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
index c366e4d..7b775f5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
+++ b/services/core/java/com/android/server/wm/WindowManagerDebugConfig.java
@@ -54,7 +54,7 @@
static final boolean DEBUG_STARTING_WINDOW_VERBOSE = false;
static final boolean DEBUG_STARTING_WINDOW = DEBUG_STARTING_WINDOW_VERBOSE || false;
static final boolean DEBUG_WALLPAPER = false;
- static final boolean DEBUG_WALLPAPER_LIGHT = false || DEBUG_WALLPAPER;
+ static final boolean DEBUG_WALLPAPER_LIGHT = true || DEBUG_WALLPAPER;
static final boolean DEBUG_DRAG = false;
static final boolean DEBUG_SCREEN_ON = false;
static final boolean DEBUG_SCREENSHOT = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ab19b82..a2ffcae 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2371,6 +2371,12 @@
@Override
public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
IBinder freezeThisOneIfNeeded, int displayId) {
+ return updateOrientationFromAppTokens(currentConfig, freezeThisOneIfNeeded, displayId,
+ false /* forceUpdate */);
+ }
+
+ public Configuration updateOrientationFromAppTokens(Configuration currentConfig,
+ IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "updateOrientationFromAppTokens()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
}
@@ -2380,7 +2386,7 @@
try {
synchronized(mWindowMap) {
config = updateOrientationFromAppTokensLocked(currentConfig, freezeThisOneIfNeeded,
- displayId);
+ displayId, forceUpdate);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2390,13 +2396,13 @@
}
private Configuration updateOrientationFromAppTokensLocked(Configuration currentConfig,
- IBinder freezeThisOneIfNeeded, int displayId) {
+ IBinder freezeThisOneIfNeeded, int displayId, boolean forceUpdate) {
if (!mDisplayReady) {
return null;
}
Configuration config = null;
- if (updateOrientationFromAppTokensLocked(displayId)) {
+ if (updateOrientationFromAppTokensLocked(displayId, forceUpdate)) {
// If we changed the orientation but mOrientationChangeComplete is already true,
// we used seamless rotation, and we don't need to freeze the screen.
if (freezeThisOneIfNeeded != null && !mRoot.mOrientationChangeComplete) {
@@ -2444,11 +2450,15 @@
* @see android.view.IWindowManager#updateOrientationFromAppTokens(Configuration, IBinder, int)
*/
boolean updateOrientationFromAppTokensLocked(int displayId) {
+ return updateOrientationFromAppTokensLocked(displayId, false /* forceUpdate */);
+ }
+
+ boolean updateOrientationFromAppTokensLocked(int displayId, boolean forceUpdate) {
long ident = Binder.clearCallingIdentity();
try {
final DisplayContent dc = mRoot.getDisplayContent(displayId);
final int req = dc.getOrientation();
- if (req != dc.getLastOrientation()) {
+ if (req != dc.getLastOrientation() || forceUpdate) {
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
@@ -2456,12 +2466,8 @@
if (dc.isDefaultDisplay) {
mPolicy.setCurrentOrientationLw(req);
}
- if (dc.updateRotationUnchecked()) {
- // changed
- return true;
- }
+ return dc.updateRotationUnchecked(forceUpdate);
}
-
return false;
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 0c9ed21..a18d34b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -87,6 +87,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RESIZE;
@@ -1763,7 +1764,7 @@
@Override
void onResize() {
final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
- if (mHasSurface && !resizingWindows.contains(this)) {
+ if (mHasSurface && !isGoneForLayoutLw() && !resizingWindows.contains(this)) {
if (DEBUG_RESIZE) Slog.d(TAG, "onResize: Resizing " + this);
resizingWindows.add(this);
}
@@ -4210,10 +4211,15 @@
}
if (!mWinAnimator.mLastHidden || wasDeferred) {
mWinAnimator.hide(reason);
+ getDisplayContent().mWallpaperController.mDeferredHideWallpaper = null;
dispatchWallpaperVisibility(false);
final DisplayContent displayContent = getDisplayContent();
if (displayContent != null) {
displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) {
+ mService.mWindowPlacerLocked.debugLayoutRepeats("hideWallpaperWindow " + this,
+ displayContent.pendingLayoutChanges);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3eef125..561c9de 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1115,7 +1115,7 @@
setSurfaceBoundariesLocked(recoveringMemory);
- if (mIsWallpaper && !mWin.mWallpaperVisible) {
+ if (mIsWallpaper && !w.mWallpaperVisible) {
// Wallpaper is no longer visible and there is no wp target => hide it.
hide("prepareSurfaceLocked");
} else if (w.isParentWindowHidden() || !w.isOnScreen()) {
@@ -1179,6 +1179,11 @@
// LogicalDisplay.
mAnimator.setPendingLayoutChanges(w.getDisplayId(),
FINISH_LAYOUT_REDO_ANIM);
+ if (DEBUG_LAYOUT_REPEATS) {
+ mService.mWindowPlacerLocked.debugLayoutRepeats(
+ "showSurfaceRobustlyLocked " + w,
+ mAnimator.getPendingLayoutChanges(w.getDisplayId()));
+ }
} else {
w.setOrientationChanging(false);
}
diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
index 340100f..d16bc26 100644
--- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -22,9 +22,7 @@
import static com.android.server.backup.testing.TransportData.localTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpCurrentTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransports;
-
import static com.google.common.truth.Truth.assertThat;
-
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -43,9 +41,10 @@
import android.content.ContextWrapper;
import android.content.Intent;
import android.os.HandlerThread;
+import android.os.PowerManager;
+import android.os.PowerSaveState;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
-
import com.android.server.backup.internal.BackupRequest;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
@@ -54,8 +53,11 @@
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowAppBackupUtils;
import com.android.server.testing.shadows.ShadowBackupPolicyEnforcer;
+import com.android.server.testing.shadows.ShadowBinder;
+import com.android.server.testing.shadows.ShadowKeyValueBackupJob;
import com.android.server.testing.shadows.ShadowPerformBackupTask;
-
+import java.io.File;
+import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -64,6 +66,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowContextWrapper;
import org.robolectric.shadows.ShadowLog;
import org.robolectric.shadows.ShadowLooper;
@@ -71,15 +74,11 @@
import org.robolectric.shadows.ShadowSettings;
import org.robolectric.shadows.ShadowSystemClock;
-import java.io.File;
-import java.util.List;
-
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
- manifest = Config.NONE,
- sdk = 26,
- shadows = {ShadowAppBackupUtils.class, ShadowBackupPolicyEnforcer.class}
-)
+ manifest = Config.NONE,
+ sdk = 26,
+ shadows = {ShadowAppBackupUtils.class, ShadowBackupPolicyEnforcer.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class BackupManagerServiceTest {
@@ -406,6 +405,51 @@
mContext.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT);
}
+ /* Tests for transport attributes */
+
+ @Test
+ public void testGetCurrentTransportComponent() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent())
+ .thenReturn(mTransport.getTransportComponent());
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isEqualTo(mTransport.getTransportComponent());
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenNoTransportSelected() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent()).thenReturn(null);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenTransportNotRegistered() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent())
+ .thenThrow(TransportNotRegisteredException.class);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_withoutPermission() throws Exception {
+ mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ expectThrows(SecurityException.class, backupManagerService::getCurrentTransportComponent);
+ }
+
/* Tests for updating transport attributes */
private static final int PACKAGE_UID = 10;
@@ -752,6 +796,34 @@
tearDownForRequestBackup();
}
+ @Test
+ @Config(shadows = {ShadowBinder.class, ShadowKeyValueBackupJob.class})
+ public void testBackupNow_clearsCallingIdentityForJobScheduler() {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+ setUpPowerManager(backupManagerService);
+ ShadowBinder.setCallingUid(1);
+
+ backupManagerService.backupNow();
+
+ assertThat(ShadowKeyValueBackupJob.getCallingUid()).isEqualTo(ShadowBinder.LOCAL_UID);
+ assertThat(ShadowBinder.getCallingUid()).isEqualTo(1);
+ }
+
+ @Test
+ @Config(shadows = {ShadowBinder.class, ShadowKeyValueBackupJobException.class})
+ public void testBackupNow_whenExceptionThrown_restoresCallingIdentity() {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+ setUpPowerManager(backupManagerService);
+ ShadowBinder.setCallingUid(1);
+
+ expectThrows(IllegalArgumentException.class, backupManagerService::backupNow);
+ assertThat(ShadowKeyValueBackupJobException.getCallingUid())
+ .isEqualTo(ShadowBinder.LOCAL_UID);
+ assertThat(ShadowBinder.getCallingUid()).isEqualTo(1);
+ }
+
private BackupManagerService createBackupManagerServiceForRequestBackup() {
BackupManagerService backupManagerService = createInitializedBackupManagerService();
backupManagerService.setEnabled(true);
@@ -809,4 +881,23 @@
ShadowSystemClock.setCurrentTimeMillis(mShadowBackupLooper.getScheduler().getCurrentTime());
return backupManagerService;
}
+
+ private void setUpPowerManager(BackupManagerService backupManagerService) {
+ PowerManager powerManagerMock = mock(PowerManager.class);
+ when(powerManagerMock.getPowerSaveState(anyInt()))
+ .thenReturn(new PowerSaveState.Builder().setBatterySaverEnabled(true).build());
+ backupManagerService.setPowerManager(powerManagerMock);
+ }
+
+ /**
+ * We can't mock the void method {@link #schedule(Context, long, BackupManagerConstants)} so we
+ * extend {@link ShadowKeyValueBackupJob} and throw an exception at the end of the method.
+ */
+ @Implements(KeyValueBackupJob.class)
+ public static class ShadowKeyValueBackupJobException extends ShadowKeyValueBackupJob {
+ public static void schedule(Context ctx, long delay, BackupManagerConstants constants) {
+ ShadowKeyValueBackupJob.schedule(ctx, delay, constants);
+ throw new IllegalArgumentException();
+ }
+ }
}
diff --git a/services/robotests/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
index c2e7595..051a4a0 100644
--- a/services/robotests/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
@@ -77,10 +77,9 @@
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
- manifest = Config.NONE,
- sdk = 26,
- shadows = {FrameworkShadowContextImpl.class}
-)
+ manifest = Config.NONE,
+ sdk = 26,
+ shadows = {FrameworkShadowContextImpl.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class TransportManagerTest {
@@ -394,6 +393,36 @@
}
@Test
+ public void testGetCurrentTransportComponent() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1);
+
+ ComponentName transportComponent = transportManager.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isEqualTo(mTransportA1.getTransportComponent());
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenNoTransportSelected() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(null, mTransportA1);
+
+ ComponentName transportComponent = transportManager.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenTransportNotRegistered() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1.unregistered());
+
+ expectThrows(
+ TransportNotRegisteredException.class,
+ transportManager::getCurrentTransportComponent);
+ }
+
+ @Test
public void testGetTransportClient_forRegisteredTransport() throws Exception {
TransportManager transportManager =
createTransportManagerWithRegisteredTransports(mTransportA1, mTransportA2);
diff --git a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
index 1fbadd4..5844131 100644
--- a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
@@ -55,6 +55,9 @@
ShadowPackageManager shadowPackageManager, TransportData... transports)
throws Exception {
for (TransportData transport : transports) {
+ if (transport.transportStatus == TransportStatus.UNREGISTERED) {
+ continue;
+ }
ComponentName transportComponent = transport.getTransportComponent();
String packageName = transportComponent.getPackageName();
ResolveInfo resolveInfo = resolveInfo(transportComponent);
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java
new file mode 100644
index 0000000..043d44b
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowBinder.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.testing.shadows;
+
+import android.os.Binder;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+/**
+ * Extends {@link org.robolectric.shadows.ShadowBinder} with {@link Binder#clearCallingIdentity()}
+ * and {@link Binder#restoreCallingIdentity(long)}. Uses a hardcoded default {@link #LOCAL_UID} to
+ * mimic the local process uid.
+ */
+@Implements(Binder.class)
+public class ShadowBinder extends org.robolectric.shadows.ShadowBinder {
+ public static final Integer LOCAL_UID = 1000;
+ private static Integer originalCallingUid;
+
+ @Implementation
+ public static long clearCallingIdentity() {
+ originalCallingUid = getCallingUid();
+ setCallingUid(LOCAL_UID);
+ return 1L;
+ }
+
+ @Implementation
+ public static void restoreCallingIdentity(long token) {
+ setCallingUid(originalCallingUid);
+ }
+}
diff --git a/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java
new file mode 100644
index 0000000..3941f17
--- /dev/null
+++ b/services/robotests/src/com/android/server/testing/shadows/ShadowKeyValueBackupJob.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.testing.shadows;
+
+import android.content.Context;
+import android.os.Binder;
+import com.android.server.backup.BackupManagerConstants;
+import com.android.server.backup.KeyValueBackupJob;
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+
+@Implements(KeyValueBackupJob.class)
+public class ShadowKeyValueBackupJob {
+ private static int callingUid;
+
+ public static int getCallingUid() {
+ return callingUid;
+ }
+
+ @Implementation
+ public static void schedule(Context ctx, long delay, BackupManagerConstants constants) {
+ callingUid = Binder.getCallingUid();
+ }
+}
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 2ac9df9..a8efe81 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -70,7 +70,7 @@
<uses-sdk android:minSdkVersion="1"
android:targetSdkVersion="26"/>
- <application>
+ <application android:testOnly="true">
<uses-library android:name="android.test.runner" />
<service android:name="com.android.server.accounts.TestAccountType1AuthenticatorService"
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 8f989df..5ac68d4 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -18,6 +18,7 @@
<option name="test-suite-tag" value="apct-instrumentation" />
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
<option name="test-file-name" value="FrameworksServicesTests.apk" />
<option name="test-file-name" value="JobTestApp.apk" />
<option name="test-file-name" value="ConnTestApp.apk" />
diff --git a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
index 5daacd7..933b3d6b4 100644
--- a/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/AppStateTrackerTest.java
@@ -445,7 +445,7 @@
areRestricted(instance, UID_10_3, PACKAGE_3, JOBS_AND_ALARMS);
areRestricted(instance, Process.SYSTEM_UID, PACKAGE_SYSTEM, NONE);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {UID_2});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_1}, new int[] {}, new int[] {UID_2});
areRestricted(instance, UID_1, PACKAGE_1, NONE);
areRestricted(instance, UID_10_1, PACKAGE_1, NONE);
@@ -482,6 +482,15 @@
}
@Test
+ public void testPowerSaveUserWhitelist() throws Exception {
+ final AppStateTrackerTestable instance = newInstance();
+ instance.setPowerSaveWhitelistAppIds(new int[] {}, new int[] {UID_1, UID_2}, new int[] {});
+ assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_1));
+ assertTrue(instance.isUidPowerSaveUserWhitelisted(UID_2));
+ assertFalse(instance.isUidPowerSaveUserWhitelisted(UID_3));
+ }
+
+ @Test
public void testUidStateForeground() throws Exception {
final AppStateTrackerTestable instance = newInstance();
callStart(instance);
@@ -861,7 +870,7 @@
// -------------------------------------------------------------------------
// Tests with system/user/temp whitelist.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -873,7 +882,7 @@
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -886,7 +895,8 @@
reset(l);
// Update temp whitelist.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+ new int[] {UID_1, UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -898,7 +908,7 @@
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -924,7 +934,7 @@
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_1, UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
// Called once for updating all whitelist and once for updating temp whitelist
@@ -937,7 +947,7 @@
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -950,7 +960,8 @@
reset(l);
// Update temp whitelist.
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_1, UID_3});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {},
+ new int[] {UID_1, UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
@@ -962,7 +973,7 @@
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
reset(l);
- instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {UID_3});
+ instance.setPowerSaveWhitelistAppIds(new int[] {UID_2}, new int[] {}, new int[] {UID_3});
waitUntilMainHandlerDrain();
verify(l, times(1)).updateAllJobs();
diff --git a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
index ea0fe45..7f397d6 100644
--- a/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/appops/AppOpsActiveWatcherTest.java
@@ -18,6 +18,8 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@@ -36,6 +38,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.List;
+
/**
* Tests app ops version upgrades
*/
@@ -107,6 +111,46 @@
verifyNoMoreInteractions(listener);
}
+ @Test
+ public void testIsRunning() throws Exception {
+ final AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class);
+ // Start the op
+ appOpsManager.startOp(AppOpsManager.OP_CAMERA);
+
+ assertTrue("Camera should be running", isCameraOn(appOpsManager));
+
+ // Finish the op
+ appOpsManager.finishOp(AppOpsManager.OP_CAMERA);
+
+ assertFalse("Camera should not be running", isCameraOn(appOpsManager));
+ }
+
+ private boolean isCameraOn(AppOpsManager appOpsManager) {
+ List<AppOpsManager.PackageOps> packages
+ = appOpsManager.getPackagesForOps(new int[] {AppOpsManager.OP_CAMERA});
+ // AppOpsManager can return null when there is no requested data.
+ if (packages != null) {
+ final int numPackages = packages.size();
+ for (int packageInd = 0; packageInd < numPackages; packageInd++) {
+ AppOpsManager.PackageOps packageOp = packages.get(packageInd);
+ List<AppOpsManager.OpEntry> opEntries = packageOp.getOps();
+ if (opEntries != null) {
+ final int numOps = opEntries.size();
+ for (int opInd = 0; opInd < numOps; opInd++) {
+ AppOpsManager.OpEntry opEntry = opEntries.get(opInd);
+ if (opEntry.getOp() == AppOpsManager.OP_CAMERA) {
+ if (opEntry.isRunning()) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
private static Context getContext() {
return InstrumentationRegistry.getContext();
}
diff --git a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
similarity index 99%
rename from services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java
rename to services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
index c004074..6bd8011 100644
--- a/services/tests/servicestests/src/com/android/server/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/ColorDisplayServiceTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.display;
import android.annotation.NonNull;
import android.app.ActivityManager;
@@ -32,8 +32,8 @@
import com.android.internal.app.ColorDisplayController;
import com.android.internal.util.test.FakeSettingsProvider;
-import com.android.server.display.DisplayTransformManager;
-import com.android.server.display.ColorDisplayService;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
new file mode 100644
index 0000000..78cb56b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.hdmi;
+
+import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
+import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
+import static com.android.server.hdmi.Constants.ADDR_TV;
+import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
+import static com.android.server.hdmi.Constants.MESSAGE_DEVICE_VENDOR_ID;
+import static com.android.server.hdmi.Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.hardware.hdmi.HdmiPortInfo;
+import android.os.test.TestLooper;
+import android.support.test.filters.SmallTest;
+import android.os.MessageQueue;
+import com.android.server.hdmi.HdmiCecController.NativeWrapper;
+import junit.framework.Assert;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@SmallTest
+@RunWith(JUnit4.class)
+/**
+ * Tests for {@link HdmiCecLocalDevice} class.
+ */
+public class HdmiCecLocalDeviceTest {
+
+ private static final class NativeWrapperImpl implements NativeWrapper {
+
+ @Override
+ public long nativeInit(HdmiCecController handler, MessageQueue messageQueue) {
+ return 1L;
+ }
+
+ @Override
+ public int nativeSendCecCommand(long controllerPtr, int srcAddress, int dstAddress,
+ byte[] body) {
+ return SendCecCommandFactory(srcAddress, dstAddress, body);
+ }
+
+ @Override
+ public int nativeAddLogicalAddress(long controllerPtr, int logicalAddress) {
+ return 0;
+ }
+
+ @Override
+ public void nativeClearLogicalAddress(long controllerPtr) {
+
+ }
+
+ @Override
+ public int nativeGetPhysicalAddress(long controllerPtr) {
+ return mPhysicalAddr;
+ }
+
+ @Override
+ public int nativeGetVersion(long controllerPtr) {
+ return 0;
+ }
+
+ @Override
+ public int nativeGetVendorId(long controllerPtr) {
+ return 0;
+ }
+
+ @Override
+ public HdmiPortInfo[] nativeGetPortInfos(long controllerPtr) {
+ return new HdmiPortInfo[0];
+ }
+
+ @Override
+ public void nativeSetOption(long controllerPtr, int flag, boolean enabled) {
+
+ }
+
+ @Override
+ public void nativeSetLanguage(long controllerPtr, String language) {
+
+ }
+
+ @Override
+ public void nativeEnableAudioReturnChannel(long controllerPtr, int port, boolean flag) {
+
+ }
+
+ @Override
+ public boolean nativeIsConnected(long controllerPtr, int port) {
+ return false;
+ }
+ }
+
+ private static int SendCecCommandFactory(int srcAddress, int dstAddress, byte[] body) {
+ switch(body[0] & 0xFF) {
+ /** {@link Constants#MESSAGE_GIVE_PHYSICAL_ADDRESS} */
+ case MESSAGE_REPORT_PHYSICAL_ADDRESS:
+ case MESSAGE_DEVICE_VENDOR_ID:
+ return srcAddress == mSrcAddr &&
+ dstAddress == mDesAddr &&
+ Arrays.equals(Arrays.copyOfRange(body, 1, body.length), param)? 0 : 1;
+ default:
+ return 1;
+ }
+ }
+
+ private class MyHdmiCecLocalDevice extends HdmiCecLocalDevice {
+
+
+ protected MyHdmiCecLocalDevice(HdmiControlService service, int deviceType) {
+ super(service, deviceType);
+ }
+
+ @Override
+ protected void onAddressAllocated(int logicalAddress, int reason) {
+
+ }
+
+ @Override
+ protected int getPreferredAddress() {
+ return 0;
+ }
+
+ @Override
+ protected void setPreferredAddress(int addr) {
+
+ }
+ }
+
+ private MyHdmiCecLocalDevice mHdmiLocalDevice;
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private TestLooper mTestLooper = new TestLooper();
+ private static int mDesAddr = -1;
+ private static int mSrcAddr = -1;
+ private static int mPhysicalAddr = 2;
+ private int callbackResult;
+ private HdmiCecMessageValidator mMessageValidator;
+ private static byte[] param;
+
+ @Before
+ public void SetUp() {
+ mHdmiControlService = new HdmiControlService(null);
+ mHdmiControlService.setIoLooper(mTestLooper.getLooper());
+ mHdmiCecController = HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, new NativeWrapperImpl());
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mHdmiLocalDevice = new MyHdmiCecLocalDevice(
+ mHdmiControlService, DEVICE_TV);
+ mMessageValidator = new HdmiCecMessageValidator(mHdmiControlService){
+ @Override
+ int isValid(HdmiCecMessage message) {
+ return HdmiCecMessageValidator.OK;
+ }
+ };
+ mHdmiControlService.setMessageValidator(mMessageValidator);
+ }
+
+ @Test
+ public void dispatchMessage_desNotValid() {
+ HdmiCecMessage msg = new HdmiCecMessage(
+ ADDR_TV, ADDR_TV, Constants.MESSAGE_CEC_VERSION, HdmiCecMessage.EMPTY_PARAM);
+ boolean handleResult = mHdmiLocalDevice.dispatchMessage(msg);
+ assertFalse(handleResult);
+ }
+
+ @Test
+ public void handleGivePhysicalAddress_success() {
+ mSrcAddr = ADDR_UNREGISTERED;
+ mDesAddr = ADDR_BROADCAST;
+ param = new byte[] {
+ (byte) ((mPhysicalAddr >> 8) & 0xFF),
+ (byte) (mPhysicalAddr & 0xFF),
+ (byte) (DEVICE_TV & 0xFF)
+ };
+ callbackResult = -1;
+ boolean handleResult = mHdmiLocalDevice.handleGivePhysicalAddress(
+ (int finalResult) -> callbackResult = finalResult);
+ mTestLooper.dispatchAll();
+ /**
+ * Test if CecMessage is sent successfully
+ * SendMessageResult#SUCCESS is defined in HAL as 0
+ */
+ assertEquals(0, callbackResult);
+ assertTrue(handleResult);
+ }
+
+ @Test
+ public void handleGiveDeviceVendorId_success() {
+ mSrcAddr = ADDR_UNREGISTERED;
+ mDesAddr = ADDR_BROADCAST;
+ /** nativeGetVendorId returns 0 */
+ param = new byte[] {
+ (byte) ((0 >> 8) & 0xFF),
+ (byte) (0 & 0xFF),
+ (byte) (0 & 0xFF)
+ };
+ callbackResult = -1;
+ mHdmiLocalDevice.handleGiveDeviceVendorId(
+ (int finalResult) -> callbackResult = finalResult);
+ mTestLooper.dispatchAll();
+ assertEquals(0, callbackResult);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 142b950..94e02bc 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -448,6 +448,39 @@
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
}
+ public void testgetHashFactorPrimaryUser() throws RemoteException {
+ final String password = "password";
+ mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
+ assertNotNull(hashFactor);
+
+ mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
+ assertNotNull(newHashFactor);
+ // Hash factor should never change after password change/removal
+ assertArrayEquals(hashFactor, newHashFactor);
+ }
+
+ public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
+ final String pattern = "1236";
+ mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, null,
+ PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+ mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+ assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
+ }
+
+ public void testgetHashFactorManagedProfileSeparateChallenge() throws RemoteException {
+ final String primaryPassword = "primary";
+ final String profilePassword = "profile";
+ mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
+ PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+ assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
+ }
+
public void testPasswordData_serializeDeserialize() {
PasswordData data = new PasswordData();
data.scryptN = 11;
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index b8922eb..c186e48 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -22,6 +22,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
import android.app.AppGlobals;
import android.content.BroadcastReceiver;
@@ -59,6 +60,7 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;
@@ -97,6 +99,9 @@
private AppCommunicationReceiver mAppCommsReceiver;
private StubbedCallback mTestCallback;
private UiDevice mUiDevice;
+ private ComponentName mDeviceAdminComponent;
+ private boolean mPoSet;
+ private boolean mDoSet;
private static final class AppCommunicationReceiver extends BroadcastReceiver {
private Context context;
@@ -163,6 +168,8 @@
mLauncherApps = (LauncherApps) mContext.getSystemService(Context.LAUNCHER_APPS_SERVICE);
mReceiverHandler = new Handler(Looper.getMainLooper());
mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ mDeviceAdminComponent = new ComponentName(mContext,
+ "com.android.server.devicepolicy.DummyDeviceAdmins$Admin1");
IPackageManager ipm = AppGlobals.getPackageManager();
try {
// Otherwise implicit broadcasts will not be delivered.
@@ -469,12 +476,83 @@
TEST_APP_PACKAGE_NAME, receivedPackageName);
}
+ private boolean setProfileOwner() throws IOException {
+ final String result = mUiDevice.executeShellCommand("dpm set-profile-owner --user cur "
+ + mDeviceAdminComponent.flattenToString());
+ return mPoSet = result.trim().startsWith("Success");
+ }
+
+ private boolean setDeviceOwner() throws IOException {
+ final String result = mUiDevice.executeShellCommand("dpm set-device-owner --user cur "
+ + mDeviceAdminComponent.flattenToString());
+ return mDoSet = result.trim().startsWith("Success");
+ }
+
+ private void removeProfileOrDeviceOwner() throws IOException {
+ if (mPoSet || mDoSet) {
+ mUiDevice.executeShellCommand("dpm remove-active-admin --user cur "
+ + mDeviceAdminComponent.flattenToString());
+ mPoSet = mDoSet = false;
+ }
+ }
+
+ @Test
+ public void testCannotSuspendWhenProfileOwner() throws IOException {
+ assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
+ assertTrue("Profile-owner could not be set", setProfileOwner());
+ try {
+ suspendTestPackage(null, null, null);
+ fail("Suspend succeeded. Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException uex) {
+ }
+ }
+
+ @Test
+ public void testCannotSuspendWhenDeviceOwner() throws IOException {
+ assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
+ assertTrue("Device-owner could not be set", setDeviceOwner());
+ try {
+ suspendTestPackage(null, null, null);
+ fail("Suspend succeeded. Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException uex) {
+ }
+ }
+
+ @Test
+ public void testPackageUnsuspendedOnAddingDeviceOwner() throws IOException {
+ assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
+ mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
+ ACTION_REPORT_MY_PACKAGE_SUSPENDED);
+ mAppCommsReceiver.drainPendingBroadcasts();
+ suspendTestPackage(null, null, null);
+ Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
+ assertTrue("Device-owner could not be set", setDeviceOwner());
+ intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
+ }
+
+ @Test
+ public void testPackageUnsuspendedOnAddingProfileOwner() throws IOException {
+ assumeTrue(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN));
+ mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MY_PACKAGE_UNSUSPENDED,
+ ACTION_REPORT_MY_PACKAGE_SUSPENDED);
+ mAppCommsReceiver.drainPendingBroadcasts();
+ suspendTestPackage(null, null, null);
+ Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertEquals(ACTION_REPORT_MY_PACKAGE_SUSPENDED, intentFromApp.getAction());
+ assertTrue("Profile-owner could not be set", setProfileOwner());
+ intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertEquals(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED, intentFromApp.getAction());
+ }
+
@After
- public void tearDown() {
+ public void tearDown() throws IOException {
mAppCommsReceiver.unregister();
if (mTestCallback != null) {
mLauncherApps.unregisterCallback(mTestCallback);
}
+ removeProfileOrDeviceOwner();
mContext.sendBroadcast(new Intent(ACTION_FINISH_TEST_ACTIVITY)
.setPackage(TEST_APP_PACKAGE_NAME));
}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index dee2556..8461166 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -218,6 +218,11 @@
+ "stable_charging_threshold=" + STABLE_CHARGING_THRESHOLD;
}
+ @Override
+ public boolean isDeviceIdleMode() {
+ return false;
+ }
+
// Internal methods
void setDisplayOn(boolean on) {
diff --git a/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java b/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java
index 4d99b32..9c010a0 100644
--- a/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/wallpaper/WallpaperServiceTests.java
@@ -20,8 +20,6 @@
import static org.junit.Assert.assertTrue;
import android.app.WallpaperColors;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
@@ -87,17 +85,4 @@
assertEquals("OnComputeColors should have been deferred.",
0, eventCountdown.getCount());
}
-
- @Test
- public void testFromDrawableTest_doesntComputeHints() {
- WallpaperColors wallpaperColors = WallpaperColors.fromDrawable(
- new ColorDrawable(Color.BLACK));
- assertEquals("WallpaperColors should not support dark theme.", 0,
- wallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME);
-
- wallpaperColors = WallpaperColors.fromDrawable(
- new ColorDrawable(Color.WHITE));
- assertEquals("WallpaperColors should not support dark text.", 0,
- wallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 0c63cd2..f6599dc 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -202,11 +202,6 @@
assertEquals(SCREEN_ORIENTATION_UNSET, mToken.getOrientation());
// Can specify orientation if the current orientation candidate is orientation behind.
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation(SCREEN_ORIENTATION_BEHIND));
-
- mToken.sendingToBottom = false;
- mToken.setIsOnTop(true);
- // Allow for mToken to provide orientation hidden if on top and not being sent to bottom.
- assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mToken.getOrientation());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
index 7bf7dd7..4447b26 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import android.app.IActivityManager;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -27,7 +28,10 @@
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
+import org.mockito.Mockito;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static com.android.server.wm.TaskPositioner.MIN_ASPECT;
import static com.android.server.wm.WindowManagerService.dipToPixel;
import static com.android.server.wm.WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP;
@@ -54,6 +58,8 @@
private int mMinVisibleWidth;
private int mMinVisibleHeight;
private TaskPositioner mPositioner;
+ private WindowState mWindow;
+ private Rect mDimBounds = new Rect();
@Before
public void setUp() throws Exception {
@@ -69,8 +75,20 @@
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
- mPositioner = TaskPositioner.create(sWm);
+ mPositioner = new TaskPositioner(sWm, Mockito.mock(IActivityManager.class));
mPositioner.register(mDisplayContent);
+
+ mWindow = Mockito.spy(createWindow(null, TYPE_BASE_APPLICATION, "window"));
+ final Task task = Mockito.spy(mWindow.getTask());
+ Mockito.when(mWindow.getTask()).thenReturn(task);
+
+ Mockito.doAnswer(invocation -> {
+ final Rect rect = (Rect) invocation.getArguments()[0];
+ rect.set(mDimBounds);
+ return (Void) null;
+ }).when(task).getDimBounds(Mockito.any(Rect.class));
+
+ mWindow.getStack().setWindowingMode(WINDOWING_MODE_FREEFORM);
}
@Test
@@ -94,14 +112,14 @@
* as does some basic tests (e.g. dragging in Y only will keep X stable).
*/
@Test
- @Ignore
public void testBasicFreeWindowResizing() throws Exception {
final Rect r = new Rect(100, 220, 700, 520);
final int midY = (r.top + r.bottom) / 2;
+ mDimBounds.set(r);
// Start a drag resize starting upper left.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -127,8 +145,8 @@
mPositioner.getWindowDragBounds());
// Start a drag resize left and see that only the left coord changes..
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -155,15 +173,15 @@
* This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored.
*/
@Test
- @Ignore
public void testFreeWindowResizingTestAllEdges() throws Exception {
final Rect r = new Rect(100, 220, 700, 520);
final int midX = (r.left + r.right) / 2;
final int midY = (r.top + r.bottom) / 2;
+ mDimBounds.set(r);
// Drag upper left.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, 0.0f);
assertTrue(r.left != mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -171,8 +189,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag upper.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -180,8 +198,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag upper right.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertTrue(r.right != mPositioner.getWindowDragBounds().right);
@@ -189,8 +207,8 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag right.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, midY, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.right + MOUSE_DELTA_X, midY);
mPositioner.resizeDrag(r.right + 100, 0.0f);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertTrue(r.right != mPositioner.getWindowDragBounds().right);
@@ -198,9 +216,9 @@
assertEquals(r.bottom, mPositioner.getWindowDragBounds().bottom);
// Drag bottom right.
- mPositioner.startDrag(true /*resizing*/,
+ mPositioner.startDrag(mWindow, true /*resizing*/,
false /*preserveOrientation*/,
- r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r);
+ r.right + MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertTrue(r.right != mPositioner.getWindowDragBounds().right);
@@ -208,8 +226,8 @@
assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
// Drag bottom.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, midX, r.bottom + MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, midX, r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(r.right + 100, r.bottom + 100);
assertEquals(r.left, mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -217,8 +235,8 @@
assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
// Drag bottom left.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.bottom + MOUSE_DELTA_Y);
mPositioner.resizeDrag(0.0f, r.bottom + 100);
assertTrue(r.left != mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -226,8 +244,8 @@
assertTrue(r.bottom != mPositioner.getWindowDragBounds().bottom);
// Drag left.
- mPositioner.startDrag(true /*resizing*/,
- false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midX, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ false /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midX);
mPositioner.resizeDrag(0.0f, r.bottom + 100);
assertTrue(r.left != mPositioner.getWindowDragBounds().left);
assertEquals(r.right, mPositioner.getWindowDragBounds().right);
@@ -240,12 +258,12 @@
* right things upon resizing when dragged from the top left corner.
*/
@Test
- @Ignore
public void testLandscapePreservedWindowResizingDragTopLeft() throws Exception {
final Rect r = new Rect(100, 220, 700, 520);
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -278,13 +296,13 @@
* right things upon resizing when dragged from the left corner.
*/
@Test
- @Ignore
public void testLandscapePreservedWindowResizingDragLeft() throws Exception {
final Rect r = new Rect(100, 220, 700, 520);
final int midY = (r.top + r.bottom) / 2;
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -319,13 +337,13 @@
* right things upon resizing when dragged from the top corner.
*/
@Test
- @Ignore
public void testLandscapePreservedWindowResizingDragTop() throws Exception {
final Rect r = new Rect(100, 220, 700, 520);
final int midX = (r.left + r.right) / 2;
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y);
// Drag to the left (no change).
mPositioner.resizeDrag(0.0f, r.top);
@@ -356,12 +374,12 @@
* right things upon resizing when dragged from the top left corner.
*/
@Test
- @Ignore
public void testPortraitPreservedWindowResizingDragTopLeft() throws Exception {
final Rect r = new Rect(330, 100, 630, 600);
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, r.top - MOUSE_DELTA_Y);
assertBoundsEquals(r, mPositioner.getWindowDragBounds());
// Drag to a good landscape size.
@@ -371,8 +389,8 @@
mPositioner.getWindowDragBounds());
// Drag to a good portrait size.
- mPositioner.resizeDrag(500.0f, 0.0f);
- assertBoundsEquals(new Rect(500 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
+ mPositioner.resizeDrag(400.0f, 0.0f);
+ assertBoundsEquals(new Rect(400 + MOUSE_DELTA_X, MOUSE_DELTA_Y, r.right, r.bottom),
mPositioner.getWindowDragBounds());
// Drag to a too small size for the height and the the width shrinking.
@@ -389,13 +407,13 @@
* right things upon resizing when dragged from the left corner.
*/
@Test
- @Ignore
public void testPortraitPreservedWindowResizingDragLeft() throws Exception {
final Rect r = new Rect(330, 100, 630, 600);
final int midY = (r.top + r.bottom) / 2;
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, r.left - MOUSE_DELTA_X, midY);
// Drag to the left.
mPositioner.resizeDrag(0.0f, midY);
@@ -432,13 +450,13 @@
* right things upon resizing when dragged from the top corner.
*/
@Test
- @Ignore
public void testPortraitPreservedWindowResizingDragTop() throws Exception {
final Rect r = new Rect(330, 100, 630, 600);
final int midX = (r.left + r.right) / 2;
+ mDimBounds.set(r);
- mPositioner.startDrag(true /*resizing*/,
- true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y, r);
+ mPositioner.startDrag(mWindow, true /*resizing*/,
+ true /*preserveOrientation*/, midX, r.top - MOUSE_DELTA_Y);
// Drag to the left (no change).
mPositioner.resizeDrag(0.0f, r.top);
@@ -472,9 +490,9 @@
+ ") " + Log.getStackTraceString(new Throwable()));
}
}
- assertEquals(expected.left, actual.left);
- assertEquals(expected.right, actual.right);
- assertEquals(expected.top, actual.top);
- assertEquals(expected.bottom, actual.bottom);
+ assertEquals("left", expected.left, actual.left);
+ assertEquals("right", expected.right, actual.right);
+ assertEquals("top", expected.top, actual.top);
+ assertEquals("bottom", expected.bottom, actual.bottom);
}
}
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index 271f813..4e99732 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -340,15 +340,27 @@
public void setAppStandbyBucket(String packageName, int userId, long elapsedRealtime,
int bucket, int reason) {
+ setAppStandbyBucket(packageName, userId, elapsedRealtime, bucket, reason, false);
+ }
+
+ public void setAppStandbyBucket(String packageName, int userId, long elapsedRealtime,
+ int bucket, int reason, boolean resetTimeout) {
ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
AppUsageHistory appUsageHistory =
getPackageHistory(userHistory, packageName, elapsedRealtime, true);
appUsageHistory.currentBucket = bucket;
appUsageHistory.bucketingReason = reason;
+
+ final long elapsed = getElapsedTime(elapsedRealtime);
+
if ((reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED) {
- appUsageHistory.lastPredictedTime = getElapsedTime(elapsedRealtime);
+ appUsageHistory.lastPredictedTime = elapsed;
appUsageHistory.lastPredictedBucket = bucket;
}
+ if (resetTimeout) {
+ appUsageHistory.bucketActiveTimeoutTime = elapsed;
+ appUsageHistory.bucketWorkingSetTimeoutTime = elapsed;
+ }
if (DEBUG) {
Slog.d(TAG, "Moved " + packageName + " to bucket=" + appUsageHistory.currentBucket
+ ", reason=0x0" + Integer.toHexString(appUsageHistory.bucketingReason));
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 08b0496..9c62700 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -24,6 +24,8 @@
import static android.app.usage.UsageStatsManager.REASON_MAIN_USAGE;
import static android.app.usage.UsageStatsManager.REASON_SUB_PREDICTED_RESTORED;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_ACTIVE_TIMEOUT;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
+import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_EXEMPTED_SYNC_START;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_BACKGROUND;
import static android.app.usage.UsageStatsManager.REASON_SUB_USAGE_MOVE_TO_FOREGROUND;
@@ -113,6 +115,9 @@
/**
* Manages the standby state of an app, listening to various events.
+ *
+ * Unit test:
+ atest ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
*/
public class AppStandbyController {
@@ -191,8 +196,9 @@
static final int MSG_ONE_TIME_CHECK_IDLE_STATES = 10;
/** Check the state of one app: arg1 = userId, arg2 = uid, obj = (String) packageName */
static final int MSG_CHECK_PACKAGE_IDLE_STATE = 11;
- static final int MSG_REPORT_EXEMPTED_SYNC_START = 12;
- static final int MSG_UPDATE_STABLE_CHARGING= 13;
+ static final int MSG_REPORT_EXEMPTED_SYNC_SCHEDULED = 12;
+ static final int MSG_REPORT_EXEMPTED_SYNC_START = 13;
+ static final int MSG_UPDATE_STABLE_CHARGING= 14;
long mCheckIdleIntervalMillis;
long mAppIdleParoleIntervalMillis;
@@ -210,8 +216,20 @@
long mPredictionTimeoutMillis;
/** Maximum time a sync adapter associated with a CP should keep the buckets elevated. */
long mSyncAdapterTimeoutMillis;
- /** Maximum time an exempted sync should keep the buckets elevated. */
- long mExemptedSyncAdapterTimeoutMillis;
+ /**
+ * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in
+ * non-doze
+ */
+ long mExemptedSyncScheduledNonDozeTimeoutMillis;
+ /**
+ * Maximum time an exempted sync should keep the buckets elevated, when sync is scheduled in
+ * doze
+ */
+ long mExemptedSyncScheduledDozeTimeoutMillis;
+ /**
+ * Maximum time an exempted sync should keep the buckets elevated, when sync is started.
+ */
+ long mExemptedSyncStartTimeoutMillis;
/** Maximum time a system interaction should keep the buckets elevated. */
long mSystemInteractionTimeoutMillis;
/** The length of time phone must be charging before considered stable enough to run jobs */
@@ -390,6 +408,37 @@
}
}
+ void reportExemptedSyncScheduled(String packageName, int userId) {
+ if (!mAppIdleEnabled) return;
+
+ final int bucketToPromote;
+ final int usageReason;
+ final long durationMillis;
+
+ if (!mInjector.isDeviceIdleMode()) {
+ // Not dozing.
+ bucketToPromote = STANDBY_BUCKET_ACTIVE;
+ usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_NON_DOZE;
+ durationMillis = mExemptedSyncScheduledNonDozeTimeoutMillis;
+ } else {
+ // Dozing.
+ bucketToPromote = STANDBY_BUCKET_WORKING_SET;
+ usageReason = REASON_SUB_USAGE_EXEMPTED_SYNC_SCHEDULED_DOZE;
+ durationMillis = mExemptedSyncScheduledDozeTimeoutMillis;
+ }
+
+ final long elapsedRealtime = mInjector.elapsedRealtime();
+
+ synchronized (mAppIdleLock) {
+ AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId,
+ bucketToPromote, usageReason,
+ 0,
+ elapsedRealtime + durationMillis);
+ maybeInformListeners(packageName, userId, elapsedRealtime,
+ appUsage.currentBucket, appUsage.bucketingReason, false);
+ }
+ }
+
void reportExemptedSyncStart(String packageName, int userId) {
if (!mAppIdleEnabled) return;
@@ -399,7 +448,7 @@
AppUsageHistory appUsage = mAppIdleHistory.reportUsage(packageName, userId,
STANDBY_BUCKET_ACTIVE, REASON_SUB_USAGE_EXEMPTED_SYNC_START,
0,
- elapsedRealtime + mExemptedSyncAdapterTimeoutMillis);
+ elapsedRealtime + mExemptedSyncStartTimeoutMillis);
maybeInformListeners(packageName, userId, elapsedRealtime,
appUsage.currentBucket, appUsage.bucketingReason, false);
}
@@ -1106,6 +1155,11 @@
void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime) {
+ setAppStandbyBucket(packageName, userId, newBucket, reason, elapsedRealtime, false);
+ }
+
+ void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
+ int reason, long elapsedRealtime, boolean resetTimeout) {
synchronized (mAppIdleLock) {
AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
userId, elapsedRealtime);
@@ -1155,7 +1209,7 @@
}
mAppIdleHistory.setAppStandbyBucket(packageName, userId, elapsedRealtime, newBucket,
- reason);
+ reason, resetTimeout);
}
maybeInformListeners(packageName, userId, elapsedRealtime, newBucket, reason, false);
}
@@ -1357,6 +1411,11 @@
.sendToTarget();
}
+ void postReportExemptedSyncScheduled(String packageName, int userId) {
+ mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_SCHEDULED, userId, 0, packageName)
+ .sendToTarget();
+ }
+
void postReportExemptedSyncStart(String packageName, int userId) {
mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_START, userId, 0, packageName)
.sendToTarget();
@@ -1393,6 +1452,16 @@
TimeUtils.formatDuration(mAppIdleParoleDurationMillis, pw);
pw.println();
+ pw.print(" mExemptedSyncScheduledNonDozeTimeoutMillis=");
+ TimeUtils.formatDuration(mExemptedSyncScheduledNonDozeTimeoutMillis, pw);
+ pw.println();
+ pw.print(" mExemptedSyncScheduledDozeTimeoutMillis=");
+ TimeUtils.formatDuration(mExemptedSyncScheduledDozeTimeoutMillis, pw);
+ pw.println();
+ pw.print(" mExemptedSyncStartTimeoutMillis=");
+ TimeUtils.formatDuration(mExemptedSyncStartTimeoutMillis, pw);
+ pw.println();
+
pw.println();
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
pw.print(" mAppIdleTempParoled="); pw.print(mAppIdleTempParoled);
@@ -1421,6 +1490,7 @@
private IBatteryStats mBatteryStats;
private PackageManagerInternal mPackageManagerInternal;
private DisplayManager mDisplayManager;
+ private PowerManager mPowerManager;
int mBootPhase;
Injector(Context context, Looper looper) {
@@ -1445,6 +1515,7 @@
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mDisplayManager = (DisplayManager) mContext.getSystemService(
Context.DISPLAY_SERVICE);
+ mPowerManager = mContext.getSystemService(PowerManager.class);
}
mBootPhase = phase;
}
@@ -1524,6 +1595,11 @@
return Global.getString(mContext.getContentResolver(),
Global.APP_IDLE_CONSTANTS);
}
+
+ /** Whether the device is in doze or not. */
+ public boolean isDeviceIdleMode() {
+ return mPowerManager.isDeviceIdleMode();
+ }
}
class AppStandbyHandler extends Handler {
@@ -1587,6 +1663,10 @@
mInjector.elapsedRealtime());
break;
+ case MSG_REPORT_EXEMPTED_SYNC_SCHEDULED:
+ reportExemptedSyncScheduled((String) msg.obj, msg.arg1);
+ break;
+
case MSG_REPORT_EXEMPTED_SYNC_START:
reportExemptedSyncStart((String) msg.obj, msg.arg1);
break;
@@ -1676,7 +1756,12 @@
"system_update_usage_duration";
private static final String KEY_PREDICTION_TIMEOUT = "prediction_timeout";
private static final String KEY_SYNC_ADAPTER_HOLD_DURATION = "sync_adapter_duration";
- private static final String KEY_EXEMPTED_SYNC_HOLD_DURATION = "exempted_sync_duration";
+ private static final String KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION
+ = "exempted_sync_scheduled_nd_duration";
+ private static final String KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION
+ = "exempted_sync_scheduled_d_duration";
+ private static final String KEY_EXEMPTED_SYNC_START_HOLD_DURATION
+ = "exempted_sync_start_duration";
private static final String KEY_SYSTEM_INTERACTION_HOLD_DURATION =
"system_interaction_duration";
private static final String KEY_STABLE_CHARGING_THRESHOLD = "stable_charging_threshold";
@@ -1685,7 +1770,9 @@
public static final long DEFAULT_SYSTEM_UPDATE_TIMEOUT = 2 * ONE_HOUR;
public static final long DEFAULT_SYSTEM_INTERACTION_TIMEOUT = 10 * ONE_MINUTE;
public static final long DEFAULT_SYNC_ADAPTER_TIMEOUT = 10 * ONE_MINUTE;
- public static final long DEFAULT_EXEMPTED_SYNC_TIMEOUT = 10 * ONE_MINUTE;
+ public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT = 10 * ONE_MINUTE;
+ public static final long DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT = 4 * ONE_HOUR;
+ public static final long DEFAULT_EXEMPTED_SYNC_START_TIMEOUT = 10 * ONE_MINUTE;
public static final long DEFAULT_STABLE_CHARGING_THRESHOLD = 10 * ONE_MINUTE;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -1770,9 +1857,22 @@
mSyncAdapterTimeoutMillis = mParser.getDurationMillis
(KEY_SYNC_ADAPTER_HOLD_DURATION,
COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYNC_ADAPTER_TIMEOUT);
- mExemptedSyncAdapterTimeoutMillis = mParser.getDurationMillis
- (KEY_EXEMPTED_SYNC_HOLD_DURATION,
- COMPRESS_TIME ? ONE_MINUTE : DEFAULT_EXEMPTED_SYNC_TIMEOUT);
+
+ mExemptedSyncScheduledNonDozeTimeoutMillis = mParser.getDurationMillis
+ (KEY_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_HOLD_DURATION,
+ COMPRESS_TIME ? (ONE_MINUTE / 2)
+ : DEFAULT_EXEMPTED_SYNC_SCHEDULED_NON_DOZE_TIMEOUT);
+
+ mExemptedSyncScheduledDozeTimeoutMillis = mParser.getDurationMillis
+ (KEY_EXEMPTED_SYNC_SCHEDULED_DOZE_HOLD_DURATION,
+ COMPRESS_TIME ? ONE_MINUTE
+ : DEFAULT_EXEMPTED_SYNC_SCHEDULED_DOZE_TIMEOUT);
+
+ mExemptedSyncStartTimeoutMillis = mParser.getDurationMillis
+ (KEY_EXEMPTED_SYNC_START_HOLD_DURATION,
+ COMPRESS_TIME ? ONE_MINUTE
+ : DEFAULT_EXEMPTED_SYNC_START_TIMEOUT);
+
mSystemInteractionTimeoutMillis = mParser.getDurationMillis
(KEY_SYSTEM_INTERACTION_HOLD_DURATION,
COMPRESS_TIME ? ONE_MINUTE : DEFAULT_SYSTEM_INTERACTION_TIMEOUT);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 71f9bb3..16f8fba 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -900,6 +900,7 @@
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
+ final boolean shellCaller = callingUid == 0 || callingUid == Process.SHELL_UID;
final boolean systemCaller = UserHandle.isCore(callingUid);
final int reason = systemCaller
? UsageStatsManager.REASON_MAIN_FORCED
@@ -918,7 +919,7 @@
+ ")");
}
mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
- SystemClock.elapsedRealtime());
+ SystemClock.elapsedRealtime(), shellCaller);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -985,7 +986,7 @@
throw new IllegalArgumentException("Cannot set your own standby bucket");
}
mAppStandby.setAppStandbyBucket(packageName, userId, bucket, reason,
- elapsedRealtime);
+ elapsedRealtime, shellCaller);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -1304,6 +1305,11 @@
}
@Override
+ public void reportExemptedSyncScheduled(String packageName, int userId) {
+ mAppStandby.postReportExemptedSyncScheduled(packageName, userId);
+ }
+
+ @Override
public void reportExemptedSyncStart(String packageName, int userId) {
mAppStandby.postReportExemptedSyncStart(packageName, userId);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 4334d3a..31381804 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -213,6 +213,17 @@
/**
* Notify the framework that the device is disconnected from the IMS network.
+ * <p>
+ * Note: Prior to calling {@link #onDeregistered(ImsReasonInfo)}, you should ensure that any
+ * changes to {@link android.telephony.ims.feature.ImsFeature} capability availability is sent
+ * to the framework. For example,
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO}
+ * and
+ * {@link android.telephony.ims.feature.MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE}
+ * may be set to unavailable to ensure the framework knows these services are no longer
+ * available due to de-registration. If you do not report capability changes impacted by
+ * de-registration, the framework will not know which features are no longer available as a
+ * result.
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index bcad554..676684c 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -152,9 +152,14 @@
&& (ai.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
Slog.i(TAG, "Update state(" + packageName + "): ENABLED for user "
+ userId);
+ packageManager.setSystemAppInstallState(
+ packageName,
+ true /*installed*/,
+ userId);
packageManager.setApplicationEnabledSetting(
packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -170,9 +175,14 @@
if (associatedApp.enabledSetting ==
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
|| associatedApp.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
+ || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
Slog.i(TAG, "Update associated state(" + associatedApp.packageName
+ "): ENABLED for user " + userId);
+ packageManager.setSystemAppInstallState(
+ associatedApp.packageName,
+ true /*installed*/,
+ userId);
packageManager.setApplicationEnabledSetting(
associatedApp.packageName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
@@ -190,15 +200,14 @@
// updated we shouldn't touch it.
if (!ai.isUpdatedSystemApp()
&& ai.enabledSetting ==
- PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
+ && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
Slog.i(TAG, "Update state(" + packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setApplicationEnabledSetting(
+ packageManager.setSystemAppInstallState(
packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
- 0,
- userId,
- callingPackage);
+ false /*installed*/,
+ userId);
}
// Also disable any associated apps for this carrier app if this is the first
@@ -213,13 +222,10 @@
Slog.i(TAG,
"Update associated state(" + associatedApp.packageName
+ "): DISABLED_UNTIL_USED for user " + userId);
- packageManager.setApplicationEnabledSetting(
+ packageManager.setSystemAppInstallState(
associatedApp.packageName,
- PackageManager
- .COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
- 0,
- userId,
- callingPackage);
+ false /*installed*/,
+ userId);
}
}
}
@@ -357,7 +363,8 @@
String packageName) {
try {
ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
- PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS, userId);
+ PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+ | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, userId);
if (ai != null && ai.isSystemApp()) {
return ai;
}
diff --git a/tests/ActivityTests/Android.mk b/tests/ActivityTests/Android.mk
index 61dbcc3..4c68c8b 100644
--- a/tests/ActivityTests/Android.mk
+++ b/tests/ActivityTests/Android.mk
@@ -9,9 +9,10 @@
LOCAL_MODULE_TAGS := tests
LOCAL_CERTIFICATE := platform
-# Disable AAPT2 to fix:
+LOCAL_USE_AAPT2 := true
+# Disable AAPT2 manifest checks to fix:
# frameworks/base/tests/ActivityTests/AndroidManifest.xml:42: error: unexpected element <preferred> found in <manifest><application><activity>.
-# TODO(b/79755007): Re-enable AAPT2 when it supports the missing features.
-LOCAL_USE_AAPT2 := false
+# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
+LOCAL_AAPT_FLAGS += --warn-manifest-validation
include $(BUILD_PACKAGE)
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 6ce66f0..4a6fe49 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -184,7 +184,8 @@
if (null != launchDirectory && !launchDirectory.isEmpty()) {
launchRootDir = new File(launchDirectory);
if (!launchRootDir.exists() && !launchRootDir.mkdirs()) {
- throw new IOException("Unable to create the destination directory");
+ throw new IOException("Unable to create the destination directory "
+ + launchRootDir + ". Try disabling selinux.");
}
}
@@ -192,7 +193,8 @@
File launchSubDir = new File(launchRootDir, LAUNCH_SUB_DIRECTORY);
if (!launchSubDir.exists() && !launchSubDir.mkdirs()) {
- throw new IOException("Unable to create the lauch file sub directory");
+ throw new IOException("Unable to create the lauch file sub directory "
+ + launchSubDir + ". Try disabling selinux.");
}
File file = new File(launchSubDir, LAUNCH_FILE);
FileOutputStream outputStream = new FileOutputStream(file);
@@ -769,6 +771,8 @@
BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(stream))) {
String cmd = String.format(SIMPLEPERF_APP_CMD, packageName, launchCmd);
+ // In the file, we need to escape any "$".
+ cmd = cmd.replace("$", "\\$");
writer.write(cmd);
}
launchCmd = launchFile.getAbsolutePath();
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index ed9cbab..0248e97 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -77,7 +77,7 @@
@SmallTest
public class ApfTest {
private static final int TIMEOUT_MS = 500;
- private final static int MIN_APF_VERSION = 2;
+ private static final int MIN_APF_VERSION = 2;
@Mock IpConnectivityLog mLog;
@Mock Context mContext;
@@ -90,20 +90,30 @@
}
// Expected return codes from APF interpreter.
- private final static int PASS = 1;
- private final static int DROP = 0;
+ private static final int PASS = 1;
+ private static final int DROP = 0;
// Interpreter will just accept packets without link layer headers, so pad fake packet to at
// least the minimum packet size.
- private final static int MIN_PKT_SIZE = 15;
+ private static final int MIN_PKT_SIZE = 15;
private static final ApfCapabilities MOCK_APF_CAPABILITIES =
new ApfCapabilities(2, 1700, ARPHRD_ETHER);
- private final static boolean DROP_MULTICAST = true;
- private final static boolean ALLOW_MULTICAST = false;
+ private static final boolean DROP_MULTICAST = true;
+ private static final boolean ALLOW_MULTICAST = false;
- private final static boolean DROP_802_3_FRAMES = true;
- private final static boolean ALLOW_802_3_FRAMES = false;
+ private static final boolean DROP_802_3_FRAMES = true;
+ private static final boolean ALLOW_802_3_FRAMES = false;
+
+ // Constants for opcode encoding
+ private static final byte LI_OP = (byte)(13 << 3);
+ private static final byte LDDW_OP = (byte)(22 << 3);
+ private static final byte STDW_OP = (byte)(23 << 3);
+ private static final byte SIZE0 = (byte)(0 << 1);
+ private static final byte SIZE8 = (byte)(1 << 1);
+ private static final byte SIZE16 = (byte)(2 << 1);
+ private static final byte SIZE32 = (byte)(3 << 1);
+ private static final byte R1 = 1;
private static ApfConfiguration getDefaultConfig() {
ApfFilter.ApfConfiguration config = new ApfConfiguration();
@@ -636,29 +646,28 @@
*/
@Test
public void testImmediateEncoding() throws IllegalInstructionException {
- final int LI_OPCODE = 13 << 3;
ApfGenerator gen;
// 0-byte immediate: li R0, 0
- gen = new ApfGenerator(3);
+ gen = new ApfGenerator(4);
gen.addLoadImmediate(Register.R0, 0);
- assertProgramEquals(new byte[]{LI_OPCODE | (0 << 1)}, gen.generate());
+ assertProgramEquals(new byte[]{LI_OP | SIZE0}, gen.generate());
// 1-byte immediate: li R0, 42
- gen = new ApfGenerator(3);
+ gen = new ApfGenerator(4);
gen.addLoadImmediate(Register.R0, 42);
- assertProgramEquals(new byte[]{LI_OPCODE | (1 << 1), 42}, gen.generate());
+ assertProgramEquals(new byte[]{LI_OP | SIZE8, 42}, gen.generate());
// 2-byte immediate: li R1, 0x1234
- gen = new ApfGenerator(3);
+ gen = new ApfGenerator(4);
gen.addLoadImmediate(Register.R1, 0x1234);
- assertProgramEquals(new byte[]{LI_OPCODE | (2 << 1) | 1 , 0x12, 0x34}, gen.generate());
+ assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, 0x12, 0x34}, gen.generate());
// 4-byte immediate: li R0, 0x12345678
gen = new ApfGenerator(3);
gen.addLoadImmediate(Register.R0, 0x12345678);
assertProgramEquals(
- new byte[]{LI_OPCODE | (3 << 1), 0x12, 0x34, 0x56, 0x78},
+ new byte[]{LI_OP | SIZE32, 0x12, 0x34, 0x56, 0x78},
gen.generate());
}
@@ -667,28 +676,61 @@
*/
@Test
public void testNegativeImmediateEncoding() throws IllegalInstructionException {
- final int LI_OPCODE = 13 << 3;
ApfGenerator gen;
// 1-byte negative immediate: li R0, -42
gen = new ApfGenerator(3);
gen.addLoadImmediate(Register.R0, -42);
- assertProgramEquals(new byte[]{LI_OPCODE | (1 << 1), -42}, gen.generate());
+ assertProgramEquals(new byte[]{LI_OP | SIZE8, -42}, gen.generate());
- // 2-byte negative immediate: li R1, -0x1234
+ // 2-byte negative immediate: li R1, -0x1122
gen = new ApfGenerator(3);
gen.addLoadImmediate(Register.R1, -0x1122);
- assertProgramEquals(new byte[]{LI_OPCODE | (2 << 1) | 1, (byte)0xEE, (byte)0xDE},
+ assertProgramEquals(new byte[]{LI_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
gen.generate());
// 4-byte negative immediate: li R0, -0x11223344
gen = new ApfGenerator(3);
gen.addLoadImmediate(Register.R0, -0x11223344);
assertProgramEquals(
- new byte[]{LI_OPCODE | (3 << 1), (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
+ new byte[]{LI_OP | SIZE32, (byte)0xEE, (byte)0xDD, (byte)0xCC, (byte)0xBC},
gen.generate());
}
+ /**
+ * Test that the generator correctly emits positive and negative immediates for LDDW/STDW.
+ */
+ @Test
+ public void testLoadStoreDataEncoding() throws IllegalInstructionException {
+ ApfGenerator gen;
+
+ // Load data with no offset: lddw R0, [0 + r1]
+ gen = new ApfGenerator(3);
+ gen.addLoadData(Register.R0, 0);
+ assertProgramEquals(new byte[]{LDDW_OP | SIZE0}, gen.generate());
+
+ // Store data with 8bit negative offset: lddw r0, [-42 + r1]
+ gen = new ApfGenerator(3);
+ gen.addStoreData(Register.R0, -42);
+ assertProgramEquals(new byte[]{STDW_OP | SIZE8, -42}, gen.generate());
+
+ // Store data to R1 with 16bit negative offset: stdw r1, [-0x1122 + r0]
+ gen = new ApfGenerator(3);
+ gen.addStoreData(Register.R1, -0x1122);
+ assertProgramEquals(new byte[]{STDW_OP | SIZE16 | R1, (byte)0xEE, (byte)0xDE},
+ gen.generate());
+
+ // Load data to R1 with 32bit negative offset: lddw r1, [0xDEADBEEF + r0]
+ gen = new ApfGenerator(3);
+ gen.addLoadData(Register.R1, 0xDEADBEEF);
+ assertProgramEquals(
+ new byte[]{LDDW_OP | SIZE32 | R1, (byte)0xDE, (byte)0xAD, (byte)0xBE, (byte)0xEF},
+ gen.generate());
+ }
+
+ /**
+ * Test that the interpreter correctly executes STDW with a negative 8bit offset
+ */
@Test
public void testApfDataWrite() throws IllegalInstructionException, Exception {
byte[] packet = new byte[MIN_PKT_SIZE];
@@ -712,12 +754,15 @@
assertDataMemoryContents(PASS, gen.generate(), packet, data, expected_data);
}
+ /**
+ * Test that the interpreter correctly executes LDDW with a negative 16bit offset
+ */
@Test
public void testApfDataRead() throws IllegalInstructionException, Exception {
// Program that DROPs if address 10 (-6) contains 0x87654321.
ApfGenerator gen = new ApfGenerator(3);
- gen.addLoadImmediate(Register.R1, 10);
- gen.addLoadData(Register.R0, -16); // 10 + -16 = -6 (offset +10 with data_len=16)
+ gen.addLoadImmediate(Register.R1, 1000);
+ gen.addLoadData(Register.R0, -1006); // 1000 + -1006 = -6 (offset +10 with data_len=16)
gen.addJumpIfR0Equals(0x87654321, gen.DROP_LABEL);
byte[] program = gen.generate();
byte[] packet = new byte[MIN_PKT_SIZE];
@@ -737,6 +782,11 @@
assertDataMemoryContents(DROP, program, packet, data, expected_data);
}
+ /**
+ * Test that the interpreter correctly executes LDDW followed by a STDW.
+ * To cover a few more edge cases, LDDW has a 0bit offset, while STDW has a positive 8bit
+ * offset.
+ */
@Test
public void testApfDataReadModifyWrite() throws IllegalInstructionException, Exception {
ApfGenerator gen = new ApfGenerator(3);
@@ -844,7 +894,7 @@
}
private static class TestApfFilter extends ApfFilter {
- public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
+ public static final byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6};
private FileDescriptor mWriteSocket;
private final long mFixedTimeMs = SystemClock.elapsedRealtime();
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 280e4c2..f89f303 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -227,9 +227,6 @@
@After
public void tearDown() throws Exception {
- // Registered by NetworkStatsService's constructor.
- LocalServices.removeServiceForTest(NetworkStatsManagerInternal.class);
-
IoUtils.deleteContents(mStatsDir);
mServiceContext = null;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 74edf6e..c3fb728 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -2135,6 +2135,12 @@
.OptionalFlag("--version-name",
"Version name to inject into the AndroidManifest.xml if none is present.",
&options.manifest_fixer_options.version_name_default)
+ .OptionalSwitch("--replace-version",
+ "If --version-code and/or --version-name are specified, these\n"
+ "values will replace any value already in the manifest. By\n"
+ "default, nothing is changed if the manifest already defines\n"
+ "these attributes.",
+ &options.manifest_fixer_options.replace_version)
.OptionalFlag("--compile-sdk-version-code",
"Version code (integer) to inject into the AndroidManifest.xml if none is\n"
"present.",
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index bfff148..ee4e702 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -261,6 +261,9 @@
manifest_action.Action(FixCoreAppAttribute);
manifest_action.Action([&](xml::Element* el) -> bool {
if (options_.version_name_default) {
+ if (options_.replace_version) {
+ el->RemoveAttribute(xml::kSchemaAndroid, "versionName");
+ }
if (el->FindAttribute(xml::kSchemaAndroid, "versionName") == nullptr) {
el->attributes.push_back(
xml::Attribute{xml::kSchemaAndroid, "versionName",
@@ -269,6 +272,9 @@
}
if (options_.version_code_default) {
+ if (options_.replace_version) {
+ el->RemoveAttribute(xml::kSchemaAndroid, "versionCode");
+ }
if (el->FindAttribute(xml::kSchemaAndroid, "versionCode") == nullptr) {
el->attributes.push_back(
xml::Attribute{xml::kSchemaAndroid, "versionCode",
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index 7d6fad2..98d06fd 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -44,10 +44,12 @@
// <instrumentation>.
Maybe<std::string> rename_instrumentation_target_package;
- // The version name to set if 'android:versionName' is not defined in <manifest>.
+ // The version name to set if 'android:versionName' is not defined in <manifest> or if
+ // replace_version is set.
Maybe<std::string> version_name_default;
- // The version code to set if 'android:versionCode' is not defined in <manifest>.
+ // The version code to set if 'android:versionCode' is not defined in <manifest> or if
+ // replace_version is set.
Maybe<std::string> version_code_default;
// The version of the framework being compiled against to set for 'android:compileSdkVersion' in
@@ -65,6 +67,9 @@
// Whether to inject the android:debuggable="true" flag into the manifest
bool debug_mode = false;
+
+ // Whether to replace the manifest version with the the command line version
+ bool replace_version = false;
};
// Verifies that the manifest is correctly formed and inserts defaults where specified with
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 5f406e8..5bc004d 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -349,6 +349,136 @@
EXPECT_THAT(attr->value, StrEq("0x10000000"));
}
+TEST_F(ManifestFixerTest, DontUseDefaultVersionNameAndCode) {
+ManifestFixerOptions options;
+options.version_name_default = std::string("Beta");
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionNameAndCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_name_default = std::string("Beta");
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Beta"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionName) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_name_default = std::string("Beta");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Beta"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
+TEST_F(ManifestFixerTest, ReplaceVersionCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+options.version_code_default = std::string("0x10000000");
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x10000000"));
+}
+
+TEST_F(ManifestFixerTest, DontReplaceVersionNameOrCode) {
+ManifestFixerOptions options;
+options.replace_version = true;
+
+std::unique_ptr<xml::XmlResource> doc = VerifyWithOptions(R"EOF(
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android"
+ android:versionCode="0x20000000"
+ android:versionName="Alpha" />)EOF",
+ options);
+ASSERT_THAT(doc, NotNull());
+
+xml::Element* manifest_el = doc->root.get();
+ASSERT_THAT(manifest_el, NotNull());
+
+xml::Attribute* attr =
+ manifest_el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("Alpha"));
+
+attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ASSERT_THAT(attr, NotNull());
+EXPECT_THAT(attr->value, StrEq("0x20000000"));
+}
+
TEST_F(ManifestFixerTest, EnsureManifestAttributesAreTyped) {
EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"hello\" />"), IsNull());
EXPECT_THAT(Verify("<manifest package=\"android\" coreApp=\"1dp\" />"), IsNull());
diff --git a/tools/aapt2/link/NoDefaultResourceRemover.cpp b/tools/aapt2/link/NoDefaultResourceRemover.cpp
index cfb4b26..5173b85 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover.cpp
@@ -22,17 +22,7 @@
namespace aapt {
-static bool IsDefaultConfigRequired(const ConfigDescription& config) {
- // We don't want to be overzealous with resource removal, so have strict requirements.
- // If a resource defines a value for a locale-only configuration, the default configuration is
- // required.
- if (ConfigDescription::DefaultConfig().diff(config) == ConfigDescription::CONFIG_LOCALE) {
- return true;
- }
- return false;
-}
-
-static bool KeepResource(const std::unique_ptr<ResourceEntry>& entry) {
+static bool KeepResource(const std::unique_ptr<ResourceEntry>& entry, int minSdk) {
if (entry->visibility.level == Visibility::Level::kPublic) {
// Removing a public API without the developer knowing is bad, so just leave this here for now.
return true;
@@ -44,22 +34,44 @@
}
// There is no default value defined, check if removal is required.
+ bool defaultRequired = false;
for (const auto& config_value : entry->values) {
- if (IsDefaultConfigRequired(config_value->config)) {
- return false;
+ const int config = ConfigDescription::DefaultConfig().diff(config_value->config);
+ // If a resource defines a value for a locale-only configuration, the default configuration is
+ // required.
+ if (config == ConfigDescription::CONFIG_LOCALE) {
+ defaultRequired = true;
+ }
+ // If a resource defines a version-only config, the config value can be used as a default if
+ // the version is at most the minimum sdk version
+ else if (config == ConfigDescription::CONFIG_VERSION
+ && config_value->config.sdkVersion <= minSdk) {
+ return true;
+ }
+ // If a resource defines a value for a density only configuration, then that value could be used
+ // as a default and the entry should not be removed
+ else if (config == ConfigDescription::CONFIG_DENSITY
+ || (config == (ConfigDescription::CONFIG_DENSITY | ConfigDescription::CONFIG_VERSION)
+ && config_value->config.sdkVersion <= minSdk)) {
+ return true;
}
}
- return true;
+
+ return !defaultRequired;
}
bool NoDefaultResourceRemover::Consume(IAaptContext* context, ResourceTable* table) {
- const ConfigDescription default_config = ConfigDescription::DefaultConfig();
for (auto& pkg : table->packages) {
for (auto& type : pkg->types) {
+ // Gather the entries without defaults that must be removed
+ const int minSdk = context->GetMinSdkVersion();
const auto end_iter = type->entries.end();
- const auto new_end_iter =
- std::stable_partition(type->entries.begin(), end_iter, KeepResource);
- for (auto iter = new_end_iter; iter != end_iter; ++iter) {
+ const auto remove_iter = std::stable_partition(type->entries.begin(), end_iter,
+ [&minSdk](const std::unique_ptr<ResourceEntry>& entry) -> bool {
+ return KeepResource(entry, minSdk);
+ });
+
+ for (auto iter = remove_iter; iter != end_iter; ++iter) {
const ResourceName name(pkg->name, type->type, (*iter)->name);
IDiagnostics* diag = context->GetDiagnostics();
diag->Warn(DiagMessage() << "removing resource " << name
@@ -74,7 +86,7 @@
}
}
- type->entries.erase(new_end_iter, type->entries.end());
+ type->entries.erase(remove_iter, end_iter);
}
}
return true;
diff --git a/tools/aapt2/link/NoDefaultResourceRemover_test.cpp b/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
index 943709a..d129c9a 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover_test.cpp
@@ -46,4 +46,64 @@
EXPECT_TRUE(table->FindResource(test::ParseNameOrDie("android:string/baz")));
}
+TEST(NoDefaultResourceRemoverTest, KeepEntryWithLocalesAndDensities) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(26).Build();
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .SetPackageId("android", 0x01)
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("mdpi")) // v4
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("fr-rFR"))
+ .AddSimple("android:drawable/keep2", test::ParseConfigOrDie("fr-rFR"))
+ .AddSimple("android:drawable/keep2", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/keep2", test::ParseConfigOrDie("xxxhdpi")) // v4
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("fr-rFR"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("w600dp-xhdpi")) // v13
+ .Build();
+
+ NoDefaultResourceRemover remover;
+ ASSERT_TRUE(remover.Consume(context.get(), table.get()));
+
+ EXPECT_TRUE(table->FindResource(test::ParseNameOrDie("android:drawable/keep1")));
+ EXPECT_TRUE(table->FindResource(test::ParseNameOrDie("android:drawable/keep2")));
+ EXPECT_FALSE(table->FindResource(test::ParseNameOrDie("android:drawable/remove1")));
+}
+
+TEST(NoDefaultResourceRemoverTest, RemoveEntryWithLocalesAndDensitiesLowVersion) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(3).Build();
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .SetPackageId("android", 0x01)
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("mdpi")) // v4
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("fr-rFR"))
+ .Build();
+
+ NoDefaultResourceRemover remover;
+ ASSERT_TRUE(remover.Consume(context.get(), table.get()));
+
+ EXPECT_FALSE(table->FindResource(test::ParseNameOrDie("android:drawable/remove1")));
+}
+
+TEST(NoDefaultResourceRemoverTest, KeepEntryWithVersion) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().SetMinSdkVersion(8).Build();
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .SetPackageId("android", 0x01)
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("v8"))
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/keep1", test::ParseConfigOrDie("fr-rFR"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("v9"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("en-rGB"))
+ .AddSimple("android:drawable/remove1", test::ParseConfigOrDie("fr-rFR"))
+ .Build();
+
+ NoDefaultResourceRemover remover;
+ ASSERT_TRUE(remover.Consume(context.get(), table.get()));
+
+ EXPECT_TRUE(table->FindResource(test::ParseNameOrDie("android:drawable/keep1")));
+ EXPECT_FALSE(table->FindResource(test::ParseNameOrDie("android:drawable/remove1")));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp
index b6cd086..acd07c2 100644
--- a/tools/aapt2/xml/XmlDom.cpp
+++ b/tools/aapt2/xml/XmlDom.cpp
@@ -423,6 +423,15 @@
return nullptr;
}
+void Element::RemoveAttribute(const StringPiece& ns, const StringPiece& name) {
+ auto new_attr_end = std::remove_if(attributes.begin(), attributes.end(),
+ [&](const Attribute& attr) -> bool {
+ return ns == attr.namespace_uri && name == attr.name;
+ });
+
+ attributes.erase(new_attr_end, attributes.end());
+}
+
Attribute* Element::FindOrCreateAttribute(const StringPiece& ns, const StringPiece& name) {
Attribute* attr = FindAttribute(ns, name);
if (attr == nullptr) {
diff --git a/tools/aapt2/xml/XmlDom.h b/tools/aapt2/xml/XmlDom.h
index 8f382961..a5b2d10 100644
--- a/tools/aapt2/xml/XmlDom.h
+++ b/tools/aapt2/xml/XmlDom.h
@@ -102,6 +102,8 @@
const android::StringPiece& name) const;
Attribute* FindOrCreateAttribute(const android::StringPiece& ns,
const android::StringPiece& name);
+ void RemoveAttribute(const android::StringPiece& ns,
+ const android::StringPiece& name);
Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name);
const Element* FindChild(const android::StringPiece& ns, const android::StringPiece& name) const;