Merge "AudioService: fix lock ordering between BtHelper and AudioDeviceBroker"
diff --git a/api/removed.txt b/api/removed.txt
index 9f4b041..262ffec 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -344,7 +344,7 @@
public final class PowerManager {
method public void goToSleep(long);
method @Deprecated public void userActivity(long, boolean);
- method public void wakeUp(long);
+ method @Deprecated public void wakeUp(long);
}
public class RecoverySystem {
diff --git a/api/system-current.txt b/api/system-current.txt
index 8d7ec26..376aad0 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1072,16 +1072,17 @@
public final class RoleManager {
method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void addOnRoleHoldersChangedListenerAsUser(@NonNull java.util.concurrent.Executor, @NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean addRoleHolderFromController(@NonNull String, @NonNull String);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @NonNull @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public java.util.List<java.lang.String> getHeldRolesFromController(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHolders(@NonNull String);
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.OBSERVE_ROLE_HOLDERS) public void removeOnRoleHoldersChangedListenerAsUser(@NonNull android.app.role.OnRoleHoldersChangedListener, @NonNull android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_ROLE_HOLDERS) public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List<java.lang.String>);
+ field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1
field public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
}
@@ -5001,10 +5002,11 @@
method public boolean getEnableAdjustBrightness();
method public boolean getEnableDataSaver();
method public boolean getEnableFirewall();
+ method public boolean getEnableNightMode();
method public boolean getEnableQuickDoze();
method public boolean getForceAllAppsStandby();
method public boolean getForceBackgroundCheck();
- method public int getGpsMode();
+ method public int getLocationMode();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.os.BatterySaverPolicyConfig> CREATOR;
}
@@ -5026,10 +5028,11 @@
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableAdjustBrightness(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableDataSaver(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableFirewall(boolean);
+ method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableNightMode(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setEnableQuickDoze(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceAllAppsStandby(boolean);
method @NonNull public android.os.BatterySaverPolicyConfig.Builder setForceBackgroundCheck(boolean);
- method @NonNull public android.os.BatterySaverPolicyConfig.Builder setGpsMode(int);
+ method @NonNull public android.os.BatterySaverPolicyConfig.Builder setLocationMode(int);
}
public class Binder implements android.os.IBinder {
@@ -6037,11 +6040,11 @@
public abstract class RoleControllerService extends android.app.Service {
ctor public RoleControllerService();
- method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onAddRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
method @Nullable public final android.os.IBinder onBind(@Nullable android.content.Intent);
- method public abstract void onClearRoleHolders(@NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onClearRoleHolders(@NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
method public abstract void onGrantDefaultRoles(@NonNull android.app.role.RoleManagerCallback);
- method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, @NonNull android.app.role.RoleManagerCallback);
+ method public abstract void onRemoveRoleHolder(@NonNull String, @NonNull String, int, @NonNull android.app.role.RoleManagerCallback);
method public abstract void onSmsKillSwitchToggled(boolean);
field public static final String SERVICE_INTERFACE = "android.rolecontrollerservice.RoleControllerService";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index f71789d..5b51d6e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -429,11 +429,11 @@
package android.app.role {
public final class RoleManager {
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void addRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void clearRoleHoldersAsUser(@NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHolders(@NonNull String);
method @NonNull @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public java.util.List<java.lang.String> getRoleHoldersAsUser(@NonNull String, @NonNull android.os.UserHandle);
- method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
+ method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
field public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
}
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 5dcb392b..46917e4 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -252,10 +252,12 @@
status_t BootAnimation::readyToRun() {
mAssets.addDefaultAssets();
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
+ mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
+ if (mDisplayToken == nullptr)
+ return -1;
+
DisplayInfo dinfo;
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &dinfo);
+ status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
if (status)
return -1;
@@ -1014,16 +1016,13 @@
// At the end of the animation, we switch to the viewport that DisplayManager will apply
// later. This changes the coordinate system, and means we must move the surface up by
// the inset amount.
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
- ISurfaceComposer::eDisplayIdMain));
-
Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset);
Rect displayRect(0, mTargetInset, mWidth, mHeight);
SurfaceComposerClient::Transaction t;
t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
.setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
- t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect);
+ t.setDisplayProjection(mDisplayToken, 0 /* orientation */, layerStackRect, displayRect);
t.apply();
mTargetInset = mCurrentInset = 0;
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 04d4f9a..19616cb 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -171,6 +171,7 @@
EGLDisplay mDisplay;
EGLDisplay mContext;
EGLDisplay mSurface;
+ sp<IBinder> mDisplayToken;
sp<SurfaceControl> mFlingerSurfaceControl;
sp<Surface> mFlingerSurface;
bool mClockEnabled;
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index 3d74f8b..c497667 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -46,23 +46,22 @@
using namespace android;
-static uint32_t DEFAULT_DISPLAY_ID = ISurfaceComposer::eDisplayIdMain;
-
#define COLORSPACE_UNKNOWN 0
#define COLORSPACE_SRGB 1
#define COLORSPACE_DISPLAY_P3 2
-static void usage(const char* pname)
+static void usage(const char* pname, PhysicalDisplayId displayId)
{
fprintf(stderr,
"usage: %s [-hp] [-d display-id] [FILENAME]\n"
" -h: this message\n"
" -p: save the file as a png.\n"
- " -d: specify the display id to capture, default %d.\n"
+ " -d: specify the physical display ID to capture (default: %"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ")\n"
+ " see \"dumpsys SurfaceFlinger --display-id\" for valid display IDs.\n"
"If FILENAME ends with .png it will be saved as a png.\n"
"If FILENAME is not given, the results will be printed to stdout.\n",
- pname, DEFAULT_DISPLAY_ID
- );
+ pname, displayId);
}
static SkColorType flinger2skia(PixelFormat f)
@@ -127,9 +126,14 @@
int main(int argc, char** argv)
{
+ std::optional<PhysicalDisplayId> displayId = SurfaceComposerClient::getInternalDisplayId();
+ if (!displayId) {
+ fprintf(stderr, "Failed to get token for internal display\n");
+ return 1;
+ }
+
const char* pname = argv[0];
bool png = false;
- int32_t displayId = DEFAULT_DISPLAY_ID;
int c;
while ((c = getopt(argc, argv, "phd:")) != -1) {
switch (c) {
@@ -137,11 +141,11 @@
png = true;
break;
case 'd':
- displayId = atoi(optarg);
+ displayId = atoll(optarg);
break;
case '?':
case 'h':
- usage(pname);
+ usage(pname, *displayId);
return 1;
}
}
@@ -166,7 +170,7 @@
}
if (fd == -1) {
- usage(pname);
+ usage(pname, *displayId);
return 1;
}
@@ -192,9 +196,10 @@
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
- if (display == NULL) {
- fprintf(stderr, "Unable to get handle for display %d\n", displayId);
+ const sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
+ if (display == nullptr) {
+ fprintf(stderr, "Failed to get token for invalid display %"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT "\n", *displayId);
return 1;
}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index ca10482..d6f045e 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -50,6 +50,7 @@
srcs: [
":statsd_aidl",
+ "src/active_config_list.proto",
"src/statsd_config.proto",
"src/FieldValue.cpp",
"src/hash.cpp",
@@ -214,7 +215,7 @@
"tests/anomaly/AnomalyTracker_test.cpp",
"tests/ConfigManager_test.cpp",
"tests/external/puller_util_test.cpp",
- "tests/external/StatsPuller_test.cpp",
+ "tests/external/StatsPuller_test.cpp",
"tests/indexed_priority_queue_test.cpp",
"tests/LogEntryMatcher_test.cpp",
"tests/LogEvent_test.cpp",
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 69cb264..250f5bf 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -14,18 +14,19 @@
* limitations under the License.
*/
-#define DEBUG false // STOPSHIP if true
+#define DEBUG false // STOPSHIP if true
#include "Log.h"
#include "statslog.h"
#include <android-base/file.h>
#include <dirent.h>
+#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
#include "StatsLogProcessor.h"
-#include "stats_log_util.h"
#include "android-base/stringprintf.h"
+#include "external/StatsPullerManager.h"
#include "guardrail/StatsdStats.h"
#include "metrics/CountMetricProducer.h"
-#include "external/StatsPullerManager.h"
+#include "stats_log_util.h"
#include "stats_util.h"
#include "storage/StorageManager.h"
@@ -67,9 +68,17 @@
const int FIELD_ID_DUMP_REPORT_REASON = 8;
const int FIELD_ID_STRINGS = 9;
+const int FIELD_ID_ACTIVE_CONFIG_LIST = 1;
+const int FIELD_ID_CONFIG_ID = 1;
+const int FIELD_ID_CONFIG_UID = 2;
+const int FIELD_ID_ACTIVE_METRIC = 3;
+const int FIELD_ID_METRIC_ID = 1;
+const int FIELD_ID_TIME_TO_LIVE_NANOS = 2;
+
#define NS_PER_HOUR 3600 * NS_PER_SEC
#define STATS_DATA_DIR "/data/misc/stats-data"
+#define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric"
// Cool down period for writing data to disk to avoid overwriting files.
#define WRITE_DATA_COOL_DOWN_SEC 5
@@ -507,6 +516,70 @@
mOnDiskDataConfigs.insert(key);
}
+void StatsLogProcessor::WriteMetricsActivationToDisk(int64_t currentTimeNs) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ ProtoOutputStream proto;
+
+ for (const auto& pair : mMetricsManagers) {
+ uint64_t activeConfigListToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_ACTIVE_CONFIG_LIST);
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_ID, (long long)pair.first.GetId());
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_UID, pair.first.GetUid());
+
+ vector<const MetricProducer*> acrtiveMetrics;
+ pair.second->getActiveMetrics(acrtiveMetrics);
+ for (const MetricProducer* metric : acrtiveMetrics) {
+ if (metric->isActive()) {
+ uint64_t metricToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
+ FIELD_ID_ACTIVE_METRIC);
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_METRIC_ID,
+ (long long)metric->getMetricId());
+ proto.write(FIELD_TYPE_INT64 | FIELD_ID_TIME_TO_LIVE_NANOS,
+ (long long)metric->getRemainingTtlNs(currentTimeNs));
+ proto.end(metricToken);
+ }
+ }
+ proto.end(activeConfigListToken);
+ }
+
+ string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
+ StorageManager::deleteFile(file_name.c_str());
+ android::base::unique_fd fd(
+ open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR));
+ if (fd == -1) {
+ ALOGE("Attempt to write %s but failed", file_name.c_str());
+ return;
+ }
+ proto.flush(fd.get());
+}
+
+void StatsLogProcessor::LoadMetricsActivationFromDisk() {
+ string file_name = StringPrintf("%s/active_metrics", STATS_ACTIVE_METRIC_DIR);
+ int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
+ if (fd != -1) {
+ string content;
+ if (android::base::ReadFdToString(fd, &content)) {
+ ActiveConfigList activeConfigList;
+ if (activeConfigList.ParseFromString(content)) {
+ for (int i = 0; i < activeConfigList.active_config_size(); i++) {
+ const auto& config = activeConfigList.active_config(i);
+ ConfigKey key(config.uid(), config.config_id());
+ auto it = mMetricsManagers.find(key);
+ if (it == mMetricsManagers.end()) {
+ ALOGE("No config found for config %s", key.ToString().c_str());
+ continue;
+ }
+ VLOG("Setting active config %s", key.ToString().c_str());
+ it->second->setActiveMetrics(config, mTimeBaseNs);
+ }
+ }
+ VLOG("Successfully loaded %d active configs.", activeConfigList.active_config_size());
+ }
+ close(fd);
+ }
+ StorageManager::deleteFile(file_name.c_str());
+}
+
void StatsLogProcessor::WriteDataToDiskLocked(const DumpReportReason dumpReportReason) {
const int64_t timeNs = getElapsedRealtimeNs();
// Do not write to disk if we already have in the last few seconds.
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index a5ce9b6..77d9a2f 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -80,6 +80,12 @@
/* Flushes data to disk. Data on memory will be gone after written to disk. */
void WriteDataToDisk(const DumpReportReason dumpReportReason);
+ /* Persist metric activation status onto disk. */
+ void WriteMetricsActivationToDisk(int64_t currentTimeNs);
+
+ /* Load metric activation status from disk. */
+ void LoadMetricsActivationFromDisk();
+
// Reset all configs.
void resetConfigs();
@@ -188,6 +194,8 @@
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitByteSize);
FRIEND_TEST(StatsLogProcessorTest, TestRateLimitBroadcast);
FRIEND_TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge);
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
+
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index b26c713..86bf3ec 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -161,7 +161,8 @@
mConfigManager = new ConfigManager();
mProcessor = new StatsLogProcessor(
mUidMap, mPullerManager, mAnomalyAlarmMonitor, mPeriodicAlarmMonitor,
- getElapsedRealtimeNs(), [this](const ConfigKey& key) {
+ getElapsedRealtimeNs(),
+ [this](const ConfigKey& key) {
sp<IStatsCompanionService> sc = getStatsCompanionService();
auto receiver = mConfigManager->GetConfigReceiver(key);
if (sc == nullptr) {
@@ -867,6 +868,7 @@
ENFORCE_UID(AID_SYSTEM);
VLOG("StatsService::informDeviceShutdown");
mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN);
+ mProcessor->WriteMetricsActivationToDisk(getElapsedRealtimeNs());
return Status::ok();
}
@@ -901,6 +903,7 @@
void StatsService::Startup() {
mConfigManager->Startup();
+ mProcessor->LoadMetricsActivationFromDisk();
}
void StatsService::Terminate() {
diff --git a/cmds/statsd/src/active_config_list.proto b/cmds/statsd/src/active_config_list.proto
new file mode 100644
index 0000000..0e9ee03
--- /dev/null
+++ b/cmds/statsd/src/active_config_list.proto
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+syntax = "proto2";
+
+package android.os.statsd;
+option java_package = "com.android.os";
+option java_multiple_files = true;
+option java_outer_classname = "ActiveConfigProto";
+
+message ActiveMetric {
+ // metric id
+ optional int64 metric_id = 1;
+ // Remaining time to live in nano seconds. -1 for infinity.
+ optional int64 time_to_live_nanos = 2;
+}
+
+message ActiveConfig {
+ // config id
+ optional int64 config_id = 1;
+ // config uid
+ optional int32 uid = 2;
+ // metrics
+ repeated ActiveMetric active_metric = 3;
+}
+
+// all configs and their metrics on device.
+message ActiveConfigList {
+ repeated ActiveConfig active_config = 1;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index fc3aa91..07aced6 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -239,6 +239,7 @@
PermissionGrantRequestResultReported permission_grant_request_result_reported = 170;
BluetoothSocketConnectionStateChanged bluetooth_socket_connection_state_changed = 171;
DeviceIdentifierAccessDenied device_identifier_access_denied = 172;
+ BubbleDeveloperErrorReported bubble_developer_error_reported = 173;
}
// Pulled events will start at field 10000.
@@ -5344,6 +5345,27 @@
}
/**
+ * Logs System UI bubbles developer errors.
+ *
+ * Logged from:
+ * frameworks/base/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+ */
+message BubbleDeveloperErrorReported {
+
+ // The app package that is posting the bubble.
+ optional string package_name = 1;
+
+ // Bubble developer error type enums.
+ enum Error {
+ UNKNOWN = 0;
+ ACTIVITY_INFO_MISSING = 1;
+ ACTIVITY_INFO_NOT_RESIZABLE = 2;
+ DOCUMENT_LAUNCH_NOT_ALWAYS = 3;
+ }
+ optional Error error = 2 [default = UNKNOWN];
+}
+
+/**
* Logs that a constraint for a scheduled job has changed.
*
* Logged from:
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index f87849e..b362e37 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -112,6 +112,28 @@
mIsActive = true;
}
+void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs) {
+ if (mEventActivationMap.size() == 0) {
+ return;
+ }
+ auto& activation = mEventActivationMap.begin()->second;
+ activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns;
+ activation.state = kActive;
+ mIsActive = true;
+ VLOG("setting new activation time to %lld, %lld, %lld", (long long)activation.activation_ns,
+ (long long)currentTimeNs, (long long)remainingTtlNs);
+}
+
+int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const {
+ int64_t maxTtl = 0;
+ for (const auto& activation : mEventActivationMap) {
+ if (activation.second.state == kActive) {
+ maxTtl = std::max(maxTtl, activation.second.ttl_ns + activation.second.activation_ns -
+ currentTimeNs);
+ }
+ }
+ return maxTtl;
+}
} // namespace statsd
} // namespace os
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 09e2409..ca37bbb 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -179,10 +179,21 @@
mBucketSizeNs = bucketSize;
}
- inline const int64_t& getMetricId() {
+ inline const int64_t& getMetricId() const {
return mMetricId;
}
+ int64_t getRemainingTtlNs(int64_t currentTimeNs) const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return getRemainingTtlNsLocked(currentTimeNs);
+ }
+
+ // Set metric to active for ttlNs.
+ void setActive(int64_t currentTimeNs, int64_t remainingTtlNs) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ setActiveLocked(currentTimeNs, remainingTtlNs);
+ }
+
// Let MetricProducer drop in-memory data to save memory.
// We still need to keep future data valid and anomaly tracking work, which means we will
// have to flush old data, informing anomaly trackers then safely drop old data.
@@ -202,6 +213,11 @@
activateLocked(activationTrackerIndex, elapsedTimestampNs);
}
+ bool isActive() const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return isActiveLocked();
+ }
+
void addActivation(int activationTrackerIndex, int64_t ttl_seconds);
void flushIfExpire(int64_t elapsedTimestampNs);
@@ -227,6 +243,10 @@
return mIsActive;
}
+ int64_t getRemainingTtlNsLocked(int64_t currentTimeNs) const;
+
+ void setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs);
+
/**
* Flushes the current bucket if the eventTime is after the current bucket's end time. This will
also flush the current partial bucket in memory.
@@ -348,6 +368,8 @@
bool mIsActive;
FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index dd969c0..ca68117 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -122,6 +122,13 @@
StatsdStats::getInstance().noteConfigReceived(
key, mAllMetricProducers.size(), mAllConditionTrackers.size(), mAllAtomMatchers.size(),
mAllAnomalyTrackers.size(), mAnnotations, mConfigValid);
+ // Check active
+ for (const auto& metric : mAllMetricProducers) {
+ if (metric->isActive()) {
+ mIsActive = true;
+ break;
+ }
+ }
}
MetricsManager::~MetricsManager() {
@@ -304,8 +311,10 @@
int tagId = event.GetTagId();
int64_t eventTimeNs = event.GetElapsedTimestampNs();
+ bool isActive = false;
for (int metric : mMetricIndexesWithActivation) {
mAllMetricProducers[metric]->flushIfExpire(eventTimeNs);
+ isActive |= mAllMetricProducers[metric]->isActive();
}
if (mTagIds.find(tagId) == mTagIds.end()) {
@@ -323,10 +332,13 @@
if (matcherCache[it.first] == MatchingState::kMatched) {
for (int metricIndex : it.second) {
mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
+ isActive |= mAllMetricProducers[metricIndex]->isActive();
}
}
}
+ mIsActive = isActive;
+
// A bitmap to see which ConditionTracker needs to be re-evaluated.
vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
@@ -418,6 +430,25 @@
return totalSize;
}
+void MetricsManager::setActiveMetrics(ActiveConfig config, int64_t currentTimeNs) {
+ if (config.active_metric_size() == 0) {
+ ALOGW("No active metric for config %s", mConfigKey.ToString().c_str());
+ return;
+ }
+
+ for (int i = 0; i < config.active_metric_size(); i++) {
+ for (int metric : mMetricIndexesWithActivation) {
+ if (mAllMetricProducers[metric]->getMetricId() == config.active_metric(i).metric_id()) {
+ VLOG("Setting active metric: %lld",
+ (long long)mAllMetricProducers[metric]->getMetricId());
+ mAllMetricProducers[metric]->setActive(
+ currentTimeNs, config.active_metric(i).time_to_live_nanos());
+ mIsActive = true;
+ }
+ }
+ }
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index a31efbd..80982c3 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -16,12 +16,13 @@
#pragma once
-#include "external/StatsPullerManager.h"
+#include <frameworks/base/cmds/statsd/src/active_config_list.pb.h>
#include "anomaly/AlarmMonitor.h"
#include "anomaly/AlarmTracker.h"
#include "anomaly/AnomalyTracker.h"
#include "condition/ConditionTracker.h"
#include "config/ConfigKey.h"
+#include "external/StatsPullerManager.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "logd/LogEvent.h"
#include "matchers/LogMatchingTracker.h"
@@ -123,6 +124,20 @@
// Does not change the state.
virtual size_t byteSize();
+ inline bool isActive() const {
+ return mIsActive;
+ }
+
+ inline void getActiveMetrics(std::vector<const MetricProducer*>& metrics) const {
+ for (const auto& metric : mAllMetricProducers) {
+ if (metric->isActive()) {
+ metrics.push_back(metric.get());
+ }
+ }
+ }
+
+ void setActiveMetrics(ActiveConfig config, int64_t currentTimeNs);
+
private:
// For test only.
inline int64_t getTtlEndNs() const { return mTtlEndNs; }
@@ -216,6 +231,9 @@
// The metrics that don't need to be uploaded or even reported.
std::set<int64_t> mNoReportMetricIds;
+ // Any metric active means the config is active.
+ bool mIsActive;
+
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions);
FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks);
FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
@@ -247,6 +265,8 @@
FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
+
+ FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
};
} // namespace statsd
diff --git a/cmds/statsd/statsd.rc b/cmds/statsd/statsd.rc
index cbf2a8d..e0cbd5d 100644
--- a/cmds/statsd/statsd.rc
+++ b/cmds/statsd/statsd.rc
@@ -26,3 +26,4 @@
# Create directory for statsd
mkdir /data/misc/stats-data/ 0770 statsd system
mkdir /data/misc/stats-service/ 0770 statsd system
+ mkdir /data/misc/stats-active-metric/ 0770 statsd system
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index d52be44..64008b5 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -286,6 +286,294 @@
EXPECT_TRUE(noData);
}
+TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
+ int uid = 1111;
+
+ // Setup a simple config, no activation
+ StatsdConfig config1;
+ config1.set_id(12341);
+ config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
+ *config1.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId1 = 1234561;
+ long metricId2 = 1234562;
+ auto countMetric1 = config1.add_count_metric();
+ countMetric1->set_id(metricId1);
+ countMetric1->set_what(wakelockAcquireMatcher.id());
+ countMetric1->set_bucket(FIVE_MINUTES);
+
+ auto countMetric2 = config1.add_count_metric();
+ countMetric2->set_id(metricId2);
+ countMetric2->set_what(wakelockAcquireMatcher.id());
+ countMetric2->set_bucket(FIVE_MINUTES);
+
+ ConfigKey cfgKey1(uid, 12341);
+ long timeBase1 = 1;
+ sp<StatsLogProcessor> processor =
+ CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
+
+ // Add another config, with two metrics, one with activation
+ StatsdConfig config2;
+ config2.set_id(12342);
+ config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ *config2.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId3 = 1234561;
+ long metricId4 = 1234562;
+
+ auto countMetric3 = config2.add_count_metric();
+ countMetric3->set_id(metricId3);
+ countMetric3->set_what(wakelockAcquireMatcher.id());
+ countMetric3->set_bucket(FIVE_MINUTES);
+
+ auto countMetric4 = config2.add_count_metric();
+ countMetric4->set_id(metricId4);
+ countMetric4->set_what(wakelockAcquireMatcher.id());
+ countMetric4->set_bucket(FIVE_MINUTES);
+
+ auto metric3Activation = config2.add_metric_activation();
+ metric3Activation->set_metric_id(metricId3);
+ auto metric3ActivationTrigger = metric3Activation->add_event_activation();
+ metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric3ActivationTrigger->set_ttl_seconds(100);
+
+ ConfigKey cfgKey2(uid, 12342);
+
+ // Add another config, with two metrics, both with activations
+ StatsdConfig config3;
+ config3.set_id(12342);
+ config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+ *config3.add_atom_matcher() = wakelockAcquireMatcher;
+
+ long metricId5 = 1234565;
+ long metricId6 = 1234566;
+ auto countMetric5 = config3.add_count_metric();
+ countMetric5->set_id(metricId5);
+ countMetric5->set_what(wakelockAcquireMatcher.id());
+ countMetric5->set_bucket(FIVE_MINUTES);
+
+ auto countMetric6 = config3.add_count_metric();
+ countMetric6->set_id(metricId6);
+ countMetric6->set_what(wakelockAcquireMatcher.id());
+ countMetric6->set_bucket(FIVE_MINUTES);
+
+ auto metric5Activation = config3.add_metric_activation();
+ metric5Activation->set_metric_id(metricId5);
+ auto metric5ActivationTrigger = metric5Activation->add_event_activation();
+ metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric5ActivationTrigger->set_ttl_seconds(100);
+
+ auto metric6Activation = config3.add_metric_activation();
+ metric6Activation->set_metric_id(metricId6);
+ auto metric6ActivationTrigger = metric6Activation->add_event_activation();
+ metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id());
+ metric6ActivationTrigger->set_ttl_seconds(200);
+
+ ConfigKey cfgKey3(uid, 12343);
+
+ processor->OnConfigUpdated(2, cfgKey2, config2);
+ processor->OnConfigUpdated(3, cfgKey3, config3);
+
+ EXPECT_EQ(3, processor->mMetricsManagers.size());
+ auto it = processor->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager1 = it->second;
+ EXPECT_TRUE(metricsManager1->isActive());
+
+ auto metricIt = metricsManager1->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId1) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
+ auto& metricProducer1 = *metricIt;
+ EXPECT_TRUE(metricProducer1->isActive());
+
+ metricIt = metricsManager1->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId2) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
+ auto& metricProducer2 = *metricIt;
+ EXPECT_TRUE(metricProducer2->isActive());
+
+ it = processor->mMetricsManagers.find(cfgKey2);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager2 = it->second;
+ EXPECT_TRUE(metricsManager2->isActive());
+
+ metricIt = metricsManager2->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId3) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
+ auto& metricProducer3 = *metricIt;
+ EXPECT_FALSE(metricProducer3->isActive());
+
+ metricIt = metricsManager2->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId4) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end());
+ auto& metricProducer4 = *metricIt;
+ EXPECT_TRUE(metricProducer4->isActive());
+
+ it = processor->mMetricsManagers.find(cfgKey3);
+ EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ auto& metricsManager3 = it->second;
+ EXPECT_FALSE(metricsManager3->isActive());
+
+ metricIt = metricsManager3->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId5) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
+ auto& metricProducer5 = *metricIt;
+ EXPECT_FALSE(metricProducer5->isActive());
+
+ metricIt = metricsManager3->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId6) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end());
+ auto& metricProducer6 = *metricIt;
+ EXPECT_FALSE(metricProducer6->isActive());
+
+ std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
+ auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1);
+ processor->OnLogEvent(event.get());
+
+ int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
+ EXPECT_TRUE(metricProducer3->isActive());
+ int64_t ttl3 = metricProducer3->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100, ttl3);
+ EXPECT_TRUE(metricProducer5->isActive());
+ int64_t ttl5 = metricProducer5->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100, ttl5);
+ EXPECT_TRUE(metricProducer6->isActive());
+ int64_t ttl6 = metricProducer6->getRemainingTtlNs(shutDownTime);
+ EXPECT_EQ(100 + 100 * NS_PER_SEC, ttl6);
+
+ processor->WriteMetricsActivationToDisk(timeBase1 + 100 * NS_PER_SEC);
+
+ long timeBase2 = 1000;
+ sp<StatsLogProcessor> processor2 =
+ CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1);
+ processor2->OnConfigUpdated(timeBase2, cfgKey2, config2);
+ processor2->OnConfigUpdated(timeBase2, cfgKey3, config3);
+
+ EXPECT_EQ(3, processor2->mMetricsManagers.size());
+ it = processor2->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1001 = it->second;
+ EXPECT_TRUE(metricsManager1001->isActive());
+
+ metricIt = metricsManager1001->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId1) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
+ auto& metricProducer1001 = *metricIt;
+ EXPECT_TRUE(metricProducer1001->isActive());
+
+ metricIt = metricsManager1001->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId2) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
+ auto& metricProducer1002 = *metricIt;
+ EXPECT_TRUE(metricProducer1002->isActive());
+
+ it = processor2->mMetricsManagers.find(cfgKey2);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1002 = it->second;
+ EXPECT_TRUE(metricsManager1002->isActive());
+
+ metricIt = metricsManager1002->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId3) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
+ auto& metricProducer1003 = *metricIt;
+ EXPECT_FALSE(metricProducer1003->isActive());
+
+ metricIt = metricsManager1002->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId4) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end());
+ auto& metricProducer1004 = *metricIt;
+ EXPECT_TRUE(metricProducer1004->isActive());
+
+ it = processor2->mMetricsManagers.find(cfgKey3);
+ EXPECT_TRUE(it != processor2->mMetricsManagers.end());
+ auto& metricsManager1003 = it->second;
+ EXPECT_FALSE(metricsManager1003->isActive());
+ EXPECT_EQ(2, metricsManager1003->mAllMetricProducers.size());
+
+ metricIt = metricsManager1003->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId5) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
+ auto& metricProducer1005 = *metricIt;
+ EXPECT_FALSE(metricProducer1005->isActive());
+
+ metricIt = metricsManager1003->mAllMetricProducers.begin();
+ for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) {
+ if ((*metricIt)->getMetricId() == metricId6) {
+ break;
+ }
+ }
+ EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end());
+ auto& metricProducer1006 = *metricIt;
+ EXPECT_FALSE(metricProducer1006->isActive());
+
+ EXPECT_FALSE(metricProducer1003->isActive());
+ const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second;
+ EXPECT_EQ(100 * NS_PER_SEC, activation1003.ttl_ns);
+ EXPECT_EQ(0, activation1003.activation_ns);
+ EXPECT_FALSE(metricProducer1005->isActive());
+ const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second;
+ EXPECT_EQ(100 * NS_PER_SEC, activation1005.ttl_ns);
+ EXPECT_EQ(0, activation1005.activation_ns);
+ EXPECT_FALSE(metricProducer1006->isActive());
+ const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second;
+ EXPECT_EQ(200 * NS_PER_SEC, activation1006.ttl_ns);
+ EXPECT_EQ(0, activation1006.activation_ns);
+
+ processor2->LoadMetricsActivationFromDisk();
+
+ EXPECT_TRUE(metricProducer1003->isActive());
+ EXPECT_EQ(timeBase2 + ttl3 - activation1003.ttl_ns, activation1003.activation_ns);
+ EXPECT_TRUE(metricProducer1005->isActive());
+ EXPECT_EQ(timeBase2 + ttl5 - activation1005.ttl_ns, activation1005.activation_ns);
+ EXPECT_TRUE(metricProducer1006->isActive());
+ EXPECT_EQ(timeBase2 + ttl6 - activation1006.ttl_ns, activation1003.activation_ns);
+}
+
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index 920a52d..d29e68e 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.os.BatteryManager;
import android.os.IPowerManager;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -71,7 +72,8 @@
if (val != 0) {
// if the request is not to set it to false, wake up the screen so that
// it can stay on as requested
- pm.wakeUp(SystemClock.uptimeMillis(), "PowerCommand", null);
+ pm.wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_UNKNOWN, "PowerCommand", null);
}
pm.setStayOnSetting(val);
}
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index 6061b66..7edd128 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -33456,7 +33456,6 @@
HSPLandroid/view/SurfaceControl;->finalize()V
HSPLandroid/view/SurfaceControl;->getActiveColorMode(Landroid/os/IBinder;)I
HSPLandroid/view/SurfaceControl;->getActiveConfig(Landroid/os/IBinder;)I
-HSPLandroid/view/SurfaceControl;->getBuiltInDisplay(I)Landroid/os/IBinder;
HSPLandroid/view/SurfaceControl;->getDisplayColorModes(Landroid/os/IBinder;)[I
HSPLandroid/view/SurfaceControl;->getDisplayConfigs(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;
HSPLandroid/view/SurfaceControl;->getHandle()Landroid/os/IBinder;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index aad412f..a0d8a12 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -828,7 +828,6 @@
Landroid/os/IPowerManager;->reboot(ZLjava/lang/String;Z)V
Landroid/os/IPowerManager;->releaseWakeLock(Landroid/os/IBinder;I)V
Landroid/os/IPowerManager;->userActivity(JII)V
-Landroid/os/IPowerManager;->wakeUp(JLjava/lang/String;Ljava/lang/String;)V
Landroid/os/IRecoverySystem$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IRecoverySystem;
Landroid/os/IRemoteCallback$Stub;-><init>()V
Landroid/os/IRemoteCallback;->sendResult(Landroid/os/Bundle;)V
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index a0464df..ebb03e7 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Looper;
import android.os.Trace;
import android.util.AndroidRuntimeException;
@@ -76,7 +77,13 @@
/**
* Internal constants
*/
- @UnsupportedAppUsage
+
+ /**
+ * System-wide animation scale.
+ *
+ * <p>To check whether animations are enabled system-wise use {@link #areAnimatorsEnabled()}.
+ */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static float sDurationScale = 1.0f;
/**
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index cf62e8d..76dbf7e 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -32,13 +32,14 @@
List<String> getRoleHoldersAsUser(in String roleName, int userId);
- void addRoleHolderAsUser(in String roleName, in String packageName, int userId,
+ void addRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId,
in IRoleManagerCallback callback);
- void removeRoleHolderAsUser(in String roleName, in String packageName, int userId,
+ void removeRoleHolderAsUser(in String roleName, in String packageName, int flags, int userId,
in IRoleManagerCallback callback);
- void clearRoleHoldersAsUser(in String roleName, int userId, in IRoleManagerCallback callback);
+ void clearRoleHoldersAsUser(in String roleName, int flags, int userId,
+ in IRoleManagerCallback callback);
void addOnRoleHoldersChangedListenerAsUser(IOnRoleHoldersChangedListener listener, int userId);
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index ddd5313..fa2a6a1 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -18,6 +18,7 @@
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -181,6 +182,22 @@
public static final String ROLE_ASSISTANT = "android.app.role.ASSISTANT";
/**
+ * @hide
+ */
+ @IntDef(flag = true, value = { MANAGE_HOLDERS_FLAG_DONT_KILL_APP })
+ public @interface ManageHoldersFlags {}
+
+ /**
+ * Flag parameter for {@link #addRoleHolderAsUser}, {@link #removeRoleHolderAsUser} and
+ * {@link #clearRoleHoldersAsUser} to indicate that apps should not be killed when changing
+ * their role holder status.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1;
+
+ /**
* The action used to request user approval of a role for an application.
*
* @hide
@@ -305,9 +322,9 @@
*
* @return a list of package names of the role holders, or an empty list if none.
*
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -335,13 +352,14 @@
*
* @param roleName the name of the role to add the role holder for
* @param packageName the package name of the application to add to the role holders
+ * @param flags optional behavior flags
* @param user the user to add the role holder for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -349,15 +367,15 @@
@SystemApi
@TestApi
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
- @NonNull RoleManagerCallback callback) {
+ @ManageHoldersFlags int flags, @NonNull UserHandle user,
+ @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.addRoleHolderAsUser(roleName, packageName, user.getIdentifier(),
+ mService.addRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -373,13 +391,14 @@
*
* @param roleName the name of the role to remove the role holder for
* @param packageName the package name of the application to remove from the role holders
+ * @param flags optional behavior flags
* @param user the user to remove the role holder for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #clearRoleHoldersAsUser(String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@@ -387,15 +406,15 @@
@SystemApi
@TestApi
public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
- @NonNull RoleManagerCallback callback) {
+ @ManageHoldersFlags int flags, @NonNull UserHandle user,
+ @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.removeRoleHolderAsUser(roleName, packageName, user.getIdentifier(),
+ mService.removeRoleHolderAsUser(roleName, packageName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -410,27 +429,29 @@
* {@code android.permission.INTERACT_ACROSS_USERS_FULL}.
*
* @param roleName the name of the role to remove role holders for
+ * @param flags optional behavior flags
* @param user the user to remove role holders for
* @param executor the {@code Executor} to run the callback on.
* @param callback the callback for whether this call is successful
*
* @see #getRoleHoldersAsUser(String, UserHandle)
- * @see #addRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
- * @see #removeRoleHolderAsUser(String, String, UserHandle, Executor, RoleManagerCallback)
+ * @see #addRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
+ * @see #removeRoleHolderAsUser(String, String, int, UserHandle, Executor, RoleManagerCallback)
*
* @hide
*/
@RequiresPermission(Manifest.permission.MANAGE_ROLE_HOLDERS)
@SystemApi
@TestApi
- public void clearRoleHoldersAsUser(@NonNull String roleName, @NonNull UserHandle user,
- @CallbackExecutor @NonNull Executor executor, @NonNull RoleManagerCallback callback) {
+ public void clearRoleHoldersAsUser(@NonNull String roleName, @ManageHoldersFlags int flags,
+ @NonNull UserHandle user, @CallbackExecutor @NonNull Executor executor,
+ @NonNull RoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(user, "user cannot be null");
Preconditions.checkNotNull(executor, "executor cannot be null");
Preconditions.checkNotNull(callback, "callback cannot be null");
try {
- mService.clearRoleHoldersAsUser(roleName, user.getIdentifier(),
+ mService.clearRoleHoldersAsUser(roleName, flags, user.getIdentifier(),
new RoleManagerCallbackDelegate(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index b6e2b69..a107a7a 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -47,10 +47,11 @@
private final boolean mEnableAdjustBrightness;
private final boolean mEnableDataSaver;
private final boolean mEnableFirewall;
+ private final boolean mEnableNightMode;
private final boolean mEnableQuickDoze;
private final boolean mForceAllAppsStandby;
private final boolean mForceBackgroundCheck;
- private final int mGpsMode;
+ private final int mLocationMode;
private BatterySaverPolicyConfig(Builder in) {
mAdjustBrightnessFactor = Math.max(0, Math.min(in.mAdjustBrightnessFactor, 1f));
@@ -67,11 +68,12 @@
mEnableAdjustBrightness = in.mEnableAdjustBrightness;
mEnableDataSaver = in.mEnableDataSaver;
mEnableFirewall = in.mEnableFirewall;
+ mEnableNightMode = in.mEnableNightMode;
mEnableQuickDoze = in.mEnableQuickDoze;
mForceAllAppsStandby = in.mForceAllAppsStandby;
mForceBackgroundCheck = in.mForceBackgroundCheck;
- mGpsMode = Math.max(PowerManager.MIN_LOCATION_MODE,
- Math.min(in.mGpsMode, PowerManager.MAX_LOCATION_MODE));
+ mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
+ Math.min(in.mLocationMode, PowerManager.MAX_LOCATION_MODE));
}
private BatterySaverPolicyConfig(Parcel in) {
@@ -101,10 +103,11 @@
mEnableAdjustBrightness = in.readBoolean();
mEnableDataSaver = in.readBoolean();
mEnableFirewall = in.readBoolean();
+ mEnableNightMode = in.readBoolean();
mEnableQuickDoze = in.readBoolean();
mForceAllAppsStandby = in.readBoolean();
mForceBackgroundCheck = in.readBoolean();
- mGpsMode = Math.max(PowerManager.MIN_LOCATION_MODE,
+ mLocationMode = Math.max(PowerManager.MIN_LOCATION_MODE,
Math.min(in.readInt(), PowerManager.MAX_LOCATION_MODE));
}
@@ -150,10 +153,11 @@
dest.writeBoolean(mEnableAdjustBrightness);
dest.writeBoolean(mEnableDataSaver);
dest.writeBoolean(mEnableFirewall);
+ dest.writeBoolean(mEnableNightMode);
dest.writeBoolean(mEnableQuickDoze);
dest.writeBoolean(mForceAllAppsStandby);
dest.writeBoolean(mForceBackgroundCheck);
- dest.writeInt(mGpsMode);
+ dest.writeInt(mLocationMode);
}
@Override
@@ -168,11 +172,12 @@
+ "animation_disabled=" + mDisableAnimation + ","
+ "aod_disabled=" + mDisableAod + ","
+ "datasaver_disabled=" + !mEnableDataSaver + ","
+ + "enable_night_mode=" + mEnableNightMode + ","
+ "firewall_disabled=" + !mEnableFirewall + ","
+ "force_all_apps_standby=" + mForceAllAppsStandby + ","
+ "force_background_check=" + mForceBackgroundCheck + ","
+ "fullbackup_deferred=" + mDeferFullBackup + ","
- + "gps_mode=" + mGpsMode + ","
+ + "gps_mode=" + mLocationMode + ","
+ "keyvaluebackup_deferred=" + mDeferKeyValueBackup + ","
+ "launch_boost_disabled=" + mDisableLaunchBoost + ","
+ "optional_sensors_disabled=" + mDisableOptionalSensors + ","
@@ -260,6 +265,11 @@
return mEnableFirewall;
}
+ /** Whether or not to enable night mode while in Battery Saver. */
+ public boolean getEnableNightMode() {
+ return mEnableNightMode;
+ }
+
/** Whether or not to enable Quick Doze while in Battery Saver. */
public boolean getEnableQuickDoze() {
return mEnableQuickDoze;
@@ -275,9 +285,9 @@
return mForceBackgroundCheck;
}
- /** The GPS mode while in Battery Saver. */
- public int getGpsMode() {
- return mGpsMode;
+ /** The location mode while in Battery Saver. */
+ public int getLocationMode() {
+ return mLocationMode;
}
/** Builder class for constructing {@link BatterySaverPolicyConfig} objects. */
@@ -297,10 +307,11 @@
private boolean mEnableAdjustBrightness = false;
private boolean mEnableDataSaver = false;
private boolean mEnableFirewall = false;
+ private boolean mEnableNightMode = false;
private boolean mEnableQuickDoze = false;
private boolean mForceAllAppsStandby = false;
private boolean mForceBackgroundCheck = false;
- private int mGpsMode = PowerManager.LOCATION_MODE_NO_CHANGE;
+ private int mLocationMode = PowerManager.LOCATION_MODE_NO_CHANGE;
public Builder() {
}
@@ -424,6 +435,13 @@
return this;
}
+ /** Set whether or not to enable night mode while in Battery Saver. */
+ @NonNull
+ public Builder setEnableNightMode(boolean enableNightMode) {
+ mEnableNightMode = enableNightMode;
+ return this;
+ }
+
/** Set whether or not to enable Quick Doze while in Battery Saver. */
@NonNull
public Builder setEnableQuickDoze(boolean enableQuickDoze) {
@@ -445,10 +463,10 @@
return this;
}
- /** Set the GPS mode while in Battery Saver. */
+ /** Set the location mode while in Battery Saver. */
@NonNull
- public Builder setGpsMode(@PowerManager.LocationPowerSaveMode int gpsMode) {
- mGpsMode = gpsMode;
+ public Builder setLocationMode(@PowerManager.LocationPowerSaveMode int locationMode) {
+ mLocationMode = locationMode;
return this;
}
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 093897a..bdef575 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -42,7 +42,7 @@
boolean isWakeLockLevelSupported(int level);
void userActivity(long time, int event, int flags);
- void wakeUp(long time, String reason, String opPackageName);
+ void wakeUp(long time, int reason, String details, String opPackageName);
void goToSleep(long time, int reason, int flags);
void nap(long time);
boolean isInteractive();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index be673ad..2ecf9d1 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -435,6 +435,106 @@
public static final int GO_TO_SLEEP_FLAG_NO_DOZE = 1 << 0;
/**
+ * @hide
+ */
+ @IntDef(prefix = { "WAKE_REASON_" }, value = {
+ WAKE_REASON_UNKNOWN,
+ WAKE_REASON_POWER_BUTTON,
+ WAKE_REASON_APPLICATION,
+ WAKE_REASON_PLUGGED_IN,
+ WAKE_REASON_GESTURE,
+ WAKE_REASON_CAMERA_LAUNCH,
+ WAKE_REASON_WAKE_KEY,
+ WAKE_REASON_WAKE_MOTION,
+ WAKE_REASON_HDMI,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WakeReason{}
+
+ /**
+ * Wake up reason code: Waking for an unknown reason.
+ * @hide
+ */
+ public static final int WAKE_REASON_UNKNOWN = 0;
+
+ /**
+ * Wake up reason code: Waking up due to power button press.
+ * @hide
+ */
+ public static final int WAKE_REASON_POWER_BUTTON = 1;
+
+ /**
+ * Wake up reason code: Waking up because an application requested it.
+ * @hide
+ */
+ public static final int WAKE_REASON_APPLICATION = 2;
+
+ /**
+ * Wake up reason code: Waking up due to being plugged in or docked on a wireless charger.
+ * @hide
+ */
+ public static final int WAKE_REASON_PLUGGED_IN = 3;
+
+ /**
+ * Wake up reason code: Waking up due to a user performed gesture (e.g. douple tapping on the
+ * screen).
+ * @hide
+ */
+ public static final int WAKE_REASON_GESTURE = 4;
+
+ /**
+ * Wake up reason code: Waking up due to the camera being launched.
+ * @hide
+ */
+ public static final int WAKE_REASON_CAMERA_LAUNCH = 5;
+
+ /**
+ * Wake up reason code: Waking up because a wake key other than power was pressed.
+ * @hide
+ */
+ public static final int WAKE_REASON_WAKE_KEY = 6;
+
+ /**
+ * Wake up reason code: Waking up because a wake motion was performed.
+ *
+ * For example, a trackball that was set to wake the device up was spun.
+ * @hide
+ */
+ public static final int WAKE_REASON_WAKE_MOTION = 7;
+
+ /**
+ * Wake up reason code: Waking due to HDMI.
+ * @hide
+ */
+ public static final int WAKE_REASON_HDMI = 8;
+
+ /**
+ * Wake up reason code: Waking due to the lid being opened.
+ * @hide
+ */
+ public static final int WAKE_REASON_LID = 9;
+
+ /**
+ * Convert the wake reason to a string for debugging purposes.
+ * @hide
+ */
+ public static String wakeReasonToString(@WakeReason int wakeReason) {
+ switch (wakeReason) {
+ case WAKE_REASON_UNKNOWN: return "WAKE_REASON_UNKNOWN";
+ case WAKE_REASON_POWER_BUTTON: return "WAKE_REASON_POWER_BUTTON";
+ case WAKE_REASON_APPLICATION: return "WAKE_REASON_APPLICATION";
+ case WAKE_REASON_PLUGGED_IN: return "WAKE_REASON_PLUGGED_IN";
+ case WAKE_REASON_GESTURE: return "WAKE_REASON_GESTURE";
+ case WAKE_REASON_CAMERA_LAUNCH: return "WAKE_REASON_CAMERA_LAUNCH";
+ case WAKE_REASON_WAKE_KEY: return "WAKE_REASON_WAKE_KEY";
+ case WAKE_REASON_WAKE_MOTION: return "WAKE_REASON_WAKE_MOTION";
+ case WAKE_REASON_HDMI: return "WAKE_REASON_HDMI";
+ case WAKE_REASON_LID: return "WAKE_REASON_LID";
+ default: return Integer.toString(wakeReason);
+ }
+ }
+
+ /**
* The value to pass as the 'reason' argument to reboot() to reboot into
* recovery mode for tasks other than applying system updates, such as
* doing factory resets.
@@ -975,22 +1075,68 @@
* @see #userActivity
* @see #goToSleep
*
+ * @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @removed Requires signature permission.
*/
+ @Deprecated
public void wakeUp(long time) {
- try {
- mService.wakeUp(time, "wakeUp", mContext.getOpPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ wakeUp(time, WAKE_REASON_UNKNOWN, "wakeUp");
}
/**
+ * Forces the device to wake up from sleep.
+ * <p>
+ * If the device is currently asleep, wakes it up, otherwise does nothing.
+ * This is what happens when the power key is pressed to turn on the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to wake up was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the wake up request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to wake up.
+ *
+ * @param details A free form string to explain the specific details behind the wake up for
+ * debugging purposes.
+ *
+ * @see #userActivity
+ * @see #goToSleep
+ *
+ * @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @hide
*/
- public void wakeUp(long time, String reason) {
+ @Deprecated
+ public void wakeUp(long time, String details) {
+ wakeUp(time, WAKE_REASON_UNKNOWN, details);
+ }
+
+ /**
+ * Forces the device to wake up from sleep.
+ * <p>
+ * If the device is currently asleep, wakes it up, otherwise does nothing.
+ * This is what happens when the power key is pressed to turn on the screen.
+ * </p><p>
+ * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
+ * </p>
+ *
+ * @param time The time when the request to wake up was issued, in the
+ * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
+ * order the wake up request with other power management functions. It should be set
+ * to the timestamp of the input event that caused the request to wake up.
+ *
+ * @param reason The reason for the wake up.
+ *
+ * @param details A free form string to explain the specific details behind the wake up for
+ * debugging purposes.
+ *
+ * @see #userActivity
+ * @see #goToSleep
+ * @hide
+ */
+ public void wakeUp(long time, @WakeReason int reason, String details) {
try {
- mService.wakeUp(time, reason, mContext.getOpPackageName());
+ mService.wakeUp(time, reason, details, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index de54a8aa..f63c0adb 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -772,19 +772,6 @@
* @param callBlockReason The reason why the call is blocked.
* @param callScreeningAppName The call screening application name which block the call.
* @param callScreeningComponentName The call screening component name which block the call.
- * @param callIdPackageName The package name of the
- * {@link android.telecom.CallScreeningService} which provided
- * {@link CallIdentification}.
- * @param callIdAppName The app name of the {@link android.telecom.CallScreeningService}
- * which provided {@link CallIdentification}.
- * @param callIdName The caller name provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdDescription The caller description provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdDetails The caller details provided by the
- * {@link android.telecom.CallScreeningService}.
- * @param callIdCallType The caller type provided by the
- * {@link android.telecom.CallScreeningService}.
*
* @result The URI of the call log entry belonging to the user that made or received this
* call. This could be of the shadow provider. Do not return it to non-system apps,
@@ -803,37 +790,10 @@
number, userToBeInsertedTo, addForAllUsers));
}
final ContentResolver resolver = context.getContentResolver();
- int numberPresentation = PRESENTATION_ALLOWED;
- TelecomManager tm = null;
- try {
- tm = TelecomManager.from(context);
- } catch (UnsupportedOperationException e) {}
+ String accountAddress = getLogAccountAddress(context, accountHandle);
- String accountAddress = null;
- if (tm != null && accountHandle != null) {
- PhoneAccount account = tm.getPhoneAccount(accountHandle);
- if (account != null) {
- Uri address = account.getSubscriptionAddress();
- if (address != null) {
- accountAddress = address.getSchemeSpecificPart();
- }
- }
- }
-
- // Remap network specified number presentation types
- // PhoneConstants.PRESENTATION_xxx to calllog number presentation types
- // Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
- // from any future radio changes.
- // If the number field is empty set the presentation type to Unknown.
- if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
- numberPresentation = PRESENTATION_RESTRICTED;
- } else if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
- numberPresentation = PRESENTATION_PAYPHONE;
- } else if (TextUtils.isEmpty(number)
- || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
- numberPresentation = PRESENTATION_UNKNOWN;
- }
+ int numberPresentation = getLogNumberPresentation(number, presentation);
if (numberPresentation != PRESENTATION_ALLOWED) {
number = "";
if (ci != null) {
@@ -1138,8 +1098,7 @@
if (TextUtils.isEmpty(countryIso)) {
return;
}
- final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number,
- getCurrentCountryIso(context));
+ final String normalizedNumber = PhoneNumberUtils.formatNumberToE164(number, countryIso);
if (TextUtils.isEmpty(normalizedNumber)) {
return;
}
@@ -1148,6 +1107,54 @@
resolver.update(Data.CONTENT_URI, values, Data._ID + "=?", new String[] {dataId});
}
+ /**
+ * Remap network specified number presentation types
+ * PhoneConstants.PRESENTATION_xxx to calllog number presentation types
+ * Calls.PRESENTATION_xxx, in order to insulate the persistent calllog
+ * from any future radio changes.
+ * If the number field is empty set the presentation type to Unknown.
+ */
+ private static int getLogNumberPresentation(String number, int presentation) {
+ if (presentation == PhoneConstants.PRESENTATION_RESTRICTED) {
+ return presentation;
+ }
+
+ if (presentation == PhoneConstants.PRESENTATION_PAYPHONE) {
+ return presentation;
+ }
+
+ if (TextUtils.isEmpty(number)
+ || presentation == PhoneConstants.PRESENTATION_UNKNOWN) {
+ return PRESENTATION_UNKNOWN;
+ }
+
+ return PRESENTATION_ALLOWED;
+ }
+
+ private static String getLogAccountAddress(Context context,
+ PhoneAccountHandle accountHandle) {
+ TelecomManager tm = null;
+ try {
+ tm = TelecomManager.from(context);
+ } catch (UnsupportedOperationException e) {
+ if (VERBOSE_LOG) {
+ Log.v(LOG_TAG, "No TelecomManager found to get account address.");
+ }
+ }
+
+ String accountAddress = null;
+ if (tm != null && accountHandle != null) {
+ PhoneAccount account = tm.getPhoneAccount(accountHandle);
+ if (account != null) {
+ Uri address = account.getSubscriptionAddress();
+ if (address != null) {
+ accountAddress = address.getSchemeSpecificPart();
+ }
+ }
+ }
+ return accountAddress;
+ }
+
private static String getCurrentCountryIso(Context context) {
String countryIso = null;
final CountryDetector detector = (CountryDetector) context.getSystemService(
diff --git a/core/java/android/rolecontrollerservice/IRoleControllerService.aidl b/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
index 4e98201..40852ea 100644
--- a/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
+++ b/core/java/android/rolecontrollerservice/IRoleControllerService.aidl
@@ -23,13 +23,13 @@
*/
oneway interface IRoleControllerService {
- void onAddRoleHolder(in String roleName, in String packageName,
+ void onAddRoleHolder(in String roleName, in String packageName, int flags,
in IRoleManagerCallback callback);
- void onRemoveRoleHolder(in String roleName, in String packageName,
+ void onRemoveRoleHolder(in String roleName, in String packageName, int flags,
in IRoleManagerCallback callback);
- void onClearRoleHolders(in String roleName, in IRoleManagerCallback callback);
+ void onClearRoleHolders(in String roleName, int flags, in IRoleManagerCallback callback);
void onGrantDefaultRoles(in IRoleManagerCallback callback);
diff --git a/core/java/android/rolecontrollerservice/RoleControllerService.java b/core/java/android/rolecontrollerservice/RoleControllerService.java
index 5403cfa..c846b07 100644
--- a/core/java/android/rolecontrollerservice/RoleControllerService.java
+++ b/core/java/android/rolecontrollerservice/RoleControllerService.java
@@ -61,32 +61,33 @@
return new IRoleControllerService.Stub() {
@Override
- public void onAddRoleHolder(String roleName, String packageName,
+ public void onAddRoleHolder(String roleName, String packageName, int flags,
IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName,
"packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onAddRoleHolder(roleName, packageName,
+ RoleControllerService.this.onAddRoleHolder(roleName, packageName, flags,
new RoleManagerCallbackDelegate(callback));
}
@Override
- public void onRemoveRoleHolder(String roleName, String packageName,
+ public void onRemoveRoleHolder(String roleName, String packageName, int flags,
IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName,
"packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onRemoveRoleHolder(roleName, packageName,
+ RoleControllerService.this.onRemoveRoleHolder(roleName, packageName, flags,
new RoleManagerCallbackDelegate(callback));
}
@Override
- public void onClearRoleHolders(String roleName, IRoleManagerCallback callback) {
+ public void onClearRoleHolders(String roleName, int flags,
+ IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
- RoleControllerService.this.onClearRoleHolders(roleName,
+ RoleControllerService.this.onClearRoleHolders(roleName, flags,
new RoleManagerCallbackDelegate(callback));
}
@@ -113,37 +114,41 @@
*
* @param roleName the name of the role to add the role holder for
* @param packageName the package name of the application to add to the role holders
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#addRoleHolderAsUser(String, String, UserHandle, Executor,
+ * @see RoleManager#addRoleHolderAsUser(String, String, int, UserHandle, Executor,
* RoleManagerCallback)
*/
public abstract void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
/**
* Remove a specific application from the holders of a role.
*
* @param roleName the name of the role to remove the role holder for
* @param packageName the package name of the application to remove from the role holders
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#removeRoleHolderAsUser(String, String, UserHandle, Executor,
+ * @see RoleManager#removeRoleHolderAsUser(String, String, int, UserHandle, Executor,
* RoleManagerCallback)
*/
public abstract void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
/**
* Remove all holders of a role.
*
* @param roleName the name of the role to remove role holders for
+ * @param flags optional behavior flags
* @param callback the callback for whether this call is successful
*
- * @see RoleManager#clearRoleHoldersAsUser(String, UserHandle, Executor, RoleManagerCallback)
+ * @see RoleManager#clearRoleHoldersAsUser(String, int, UserHandle, Executor,
+ * RoleManagerCallback)
*/
public abstract void onClearRoleHolders(@NonNull String roleName,
- @NonNull RoleManagerCallback callback);
+ @RoleManager.ManageHoldersFlags int flags, @NonNull RoleManagerCallback callback);
/**
* Cleanup appop/permissions state in response to sms kill switch toggle
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 8e0f522..81d066d 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -234,7 +234,12 @@
}
/**
- * Implementation specific {@code dump}.
+ * Implementation specific {@code dump}. The child class can override the method to provide
+ * additional information about the Service's state into the dumpsys output.
+ *
+ * @param pw The PrintWriter to which you should dump your state. This will be closed for
+ * you after you return.
+ * @param args additional arguments to the dump request.
*/
protected void dump(@NonNull PrintWriter pw,
@SuppressWarnings("unused") @NonNull String[] args) {
diff --git a/core/java/android/service/dreams/Sandman.java b/core/java/android/service/dreams/Sandman.java
index eeb340b..efb8923 100644
--- a/core/java/android/service/dreams/Sandman.java
+++ b/core/java/android/service/dreams/Sandman.java
@@ -91,8 +91,9 @@
// and the UI mode manager starting a dream. We want the system to already
// be awake by the time this happens. Otherwise the dream may not start.
PowerManager powerManager =
- (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ context.getSystemService(PowerManager.class);
powerManager.wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_PLUGGED_IN,
"android.service.dreams:DREAM");
} else {
Slog.i(TAG, "Activating dream by user request.");
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 949328f..915a18e 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -94,7 +94,8 @@
private final DecorationInfo mDecorationInfo = new DecorationInfo();
private final ArrayList<DecorationInfo> mDecorations = new ArrayList<>();
- @UnsupportedAppUsage
+ /** Not allowed to access. If it's for memory leak workaround, it was already fixed M. */
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
private static final TextLine[] sCached = new TextLine[3];
/**
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 59e562f..62ed901 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -40,6 +40,7 @@
import android.view.View.AttachInfo;
import android.view.accessibility.AccessibilityInteractionClient;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -154,13 +155,7 @@
}
private boolean isShown(View view) {
- // The first two checks are made also made by isShown() which
- // however traverses the tree up to the parent to catch that.
- // Therefore, we do some fail fast check to minimize the up
- // tree traversal.
- return (view.mAttachInfo != null
- && view.mAttachInfo.mWindowVisibility == View.VISIBLE
- && view.isShown());
+ return (view != null) && (view.getWindowVisibility() == View.VISIBLE && view.isShown());
}
public void findAccessibilityNodeInfoByAccessibilityIdClientThread(
@@ -340,13 +335,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = mViewRootImpl.mView;
- } else {
- root = findViewByAccessibilityId(accessibilityViewId);
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
mPrefetcher.prefetchAccessibilityNodeInfos(
root, virtualDescendantId, flags, infos, arguments);
}
@@ -396,12 +386,7 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
+ final View root = findViewByAccessibilityId(accessibilityViewId);
if (root != null) {
final int resolvedViewId = root.getContext().getResources()
.getIdentifier(viewId, null, null);
@@ -462,13 +447,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
if (provider != null) {
infos = provider.findAccessibilityNodeInfosByText(text,
@@ -550,13 +530,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
switch (focusType) {
case AccessibilityNodeInfo.FOCUS_ACCESSIBILITY: {
View host = mViewRootImpl.mAccessibilityFocusedHost;
@@ -583,7 +558,7 @@
} break;
case AccessibilityNodeInfo.FOCUS_INPUT: {
View target = root.findFocus();
- if (target == null || !isShown(target)) {
+ if (!isShown(target)) {
break;
}
AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
@@ -645,13 +620,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View root = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- root = findViewByAccessibilityId(accessibilityViewId);
- } else {
- root = mViewRootImpl.mView;
- }
- if (root != null && isShown(root)) {
+ final View root = findViewByAccessibilityId(accessibilityViewId);
+ if (root != null) {
View nextView = root.focusSearch(direction);
if (nextView != null) {
next = nextView.createAccessibilityNodeInfo();
@@ -705,13 +675,8 @@
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- View target = null;
- if (accessibilityViewId != AccessibilityNodeInfo.ROOT_ITEM_ID) {
- target = findViewByAccessibilityId(accessibilityViewId);
- } else {
- target = mViewRootImpl.mView;
- }
- if (target != null && isShown(target)) {
+ final View target = findViewByAccessibilityId(accessibilityViewId);
+ if (target != null) {
if (action == R.id.accessibilityActionClickOnClickableSpan) {
// Handle this hidden action separately
succeeded = handleClickableSpanActionUiThread(
@@ -791,15 +756,13 @@
}
private View findViewByAccessibilityId(int accessibilityId) {
- View root = mViewRootImpl.mView;
- if (root == null) {
- return null;
+ if (accessibilityId == AccessibilityNodeInfo.ROOT_ITEM_ID) {
+ return mViewRootImpl.mView;
+ } else {
+ final View foundView =
+ AccessibilityNodeIdManager.getInstance().findView(accessibilityId);
+ return isShown(foundView) ? foundView : null;
}
- View foundView = root.findViewByAccessibilityId(accessibilityId);
- if (foundView != null && !isShown(foundView)) {
- return null;
- }
- return foundView;
}
private void applyAppScaleAndMagnificationSpecIfNeeded(List<AccessibilityNodeInfo> infos,
@@ -1171,7 +1134,7 @@
}
View child = children.get(i);
if (child.getAccessibilityViewId() != current.getAccessibilityViewId()
- && isShown(child)) {
+ && isShown(child)) {
AccessibilityNodeInfo info = null;
AccessibilityNodeProvider provider =
child.getAccessibilityNodeProvider();
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index ccd0fc1..03e8a0f 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -22,7 +22,6 @@
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.graphics.FrameInfo;
-import android.graphics.Insets;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
import android.os.Handler;
@@ -914,25 +913,11 @@
super(looper, vsyncSource);
}
+ // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
+ // the internal display and DisplayEventReceiver#scheduleVsync only allows requesting VSYNC
+ // for the internal display implicitly.
@Override
- public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
- // Ignore vsync from secondary display.
- // This can be problematic because the call to scheduleVsync() is a one-shot.
- // We need to ensure that we will still receive the vsync from the primary
- // display which is the one we really care about. Ideally we should schedule
- // vsync for a particular display.
- // At this time Surface Flinger won't send us vsyncs for secondary displays
- // but that could change in the future so let's log a message to help us remember
- // that we need to fix this.
- if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
- Log.d(TAG, "Received vsync from secondary display, but we don't support "
- + "this case yet. Choreographer needs a way to explicitly request "
- + "vsync for a specific display to ensure it doesn't lose track "
- + "of its scheduled vsync.");
- scheduleVsync();
- return;
- }
-
+ public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
// Post the vsync event to the Handler.
// The idea is to prevent incoming vsync events from completely starving
// the message queue. If there are no messages in the queue with timestamps
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index edd3f1a..3e8002f 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -136,12 +136,11 @@
*
* @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
* timebase.
- * @param builtInDisplayId The surface flinger built-in display id such as
- * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
+ * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
* @param frame The frame number. Increases by one for each vertical sync interval.
*/
@UnsupportedAppUsage
- public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
+ public void onVsync(long timestampNanos, long physicalDisplayId, int frame) {
}
/**
@@ -149,12 +148,11 @@
*
* @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
* timebase.
- * @param builtInDisplayId The surface flinger built-in display id such as
- * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
+ * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
* @param connected True if the display is connected, false if it disconnected.
*/
@UnsupportedAppUsage
- public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
+ public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
}
/**
@@ -174,14 +172,14 @@
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage
- private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
- onVsync(timestampNanos, builtInDisplayId, frame);
+ private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
+ onVsync(timestampNanos, physicalDisplayId, frame);
}
// Called from native code.
@SuppressWarnings("unused")
@UnsupportedAppUsage
- private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
- onHotplug(timestampNanos, builtInDisplayId, connected);
+ private void dispatchHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
+ onHotplug(timestampNanos, physicalDisplayId, connected);
}
}
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index 78ad0da..1dbc46b 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -24,6 +24,7 @@
import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.RenderNode;
+import android.os.Build;
import android.util.SparseIntArray;
import com.android.internal.util.VirtualRefBasePtr;
@@ -282,7 +283,7 @@
throw new UnsupportedOperationException();
}
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
public void setTarget(View view) {
mViewTarget = view;
setTarget(mViewTarget.mRenderNode);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 8061cc3..c0a4028 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -44,6 +44,7 @@
import android.hardware.HardwareBuffer;
import android.hardware.display.DisplayedContentSample;
import android.hardware.display.DisplayedContentSamplingAttributes;
+import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
@@ -131,7 +132,8 @@
private static native boolean nativeClearAnimationFrameStats();
private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats);
- private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
+ private static native long[] nativeGetPhysicalDisplayIds();
+ private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId);
private static native IBinder nativeCreateDisplay(String name, boolean secure);
private static native void nativeDestroyDisplay(IBinder displayToken);
private static native void nativeSetDisplaySurface(long transactionObj,
@@ -329,24 +331,6 @@
*/
private static final int SURFACE_OPAQUE = 0x02;
-
- /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
- * these are different from the logical display ids used elsewhere in the framework */
-
- /**
- * Built-in physical display id: Main display.
- * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
-
- /**
- * Built-in physical display id: Attached HDMI display.
- * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
-
// Display power modes.
/**
* Display power mode off: used while blanking the screen.
@@ -1729,9 +1713,28 @@
/**
* @hide
*/
- @UnsupportedAppUsage
- public static IBinder getBuiltInDisplay(int builtInDisplayId) {
- return nativeGetBuiltInDisplay(builtInDisplayId);
+ public static long[] getPhysicalDisplayIds() {
+ return nativeGetPhysicalDisplayIds();
+ }
+
+ /**
+ * @hide
+ */
+ public static IBinder getPhysicalDisplayToken(long physicalDisplayId) {
+ return nativeGetPhysicalDisplayToken(physicalDisplayId);
+ }
+
+ /**
+ * TODO(116025192): Remove this stopgap once framework is display-agnostic.
+ *
+ * @hide
+ */
+ public static IBinder getInternalDisplayToken() {
+ final long[] physicalDisplayIds = getPhysicalDisplayIds();
+ if (physicalDisplayIds.length == 0) {
+ return null;
+ }
+ return getPhysicalDisplayToken(physicalDisplayIds[0]);
}
/**
@@ -1790,8 +1793,12 @@
public static Bitmap screenshot(Rect sourceCrop, int width, int height,
boolean useIdentityTransform, int rotation) {
// TODO: should take the display as a parameter
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+ if (displayToken == null) {
+ Log.w(TAG, "Failed to take screenshot because internal display is disconnected");
+ return null;
+ }
+
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
}
@@ -2194,7 +2201,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
public Transaction setLayerStack(SurfaceControl sc, int layerStack) {
sc.checkNotReleased();
nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 04ffa33..cb8f703 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -103,6 +103,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -19041,6 +19042,7 @@
jumpDrawablesToCurrentState();
+ AccessibilityNodeIdManager.getInstance().registerViewWithId(this, getAccessibilityViewId());
resetSubtreeAccessibilityStateChanged();
// rebuild, since Outline not maintained while View is detached
@@ -19433,6 +19435,8 @@
if ((mViewFlags & TOOLTIP) == TOOLTIP) {
hideTooltip();
}
+
+ AccessibilityNodeIdManager.getInstance().unregisterViewWithId(getAccessibilityViewId());
}
private void cleanupDraw() {
@@ -23947,24 +23951,6 @@
}
/**
- * Finds a view by its unuque and stable accessibility id.
- *
- * @param accessibilityId The searched accessibility id.
- * @return The found view.
- */
- @UnsupportedAppUsage
- final <T extends View> T findViewByAccessibilityId(int accessibilityId) {
- if (accessibilityId < 0) {
- return null;
- }
- T view = findViewByAccessibilityIdTraversal(accessibilityId);
- if (view != null) {
- return view.includeForAccessibility() ? view : null;
- }
- return null;
- }
-
- /**
* Performs the traversal to find a view by its unique and stable accessibility id.
*
* <strong>Note:</strong>This method does not stop at the root namespace
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 47528a0..67cca56 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -95,6 +95,7 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.accessibility.AccessibilityManager.HighTextContrastChangeListener;
+import android.view.accessibility.AccessibilityNodeIdManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityNodeProvider;
@@ -7954,17 +7955,14 @@
// Intercept accessibility focus events fired by virtual nodes to keep
// track of accessibility focus position in such nodes.
final int eventType = event.getEventType();
+ final View source = getSourceForAccessibilityEvent(event);
switch (eventType) {
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED: {
- final long sourceNodeId = event.getSourceNodeId();
- final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
- sourceNodeId);
- View source = mView.findViewByAccessibilityId(accessibilityViewId);
if (source != null) {
AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
if (provider != null) {
final int virtualNodeId = AccessibilityNodeInfo.getVirtualDescendantId(
- sourceNodeId);
+ event.getSourceNodeId());
final AccessibilityNodeInfo node;
node = provider.createAccessibilityNodeInfo(virtualNodeId);
setAccessibilityFocus(source, node);
@@ -7972,15 +7970,8 @@
}
} break;
case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED: {
- final long sourceNodeId = event.getSourceNodeId();
- final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
- sourceNodeId);
- View source = mView.findViewByAccessibilityId(accessibilityViewId);
- if (source != null) {
- AccessibilityNodeProvider provider = source.getAccessibilityNodeProvider();
- if (provider != null) {
- setAccessibilityFocus(null, null);
- }
+ if (source != null && source.getAccessibilityNodeProvider() != null) {
+ setAccessibilityFocus(null, null);
}
} break;
@@ -7993,6 +7984,13 @@
return true;
}
+ private View getSourceForAccessibilityEvent(AccessibilityEvent event) {
+ final long sourceNodeId = event.getSourceNodeId();
+ final int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(
+ sourceNodeId);
+ return AccessibilityNodeIdManager.getInstance().findView(accessibilityViewId);
+ }
+
/**
* Updates the focused virtual view, when necessary, in response to a
* content changed event.
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 16bafe2..35ed7bf 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -16,6 +16,11 @@
package android.view;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Constants for interfacing with WindowManagerService and WindowManagerPolicyInternal.
* @hide
@@ -89,6 +94,35 @@
/** Screen turned off because of timeout */
int OFF_BECAUSE_OF_TIMEOUT = 3;
+ @IntDef(prefix = { "ON_BECAUSE_OF_" }, value = {
+ ON_BECAUSE_OF_USER,
+ ON_BECAUSE_OF_APPLICATION,
+ ON_BECAUSE_OF_UNKNOWN,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface OnReason{}
+
+ /** Convert the on reason to a human readable format */
+ static String onReasonToString(@OnReason int why) {
+ switch (why) {
+ case ON_BECAUSE_OF_USER:
+ return "ON_BECAUSE_OF_USER";
+ case ON_BECAUSE_OF_APPLICATION:
+ return "ON_BECAUSE_OF_APPLICATION";
+ case ON_BECAUSE_OF_UNKNOWN:
+ return "ON_BECAUSE_OF_UNKNOWN";
+ default:
+ return Integer.toString(why);
+ }
+ }
+
+ /** Screen turned on because of a user-initiated action. */
+ int ON_BECAUSE_OF_USER = 1;
+ /** Screen turned on because of an application request or event */
+ int ON_BECAUSE_OF_APPLICATION = 2;
+ /** Screen turned on for an unknown reason */
+ int ON_BECAUSE_OF_UNKNOWN = 3;
+
int APPLICATION_LAYER = 2;
int APPLICATION_MEDIA_SUBLAYER = -2;
int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
diff --git a/core/java/android/view/accessibility/AccessibilityNodeIdManager.java b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
new file mode 100644
index 0000000..1ac7047
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityNodeIdManager.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2019 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.accessibility;
+
+import android.util.SparseArray;
+import android.view.View;
+
+/** @hide */
+public final class AccessibilityNodeIdManager {
+ private SparseArray<View> mIdsToViews = new SparseArray<>();
+ private static AccessibilityNodeIdManager sIdManager;
+
+ /**
+ * Gets singleton.
+ * @return The instance.
+ */
+ public static synchronized AccessibilityNodeIdManager getInstance() {
+ if (sIdManager == null) {
+ sIdManager = new AccessibilityNodeIdManager();
+ }
+ return sIdManager;
+ }
+
+ private AccessibilityNodeIdManager() {
+ }
+
+ /**
+ * Register view to be kept track of by the accessibility system.
+ * Must be paired with unregisterView, otherwise this will leak.
+ * @param view The view to be registered.
+ * @param id The accessibilityViewId of the view.
+ */
+ public void registerViewWithId(View view, int id) {
+ mIdsToViews.append(id, view);
+ }
+
+ /**
+ * Unregister view, accessibility won't keep track of this view after this call.
+ * @param id The id returned from registerView when the view as first associated.
+ */
+ public void unregisterViewWithId(int id) {
+ mIdsToViews.remove(id);
+ }
+
+ /**
+ * Accessibility uses this to find the view in the hierarchy.
+ * @param id The accessibility view id.
+ * @return The view.
+ */
+ public View findView(int id) {
+ final View view = mIdsToViews.get(id);
+ return view != null && view.includeForAccessibility() ? view : null;
+ }
+}
diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java
index dfac35d..22254cd 100644
--- a/core/java/android/view/contentcapture/ContentCaptureEvent.java
+++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java
@@ -138,8 +138,11 @@
/**
* Adds an autofill id to the this event, merging the single id into a list if necessary.
- * @hide */
+ *
+ * @hide
+ */
public ContentCaptureEvent addAutofillId(@NonNull AutofillId id) {
+ Preconditions.checkNotNull(id);
if (mIds == null) {
mIds = new ArrayList<>();
if (mId == null) {
diff --git a/core/java/android/view/contentcapture/ViewNode.java b/core/java/android/view/contentcapture/ViewNode.java
index eef841d..924bb9a 100644
--- a/core/java/android/view/contentcapture/ViewNode.java
+++ b/core/java/android/view/contentcapture/ViewNode.java
@@ -600,7 +600,7 @@
/** @hide */
public static @Nullable ViewNode readFromParcel(@NonNull Parcel parcel) {
final long nodeFlags = parcel.readLong();
- return nodeFlags == 0 ? new ViewNode() : new ViewNode(nodeFlags, parcel);
+ return nodeFlags == 0 ? null : new ViewNode(nodeFlags, parcel);
}
/** @hide */
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4dd7d3a..a02103e 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -483,7 +483,7 @@
/**
* Optional callback to notify client when scroll position has changed
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769353)
private OnScrollListener mOnScrollListener;
/**
@@ -1611,15 +1611,6 @@
return false;
}
- /** @hide */
- @Override
- public View findViewByAccessibilityIdTraversal(int accessibilityId) {
- if (accessibilityId == getAccessibilityViewId()) {
- return this;
- }
- return super.findViewByAccessibilityIdTraversal(accessibilityId);
- }
-
/**
* Indicates whether the children's drawing cache is used during a scroll.
* By default, the drawing cache is enabled but this will consume more memory.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 659b71f..0f4e23d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -712,7 +712,7 @@
@UnsupportedAppUsage
private ChangeWatcher mChangeWatcher;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(trackingBug = 123769451)
private ArrayList<TextWatcher> mListeners;
// display attributes
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index c1b5aae..191472d 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -59,8 +59,8 @@
sp<MessageQueue> mMessageQueue;
DisplayEventReceiver mReceiver;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
+ void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
+ void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
};
@@ -84,28 +84,30 @@
DisplayEventDispatcher::dispose();
}
-void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) {
+void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
+ uint32_t count) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking vsync handler.", this);
env->CallVoidMethod(receiverObj.get(),
- gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, id, count);
+ gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId, count);
ALOGV("receiver %p ~ Returned from vsync handler.", this);
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
-void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) {
+void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
+ bool connected) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking hotplug handler.", this);
env->CallVoidMethod(receiverObj.get(),
- gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, id, connected);
+ gDisplayEventReceiverClassInfo.dispatchHotplug, timestamp, displayId, connected);
ALOGV("receiver %p ~ Returned from hotplug handler.", this);
}
@@ -175,9 +177,9 @@
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env,
- gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JII)V");
+ gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V");
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
- gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JIZ)V");
+ gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
return res;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index fad2fe0..68be005 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -483,8 +483,29 @@
transaction->setLayerStack(ctrl, layerStack);
}
-static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
- sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
+static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
+ const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
+ jlongArray array = env->NewLongArray(displayIds.size());
+ if (array == nullptr) {
+ jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
+ return nullptr;
+ }
+
+ if (displayIds.empty()) {
+ return array;
+ }
+
+ jlong* values = env->GetLongArrayElements(array, 0);
+ for (size_t i = 0; i < displayIds.size(); ++i) {
+ values[i] = static_cast<jlong>(displayIds[i]);
+ }
+
+ env->ReleaseLongArrayElements(array, values, 0);
+ return array;
+}
+
+static jobject nativeGetPhysicalDisplayToken(JNIEnv* env, jclass clazz, jlong physicalDisplayId) {
+ sp<IBinder> token = SurfaceComposerClient::getPhysicalDisplayToken(physicalDisplayId);
return javaObjectForIBinder(env, token);
}
@@ -1145,8 +1166,10 @@
(void*)nativeSetCornerRadius },
{"nativeSetLayerStack", "(JJI)V",
(void*)nativeSetLayerStack },
- {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
- (void*)nativeGetBuiltInDisplay },
+ {"nativeGetPhysicalDisplayIds", "()[J",
+ (void*)nativeGetPhysicalDisplayIds },
+ {"nativeGetPhysicalDisplayToken", "(J)Landroid/os/IBinder;",
+ (void*)nativeGetPhysicalDisplayToken },
{"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
(void*)nativeCreateDisplay },
{"nativeDestroyDisplay", "(Landroid/os/IBinder;)V",
@@ -1314,4 +1337,4 @@
return err;
}
-};
+} // namespace android
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 2c058cd..8c73630 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -1202,12 +1202,12 @@
static JavaVM* mJvm = nullptr;
-static void attachRenderThreadToJvm() {
+static void attachRenderThreadToJvm(const char* name) {
LOG_ALWAYS_FATAL_IF(!mJvm, "No jvm but we set the hook??");
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_4;
- args.name = NULL;
+ args.name = name;
args.group = NULL;
JNIEnv* env;
mJvm->AttachCurrentThreadAsDaemon(&env, (void*) &args);
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9f4fece..76b589c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1594,7 +1594,7 @@
<integer-array name="config_screenBrighteningThresholds">
<item>100</item>
</integer-array>
-
+
<!-- Array of hysteresis constraint values for darkening, represented as tenths of a
percent. The length of this array is assumed to be one greater than
config_screenThresholdLevels. The darkening threshold is calculated as
@@ -3425,8 +3425,10 @@
<!-- Flag indicates that whether non-system apps can be installed on internal storage. -->
<bool name="config_allow3rdPartyAppOnInternal">true</bool>
- <!-- Package name of the default cell broadcast receiver -->
- <string name="config_defaultCellBroadcastReceiverPkg" translatable="false">com.android.cellbroadcastreceiver</string>
+ <!-- Package names of the default cell broadcast receivers -->
+ <string-array name="config_defaultCellBroadcastReceiverPkgs" translatable="false">
+ <item>com.android.cellbroadcastreceiver</item>
+ </string-array>
<!-- Specifies the path that is used by AdaptiveIconDrawable class to crop launcher icons. -->
<string name="config_icon_mask" translatable="false">"M50,0L92,0C96.42,0 100,4.58 100 8L100,92C100, 96.42 96.42 100 92 100L8 100C4.58, 100 0 96.42 0 92L0 8 C 0 4.42 4.42 0 8 0L50 0Z"</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 401a7fe..1da9149 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3151,7 +3151,7 @@
<java-symbol type="drawable" name="lockscreen_selected" />
<java-symbol type="string" name="notification_header_divider_symbol_with_spaces" />
- <java-symbol type="string" name="config_defaultCellBroadcastReceiverPkg" />
+ <java-symbol type="array" name="config_defaultCellBroadcastReceiverPkgs" />
<java-symbol type="color" name="notification_primary_text_color_light" />
<java-symbol type="color" name="notification_primary_text_color_dark" />
@@ -3595,7 +3595,7 @@
<!-- For Secondary Launcher -->
<java-symbol type="string" name="config_secondaryHomeComponent" />
-
+
<java-symbol type="string" name="dynamic_mode_notification_channel_name" />
<java-symbol type="string" name="dynamic_mode_notification_title" />
<java-symbol type="string" name="dynamic_mode_notification_summary" />
diff --git a/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java b/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java
new file mode 100644
index 0000000..da6ecb4
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/FindViewByIdTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 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.accessibility;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.annotation.UiThreadTest;
+import androidx.test.filters.MediumTest;
+import androidx.test.rule.ActivityTestRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+@MediumTest
+public class FindViewByIdTest {
+
+ @Rule
+ public ActivityTestRule<Activity> mActivityRule = new ActivityTestRule<>(Activity.class);
+
+ private Context getContext() {
+ return InstrumentationRegistry.getTargetContext();
+ }
+
+ private Activity getActivity() {
+ return mActivityRule.getActivity();
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewById() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ child1.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.addView(child1);
+ contentView.addView(child2);
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child2.getAccessibilityViewId());
+ assertEquals(result, child2);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewByIdReturnNullIfRemovedFromHierarchy() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ contentView.addView(child1);
+ contentView.addView(child2);
+ child1.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.removeView(child1);
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child1.getAccessibilityViewId());
+ assertNull(result);
+ }
+
+ @UiThreadTest
+ @Test
+ public void testFindViewByIdReturnNullIfNotImportant() {
+ LinearLayout contentView = new LinearLayout(getContext());
+ getActivity().setContentView(contentView);
+ View child1 = new View(getContext());
+ View child2 = new View(getContext());
+ child2.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+
+ contentView.addView(child1);
+ contentView.addView(child2);
+
+ View result = AccessibilityNodeIdManager.getInstance().findView(
+ child1.getAccessibilityViewId());
+ assertNull(result);
+ }
+}
diff --git a/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
new file mode 100644
index 0000000..f325d89
--- /dev/null
+++ b/core/tests/coretests/src/android/view/contentcapture/ContentCaptureEventTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2019 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.contentcapture;
+
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_FINISHED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_SESSION_STARTED;
+import static android.view.contentcapture.ContentCaptureEvent.TYPE_VIEW_DISAPPEARED;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.os.Parcel;
+import android.os.SystemClock;
+import android.view.autofill.AutofillId;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.ArrayList;
+
+/**
+ * Unit test for {@link ContentCaptureEvent}.
+ *
+ * <p>To run it:
+ * {@code atest FrameworksCoreTests:android.view.contentcapture.ContentCaptureEventTest}
+ */
+@RunWith(JUnit4.class)
+public class ContentCaptureEventTest {
+
+ private static final long MY_EPOCH = SystemClock.uptimeMillis();
+
+ // Not using @Mock because it's final - no need to be fancy here....
+ private final ContentCaptureContext mClientContext = new ContentCaptureContext.Builder()
+ .setAction("WHATEVER").build();
+
+ @Test
+ public void testSetAutofillId_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.setAutofillId(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillIds_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.setAutofillIds(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testAddAutofillId_null() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ assertThrows(NullPointerException.class, () -> event.addAutofillId(null));
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id = new AutofillId(108);
+ event.setAutofillId(id);
+ assertThat(event.getId()).isEqualTo(id);
+ assertThat(event.getIds()).isNull();
+ }
+
+ @Test
+ public void testSetAutofillIds() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id = new AutofillId(108);
+ final ArrayList<AutofillId> ids = new ArrayList<>(1);
+ ids.add(id);
+ event.setAutofillIds(ids);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id);
+ }
+
+ @Test
+ public void testAddAutofillId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ event.addAutofillId(id1);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1);
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testAddAutofillId_afterSetId() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ event.setAutofillId(id1);
+ assertThat(event.getId()).isEqualTo(id1);
+ assertThat(event.getIds()).isNull();
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testAddAutofillId_afterSetIds() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_VIEW_DISAPPEARED);
+
+ final AutofillId id1 = new AutofillId(108);
+ final ArrayList<AutofillId> ids = new ArrayList<>(1);
+ ids.add(id1);
+ event.setAutofillIds(ids);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1);
+
+ final AutofillId id2 = new AutofillId(666);
+ event.addAutofillId(id2);
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).containsExactly(id1, id2).inOrder();
+ }
+
+ @Test
+ public void testSessionStarted_directly() {
+ final ContentCaptureEvent event = newEventForSessionStarted();
+ assertSessionStartedEvent(event);
+ }
+
+ @Test
+ public void testSessionStarted_throughParcel() {
+ final ContentCaptureEvent event = newEventForSessionStarted();
+ final ContentCaptureEvent clone = cloneThroughParcel(event);
+ assertSessionStartedEvent(clone);
+ }
+
+ private ContentCaptureEvent newEventForSessionStarted() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_STARTED)
+ .setClientContext(mClientContext)
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ return event;
+ }
+
+ private void assertSessionStartedEvent(ContentCaptureEvent event) {
+ assertThat(event.getType()).isEqualTo(TYPE_SESSION_STARTED);
+ assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
+ assertThat(event.getSessionId()).isEqualTo("42");
+ assertThat(event.getParentSessionId()).isEqualTo("108");
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ assertThat(event.getText()).isNull();
+ assertThat(event.getViewNode()).isNull();
+ final ContentCaptureContext clientContext = event.getClientContext();
+ assertThat(clientContext.getAction()).isEqualTo("WHATEVER");
+ }
+
+ @Test
+ public void testSessionFinished_directly() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ assertSessionFinishedEvent(event);
+ }
+
+ @Test
+ public void testSessionFinished_throughParcel() {
+ final ContentCaptureEvent event = new ContentCaptureEvent("42", TYPE_SESSION_FINISHED)
+ .setClientContext(mClientContext) // should not be writting to parcel
+ .setParentSessionId("108");
+ assertThat(event).isNotNull();
+ final ContentCaptureEvent clone = cloneThroughParcel(event);
+ assertSessionFinishedEvent(clone);
+ }
+
+ private void assertSessionFinishedEvent(ContentCaptureEvent event) {
+ assertThat(event.getType()).isEqualTo(TYPE_SESSION_FINISHED);
+ assertThat(event.getEventTime()).isAtLeast(MY_EPOCH);
+ assertThat(event.getSessionId()).isEqualTo("42");
+ assertThat(event.getParentSessionId()).isEqualTo("108");
+ assertThat(event.getId()).isNull();
+ assertThat(event.getIds()).isNull();
+ assertThat(event.getText()).isNull();
+ assertThat(event.getViewNode()).isNull();
+ assertThat(event.getClientContext()).isNull();
+ }
+
+ private ContentCaptureEvent cloneThroughParcel(ContentCaptureEvent event) {
+ Parcel parcel = Parcel.obtain();
+
+ try {
+ // Write to parcel
+ parcel.setDataPosition(0); // Sanity / paranoid check
+ event.writeToParcel(parcel, 0);
+
+ // Read from parcel
+ parcel.setDataPosition(0);
+ ContentCaptureEvent clone = ContentCaptureEvent.CREATOR.createFromParcel(parcel);
+ assertThat(clone).isNotNull();
+ return clone;
+ } finally {
+ parcel.recycle();
+ }
+ }
+
+}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 27a51ec..bb04ff3 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -92,7 +92,13 @@
/** The NORMAL style of the default monospace typeface. */
public static final Typeface MONOSPACE;
- @UnsupportedAppUsage
+ /**
+ * The default {@link Typeface}s for different text styles.
+ * Call {@link #defaultFromStyle(int)} to get the default typeface for the given text style.
+ * It shouldn't be changed for app wide typeface settings. Please use theme and font XML for
+ * the same purpose.
+ */
+ @UnsupportedAppUsage(trackingBug = 123769446)
static Typeface[] sDefaults;
/**
diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp
index 7708e43..3b9a348 100644
--- a/libs/androidfw/DisplayEventDispatcher.cpp
+++ b/libs/androidfw/DisplayEventDispatcher.cpp
@@ -68,7 +68,7 @@
// Drain all pending events.
nsecs_t vsyncTimestamp;
- int32_t vsyncDisplayId;
+ PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "",
@@ -101,10 +101,11 @@
// Drain all pending events, keep the last vsync.
nsecs_t vsyncTimestamp;
- int32_t vsyncDisplayId;
+ PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount)) {
- ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", id=%d, count=%d",
+ ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%d",
this, ns2ms(vsyncTimestamp), vsyncDisplayId, vsyncCount);
mWaitingForVsync = false;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount);
@@ -114,7 +115,7 @@
}
bool DisplayEventDispatcher::processPendingEvents(
- nsecs_t* outTimestamp, int32_t* outId, uint32_t* outCount) {
+ nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId, uint32_t* outCount) {
bool gotVsync = false;
DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
ssize_t n;
@@ -128,11 +129,11 @@
// ones. That's fine, we only care about the most recent.
gotVsync = true;
*outTimestamp = ev.header.timestamp;
- *outId = ev.header.id;
+ *outDisplayId = ev.header.displayId;
*outCount = ev.vsync.count;
break;
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
- dispatchHotplug(ev.header.timestamp, ev.header.id, ev.hotplug.connected);
+ dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
break;
default:
ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
index bf35aa3..d2addba 100644
--- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
+++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
@@ -37,10 +37,12 @@
DisplayEventReceiver mReceiver;
bool mWaitingForVsync;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count) = 0;
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected) = 0;
+ virtual void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) = 0;
+ virtual void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId,
+ bool connected) = 0;
virtual int handleEvent(int receiveFd, int events, void* data);
- bool processPendingEvents(nsecs_t* outTimestamp, int32_t* id, uint32_t* outCount);
+ bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
+ uint32_t* outCount);
};
}
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 4c67513..cf5d7ce 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -55,9 +55,12 @@
return sDummyDisplay;
}
+ const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
+ LOG_ALWAYS_FATAL_IF(token == nullptr,
+ "Failed to get display info because internal display is disconnected");
+
DisplayInfo displayInfo;
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &displayInfo);
+ status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
return displayInfo;
}
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 2a48837..76c56609 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -164,14 +164,15 @@
* with reading incorrect data from EGLImage backed SkImage (likely a driver bug).
*/
sk_sp<SkSurface> tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(),
- SkBudgeted::kYes, bitmap->info());
+ SkBudgeted::kYes, bitmap->info(), 0,
+ kTopLeft_GrSurfaceOrigin, nullptr);
// if we can't generate a GPU surface that matches the destination bitmap (e.g. 565) then we
// attempt to do the intermediate rendering step in 8888
if (!tmpSurface.get()) {
SkImageInfo tmpInfo = bitmap->info().makeColorType(SkColorType::kN32_SkColorType);
tmpSurface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
- tmpInfo);
+ tmpInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr);
if (!tmpSurface.get()) {
ALOGW("Unable to generate GPU buffer in a format compatible with the provided bitmap");
return false;
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 1f24f0e..3904ed2 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -329,7 +329,7 @@
bool RenderThread::threadLoop() {
setpriority(PRIO_PROCESS, 0, PRIORITY_DISPLAY);
if (gOnStartHook) {
- gOnStartHook();
+ gOnStartHook("RenderThread");
}
initThreadLocals();
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index d062dba..b182928 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -75,7 +75,7 @@
class DummyVsyncSource;
-typedef void (*JVMAttachHook)();
+typedef void (*JVMAttachHook)(const char* name);
class RenderThread : private ThreadBase {
PREVENT_COPY_AND_ASSIGN(RenderThread);
diff --git a/libs/hwui/tests/common/TestContext.cpp b/libs/hwui/tests/common/TestContext.cpp
index 92b6cbd..0a54aca 100644
--- a/libs/hwui/tests/common/TestContext.cpp
+++ b/libs/hwui/tests/common/TestContext.cpp
@@ -37,11 +37,13 @@
0, // presentationDeadline
};
-DisplayInfo getBuiltInDisplay() {
+DisplayInfo getInternalDisplay() {
#if !HWUI_NULL_GPU
DisplayInfo display;
- sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
- status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display);
+ const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
+ LOG_ALWAYS_FATAL_IF(token == nullptr,
+ "Failed to get display info because internal display is disconnected\n");
+ status_t status = SurfaceComposerClient::getDisplayInfo(token, &display);
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
return display;
#else
diff --git a/libs/hwui/tests/common/TestContext.h b/libs/hwui/tests/common/TestContext.h
index 0996f4d..116d4de 100644
--- a/libs/hwui/tests/common/TestContext.h
+++ b/libs/hwui/tests/common/TestContext.h
@@ -36,7 +36,7 @@
extern DisplayInfo gDisplay;
#define dp(x) ((x)*android::uirenderer::test::gDisplay.density)
-DisplayInfo getBuiltInDisplay();
+DisplayInfo getInternalDisplay();
class TestContext {
public:
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 5fa008b..0e61899e 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -109,7 +109,7 @@
void run(const TestScene::Info& info, const TestScene::Options& opts,
benchmark::BenchmarkReporter* reporter) {
// Switch to the real display
- gDisplay = getBuiltInDisplay();
+ gDisplay = getInternalDisplay();
Properties::forceDrawFrame = true;
TestContext testContext;
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 6493d49..de10ff1 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -87,7 +87,7 @@
setpriority(PRIO_PROCESS, 0, PRIORITY_FOREGROUND);
auto onStartHook = renderthread::RenderThread::getOnStartHook();
if (onStartHook) {
- onStartHook();
+ onStartHook(mName.c_str());
}
return NO_ERROR;
diff --git a/native/android/choreographer.cpp b/native/android/choreographer.cpp
index c3629da..2db575b 100644
--- a/native/android/choreographer.cpp
+++ b/native/android/choreographer.cpp
@@ -24,6 +24,7 @@
#include <android/choreographer.h>
#include <androidfw/DisplayEventDispatcher.h>
#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
#include <utils/Looper.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
@@ -67,8 +68,8 @@
explicit Choreographer(const sp<Looper>& looper);
Choreographer(const Choreographer&) = delete;
- virtual void dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t count);
- virtual void dispatchHotplug(nsecs_t timestamp, int32_t id, bool connected);
+ void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count) override;
+ void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
void scheduleCallbacks();
@@ -139,13 +140,10 @@
}
}
-
-void Choreographer::dispatchVsync(nsecs_t timestamp, int32_t id, uint32_t) {
- if (id != ISurfaceComposer::eDisplayIdMain) {
- ALOGV("choreographer %p ~ ignoring vsync signal for non-main display (id=%d)", this, id);
- scheduleVsync();
- return;
- }
+// TODO(b/74619554): The PhysicalDisplayId is ignored because SF only emits VSYNC events for the
+// internal display and DisplayEventReceiver::requestNextVsync only allows requesting VSYNC for
+// the internal display implicitly.
+void Choreographer::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId, uint32_t) {
std::vector<FrameCallback> callbacks{};
{
AutoMutex _l{mLock};
@@ -160,9 +158,10 @@
}
}
-void Choreographer::dispatchHotplug(nsecs_t, int32_t id, bool connected) {
- ALOGV("choreographer %p ~ received hotplug event (id=%" PRId32 ", connected=%s), ignoring.",
- this, id, toString(connected));
+void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
+ ALOGV("choreographer %p ~ received hotplug event (displayId=%"
+ ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", connected=%s), ignoring.",
+ this, displayId, toString(connected));
}
void Choreographer::handleMessage(const Message& message) {
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 416ef42..7d2934b 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -46,7 +46,13 @@
static bool getWideColorSupport(const sp<SurfaceControl>& surfaceControl) {
sp<SurfaceComposerClient> client = surfaceControl->getClient();
- sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
+
+ const sp<IBinder> display = client->getInternalDisplayToken();
+ if (display == nullptr) {
+ ALOGE("unable to get wide color support for disconnected internal display");
+ return false;
+ }
+
bool isWideColorDisplay = false;
status_t err = client->isWideColorDisplay(display, &isWideColorDisplay);
if (err) {
@@ -58,7 +64,12 @@
static bool getHdrSupport(const sp<SurfaceControl>& surfaceControl) {
sp<SurfaceComposerClient> client = surfaceControl->getClient();
- sp<IBinder> display(client->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
+
+ const sp<IBinder> display = client->getInternalDisplayToken();
+ if (display == nullptr) {
+ ALOGE("unable to get hdr capabilities for disconnected internal display");
+ return false;
+ }
HdrCapabilities hdrCapabilities;
status_t err = client->getHdrCapabilities(display, &hdrCapabilities);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index d6a46a9..6877f5e 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -16,6 +16,10 @@
package com.android.systemui.bubbles;
+import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
+import static android.util.StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -26,17 +30,16 @@
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
-import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Point;
import android.graphics.Rect;
-import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
+import android.util.StatsLog;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -427,11 +430,15 @@
@Nullable
private PendingIntent getValidBubbleIntent(NotificationEntry notif) {
Notification notification = notif.notification.getNotification();
+ String packageName = notif.notification.getPackageName();
Notification.BubbleMetadata data = notif.getBubbleMetadata();
- if (data != null && canLaunchInActivityView(data.getIntent())) {
+ if (data != null && canLaunchInActivityView(data.getIntent(),
+ true /* enable logging for bubbles */, packageName)) {
return data.getIntent();
- } else if (shouldUseContentIntent(mContext)
- && canLaunchInActivityView(notification.contentIntent)) {
+ }
+ if (shouldUseContentIntent(mContext)
+ && canLaunchInActivityView(notification.contentIntent,
+ false /* disable logging for notifications */, packageName)) {
Log.d(TAG, "[addBubble " + notif.key
+ "]: No appOverlayIntent, using contentIntent.");
return notification.contentIntent;
@@ -442,16 +449,41 @@
/**
* Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
+ *
+ * @param intent the pending intent of the bubble.
+ * @param enableLogging whether bubble developer error should be logged.
+ * @param packageName the notification package name for this bubble.
+ * @return
*/
- private boolean canLaunchInActivityView(PendingIntent intent) {
+ private boolean canLaunchInActivityView(PendingIntent intent, boolean enableLogging,
+ String packageName) {
if (intent == null) {
return false;
}
ActivityInfo info =
intent.getIntent().resolveActivityInfo(mContext.getPackageManager(), 0);
- return info != null
- && ActivityInfo.isResizeableMode(info.resizeMode)
- && (info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
+ if (info == null) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING);
+ }
+ return false;
+ }
+ if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE);
+ }
+ return false;
+ }
+ if (info.documentLaunchMode != DOCUMENT_LAUNCH_ALWAYS) {
+ if (enableLogging) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS);
+ }
+ return false;
+ }
+ return (info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 4557b4d..d06feed 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -110,7 +110,8 @@
@Override
public void requestWakeUp() {
PowerManager pm = getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:NODOZE");
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4527f73..66cfadf 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -884,6 +884,7 @@
// Just to make sure, make sure the device is awake.
mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK");
mPendingLock = false;
mPendingReset = false;
@@ -1854,8 +1855,9 @@
// It's possible that the device was unlocked in a dream state. It's time to wake up.
if (mAodShowing) {
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:BOUNCER_DOZING");
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:BOUNCER_DOZING");
}
synchronized (KeyguardViewMediator.this) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 491f310..b820dc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -132,7 +132,8 @@
@Override
public boolean onClickHandler(
View view, PendingIntent pendingIntent, RemoteViews.RemoteResponse response) {
- mShadeController.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view);
+ mShadeController.get().wakeUpIfDozing(SystemClock.uptimeMillis(), view,
+ "NOTIFICATION_CLICK");
if (handleRemoteInput(view, pendingIntent)) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 49f1a8d..b788f53 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -52,7 +52,7 @@
return;
}
- mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v);
+ mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v, "NOTIFICATION_CLICK");
final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
final StatusBarNotification sbn = row.getStatusBarNotification();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 304d2ee..2162ea7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -232,7 +232,8 @@
if (DEBUG_BIO_WAKELOCK) {
Log.i(TAG, "bio wakelock: Authenticated, waking up...");
}
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.policy:BIOMETRIC");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "android.policy:BIOMETRIC");
}
if (delayWakeUp) {
mKeyguardViewMediator.onWakeAndUnlocking();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
index f926218..234a968 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -14,6 +14,7 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.NonNull;
import android.view.View;
import com.android.systemui.statusbar.StatusBarState;
@@ -96,8 +97,9 @@
*
* @param time when to wake up
* @param view the view requesting the wakeup
+ * @param why the reason for the wake up
*/
- void wakeUpIfDozing(long time, View view);
+ void wakeUpIfDozing(long time, View view, @NonNull String why);
/**
* If secure with redaction: Show bouncer, go to unlocked shade.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 3532af5..8a2fc37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -551,7 +551,7 @@
private final View.OnClickListener mGoToLockedShadeListener = v -> {
if (mState == StatusBarState.KEYGUARD) {
- wakeUpIfDozing(SystemClock.uptimeMillis(), v);
+ wakeUpIfDozing(SystemClock.uptimeMillis(), v, "SHADE_CLICK");
goToLockedShade(null);
}
};
@@ -1090,10 +1090,10 @@
}
@Override
- public void wakeUpIfDozing(long time, View where) {
+ public void wakeUpIfDozing(long time, View where, String why) {
if (mDozing) {
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- pm.wakeUp(time, "com.android.systemui:NODOZE");
+ PowerManager pm = mContext.getSystemService(PowerManager.class);
+ pm.wakeUp(time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
where.getLocationInWindow(mTmpInt2);
mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
@@ -3729,7 +3729,8 @@
}
if (!mDeviceInteractive) {
PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:CAMERA_GESTURE");
+ pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
+ "com.android.systemui:CAMERA_GESTURE");
mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
}
vibrateForCameraGesture();
@@ -3890,7 +3891,8 @@
public void pulseWhileDozing(@NonNull PulseCallback callback, int reason) {
mScrimController.setPulseReason(reason);
if (reason == DozeLog.PULSE_REASON_SENSOR_LONG_PRESS) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "com.android.systemui:NODOZE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE,
+ "com.android.systemui:LONG_PRESS");
startAssist(new Bundle());
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 8b25c34..c39e172 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -112,7 +112,7 @@
mTransparentSrcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
mFalsingManager = FalsingManager.getInstance(context);
mDoubleTapHelper = new DoubleTapHelper(this, active -> {}, () -> {
- mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this);
+ mService.wakeUpIfDozing(SystemClock.uptimeMillis(), this, "DOUBLE_TAP");
return true;
}, null, null);
}
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index b8a57ae..1294dbb 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -16,17 +16,13 @@
include $(CLEAR_VARS)
LOCAL_MODULE := frameworks-base-overlays
-
LOCAL_REQUIRED_MODULES := \
- ExperimentNavigationBarFloatingOverlay \
- ExperimentNavigationBarDefaultOverlay \
- ExperimentNavigationBarSlimOverlay32 \
- ExperimentNavigationBarSlimOverlay40 \
- ExperimentNavigationBarLargeOverlay56 \
- ExperimentNavigationBarLargeOverlay64 \
AccentColorBlackOverlay \
AccentColorGreenOverlay \
AccentColorPurpleOverlay \
+ DisplayCutoutEmulationCornerOverlay \
+ DisplayCutoutEmulationDoubleOverlay \
+ DisplayCutoutEmulationTallOverlay \
FontNotoSerifSourceOverlay \
IconPackCircularAndroidOverlay \
IconPackCircularSettingsOverlay \
@@ -42,7 +38,17 @@
IconShapeSquircleOverlay \
IconShapeTeardropOverlay
+include $(BUILD_PHONY_PACKAGE)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := frameworks-base-overlays-debug
+LOCAL_REQUIRED_MODULES := \
+ ExperimentNavigationBarFloatingOverlay \
+ ExperimentNavigationBarDefaultOverlay \
+ ExperimentNavigationBarSlimOverlay32 \
+ ExperimentNavigationBarSlimOverlay40 \
+ ExperimentNavigationBarLargeOverlay56 \
+ ExperimentNavigationBarLargeOverlay64
include $(BUILD_PHONY_PACKAGE)
-
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 8886ee2..1bce11ee 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -180,7 +180,7 @@
mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(),
com.android.internal.R.string.config_defaultAugmentedAutofillService);
mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
- (u, s) -> updateRemoteAugmentedAutofillService());
+ (u, s) -> updateRemoteAugmentedAutofillService(s));
updateLocked(disabled);
}
@@ -1048,8 +1048,12 @@
componentName, mUserId, new RemoteAugmentedAutofillServiceCallbacks() {
@Override
public void onServiceDied(@NonNull RemoteAugmentedAutofillService service) {
- // TODO(b/123100811): properly implement
Slog.w(TAG, "remote augmented autofill service died");
+ final RemoteAugmentedAutofillService remoteService =
+ mRemoteAugmentedAutofillService;
+ if (remoteService != null) {
+ remoteService.destroy();
+ }
}
}, mMaster.isInstantServiceAllowed(), mMaster.verbose);
}
@@ -1060,8 +1064,7 @@
/**
* Called when the {@link #mAugmentedAutofillResolver} changed (among other places).
*/
- private void updateRemoteAugmentedAutofillService() {
- final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId);
+ private void updateRemoteAugmentedAutofillService(@Nullable String serviceName) {
if (serviceName == null) {
if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): time's up!");
if (mRemoteAugmentedAutofillService != null) {
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
index 2f78276..39d5c9d 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerServiceShellCommand.java
@@ -77,6 +77,15 @@
pw.println(" Temporarily (for DURATION ms) changes the service implemtation.");
pw.println(" To reset, call with just the USER_ID argument.");
pw.println("");
+ pw.println("");
+ pw.println(" set default-service-enabled USER_ID [true|false]");
+ pw.println(" Enable / disable the default service for the user.");
+ pw.println("");
+ pw.println("");
+ pw.println(" get default-service-enabled USER_ID");
+ pw.println(" Checks whether the default service is enabled for the user.");
+ pw.println("");
+ pw.println("");
pw.println(" list sessions [--user USER_ID]");
pw.println(" Lists all pending sessions.");
pw.println("");
@@ -91,6 +100,8 @@
switch(what) {
case "bind-instant-service-allowed":
return getBindInstantService(pw);
+ case "default-service-enabled":
+ return getDefaultServiceEnabled(pw);
default:
pw.println("Invalid set: " + what);
return -1;
@@ -105,6 +116,8 @@
return setBindInstantService(pw);
case "temporary-service":
return setTemporaryService(pw);
+ case "default-service-enabled":
+ return setDefaultServiceEnabled();
default:
pw.println("Invalid set: " + what);
return -1;
@@ -149,6 +162,20 @@
return 0;
}
+ private int setDefaultServiceEnabled() {
+ final int userId = getNextIntArgRequired();
+ final boolean enabled = Boolean.parseBoolean(getNextArg());
+ mService.setDefaultServiceEnabled(userId, enabled);
+ return 0;
+ }
+
+ private int getDefaultServiceEnabled(PrintWriter pw) {
+ final int userId = getNextIntArgRequired();
+ final boolean enabled = mService.isDefaultServiceEnabled(userId);
+ pw.println(enabled);
+ return 0;
+ }
+
private int requestDestroy(PrintWriter pw) {
if (!isNextArgSessions(pw)) {
return -1;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 2f1f91e..026430b 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -333,7 +333,8 @@
}
r.delayed = false;
try {
- startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
+ startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true,
+ false);
} catch (TransactionTooLargeException e) {
// Ignore, nobody upstack cares.
}
@@ -643,7 +644,8 @@
SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
}
}
- ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+ ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
+ allowBackgroundActivityStarts);
return cmp;
}
@@ -702,7 +704,8 @@
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
- boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
+ boolean callerFg, boolean addToStarting, boolean allowBackgroundActivityStarts)
+ throws TransactionTooLargeException {
ServiceState stracker = r.getTracker();
if (stracker != null) {
stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
@@ -713,7 +716,8 @@
synchronized (r.stats.getBatteryStats()) {
r.stats.startRunningLocked();
}
- String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
+ String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false,
+ allowBackgroundActivityStarts);
if (error != null) {
return new ComponentName("!!", error);
}
@@ -1645,7 +1649,7 @@
try {
bringUpServiceLocked(serviceRecord,
serviceIntent.getFlags(),
- callerFg, false, false);
+ callerFg, false, false, false);
} catch (RemoteException e) {
/* ignore - local call */
}
@@ -1748,7 +1752,7 @@
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
s.lastActivity = SystemClock.uptimeMillis();
if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
- permissionsReviewRequired) != null) {
+ permissionsReviewRequired, false) != null) {
return 0;
}
}
@@ -2418,7 +2422,8 @@
return;
}
try {
- bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
+ bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false,
+ false);
} catch (TransactionTooLargeException e) {
// Ignore, it's been logged and nothing upstack cares.
}
@@ -2463,8 +2468,8 @@
}
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
- boolean whileRestarting, boolean permissionsReviewRequired)
- throws TransactionTooLargeException {
+ boolean whileRestarting, boolean permissionsReviewRequired,
+ boolean allowBackgroundActivityStarts) throws TransactionTooLargeException {
//Slog.i(TAG, "Bring up service:");
//r.dump(" ");
@@ -2575,6 +2580,13 @@
}
}
+ if (app != null && allowBackgroundActivityStarts) {
+ app.addAllowBackgroundActivityStartsToken(r);
+ // schedule removal of the whitelisting token after the timeout
+ removeAllowBackgroundActivityStartsServiceToken(app, r,
+ SERVICE_BG_ACTIVITY_START_TIMEOUT_MS);
+ }
+
if (r.fgRequired) {
if (DEBUG_FOREGROUND_SERVICE) {
Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d199424..5932f99 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14997,7 +14997,7 @@
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
- false, false, oldRecord.userId);
+ false, false, oldRecord.userId, oldRecord);
} catch (RemoteException e) {
Slog.w(TAG, "Failure ["
+ queue.mQueueName + "] sending broadcast result of "
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index a11ebfd..f0b137a 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -74,6 +74,9 @@
static final int MAX_BROADCAST_SUMMARY_HISTORY
= ActivityManager.isLowRamDeviceStatic() ? 25 : 300;
+ // For how long after a whitelisted receiver's start its process can start a background activity
+ private static final int RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS = 10_000;
+
final ActivityManagerService mService;
/**
@@ -551,13 +554,23 @@
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
- boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
+ boolean ordered, boolean sticky, int sendingUser, BroadcastRecord br)
+ throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
+ if (br.allowBackgroundActivityStarts) {
+ app.addAllowBackgroundActivityStartsToken(br);
+ // schedule removal of the whitelisting token after the timeout
+ mHandler.postDelayed(() -> {
+ if (app != null) {
+ app.removeAllowBackgroundActivityStartsToken(br);
+ }
+ }, RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS);
+ }
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
@@ -783,7 +796,7 @@
} else {
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
- r.resultExtras, r.ordered, r.initialSticky, r.userId);
+ r.resultExtras, r.ordered, r.initialSticky, r.userId, r);
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
@@ -1082,7 +1095,7 @@
}
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
- r.resultData, r.resultExtras, false, false, r.userId);
+ r.resultData, r.resultExtras, false, false, r.userId, r);
// Set this to null so that the reference
// (local and remote) isn't kept in the mBroadcastHistory.
r.resultTo = null;
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 0b27a8a..af56352 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -384,6 +384,9 @@
final boolean allowTrampoline = uid != callingUid
&& controller.mAtmInternal.isUidForeground(callingUid);
+ // note: we on purpose don't pass in the information about the PendingIntent's creator,
+ // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because
+ // it's not unusual for the creator's process to not be alive at this time
switch (key.type) {
case ActivityManager.INTENT_SENDER_ACTIVITY:
try {
diff --git a/services/core/java/com/android/server/display/ColorDisplayService.java b/services/core/java/com/android/server/display/ColorDisplayService.java
index b3a1a06..6a76087 100644
--- a/services/core/java/com/android/server/display/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/ColorDisplayService.java
@@ -115,6 +115,7 @@
private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0;
private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1;
private static final int MSG_APPLY_GLOBAL_SATURATION = 2;
+ private static final int MSG_APPLY_DISPLAY_WHITE_BALANCE = 3;
/**
* Return value if a setting has not been set.
@@ -323,8 +324,7 @@
}
private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
if (displayToken == null) {
return null;
}
@@ -871,7 +871,7 @@
// If disabled, clear the tint. If enabled, do nothing more here and let the next
// temperature update set the correct tint.
if (!activated) {
- applyTint(mDisplayWhiteBalanceTintController, false);
+ mHandler.sendEmptyMessage(MSG_APPLY_DISPLAY_WHITE_BALANCE);
}
}
@@ -1543,7 +1543,7 @@
mDisplayWhiteBalanceTintController.setMatrix(cct);
if (mDisplayWhiteBalanceTintController.isActivated()) {
- applyTint(mDisplayWhiteBalanceTintController, false);
+ mHandler.sendEmptyMessage(MSG_APPLY_DISPLAY_WHITE_BALANCE);
return true;
}
return false;
@@ -1603,6 +1603,9 @@
case MSG_APPLY_NIGHT_DISPLAY_ANIMATED:
applyTint(mNightDisplayTintController, false);
break;
+ case MSG_APPLY_DISPLAY_WHITE_BALANCE:
+ applyTint(mDisplayWhiteBalanceTintController, false);
+ break;
}
}
}
diff --git a/services/core/java/com/android/server/display/ColorFade.java b/services/core/java/com/android/server/display/ColorFade.java
index f2c539c..2f277e4 100644
--- a/services/core/java/com/android/server/display/ColorFade.java
+++ b/services/core/java/com/android/server/display/ColorFade.java
@@ -27,6 +27,7 @@
import android.opengl.EGLSurface;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
+import android.os.IBinder;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -474,8 +475,14 @@
final SurfaceTexture st = new SurfaceTexture(mTexNames[0]);
final Surface s = new Surface(st);
try {
- SurfaceControl.screenshot(SurfaceControl.getBuiltInDisplay(
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s);
+ final IBinder token = SurfaceControl.getInternalDisplayToken();
+ if (token == null) {
+ Slog.e(TAG,
+ "Failed to take screenshot because internal display is disconnected");
+ return false;
+ }
+
+ SurfaceControl.screenshot(token, s);
st.updateTexImage();
st.getTransformMatrix(mTexMatrix);
} finally {
diff --git a/services/core/java/com/android/server/display/DisplayTransformManager.java b/services/core/java/com/android/server/display/DisplayTransformManager.java
index b1b7d3c..ef92401 100644
--- a/services/core/java/com/android/server/display/DisplayTransformManager.java
+++ b/services/core/java/com/android/server/display/DisplayTransformManager.java
@@ -87,7 +87,7 @@
* Map of level -> color transformation matrix.
*/
@GuardedBy("mColorMatrix")
- private final SparseArray<float[]> mColorMatrix = new SparseArray<>(3);
+ private final SparseArray<float[]> mColorMatrix = new SparseArray<>(5);
/**
* Temporary matrix used internally by {@link #computeColorMatrixLocked()}.
*/
@@ -148,6 +148,21 @@
}
/**
+ * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate
+ * various types of color blindness.
+ *
+ * @param mode the new Daltonization mode, or -1 to disable
+ */
+ public void setDaltonizerMode(int mode) {
+ synchronized (mDaltonizerModeLock) {
+ if (mDaltonizerMode != mode) {
+ mDaltonizerMode = mode;
+ applyDaltonizerMode(mode);
+ }
+ }
+ }
+
+ /**
* Returns the composition of all current color matrices, or {@code null} if there are none.
*/
@GuardedBy("mColorMatrix")
@@ -167,30 +182,6 @@
}
/**
- * Returns the current Daltonization mode.
- */
- public int getDaltonizerMode() {
- synchronized (mDaltonizerModeLock) {
- return mDaltonizerMode;
- }
- }
-
- /**
- * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate
- * various types of color blindness.
- *
- * @param mode the new Daltonization mode, or -1 to disable
- */
- public void setDaltonizerMode(int mode) {
- synchronized (mDaltonizerModeLock) {
- if (mDaltonizerMode != mode) {
- mDaltonizerMode = mode;
- applyDaltonizerMode(mode);
- }
- }
- }
-
- /**
* Propagates the provided color transformation matrix to the SurfaceFlinger.
*/
private static void applyColorMatrix(float[] m) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 16d82df..28f21f63 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -17,12 +17,8 @@
package com.android.server.display;
import android.app.ActivityThread;
-import android.content.res.Resources;
-import com.android.server.LocalServices;
-import com.android.server.lights.Light;
-import com.android.server.lights.LightsManager;
-
import android.content.Context;
+import android.content.res.Resources;
import android.hardware.sidekick.SidekickInternal;
import android.os.Build;
import android.os.Handler;
@@ -31,6 +27,7 @@
import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.Trace;
+import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
@@ -38,6 +35,11 @@
import android.view.DisplayEventReceiver;
import android.view.Surface;
import android.view.SurfaceControl;
+
+import com.android.server.LocalServices;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -58,13 +60,9 @@
private static final String PROPERTY_EMULATOR_CIRCULAR = "ro.emulator.circular";
- private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
- SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
- SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
- };
+ private final LongSparseArray<LocalDisplayDevice> mDevices =
+ new LongSparseArray<LocalDisplayDevice>();
- private final SparseArray<LocalDisplayDevice> mDevices =
- new SparseArray<LocalDisplayDevice>();
@SuppressWarnings("unused") // Becomes active at instantiation time.
private HotplugDisplayEventReceiver mHotplugReceiver;
@@ -80,28 +78,26 @@
mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());
- for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
- tryConnectDisplayLocked(builtInDisplayId);
+ for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) {
+ tryConnectDisplayLocked(physicalDisplayId);
}
}
- private void tryConnectDisplayLocked(int builtInDisplayId) {
- IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
+ private void tryConnectDisplayLocked(long physicalDisplayId) {
+ final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
if (displayToken != null) {
SurfaceControl.PhysicalDisplayInfo[] configs =
SurfaceControl.getDisplayConfigs(displayToken);
if (configs == null) {
// There are no valid configs for this device, so we can't use it
- Slog.w(TAG, "No valid configs found for display device " +
- builtInDisplayId);
+ Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
return;
}
int activeConfig = SurfaceControl.getActiveConfig(displayToken);
if (activeConfig < 0) {
// There is no active config, and for now we don't have the
// policy to set one.
- Slog.w(TAG, "No active config found for display device " +
- builtInDisplayId);
+ Slog.w(TAG, "No active config found for display device " + physicalDisplayId);
return;
}
int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
@@ -110,16 +106,17 @@
// configuration pass we'll go ahead and set it to whatever it was set to last (or
// COLOR_MODE_NATIVE if this is the first configuration).
Slog.w(TAG, "Unable to get active color mode for display device " +
- builtInDisplayId);
+ physicalDisplayId);
activeColorMode = Display.COLOR_MODE_INVALID;
}
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
- LocalDisplayDevice device = mDevices.get(builtInDisplayId);
+ LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
- device = new LocalDisplayDevice(displayToken, builtInDisplayId,
- configs, activeConfig, colorModes, activeColorMode);
- mDevices.put(builtInDisplayId, device);
+ final boolean isInternal = mDevices.size() == 0;
+ device = new LocalDisplayDevice(displayToken, physicalDisplayId,
+ configs, activeConfig, colorModes, activeColorMode, isInternal);
+ mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
colorModes, activeColorMode)) {
@@ -133,11 +130,11 @@
}
}
- private void tryDisconnectDisplayLocked(int builtInDisplayId) {
- LocalDisplayDevice device = mDevices.get(builtInDisplayId);
+ private void tryDisconnectDisplayLocked(long physicalDisplayId) {
+ LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device != null) {
// Display was removed.
- mDevices.remove(builtInDisplayId);
+ mDevices.remove(physicalDisplayId);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_REMOVED);
}
}
@@ -158,10 +155,11 @@
}
private final class LocalDisplayDevice extends DisplayDevice {
- private final int mBuiltInDisplayId;
+ private final long mPhysicalDisplayId;
private final Light mBacklight;
private final SparseArray<DisplayModeRecord> mSupportedModes = new SparseArray<>();
private final ArrayList<Integer> mSupportedColorModes = new ArrayList<>();
+ private final boolean mIsInternal;
private DisplayDeviceInfo mInfo;
private boolean mHavePendingChanges;
@@ -179,16 +177,17 @@
private SurfaceControl.PhysicalDisplayInfo mDisplayInfos[];
- public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
+ LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
- int[] colorModes, int activeColorMode) {
- super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
- mBuiltInDisplayId = builtInDisplayId;
+ int[] colorModes, int activeColorMode, boolean isInternal) {
+ super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
+ mPhysicalDisplayId = physicalDisplayId;
+ mIsInternal = isInternal;
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
colorModes, activeColorMode);
updateColorModesLocked(colorModes, activeColorMode);
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
- if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ if (mIsInternal) {
LightsManager lights = LocalServices.getService(LightsManager.class);
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
} else {
@@ -392,7 +391,7 @@
}
final Resources res = getOverlayContext().getResources();
- if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
+ if (mIsInternal) {
mInfo.name = res.getString(
com.android.internal.R.string.display_manager_built_in_display_name);
mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
@@ -455,7 +454,7 @@
final boolean stateChanged = (mState != state);
final boolean brightnessChanged = (mBrightness != brightness) && mBacklight != null;
if (stateChanged || brightnessChanged) {
- final int displayId = mBuiltInDisplayId;
+ final long physicalDisplayId = mPhysicalDisplayId;
final IBinder token = getDisplayTokenLocked();
final int oldState = mState;
@@ -519,7 +518,7 @@
private void setVrMode(boolean isVrEnabled) {
if (DEBUG) {
Slog.d(TAG, "setVrMode("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
}
mBacklight.setVrMode(isVrEnabled);
@@ -528,7 +527,7 @@
private void setDisplayState(int state) {
if (DEBUG) {
Slog.d(TAG, "setDisplayState("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
}
@@ -546,7 +545,7 @@
}
final int mode = getPowerModeForState(state);
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayState("
- + "id=" + displayId
+ + "id=" + physicalDisplayId
+ ", state=" + Display.stateToString(state) + ")");
try {
SurfaceControl.setDisplayPowerMode(token, mode);
@@ -571,11 +570,12 @@
private void setDisplayBrightness(int brightness) {
if (DEBUG) {
Slog.d(TAG, "setDisplayBrightness("
- + "id=" + displayId + ", brightness=" + brightness + ")");
+ + "id=" + physicalDisplayId
+ + ", brightness=" + brightness + ")");
}
Trace.traceBegin(Trace.TRACE_TAG_POWER, "setDisplayBrightness("
- + "id=" + displayId + ", brightness=" + brightness + ")");
+ + "id=" + physicalDisplayId + ", brightness=" + brightness + ")");
try {
mBacklight.setBrightness(brightness);
Trace.traceCounter(Trace.TRACE_TAG_POWER,
@@ -646,7 +646,7 @@
@Override
public void dumpLocked(PrintWriter pw) {
super.dumpLocked(pw);
- pw.println("mBuiltInDisplayId=" + mBuiltInDisplayId);
+ pw.println("mPhysicalDisplayId=" + mPhysicalDisplayId);
pw.println("mActivePhysIndex=" + mActivePhysIndex);
pw.println("mActiveModeId=" + mActiveModeId);
pw.println("mActiveColorMode=" + mActiveColorMode);
@@ -731,12 +731,12 @@
}
@Override
- public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
+ public void onHotplug(long timestampNanos, long physicalDisplayId, boolean connected) {
synchronized (getSyncRoot()) {
if (connected) {
- tryConnectDisplayLocked(builtInDisplayId);
+ tryConnectDisplayLocked(physicalDisplayId);
} else {
- tryDisconnectDisplayLocked(builtInDisplayId);
+ tryDisconnectDisplayLocked(physicalDisplayId);
}
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 7376ed2..072238e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -2412,7 +2412,8 @@
void wakeUp() {
assertRunOnServiceThread();
mWakeUpMessageReceived = true;
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.hdmi:WAKE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_HDMI,
+ "android.server.hdmi:WAKE");
// PowerManger will send the broadcast Intent.ACTION_SCREEN_ON and after this gets
// the intent, the sequence will continue at onWakeUp().
}
@@ -2637,7 +2638,8 @@
playback().sendStandby(0 /* unused */);
}
} else if (isPowerStandbyOrTransient() && !isStandbyModeOn) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.hdmi:WAKE");
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_HDMI,
+ "android.server.hdmi:WAKE");
if (playback() != null) {
oneTouchPlay(new IHdmiControlCallback.Stub() {
@Override
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 532aa01..2bfb31f 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -286,6 +286,46 @@
}
/**
+ * Sets whether the default service should be used.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @throws SecurityException if caller is not allowed to manage this service's settings.
+ */
+ public final void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
+ Slog.i(mTag, "setDefaultServiceEnabled() for userId " + userId + ": " + enabled);
+ enforceCallingPermissionForManagement();
+
+ synchronized (mLock) {
+ final S oldService = peekServiceForUserLocked(userId);
+ if (oldService != null) {
+ oldService.removeSelfFromCacheLocked();
+ }
+ mServiceNameResolver.setDefaultServiceEnabled(userId, enabled);
+
+ // Must update the service on cache so its initialization code is triggered
+ updateCachedServiceLocked(userId);
+ }
+ }
+
+ /**
+ * Checks whether the default service should be used.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @throws SecurityException if caller is not allowed to manage this service's settings.
+ */
+ public final boolean isDefaultServiceEnabled(@UserIdInt int userId) {
+ enforceCallingPermissionForManagement();
+
+ synchronized (mLock) {
+ return mServiceNameResolver.isDefaultServiceEnabled(userId);
+ }
+ }
+
+ /**
* Gets the maximum time the service implementation can be changed.
*
* @throws UnsupportedOperationException if subclass doesn't override it.
diff --git a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
index 7f198ac..cf84e22 100644
--- a/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/FrameworkResourcesServiceNameResolver.java
@@ -27,6 +27,7 @@
import android.text.TextUtils;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.TimeUtils;
import com.android.internal.annotations.GuardedBy;
@@ -61,6 +62,15 @@
private final SparseArray<String> mTemporaryServiceNames = new SparseArray<>();
/**
+ * Map of default services that have been disabled by
+ * {@link #setDefaultServiceEnabled(int, boolean)},keyed by {@code userId}.
+ *
+ * <p>Typically used by Shell command and/or CTS tests.
+ */
+ @GuardedBy("mLock")
+ private final SparseBooleanArray mDefaultServicesDisabled = new SparseBooleanArray();
+
+ /**
* When the temporary service will expire (and reset back to the default).
*/
@GuardedBy("mLock")
@@ -99,12 +109,18 @@
final String temporaryName = mTemporaryServiceNames.get(userId);
if (temporaryName != null) {
// Always log it, as it should only be used on CTS or during development
- Slog.w(TAG, "getComponentName(): using temporary name " + temporaryName
+ Slog.w(TAG, "getServiceName(): using temporary name " + temporaryName
+ " for user " + userId);
return temporaryName;
- } else {
- return getDefaultServiceName(userId);
}
+ final boolean disabled = mDefaultServicesDisabled.get(userId);
+ if (disabled) {
+ // Always log it, as it should only be used on CTS or during development
+ Slog.w(TAG, "getServiceName(): temporary name not set and default disabled for "
+ + "user " + userId);
+ return null;
+ }
+ return getDefaultServiceName(userId);
}
}
@@ -158,6 +174,24 @@
}
@Override
+ public void setDefaultServiceEnabled(int userId, boolean enabled) {
+ synchronized (mLock) {
+ if (enabled) {
+ mDefaultServicesDisabled.removeAt(userId);
+ } else {
+ mDefaultServicesDisabled.put(userId, true);
+ }
+ }
+ }
+
+ @Override
+ public boolean isDefaultServiceEnabled(int userId) {
+ synchronized (mLock) {
+ return mDefaultServicesDisabled.get(userId);
+ }
+ }
+
+ @Override
public String toString() {
return "FrameworkResourcesServiceNamer[temps=" + mTemporaryServiceNames + "]";
}
@@ -168,6 +202,7 @@
synchronized (mLock) {
pw.print("FrameworkResourcesServiceNamer: resId="); pw.print(mResourceId);
pw.print(", numberTemps="); pw.print(mTemporaryServiceNames.size());
+ pw.print(", enabledDefaults="); pw.print(mDefaultServicesDisabled.size());
}
}
@@ -181,7 +216,9 @@
final long ttl = mTemporaryServiceExpiration - SystemClock.elapsedRealtime();
pw.print(" (expires in "); TimeUtils.formatDuration(ttl, pw); pw.print("), ");
}
- pw.print("defaultName="); pw.println(getDefaultServiceName(userId));
+ pw.print("defaultName="); pw.print(getDefaultServiceName(userId));
+ final boolean disabled = mDefaultServicesDisabled.get(userId);
+ pw.println(disabled ? " (disabled)" : " (enabled)");
}
}
diff --git a/services/core/java/com/android/server/infra/ServiceNameResolver.java b/services/core/java/com/android/server/infra/ServiceNameResolver.java
index bc11ff3..5b60413 100644
--- a/services/core/java/com/android/server/infra/ServiceNameResolver.java
+++ b/services/core/java/com/android/server/infra/ServiceNameResolver.java
@@ -108,6 +108,36 @@
}
/**
+ * Sets whether the default service should be used when the temporary service is not set.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @param userId user handle
+ * @param enabled whether the default service should be used when the temporary service is not
+ * set
+ *
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ default void setDefaultServiceEnabled(@UserIdInt int userId, boolean enabled) {
+ throw new UnsupportedOperationException("changing default service not supported");
+ }
+
+ /**
+ * Checks whether the default service should be used when the temporary service is not set.
+ *
+ * <p>Typically used during CTS tests to make sure only the default service doesn't interfere
+ * with the test results.
+ *
+ * @param userId user handle
+ *
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ default boolean isDefaultServiceEnabled(@UserIdInt int userId) {
+ throw new UnsupportedOperationException("checking default service not supported");
+ }
+
+ /**
* Dumps the generic info in just one line (without calling {@code println}.
*/
// TODO(b/117779333): support proto
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0796a9c..b00193f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -148,6 +148,7 @@
import android.os.IDeviceIdleController;
import android.os.Message;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
@@ -189,6 +190,7 @@
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerGlobal;
+import android.view.WindowManagerPolicyConstants;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Animation;
@@ -809,7 +811,7 @@
performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false,
"Wake Up");
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture,
- "android.policy:GESTURE");
+ PowerManager.WAKE_REASON_GESTURE, "android.policy:GESTURE");
}
}
}
@@ -3527,7 +3529,7 @@
if (lidOpen) {
wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch,
- "android.policy:LID");
+ PowerManager.WAKE_REASON_LID, "android.policy:LID");
} else if (!mLidControlsSleep) {
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
@@ -3550,7 +3552,7 @@
intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
}
wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens,
- "android.policy:CAMERA_COVER");
+ PowerManager.WAKE_REASON_CAMERA_LAUNCH, "android.policy:CAMERA_COVER");
startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
}
mCameraLensCoverState = lensCoverState;
@@ -3679,7 +3681,8 @@
if (isValidGlobalKey(keyCode)
&& mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) {
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
+ PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY");
}
return result;
}
@@ -4025,7 +4028,8 @@
}
if (isWakeKey) {
- wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey, "android.policy:KEY");
+ wakeUp(event.getEventTime(), mAllowTheaterModeWakeFromKey,
+ PowerManager.WAKE_REASON_WAKE_KEY, "android.policy:KEY");
}
return result;
@@ -4125,7 +4129,7 @@
public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) {
if ((policyFlags & FLAG_WAKE) != 0) {
if (wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion,
- "android.policy:MOTION")) {
+ PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION")) {
return 0;
}
}
@@ -4139,7 +4143,7 @@
// wake up in this case.
if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotionWhenNotDreaming,
- "android.policy:MOTION");
+ PowerManager.WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
}
return 0;
@@ -4371,7 +4375,10 @@
// Called on the PowerManager's Notifier thread.
@Override
public void startedGoingToSleep(int why) {
- if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Started going to sleep... (why="
+ + WindowManagerPolicyConstants.offReasonToString(why) + ")");
+ }
mGoingToSleep = true;
mRequestedOrGoingToSleep = true;
@@ -4385,7 +4392,10 @@
@Override
public void finishedGoingToSleep(int why) {
EventLog.writeEvent(70000, 0);
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Finished going to sleep... (why="
+ + WindowManagerPolicyConstants.offReasonToString(why) + ")");
+ }
MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000);
mGoingToSleep = false;
@@ -4409,9 +4419,12 @@
// Called on the PowerManager's Notifier thread.
@Override
- public void startedWakingUp() {
+ public void startedWakingUp(@OnReason int why) {
EventLog.writeEvent(70000, 1);
- if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Started waking up... (why="
+ + WindowManagerPolicyConstants.onReasonToString(why) + ")");
+ }
mDefaultDisplayPolicy.setAwake(true);
@@ -4432,8 +4445,11 @@
// Called on the PowerManager's Notifier thread.
@Override
- public void finishedWakingUp() {
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished waking up...");
+ public void finishedWakingUp(@OnReason int why) {
+ if (DEBUG_WAKEUP) {
+ Slog.i(TAG, "Finished waking up... (why="
+ + WindowManagerPolicyConstants.onReasonToString(why) + ")");
+ }
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedWakingUp();
@@ -4441,10 +4457,12 @@
}
private void wakeUpFromPowerKey(long eventTime) {
- wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey, "android.policy:POWER");
+ wakeUp(eventTime, mAllowTheaterModeWakeFromPowerKey,
+ PowerManager.WAKE_REASON_POWER_BUTTON, "android.policy:POWER");
}
- private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, String reason) {
+ private boolean wakeUp(long wakeTime, boolean wakeInTheaterMode, @WakeReason int reason,
+ String details) {
final boolean theaterModeEnabled = isTheaterModeEnabled();
if (!wakeInTheaterMode && theaterModeEnabled) {
return false;
@@ -4455,7 +4473,7 @@
Settings.Global.THEATER_MODE_ON, 0);
}
- mPowerManager.wakeUp(wakeTime, reason);
+ mPowerManager.wakeUp(wakeTime, reason, details);
return true;
}
@@ -4786,7 +4804,7 @@
mKeyguardDelegate.onBootCompleted();
}
}
- startedWakingUp();
+ startedWakingUp(ON_BECAUSE_OF_UNKNOWN);
screenTurningOn(null);
screenTurnedOn();
}
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index e18cd17..d1bd102 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1070,12 +1070,12 @@
/**
* Called when the device has started waking up.
*/
- public void startedWakingUp();
+ void startedWakingUp(@OnReason int reason);
/**
* Called when the device has finished waking up.
*/
- public void finishedWakingUp();
+ void finishedWakingUp(@OnReason int reason);
/**
* Called when the device has started going to sleep.
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index c3f20aa..1a82858 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -36,6 +36,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteException;
@@ -48,6 +49,7 @@
import android.util.EventLog;
import android.util.Slog;
import android.util.StatsLog;
+import android.view.WindowManagerPolicyConstants.OnReason;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
@@ -136,6 +138,7 @@
// broadcasted state over the course of reporting the transition asynchronously.
private boolean mInteractive = true;
private int mInteractiveChangeReason;
+ private long mInteractiveChangeStartTime; // In SystemClock.uptimeMillis()
private boolean mInteractiveChanging;
// The pending interactive state that we will eventually want to broadcast.
@@ -371,7 +374,7 @@
* which case it will assume that the state did not fully converge before the
* next transition began and will recover accordingly.
*/
- public void onWakefulnessChangeStarted(final int wakefulness, int reason) {
+ public void onWakefulnessChangeStarted(final int wakefulness, int reason, long eventTime) {
final boolean interactive = PowerManagerInternal.isInteractive(wakefulness);
if (DEBUG) {
Slog.d(TAG, "onWakefulnessChangeStarted: wakefulness=" + wakefulness
@@ -410,6 +413,7 @@
// Handle early behaviors.
mInteractive = interactive;
mInteractiveChangeReason = reason;
+ mInteractiveChangeStartTime = eventTime;
mInteractiveChanging = true;
handleEarlyInteractiveChange();
}
@@ -440,8 +444,8 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- // Note a SCREEN tron event is logged in PowerManagerService.
- mPolicy.startedWakingUp();
+ final int why = translateOnReason(mInteractiveChangeReason);
+ mPolicy.startedWakingUp(why);
}
});
@@ -470,12 +474,21 @@
*/
private void handleLateInteractiveChange() {
synchronized (mLock) {
+ final int interactiveChangeLatency =
+ (int) (SystemClock.uptimeMillis() - mInteractiveChangeStartTime);
if (mInteractive) {
// Finished waking up...
+ final int why = translateOnReason(mInteractiveChangeReason);
mHandler.post(new Runnable() {
@Override
public void run() {
- mPolicy.finishedWakingUp();
+ LogMaker log = new LogMaker(MetricsEvent.SCREEN);
+ log.setType(MetricsEvent.TYPE_OPEN);
+ log.setSubtype(why);
+ log.setLatency(interactiveChangeLatency);
+ MetricsLogger.action(log);
+ EventLogTags.writePowerScreenState(1, 0, 0, 0, interactiveChangeLatency);
+ mPolicy.finishedWakingUp(why);
}
});
} else {
@@ -499,8 +512,9 @@
LogMaker log = new LogMaker(MetricsEvent.SCREEN);
log.setType(MetricsEvent.TYPE_CLOSE);
log.setSubtype(why);
+ log.setLatency(interactiveChangeLatency);
MetricsLogger.action(log);
- EventLogTags.writePowerScreenState(0, why, 0, 0, 0);
+ EventLogTags.writePowerScreenState(0, why, 0, 0, interactiveChangeLatency);
mPolicy.finishedGoingToSleep(why);
}
});
@@ -524,6 +538,23 @@
}
}
+ private static @OnReason int translateOnReason(@WakeReason int reason) {
+ switch (reason) {
+ case PowerManager.WAKE_REASON_POWER_BUTTON:
+ case PowerManager.WAKE_REASON_PLUGGED_IN:
+ case PowerManager.WAKE_REASON_GESTURE:
+ case PowerManager.WAKE_REASON_CAMERA_LAUNCH:
+ case PowerManager.WAKE_REASON_WAKE_KEY:
+ case PowerManager.WAKE_REASON_WAKE_MOTION:
+ case PowerManager.WAKE_REASON_LID:
+ return WindowManagerPolicy.ON_BECAUSE_OF_USER;
+ case PowerManager.WAKE_REASON_APPLICATION:
+ return WindowManagerPolicy.ON_BECAUSE_OF_APPLICATION;
+ default:
+ return WindowManagerPolicy.ON_BECAUSE_OF_UNKNOWN;
+ }
+ }
+
/**
* Called when screen brightness boost begins or ends.
*/
@@ -565,14 +596,16 @@
/**
* Called when the screen has turned on.
*/
- public void onWakeUp(String reason, int reasonUid, String opPackageName, int opUid) {
+ public void onWakeUp(int reason, String details, int reasonUid, String opPackageName,
+ int opUid) {
if (DEBUG) {
- Slog.d(TAG, "onWakeUp: event=" + reason + ", reasonUid=" + reasonUid
+ Slog.d(TAG, "onWakeUp: reason=" + PowerManager.wakeReasonToString(reason)
+ + ", details=" + details + ", reasonUid=" + reasonUid
+ " opPackageName=" + opPackageName + " opUid=" + opUid);
}
try {
- mBatteryStats.noteWakeUp(reason, reasonUid);
+ mBatteryStats.noteWakeUp(details, reasonUid);
if (opPackageName != null) {
mAppOps.noteOpNoThrow(AppOpsManager.OP_TURN_SCREEN_ON, opUid, opPackageName);
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 3ccd234..af3bff0 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -39,7 +39,6 @@
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.hardware.power.V1_0.PowerHint;
-import android.metrics.LogMaker;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
@@ -52,6 +51,7 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.ServiceType;
+import android.os.PowerManager.WakeReason;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.Process;
@@ -82,8 +82,6 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
@@ -295,6 +293,7 @@
private long mLastSleepTime;
// Last reason the device went to sleep.
+ private @WakeReason int mLastWakeReason;
private int mLastSleepReason;
// Timestamp of the last call to user activity.
@@ -1119,8 +1118,9 @@
opPackageName = wakeLock.mPackageName;
opUid = wakeLock.mOwnerUid;
}
- wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), wakeLock.mTag, opUid,
- opPackageName, opUid);
+ wakeUpNoUpdateLocked(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_APPLICATION, wakeLock.mTag,
+ opUid, opPackageName, opUid);
}
}
@@ -1410,17 +1410,17 @@
}
}
- private void wakeUpInternal(long eventTime, String reason, int uid, String opPackageName,
- int opUid) {
+ private void wakeUpInternal(long eventTime, @WakeReason int reason, String details, int uid,
+ String opPackageName, int opUid) {
synchronized (mLock) {
- if (wakeUpNoUpdateLocked(eventTime, reason, uid, opPackageName, opUid)) {
+ if (wakeUpNoUpdateLocked(eventTime, reason, details, uid, opPackageName, opUid)) {
updatePowerStateLocked();
}
}
}
- private boolean wakeUpNoUpdateLocked(long eventTime, String reason, int reasonUid,
- String opPackageName, int opUid) {
+ private boolean wakeUpNoUpdateLocked(long eventTime, @WakeReason int reason, String details,
+ int reasonUid, String opPackageName, int opUid) {
if (DEBUG_SPEW) {
Slog.d(TAG, "wakeUpNoUpdateLocked: eventTime=" + eventTime + ", uid=" + reasonUid);
}
@@ -1434,25 +1434,18 @@
Trace.traceBegin(Trace.TRACE_TAG_POWER, "wakeUp");
try {
- switch (mWakefulness) {
- case WAKEFULNESS_ASLEEP:
- Slog.i(TAG, "Waking up from sleep (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- case WAKEFULNESS_DREAMING:
- Slog.i(TAG, "Waking up from dream (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- case WAKEFULNESS_DOZING:
- Slog.i(TAG, "Waking up from dozing (uid=" + reasonUid + " reason=" + reason
- + ")...");
- break;
- }
+ Slog.i(TAG, "Waking up from "
+ + PowerManagerInternal.wakefulnessToString(mWakefulness)
+ + " (uid=" + reasonUid
+ + ", reason=" + PowerManager.wakeReasonToString(reason)
+ + ", details=" + details
+ + ")...");
mLastWakeTime = eventTime;
- setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mLastWakeReason = reason;
+ setWakefulnessLocked(WAKEFULNESS_AWAKE, reason, eventTime);
- mNotifier.onWakeUp(reason, reasonUid, opPackageName, opUid);
+ mNotifier.onWakeUp(reason, details, reasonUid, opPackageName, opUid);
userActivityNoUpdateLocked(
eventTime, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, reasonUid);
} finally {
@@ -1520,7 +1513,7 @@
mLastSleepTime = eventTime;
mLastSleepReason = reason;
mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DOZING, reason);
+ setWakefulnessLocked(WAKEFULNESS_DOZING, reason, eventTime);
// Report the number of wake locks that will be cleared by going to sleep.
int numWakeLocksCleared = 0;
@@ -1570,7 +1563,7 @@
Slog.i(TAG, "Nap time (uid " + uid +")...");
mSandmanSummoned = true;
- setWakefulnessLocked(WAKEFULNESS_DREAMING, 0);
+ setWakefulnessLocked(WAKEFULNESS_DREAMING, 0, eventTime);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -1593,7 +1586,8 @@
try {
Slog.i(TAG, "Sleeping (uid " + uid +")...");
- setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+ setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+ eventTime);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_POWER);
}
@@ -1601,13 +1595,13 @@
}
@VisibleForTesting
- void setWakefulnessLocked(int wakefulness, int reason) {
+ void setWakefulnessLocked(int wakefulness, int reason, long eventTime) {
if (mWakefulness != wakefulness) {
mWakefulness = wakefulness;
mWakefulnessChanging = true;
mDirty |= DIRTY_WAKEFULNESS;
if (mNotifier != null) {
- mNotifier.onWakefulnessChangeStarted(wakefulness, reason);
+ mNotifier.onWakefulnessChangeStarted(wakefulness, reason, eventTime);
}
mAttentionDetector.onWakefulnessChangeStarted(wakefulness);
}
@@ -1631,23 +1625,6 @@
}
}
- private void logScreenOn() {
- Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
-
- final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
-
- LogMaker log = new LogMaker(MetricsEvent.SCREEN);
- log.setType(MetricsEvent.TYPE_OPEN);
- log.setSubtype(0); // not user initiated
- log.setLatency(latencyMs); // How long it took.
- MetricsLogger.action(log);
- EventLogTags.writePowerScreenState(1, 0, 0, 0, latencyMs);
-
- if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
- Slog.w(TAG, "Screen on took " + latencyMs+ " ms");
- }
- }
-
private void finishWakefulnessChangeIfNeededLocked() {
if (mWakefulnessChanging && mDisplayReady) {
if (mWakefulness == WAKEFULNESS_DOZING
@@ -1658,7 +1635,11 @@
logSleepTimeoutRecapturedLocked();
}
if (mWakefulness == WAKEFULNESS_AWAKE) {
- logScreenOn();
+ Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, 0);
+ final int latencyMs = (int) (SystemClock.uptimeMillis() - mLastWakeTime);
+ if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
+ Slog.w(TAG, "Screen on took " + latencyMs + " ms");
+ }
}
mWakefulnessChanging = false;
mNotifier.onWakefulnessChangeFinished();
@@ -1786,7 +1767,8 @@
final long now = SystemClock.uptimeMillis();
if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
dockedOnWirelessCharger)) {
- wakeUpNoUpdateLocked(now, "android.server.power:POWER", Process.SYSTEM_UID,
+ wakeUpNoUpdateLocked(now, PowerManager.WAKE_REASON_PLUGGED_IN,
+ "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
mContext.getOpPackageName(), Process.SYSTEM_UID);
}
userActivityNoUpdateLocked(
@@ -2369,8 +2351,10 @@
PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, 0, Process.SYSTEM_UID);
updatePowerStateLocked();
} else {
- wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), "android.server.power:DREAM",
- Process.SYSTEM_UID, mContext.getOpPackageName(), Process.SYSTEM_UID);
+ wakeUpNoUpdateLocked(SystemClock.uptimeMillis(),
+ PowerManager.WAKE_REASON_UNKNOWN,
+ "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
+ mContext.getOpPackageName(), Process.SYSTEM_UID);
updatePowerStateLocked();
}
} else if (wakefulness == WAKEFULNESS_DOZING) {
@@ -4375,7 +4359,8 @@
}
@Override // Binder call
- public void wakeUp(long eventTime, String reason, String opPackageName) {
+ public void wakeUp(long eventTime, @WakeReason int reason, String details,
+ String opPackageName) {
if (eventTime > SystemClock.uptimeMillis()) {
throw new IllegalArgumentException("event time must not be in the future");
}
@@ -4386,7 +4371,7 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
- wakeUpInternal(eventTime, reason, uid, opPackageName, uid);
+ wakeUpInternal(eventTime, reason, details, uid, opPackageName, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
index bd46a50..fac95f9 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverPolicy.java
@@ -665,8 +665,7 @@
config.getEnableAdjustBrightness(),
config.getEnableDataSaver(),
config.getEnableFirewall(),
- // TODO: add option to config
- config.getAdvertiseIsEnabled(),
+ config.getEnableNightMode(),
config.getEnableQuickDoze(),
/* filesForInteractive */
(new CpuFrequencies()).parseString(cpuFreqInteractive).toSysFileMap(),
@@ -674,7 +673,7 @@
(new CpuFrequencies()).parseString(cpuFreqNoninteractive).toSysFileMap(),
config.getForceAllAppsStandby(),
config.getForceBackgroundCheck(),
- config.getGpsMode()
+ config.getLocationMode()
);
}
diff --git a/services/core/java/com/android/server/role/RemoteRoleControllerService.java b/services/core/java/com/android/server/role/RemoteRoleControllerService.java
index 107cb2c..4fb40db 100644
--- a/services/core/java/com/android/server/role/RemoteRoleControllerService.java
+++ b/services/core/java/com/android/server/role/RemoteRoleControllerService.java
@@ -21,6 +21,7 @@
import android.annotation.UserIdInt;
import android.annotation.WorkerThread;
import android.app.role.IRoleManagerCallback;
+import android.app.role.RoleManager;
import android.app.role.RoleManagerCallback;
import android.content.ComponentName;
import android.content.Context;
@@ -61,34 +62,35 @@
* Add a specific application to the holders of a role. If the role is exclusive, the previous
* holder will be replaced.
*
- * @see RoleControllerService#onAddRoleHolder(String, String, RoleManagerCallback)
+ * @see RoleControllerService#onAddRoleHolder(String, String, int, RoleManagerCallback)
*/
public void onAddRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onAddRoleHolder(roleName, packageName, callbackDelegate), callback));
+ service.onAddRoleHolder(roleName, packageName, flags, callbackDelegate), callback));
}
/**
* Remove a specific application from the holders of a role.
*
- * @see RoleControllerService#onRemoveRoleHolder(String, String, RoleManagerCallback)
+ * @see RoleControllerService#onRemoveRoleHolder(String, String, int, RoleManagerCallback)
*/
public void onRemoveRoleHolder(@NonNull String roleName, @NonNull String packageName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onRemoveRoleHolder(roleName, packageName, callbackDelegate), callback));
+ service.onRemoveRoleHolder(roleName, packageName, flags, callbackDelegate),
+ callback));
}
/**
* Remove all holders of a role.
*
- * @see RoleControllerService#onClearRoleHolders(String, RoleManagerCallback)
+ * @see RoleControllerService#onClearRoleHolders(String, int, RoleManagerCallback)
*/
public void onClearRoleHolders(@NonNull String roleName,
- @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @NonNull IRoleManagerCallback callback) {
mConnection.enqueueCall(new Connection.Call((service, callbackDelegate) ->
- service.onClearRoleHolders(roleName, callbackDelegate), callback));
+ service.onClearRoleHolders(roleName, flags, callbackDelegate), callback));
}
/**
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 84305be..21bf9de 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -201,10 +201,15 @@
new ContentObserver(getContext().getMainThreadHandler()) {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
- getOrCreateControllerService(userId).onSmsKillSwitchToggled(
- Settings.Global.getInt(
- getContext().getContentResolver(),
- Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1);
+ boolean killSwitchEnabled = Settings.Global.getInt(
+ getContext().getContentResolver(),
+ Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1;
+ for (int user : mUserManagerInternal.getUserIds()) {
+ if (mUserManagerInternal.isUserRunning(user)) {
+ getOrCreateControllerService(user)
+ .onSmsKillSwitchToggled(killSwitchEnabled);
+ }
+ }
}
}, UserHandle.USER_ALL);
}
@@ -450,7 +455,8 @@
@Override
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @UserIdInt int userId, @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
+ @NonNull IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -462,12 +468,14 @@
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"addRoleHolderAsUser");
- getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, callback);
+ getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, flags,
+ callback);
}
@Override
public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
- @UserIdInt int userId, @NonNull IRoleManagerCallback callback) {
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
+ @NonNull IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -479,12 +487,13 @@
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"removeRoleHolderAsUser");
- getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName,
+ getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName, flags,
callback);
}
@Override
- public void clearRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId,
+ public void clearRoleHoldersAsUser(@NonNull String roleName,
+ @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
@NonNull IRoleManagerCallback callback) {
Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
Preconditions.checkNotNull(callback, "callback cannot be null");
@@ -496,7 +505,7 @@
getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
"clearRoleHoldersAsUser");
- getOrCreateControllerService(userId).onClearRoleHolders(roleName, callback);
+ getOrCreateControllerService(userId).onClearRoleHolders(roleName, flags, callback);
}
@Override
@@ -718,9 +727,9 @@
};
if (packageName != null) {
getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
- packageName, callback);
+ packageName, 0, callback);
} else {
- getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER,
+ getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
callback);
}
try {
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index b245e98..00021d7 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -98,13 +98,22 @@
return userId;
}
+ private int getFlagsMaybe() {
+ String flags = getNextArg();
+ if (flags == null) {
+ return 0;
+ }
+ return Integer.parseInt(flags);
+ }
+
private int runAddRoleHolder() throws RemoteException {
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
String packageName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.addRoleHolderAsUser(roleName, packageName, userId, callback);
+ mRoleManager.addRoleHolderAsUser(roleName, packageName, flags, userId, callback);
return callback.waitForResult();
}
@@ -112,18 +121,20 @@
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
String packageName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.removeRoleHolderAsUser(roleName, packageName, userId, callback);
+ mRoleManager.removeRoleHolderAsUser(roleName, packageName, flags, userId, callback);
return callback.waitForResult();
}
private int runClearRoleHolders() throws RemoteException {
int userId = getUserIdMaybe();
String roleName = getNextArgRequired();
+ int flags = getFlagsMaybe();
Callback callback = new Callback();
- mRoleManager.clearRoleHoldersAsUser(roleName, userId, callback);
+ mRoleManager.clearRoleHoldersAsUser(roleName, flags, userId, callback);
return callback.waitForResult();
}
@@ -134,9 +145,9 @@
pw.println(" help");
pw.println(" Print this help text.");
pw.println();
- pw.println(" add-role-holder [--user USER_ID] ROLE PACKAGE");
- pw.println(" remove-role-holder [--user USER_ID] ROLE PACKAGE");
- pw.println(" clear-role-holders [--user USER_ID] ROLE");
+ pw.println(" add-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]");
+ pw.println(" remove-role-holder [--user USER_ID] ROLE PACKAGE [FLAGS]");
+ pw.println(" clear-role-holders [--user USER_ID] ROLE [FLAGS]");
pw.println();
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index c0fe6e9..0a3c2fb 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -97,7 +97,6 @@
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.ResumeActivityItem;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -467,7 +466,7 @@
* initialized. So we initialize our wakelocks afterwards.
*/
void initPowerManagement() {
- mPowerManager = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
+ mPowerManager = mService.mContext.getSystemService(PowerManager.class);
mGoingToSleep = mPowerManager
.newWakeLock(PARTIAL_WAKE_LOCK, "ActivityManager-Sleep");
mLaunchingActivity = mPowerManager.newWakeLock(PARTIAL_WAKE_LOCK, "*launch*");
@@ -2456,7 +2455,8 @@
}
void wakeUp(String reason) {
- mPowerManager.wakeUp(SystemClock.uptimeMillis(), "android.server.am:TURN_ON:" + reason);
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_APPLICATION,
+ "android.server.am:TURN_ON:" + reason);
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 1d71d876..678a896 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -753,8 +753,8 @@
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"shouldAbortBackgroundActivityStart");
abortBackgroundStart = shouldAbortBackgroundActivityStart(callingUid, callingPid,
- callingPackage, realCallingUid, callerApp, originatingPendingIntent,
- allowBackgroundActivityStart, intent);
+ callingPackage, realCallingUid, realCallingPid, callerApp,
+ originatingPendingIntent, allowBackgroundActivityStart, intent);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -914,22 +914,14 @@
}
private boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
- final String callingPackage, int realCallingUid, WindowProcessController callerApp,
- PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart,
- Intent intent) {
+ final String callingPackage, int realCallingUid, int realCallingPid,
+ WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
+ boolean allowBackgroundActivityStart, Intent intent) {
// don't abort for the most important UIDs
if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID
|| callingUid == Process.NFC_UID) {
return false;
}
- // don't abort if the callerApp has any visible activity
- if (callerApp != null && callerApp.hasForegroundActivities()) {
- return false;
- }
- // don't abort if the callerApp is instrumenting with background activity starts privileges
- if (callerApp != null && callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
- return false;
- }
// don't abort if the callingUid is in the foreground or is a persistent system process
final int callingUidProcState = mService.getUidStateLocked(callingUid);
final boolean callingUidHasAnyVisibleWindow =
@@ -967,9 +959,26 @@
return false;
}
}
- // don't abort if the caller is currently temporarily whitelisted
- if (callerApp != null && callerApp.areBackgroundActivityStartsAllowed()) {
- return false;
+ // If we don't have callerApp at this point, no caller was provided to startActivity().
+ // That's the case for PendingIntent-based starts, since the creator's process might not be
+ // up and alive. If that's the case, we retrieve the WindowProcessController for the send()
+ // caller, so that we can make the decision based on its foreground/whitelisted state.
+ if (callerApp == null) {
+ callerApp = mService.getProcessController(realCallingPid, realCallingUid);
+ }
+ if (callerApp != null) {
+ // don't abort if the callerApp has any visible activity
+ if (callerApp.hasForegroundActivities()) {
+ return false;
+ }
+ // don't abort if the callerApp is instrumenting with background activity starts privs
+ if (callerApp.isInstrumentingWithBackgroundActivityStartPrivileges()) {
+ return false;
+ }
+ // don't abort if the caller is currently temporarily whitelisted
+ if (callerApp.areBackgroundActivityStartsAllowed()) {
+ return false;
+ }
}
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
@@ -996,6 +1005,7 @@
+ "; originatingPendingIntent: " + originatingPendingIntent
+ "; isBgStartWhitelisted: " + allowBackgroundActivityStart
+ "; intent: " + intent
+ + "; callerApp: " + callerApp
+ "]");
// log aborted activity start to TRON
if (mService.isActivityStartsLoggingEnabled()) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index b6bac613..7aa3481 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -5666,6 +5666,20 @@
return null;
}
+ WindowProcessController getProcessController(int pid, int uid) {
+ final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
+ for (int i = pmap.size()-1; i >= 0; i--) {
+ final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
+ for (int j = procs.size() - 1; j >= 0; j--) {
+ final WindowProcessController proc = procs.valueAt(j);
+ if (UserHandle.isApp(uid) && proc.getPid() == pid && proc.mUid == uid) {
+ return proc;
+ }
+ }
+ }
+ return null;
+ }
+
int getUidStateLocked(int uid) {
return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 18df88b..7a8fd49 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -33,14 +33,11 @@
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.InsetsState.TYPE_IME;
-import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
-import static android.view.InsetsState.TYPE_TOP_BAR;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_180;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import static android.view.View.GONE;
-import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_TOP;
@@ -175,7 +172,6 @@
import android.view.SurfaceControl.Transaction;
import android.view.SurfaceSession;
import android.view.View;
-import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants.PointerEventListener;
@@ -1162,14 +1158,12 @@
@Override
boolean onDescendantOrientationChanged(IBinder freezeDisplayToken,
ConfigurationContainer requestingContainer) {
- final int previousRotation = mRotation;
final Configuration config = updateOrientationFromAppTokens(
getRequestedOverrideConfiguration(), freezeDisplayToken, false);
- // This event is considered handled iff a configuration propagation is triggered, because
- // that's the only place lower level containers check if they need to do something to this
- // request. The only guaranteed signal is that the display is rotated to a different
- // orientation (i.e. rotating 180 degrees doesn't count).
- final boolean handled = (mRotation - previousRotation) % 2 != 0;
+ // If display rotation class tells us that it doesn't consider app requested orientation,
+ // this display won't rotate just because of an app changes its requested orientation. Thus
+ // it indicates that this display chooses not to handle this request.
+ final boolean handled = getDisplayRotation().respectAppRequestedOrientation();
if (config == null) {
return handled;
}
@@ -1191,6 +1185,11 @@
return handled;
}
+ @Override
+ boolean handlesOrientationChangeFromDescendant() {
+ return getDisplayRotation().respectAppRequestedOrientation();
+ }
+
/**
* Determine the new desired orientation of this display.
*
@@ -1371,8 +1370,7 @@
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
+ " selected orientation " + lastOrientation
- + ", got rotation " + rotation + " which has "
- + " metrics");
+ + ", got rotation " + rotation);
if (oldRotation == rotation) {
// No change.
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bc165dc..5f341ee 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -329,6 +329,15 @@
return mFixedToUserRotation;
}
+ /**
+ * Returns {@code true} if this display rotation takes app requested orientation into
+ * consideration; {@code false} otherwise. For the time being the only case where this is {@code
+ * false} is when {@link #isFixedToUserRotation()} is {@code true}.
+ */
+ boolean respectAppRequestedOrientation() {
+ return !mFixedToUserRotation;
+ }
+
public int getLandscapeRotation() {
return mLandscapeRotation;
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index af38c06..69f0012 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -2197,11 +2197,15 @@
// In FULLSCREEN mode, always start with empty bounds to indicate "fill parent"
outOverrideBounds.setEmpty();
+ final boolean parentHandlesOrientationChange = mTask != null
+ && mTask.getParent() != null
+ && mTask.getParent().handlesOrientationChangeFromDescendant();
// If the task or its top activity requires a different orientation, make it fit the
// available bounds by scaling down its bounds.
int forcedOrientation = getTopActivityRequestedOrientation();
if (forcedOrientation != ORIENTATION_UNDEFINED
- && forcedOrientation != newParentConfig.orientation) {
+ && forcedOrientation != newParentConfig.orientation
+ && !parentHandlesOrientationChange) {
final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
final int parentWidth = parentBounds.width();
final int parentHeight = parentBounds.height();
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index b246da4..a054148 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -715,6 +715,21 @@
}
/**
+ * Check if this container or its parent will handle orientation changes from descendants. It's
+ * different from the return value of {@link #onDescendantOrientationChanged(IBinder,
+ * ConfigurationContainer)} in the sense that the return value of this method tells if this
+ * container or its parent will handle the request eventually, while the return value of the
+ * other method is if it handled the request synchronously.
+ *
+ * @return {@code true} if it handles or will handle orientation change in the future; {@code
+ * false} if it won't handle the change at anytime.
+ */
+ boolean handlesOrientationChangeFromDescendant() {
+ final WindowContainer parent = getParent();
+ return parent != null && parent.handlesOrientationChangeFromDescendant();
+ }
+
+ /**
* Calls {@link #setOrientation(int, IBinder, ActivityRecord)} with {@code null} to the last 2
* parameters.
*
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 0fb900a..465f413 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -986,7 +986,7 @@
@Override
public String toString() {
- return mOwner.toString();
+ return mOwner != null ? mOwner.toString() : null;
}
public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4bc1400..85b251a 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -156,6 +156,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.os.PowerManager;
+import android.os.PowerManager.WakeReason;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -611,7 +612,7 @@
}
interface PowerManagerWrapper {
- void wakeUp(long time, String reason);
+ void wakeUp(long time, @WakeReason int reason, String details);
boolean isInteractive();
@@ -623,8 +624,8 @@
this(service, s, c, token, parentWindow, appOp, seq, a, viewVisibility, ownerId,
ownerCanAddInternalSystemWindow, new PowerManagerWrapper() {
@Override
- public void wakeUp(long time, String reason) {
- service.mPowerManager.wakeUp(time, reason);
+ public void wakeUp(long time, @WakeReason int reason, String details) {
+ service.mPowerManager.wakeUp(time, reason, details);
}
@Override
@@ -2253,7 +2254,7 @@
Slog.v(TAG, "Relayout window turning screen on: " + this);
}
mPowerManagerWrapper.wakeUp(SystemClock.uptimeMillis(),
- "android.server.wm:TURN_ON");
+ PowerManager.WAKE_REASON_APPLICATION, "android.server.wm:SCREEN_ON_FLAG");
}
if (mAppToken != null) {
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index bfa0b74..63341b6 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -150,7 +150,7 @@
@SmallTest
public void testGetDesiredScreenPolicy_WithVR() throws Exception {
// Brighten up the screen
- mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_BRIGHT);
@@ -160,12 +160,13 @@
DisplayPowerRequest.POLICY_VR);
// Then take a nap
- mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_ASLEEP, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
+ 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_OFF);
// Wake up to VR
- mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, 0);
+ mService.setWakefulnessLocked(WAKEFULNESS_AWAKE, PowerManager.WAKE_REASON_UNKNOWN, 0);
assertThat(mService.getDesiredScreenPolicyLocked()).isEqualTo(
DisplayPowerRequest.POLICY_VR);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index ee22861..2de4ae0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -57,7 +57,6 @@
*/
@SmallTest
@Presubmit
-@FlakyTest(detail="promote once confirmed non-flaky")
public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
private ActivityMetricsLogger mActivityMetricsLogger;
private ActivityMetricsLaunchObserver mLaunchObserver;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
index 3bf884f..defe981 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java
@@ -42,7 +42,6 @@
* Build/Install/Run:
* atest WmTests:AppChangeTransitionTests
*/
-@FlakyTest(detail = "Promote when shown to be stable.")
@SmallTest
public class AppChangeTransitionTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index f399463..3826fac 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -59,7 +59,6 @@
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.view.DisplayCutout;
-import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
@@ -585,17 +584,15 @@
@Test
public void testOnDescendantOrientationRequestChanged() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1080;
- info.logicalHeight = 1920;
- info.logicalDensityDpi = 240;
- final DisplayContent dc = createNewDisplay(info);
- dc.configureDisplayPolicy();
+ final DisplayContent dc = createNewDisplay();
mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
+ final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
+ ? SCREEN_ORIENTATION_PORTRAIT
+ : SCREEN_ORIENTATION_LANDSCAPE;
final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
- window.mAppToken.mOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+ window.mAppToken.setOrientation(newOrientation);
ActivityRecord activityRecord = mock(ActivityRecord.class);
@@ -606,22 +603,21 @@
verify(mWm.mAtmService).updateDisplayOverrideConfigurationLocked(captor.capture(),
same(activityRecord), anyBoolean(), eq(dc.getDisplayId()));
final Configuration newDisplayConfig = captor.getValue();
- assertEquals(Configuration.ORIENTATION_LANDSCAPE, newDisplayConfig.orientation);
+ assertEquals(Configuration.ORIENTATION_PORTRAIT, newDisplayConfig.orientation);
}
@Test
public void testOnDescendantOrientationRequestChanged_FrozenToUserRotation() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1080;
- info.logicalHeight = 1920;
- info.logicalDensityDpi = 240;
- final DisplayContent dc = createNewDisplay(info);
+ final DisplayContent dc = createNewDisplay();
dc.getDisplayRotation().setFixedToUserRotation(true);
mWm.mAtmService.mRootActivityContainer = mock(RootActivityContainer.class);
+ final int newOrientation = dc.getLastOrientation() == SCREEN_ORIENTATION_LANDSCAPE
+ ? SCREEN_ORIENTATION_PORTRAIT
+ : SCREEN_ORIENTATION_LANDSCAPE;
final WindowState window = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
window.getTask().mTaskRecord = mock(TaskRecord.class, ExtendedMockito.RETURNS_DEEP_STUBS);
- window.mAppToken.mOrientation = SCREEN_ORIENTATION_LANDSCAPE;
+ window.mAppToken.setOrientation(newOrientation);
ActivityRecord activityRecord = mock(ActivityRecord.class);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
index d05711e..198e7ce 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationTests.java
@@ -33,6 +33,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.content.ContentResolver;
@@ -611,6 +612,23 @@
// ========================
// Non-rotation API Tests
// ========================
+ @Test
+ public void testRespectsAppRequestedOrientationByDefault() throws Exception {
+ mBuilder.build();
+
+ assertTrue("Display rotation should respect app requested orientation by"
+ + " default.", mTarget.respectAppRequestedOrientation());
+ }
+
+ @Test
+ public void testNotRespectAppRequestedOrientation_FixedToUserRotation() throws Exception {
+ mBuilder.build();
+ mTarget.setFixedToUserRotation(true);
+
+ assertFalse("Display rotation shouldn't respect app requested orientation if"
+ + " fixed to user rotation.", mTarget.respectAppRequestedOrientation());
+ }
+
/**
* Call {@link DisplayRotation#configure(int, int, int, int)} to configure {@link #mTarget}
* according to given parameters.
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index a498a1a..0c363de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -39,7 +39,6 @@
import org.junit.Test;
@SmallTest
-@FlakyTest(detail = "Promote once confirmed non-flaky")
@Presubmit
public class InsetsSourceProviderTest extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
index beaac8e..86bf3db 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PendingRemoteAnimationRegistryTest.java
@@ -40,7 +40,6 @@
* atest WmTests:PendingRemoteAnimationRegistryTest
*/
@SmallTest
-@FlakyTest
@Presubmit
public class PendingRemoteAnimationRegistryTest extends ActivityTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index 434ba93..c3d2f33 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -47,7 +47,6 @@
* atest WmTests:PersisterQueueTests
*/
@MediumTest
-@FlakyTest(detail = "Confirm stable in post-submit before removing")
@Presubmit
public class PersisterQueueTests implements PersisterQueue.Listener {
private static final long INTER_WRITE_DELAY_MS = 50;
diff --git a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
index 530fd6d..dad6c95 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SafeActivityOptionsTest.java
@@ -31,7 +31,6 @@
* atest WmTests:SafeActivityOptionsTest
*/
@MediumTest
-@FlakyTest
@Presubmit
public class SafeActivityOptionsTest {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 9b84215..edb395a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -179,7 +179,6 @@
}
@Test
- @FlakyTest(detail = "Promote once confirmed non-flaky")
public void testDeferFinish() {
// Start animation
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
index df7bc11..12ed3c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskPersisterTest.java
@@ -41,7 +41,6 @@
* Build/Install/Run:
* atest WmTests:TaskPersisterTest
*/
-@FlakyTest(detail = "Promote to presubmit if stable")
@Presubmit
public class TaskPersisterTest {
private static final String TEST_USER_NAME = "AM-Test-User";
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index e182c45..bcf9dd2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -25,13 +25,6 @@
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doCallRealMethod;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.hamcrest.Matchers.not;
@@ -41,6 +34,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -53,7 +47,6 @@
import android.service.voice.IVoiceInteractionSession;
import android.util.Xml;
import android.view.DisplayInfo;
-import android.view.Surface;
import androidx.test.filters.MediumTest;
@@ -62,6 +55,7 @@
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -284,48 +278,33 @@
}
@Test
- public void testUpdatesForcedOrientationInBackground() {
- final DisplayInfo info = new DisplayInfo();
- info.logicalWidth = 1920;
- info.logicalHeight = 1080;
- final ActivityDisplay display = addNewActivityDisplayAt(info, POSITION_TOP);
- doCallRealMethod().when(display.mDisplayContent).setDisplayRotation(any());
- display.mDisplayContent.setDisplayRotation(mock(DisplayRotation.class));
- doCallRealMethod().when(display.mDisplayContent).onDescendantOrientationChanged(any(),
- any());
- doCallRealMethod().when(display.mDisplayContent).setRotation(anyInt());
- doAnswer(invocation -> {
- display.mDisplayContent.setRotation(Surface.ROTATION_0);
- return null;
- }).when(display.mDisplayContent).updateOrientationFromAppTokens(any(), any(), anyBoolean());
+ public void testIgnoresForcedOrientationWhenParentHandles() {
+ final Rect fullScreenBounds = new Rect(0, 0, 1920, 1080);
+ DisplayInfo info = new DisplayInfo();
+ info.logicalWidth = fullScreenBounds.width();
+ info.logicalHeight = fullScreenBounds.height();
+ ActivityDisplay display = addNewActivityDisplayAt(info, POSITION_TOP);
- final ActivityStack stack = new StackBuilder(mRootActivityContainer)
+ display.getRequestedOverrideConfiguration().orientation =
+ Configuration.ORIENTATION_LANDSCAPE;
+ display.onRequestedOverrideConfigurationChanged(
+ display.getRequestedOverrideConfiguration());
+ ActivityStack stack = new StackBuilder(mRootActivityContainer)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
- final TaskRecord task = stack.getChildAt(0);
- final ActivityRecord activity = task.getRootActivity();
+ TaskRecord task = stack.getChildAt(0);
+ ActivityRecord root = task.getTopActivity();
- // Wire up app window token and task.
- doCallRealMethod().when(activity.mAppWindowToken).setOrientation(anyInt(), any(), any());
- doCallRealMethod().when(activity.mAppWindowToken).onDescendantOrientationChanged(any(),
- any());
- doReturn(task.mTask).when(activity.mAppWindowToken).getParent();
+ final WindowContainer parentWindowContainer = mock(WindowContainer.class);
+ Mockito.doReturn(parentWindowContainer).when(task.mTask).getParent();
+ Mockito.doReturn(true).when(parentWindowContainer)
+ .handlesOrientationChangeFromDescendant();
- // Wire up task and stack.
- task.mTask.mTaskRecord = task;
- doCallRealMethod().when(task.mTask).onDescendantOrientationChanged(any(), any());
- doReturn(stack.getTaskStack()).when(task.mTask).getParent();
-
- // Wire up stack and display content.
- doCallRealMethod().when(stack.mTaskStack).onDescendantOrientationChanged(any(), any());
- doReturn(display.mDisplayContent).when(stack.mTaskStack).getParent();
-
- activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
- assertTrue("Bounds of the task should be pillarboxed.",
- task.getBounds().width() < task.getBounds().height());
-
- activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- assertTrue("Bounds of the task should be fullscreen.",
- task.getBounds().equals(new Rect(0, 0, 1920, 1080)));
+ // Setting app to fixed portrait fits within parent, but TaskRecord shouldn't adjust the
+ // bounds because its parent says it will handle it at a later time.
+ setActivityRequestedOrientation(root, SCREEN_ORIENTATION_PORTRAIT);
+ assertEquals(root, task.getRootActivity());
+ assertEquals(SCREEN_ORIENTATION_PORTRAIT, task.getRootActivity().getOrientation());
+ assertEquals(fullScreenBounds, task.getBounds());
}
/** Ensures that the alias intent won't have target component resolved. */
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index d1fe48a..bfb9193 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -28,6 +28,7 @@
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.PowerManager.WakeReason;
import android.os.RemoteException;
import android.util.proto.ProtoOutputStream;
import android.view.IWindow;
@@ -182,11 +183,11 @@
}
@Override
- public void startedWakingUp() {
+ public void startedWakingUp(@WakeReason int reason) {
}
@Override
- public void finishedWakingUp() {
+ public void finishedWakingUp(@WakeReason int reason) {
}
@Override
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
index de3567e..af8ccc9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -37,7 +37,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowContainerControllerTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowContainerControllerTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 8628575..a9a76c2 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -51,6 +51,7 @@
import androidx.test.filters.SmallTest;
import org.junit.Test;
+import org.mockito.Mockito;
import java.util.Comparator;
@@ -739,6 +740,18 @@
verify(root).onDescendantOrientationChanged(binder, activityRecord);
}
+ @Test
+ public void testHandlesOrientationChangeFromDescendantProgation() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
+ final TestWindowContainer root = spy(builder.build());
+
+ final TestWindowContainer child = root.addChildWindow();
+ assertFalse(child.handlesOrientationChangeFromDescendant());
+
+ Mockito.doReturn(true).when(root).handlesOrientationChangeFromDescendant();
+ assertTrue(child.handlesOrientationChangeFromDescendant());
+ }
+
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
private final int mLayer;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index c09cd46..be47153 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -48,6 +48,7 @@
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -263,12 +264,12 @@
reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
assertTrue(appWindowToken.canTurnScreenOn());
reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
@@ -279,12 +280,12 @@
reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyInt(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
@@ -300,11 +301,11 @@
reset(sPowerManagerWrapper);
firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
reset(sPowerManagerWrapper);
secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
}
@Test
@@ -435,6 +436,6 @@
root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
- verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyInt(), anyString());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index 3048f1a..d556886 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -39,7 +39,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTokenTests
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTokenTests extends WindowTestsBase {
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index b81a8e7..b6b9a86 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -60,7 +60,6 @@
* Build/Install/Run:
* atest FrameworksServicesTests:WindowTracingTest
*/
-@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
public class WindowTracingTest {
diff --git a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
index 33f34b4..05d8237 100644
--- a/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/utils/RotationCacheTest.java
@@ -37,7 +37,6 @@
* atest WmTests:RotationCacheTest
*/
@SmallTest
-@FlakyTest(bugId = 74078662)
@Presubmit
public class RotationCacheTest {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index a6d7ee6..df2f455 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -493,6 +493,8 @@
switch (event.mEventType) {
case Event.ACTIVITY_RESUMED:
synchronized (mVisibleActivities) {
+ // check if this activity has already been resumed
+ if (mVisibleActivities.get(event.mInstanceId) != null) break;
mVisibleActivities.put(event.mInstanceId, event.getClassName());
try {
mAppTimeLimit.noteUsageStart(packageName, userId);
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index 37caeb2..f5b4308 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -58,8 +58,6 @@
"util.cc",
"layout_validation.cc",
],
- // b/123880763, clang-tidy analyzer has segmentation fault with dex_builder.cc
- tidy_checks: ["-clang-analyzer-*"],
host_supported: true,
}
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 4c1a0dc7..6047e8c 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -426,7 +426,7 @@
// Some of the registers don't fit in the four bit short form of the invoke
// instruction, so we need to do an invoke/range. To do this, we need to
// first move all the arguments into contiguous temporary registers.
- std::array<Value, kMaxArgs> scratch{GetScratchRegisters<kMaxArgs>()};
+ std::array<Value, kMaxArgs> scratch = GetScratchRegisters<kMaxArgs>();
const auto& prototype = dex_->GetPrototypeByMethodId(instruction.method_id());
CHECK(prototype.has_value());
diff --git a/telecomm/java/android/telecom/ConferenceParticipant.java b/telecomm/java/android/telecom/ConferenceParticipant.java
index 20b04eb..6317770 100644
--- a/telecomm/java/android/telecom/ConferenceParticipant.java
+++ b/telecomm/java/android/telecom/ConferenceParticipant.java
@@ -19,6 +19,10 @@
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.PhoneConstants;
/**
* Parcelable representation of a participant's state in a conference call.
@@ -27,6 +31,11 @@
public class ConferenceParticipant implements Parcelable {
/**
+ * RFC5767 states that a SIP URI with an unknown number should use an address of
+ * {@code anonymous@anonymous.invalid}. E.g. the host name is anonymous.invalid.
+ */
+ private static final String ANONYMOUS_INVALID_HOST = "anonymous.invalid";
+ /**
* The conference participant's handle (e.g., phone number).
*/
private final Uri mHandle;
@@ -50,6 +59,16 @@
private final int mState;
/**
+ * The connect time of the participant.
+ */
+ private long mConnectTime;
+
+ /**
+ * The connect elapsed time of the participant.
+ */
+ private long mConnectElapsedTime;
+
+ /**
* Creates an instance of {@code ConferenceParticipant}.
*
* @param handle The conference participant's handle (e.g., phone number).
@@ -92,6 +111,54 @@
}
/**
+ * Determines the number presentation for a conference participant. Per RFC5767, if the host
+ * name contains {@code anonymous.invalid} we can assume that there is no valid caller ID
+ * information for the caller, otherwise we'll assume that the URI can be shown.
+ *
+ * @return The number presentation.
+ */
+ @VisibleForTesting
+ public int getParticipantPresentation() {
+ Uri address = getHandle();
+ if (address == null) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+
+ String number = address.getSchemeSpecificPart();
+ // If no number, bail early and set restricted presentation.
+ if (TextUtils.isEmpty(number)) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+ // Per RFC3261, the host name portion can also potentially include extra information:
+ // E.g. sip:anonymous1@anonymous.invalid;legid=1
+ // In this case, hostName will be anonymous.invalid and there is an extra parameter for
+ // legid=1.
+ // Parameters are optional, and the address (e.g. test@test.com) will always be the first
+ // part, with any parameters coming afterwards.
+ String [] hostParts = number.split("[;]");
+ String addressPart = hostParts[0];
+
+ // Get the number portion from the address part.
+ // This will typically be formatted similar to: 6505551212@test.com
+ String [] numberParts = addressPart.split("[@]");
+
+ // If we can't parse the host name out of the URI, then there is probably other data
+ // present, and is likely a valid SIP URI.
+ if (numberParts.length != 2) {
+ return PhoneConstants.PRESENTATION_ALLOWED;
+ }
+ String hostName = numberParts[1];
+
+ // If the hostname portion of the SIP URI is the invalid host string, presentation is
+ // restricted.
+ if (hostName.equals(ANONYMOUS_INVALID_HOST)) {
+ return PhoneConstants.PRESENTATION_RESTRICTED;
+ }
+
+ return PhoneConstants.PRESENTATION_ALLOWED;
+ }
+
+ /**
* Writes the {@code ConferenceParticipant} to a parcel.
*
* @param dest The Parcel in which the object should be written.
@@ -121,6 +188,10 @@
sb.append(Log.pii(mEndpoint));
sb.append(" State: ");
sb.append(Connection.stateToString(mState));
+ sb.append(" ConnectTime: ");
+ sb.append(getConnectTime());
+ sb.append(" ConnectElapsedTime: ");
+ sb.append(getConnectElapsedTime());
sb.append("]");
return sb.toString();
}
@@ -155,4 +226,26 @@
public int getState() {
return mState;
}
+
+ /**
+ * The connect time of the participant to the conference.
+ */
+ public long getConnectTime() {
+ return mConnectTime;
+ }
+
+ public void setConnectTime(long connectTime) {
+ this.mConnectTime = connectTime;
+ }
+
+ /**
+ * The connect elpased time of the participant to the conference.
+ */
+ public long getConnectElapsedTime() {
+ return mConnectElapsedTime;
+ }
+
+ public void setConnectElapsedTime(long connectElapsedTime) {
+ mConnectElapsedTime = connectElapsedTime;
+ }
}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 05d5a13..bd0d4ae 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -16,10 +16,6 @@
package android.telecom;
-import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.IVideoCallback;
-import com.android.internal.telecom.IVideoProvider;
-
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -43,6 +39,10 @@
import android.util.ArraySet;
import android.view.Surface;
+import com.android.internal.os.SomeArgs;
+import com.android.internal.telecom.IVideoCallback;
+import com.android.internal.telecom.IVideoProvider;
+
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
diff --git a/telecomm/java/android/telecom/DefaultDialerManager.java b/telecomm/java/android/telecom/DefaultDialerManager.java
index 57ae5d3..aac0956d 100644
--- a/telecomm/java/android/telecom/DefaultDialerManager.java
+++ b/telecomm/java/android/telecom/DefaultDialerManager.java
@@ -78,7 +78,7 @@
try {
RoleManagerCallback.Future cb = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
- RoleManager.ROLE_DIALER, packageName, UserHandle.of(user),
+ RoleManager.ROLE_DIALER, packageName, 0, UserHandle.of(user),
AsyncTask.THREAD_POOL_EXECUTOR, cb);
cb.get(5, TimeUnit.SECONDS);
return true;
diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java
index 1de67a5..5a97c94 100644
--- a/telecomm/java/android/telecom/DisconnectCause.java
+++ b/telecomm/java/android/telecom/DisconnectCause.java
@@ -16,9 +16,9 @@
package android.telecom;
+import android.media.ToneGenerator;
import android.os.Parcel;
import android.os.Parcelable;
-import android.media.ToneGenerator;
import android.text.TextUtils;
import java.util.Objects;
@@ -91,6 +91,12 @@
*/
public static final String REASON_IMS_ACCESS_BLOCKED = "REASON_IMS_ACCESS_BLOCKED";
+ /**
+ * Reason code, which indicates that the conference call is simulating single party conference.
+ * @hide
+ */
+ public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL";
+
private int mDisconnectCode;
private CharSequence mDisconnectLabel;
private CharSequence mDisconnectDescription;
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index d3420ee..7478a00 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -636,7 +636,7 @@
// Update the setting.
RoleManagerCallback.Future res = new RoleManagerCallback.Future();
context.getSystemService(RoleManager.class).addRoleHolderAsUser(
- RoleManager.ROLE_SMS, applicationData.mPackageName, UserHandle.of(userId),
+ RoleManager.ROLE_SMS, applicationData.mPackageName, 0, UserHandle.of(userId),
AsyncTask.THREAD_POOL_EXECUTOR, res);
try {
res.get(5, TimeUnit.SECONDS);