Merge "Remove legacy migration code from sync manager"
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
index dfbabeb..a283e06 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
@@ -47,8 +47,7 @@
public void testCreateRenderNodeNoName() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- RenderNode node = RenderNode.create(null, null);
- node.destroy();
+ RenderNode.create(null, null);
}
}
@@ -56,8 +55,7 @@
public void testCreateRenderNode() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- RenderNode node = RenderNode.create("LinearLayout", null);
- node.destroy();
+ RenderNode.create("LinearLayout", null);
}
}
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 453fb72..6943dab 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -27,7 +27,9 @@
LOCAL_SHARED_LIBRARIES += \
libandroidthings \
+ libandroidthings_protos \
libchrome \
+ libprotobuf-cpp-lite \
LOCAL_STATIC_LIBRARIES += \
libjsoncpp
diff --git a/cmds/bootanimation/iot/Android.mk b/cmds/bootanimation/iot/Android.mk
index 8b475d3..3d288e4 100644
--- a/cmds/bootanimation/iot/Android.mk
+++ b/cmds/bootanimation/iot/Android.mk
@@ -25,9 +25,11 @@
LOCAL_SHARED_LIBRARIES := \
libandroidthings \
+ libandroidthings_protos \
libbase \
libchrome \
liblog \
+ libprotobuf-cpp-lite \
LOCAL_STATIC_LIBRARIES += \
libjsoncpp
diff --git a/cmds/bootanimation/iot/BootParameters.cpp b/cmds/bootanimation/iot/BootParameters.cpp
index 2cf1c19..30a9b28 100644
--- a/cmds/bootanimation/iot/BootParameters.cpp
+++ b/cmds/bootanimation/iot/BootParameters.cpp
@@ -22,10 +22,13 @@
#include <fcntl.h>
#include <android-base/file.h>
+#include <json/json.h>
#include <utils/Log.h>
using android::base::ReadFileToString;
using android::base::RemoveFileIfExists;
+using android::base::WriteStringToFile;
+using Json::ArrayIndex;
using Json::Reader;
using Json::Value;
@@ -33,23 +36,34 @@
namespace {
-// Keys for supporting a silent boot and user-defined BootAction parameters.
-constexpr const char *kKeySilentBoot = "silent_boot";
-constexpr const char* kKeyParams = "params";
+// Keys for deprecated parameters. Devices that OTA from N to O and that used
+// the hidden BootParameters API will store these in the JSON blob. To support
+// the transition from N to O, these keys are mapped to the new parameters.
+constexpr const char *kKeyLegacyVolume = "volume";
+constexpr const char *kKeyLegacyAnimationsDisabled = "boot_animation_disabled";
+constexpr const char *kKeyLegacyParamNames = "param_names";
+constexpr const char *kKeyLegacyParamValues = "param_values";
-constexpr const char* kNextBootFile = "/data/misc/bootanimation/next_boot.json";
-constexpr const char* kLastBootFile = "/data/misc/bootanimation/last_boot.json";
+constexpr const char *kNextBootFile = "/data/misc/bootanimation/next_boot.proto";
+constexpr const char *kLastBootFile = "/data/misc/bootanimation/last_boot.proto";
-void swapBootConfigs() {
- // rename() will fail if next_boot.json doesn't exist, so delete
- // last_boot.json manually first.
+constexpr const char *kLegacyNextBootFile = "/data/misc/bootanimation/next_boot.json";
+constexpr const char *kLegacyLastBootFile = "/data/misc/bootanimation/last_boot.json";
+
+void removeLegacyFiles() {
std::string err;
- if (!RemoveFileIfExists(kLastBootFile, &err))
- ALOGE("Unable to delete last boot file: %s", err.c_str());
+ if (!RemoveFileIfExists(kLegacyLastBootFile, &err)) {
+ ALOGW("Unable to delete %s: %s", kLegacyLastBootFile, err.c_str());
+ }
- if (rename(kNextBootFile, kLastBootFile) && errno != ENOENT)
- ALOGE("Unable to swap boot files: %s", strerror(errno));
+ err.clear();
+ if (!RemoveFileIfExists(kLegacyNextBootFile, &err)) {
+ ALOGW("Unable to delete %s: %s", kLegacyNextBootFile, err.c_str());
+ }
+}
+void createNextBootFile() {
+ errno = 0;
int fd = open(kNextBootFile, O_CREAT, DEFFILEMODE);
if (fd == -1) {
ALOGE("Unable to create next boot file: %s", strerror(errno));
@@ -64,54 +78,120 @@
} // namespace
+// Renames the 'next' boot file to the 'last' file and reads its contents.
+bool BootParameters::swapAndLoadBootConfigContents(const char *lastBootFile,
+ const char *nextBootFile,
+ std::string *contents) {
+ if (!ReadFileToString(nextBootFile, contents)) {
+ RemoveFileIfExists(lastBootFile);
+ return false;
+ }
+
+ errno = 0;
+ if (rename(nextBootFile, lastBootFile) && errno != ENOENT)
+ ALOGE("Unable to swap boot files: %s", strerror(errno));
+
+ return true;
+}
+
BootParameters::BootParameters() {
- swapBootConfigs();
loadParameters();
}
-void BootParameters::loadParameters() {
- std::string contents;
- if (!ReadFileToString(kLastBootFile, &contents)) {
- if (errno != ENOENT)
- ALOGE("Unable to read from %s: %s", kLastBootFile, strerror(errno));
+// Saves the boot parameters state to disk so the framework can read it.
+void BootParameters::storeParameters() {
+ errno = 0;
+ if (!WriteStringToFile(mProto.SerializeAsString(), kLastBootFile)) {
+ ALOGE("Failed to write boot parameters to %s: %s", kLastBootFile, strerror(errno));
+ }
+ // WriteStringToFile sets the file permissions to 0666, but these are not
+ // honored by the system.
+ errno = 0;
+ if (chmod(kLastBootFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) {
+ ALOGE("Failed to set permissions for %s: %s", kLastBootFile, strerror(errno));
+ }
+}
+
+// Load the boot parameters from disk, try the old location and format if the
+// file does not exist. Note:
+// - Parse errors result in defaults being used (a normal boot).
+// - Legacy boot parameters default to a silent boot.
+void BootParameters::loadParameters() {
+ // Precedence is given to the new file format (.proto).
+ std::string contents;
+ if (swapAndLoadBootConfigContents(kLastBootFile, kNextBootFile, &contents)) {
+ parseBootParameters(contents);
+ } else if (swapAndLoadBootConfigContents(kLegacyLastBootFile, kLegacyNextBootFile, &contents)) {
+ parseLegacyBootParameters(contents);
+ storeParameters();
+ removeLegacyFiles();
+ }
+
+ createNextBootFile();
+}
+
+void BootParameters::parseBootParameters(const std::string &contents) {
+ if (!mProto.ParseFromString(contents)) {
+ ALOGW("Failed to parse parameters from %s", kLastBootFile);
return;
}
- loadParameters(contents);
+ loadStateFromProto();
}
-// If the boot parameters -
-// - File is missing, we assume a normal, non-silent boot.
-// - Are well-formed, initially assume a normal, non-silent boot and parse.
-void BootParameters::loadParameters(const std::string& raw_json) {
- if (!Reader().parse(raw_json, mJson)) {
- return;
- }
-
- parseBootParameters();
-}
-
-void BootParameters::parseBootParameters() {
- // A missing key returns a safe, missing value.
- // Ignore invalid or missing JSON parameters.
- Value &jsonValue = mJson[kKeySilentBoot];
- if (jsonValue.isBool()) {
- mIsSilentBoot = jsonValue.asBool();
+// Parses the JSON in the proto.
+void BootParameters::parseLegacyBootParameters(const std::string &contents) {
+ Value json;
+ if (!Reader().parse(contents, json)) {
+ ALOGW("Failed to parse parameters from %s", kLegacyLastBootFile);
+ return;
}
- jsonValue = mJson[kKeyParams];
- if (jsonValue.isObject()) {
- // getMemberNames returns a copy of the keys which must be stored.
- mKeys = jsonValue.getMemberNames();
- for (auto &key : mKeys) {
- Value &value = jsonValue[key];
- if (value.isString()) {
- mParameters.push_back(
- {.key = key.c_str(), .value = value.asCString()});
+ int volume = 0;
+ bool bootAnimationDisabled = true;
+
+ Value &jsonValue = json[kKeyLegacyVolume];
+ if (jsonValue.isIntegral()) {
+ volume = jsonValue.asInt();
+ }
+
+ jsonValue = json[kKeyLegacyAnimationsDisabled];
+ if (jsonValue.isIntegral()) {
+ bootAnimationDisabled = jsonValue.asInt() == 1;
+ }
+
+ // Assume a silent boot unless all of the following are true -
+ // 1. The volume is neither 0 nor -1000 (the legacy default value).
+ // 2. The boot animations are explicitly enabled.
+ // Note: brightness was never used.
+ mProto.set_silent_boot((volume == 0) || (volume == -1000) || bootAnimationDisabled);
+
+ Value &keys = json[kKeyLegacyParamNames];
+ Value &values = json[kKeyLegacyParamValues];
+ if (keys.isArray() && values.isArray() && (keys.size() == values.size())) {
+ for (ArrayIndex i = 0; i < keys.size(); ++i) {
+ auto &key = keys[i];
+ auto &value = values[i];
+ if (key.isString() && value.isString()) {
+ auto userParameter = mProto.add_user_parameter();
+ userParameter->set_key(key.asString());
+ userParameter->set_value(value.asString());
}
}
}
+
+ loadStateFromProto();
+}
+
+void BootParameters::loadStateFromProto() {
+ // A missing key returns a safe, default value.
+ // Ignore invalid or missing parameters.
+ mIsSilentBoot = mProto.silent_boot();
+
+ for (const auto ¶m : mProto.user_parameter()) {
+ mParameters.push_back({.key = param.key().c_str(), .value = param.value().c_str()});
+ }
}
} // namespace android
diff --git a/cmds/bootanimation/iot/BootParameters.h b/cmds/bootanimation/iot/BootParameters.h
index 49c34dd..cbd1ca6 100644
--- a/cmds/bootanimation/iot/BootParameters.h
+++ b/cmds/bootanimation/iot/BootParameters.h
@@ -22,7 +22,7 @@
#include <vector>
#include <boot_action/boot_action.h> // libandroidthings native API.
-#include <json/json.h>
+#include <boot_parameters.pb.h>
namespace android {
@@ -39,22 +39,33 @@
// Returns the additional boot parameters that were set on reboot.
const std::vector<ABootActionParameter>& getParameters() const { return mParameters; }
- // Exposed for testing. Updates the parameters with new JSON values.
- void loadParameters(const std::string& raw_json);
-private:
+ // Exposed for testing. Sets the parameters to the serialized proto.
+ void parseBootParameters(const std::string &contents);
+
+ // For devices that OTA from N to O.
+ // Exposed for testing. Sets the parameters to the raw JSON.
+ void parseLegacyBootParameters(const std::string &contents);
+
+ // Exposed for testing. Loads the contents from |nextBootFile| and replaces
+ // |lastBootFile| with |nextBootFile|.
+ static bool swapAndLoadBootConfigContents(const char *lastBootFile, const char *nextBootFile,
+ std::string *contents);
+
+ private:
void loadParameters();
- void parseBootParameters();
+ // Replaces the legacy JSON blob with the updated version, allowing the
+ // framework to read it.
+ void storeParameters();
+
+ void loadStateFromProto();
bool mIsSilentBoot = false;
std::vector<ABootActionParameter> mParameters;
- // Store parsed JSON because mParameters makes a shallow copy.
- Json::Value mJson;
-
- // Store parameter keys because mParameters makes a shallow copy.
- Json::Value::Members mKeys;
+ // Store the proto because mParameters makes a shallow copy.
+ android::things::proto::BootParameters mProto;
};
} // namespace android
diff --git a/cmds/bootanimation/iot/BootParameters_test.cpp b/cmds/bootanimation/iot/BootParameters_test.cpp
index 27d7d6f..d55bce6 100644
--- a/cmds/bootanimation/iot/BootParameters_test.cpp
+++ b/cmds/bootanimation/iot/BootParameters_test.cpp
@@ -16,6 +16,13 @@
#include "BootParameters.h"
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/file.h>
+#include <android-base/test_utils.h>
+#include <boot_parameters.pb.h>
#include <gtest/gtest.h>
namespace android {
@@ -23,50 +30,51 @@
namespace {
TEST(BootParametersTest, TestNoBootParametersIsNotSilent) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters("");
+ android::things::proto::BootParameters proto;
- ASSERT_FALSE(boot_parameters.isSilentBoot());
- ASSERT_EQ(0u, boot_parameters.getParameters().size());
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseBootParameters(proto.SerializeAsString());
+
+ ASSERT_FALSE(bootParameters.isSilentBoot());
+ ASSERT_EQ(0u, bootParameters.getParameters().size());
}
TEST(BootParametersTest, TestParseIsSilent) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters(R"(
- {
- "silent_boot":true,
- "params":{}
- }
- )");
+ android::things::proto::BootParameters proto;
+ proto.set_silent_boot(true);
- ASSERT_TRUE(boot_parameters.isSilentBoot());
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseBootParameters(proto.SerializeAsString());
+
+ ASSERT_TRUE(bootParameters.isSilentBoot());
}
TEST(BootParametersTest, TestParseIsNotSilent) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters(R"(
- {
- "silent_boot":false,
- "params":{}
- }
- )");
+ android::things::proto::BootParameters proto;
+ proto.set_silent_boot(false);
- ASSERT_FALSE(boot_parameters.isSilentBoot());
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseBootParameters(proto.SerializeAsString());
+
+ ASSERT_FALSE(bootParameters.isSilentBoot());
}
TEST(BootParametersTest, TestParseBootParameters) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters(R"(
- {
- "silent_boot":false,
- "params":{
- "key1":"value1",
- "key2":"value2"
- }
- }
- )");
+ android::things::proto::BootParameters proto;
+ proto.set_silent_boot(false);
- auto ¶meters = boot_parameters.getParameters();
+ auto userParameter = proto.add_user_parameter();
+ userParameter->set_key("key1");
+ userParameter->set_value("value1");
+
+ userParameter = proto.add_user_parameter();
+ userParameter->set_key("key2");
+ userParameter->set_value("value2");
+
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseBootParameters(proto.SerializeAsString());
+
+ auto ¶meters = bootParameters.getParameters();
ASSERT_EQ(2u, parameters.size());
ASSERT_STREQ(parameters[0].key, "key1");
ASSERT_STREQ(parameters[0].value, "value1");
@@ -74,35 +82,182 @@
ASSERT_STREQ(parameters[1].value, "value2");
}
-TEST(BootParametersTest, TestParseMissingParametersIsNotSilent) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters(R"(
+TEST(BootParametersTest, TestParseLegacyDisableBootAnimationIsSilent) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
{
- "params":{}
+ "brightness":200,
+ "volume":100,
+ "boot_animation_disabled":1,
+ "param_names":[],
+ "param_values":[]
}
)");
- ASSERT_FALSE(boot_parameters.isSilentBoot());
+ ASSERT_TRUE(bootParameters.isSilentBoot());
}
-TEST(BootParametersTest, TestParseMalformedParametersAreSkipped) {
- BootParameters boot_parameters = BootParameters();
- boot_parameters.loadParameters(R"(
+TEST(BootParametersTest, TestParseLegacyZeroVolumeIsSilent) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
{
- "silent_boot":false,
- "params":{
- "key1":123,
- "key2":"value2"
- }
+ "brightness":200,
+ "volume":0,
+ "boot_animation_disabled":0,
+ "param_names":[],
+ "param_values":[]
}
)");
- auto ¶meters = boot_parameters.getParameters();
+ ASSERT_TRUE(bootParameters.isSilentBoot());
+}
+
+TEST(BootParametersTest, TestParseLegacyDefaultVolumeIsSilent) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":200,
+ "volume":-1000,
+ "boot_animation_disabled":0,
+ "param_names":[],
+ "param_values":[]
+ }
+ )");
+
+ ASSERT_TRUE(bootParameters.isSilentBoot());
+}
+
+TEST(BootParametersTest, TestParseLegacyNotSilent) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":200,
+ "volume":500,
+ "boot_animation_disabled":0,
+ "param_names":[],
+ "param_values":[]
+ }
+ )");
+
+ ASSERT_FALSE(bootParameters.isSilentBoot());
+}
+
+TEST(BootParametersTest, TestParseLegacyParameters) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":200,
+ "volume":100,
+ "boot_animation_disabled":1,
+ "param_names":["key1", "key2"],
+ "param_values":["value1", "value2"]
+ }
+ )");
+
+ auto parameters = bootParameters.getParameters();
+ ASSERT_EQ(2u, parameters.size());
+ ASSERT_STREQ(parameters[0].key, "key1");
+ ASSERT_STREQ(parameters[0].value, "value1");
+ ASSERT_STREQ(parameters[1].key, "key2");
+ ASSERT_STREQ(parameters[1].value, "value2");
+}
+
+TEST(BootParametersTest, TestParseLegacyZeroParameters) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":200,
+ "volume":100,
+ "boot_animation_disabled":1,
+ "param_names":[],
+ "param_values":[]
+ }
+ )");
+
+ ASSERT_EQ(0u, bootParameters.getParameters().size());
+}
+
+TEST(BootParametersTest, TestMalformedLegacyParametersAreSkipped) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":500,
+ "volume":500,
+ "boot_animation_disabled":0,
+ "param_names":["key1", "key2"],
+ "param_values":[1, "value2"]
+ }
+ )");
+
+ auto parameters = bootParameters.getParameters();
ASSERT_EQ(1u, parameters.size());
ASSERT_STREQ(parameters[0].key, "key2");
ASSERT_STREQ(parameters[0].value, "value2");
}
+TEST(BootParametersTest, TestLegacyUnequalParameterSizesAreSkipped) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":500,
+ "volume":500,
+ "boot_animation_disabled":0,
+ "param_names":["key1", "key2"],
+ "param_values":["value1"]
+ }
+ )");
+
+ ASSERT_EQ(0u, bootParameters.getParameters().size());
+}
+
+TEST(BootParametersTest, TestMissingLegacyBootParametersIsSilent) {
+ BootParameters bootParameters = BootParameters();
+ bootParameters.parseLegacyBootParameters(R"(
+ {
+ "brightness":500
+ }
+ )");
+
+ EXPECT_TRUE(bootParameters.isSilentBoot());
+ ASSERT_EQ(0u, bootParameters.getParameters().size());
+}
+
+TEST(BootParametersTest, TestLastFileIsRemovedOnError) {
+ TemporaryFile lastFile;
+ TemporaryDir tempDir;
+ std::string nonExistentFilePath(std::string(tempDir.path) + "/nonexistent");
+ std::string contents;
+
+ BootParameters::swapAndLoadBootConfigContents(lastFile.path, nonExistentFilePath.c_str(),
+ &contents);
+
+ struct stat buf;
+ ASSERT_EQ(-1, lstat(lastFile.path, &buf));
+ ASSERT_TRUE(contents.empty());
+}
+
+TEST(BootParametersTest, TestNextFileIsRemovedLastFileExistsOnSuccess) {
+ TemporaryFile lastFile;
+ TemporaryFile nextFile;
+
+ base::WriteStringToFile("foo", nextFile.path);
+
+ std::string contents;
+ // Expected side effects:
+ // - |next_file| is moved to |last_file|
+ // - |contents| is the contents of |next_file| before being moved.
+ BootParameters::swapAndLoadBootConfigContents(lastFile.path, nextFile.path, &contents);
+
+ struct stat buf;
+ ASSERT_EQ(0, lstat(lastFile.path, &buf));
+ ASSERT_EQ(-1, lstat(nextFile.path, &buf));
+ ASSERT_EQ(contents, "foo");
+
+ contents.clear();
+ ASSERT_TRUE(base::ReadFileToString(lastFile.path, &contents));
+ ASSERT_EQ(contents, "foo");
+}
+
} // namespace
} // namespace android
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index cc17ea8..1a3260f 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -137,6 +137,7 @@
Landroid/app/ActivityManager$StackInfo;->visible:Z
Landroid/app/ActivityManager$TaskDescription;->getBackgroundColor()I
Landroid/app/ActivityManager$TaskDescription;->getInMemoryIcon()Landroid/graphics/Bitmap;
+Landroid/app/ActivityManager$TaskDescription;->setIcon(Landroid/graphics/Bitmap;)V
Landroid/app/ActivityManager$TaskSnapshot;->getContentInsets()Landroid/graphics/Rect;
Landroid/app/ActivityManager$TaskSnapshot;->getOrientation()I
Landroid/app/ActivityManager$TaskSnapshot;->getScale()F
@@ -1217,6 +1218,7 @@
Landroid/bluetooth/IBluetooth$Stub;-><init>()V
Landroid/bluetooth/IBluetooth$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetooth;
Landroid/bluetooth/IBluetooth$Stub;->TRANSACTION_enable:I
+Landroid/bluetooth/IBluetooth;->fetchRemoteUuids(Landroid/bluetooth/BluetoothDevice;)Z
Landroid/bluetooth/IBluetooth;->getAddress()Ljava/lang/String;
Landroid/bluetooth/IBluetooth;->getRemoteAlias(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
Landroid/bluetooth/IBluetooth;->isEnabled()Z
@@ -1491,6 +1493,7 @@
Landroid/content/pm/IPackageManager$Stub$Proxy;->getAppOpPermissionPackages(Ljava/lang/String;)[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstalledPackages(II)Landroid/content/pm/ParceledListSlice;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getInstallLocation()I
+Landroid/content/pm/IPackageManager$Stub$Proxy;->getLastChosenActivity(Landroid/content/Intent;Ljava/lang/String;I)Landroid/content/pm/ResolveInfo;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackageInfo(Ljava/lang/String;II)Landroid/content/pm/PackageInfo;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getPackagesForUid(I)[Ljava/lang/String;
Landroid/content/pm/IPackageManager$Stub$Proxy;->getSystemSharedLibraryNames()[Ljava/lang/String;
@@ -1721,6 +1724,7 @@
Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Ljava/io/File;Z)V
Landroid/content/pm/PackageParser;->collectCertificates(Landroid/content/pm/PackageParser$Package;Z)V
Landroid/content/pm/PackageParser;->generateActivityInfo(Landroid/content/pm/PackageParser$Activity;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ActivityInfo;
+Landroid/content/pm/PackageParser;->generateApplicationInfo(Landroid/content/pm/PackageParser$Package;ILandroid/content/pm/PackageUserState;)Landroid/content/pm/ApplicationInfo;
Landroid/content/pm/PackageParser;->generateApplicationInfo(Landroid/content/pm/PackageParser$Package;ILandroid/content/pm/PackageUserState;I)Landroid/content/pm/ApplicationInfo;
Landroid/content/pm/PackageParser;->generateInstrumentationInfo(Landroid/content/pm/PackageParser$Instrumentation;I)Landroid/content/pm/InstrumentationInfo;
Landroid/content/pm/PackageParser;->generatePackageInfo(Landroid/content/pm/PackageParser$Package;[IIJJLjava/util/Set;Landroid/content/pm/PackageUserState;)Landroid/content/pm/PackageInfo;
@@ -1732,6 +1736,7 @@
Landroid/content/pm/PackageParser;->mCallback:Landroid/content/pm/PackageParser$Callback;
Landroid/content/pm/PackageParser;->NEW_PERMISSIONS:[Landroid/content/pm/PackageParser$NewPermissionInfo;
Landroid/content/pm/PackageParser;->parseBaseApk(Ljava/lang/String;Landroid/content/res/Resources;Landroid/content/res/XmlResourceParser;I[Ljava/lang/String;)Landroid/content/pm/PackageParser$Package;
+Landroid/content/pm/PackageParser;->parseBaseApplication(Landroid/content/pm/PackageParser$Package;Landroid/content/res/Resources;Landroid/content/res/XmlResourceParser;I[Ljava/lang/String;)Z
Landroid/content/pm/PackageParser;->parseMonolithicPackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;I)Landroid/content/pm/PackageParser$Package;
Landroid/content/pm/PackageParser;->parsePackage(Ljava/io/File;IZ)Landroid/content/pm/PackageParser$Package;
@@ -1815,6 +1820,7 @@
Landroid/content/res/AssetManager;->setConfiguration(IILjava/lang/String;IIIIIIIIIIIIIII)V
Landroid/content/res/AssetManager;->sSystem:Landroid/content/res/AssetManager;
Landroid/content/res/ColorStateList$ColorStateListFactory;-><init>(Landroid/content/res/ColorStateList;)V
+Landroid/content/res/ColorStateList;-><init>()V
Landroid/content/res/ColorStateList;->canApplyTheme()Z
Landroid/content/res/ColorStateList;->getColors()[I
Landroid/content/res/ColorStateList;->getStates()[[I
@@ -1877,6 +1883,7 @@
Landroid/content/res/Resources;->updateSystemConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V
Landroid/content/res/ResourcesImpl;-><init>(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;Landroid/view/DisplayAdjustments;)V
Landroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
+Landroid/content/res/ResourcesImpl;->getDisplayMetrics()Landroid/util/DisplayMetrics;
Landroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
Landroid/content/res/ResourcesImpl;->mAccessLock:Ljava/lang/Object;
Landroid/content/res/ResourcesImpl;->mAnimatorCache:Landroid/content/res/ConfigurationBoundResourceCache;
@@ -2132,6 +2139,7 @@
Landroid/graphics/CanvasProperty;->createPaint(Landroid/graphics/Paint;)Landroid/graphics/CanvasProperty;
Landroid/graphics/ColorMatrixColorFilter;->mMatrix:Landroid/graphics/ColorMatrix;
Landroid/graphics/ColorMatrixColorFilter;->setColorMatrix(Landroid/graphics/ColorMatrix;)V
+Landroid/graphics/ColorMatrixColorFilter;->setColorMatrixArray([F)V
Landroid/graphics/drawable/AnimatedImageDrawable;->onAnimationEnd()V
Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesCount(I)V
Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesDuration(I)V
@@ -4139,6 +4147,7 @@
Landroid/os/SELinux;->restoreconRecursive(Ljava/io/File;)Z
Landroid/os/ServiceManager;-><init>()V
Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;)V
+Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;Z)V
Landroid/os/ServiceManager;->addService(Ljava/lang/String;Landroid/os/IBinder;ZI)V
Landroid/os/ServiceManager;->checkService(Ljava/lang/String;)Landroid/os/IBinder;
Landroid/os/ServiceManager;->getIServiceManager()Landroid/os/IServiceManager;
@@ -4223,6 +4232,7 @@
Landroid/os/storage/VolumeInfo;->getDiskId()Ljava/lang/String;
Landroid/os/storage/VolumeInfo;->getEnvironmentForState(I)Ljava/lang/String;
Landroid/os/storage/VolumeInfo;->getFsUuid()Ljava/lang/String;
+Landroid/os/storage/VolumeInfo;->getInternalPath()Ljava/io/File;
Landroid/os/storage/VolumeInfo;->getInternalPathForUser(I)Ljava/io/File;
Landroid/os/storage/VolumeInfo;->getMountUserId()I
Landroid/os/storage/VolumeInfo;->getPath()Ljava/io/File;
@@ -4258,6 +4268,7 @@
Landroid/os/StrictMode;->sLastVmViolationTime:Ljava/util/HashMap;
Landroid/os/StrictMode;->sWindowManager:Landroid/util/Singleton;
Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
+Landroid/os/SystemClock;-><init>()V
Landroid/os/SystemClock;->currentThreadTimeMicro()J
Landroid/os/SystemClock;->currentTimeMicro()J
Landroid/os/SystemProperties;-><init>()V
@@ -4342,6 +4353,7 @@
Landroid/os/UserManager;->getUserStartRealtime()J
Landroid/os/UserManager;->getUserUnlockRealtime()J
Landroid/os/UserManager;->hasBaseUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
+Landroid/os/UserManager;->isDeviceInDemoMode(Landroid/content/Context;)Z
Landroid/os/UserManager;->isGuestUser(I)Z
Landroid/os/UserManager;->isLinkedUser()Z
Landroid/os/UserManager;->isUserAdmin(I)Z
@@ -4547,6 +4559,7 @@
Landroid/provider/Settings$Global;->ZEN_MODE_IMPORTANT_INTERRUPTIONS:I
Landroid/provider/Settings$Global;->ZEN_MODE_NO_INTERRUPTIONS:I
Landroid/provider/Settings$Global;->ZEN_MODE_OFF:I
+Landroid/provider/Settings$NameValueCache;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
Landroid/provider/Settings$NameValueCache;->mProviderHolder:Landroid/provider/Settings$ContentProviderHolder;
Landroid/provider/Settings$Secure;->ACCESSIBILITY_AUTOCLICK_ENABLED:Ljava/lang/String;
Landroid/provider/Settings$Secure;->ACCESSIBILITY_CAPTIONING_TYPEFACE:Ljava/lang/String;
@@ -4585,10 +4598,12 @@
Landroid/provider/Settings$Secure;->SETTINGS_TO_BACKUP:[Ljava/lang/String;
Landroid/provider/Settings$Secure;->SMS_DEFAULT_APPLICATION:Ljava/lang/String;
Landroid/provider/Settings$Secure;->sNameValueCache:Landroid/provider/Settings$NameValueCache;
+Landroid/provider/Settings$Secure;->sProviderHolder:Landroid/provider/Settings$ContentProviderHolder;
Landroid/provider/Settings$Secure;->VOICE_RECOGNITION_SERVICE:Ljava/lang/String;
Landroid/provider/Settings$System;->AIRPLANE_MODE_TOGGLEABLE_RADIOS:Ljava/lang/String;
Landroid/provider/Settings$System;->CAR_DOCK_SOUND:Ljava/lang/String;
Landroid/provider/Settings$System;->CAR_UNDOCK_SOUND:Ljava/lang/String;
+Landroid/provider/Settings$System;->CLONE_TO_MANAGED_PROFILE:Ljava/util/Set;
Landroid/provider/Settings$System;->DESK_DOCK_SOUND:Ljava/lang/String;
Landroid/provider/Settings$System;->DESK_UNDOCK_SOUND:Ljava/lang/String;
Landroid/provider/Settings$System;->DOCK_SOUNDS_ENABLED:Ljava/lang/String;
@@ -4600,6 +4615,9 @@
Landroid/provider/Settings$System;->LOCKSCREEN_SOUNDS_ENABLED:Ljava/lang/String;
Landroid/provider/Settings$System;->LOCK_SOUND:Ljava/lang/String;
Landroid/provider/Settings$System;->MASTER_MONO:Ljava/lang/String;
+Landroid/provider/Settings$System;->MOVED_TO_GLOBAL:Ljava/util/HashSet;
+Landroid/provider/Settings$System;->MOVED_TO_SECURE:Ljava/util/HashSet;
+Landroid/provider/Settings$System;->MOVED_TO_SECURE_THEN_GLOBAL:Ljava/util/HashSet;
Landroid/provider/Settings$System;->NOTIFICATION_LIGHT_PULSE:Ljava/lang/String;
Landroid/provider/Settings$System;->POINTER_LOCATION:Ljava/lang/String;
Landroid/provider/Settings$System;->POINTER_SPEED:Ljava/lang/String;
@@ -4614,6 +4632,7 @@
Landroid/provider/Settings$System;->sProviderHolder:Landroid/provider/Settings$ContentProviderHolder;
Landroid/provider/Settings$System;->TTY_MODE:Ljava/lang/String;
Landroid/provider/Settings$System;->UNLOCK_SOUND:Ljava/lang/String;
+Landroid/provider/Settings$System;->VALIDATORS:Ljava/util/Map;
Landroid/provider/Settings$System;->VIBRATE_IN_SILENT:Ljava/lang/String;
Landroid/provider/Settings;->ACTION_TRUSTED_CREDENTIALS_USER:Ljava/lang/String;
Landroid/provider/Settings;->ACTION_USER_DICTIONARY_INSERT:Ljava/lang/String;
@@ -5357,6 +5376,7 @@
Landroid/telephony/ServiceState;->mCdmaRoamingIndicator:I
Landroid/telephony/ServiceState;->mCssIndicator:Z
Landroid/telephony/ServiceState;->mIsManualNetworkSelection:Z
+Landroid/telephony/ServiceState;->mIsUsingCarrierAggregation:Z
Landroid/telephony/ServiceState;->mNetworkId:I
Landroid/telephony/ServiceState;->mSystemId:I
Landroid/telephony/ServiceState;->newFromBundle(Landroid/os/Bundle;)Landroid/telephony/ServiceState;
@@ -5720,6 +5740,7 @@
Landroid/transition/Scene;->setCurrentScene(Landroid/view/View;Landroid/transition/Scene;)V
Landroid/transition/Transition;->cancel()V
Landroid/transition/Transition;->end()V
+Landroid/transition/Transition;->getRunningAnimators()Landroid/util/ArrayMap;
Landroid/transition/TransitionManager;->getRunningTransitions()Landroid/util/ArrayMap;
Landroid/transition/TransitionManager;->sPendingTransitions:Ljava/util/ArrayList;
Landroid/transition/TransitionManager;->sRunningTransitions:Ljava/lang/ThreadLocal;
@@ -6166,6 +6187,7 @@
Landroid/view/SurfaceControl;->HIDDEN:I
Landroid/view/SurfaceControl;->hide()V
Landroid/view/SurfaceControl;->openTransaction()V
+Landroid/view/SurfaceControl;->screenshot(Landroid/graphics/Rect;III)Landroid/graphics/Bitmap;
Landroid/view/SurfaceControl;->screenshot(Landroid/graphics/Rect;IIIIZI)Landroid/graphics/Bitmap;
Landroid/view/SurfaceControl;->screenshot(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V
Landroid/view/SurfaceControl;->setDisplayLayerStack(Landroid/os/IBinder;I)V
@@ -6959,6 +6981,7 @@
Landroid/widget/ListView;->fillSpecific(II)Landroid/view/View;
Landroid/widget/ListView;->fillUp(II)Landroid/view/View;
Landroid/widget/ListView;->getHeightForPosition(I)I
+Landroid/widget/ListView;->isDirectChildHeaderOrFooter(Landroid/view/View;)Z
Landroid/widget/ListView;->makeAndAddView(IIZIZ)Landroid/view/View;
Landroid/widget/ListView;->mAreAllItemsSelectable:Z
Landroid/widget/ListView;->mDivider:Landroid/graphics/drawable/Drawable;
@@ -7507,6 +7530,7 @@
Lcom/android/internal/appwidget/IAppWidgetService;->bindAppWidgetId(Ljava/lang/String;IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
Lcom/android/internal/appwidget/IAppWidgetService;->bindRemoteViewsService(Ljava/lang/String;ILandroid/content/Intent;Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/app/IServiceConnection;I)Z
Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetIds(Landroid/content/ComponentName;)[I
+Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetViews(Ljava/lang/String;I)Landroid/widget/RemoteViews;
Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
Lcom/android/internal/backup/IBackupTransport$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/backup/IBackupTransport;
Lcom/android/internal/backup/IBackupTransport;->clearBackupData(Landroid/content/pm/PackageInfo;)I
@@ -7723,6 +7747,9 @@
Lcom/android/internal/R$attr;->text:I
Lcom/android/internal/R$attr;->title:I
Lcom/android/internal/R$attr;->webViewStyle:I
+Lcom/android/internal/R$bool;-><init>()V
+Lcom/android/internal/R$bool;->config_automatic_brightness_available:I
+Lcom/android/internal/R$bool;->config_intrusiveNotificationLed:I
Lcom/android/internal/R$bool;->config_mms_content_disposition_support:I
Lcom/android/internal/R$bool;->config_showNavigationBar:I
Lcom/android/internal/R$dimen;-><init>()V
@@ -8146,6 +8173,8 @@
Lcom/android/internal/R$styleable;->Window:[I
Lcom/android/internal/R$styleable;->WindowAnimation:[I
Lcom/android/internal/R$styleable;->Window_windowActionBarFullscreenDecorLayout:I
+Lcom/android/internal/R$styleable;->Window_windowBackground:I
+Lcom/android/internal/R$styleable;->Window_windowFullscreen:I
Lcom/android/internal/R$styleable;->Window_windowIsFloating:I
Lcom/android/internal/R$styleable;->Window_windowIsTranslucent:I
Lcom/android/internal/R$styleable;->Window_windowShowWallpaper:I
@@ -8215,6 +8244,7 @@
Lcom/android/internal/telephony/IPhoneStateListener;->onSignalStrengthChanged(I)V
Lcom/android/internal/telephony/IPhoneStateListener;->onSignalStrengthsChanged(Landroid/telephony/SignalStrength;)V
Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
Lcom/android/internal/telephony/IPhoneSubInfo$Stub;-><init>()V
Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneSubInfo;
Lcom/android/internal/telephony/IPhoneSubInfo$Stub;->TRANSACTION_getDeviceId:I
@@ -8400,6 +8430,8 @@
Lcom/android/internal/view/menu/MenuBuilder;->addMenuPresenter(Lcom/android/internal/view/menu/MenuPresenter;Landroid/content/Context;)V
Lcom/android/internal/view/menu/MenuBuilder;->collapseItemActionView(Lcom/android/internal/view/menu/MenuItemImpl;)Z
Lcom/android/internal/view/menu/MenuBuilder;->getContext()Landroid/content/Context;
+Lcom/android/internal/view/menu/MenuBuilder;->getHeaderIcon()Landroid/graphics/drawable/Drawable;
+Lcom/android/internal/view/menu/MenuBuilder;->getHeaderTitle()Ljava/lang/CharSequence;
Lcom/android/internal/view/menu/MenuBuilder;->getNonActionItems()Ljava/util/ArrayList;
Lcom/android/internal/view/menu/MenuBuilder;->getRootMenu()Lcom/android/internal/view/menu/MenuBuilder;
Lcom/android/internal/view/menu/MenuBuilder;->getVisibleItems()Ljava/util/ArrayList;
@@ -8417,11 +8449,14 @@
Lcom/android/internal/view/menu/MenuItemImpl;->requestsActionButton()Z
Lcom/android/internal/view/menu/MenuItemImpl;->requiresActionButton()Z
Lcom/android/internal/view/menu/MenuItemImpl;->setActionViewExpanded(Z)V
+Lcom/android/internal/view/menu/MenuItemImpl;->setExclusiveCheckable(Z)V
Lcom/android/internal/view/menu/MenuItemImpl;->setMenuInfo(Landroid/view/ContextMenu$ContextMenuInfo;)V
Lcom/android/internal/view/menu/MenuPopupHelper;-><init>(Landroid/content/Context;Lcom/android/internal/view/menu/MenuBuilder;)V
Lcom/android/internal/view/menu/MenuPopupHelper;-><init>(Landroid/content/Context;Lcom/android/internal/view/menu/MenuBuilder;Landroid/view/View;)V
Lcom/android/internal/view/menu/MenuPopupHelper;->dismiss()V
+Lcom/android/internal/view/menu/MenuPopupHelper;->getPopup()Lcom/android/internal/view/menu/MenuPopup;
Lcom/android/internal/view/menu/MenuPopupHelper;->mForceShowIcon:Z
+Lcom/android/internal/view/menu/MenuPopupHelper;->setAnchorView(Landroid/view/View;)V
Lcom/android/internal/view/menu/MenuPopupHelper;->setForceShowIcon(Z)V
Lcom/android/internal/view/menu/MenuPopupHelper;->setGravity(I)V
Lcom/android/internal/view/menu/MenuPopupHelper;->show()V
@@ -8751,6 +8786,7 @@
Ljava/lang/reflect/Field;->getOffset()I
Ljava/lang/reflect/Parameter;-><init>(Ljava/lang/String;ILjava/lang/reflect/Executable;I)V
Ljava/lang/reflect/Proxy;->invoke(Ljava/lang/reflect/Proxy;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/Runtime;-><init>()V
Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V
Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V
Ljava/lang/Runtime;->loadLibrary0(Ljava/lang/ClassLoader;Ljava/lang/String;)V
@@ -9119,6 +9155,7 @@
Lorg/xml/sax/helpers/NamespaceSupport;->contexts:[Lorg/xml/sax/helpers/NamespaceSupport$Context;
Lorg/xml/sax/helpers/NamespaceSupport;->currentContext:Lorg/xml/sax/helpers/NamespaceSupport$Context;
Lorg/xml/sax/helpers/NamespaceSupport;->EMPTY_ENUMERATION:Ljava/util/Enumeration;
+Lorg/xml/sax/helpers/NamespaceSupport;->namespaceDeclUris:Z
Lorg/xml/sax/helpers/ParserAdapter;->attAdapter:Lorg/xml/sax/helpers/ParserAdapter$AttributeListAdapter;
Lorg/xml/sax/helpers/ParserAdapter;->atts:Lorg/xml/sax/helpers/AttributesImpl;
Lorg/xml/sax/helpers/ParserAdapter;->checkNotParsing(Ljava/lang/String;Ljava/lang/String;)V
@@ -9138,6 +9175,7 @@
Lorg/xml/sax/helpers/ParserAdapter;->reportError(Ljava/lang/String;)V
Lorg/xml/sax/helpers/ParserAdapter;->setup(Lorg/xml/sax/Parser;)V
Lorg/xml/sax/helpers/ParserAdapter;->setupParser()V
+Lorg/xml/sax/helpers/ParserAdapter;->uris:Z
Lorg/xml/sax/helpers/XMLFilterImpl;->contentHandler:Lorg/xml/sax/ContentHandler;
Lorg/xml/sax/helpers/XMLFilterImpl;->dtdHandler:Lorg/xml/sax/DTDHandler;
Lorg/xml/sax/helpers/XMLFilterImpl;->entityResolver:Lorg/xml/sax/EntityResolver;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 4e6cc7e..2fdb715 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -21,6 +21,7 @@
import android.content.ComponentName;
import android.content.IIntentSender;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.IBinder;
@@ -41,6 +42,11 @@
public abstract class ActivityManagerInternal {
+ // Access modes for handleIncomingUser.
+ public static final int ALLOW_NON_FULL = 0;
+ public static final int ALLOW_NON_FULL_IN_PROFILE = 1;
+ public static final int ALLOW_FULL_ONLY = 2;
+
/**
* Grant Uri permissions from one app to another. This method only extends
* permission grants if {@code callingUid} has permission to them.
@@ -63,15 +69,6 @@
String processName, String abiOverride, int uid, Runnable crashHandler);
/**
- * Called when a user has been deleted. This can happen during normal device usage
- * or just at startup, when partially removed users are purged. Any state persisted by the
- * ActivityManager should be purged now.
- *
- * @param userId The user being cleaned up.
- */
- public abstract void onUserRemoved(int userId);
-
- /**
* Kill foreground apps from the specified user.
*/
public abstract void killForegroundAppsForUser(int userHandle);
@@ -95,15 +92,6 @@
boolean adding);
/**
- * Updates and persists the {@link Configuration} for a given user.
- *
- * @param values the configuration to update
- * @param userId the user to update the configuration for
- */
- public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values,
- int userId);
-
- /**
* Get the procstate for the UID. The return value will be between
* {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}.
* Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT}
@@ -155,17 +143,6 @@
public abstract void clearSavedANRState();
/**
- * Set a uid that is allowed to bypass stopped app switches, launching an app
- * whenever it wants.
- *
- * @param type Type of the caller -- unique string the caller supplies to identify itself
- * and disambiguate with other calles.
- * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type.
- * @param userId The user it is allowed for.
- */
- public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId);
-
- /**
* @return true if runtime was restarted, false if it's normal boot
*/
public abstract boolean isRuntimeRestarted();
@@ -199,4 +176,32 @@
* Returns a list that contains the memory stats for currently running processes.
*/
public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
+
+ /**
+ * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
+ * needed.
+ */
+ public abstract int handleIncomingUser(int callingPid, int callingUid, int userId,
+ boolean allowAll, int allowMode, String name, String callerPackage);
+
+ /** Checks if the calling binder pid as the permission. */
+ public abstract void enforceCallingPermission(String permission, String func);
+
+ /** Returns the current user id. */
+ public abstract int getCurrentUserId();
+
+ /** Returns true if the user is running. */
+ public abstract boolean isUserRunning(int userId, int flags);
+
+ /** Trims memory usage in the system by removing/stopping unused application processes. */
+ public abstract void trimApplications();
+
+ /** Returns the screen compatibility mode for the given application. */
+ public abstract int getPackageScreenCompatMode(ApplicationInfo ai);
+
+ /** Sets the screen compatibility mode for the given application. */
+ public abstract void setPackageScreenCompatMode(ApplicationInfo ai, int mode);
+
+ /** Closes all system dialogs. */
+ public abstract void closeSystemDialogs(String reason);
}
diff --git a/core/java/android/app/ActivityTaskManagerInternal.java b/core/java/android/app/ActivityTaskManagerInternal.java
index 170cb52..fa78db5 100644
--- a/core/java/android/app/ActivityTaskManagerInternal.java
+++ b/core/java/android/app/ActivityTaskManagerInternal.java
@@ -243,4 +243,24 @@
*/
public abstract void notifyActiveVoiceInteractionServiceChanged(ComponentName component);
+ /**
+ * Set a uid that is allowed to bypass stopped app switches, launching an app
+ * whenever it wants.
+ *
+ * @param type Type of the caller -- unique string the caller supplies to identify itself
+ * and disambiguate with other calles.
+ * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type.
+ * @param userId The user it is allowed for.
+ */
+ public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId);
+
+ /**
+ * Called when a user has been deleted. This can happen during normal device usage
+ * or just at startup, when partially removed users are purged. Any state persisted by the
+ * ActivityManager should be purged now.
+ *
+ * @param userId The user being cleaned up.
+ */
+ public abstract void onUserStopped(int userId);
+ public abstract boolean isGetTasksAllowed(String caller, int callingPid, int callingUid);
}
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index a508289..1eb187e 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -418,4 +418,7 @@
void setVrThread(int tid);
void setPersistentVrThread(int tid);
+ void stopAppSwitches();
+ void resumeAppSwitches();
+ void setActivityController(in IActivityController watcher, boolean imAMonkey);
}
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index 09c7981..7a729f9 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -59,11 +59,6 @@
/** The current windowing mode of the configuration. */
private @WindowingMode int mWindowingMode;
- private int mFlags;
-
- /** Indicates that this window should always be on top of the other windows. */
- private static final int PFLAG_ALWAYS_ON_TOP = 1 << 0;
-
/** Windowing mode is currently not defined. */
public static final int WINDOWING_MODE_UNDEFINED = 0;
/** Occupies the full area of the screen or the parent container. */
@@ -129,6 +124,24 @@
})
public @interface ActivityType {}
+ /** The current always on top status of the configuration. */
+ private @AlwaysOnTop int mAlwaysOnTop;
+
+ /** Always on top is currently not defined. */
+ private static final int ALWAYS_ON_TOP_UNDEFINED = 0;
+ /** Always on top is currently on for this configuration. */
+ private static final int ALWAYS_ON_TOP_ON = 1;
+ /** Always on top is currently off for this configuration. */
+ private static final int ALWAYS_ON_TOP_OFF = 2;
+
+ /** @hide */
+ @IntDef(prefix = { "ALWAYS_ON_TOP_" }, value = {
+ ALWAYS_ON_TOP_UNDEFINED,
+ ALWAYS_ON_TOP_ON,
+ ALWAYS_ON_TOP_OFF,
+ })
+ private @interface AlwaysOnTop {}
+
/** Bit that indicates that the {@link #mBounds} changed.
* @hide */
public static final int WINDOW_CONFIG_BOUNDS = 1 << 0;
@@ -141,16 +154,16 @@
/** Bit that indicates that the {@link #mActivityType} changed.
* @hide */
public static final int WINDOW_CONFIG_ACTIVITY_TYPE = 1 << 3;
- /** Bit that indicates that the {@link #mFlags} changed.
+ /** Bit that indicates that the {@link #mAlwaysOnTop} changed.
* @hide */
- public static final int WINDOW_CONFIG_FLAGS = 1 << 4;
+ public static final int WINDOW_CONFIG_ALWAYS_ON_TOP = 1 << 4;
/** @hide */
@IntDef(flag = true, prefix = { "WINDOW_CONFIG_" }, value = {
WINDOW_CONFIG_BOUNDS,
WINDOW_CONFIG_APP_BOUNDS,
WINDOW_CONFIG_WINDOWING_MODE,
WINDOW_CONFIG_ACTIVITY_TYPE,
- WINDOW_CONFIG_FLAGS
+ WINDOW_CONFIG_ALWAYS_ON_TOP,
})
public @interface WindowConfig {}
@@ -176,7 +189,7 @@
dest.writeParcelable(mAppBounds, flags);
dest.writeInt(mWindowingMode);
dest.writeInt(mActivityType);
- dest.writeInt(mFlags);
+ dest.writeInt(mAlwaysOnTop);
}
private void readFromParcel(Parcel source) {
@@ -184,7 +197,7 @@
mAppBounds = source.readParcelable(Rect.class.getClassLoader());
mWindowingMode = source.readInt();
mActivityType = source.readInt();
- mFlags = source.readInt();
+ mAlwaysOnTop = source.readInt();
}
@Override
@@ -232,9 +245,7 @@
setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
}
- private void setFlags(int flags) {
- mFlags = flags;
- }
+
/**
* Sets whether this window should be always on top.
@@ -242,11 +253,11 @@
* @hide
*/
public void setAlwaysOnTop(boolean alwaysOnTop) {
- if (alwaysOnTop) {
- mFlags |= PFLAG_ALWAYS_ON_TOP;
- } else {
- mFlags &= ~PFLAG_ALWAYS_ON_TOP;
- }
+ mAlwaysOnTop = alwaysOnTop ? ALWAYS_ON_TOP_ON : ALWAYS_ON_TOP_OFF;
+ }
+
+ private void setAlwaysOnTop(@AlwaysOnTop int alwaysOnTop) {
+ mAlwaysOnTop = alwaysOnTop;
}
/**
@@ -308,7 +319,7 @@
setAppBounds(other.mAppBounds);
setWindowingMode(other.mWindowingMode);
setActivityType(other.mActivityType);
- setFlags(other.mFlags);
+ setAlwaysOnTop(other.mAlwaysOnTop);
}
/** Set this object to completely undefined.
@@ -323,7 +334,7 @@
setBounds(null);
setWindowingMode(WINDOWING_MODE_UNDEFINED);
setActivityType(ACTIVITY_TYPE_UNDEFINED);
- setFlags(0);
+ setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
}
/**
@@ -341,10 +352,6 @@
changed |= WINDOW_CONFIG_BOUNDS;
setBounds(delta.mBounds);
}
- if (delta.mFlags != mFlags) {
- changed |= WINDOW_CONFIG_FLAGS;
- setFlags(delta.mFlags);
- }
if (delta.mAppBounds != null && !delta.mAppBounds.equals(mAppBounds)) {
changed |= WINDOW_CONFIG_APP_BOUNDS;
setAppBounds(delta.mAppBounds);
@@ -359,6 +366,11 @@
changed |= WINDOW_CONFIG_ACTIVITY_TYPE;
setActivityType(delta.mActivityType);
}
+ if (delta.mAlwaysOnTop != ALWAYS_ON_TOP_UNDEFINED
+ && mAlwaysOnTop != delta.mAlwaysOnTop) {
+ changed |= WINDOW_CONFIG_ALWAYS_ON_TOP;
+ setAlwaysOnTop(delta.mAlwaysOnTop);
+ }
return changed;
}
@@ -380,10 +392,6 @@
changes |= WINDOW_CONFIG_BOUNDS;
}
- if (mFlags != other.mFlags) {
- changes |= WINDOW_CONFIG_FLAGS;
- }
-
// Make sure that one of the values is not null and that they are not equal.
if ((compareUndefined || other.mAppBounds != null)
&& mAppBounds != other.mAppBounds
@@ -401,6 +409,11 @@
changes |= WINDOW_CONFIG_ACTIVITY_TYPE;
}
+ if ((compareUndefined || other.mAlwaysOnTop != ALWAYS_ON_TOP_UNDEFINED)
+ && mAlwaysOnTop != other.mAlwaysOnTop) {
+ changes |= WINDOW_CONFIG_ALWAYS_ON_TOP;
+ }
+
return changes;
}
@@ -435,8 +448,7 @@
if (n != 0) return n;
n = mActivityType - that.mActivityType;
if (n != 0) return n;
-
- n = mFlags - that.mFlags;
+ n = mAlwaysOnTop - that.mAlwaysOnTop;
if (n != 0) return n;
// if (n != 0) return n;
@@ -465,7 +477,7 @@
result = 31 * result + mWindowingMode;
result = 31 * result + mActivityType;
- result = 31 * result + mFlags;
+ result = 31 * result + mAlwaysOnTop;
return result;
}
@@ -476,7 +488,7 @@
+ " mAppBounds=" + mAppBounds
+ " mWindowingMode=" + windowingModeToString(mWindowingMode)
+ " mActivityType=" + activityTypeToString(mActivityType)
- + " mFlags=0x" + Integer.toHexString(mFlags)
+ + " mAlwaysOnTop=" + activityTypeToString(mAlwaysOnTop)
+ "}";
}
@@ -563,7 +575,7 @@
* @hide
*/
public boolean isAlwaysOnTop() {
- return mWindowingMode == WINDOWING_MODE_PINNED || (mFlags & PFLAG_ALWAYS_ON_TOP) != 0;
+ return mWindowingMode == WINDOWING_MODE_PINNED || mAlwaysOnTop == ALWAYS_ON_TOP_ON;
}
/**
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index c56b685..414c463 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -725,7 +725,7 @@
* Get the minimum {@link CaptureRequest#SENSOR_FRAME_DURATION frame duration}
* for the class/size combination (in nanoseconds).
*
- * <p>This assumes a the {@code klass} is set up to use {@link ImageFormat#PRIVATE}.
+ * <p>This assumes that the {@code klass} is set up to use {@link ImageFormat#PRIVATE}.
* For user-defined formats, use {@link #getOutputMinFrameDuration(int, Size)}.</p>
*
* <p>{@code klass} should be one of the ones which is supported by
@@ -870,7 +870,7 @@
/**
* Get the stall duration for the class/size combination (in nanoseconds).
*
- * <p>This assumes a the {@code klass} is set up to use {@link ImageFormat#PRIVATE}.
+ * <p>This assumes that the {@code klass} is set up to use {@link ImageFormat#PRIVATE}.
* For user-defined formats, use {@link #getOutputMinFrameDuration(int, Size)}.</p>
*
* <p>{@code klass} should be one of the ones with a non-empty array returned by
diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java
new file mode 100644
index 0000000..60eb5c3
--- /dev/null
+++ b/core/java/android/os/RedactingFileDescriptor.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.content.Context;
+import android.os.storage.StorageManager;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Slog;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+/**
+ * Variant of {@link FileDescriptor} that allows its creator to specify regions
+ * that should be redacted (appearing as zeros to the reader).
+ *
+ * @hide
+ */
+public class RedactingFileDescriptor {
+ private static final String TAG = "RedactingFileDescriptor";
+ private static final boolean DEBUG = true;
+
+ private final long[] mRedactRanges;
+
+ private FileDescriptor mInner = null;
+ private ParcelFileDescriptor mOuter = null;
+
+ private RedactingFileDescriptor(Context context, File file, long[] redactRanges)
+ throws IOException {
+ mRedactRanges = checkRangesArgument(redactRanges);
+
+ try {
+ try {
+ mInner = Os.open(file.getAbsolutePath(), OsConstants.O_RDONLY, 0);
+ mOuter = context.getSystemService(StorageManager.class)
+ .openProxyFileDescriptor(ParcelFileDescriptor.MODE_READ_ONLY, mCallback);
+ } catch (ErrnoException e) {
+ throw e.rethrowAsIOException();
+ }
+ } catch (IOException e) {
+ IoUtils.closeQuietly(mInner);
+ IoUtils.closeQuietly(mOuter);
+ throw e;
+ }
+ }
+
+ private static long[] checkRangesArgument(long[] ranges) {
+ if (ranges.length % 2 != 0) {
+ throw new IllegalArgumentException();
+ }
+ for (int i = 0; i < ranges.length - 1; i += 2) {
+ if (ranges[i] > ranges[i + 1]) {
+ throw new IllegalArgumentException();
+ }
+ }
+ return ranges;
+ }
+
+ /**
+ * Open the given {@link File} and returns a {@link ParcelFileDescriptor}
+ * that offers a redacted, read-only view of the underlying data.
+ *
+ * @param file The underlying file to open.
+ * @param redactRanges List of file offsets that should be redacted, stored
+ * as {@code [start1, end1, start2, end2, ...]}. Start values are
+ * inclusive and end values are exclusive.
+ */
+ public static ParcelFileDescriptor open(Context context, File file, long[] redactRanges)
+ throws IOException {
+ return new RedactingFileDescriptor(context, file, redactRanges).mOuter;
+ }
+
+ private final ProxyFileDescriptorCallback mCallback = new ProxyFileDescriptorCallback() {
+ @Override
+ public long onGetSize() throws ErrnoException {
+ return Os.fstat(mInner).st_size;
+ }
+
+ @Override
+ public int onRead(long offset, int size, byte[] data) throws ErrnoException {
+ int n = 0;
+ while (n < size) {
+ try {
+ final int res = Os.pread(mInner, data, n, size - n, offset + n);
+ if (res == 0) {
+ break;
+ } else {
+ n += res;
+ }
+ } catch (InterruptedIOException e) {
+ n += e.bytesTransferred;
+ }
+ }
+
+ // Redact any relevant ranges before returning
+ final long[] ranges = mRedactRanges;
+ for (int i = 0; i < ranges.length; i += 2) {
+ final long start = Math.max(offset, ranges[i]);
+ final long end = Math.min(offset + size, ranges[i + 1]);
+ for (long j = start; j < end; j++) {
+ data[(int) (j - offset)] = 0;
+ }
+ }
+ return n;
+ }
+
+ @Override
+ public int onWrite(long offset, int size, byte[] data) throws ErrnoException {
+ throw new ErrnoException(TAG, OsConstants.EBADF);
+ }
+
+ @Override
+ public void onFsync() throws ErrnoException {
+ Os.fsync(mInner);
+ }
+
+ @Override
+ public void onRelease() {
+ if (DEBUG) Slog.v(TAG, "onRelease()");
+ IoUtils.closeQuietly(mInner);
+ }
+ };
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a9cc1ee..6edcec1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9935,6 +9935,14 @@
public static final String WIFI_DATA_STALL_MIN_TX_SUCCESS_WITHOUT_RX =
"wifi_data_stall_min_tx_success_without_rx";
+ /**
+ * Setting to enable logging Wifi LinkSpeedCounts in metrics.
+ * Disabled by default, and setting it to 1 will enable it.
+ * @hide
+ */
+ public static final String WIFI_LINK_SPEED_METRICS_ENABLED =
+ "wifi_link_speed_metrics_enabled";
+
/**
* The maximum number of times we will retry a connection to an access
* point for which we have failed in acquiring an IP address from DHCP.
diff --git a/core/java/android/view/DisplayListCanvas.java b/core/java/android/view/DisplayListCanvas.java
index 671532c..df4d5c4 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/core/java/android/view/DisplayListCanvas.java
@@ -180,13 +180,12 @@
///////////////////////////////////////////////////////////////////////////
/**
- * Draws the specified display list onto this canvas. The display list can only
- * be drawn if {@link android.view.RenderNode#isValid()} returns true.
+ * Draws the specified display list onto this canvas.
*
* @param renderNode The RenderNode to draw.
*/
public void drawRenderNode(RenderNode renderNode) {
- nDrawRenderNode(mNativeCanvasWrapper, renderNode.getNativeDisplayList());
+ nDrawRenderNode(mNativeCanvasWrapper, renderNode.mNativeRenderNode);
}
///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
index 7c25fac..e10eeb0 100644
--- a/core/java/android/view/RenderNode.java
+++ b/core/java/android/view/RenderNode.java
@@ -139,7 +139,9 @@
RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
}
- // Do not access directly unless you are ThreadedRenderer
+ /** Not for general use; use only if you are ThreadedRenderer or DisplayListCanvas.
+ * @hide
+ */
final long mNativeRenderNode;
private final View mOwningView;
@@ -159,15 +161,6 @@
}
/**
- * Immediately destroys the RenderNode
- * Only suitable for testing/benchmarking where waiting for the GC/finalizer
- * is not feasible.
- */
- public void destroy() {
- // TODO: Removed temporarily
- }
-
- /**
* Creates a new RenderNode that can be used to record batches of
* drawing operations, and store / apply render properties when drawn.
*
@@ -219,6 +212,14 @@
}
/**
+ * Same as {@link #start(int, int)} but with the RenderNode's width & height
+ */
+ public DisplayListCanvas start() {
+ return DisplayListCanvas.obtain(this,
+ nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
+ }
+
+ /**
* Ends the recording for this display list. A display list cannot be
* replayed if recording is not finished. Calling this method marks
* the display list valid and {@link #isValid()} will return true.
@@ -251,13 +252,6 @@
return nIsValid(mNativeRenderNode);
}
- long getNativeDisplayList() {
- if (!isValid()) {
- throw new IllegalStateException("The display list is not valid.");
- }
- return mNativeRenderNode;
- }
-
///////////////////////////////////////////////////////////////////////////
// Matrix manipulation
///////////////////////////////////////////////////////////////////////////
@@ -463,7 +457,6 @@
* @see #setHasOverlappingRendering(boolean)
*/
public boolean hasOverlappingRendering() {
- //noinspection SimplifiableIfStatement
return nHasOverlappingRendering(mNativeRenderNode);
}
@@ -1009,4 +1002,8 @@
private static native float nGetPivotX(long renderNode);
@CriticalNative
private static native float nGetPivotY(long renderNode);
+ @CriticalNative
+ private static native int nGetWidth(long renderNode);
+ @CriticalNative
+ private static native int nGetHeight(long renderNode);
}
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index aa1e407..2f975b6 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -850,7 +850,9 @@
void buildLayer(RenderNode node) {
- nBuildLayer(mNativeProxy, node.getNativeDisplayList());
+ if (node.isValid()) {
+ nBuildLayer(mNativeProxy, node.mNativeRenderNode);
+ }
}
@@ -928,7 +930,7 @@
* not the RenderNode from a View.
**/
public static Bitmap createHardwareBitmap(RenderNode node, int width, int height) {
- return nCreateHardwareBitmap(node.getNativeDisplayList(), width, height);
+ return nCreateHardwareBitmap(node.mNativeRenderNode, width, height);
}
/**
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 276f50a..e4c595b 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -531,7 +531,6 @@
throws IOException {
RenderNode node = RenderNode.create("ViewDebug", null);
profileViewAndChildren(view, node, out, true);
- node.destroy();
}
private static void profileViewAndChildren(View view, RenderNode node, BufferedWriter out,
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7e6af49..63ee624 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1239,7 +1239,7 @@
}
boolean startInputInner(@InputMethodClient.StartInputReason final int startInputReason,
- IBinder windowGainingFocus, int controlFlags, int softInputMode,
+ @Nullable IBinder windowGainingFocus, int controlFlags, int softInputMode,
int windowFlags) {
final View view;
synchronized (mH) {
@@ -1256,6 +1256,20 @@
}
}
+ if (windowGainingFocus == null) {
+ windowGainingFocus = view.getWindowToken();
+ if (windowGainingFocus == null) {
+ Log.e(TAG, "ABORT input: ServedView must be attached to a Window");
+ return false;
+ }
+ controlFlags |= CONTROL_WINDOW_VIEW_HAS_FOCUS;
+ if (view.onCheckIsTextEditor()) {
+ controlFlags |= CONTROL_WINDOW_IS_TEXT_EDITOR;
+ }
+ softInputMode = view.getViewRootImpl().mWindowAttributes.softInputMode;
+ windowFlags = view.getViewRootImpl().mWindowAttributes.flags;
+ }
+
// Now we need to get an input connection from the served view.
// This is complicated in a couple ways: we can't be holding our lock
// when calling out to the view, and we need to make sure we call into
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 929496f..11054c8 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -611,7 +611,6 @@
mRenderer.destroy();
mSurfaceControl.destroy();
mSurfaceSession.kill();
- mBitmapRenderNode.destroy();
mHandler.removeCallbacks(mMagnifierUpdater);
if (mBitmap != null) {
mBitmap.recycle();
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 37ea810..22bbc3c 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -431,6 +431,14 @@
return renderNode->stagingProperties().getPivotY();
}
+static jint android_view_RenderNode_getWidth(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getWidth();
+}
+
+static jint android_view_RenderNode_getHeight(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getHeight();
+}
+
// ----------------------------------------------------------------------------
// RenderProperties - Animations
// ----------------------------------------------------------------------------
@@ -648,6 +656,8 @@
{ "nGetPivotX", "(J)F", (void*) android_view_RenderNode_getPivotX },
{ "nGetPivotY", "(J)F", (void*) android_view_RenderNode_getPivotY },
+ { "nGetWidth", "(J)I", (void*) android_view_RenderNode_getWidth },
+ { "nGetHeight", "(J)I", (void*) android_view_RenderNode_getHeight },
};
int register_android_view_RenderNode(JNIEnv* env) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d12a05b..c601215 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -262,6 +262,7 @@
<protected-broadcast android:name="android.intent.action.HEADSET_PLUG" />
<protected-broadcast android:name="android.media.action.HDMI_AUDIO_PLUG" />
+ <protected-broadcast android:name="android.media.action.MICROPHONE_MUTE_CHANGED" />
<protected-broadcast android:name="android.media.AUDIO_BECOMING_NOISY" />
<protected-broadcast android:name="android.media.RINGER_MODE_CHANGED" />
@@ -2257,7 +2258,8 @@
android:description="@string/permdesc_install_shortcut"
android:protectionLevel="normal"/>
- <!--This permission is no longer supported.
+ <!-- <p class="caution"><strong>Don't use this permission in your app.</strong><br>This
+ permission is no longer supported.
-->
<permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:label="@string/permlab_uninstall_shortcut"
@@ -3995,6 +3997,11 @@
<permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
android:protectionLevel="signature" />
+ <!-- Allows an application to read emergency info name.
+ @hide <p>Not for use by third-party applications. -->
+ <permission android:name="com.android.emergency.permission.READ_EMERGENCY_INFO_NAME"
+ android:protectionLevel="signature" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index a129521..408a4d0 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3479,4 +3479,6 @@
<!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
<bool name="config_swipe_up_gesture_setting_available">false</bool>
+ <!-- Whether or not we should show the option to show battery percentage -->
+ <bool name="config_battery_percentage_setting_available">true</bool>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9ac80e7..d9642cb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2200,6 +2200,7 @@
<java-symbol type="string" name="ext_media_move_failure_message" />
<java-symbol type="style" name="Animation.RecentApplications" />
<java-symbol type="integer" name="dock_enter_exit_duration" />
+ <java-symbol type="bool" name="config_battery_percentage_setting_available" />
<!-- ImfTest -->
<java-symbol type="layout" name="auto_complete_list" />
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
new file mode 100644
index 0000000..c8bc35c
--- /dev/null
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.system.Os;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Arrays;
+
+@RunWith(AndroidJUnit4.class)
+public class RedactingFileDescriptorTest {
+ private Context mContext;
+ private File mFile;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mFile = File.createTempFile("redacting", "dat");
+ try (FileOutputStream out = new FileOutputStream(mFile)) {
+ final byte[] buf = new byte[1_000_000];
+ Arrays.fill(buf, (byte) 64);
+ out.write(buf);
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mFile.delete();
+ }
+
+ @Test
+ public void testSingleByte() throws Exception {
+ final FileDescriptor fd = RedactingFileDescriptor
+ .open(mContext, mFile, new long[] { 10, 11 }).getFileDescriptor();
+
+ final byte[] buf = new byte[1_000];
+ assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
+ for (int i = 0; i < buf.length; i++) {
+ if (i == 10) {
+ assertEquals(0, buf[i]);
+ } else {
+ assertEquals(64, buf[i]);
+ }
+ }
+ }
+
+ @Test
+ public void testRanges() throws Exception {
+ final FileDescriptor fd = RedactingFileDescriptor
+ .open(mContext, mFile, new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+
+ final byte[] buf = new byte[10];
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
+ assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 }, buf);
+
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95));
+ assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 0, 0, 0 }, buf);
+
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 100));
+ assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, buf);
+
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 195));
+ assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 64, 64, 64, 64, 64 }, buf);
+
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 395));
+ assertArrayEquals(new byte[] { 0, 0, 0, 0, 0, 64, 64, 64, 64, 64 }, buf);
+ }
+
+ @Test
+ public void testEntireFile() throws Exception {
+ final FileDescriptor fd = RedactingFileDescriptor
+ .open(mContext, mFile, new long[] { 0, 5_000_000 }).getFileDescriptor();
+
+ try (FileInputStream in = new FileInputStream(fd)) {
+ int val;
+ while ((val = in.read()) != -1) {
+ assertEquals(0, val);
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 676d8d9..c22dd13 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -471,6 +471,7 @@
Settings.Global.WIFI_FREQUENCY_BAND,
Settings.Global.WIFI_IDLE_MS,
Settings.Global.WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED,
+ Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED,
Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
Settings.Global.WIFI_NETWORK_SHOW_RSSI,
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 62f820a..10edf73 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -31,44 +31,242 @@
namespace uirenderer {
namespace renderthread {
-#define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(instance, "vk" #F)
-#define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(device, "vk" #F)
+#define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F)
+#define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F)
+#define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F)
VulkanManager::VulkanManager(RenderThread& thread) : mRenderThread(thread) {}
void VulkanManager::destroy() {
- if (!hasVkContext()) return;
-
mRenderThread.renderState().onVkContextDestroyed();
mRenderThread.setGrContext(nullptr);
if (VK_NULL_HANDLE != mCommandPool) {
- mDestroyCommandPool(mBackendContext->fDevice, mCommandPool, nullptr);
+ mDestroyCommandPool(mDevice, mCommandPool, nullptr);
mCommandPool = VK_NULL_HANDLE;
}
- mBackendContext.reset();
-}
-void VulkanManager::initialize() {
- if (hasVkContext()) {
- return;
+ if (mDevice != VK_NULL_HANDLE) {
+ mDeviceWaitIdle(mDevice);
+ mDestroyDevice(mDevice, nullptr);
}
- auto canPresent = [](VkInstance, VkPhysicalDevice, uint32_t) { return true; };
+ if (mInstance != VK_NULL_HANDLE) {
+ mDestroyInstance(mInstance, nullptr);
+ }
- mBackendContext.reset(GrVkBackendContext::Create(vkGetInstanceProcAddr, vkGetDeviceProcAddr,
- &mPresentQueueIndex, canPresent));
- LOG_ALWAYS_FATAL_IF(!mBackendContext.get());
+ mGraphicsQueue = VK_NULL_HANDLE;
+ mPresentQueue = VK_NULL_HANDLE;
+ mDevice = VK_NULL_HANDLE;
+ mPhysicalDevice = VK_NULL_HANDLE;
+ mInstance = VK_NULL_HANDLE;
+}
- // Get all the addresses of needed vulkan functions
- VkInstance instance = mBackendContext->fInstance;
- VkDevice device = mBackendContext->fDevice;
- GET_PROC(CreateAndroidSurfaceKHR);
- GET_PROC(DestroySurfaceKHR);
- GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
- GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
- GET_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
- GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
+bool VulkanManager::setupDevice(VkPhysicalDeviceFeatures& deviceFeatures) {
+ VkResult err;
+
+ constexpr VkApplicationInfo app_info = {
+ VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
+ nullptr, // pNext
+ "android framework", // pApplicationName
+ 0, // applicationVersion
+ "android framework", // pEngineName
+ 0, // engineVerison
+ VK_MAKE_VERSION(1, 0, 0), // apiVersion
+ };
+
+ std::vector<const char*> instanceExtensions;
+ {
+ GET_PROC(EnumerateInstanceExtensionProperties);
+
+ uint32_t extensionCount = 0;
+ err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
+ if (VK_SUCCESS != err) {
+ return false;
+ }
+ std::unique_ptr<VkExtensionProperties[]> extensions(
+ new VkExtensionProperties[extensionCount]);
+ err = mEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.get());
+ if (VK_SUCCESS != err) {
+ return false;
+ }
+ bool hasKHRSurfaceExtension = false;
+ bool hasKHRAndroidSurfaceExtension = false;
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ instanceExtensions.push_back(extensions[i].extensionName);
+ if (!strcmp(extensions[i].extensionName, VK_KHR_SURFACE_EXTENSION_NAME)) {
+ hasKHRSurfaceExtension = true;
+ }
+ if (!strcmp(extensions[i].extensionName,VK_KHR_ANDROID_SURFACE_EXTENSION_NAME)) {
+ hasKHRAndroidSurfaceExtension = true;
+ }
+ }
+ if (!hasKHRSurfaceExtension || !hasKHRAndroidSurfaceExtension) {
+ this->destroy();
+ return false;
+ }
+ }
+
+ const VkInstanceCreateInfo instance_create = {
+ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
+ nullptr, // pNext
+ 0, // flags
+ &app_info, // pApplicationInfo
+ 0, // enabledLayerNameCount
+ nullptr, // ppEnabledLayerNames
+ (uint32_t) instanceExtensions.size(), // enabledExtensionNameCount
+ instanceExtensions.data(), // ppEnabledExtensionNames
+ };
+
+ GET_PROC(CreateInstance);
+ err = mCreateInstance(&instance_create, nullptr, &mInstance);
+ if (err < 0) {
+ this->destroy();
+ return false;
+ }
+
+ GET_INST_PROC(DestroyInstance);
+ GET_INST_PROC(EnumeratePhysicalDevices);
+ GET_INST_PROC(GetPhysicalDeviceQueueFamilyProperties);
+ GET_INST_PROC(GetPhysicalDeviceFeatures);
+ GET_INST_PROC(CreateDevice);
+ GET_INST_PROC(EnumerateDeviceExtensionProperties);
+ GET_INST_PROC(CreateAndroidSurfaceKHR);
+ GET_INST_PROC(DestroySurfaceKHR);
+ GET_INST_PROC(GetPhysicalDeviceSurfaceSupportKHR);
+ GET_INST_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
+ GET_INST_PROC(GetPhysicalDeviceSurfaceFormatsKHR);
+ GET_INST_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
+
+ uint32_t gpuCount;
+ err = mEnumeratePhysicalDevices(mInstance, &gpuCount, nullptr);
+ if (err) {
+ this->destroy();
+ return false;
+ }
+ if (!gpuCount) {
+ this->destroy();
+ return false;
+ }
+ // Just returning the first physical device instead of getting the whole array. Since there
+ // should only be one device on android.
+ gpuCount = 1;
+ err = mEnumeratePhysicalDevices(mInstance, &gpuCount, &mPhysicalDevice);
+ // VK_INCOMPLETE is returned when the count we provide is less than the total device count.
+ if (err && VK_INCOMPLETE != err) {
+ this->destroy();
+ return false;
+ }
+
+ // query to get the initial queue props size
+ uint32_t queueCount;
+ mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr);
+ if (!queueCount) {
+ this->destroy();
+ return false;
+ }
+
+ // now get the actual queue props
+ std::unique_ptr<VkQueueFamilyProperties[]> queueProps(new VkQueueFamilyProperties[queueCount]);
+ mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, queueProps.get());
+
+ // iterate to find the graphics queue
+ mGraphicsQueueIndex = queueCount;
+ for (uint32_t i = 0; i < queueCount; i++) {
+ if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ mGraphicsQueueIndex = i;
+ break;
+ }
+ }
+ if (mGraphicsQueueIndex == queueCount) {
+ this->destroy();
+ return false;
+ }
+
+ // All physical devices and queue families on Android must be capable of
+ // presentation with any native window. So just use the first one.
+ mPresentQueueIndex = 0;
+
+ std::vector<const char*> deviceExtensions;
+ {
+ uint32_t extensionCount = 0;
+ err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
+ nullptr);
+ if (VK_SUCCESS != err) {
+ this->destroy();
+ return false;
+ }
+ std::unique_ptr<VkExtensionProperties[]> extensions(
+ new VkExtensionProperties[extensionCount]);
+ err = mEnumerateDeviceExtensionProperties(mPhysicalDevice, nullptr, &extensionCount,
+ extensions.get());
+ if (VK_SUCCESS != err) {
+ this->destroy();
+ return false;
+ }
+ bool hasKHRSwapchainExtension = false;
+ for (uint32_t i = 0; i < extensionCount; ++i) {
+ deviceExtensions.push_back(extensions[i].extensionName);
+ if (!strcmp(extensions[i].extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
+ hasKHRSwapchainExtension = true;
+ }
+ }
+ if (!hasKHRSwapchainExtension) {
+ this->destroy();
+ return false;
+ }
+ }
+
+ // query to get the physical device properties
+ mGetPhysicalDeviceFeatures(mPhysicalDevice, &deviceFeatures);
+ // this looks like it would slow things down,
+ // and we can't depend on it on all platforms
+ deviceFeatures.robustBufferAccess = VK_FALSE;
+
+ float queuePriorities[1] = { 0.0 };
+
+ const VkDeviceQueueCreateInfo queueInfo[2] = {
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+ nullptr, // pNext
+ 0, // VkDeviceQueueCreateFlags
+ mGraphicsQueueIndex, // queueFamilyIndex
+ 1, // queueCount
+ queuePriorities, // pQueuePriorities
+ },
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
+ nullptr, // pNext
+ 0, // VkDeviceQueueCreateFlags
+ mPresentQueueIndex, // queueFamilyIndex
+ 1, // queueCount
+ queuePriorities, // pQueuePriorities
+ }
+ };
+ uint32_t queueInfoCount = (mPresentQueueIndex != mGraphicsQueueIndex) ? 2 : 1;
+
+ const VkDeviceCreateInfo deviceInfo = {
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
+ nullptr, // pNext
+ 0, // VkDeviceCreateFlags
+ queueInfoCount, // queueCreateInfoCount
+ queueInfo, // pQueueCreateInfos
+ 0, // layerCount
+ nullptr, // ppEnabledLayerNames
+ (uint32_t) deviceExtensions.size(), // extensionCount
+ deviceExtensions.data(), // ppEnabledExtensionNames
+ &deviceFeatures // ppEnabledFeatures
+ };
+
+ err = mCreateDevice(mPhysicalDevice, &deviceInfo, nullptr, &mDevice);
+ if (err) {
+ this->destroy();
+ return false;
+ }
+
+ GET_DEV_PROC(GetDeviceQueue);
+ GET_DEV_PROC(DeviceWaitIdle);
+ GET_DEV_PROC(DestroyDevice);
GET_DEV_PROC(CreateSwapchainKHR);
GET_DEV_PROC(DestroySwapchainKHR);
GET_DEV_PROC(GetSwapchainImagesKHR);
@@ -93,25 +291,76 @@
GET_DEV_PROC(WaitForFences);
GET_DEV_PROC(ResetFences);
+ return true;
+}
+
+void VulkanManager::initialize() {
+ if (mDevice != VK_NULL_HANDLE) {
+ return;
+ }
+
+ std::vector<const char*> instanceExtensions;
+ std::vector<const char*> deviceExtensions;
+ VkPhysicalDeviceFeatures deviceFeatures;
+ LOG_ALWAYS_FATAL_IF(!this->setupDevice(deviceFeatures));
+
+ mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue);
+
+ uint32_t extensionFlags = kKHR_surface_GrVkExtensionFlag |
+ kKHR_android_surface_GrVkExtensionFlag |
+ kKHR_swapchain_GrVkExtensionFlag;
+
+ uint32_t featureFlags = 0;
+ if (deviceFeatures.geometryShader) {
+ featureFlags |= kGeometryShader_GrVkFeatureFlag;
+ }
+ if (deviceFeatures.dualSrcBlend) {
+ featureFlags |= kDualSrcBlend_GrVkFeatureFlag;
+ }
+ if (deviceFeatures.sampleRateShading) {
+ featureFlags |= kSampleRateShading_GrVkFeatureFlag;
+ }
+
+ auto getProc = [] (const char* proc_name, VkInstance instance, VkDevice device) {
+ if (device != VK_NULL_HANDLE) {
+ return vkGetDeviceProcAddr(device, proc_name);
+ }
+ return vkGetInstanceProcAddr(instance, proc_name);
+ };
+ auto interface =
+ sk_make_sp<GrVkInterface>(getProc, mInstance, mDevice, extensionFlags);
+
+ GrVkBackendContext backendContext;
+ backendContext.fInstance = mInstance;
+ backendContext.fPhysicalDevice = mPhysicalDevice;
+ backendContext.fDevice = mDevice;
+ backendContext.fQueue = mGraphicsQueue;
+ backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex;
+ backendContext.fMinAPIVersion = VK_MAKE_VERSION(1, 0, 0);
+ backendContext.fExtensions = extensionFlags;
+ backendContext.fFeatures = featureFlags;
+ backendContext.fInterface = std::move(interface);
+ backendContext.fOwnsInstanceAndDevice = false;
+
// create the command pool for the command buffers
if (VK_NULL_HANDLE == mCommandPool) {
VkCommandPoolCreateInfo commandPoolInfo;
memset(&commandPoolInfo, 0, sizeof(VkCommandPoolCreateInfo));
commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
// this needs to be on the render queue
- commandPoolInfo.queueFamilyIndex = mBackendContext->fGraphicsQueueIndex;
+ commandPoolInfo.queueFamilyIndex = mGraphicsQueueIndex;
commandPoolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
- SkDEBUGCODE(VkResult res =) mCreateCommandPool(mBackendContext->fDevice, &commandPoolInfo,
- nullptr, &mCommandPool);
+ SkDEBUGCODE(VkResult res =) mCreateCommandPool(mDevice, &commandPoolInfo, nullptr,
+ &mCommandPool);
SkASSERT(VK_SUCCESS == res);
}
- mGetDeviceQueue(mBackendContext->fDevice, mPresentQueueIndex, 0, &mPresentQueue);
+ mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue);
GrContextOptions options;
options.fDisableDistanceFieldPaths = true;
mRenderThread.cacheManager().configureContext(&options);
- sk_sp<GrContext> grContext(GrContext::MakeVulkan(mBackendContext, options));
+ sk_sp<GrContext> grContext(GrContext::MakeVulkan(backendContext, options));
LOG_ALWAYS_FATAL_IF(!grContext.get());
mRenderThread.setGrContext(grContext);
DeviceInfo::initialize(mRenderThread.getGrContext()->maxRenderTargetSize());
@@ -138,8 +387,7 @@
// Before we reuse a backbuffer, make sure its fences have all signaled so that we can safely
// reuse its commands buffers.
- VkResult res =
- mWaitForFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences, true, UINT64_MAX);
+ VkResult res = mWaitForFences(mDevice, 2, backbuffer->mUsageFences, true, UINT64_MAX);
if (res != VK_SUCCESS) {
return nullptr;
}
@@ -153,12 +401,12 @@
VkResult res;
- res = mResetFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences);
+ res = mResetFences(mDevice, 2, backbuffer->mUsageFences);
SkASSERT(VK_SUCCESS == res);
// The acquire will signal the attached mAcquireSemaphore. We use this to know the image has
// finished presenting and that it is safe to begin sending new commands to the returned image.
- res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX,
+ res = mAcquireNextImageKHR(mDevice, surface->mSwapchain, UINT64_MAX,
backbuffer->mAcquireSemaphore, VK_NULL_HANDLE,
&backbuffer->mImageIndex);
@@ -173,11 +421,11 @@
return nullptr;
}
backbuffer = getAvailableBackbuffer(surface);
- res = mResetFences(mBackendContext->fDevice, 2, backbuffer->mUsageFences);
+ res = mResetFences(mDevice, 2, backbuffer->mUsageFences);
SkASSERT(VK_SUCCESS == res);
// acquire the image
- res = mAcquireNextImageKHR(mBackendContext->fDevice, surface->mSwapchain, UINT64_MAX,
+ res = mAcquireNextImageKHR(mDevice, surface->mSwapchain, UINT64_MAX,
backbuffer->mAcquireSemaphore, VK_NULL_HANDLE,
&backbuffer->mImageIndex);
@@ -205,7 +453,7 @@
layout, // oldLayout
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
mPresentQueueIndex, // srcQueueFamilyIndex
- mBackendContext->fGraphicsQueueIndex, // dstQueueFamilyIndex
+ mGraphicsQueueIndex, // dstQueueFamilyIndex
surface->mImages[backbuffer->mImageIndex], // image
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} // subresourceRange
};
@@ -236,7 +484,7 @@
submitInfo.signalSemaphoreCount = 0;
// Attach first fence to submission here so we can track when the command buffer finishes.
- mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[0]);
+ mQueueSubmit(mGraphicsQueue, 1, &submitInfo, backbuffer->mUsageFences[0]);
// We need to notify Skia that we changed the layout of the wrapped VkImage
sk_sp<SkSurface> skSurface = surface->mImageInfos[backbuffer->mImageIndex].mSurface;
@@ -255,17 +503,14 @@
void VulkanManager::destroyBuffers(VulkanSurface* surface) {
if (surface->mBackbuffers) {
for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) {
- mWaitForFences(mBackendContext->fDevice, 2, surface->mBackbuffers[i].mUsageFences, true,
- UINT64_MAX);
+ mWaitForFences(mDevice, 2, surface->mBackbuffers[i].mUsageFences, true, UINT64_MAX);
surface->mBackbuffers[i].mImageIndex = -1;
- mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mAcquireSemaphore,
- nullptr);
- mDestroySemaphore(mBackendContext->fDevice, surface->mBackbuffers[i].mRenderSemaphore,
- nullptr);
- mFreeCommandBuffers(mBackendContext->fDevice, mCommandPool, 2,
- surface->mBackbuffers[i].mTransitionCmdBuffers);
- mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[0], 0);
- mDestroyFence(mBackendContext->fDevice, surface->mBackbuffers[i].mUsageFences[1], 0);
+ mDestroySemaphore(mDevice, surface->mBackbuffers[i].mAcquireSemaphore, nullptr);
+ mDestroySemaphore(mDevice, surface->mBackbuffers[i].mRenderSemaphore, nullptr);
+ mFreeCommandBuffers(mDevice, mCommandPool, 2,
+ surface->mBackbuffers[i].mTransitionCmdBuffers);
+ mDestroyFence(mDevice, surface->mBackbuffers[i].mUsageFences[0], 0);
+ mDestroyFence(mDevice, surface->mBackbuffers[i].mUsageFences[1], 0);
}
}
@@ -282,29 +527,27 @@
if (VK_NULL_HANDLE != mPresentQueue) {
mQueueWaitIdle(mPresentQueue);
}
- mDeviceWaitIdle(mBackendContext->fDevice);
+ mDeviceWaitIdle(mDevice);
destroyBuffers(surface);
if (VK_NULL_HANDLE != surface->mSwapchain) {
- mDestroySwapchainKHR(mBackendContext->fDevice, surface->mSwapchain, nullptr);
+ mDestroySwapchainKHR(mDevice, surface->mSwapchain, nullptr);
surface->mSwapchain = VK_NULL_HANDLE;
}
if (VK_NULL_HANDLE != surface->mVkSurface) {
- mDestroySurfaceKHR(mBackendContext->fInstance, surface->mVkSurface, nullptr);
+ mDestroySurfaceKHR(mInstance, surface->mVkSurface, nullptr);
surface->mVkSurface = VK_NULL_HANDLE;
}
delete surface;
}
void VulkanManager::createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent) {
- mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain, &surface->mImageCount,
- nullptr);
+ mGetSwapchainImagesKHR(mDevice, surface->mSwapchain, &surface->mImageCount, nullptr);
SkASSERT(surface->mImageCount);
surface->mImages = new VkImage[surface->mImageCount];
- mGetSwapchainImagesKHR(mBackendContext->fDevice, surface->mSwapchain, &surface->mImageCount,
- surface->mImages);
+ mGetSwapchainImagesKHR(mDevice, surface->mSwapchain, &surface->mImageCount, surface->mImages);
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
@@ -354,15 +597,15 @@
for (uint32_t i = 0; i < surface->mImageCount + 1; ++i) {
SkDEBUGCODE(VkResult res);
surface->mBackbuffers[i].mImageIndex = -1;
- SkDEBUGCODE(res =) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr,
+ SkDEBUGCODE(res =) mCreateSemaphore(mDevice, &semaphoreInfo, nullptr,
&surface->mBackbuffers[i].mAcquireSemaphore);
- SkDEBUGCODE(res =) mCreateSemaphore(mBackendContext->fDevice, &semaphoreInfo, nullptr,
+ SkDEBUGCODE(res =) mCreateSemaphore(mDevice, &semaphoreInfo, nullptr,
&surface->mBackbuffers[i].mRenderSemaphore);
- SkDEBUGCODE(res =) mAllocateCommandBuffers(mBackendContext->fDevice, &commandBuffersInfo,
+ SkDEBUGCODE(res =) mAllocateCommandBuffers(mDevice, &commandBuffersInfo,
surface->mBackbuffers[i].mTransitionCmdBuffers);
- SkDEBUGCODE(res =) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr,
+ SkDEBUGCODE(res =) mCreateFence(mDevice, &fenceInfo, nullptr,
&surface->mBackbuffers[i].mUsageFences[0]);
- SkDEBUGCODE(res =) mCreateFence(mBackendContext->fDevice, &fenceInfo, nullptr,
+ SkDEBUGCODE(res =) mCreateFence(mDevice, &fenceInfo, nullptr,
&surface->mBackbuffers[i].mUsageFences[1]);
SkASSERT(VK_SUCCESS == res);
}
@@ -372,35 +615,35 @@
bool VulkanManager::createSwapchain(VulkanSurface* surface) {
// check for capabilities
VkSurfaceCapabilitiesKHR caps;
- VkResult res = mGetPhysicalDeviceSurfaceCapabilitiesKHR(mBackendContext->fPhysicalDevice,
+ VkResult res = mGetPhysicalDeviceSurfaceCapabilitiesKHR(mPhysicalDevice,
surface->mVkSurface, &caps);
if (VK_SUCCESS != res) {
return false;
}
uint32_t surfaceFormatCount;
- res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface,
+ res = mGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDevice, surface->mVkSurface,
&surfaceFormatCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
FatVector<VkSurfaceFormatKHR, 4> surfaceFormats(surfaceFormatCount);
- res = mGetPhysicalDeviceSurfaceFormatsKHR(mBackendContext->fPhysicalDevice, surface->mVkSurface,
+ res = mGetPhysicalDeviceSurfaceFormatsKHR(mPhysicalDevice, surface->mVkSurface,
&surfaceFormatCount, surfaceFormats.data());
if (VK_SUCCESS != res) {
return false;
}
uint32_t presentModeCount;
- res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice,
+ res = mGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDevice,
surface->mVkSurface, &presentModeCount, nullptr);
if (VK_SUCCESS != res) {
return false;
}
FatVector<VkPresentModeKHR, VK_PRESENT_MODE_RANGE_SIZE_KHR> presentModes(presentModeCount);
- res = mGetPhysicalDeviceSurfacePresentModesKHR(mBackendContext->fPhysicalDevice,
+ res = mGetPhysicalDeviceSurfacePresentModesKHR(mPhysicalDevice,
surface->mVkSurface, &presentModeCount,
presentModes.data());
if (VK_SUCCESS != res) {
@@ -482,8 +725,8 @@
swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageUsage = usageFlags;
- uint32_t queueFamilies[] = {mBackendContext->fGraphicsQueueIndex, mPresentQueueIndex};
- if (mBackendContext->fGraphicsQueueIndex != mPresentQueueIndex) {
+ uint32_t queueFamilies[] = {mGraphicsQueueIndex, mPresentQueueIndex};
+ if (mGraphicsQueueIndex != mPresentQueueIndex) {
swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
swapchainCreateInfo.queueFamilyIndexCount = 2;
swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
@@ -499,19 +742,18 @@
swapchainCreateInfo.clipped = true;
swapchainCreateInfo.oldSwapchain = surface->mSwapchain;
- res = mCreateSwapchainKHR(mBackendContext->fDevice, &swapchainCreateInfo, nullptr,
- &surface->mSwapchain);
+ res = mCreateSwapchainKHR(mDevice, &swapchainCreateInfo, nullptr, &surface->mSwapchain);
if (VK_SUCCESS != res) {
return false;
}
// destroy the old swapchain
if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
- mDeviceWaitIdle(mBackendContext->fDevice);
+ mDeviceWaitIdle(mDevice);
destroyBuffers(surface);
- mDestroySwapchainKHR(mBackendContext->fDevice, swapchainCreateInfo.oldSwapchain, nullptr);
+ mDestroySwapchainKHR(mDevice, swapchainCreateInfo.oldSwapchain, nullptr);
}
createBuffers(surface, surfaceFormat, extent);
@@ -535,20 +777,18 @@
surfaceCreateInfo.flags = 0;
surfaceCreateInfo.window = window;
- VkResult res = mCreateAndroidSurfaceKHR(mBackendContext->fInstance, &surfaceCreateInfo, nullptr,
- &surface->mVkSurface);
+ VkResult res = mCreateAndroidSurfaceKHR(mInstance, &surfaceCreateInfo, nullptr,
+ &surface->mVkSurface);
if (VK_SUCCESS != res) {
delete surface;
return nullptr;
}
SkDEBUGCODE(VkBool32 supported; res = mGetPhysicalDeviceSurfaceSupportKHR(
- mBackendContext->fPhysicalDevice, mPresentQueueIndex,
- surface->mVkSurface, &supported);
- // All physical devices and queue families on Android must be capable of
- // presentation with any
- // native window.
- SkASSERT(VK_SUCCESS == res && supported););
+ mPhysicalDevice, mPresentQueueIndex, surface->mVkSurface, &supported);
+ // All physical devices and queue families on Android must be capable of
+ // presentation with any native window.
+ SkASSERT(VK_SUCCESS == res && supported););
if (!createSwapchain(surface)) {
destroySurface(surface);
@@ -605,7 +845,7 @@
void VulkanManager::swapBuffers(VulkanSurface* surface) {
if (CC_UNLIKELY(Properties::waitForGpuCompletion)) {
ATRACE_NAME("Finishing GPU work");
- mDeviceWaitIdle(mBackendContext->fDevice);
+ mDeviceWaitIdle(mDevice);
}
SkASSERT(surface->mBackbuffers);
@@ -638,7 +878,7 @@
dstAccessMask, // inputMask
layout, // oldLayout
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, // newLayout
- mBackendContext->fGraphicsQueueIndex, // srcQueueFamilyIndex
+ mGraphicsQueueIndex, // srcQueueFamilyIndex
mPresentQueueIndex, // dstQueueFamilyIndex
surface->mImages[backbuffer->mImageIndex], // image
{VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1} // subresourceRange
@@ -670,7 +910,7 @@
submitInfo.pSignalSemaphores = &backbuffer->mRenderSemaphore;
// Attach second fence to submission here so we can track when the command buffer finishes.
- mQueueSubmit(mBackendContext->fQueue, 1, &submitInfo, backbuffer->mUsageFences[1]);
+ mQueueSubmit(mGraphicsQueue, 1, &submitInfo, backbuffer->mUsageFences[1]);
// Submit present operation to present queue. We use a semaphore here to make sure all rendering
// to the image is complete and that the layout has been change to present on the graphics
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index c319c9e..2a1b36f 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -111,6 +111,10 @@
explicit VulkanManager(RenderThread& thread);
~VulkanManager() { destroy(); }
+ // Sets up the VkInstance and VkDevice objects. Also fills out the passed in
+ // VkPhysicalDeviceFeatures struct.
+ bool setupDevice(VkPhysicalDeviceFeatures& deviceFeatures);
+
void destroyBuffers(VulkanSurface* surface);
bool createSwapchain(VulkanSurface* surface);
@@ -148,7 +152,21 @@
VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR;
VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR;
- // Additional vulkan functions
+ // Instance Functions
+ VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties;
+ VkPtr<PFN_vkCreateInstance> mCreateInstance;
+
+ VkPtr<PFN_vkDestroyInstance> mDestroyInstance;
+ VkPtr<PFN_vkEnumeratePhysicalDevices> mEnumeratePhysicalDevices;
+ VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties> mGetPhysicalDeviceQueueFamilyProperties;
+ VkPtr<PFN_vkGetPhysicalDeviceFeatures> mGetPhysicalDeviceFeatures;
+ VkPtr<PFN_vkCreateDevice> mCreateDevice;
+ VkPtr<PFN_vkEnumerateDeviceExtensionProperties> mEnumerateDeviceExtensionProperties;
+
+ // Device Functions
+ VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue;
+ VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle;
+ VkPtr<PFN_vkDestroyDevice> mDestroyDevice;
VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool;
VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool;
VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers;
@@ -158,10 +176,8 @@
VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer;
VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier;
- VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue;
VkPtr<PFN_vkQueueSubmit> mQueueSubmit;
VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle;
- VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle;
VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore;
VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore;
@@ -173,6 +189,13 @@
RenderThread& mRenderThread;
sk_sp<const GrVkBackendContext> mBackendContext;
+
+ VkInstance mInstance = VK_NULL_HANDLE;
+ VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE;
+ VkDevice mDevice = VK_NULL_HANDLE;
+
+ uint32_t mGraphicsQueueIndex;
+ VkQueue mGraphicsQueue = VK_NULL_HANDLE;
uint32_t mPresentQueueIndex;
VkQueue mPresentQueue = VK_NULL_HANDLE;
VkCommandPool mCommandPool = VK_NULL_HANDLE;
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index 7f8cb2d..3d50d2d 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -127,7 +127,7 @@
return false;
}
void* addr = mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (!addr) {
+ if (addr == MAP_FAILED) {
int err = errno;
// The file not existing is normal for addToDump(), so only log if
// we get an unexpected error
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 196b886..1a282b2 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -794,6 +794,11 @@
* <p>
* This method should only be used by applications that replace the platform-wide
* management of audio settings or the main telephony application.
+ * <p>This method has no effect if the device implements a fixed volume policy
+ * as indicated by {@link #isVolumeFixed()}.
+ * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed
+ * unless the app has been granted Do Not Disturb Access.
+ * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
*
* @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
* {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC},
@@ -804,6 +809,8 @@
* @param flags One or more flags.
* @see #adjustVolume(int, int)
* @see #setStreamVolume(int, int, int)
+ * @throws SecurityException if the adjustment triggers a Do Not Disturb change
+ * and the caller is not granted notification policy access.
*/
public void adjustStreamVolume(int streamType, int direction, int flags) {
final IAudioService service = getService();
@@ -1121,6 +1128,8 @@
* @see #getStreamMaxVolume(int)
* @see #getStreamVolume(int)
* @see #isVolumeFixed()
+ * @throws SecurityException if the volume change triggers a Do Not Disturb change
+ * and the caller is not granted notification policy access.
*/
public void setStreamVolume(int streamType, int index, int flags) {
final IAudioService service = getService();
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
index aae1f51..6bf52bd 100644
--- a/media/java/android/media/MediaHTTPConnection.java
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -323,8 +323,10 @@
StrictMode.setThreadPolicy(policy);
try {
- if (offset != mCurrentOffset) {
- seekTo(offset);
+ synchronized(this) {
+ if (offset != mCurrentOffset) {
+ seekTo(offset);
+ }
}
int n = mInputStream.read(data, 0, size);
@@ -366,7 +368,7 @@
}
@Override
- public long getSize() {
+ public synchronized long getSize() {
if (mConnection == null) {
try {
seekTo(0);
@@ -379,7 +381,7 @@
}
@Override
- public String getMIMEType() {
+ public synchronized String getMIMEType() {
if (mConnection == null) {
try {
seekTo(0);
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index e2935d7..70ef81f 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -453,8 +453,8 @@
* thread by default has a Looper running).
*
*/
-public abstract class MediaPlayer2 extends MediaPlayerBase
- implements SubtitleController.Listener
+public abstract class MediaPlayer2 implements SubtitleController.Listener
+ , AutoCloseable
, AudioRouting {
/**
* Create a MediaPlayer2 object.
@@ -514,6 +514,12 @@
public MediaPlayer2() { }
/**
+ * Returns a {@link MediaPlayerBase} implementation which runs based on
+ * this MediaPlayer2 instance.
+ */
+ public abstract MediaPlayerBase getMediaPlayerBase();
+
+ /**
* Releases the resources held by this {@code MediaPlayer2} object.
*
* It is considered good practice to call this method when you're
@@ -549,7 +555,6 @@
*
*/
// This is an asynchronous call.
- @Override
public abstract void play();
/**
@@ -560,21 +565,18 @@
*
*/
// This is an asynchronous call.
- @Override
public abstract void prepare();
/**
* Pauses playback. Call play() to resume.
*/
// This is an asynchronous call.
- @Override
public abstract void pause();
/**
* Tries to play next data source if applicable.
*/
// This is an asynchronous call.
- @Override
public abstract void skipToNext();
/**
@@ -584,7 +586,6 @@
* @param msec the offset in milliseconds from the start to seek to
*/
// This is an asynchronous call.
- @Override
public void seekTo(long msec) {
seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
}
@@ -594,7 +595,6 @@
*
* @return the current position in milliseconds
*/
- @Override
public abstract long getCurrentPosition();
/**
@@ -603,7 +603,6 @@
* @return the duration in milliseconds, if no duration is available
* (for example, if streaming live content), -1 is returned.
*/
- @Override
public abstract long getDuration();
/**
@@ -615,25 +614,60 @@
*
* @return the current buffered media source position in milliseconds
*/
- @Override
public abstract long getBufferedPosition();
/**
+ * MediaPlayer2 has not been prepared or just has been reset.
+ * In this state, MediaPlayer2 doesn't fetch data.
+ * @hide
+ */
+ public static final int PLAYER_STATE_IDLE = 1001;
+
+ /**
+ * MediaPlayer2 has been just prepared.
+ * In this state, MediaPlayer2 just fetches data from media source,
+ * but doesn't actively render data.
+ * @hide
+ */
+ public static final int PLAYER_STATE_PREPARED = 1002;
+
+ /**
+ * MediaPlayer2 is paused.
+ * In this state, MediaPlayer2 doesn't actively render data.
+ * @hide
+ */
+ public static final int PLAYER_STATE_PAUSED = 1003;
+
+ /**
+ * MediaPlayer2 is actively playing back data.
+ * @hide
+ */
+ public static final int PLAYER_STATE_PLAYING = 1004;
+
+ /**
+ * MediaPlayer2 has hit some fatal error and cannot continue playback.
+ * @hide
+ */
+ public static final int PLAYER_STATE_ERROR = 1005;
+
+ /**
+ * @hide
+ */
+ @IntDef(flag = false, prefix = "MEDIAPLAYER2_STATE", value = {
+ PLAYER_STATE_IDLE,
+ PLAYER_STATE_PREPARED,
+ PLAYER_STATE_PAUSED,
+ PLAYER_STATE_PLAYING,
+ PLAYER_STATE_ERROR })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface MediaPlayer2State {}
+
+ /**
* Gets the current player state.
*
* @return the current player state.
*/
- @Override
- public abstract @PlayerState int getPlayerState();
-
- /**
- * Gets the current buffering state of the player.
- * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
- * buffered.
- * @return the buffering state, one of the following:
- */
- @Override
- public abstract @BuffState int getBufferingState();
+ public abstract @MediaPlayer2State int getState();
/**
* Sets the audio attributes for this MediaPlayer2.
@@ -643,14 +677,12 @@
* @param attributes a non-null set of audio attributes
*/
// This is an asynchronous call.
- @Override
public abstract void setAudioAttributes(@NonNull AudioAttributes attributes);
/**
* Gets the audio attributes for this MediaPlayer2.
* @return attributes a set of audio attributes
*/
- @Override
public abstract @Nullable AudioAttributes getAudioAttributes();
/**
@@ -659,7 +691,6 @@
* @param dsd the descriptor of data source you want to play
*/
// This is an asynchronous call.
- @Override
public abstract void setDataSource(@NonNull DataSourceDesc dsd);
/**
@@ -669,7 +700,6 @@
* @param dsd the descriptor of data source you want to play after current one
*/
// This is an asynchronous call.
- @Override
public abstract void setNextDataSource(@NonNull DataSourceDesc dsd);
/**
@@ -678,7 +708,6 @@
* @param dsds the list of data sources you want to play after current one
*/
// This is an asynchronous call.
- @Override
public abstract void setNextDataSources(@NonNull List<DataSourceDesc> dsds);
/**
@@ -686,7 +715,6 @@
*
* @return the current DataSourceDesc
*/
- @Override
public abstract @NonNull DataSourceDesc getCurrentDataSource();
/**
@@ -694,44 +722,9 @@
* @param loop true if the current data source is meant to loop.
*/
// This is an asynchronous call.
- @Override
public abstract void loopCurrent(boolean loop);
/**
- * Sets the playback speed.
- * A value of 1.0f is the default playback value.
- * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
- * before using negative values.<br>
- * After changing the playback speed, it is recommended to query the actual speed supported
- * by the player, see {@link #getPlaybackSpeed()}.
- * @param speed the desired playback speed
- */
- // This is an asynchronous call.
- @Override
- public abstract void setPlaybackSpeed(float speed);
-
- /**
- * Returns the actual playback speed to be used by the player when playing.
- * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
- * @return the actual playback speed
- */
- @Override
- public float getPlaybackSpeed() {
- return 1.0f;
- }
-
- /**
- * Indicates whether reverse playback is supported.
- * Reverse playback is indicated by negative playback speeds, see
- * {@link #setPlaybackSpeed(float)}.
- * @return true if reverse playback is supported.
- */
- @Override
- public boolean isReversePlaybackSupported() {
- return false;
- }
-
- /**
* Sets the volume of the audio of the media to play, expressed as a linear multiplier
* on the audio samples.
* Note that this volume is specific to the player, and is separate from stream volume
@@ -741,7 +734,6 @@
* @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
*/
// This is an asynchronous call.
- @Override
public abstract void setPlayerVolume(float volume);
/**
@@ -749,36 +741,16 @@
* Note that it does not take into account the associated stream volume.
* @return the player volume.
*/
- @Override
public abstract float getPlayerVolume();
/**
* @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
*/
- @Override
public float getMaxPlayerVolume() {
return 1.0f;
}
/**
- * Adds a callback to be notified of events for this player.
- * @param e the {@link Executor} to be used for the events.
- * @param cb the callback to receive the events.
- */
- // This is a synchronous call.
- @Override
- public abstract void registerPlayerEventCallback(@NonNull Executor e,
- @NonNull PlayerEventCallback cb);
-
- /**
- * Removes a previously registered callback for player events
- * @param cb the callback to remove
- */
- // This is a synchronous call.
- @Override
- public abstract void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb);
-
- /**
* Create a request parcel which can be routed to the native media
* player using {@link #invoke(Parcel, Parcel)}. The Parcel
* returned has the proper InterfaceToken set. The caller should
@@ -973,7 +945,8 @@
*/
// This is a synchronous call.
@Override
- public abstract void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener);
+ public abstract void removeOnRoutingChangedListener(
+ AudioRouting.OnRoutingChangedListener listener);
/**
* Set the low-level power management behavior for this MediaPlayer2.
@@ -1024,7 +997,8 @@
* no display surface was set, or the height has not been determined
* yet. The {@code EventCallback} can be registered via
* {@link #setEventCallback(Executor, EventCallback)} to provide a
- * notification {@code EventCallback.onVideoSizeChanged} when the height is available.
+ * notification {@code EventCallback.onVideoSizeChanged} when the height is
+ * available.
*/
public abstract int getVideoHeight();
@@ -1051,60 +1025,6 @@
public abstract boolean isPlaying();
/**
- * MediaPlayer2 has not been prepared or just has been reset.
- * In this state, MediaPlayer2 doesn't fetch data.
- * @hide
- */
- public static final int MEDIAPLAYER2_STATE_IDLE = 1;
-
- /**
- * MediaPlayer2 has been just prepared.
- * In this state, MediaPlayer2 just fetches data from media source,
- * but doesn't actively render data.
- * @hide
- */
- public static final int MEDIAPLAYER2_STATE_PREPARED = 2;
-
- /**
- * MediaPlayer2 is paused.
- * In this state, MediaPlayer2 doesn't actively render data.
- * @hide
- */
- public static final int MEDIAPLAYER2_STATE_PAUSED = 3;
-
- /**
- * MediaPlayer2 is actively playing back data.
- * @hide
- */
- public static final int MEDIAPLAYER2_STATE_PLAYING = 4;
-
- /**
- * MediaPlayer2 has hit some fatal error and cannot continue playback.
- * @hide
- */
- public static final int MEDIAPLAYER2_STATE_ERROR = 5;
-
- /**
- * @hide
- */
- @IntDef(flag = false, prefix = "MEDIAPLAYER2_STATE", value = {
- MEDIAPLAYER2_STATE_IDLE,
- MEDIAPLAYER2_STATE_PREPARED,
- MEDIAPLAYER2_STATE_PAUSED,
- MEDIAPLAYER2_STATE_PLAYING,
- MEDIAPLAYER2_STATE_ERROR })
- @Retention(RetentionPolicy.SOURCE)
- public @interface MediaPlayer2State {}
-
- /**
- * Gets the current MediaPlayer2 state.
- *
- * @return the current MediaPlayer2 state.
- * @hide
- */
- public abstract @MediaPlayer2State int getMediaPlayer2State();
-
- /**
* Gets the current buffering management params used by the source component.
* Calling it only after {@code setDataSource} has been called.
* Each type of data source might have different set of default params.
@@ -1383,7 +1303,6 @@
* data source and calling prepare().
*/
// This is a synchronous call.
- @Override
public abstract void reset();
/**
@@ -1718,7 +1637,8 @@
* @param width the width of the video
* @param height the height of the video
*/
- public void onVideoSizeChanged(MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) { }
+ public void onVideoSizeChanged(
+ MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) { }
/**
* Called to indicate an avaliable timed text
@@ -2200,7 +2120,6 @@
CALL_COMPLETED_SET_NEXT_DATA_SOURCE,
CALL_COMPLETED_SET_NEXT_DATA_SOURCES,
CALL_COMPLETED_SET_PLAYBACK_PARAMS,
- CALL_COMPLETED_SET_PLAYBACK_SPEED,
CALL_COMPLETED_SET_PLAYER_VOLUME,
CALL_COMPLETED_SET_SURFACE,
CALL_COMPLETED_SET_SYNC_PARAMS,
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index 0d339a1..2b61b2e 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -173,6 +173,11 @@
native_setup(new WeakReference<MediaPlayer2Impl>(this));
}
+ @Override
+ public MediaPlayerBase getMediaPlayerBase() {
+ return null;
+ }
+
/**
* Releases the resources held by this {@code MediaPlayer2} object.
*
@@ -313,39 +318,11 @@
}
@Override
- public @PlayerState int getPlayerState() {
- int mediaplayer2State = getMediaPlayer2State();
- int playerState;
- switch (mediaplayer2State) {
- case MEDIAPLAYER2_STATE_IDLE:
- playerState = PLAYER_STATE_IDLE;
- break;
- case MEDIAPLAYER2_STATE_PREPARED:
- case MEDIAPLAYER2_STATE_PAUSED:
- playerState = PLAYER_STATE_PAUSED;
- break;
- case MEDIAPLAYER2_STATE_PLAYING:
- playerState = PLAYER_STATE_PLAYING;
- break;
- case MEDIAPLAYER2_STATE_ERROR:
- default:
- playerState = PLAYER_STATE_ERROR;
- break;
- }
-
- return playerState;
+ public @MediaPlayer2State int getState() {
+ return native_getState();
}
- /**
- * Gets the current buffering state of the player.
- * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
- * buffered.
- */
- @Override
- public @BuffState int getBufferingState() {
- // TODO: use cached state or call native function.
- return BUFFERING_STATE_UNKNOWN;
- }
+ private native int native_getState();
/**
* Sets the audio attributes for this MediaPlayer2.
@@ -427,8 +404,8 @@
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
- int state = getMediaPlayer2State();
- if (state != MEDIAPLAYER2_STATE_IDLE) {
+ int state = getState();
+ if (state != PLAYER_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
}
@@ -465,8 +442,8 @@
mNextSourceState = NEXT_SOURCE_STATE_INIT;
mNextSourcePlayPending = false;
}
- int state = getMediaPlayer2State();
- if (state != MEDIAPLAYER2_STATE_IDLE) {
+ int state = getState();
+ if (state != PLAYER_STATE_IDLE) {
synchronized (mSrcLock) {
prepareNextDataSource_l();
}
@@ -500,46 +477,6 @@
private native void setLooping(boolean looping);
/**
- * Sets the playback speed.
- * A value of 1.0f is the default playback value.
- * A negative value indicates reverse playback, check {@link #isReversePlaybackSupported()}
- * before using negative values.<br>
- * After changing the playback speed, it is recommended to query the actual speed supported
- * by the player, see {@link #getPlaybackSpeed()}.
- * @param speed the desired playback speed
- */
- @Override
- public void setPlaybackSpeed(float speed) {
- addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_SPEED, false) {
- @Override
- void process() {
- _setPlaybackParams(getPlaybackParams().setSpeed(speed));
- }
- });
- }
-
- /**
- * Returns the actual playback speed to be used by the player when playing.
- * Note that it may differ from the speed set in {@link #setPlaybackSpeed(float)}.
- * @return the actual playback speed
- */
- @Override
- public float getPlaybackSpeed() {
- return getPlaybackParams().getSpeed();
- }
-
- /**
- * Indicates whether reverse playback is supported.
- * Reverse playback is indicated by negative playback speeds, see
- * {@link #setPlaybackSpeed(float)}.
- * @return true if reverse playback is supported.
- */
- @Override
- public boolean isReversePlaybackSupported() {
- return false;
- }
-
- /**
* Sets the volume of the audio of the media to play, expressed as a linear multiplier
* on the audio samples.
* Note that this volume is specific to the player, and is separate from stream volume
@@ -579,25 +516,6 @@
return 1.0f;
}
- /**
- * Adds a callback to be notified of events for this player.
- * @param e the {@link Executor} to be used for the events.
- * @param cb the callback to receive the events.
- */
- @Override
- public void registerPlayerEventCallback(@NonNull Executor e,
- @NonNull PlayerEventCallback cb) {
- }
-
- /**
- * Removes a previously registered callback for player events
- * @param cb the callback to remove
- */
- @Override
- public void unregisterPlayerEventCallback(@NonNull PlayerEventCallback cb) {
- }
-
-
private static final int NEXT_SOURCE_STATE_ERROR = -1;
private static final int NEXT_SOURCE_STATE_INIT = 0;
private static final int NEXT_SOURCE_STATE_PREPARING = 1;
@@ -1355,13 +1273,6 @@
@Override
public native boolean isPlaying();
- @Override
- public @MediaPlayer2State int getMediaPlayer2State() {
- return native_getMediaPlayer2State();
- }
-
- private native int native_getMediaPlayer2State();
-
/**
* Gets the current buffering management params used by the source component.
* Calling it only after {@code setDataSource} has been called.
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 6546cf0..d166cc3 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -786,13 +786,13 @@
}
static jint
-android_media_MediaPlayer2_getMediaPlayer2State(JNIEnv *env, jobject thiz)
+android_media_MediaPlayer2_getState(JNIEnv *env, jobject thiz)
{
sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
if (mp == NULL) {
return MEDIAPLAYER2_STATE_IDLE;
}
- return (jint)mp->getMediaPlayer2State();
+ return (jint)mp->getState();
}
static jint
@@ -1502,7 +1502,7 @@
{"_prepare", "()V", (void *)android_media_MediaPlayer2_prepare},
{"_start", "()V", (void *)android_media_MediaPlayer2_start},
{"_stop", "()V", (void *)android_media_MediaPlayer2_stop},
- {"native_getMediaPlayer2State", "()I", (void *)android_media_MediaPlayer2_getMediaPlayer2State},
+ {"native_getState", "()I", (void *)android_media_MediaPlayer2_getState},
{"getVideoWidth", "()I", (void *)android_media_MediaPlayer2_getVideoWidth},
{"getVideoHeight", "()I", (void *)android_media_MediaPlayer2_getVideoHeight},
{"native_getMetrics", "()Landroid/os/PersistableBundle;", (void *)android_media_MediaPlayer2_native_getMetrics},
diff --git a/media/native/midi/include/midi.h b/media/native/midi/include/midi.h
index 780d8a7..755d09f 100644
--- a/media/native/midi/include/midi.h
+++ b/media/native/midi/include/midi.h
@@ -71,7 +71,7 @@
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - an unknown error occurred.
*/
media_status_t AMIDI_API AMidiDevice_fromJava(
- JNIEnv *env, jobject midiDeviceObj, AMidiDevice **outDevicePtrPtr);
+ JNIEnv *env, jobject midiDeviceObj, AMidiDevice **outDevicePtrPtr) __INTRODUCED_IN(29);
/**
* Disconnects the native Midi Device Object from the associated Java MidiDevice object.
@@ -88,7 +88,7 @@
* - the JNI interface initialization to the associated java MidiDevice failed.
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - couldn't retrieve the device info.
*/
-media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *midiDevice);
+media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *midiDevice) __INTRODUCED_IN(29);
/**
* Gets the MIDI device type.
@@ -104,7 +104,7 @@
* parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - Unknown error.
*/
-int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device);
+int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device) __INTRODUCED_IN(29);
/**
* Gets the number of input (sending) ports available on the specified MIDI device.
@@ -117,7 +117,7 @@
* parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - couldn't retrieve the device info.
*/
-ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device);
+ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
/**
* Gets the number of output (receiving) ports available on the specified MIDI device.
@@ -130,7 +130,7 @@
* parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN}- couldn't retrieve the device info.
*/
-ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device);
+ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
/*
* API for receiving data from the Output port of a device.
@@ -149,14 +149,14 @@
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - Unknown Error.
*/
media_status_t AMIDI_API AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber,
- AMidiOutputPort **outOutputPortPtr);
+ AMidiOutputPort **outOutputPortPtr) __INTRODUCED_IN(29);
/**
* Closes the output port.
*
* @param outputPort The native API port identifier of the port.
*/
-void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort);
+void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort) __INTRODUCED_IN(29);
/**
* Receives the next pending MIDI message. To retrieve all pending messages, the client should
@@ -177,7 +177,7 @@
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - Unknown Error.
*/
ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr,
- uint8_t *buffer, size_t maxBytes, size_t* numBytesReceivedPtr, int64_t *outTimestampPtr);
+ uint8_t *buffer, size_t maxBytes, size_t* numBytesReceivedPtr, int64_t *outTimestampPtr) __INTRODUCED_IN(29);
/*
* API for sending data to the Input port of a device.
@@ -196,7 +196,7 @@
* @see AMEDIA_ERROR_UNKNOWN {@link AMEDIA_ERROR_UNKNOWN} - Unknown Error.
*/
media_status_t AMIDI_API AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber,
- AMidiInputPort **outInputPortPtr);
+ AMidiInputPort **outInputPortPtr) __INTRODUCED_IN(29);
/**
* Sends data to the specified input port.
@@ -210,7 +210,7 @@
* was NULL, the specified buffer was NULL.
*/
ssize_t AMIDI_API AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer,
- size_t numBytes);
+ size_t numBytes) __INTRODUCED_IN(29);
/**
* Sends data to the specified input port with a timestamp.
@@ -225,7 +225,7 @@
* was NULL, the specified buffer was NULL.
*/
ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort,
- const uint8_t *buffer, size_t numBytes, int64_t timestamp);
+ const uint8_t *buffer, size_t numBytes, int64_t timestamp) __INTRODUCED_IN(29);
/**
* Sends a message with a 'MIDI flush command code' to the specified port. This should cause
@@ -239,14 +239,14 @@
* @see AMEDIA_ERROR_UNSUPPORTED {@link AMEDIA_ERROR_UNSUPPORTED} The FLUSH command couldn't
* be sent.
*/
-media_status_t AMIDI_API AMidiInputPort_sendFlush(const AMidiInputPort *inputPort);
+media_status_t AMIDI_API AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
/**
* Closes the input port.
*
* @param inputPort Identifies the input (sending) port to close.
*/
-void AMIDI_API AMidiInputPort_close(const AMidiInputPort *inputPort);
+void AMIDI_API AMidiInputPort_close(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
#ifdef __cplusplus
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index f7aa297..87f5b4f 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -41,6 +41,7 @@
import android.util.Pair;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import java.time.ZonedDateTime;
import java.util.Date;
@@ -86,7 +87,8 @@
* mContext.getResources().getInteger(R.integer.default_data_warning_level_mb);
}
- private INetworkStatsSession getSession() {
+ @VisibleForTesting
+ INetworkStatsSession getSession() {
if (mSession == null) {
try {
mSession = mStatsService.openSession();
@@ -176,6 +178,30 @@
}
}
+ /**
+ * Get the total usage level recorded in the network history
+ * @param template the network template to retrieve the network history
+ * @return the total usage level recorded in the network history
+ */
+ public long getHistoriclUsageLevel(NetworkTemplate template) {
+ final INetworkStatsSession session = getSession();
+ if (session != null) {
+ try {
+ final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS);
+ final long now = System.currentTimeMillis();
+ final NetworkStatsHistory.Entry entry =
+ history.getValues(0L /* start */, now /* end */, now, null /* recycle */);
+ if (entry != null) {
+ return entry.rxBytes + entry.txBytes;
+ }
+ Log.w(TAG, "Failed to get data usage, no entry data");
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to get data usage, remote call failed");
+ }
+ }
+ return 0L;
+ }
+
private NetworkPolicy findNetworkPolicy(NetworkTemplate template) {
if (mPolicyManager == null || template == null) return null;
final NetworkPolicy[] policies = mPolicyManager.getNetworkPolicies();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
new file mode 100644
index 0000000..1be856a
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.net;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.INetworkStatsSession;
+import android.net.NetworkStatsHistory;
+import android.net.NetworkStatsHistory.Entry;
+import android.net.NetworkTemplate;
+import android.os.RemoteException;
+import android.text.format.DateUtils;
+
+import com.android.settingslib.SettingsLibRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+
+@RunWith(SettingsLibRobolectricTestRunner.class)
+public class DataUsageControllerTest {
+
+ @Mock
+ private INetworkStatsSession mSession;
+
+ private Context mContext;
+ private DataUsageController mController;
+ private NetworkStatsHistory mNetworkStatsHistory;
+
+ @Before
+ public void setUp() throws RemoteException {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ mController = spy(new DataUsageController(mContext));
+ mNetworkStatsHistory = spy(
+ new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */));
+ doReturn(mNetworkStatsHistory)
+ .when(mSession).getHistoryForNetwork(any(NetworkTemplate.class), anyInt());
+ }
+
+ @Test
+ public void getHistoriclUsageLevel_noNetworkSession_shouldReturn0() {
+ doReturn(null).when(mController).getSession();
+
+ assertThat(mController.getHistoriclUsageLevel(null /* template */)).isEqualTo(0L);
+
+ }
+
+ @Test
+ public void getHistoriclUsageLevel_noUsageData_shouldReturn0() {
+ doReturn(mSession).when(mController).getSession();
+
+ assertThat(mController.getHistoriclUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+ .isEqualTo(0L);
+
+ }
+
+ @Test
+ public void getHistoriclUsageLevel_hasUsageData_shouldReturnTotalUsage() {
+ doReturn(mSession).when(mController).getSession();
+ final long receivedBytes = 743823454L;
+ final long transmittedBytes = 16574289L;
+ final Entry entry = new Entry();
+ entry.bucketStart = 1521583200000L;
+ entry.rxBytes = receivedBytes;
+ entry.txBytes = transmittedBytes;
+ when(mNetworkStatsHistory.getValues(eq(0L), anyLong(), anyLong(), nullable(Entry.class)))
+ .thenReturn(entry);
+
+ assertThat(mController.getHistoriclUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+ .isEqualTo(receivedBytes + transmittedBytes);
+
+ }
+}
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 88d19f4..28466fd 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -161,30 +161,31 @@
style="@style/TextAppearance.NotificationInfo.Button"/>
</LinearLayout>
</LinearLayout>
- <RelativeLayout
+ <com.android.systemui.statusbar.NotificationUndoLayout
android:id="@+id/confirmation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/notification_guts_button_spacing"
- android:layout_marginTop="@dimen/notification_guts_button_spacing"
- android:layout_marginStart="@dimen/notification_guts_button_side_margin"
- android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
android:visibility="gone"
android:orientation="horizontal" >
<TextView
android:id="@+id/confirmation_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerVertical="true"
+ android:layout_gravity="start|center_vertical"
+ android:layout_marginStart="@*android:dimen/notification_content_margin_start"
+ android:layout_marginEnd="@*android:dimen/notification_content_margin_start"
android:text="@string/notification_channel_disabled"
style="@style/TextAppearance.NotificationInfo.Confirmation"/>
<TextView
android:id="@+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:layout_centerVertical="true"
+ android:layout_marginTop="@dimen/notification_guts_button_spacing"
+ android:layout_marginBottom="@dimen/notification_guts_button_spacing"
+ android:layout_marginStart="@dimen/notification_guts_button_side_margin"
+ android:layout_marginEnd="@dimen/notification_guts_button_side_margin"
+ android:layout_gravity="end|center_vertical"
android:text="@string/inline_undo"
style="@style/TextAppearance.NotificationInfo.Button"/>
- </RelativeLayout>
+ </com.android.systemui.statusbar.NotificationUndoLayout>
</com.android.systemui.statusbar.NotificationInfo>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 61784fa..3ac6705 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -55,6 +55,7 @@
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.Utils.DisableStateTracker;
+import com.android.systemui.R;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -74,6 +75,7 @@
private int mTextColor;
private int mLevel;
private boolean mForceShowPercent;
+ private boolean mShowPercentAvailable;
private int mDarkModeBackgroundColor;
private int mDarkModeFillColor;
@@ -113,6 +115,9 @@
atts.recycle();
mSettingObserver = new SettingObserver(new Handler(context.getMainLooper()));
+ mShowPercentAvailable = context.getResources().getBoolean(
+ com.android.internal.R.bool.config_battery_percentage_setting_available);
+
addOnAttachStateChangeListener(
new DisableStateTracker(DISABLE_NONE, DISABLE2_SYSTEM_ICONS));
@@ -264,8 +269,11 @@
private void updateShowPercent() {
final boolean showing = mBatteryPercentView != null;
- if (0 != Settings.System.getIntForUser(getContext().getContentResolver(),
- SHOW_BATTERY_PERCENT, 0, mUser) || mForceShowPercent) {
+ final boolean systemSetting = 0 != Settings.System
+ .getIntForUser(getContext().getContentResolver(),
+ SHOW_BATTERY_PERCENT, 0, mUser);
+
+ if ((mShowPercentAvailable && systemSetting) || mForceShowPercent) {
if (!showing) {
mBatteryPercentView = loadPercentView();
if (mTextColor != 0) mBatteryPercentView.setTextColor(mTextColor);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 615b29f..2dc531a 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -229,7 +229,9 @@
mSettingsButton = findViewById(R.id.settings);
mSettingsButton.setAlpha(0);
mSettingsButton.setOnClickListener((v) -> {
- showSettings();
+ if (v.getAlpha() != 0) {
+ showSettings();
+ }
});
mDismissButton = findViewById(R.id.dismiss);
mDismissButton.setAlpha(0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUndoLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUndoLayout.java
new file mode 100644
index 0000000..11a1c9b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUndoLayout.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.systemui.R;
+
+/**
+ * Custom view for the NotificationInfo confirmation views so that the confirmation text can
+ * occupy the full width of the notification and push the undo button down to the next line if
+ * necessary.
+ *
+ * @see NotificationInfo
+ */
+public class NotificationUndoLayout extends FrameLayout {
+ /**
+ * View for the prompt/confirmation text to tell the user the previous action was successful.
+ */
+ private View mConfirmationTextView;
+ /** Undo button (actionable text) view. */
+ private View mUndoView;
+
+ /**
+ * Whether {@link #mConfirmationTextView} is multiline and will require the full width of the
+ * parent (which causes the {@link #mUndoView} to push down).
+ */
+ private boolean mIsMultiline = false;
+ private int mMultilineTopMargin;
+
+ public NotificationUndoLayout(Context context) {
+ this(context, null);
+ }
+
+ public NotificationUndoLayout(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public NotificationUndoLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mConfirmationTextView = findViewById(R.id.confirmation_text);
+ mUndoView = findViewById(R.id.undo);
+
+ mMultilineTopMargin = getResources().getDimensionPixelOffset(
+ com.android.internal.R.dimen.notification_content_margin_start);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ LayoutParams confirmationLayoutParams =
+ (LayoutParams) mConfirmationTextView.getLayoutParams();
+ LayoutParams undoLayoutParams =(LayoutParams) mUndoView.getLayoutParams();
+
+ int measuredWidth = getMeasuredWidth();
+ // Ignore the left margin on the undo button - no need for additional extra space between
+ // the text and the button.
+ int requiredWidth = mConfirmationTextView.getMeasuredWidth()
+ + confirmationLayoutParams.rightMargin
+ + confirmationLayoutParams.leftMargin
+ + mUndoView.getMeasuredWidth()
+ + undoLayoutParams.rightMargin;
+ // If the measured width isn't enough to accommodate both the undo button and the text in
+ // the same line, we'll need to adjust the view to be multi-line. Otherwise, we're done.
+ if (requiredWidth > measuredWidth) {
+ mIsMultiline = true;
+
+ // Update height requirement to the text height and the button's height (along with
+ // additional spacing for the top of the text).
+ int updatedHeight = mMultilineTopMargin
+ + mConfirmationTextView.getMeasuredHeight()
+ + mUndoView.getMeasuredHeight()
+ + undoLayoutParams.topMargin
+ + undoLayoutParams.bottomMargin;
+
+ setMeasuredDimension(measuredWidth, updatedHeight);
+ } else {
+ mIsMultiline = false;
+ }
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ // If the text view and undo view don't fit on the same line, we'll need to manually lay
+ // out the content.
+ if (mIsMultiline) {
+ // Re-align parent right/bottom values. Left and top are considered to be 0.
+ int parentBottom = getMeasuredHeight();
+ int parentRight = getMeasuredWidth();
+
+ LayoutParams confirmationLayoutParams =
+ (LayoutParams) mConfirmationTextView.getLayoutParams();
+ LayoutParams undoLayoutParams = (LayoutParams) mUndoView.getLayoutParams();
+
+ // The confirmation text occupies the full width as computed earlier. Both side margins
+ // are equivalent, so we only need to grab the left one here.
+ mConfirmationTextView.layout(
+ confirmationLayoutParams.leftMargin,
+ mMultilineTopMargin,
+ confirmationLayoutParams.leftMargin + mConfirmationTextView.getMeasuredWidth(),
+ mMultilineTopMargin + mConfirmationTextView.getMeasuredHeight());
+
+ // The undo button is aligned bottom|end with the parent in the case of multiline text.
+ int undoViewLeft = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL
+ ? undoLayoutParams.rightMargin
+ : parentRight - mUndoView.getMeasuredWidth() - undoLayoutParams.rightMargin;
+ mUndoView.layout(
+ undoViewLeft,
+ parentBottom - mUndoView.getMeasuredHeight() - undoLayoutParams.bottomMargin,
+ undoViewLeft + mUndoView.getMeasuredWidth(),
+ parentBottom - undoLayoutParams.bottomMargin);
+ } else {
+ super.onLayout(changed, left, top, right, bottom);
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index e47dcea..20ea27a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -70,6 +70,7 @@
private static final int LAYOUT_CUTOUT = 1;
private static final int LAYOUT_NO_CUTOUT = 2;
+ private boolean mShowPercentAvailable;
private boolean mBatteryCharging;
private boolean mKeyguardUserSwitcherShowing;
private boolean mBatteryListening;
@@ -168,6 +169,8 @@
R.dimen.system_icons_super_container_avatarless_margin_end);
mCutoutSideNudge = getResources().getDimensionPixelSize(
R.dimen.display_cutout_margin_consumption);
+ mShowPercentAvailable = getContext().getResources().getBoolean(
+ com.android.internal.R.bool.config_battery_percentage_setting_available);
}
private void updateVisibilities() {
@@ -189,7 +192,7 @@
mMultiUserSwitch.setVisibility(View.GONE);
}
}
- mBatteryView.setForceShowPercent(mBatteryCharging);
+ mBatteryView.setForceShowPercent(mBatteryCharging && mShowPercentAvailable);
}
private void updateSystemIconsLayoutParams() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
index dce7537..ed1ae10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java
@@ -75,7 +75,6 @@
private int mTouchDownY;
private boolean mDownOnRecents;
private VelocityTracker mVelocityTracker;
- private boolean mIsInScreenPinning;
private boolean mNotificationsVisibleOnDown;
private boolean mDockWindowEnabled;
@@ -110,7 +109,6 @@
public boolean onInterceptTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mIsInScreenPinning = mNavigationBarView.inScreenPinning();
mNotificationsVisibleOnDown = !mStatusBar.isPresenterFullyCollapsed();
}
if (!canHandleGestures()) {
@@ -277,8 +275,7 @@
}
private boolean canHandleGestures() {
- return !mIsInScreenPinning && !mStatusBar.isKeyguardShowing()
- && !mNotificationsVisibleOnDown;
+ return !mStatusBar.isKeyguardShowing() && !mNotificationsVisibleOnDown;
}
private int calculateDragMode() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 8b9e12c..4a98262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -161,6 +161,13 @@
private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
+ /**
+ * Helper that is responsible for showing the right toast when a disallowed activity operation
+ * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
+ * fully locked mode we only show that unlocking is blocked.
+ */
+ private ScreenPinningNotify mScreenPinningNotify;
+
private class NavTransitionListener implements TransitionListener {
private boolean mBackTransitioning;
private boolean mHomeAppearing;
@@ -286,6 +293,7 @@
mConfiguration.updateFrom(context.getResources().getConfiguration());
reloadNavIcons();
+ mScreenPinningNotify = new ScreenPinningNotify(mContext);
mBarTransitions = new NavigationBarTransitions(this);
mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
@@ -983,6 +991,18 @@
mBarTransitions.reapplyDarkIntensity();
}
+ public void showPinningEnterExitToast(boolean entering) {
+ if (entering) {
+ mScreenPinningNotify.showPinningStartToast();
+ } else {
+ mScreenPinningNotify.showPinningExitToast();
+ }
+ }
+
+ public void showPinningEscapeToast() {
+ mScreenPinningNotify.showEscapeToast(isRecentsButtonVisible());
+ }
+
public boolean isVertical() {
return mVertical;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index ea1b980..15790d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -84,6 +84,7 @@
private AnimatorSet mTrackAnimator;
private ButtonDispatcher mHitTarget;
private View mCurrentNavigationBarView;
+ private boolean mIsInScreenPinning;
private final Handler mHandler = new Handler();
private final Rect mTrackRect = new Rect();
@@ -195,6 +196,7 @@
case MotionEvent.ACTION_DOWN: {
int x = (int) event.getX();
int y = (int) event.getY();
+ mIsInScreenPinning = mNavigationBarView.inScreenPinning();
// End any existing quickscrub animations before starting the new transition
if (mTrackAnimator != null) {
@@ -298,8 +300,8 @@
// Proxy motion events to launcher if not handled by quick scrub
// Proxy motion events up/cancel that would be sent after long press on any nav button
- if (!mQuickScrubActive && (mAllowGestureDetection || action == MotionEvent.ACTION_CANCEL
- || action == MotionEvent.ACTION_UP)) {
+ if (!mQuickScrubActive && !mIsInScreenPinning && (mAllowGestureDetection
+ || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP)) {
proxyMotionEvents(event);
}
return mQuickScrubActive || mQuickStepStarted;
@@ -382,6 +384,12 @@
}
private void startQuickStep(MotionEvent event) {
+ if (mIsInScreenPinning) {
+ mNavigationBarView.showPinningEscapeToast();
+ mAllowGestureDetection = false;
+ return;
+ }
+
mQuickStepStarted = true;
event.transform(mTransformGlobalMatrix);
try {
@@ -407,6 +415,12 @@
}
private void startQuickScrub() {
+ if (mIsInScreenPinning) {
+ mNavigationBarView.showPinningEscapeToast();
+ mAllowGestureDetection = false;
+ return;
+ }
+
if (!mQuickScrubActive) {
mQuickScrubActive = true;
mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
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 e61ff79..c2f31bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -423,13 +423,6 @@
protected KeyguardViewMediator mKeyguardViewMediator;
private ZenModeController mZenController;
- /**
- * Helper that is responsible for showing the right toast when a disallowed activity operation
- * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in
- * fully locked mode we only show that unlocking is blocked.
- */
- private ScreenPinningNotify mScreenPinningNotify;
-
// for disabling the status bar
private int mDisabled1 = 0;
private int mDisabled2 = 0;
@@ -902,7 +895,6 @@
} catch (RemoteException ex) {
// no window manager? good luck with that
}
- mScreenPinningNotify = new ScreenPinningNotify(mContext);
mStackScroller.setLongPressListener(mEntryManager.getNotificationLongClicker());
mStackScroller.setStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
@@ -2241,17 +2233,16 @@
@Override
public void showPinningEnterExitToast(boolean entering) {
- if (entering) {
- mScreenPinningNotify.showPinningStartToast();
- } else {
- mScreenPinningNotify.showPinningExitToast();
+ if (getNavigationBarView() != null) {
+ getNavigationBarView().showPinningEnterExitToast(entering);
}
}
@Override
public void showPinningEscapeToast() {
- mScreenPinningNotify.showEscapeToast(getNavigationBarView() == null
- || getNavigationBarView().isRecentsButtonVisible());
+ if (getNavigationBarView() != null) {
+ getNavigationBarView().showPinningEscapeToast();
+ }
}
boolean panelsEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index d6d0673..3c16329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -134,6 +134,10 @@
@Override
public void setHotspotEnabled(boolean enabled) {
+ if (mWaitingForCallback) {
+ if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for callback.");
+ return;
+ }
if (enabled) {
OnStartTetheringCallback callback = new OnStartTetheringCallback();
mWaitingForCallback = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 2dd3d4e..ffd5494 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -49,10 +49,14 @@
*/
public class NotificationChildrenContainer extends ViewGroup {
- private static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
- private static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5;
- private static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8;
- private static final int NUMBER_OF_CHILDREN_WHEN_AMBIENT = 1;
+ @VisibleForTesting
+ static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
+ @VisibleForTesting
+ static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5;
+ @VisibleForTesting
+ static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8;
+ @VisibleForTesting
+ static final int NUMBER_OF_CHILDREN_WHEN_AMBIENT = 1;
private static final AnimationProperties ALPHA_FADE_IN = new AnimationProperties() {
private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
@@ -699,15 +703,18 @@
return childState.height != intrinsicHeight && !childState.hidden;
}
- private int getMaxAllowedVisibleChildren() {
+ @VisibleForTesting
+ int getMaxAllowedVisibleChildren() {
return getMaxAllowedVisibleChildren(false /* likeCollapsed */);
}
- private int getMaxAllowedVisibleChildren(boolean likeCollapsed) {
+ @VisibleForTesting
+ int getMaxAllowedVisibleChildren(boolean likeCollapsed) {
if (mContainingNotification.isShowingAmbient()) {
return NUMBER_OF_CHILDREN_WHEN_AMBIENT;
}
- if (!likeCollapsed && (mChildrenExpanded || mContainingNotification.isUserLocked())) {
+ if (!likeCollapsed && (mChildrenExpanded || mContainingNotification.isUserLocked())
+ && !showingAsLowPriority()) {
return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
}
if (mIsLowPriority || !mContainingNotification.isOnKeyguard()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index ff12c53..f363cf0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -308,4 +308,12 @@
mGroupRow.resetTranslation();
assertEquals(0, mGroupRow.getEntry().expandedIcon.getScrollX());
}
+
+ @Test
+ public void testIsExpanded_userExpanded() {
+ mGroupRow.setExpandable(true);
+ Assert.assertFalse(mGroupRow.isExpanded());
+ mGroupRow.setUserExpanded(true);
+ Assert.assertTrue(mGroupRow.isExpanded());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
index 8a74019..cfacf0b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationChildrenContainerTest.java
@@ -40,30 +40,117 @@
private ExpandableNotificationRow mGroup;
private int mId;
private NotificationTestHelper mNotificationTestHelper;
+ private NotificationChildrenContainer mChildrenContainer;
@Before
public void setUp() throws Exception {
mNotificationTestHelper = new NotificationTestHelper(mContext);
mGroup = mNotificationTestHelper.createGroup();
+ mChildrenContainer = mGroup.getChildrenContainer();
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_ambient() {
+ mGroup.setShowAmbient(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_AMBIENT);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_lowPriority() {
+ mChildrenContainer.setIsLowPriority(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_headsUp() {
+ mGroup.setHeadsUp(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_lowPriority_expandedChildren() {
+ mChildrenContainer.setIsLowPriority(true);
+ mChildrenContainer.setChildrenExpanded(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_lowPriority_userLocked() {
+ mChildrenContainer.setIsLowPriority(true);
+ mChildrenContainer.setUserLocked(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_likeCollapsed() {
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(true),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_COLLAPSED);
+ }
+
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_expandedChildren() {
+ mChildrenContainer.setChildrenExpanded(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED);
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_userLocked() {
+ mGroup.setUserLocked(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED);
+ }
+
+ @Test
+ public void testShowingAsLowPriority_lowPriority() {
+ mChildrenContainer.setIsLowPriority(true);
+ Assert.assertTrue(mChildrenContainer.showingAsLowPriority());
+ }
+
+ @Test
+ public void testShowingAsLowPriority_notLowPriority() {
+ Assert.assertFalse(mChildrenContainer.showingAsLowPriority());
+ }
+
+ @Test
+ public void testShowingAsLowPriority_lowPriority_expanded() {
+ mChildrenContainer.setIsLowPriority(true);
+ mGroup.setExpandable(true);
+ mGroup.setUserExpanded(true, false);
+ Assert.assertFalse(mChildrenContainer.showingAsLowPriority());
+ }
+
+ @Test
+ public void testGetMaxAllowedVisibleChildren_userLocked_expandedChildren_lowPriority() {
+ mGroup.setUserLocked(true);
+ mGroup.setExpandable(true);
+ mGroup.setUserExpanded(true);
+ mChildrenContainer.setIsLowPriority(true);
+ Assert.assertEquals(mChildrenContainer.getMaxAllowedVisibleChildren(),
+ NotificationChildrenContainer.NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED);
}
@Test
public void testLowPriorityHeaderCleared() {
mGroup.setIsLowPriority(true);
- NotificationChildrenContainer childrenContainer = mGroup.getChildrenContainer();
- NotificationHeaderView lowPriorityHeaderView = childrenContainer.getLowPriorityHeaderView();
+ NotificationHeaderView lowPriorityHeaderView = mChildrenContainer.getLowPriorityHeaderView();
Assert.assertTrue(lowPriorityHeaderView.getVisibility() == View.VISIBLE);
- Assert.assertTrue(lowPriorityHeaderView.getParent() == childrenContainer);
+ Assert.assertTrue(lowPriorityHeaderView.getParent() == mChildrenContainer);
mGroup.setIsLowPriority(false);
Assert.assertTrue(lowPriorityHeaderView.getParent() == null);
- Assert.assertTrue(childrenContainer.getLowPriorityHeaderView() == null);
+ Assert.assertTrue(mChildrenContainer.getLowPriorityHeaderView() == null);
}
@Test
public void testRecreateNotificationHeader_hasHeader() {
- NotificationChildrenContainer childrenContainer = mGroup.getChildrenContainer();
- childrenContainer.recreateNotificationHeader(null);
+ mChildrenContainer.recreateNotificationHeader(null);
Assert.assertNotNull("Children container must have a header after recreation",
- childrenContainer.getCurrentHeaderView());
+ mChildrenContainer.getCurrentHeaderView());
}
}
diff --git a/packages/VpnDialogs/res/drawable-hdpi/ic_vpn_dialog.png b/packages/VpnDialogs/res/drawable-hdpi/ic_vpn_dialog.png
deleted file mode 100644
index a0b4b61..0000000
--- a/packages/VpnDialogs/res/drawable-hdpi/ic_vpn_dialog.png
+++ /dev/null
Binary files differ
diff --git a/packages/VpnDialogs/res/drawable-mdpi/ic_vpn_dialog.png b/packages/VpnDialogs/res/drawable-mdpi/ic_vpn_dialog.png
deleted file mode 100644
index df5dfe8..0000000
--- a/packages/VpnDialogs/res/drawable-mdpi/ic_vpn_dialog.png
+++ /dev/null
Binary files differ
diff --git a/packages/VpnDialogs/res/drawable-xhdpi/ic_vpn_dialog.png b/packages/VpnDialogs/res/drawable-xhdpi/ic_vpn_dialog.png
deleted file mode 100644
index 18d5a3a..0000000
--- a/packages/VpnDialogs/res/drawable-xhdpi/ic_vpn_dialog.png
+++ /dev/null
Binary files differ
diff --git a/packages/VpnDialogs/res/drawable-xxhdpi/ic_vpn_dialog.png b/packages/VpnDialogs/res/drawable-xxhdpi/ic_vpn_dialog.png
deleted file mode 100644
index 4d475dc..0000000
--- a/packages/VpnDialogs/res/drawable-xxhdpi/ic_vpn_dialog.png
+++ /dev/null
Binary files differ
diff --git a/packages/VpnDialogs/res/drawable-xxxhdpi/ic_vpn_dialog.png b/packages/VpnDialogs/res/drawable-xxxhdpi/ic_vpn_dialog.png
deleted file mode 100644
index 9d458b4..0000000
--- a/packages/VpnDialogs/res/drawable-xxxhdpi/ic_vpn_dialog.png
+++ /dev/null
Binary files differ
diff --git a/packages/VpnDialogs/res/drawable/ic_vpn_dialog.xml b/packages/VpnDialogs/res/drawable/ic_vpn_dialog.xml
new file mode 100644
index 0000000..24f622e
--- /dev/null
+++ b/packages/VpnDialogs/res/drawable/ic_vpn_dialog.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2017, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="17dp"
+ android:height="17dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M12.09,9C11.11,7.5 9.43,6.5 7.5,6.5C4.46,6.5 2,8.96 2,12c0,3.04 2.46,5.5 5.5,5.5c1.93,0 3.61,-1 4.59,-2.5H14v3h6v-3h2V9H12.09zM20,13h-2v3h-2v-3h-5.16c-0.43,1.44 -1.76,2.5 -3.34,2.5C5.57,15.5 4,13.93 4,12c0,-1.93 1.57,-3.5 3.5,-3.5c1.58,0 2.9,1.06 3.34,2.5H20V13z"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M7.5,12m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0"/>
+</vector>
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index a80ea02..7905def 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6126,6 +6126,15 @@
// CATEGORY: NOTIFICATION
NOTIFICATION_INTERRUPTION = 1501;
+ // OPEN: Settings
+ // CATEGORY: SETTINGS
+ // OS: Q
+ SETTINGS_HOMEPAGE = 1502;
+
+ // OPEN: Settings > Create shortcut(widget)
+ // CATEGORY: SETTINGS
+ // OS: Q
+ SETTINGS_CREATE_SHORTCUT = 1503;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 4117148..33fc5e5 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -466,6 +466,10 @@
// List of WifiIsUnusableEvents which get logged when we notice that WiFi is unusable.
// Collected only when WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED Settings is enabled.
repeated WifiIsUnusableEvent wifi_is_unusable_event_list = 120;
+
+ // Counts the occurrences of each link speed (Mbps) level
+ // with rssi (dBm) and rssi^2 sums (dBm^2)
+ repeated LinkSpeedCount link_speed_counts = 121;
}
// Information that gets logged for every WiFi connection.
@@ -651,6 +655,22 @@
optional int32 count = 2;
}
+// Number of occurrences of a specific link speed (Mbps)
+// and sum of rssi (dBm) and rssi^2 (dBm^2)
+message LinkSpeedCount {
+ // Link speed (Mbps)
+ optional int32 link_speed_mbps = 1;
+
+ // Number of RSSI polls with link_speed
+ optional int32 count = 2;
+
+ // Sum of absolute values of rssi values (dBm)
+ optional int32 rssi_sum_dbm = 3;
+
+ // Sum of squares of rssi values (dBm^2)
+ optional int64 rssi_sum_of_squares_dbm_sq = 4;
+}
+
// Number of occurrences of Soft AP session durations
message SoftApDurationBucket {
// Bucket covers duration : [duration_sec, duration_sec + bucket_size_sec)
@@ -1532,6 +1552,9 @@
// Minimum number of txSuccess to trigger a data stall
// when rxSuccess is 0
optional int32 wifi_data_stall_min_tx_success_without_rx = 3;
+
+ // Indicates if we are logging LinkSpeedCount in metrics
+ optional bool link_speed_counts_logging_enabled = 4;
}
message WifiIsUnusableEvent {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 6ca81c2..3261209 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -172,7 +172,8 @@
long mNativeData;
private long mNextWakeup;
private long mNextNonWakeup;
- private long mLastWakeupSet;
+ private long mNextWakeUpSetAt;
+ private long mNextNonWakeUpSetAt;
private long mLastWakeup;
private long mLastTrigger;
private long mLastTickSet;
@@ -1939,7 +1940,7 @@
TimeUtils.formatDuration(nowELAPSED - mLastAlarmDeliveryTime, pw);
pw.println();
pw.print(" Next non-wakeup delivery time: ");
- TimeUtils.formatDuration(nowELAPSED - mNextNonWakeupDeliveryTime, pw);
+ TimeUtils.formatDuration(mNextNonWakeupDeliveryTime, nowELAPSED, pw);
pw.println();
long nextWakeupRTC = mNextWakeup + (nowRTC - nowELAPSED);
@@ -1948,10 +1949,12 @@
TimeUtils.formatDuration(mNextNonWakeup, nowELAPSED, pw);
pw.print(" = "); pw.print(mNextNonWakeup);
pw.print(" = "); pw.println(sdf.format(new Date(nextNonWakeupRTC)));
+ pw.print(" set at "); TimeUtils.formatDuration(mNextNonWakeUpSetAt, nowELAPSED, pw);
+ pw.println();
pw.print(" Next wakeup alarm: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw);
pw.print(" = "); pw.print(mNextWakeup);
pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC)));
- pw.print(" set at "); TimeUtils.formatDuration(mLastWakeupSet, nowELAPSED, pw);
+ pw.print(" set at "); TimeUtils.formatDuration(mNextWakeUpSetAt, nowELAPSED, pw);
pw.println();
pw.print(" Next kernel non-wakeup alarm: ");
@@ -2290,7 +2293,7 @@
proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_MS,
nowElapsed - mLastWakeup);
proto.write(AlarmManagerServiceDumpProto.TIME_SINCE_LAST_WAKEUP_SET_MS,
- nowElapsed - mLastWakeupSet);
+ nowElapsed - mNextWakeUpSetAt);
proto.write(AlarmManagerServiceDumpProto.TIME_CHANGE_EVENT_COUNT, mNumTimeChanged);
final TreeSet<Integer> users = new TreeSet<>();
@@ -2675,16 +2678,49 @@
DateFormat.format(pattern, info.getTriggerTime()).toString();
}
+ /**
+ * If the last time AlarmThread woke up precedes any due wakeup or non-wakeup alarm that we set
+ * by more than half a minute, log a wtf.
+ */
+ private void validateLastAlarmExpiredLocked(long nowElapsed) {
+ final StringBuilder errorMsg = new StringBuilder();
+ boolean stuck = false;
+ if (mNextNonWakeup < nowElapsed && mLastWakeup < (mNextNonWakeup - 30_000)) {
+ stuck = true;
+ errorMsg.append("[mNextNonWakeup=");
+ TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
+ errorMsg.append(", mLastWakeup=");
+ TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
+ errorMsg.append(", timerfd_gettime=" + getNextAlarm(mNativeData, ELAPSED_REALTIME));
+ errorMsg.append("];");
+ }
+ if (mNextWakeup < nowElapsed && mLastWakeup < (mNextWakeup - 30_000)) {
+ stuck = true;
+ errorMsg.append("[mNextWakeup=");
+ TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
+ errorMsg.append(", mLastWakeup=");
+ TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
+ errorMsg.append(", timerfd_gettime="
+ + getNextAlarm(mNativeData, ELAPSED_REALTIME_WAKEUP));
+ errorMsg.append("];");
+ }
+ if (stuck) {
+ Slog.wtf(TAG, "Alarm delivery stuck: " + errorMsg.toString());
+ }
+ }
+
void rescheduleKernelAlarmsLocked() {
// Schedule the next upcoming wakeup alarm. If there is a deliverable batch
// prior to that which contains no wakeups, we schedule that as well.
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ validateLastAlarmExpiredLocked(nowElapsed);
long nextNonWakeup = 0;
if (mAlarmBatches.size() > 0) {
final Batch firstWakeup = findFirstWakeupBatchLocked();
final Batch firstBatch = mAlarmBatches.get(0);
if (firstWakeup != null) {
mNextWakeup = firstWakeup.start;
- mLastWakeupSet = SystemClock.elapsedRealtime();
+ mNextWakeUpSetAt = nowElapsed;
setLocked(ELAPSED_REALTIME_WAKEUP, firstWakeup.start);
}
if (firstBatch != firstWakeup) {
@@ -2698,6 +2734,7 @@
}
if (nextNonWakeup != 0) {
mNextNonWakeup = nextNonWakeup;
+ mNextNonWakeUpSetAt = nowElapsed;
setLocked(ELAPSED_REALTIME, nextNonWakeup);
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f096135..3c94a34 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1024,7 +1024,8 @@
}
}
- private NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
+ @VisibleForTesting
+ protected NetworkAgentInfo getNetworkAgentInfoForNetwork(Network network) {
if (network == null) {
return null;
}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index caea282..20875a9 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1827,50 +1827,6 @@
@GuardedBy("mMethodMap")
@NonNull
- InputBindResult startInputLocked(
- /* @InputMethodClient.StartInputReason */ final int startInputReason,
- IInputMethodClient client, IInputContext inputContext,
- /* @InputConnectionInspector.missingMethods */ final int missingMethods,
- @Nullable EditorInfo attribute, int controlFlags) {
- // If no method is currently selected, do nothing.
- if (mCurMethodId == null) {
- return InputBindResult.NO_IME;
- }
-
- ClientState cs = mClients.get(client.asBinder());
- if (cs == null) {
- throw new IllegalArgumentException("unknown client "
- + client.asBinder());
- }
-
- if (attribute == null) {
- Slog.w(TAG, "Ignoring startInput with null EditorInfo."
- + " uid=" + cs.uid + " pid=" + cs.pid);
- return InputBindResult.NULL_EDITOR_INFO;
- }
-
- try {
- if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
- // Check with the window manager to make sure this client actually
- // has a window with focus. If not, reject. This is thread safe
- // because if the focus changes some time before or after, the
- // next client receiving focus that has any interest in input will
- // be calling through here after that change happens.
- if (DEBUG) {
- Slog.w(TAG, "Starting input on non-focused client " + cs.client
- + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
- }
- return InputBindResult.NOT_IME_TARGET_WINDOW;
- }
- } catch (RemoteException e) {
- }
-
- return startInputUncheckedLocked(cs, inputContext, missingMethods, attribute,
- controlFlags, startInputReason);
- }
-
- @GuardedBy("mMethodMap")
- @NonNull
InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext,
/* @InputConnectionInspector.missingMethods */ final int missingMethods,
@NonNull EditorInfo attribute, int controlFlags,
@@ -1997,36 +1953,6 @@
return InputBindResult.IME_NOT_CONNECTED;
}
- @NonNull
- private InputBindResult startInput(
- /* @InputMethodClient.StartInputReason */ final int startInputReason,
- IInputMethodClient client, IInputContext inputContext,
- /* @InputConnectionInspector.missingMethods */ final int missingMethods,
- @Nullable EditorInfo attribute, int controlFlags) {
- if (!calledFromValidUser()) {
- return InputBindResult.INVALID_USER;
- }
- synchronized (mMethodMap) {
- if (DEBUG) {
- Slog.v(TAG, "startInput: reason="
- + InputMethodClient.getStartInputReason(startInputReason)
- + " client = " + client.asBinder()
- + " inputContext=" + inputContext
- + " missingMethods="
- + InputConnectionInspector.getMissingMethodFlagsAsString(missingMethods)
- + " attribute=" + attribute
- + " controlFlags=#" + Integer.toHexString(controlFlags));
- }
- final long ident = Binder.clearCallingIdentity();
- try {
- return startInputLocked(startInputReason, client, inputContext, missingMethods,
- attribute, controlFlags);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
@Override
public void finishInput(IInputMethodClient client) {
}
@@ -2741,15 +2667,13 @@
int windowFlags, @Nullable EditorInfo attribute, IInputContext inputContext,
/* @InputConnectionInspector.missingMethods */ final int missingMethods,
int unverifiedTargetSdkVersion) {
- final InputBindResult result;
- if (windowToken != null) {
- result = windowGainedFocus(startInputReason, client, windowToken, controlFlags,
- softInputMode, windowFlags, attribute, inputContext, missingMethods,
- unverifiedTargetSdkVersion);
- } else {
- result = startInput(startInputReason, client, inputContext, missingMethods, attribute,
- controlFlags);
+ if (windowToken == null) {
+ Slog.e(TAG, "windowToken cannot be null.");
+ return InputBindResult.NULL;
}
+ final InputBindResult result = startInputOrWindowGainedFocusInternal(startInputReason,
+ client, windowToken, controlFlags, softInputMode, windowFlags, attribute,
+ inputContext, missingMethods, unverifiedTargetSdkVersion);
if (result == null) {
// This must never happen, but just in case.
Slog.wtf(TAG, "InputBindResult is @NonNull. startInputReason="
@@ -2762,9 +2686,9 @@
}
@NonNull
- private InputBindResult windowGainedFocus(
+ private InputBindResult startInputOrWindowGainedFocusInternal(
/* @InputMethodClient.StartInputReason */ final int startInputReason,
- IInputMethodClient client, IBinder windowToken, int controlFlags,
+ IInputMethodClient client, @NonNull IBinder windowToken, int controlFlags,
/* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
int windowFlags, EditorInfo attribute, IInputContext inputContext,
/* @InputConnectionInspector.missingMethods */ final int missingMethods,
@@ -2775,7 +2699,7 @@
long ident = Binder.clearCallingIdentity();
try {
synchronized (mMethodMap) {
- if (DEBUG) Slog.v(TAG, "windowGainedFocus: reason="
+ if (DEBUG) Slog.v(TAG, "startInputOrWindowGainedFocusInternal: reason="
+ InputMethodClient.getStartInputReason(startInputReason)
+ " client=" + client.asBinder()
+ " inputContext=" + inputContext
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 607db4e..ad9fa40 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1588,10 +1588,10 @@
// Wakeup apps for the (SUBSCRIPTION_)PHONE_STATE broadcast.
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ // Create a version of the intent with the number always populated.
Intent intentWithPhoneNumber = new Intent(intent);
- if (!TextUtils.isEmpty(incomingNumber)) {
- intentWithPhoneNumber.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
- }
+ intentWithPhoneNumber.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
+
// Send broadcast twice, once for apps that have PRIVILEGED permission and once for those
// that have the runtime one
mContext.sendBroadcastAsUser(intentWithPhoneNumber, UserHandle.ALL,
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 0941bc8..c043e18 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -63,6 +63,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
@@ -1024,19 +1025,46 @@
private static final class ISpellCheckerServiceCallbackBinder
extends ISpellCheckerServiceCallback.Stub {
@NonNull
- private final SpellCheckerBindGroup mBindGroup;
- @NonNull
- private final SessionRequest mRequest;
+ private final Object mCallbackLock = new Object();
- ISpellCheckerServiceCallbackBinder(@NonNull final SpellCheckerBindGroup bindGroup,
- @NonNull final SessionRequest request) {
- mBindGroup = bindGroup;
- mRequest = request;
+ @GuardedBy("mCallbackLock")
+ @Nullable
+ private WeakReference<SpellCheckerBindGroup> mBindGroup;
+
+ /**
+ * Original {@link SessionRequest} that is associated with this callback.
+ *
+ * <p>Note that {@link SpellCheckerBindGroup#mOnGoingSessionRequests} guarantees that this
+ * {@link SessionRequest} object is kept alive until the request is canceled.</p>
+ */
+ @GuardedBy("mCallbackLock")
+ @Nullable
+ private WeakReference<SessionRequest> mRequest;
+
+ ISpellCheckerServiceCallbackBinder(@NonNull SpellCheckerBindGroup bindGroup,
+ @NonNull SessionRequest request) {
+ synchronized (mCallbackLock) {
+ mBindGroup = new WeakReference<>(bindGroup);
+ mRequest = new WeakReference<>(request);
+ }
}
@Override
public void onSessionCreated(@Nullable ISpellCheckerSession newSession) {
- mBindGroup.onSessionCreated(newSession, mRequest);
+ final SpellCheckerBindGroup group;
+ final SessionRequest request;
+ synchronized (mCallbackLock) {
+ if (mBindGroup == null || mRequest == null) {
+ return;
+ }
+ group = mBindGroup.get();
+ request = mRequest.get();
+ mBindGroup = null;
+ mRequest = null;
+ }
+ if (group != null && request != null) {
+ group.onSessionCreated(newSession, request);
+ }
}
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index ca715b5..652bc6a 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -24,7 +24,6 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
@@ -32,6 +31,7 @@
import java.util.Set;
import java.util.function.Predicate;
+import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.NotificationManager;
@@ -59,7 +59,6 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.TransferPipe;
-import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.server.AppStateTracker;
@@ -1869,7 +1868,7 @@
+ " type=" + resolvedType + " callingUid=" + callingUid);
userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
- ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
+ ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", null);
ServiceMap smap = getServiceMapLocked(userId);
final ComponentName comp = service.getComponent();
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index ee93fc8..5608f97 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -300,7 +300,7 @@
}
}
- final ActivityManagerService service = mSupervisor.mService.mAm;
+ final ActivityTaskManagerService service = mSupervisor.mService;
if (!isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow,
service.mSupportsSplitScreenMultiWindow, service.mSupportsFreeformWindowManagement,
service.mSupportsPictureInPicture, activityType)) {
@@ -536,7 +536,7 @@
}
// Make sure the windowing mode we are trying to use makes sense for what is supported.
- final ActivityManagerService service = mSupervisor.mService.mAm;
+ final ActivityTaskManagerService service = mSupervisor.mService;
boolean supportsMultiWindow = service.mSupportsMultiWindow;
boolean supportsSplitScreen = service.mSupportsSplitScreenMultiWindow;
boolean supportsFreeform = service.mSupportsFreeformWindowManagement;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 37253ec..1c61f30 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -22,11 +22,10 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.REMOVE_TASKS;
-import static android.Manifest.permission.STOP_APP_SWITCHES;
+import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
import static android.app.AppOpsManager.OP_NONE;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
@@ -120,7 +119,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
@@ -134,9 +132,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
@@ -169,10 +165,6 @@
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
import static com.android.server.am.MemoryStatUtil.hasMemcg;
-import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
-import static android.view.WindowManager.TRANSIT_NONE;
-import static android.view.WindowManager.TRANSIT_TASK_OPEN;
-import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -187,6 +179,7 @@
import android.app.ActivityManager.StackInfo;
import android.app.ActivityManager.TaskSnapshot;
import android.app.ActivityManagerInternal;
+import android.app.ActivityTaskManagerInternal;
import android.app.ActivityTaskManagerInternal.ScreenObserver;
import android.app.ActivityTaskManagerInternal.SleepToken;
import android.app.ActivityManagerProto;
@@ -307,7 +300,6 @@
import android.os.SystemProperties;
import android.os.Trace;
import android.os.TransactionTooLargeException;
-import android.os.UpdateLock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
@@ -471,8 +463,6 @@
private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
- private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
- private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_LRU = TAG + POSTFIX_LRU;
private static final String TAG_MU = TAG + POSTFIX_MU;
@@ -483,13 +473,10 @@
private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
private static final String TAG_PSS = TAG + POSTFIX_PSS;
- private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
- private static final String TAG_STACK = TAG + POSTFIX_STACK;
private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
- private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
// Mock "pretend we're idle now" broadcast action to the job scheduler; declared
// here so that while the job scheduler can depend on AMS, the other way around
@@ -514,10 +501,6 @@
// Maximum number of receivers an app can register.
private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
- // Amount of time after a call to stopAppSwitches() during which we will
- // prevent further untrusted switches from happening.
- static final long APP_SWITCH_DELAY_TIME = 5*1000;
-
// How long we wait for a launched process to attach to the activity manager
// before we decide it's never going to come up for real.
static final int PROC_START_TIMEOUT = 10*1000;
@@ -561,11 +544,6 @@
/** If a UID observer takes more than this long, send a WTF. */
private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
- // Access modes for handleIncomingUser.
- static final int ALLOW_NON_FULL = 0;
- static final int ALLOW_NON_FULL_IN_PROFILE = 1;
- static final int ALLOW_FULL_ONLY = 2;
-
// Necessary ApplicationInfo flags to mark an app as persistent
private static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
@@ -577,9 +555,6 @@
// Used to indicate that an app transition should be animated.
static final boolean ANIMATE = true;
- // Determines whether to take full screen screenshots
- static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
-
/**
* Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
*/
@@ -628,9 +603,6 @@
// devices.
private boolean mShowDialogs = true;
- // VR Vr2d Display Id.
- int mVr2dDisplayId = INVALID_DISPLAY;
-
// Whether we should use SCHED_FIFO for UI and RenderThreads.
private boolean mUseFifoUiScheduling = false;
@@ -679,12 +651,6 @@
final UserController mUserController;
- /**
- * Packages that are being allowed to perform unrestricted app switches. Mapping is
- * User -> Type -> uid.
- */
- final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
-
final AppErrors mAppErrors;
final AppWarnings mAppWarnings;
@@ -1329,18 +1295,6 @@
final Context mUiContext;
/**
- * The time at which we will allow normal application switches again,
- * after a call to {@link #stopAppSwitches()}.
- */
- long mAppSwitchesAllowedTime;
-
- /**
- * This is set to true after the first switch after mAppSwitchesAllowedTime
- * is set; any switches after that will clear the time.
- */
- boolean mDidAppSwitch;
-
- /**
* Last time (in uptime) at which we checked for power usage.
*/
long mLastPowerCheckUptime;
@@ -1491,29 +1445,7 @@
String mOrigDebugApp = null;
boolean mOrigWaitForDebugger = false;
boolean mAlwaysFinishActivities = false;
- boolean mForceResizableActivities;
- /**
- * Flag that indicates if multi-window is enabled.
- *
- * For any particular form of multi-window to be enabled, generic multi-window must be enabled
- * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
- * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
- * At least one of the forms of multi-window must be enabled in order for this flag to be
- * initialized to 'true'.
- *
- * @see #mSupportsSplitScreenMultiWindow
- * @see #mSupportsFreeformWindowManagement
- * @see #mSupportsPictureInPicture
- * @see #mSupportsMultiDisplay
- */
- boolean mSupportsMultiWindow;
- boolean mSupportsSplitScreenMultiWindow;
- boolean mSupportsFreeformWindowManagement;
- boolean mSupportsPictureInPicture;
- boolean mSupportsMultiDisplay;
- boolean mSupportsLeanbackOnly;
- IActivityController mController = null;
- boolean mControllerIsAMonkey = false;
+
String mProfileApp = null;
ProcessRecord mProfileProc = null;
ProfilerInfo mProfilerInfo = null;
@@ -1637,8 +1569,6 @@
}
}
- final List<ScreenObserver> mScreenObservers = new ArrayList<>();
-
final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
@@ -1680,12 +1610,6 @@
long mLastWriteTime = 0;
/**
- * Used to retain an update lock when the foreground activity is in
- * immersive mode.
- */
- final UpdateLock mUpdateLock = new UpdateLock("immersive");
-
- /**
* Set to true after the system has finished booting.
*/
boolean mBooted = false;
@@ -1697,6 +1621,7 @@
WindowManagerService mWindowManager;
ActivityTaskManagerService mActivityTaskManager;
+ ActivityTaskManagerInternal mAtmInternal;
final ActivityThread mSystemThread;
private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -1748,7 +1673,6 @@
static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
static final int REPORT_MEM_USAGE_MSG = 33;
- static final int IMMERSIVE_MODE_LOCK_MSG = 37;
static final int PERSIST_URI_GRANTS_MSG = 38;
static final int UPDATE_TIME_PREFERENCE_MSG = 41;
static final int FINISH_BOOTING_MSG = 45;
@@ -1763,8 +1687,6 @@
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
static final int IDLE_UIDS_MSG = 58;
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
- static final int DISPATCH_SCREEN_AWAKE_MSG = 64;
- static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65;
static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
@@ -1790,11 +1712,6 @@
*/
private boolean mUserIsMonkey;
- /** The dimensions of the thumbnails in the Recents UI. */
- int mThumbnailWidth;
- int mThumbnailHeight;
- float mFullscreenThumbnailScale;
-
final ServiceThread mHandlerThread;
final MainHandler mHandler;
final Handler mUiHandler;
@@ -2201,20 +2118,6 @@
thread.start();
break;
}
- case IMMERSIVE_MODE_LOCK_MSG: {
- final boolean nextState = (msg.arg1 != 0);
- if (mUpdateLock.isHeld() != nextState) {
- if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
- "Applying new update lock state '" + nextState
- + "' for " + (ActivityRecord)msg.obj);
- if (nextState) {
- mUpdateLock.acquire();
- } else {
- mUpdateLock.release();
- }
- }
- break;
- }
case PERSIST_URI_GRANTS_MSG: {
writeGrantedUriPermissions();
break;
@@ -2382,18 +2285,6 @@
case IDLE_UIDS_MSG: {
idleUids();
} break;
- case DISPATCH_SCREEN_AWAKE_MSG: {
- final boolean isAwake = msg.arg1 != 0;
- for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
- mScreenObservers.get(i).onAwakeStateChanged(isAwake);
- }
- } break;
- case DISPATCH_SCREEN_KEYGUARD_MSG: {
- final boolean isShowing = msg.arg1 != 0;
- for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
- mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
- }
- } break;
case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -2588,6 +2479,7 @@
synchronized (this) {
mActivityTaskManager = atm;
mActivityTaskManager.setActivityManagerService(this);
+ mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
mStackSupervisor = mActivityTaskManager.mStackSupervisor;
}
}
@@ -3011,11 +2903,6 @@
}
}
- void onUserStoppedLocked(int userId) {
- mActivityTaskManager.getRecentTasks().unloadUserDataFromMemoryLocked(userId);
- mAllowAppSwitchUids.remove(userId);
- }
-
public void initPowerManagement() {
mStackSupervisor.initPowerManagement();
mBatteryStatsService.initPowerManagement();
@@ -3338,7 +3225,7 @@
mWindowManager.setFocusedApp(r.appToken, true);
- applyUpdateLockStateLocked(r);
+ mActivityTaskManager.applyUpdateLockStateLocked(r);
mActivityTaskManager.applyUpdateVrModeLocked(r);
EventLogTags.writeAmSetResumedActivity(
@@ -3382,16 +3269,6 @@
mActivityTaskManager.unregisterTaskStackListener(listener);
}
- final void applyUpdateLockStateLocked(ActivityRecord r) {
- // Modifications to the UpdateLock state are done on our handler, outside
- // the activity manager's locks. The new state is determined based on the
- // state *now* of the relevant activity record. The object is passed to
- // the handler solely for logging detail, not to be consulted/modified.
- final boolean nextState = r != null && r.immersive;
- mHandler.sendMessage(
- mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
- }
-
final void showAskCompatModeDialogLocked(ActivityRecord r) {
Message msg = Message.obtain();
msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
@@ -4416,7 +4293,7 @@
return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
}
- void enforceNotIsolatedCaller(String caller) {
+ private void enforceNotIsolatedCaller(String caller) {
if (UserHandle.isIsolated(Binder.getCallingUid())) {
throw new SecurityException("Isolated process not allowed to call " + caller);
}
@@ -5651,7 +5528,7 @@
* @param maxProcState the process state at or below which to preserve
* processes, or {@code -1} to ignore the process state
*/
- private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
+ void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
!= PackageManager.PERMISSION_GRANTED) {
final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
@@ -7612,7 +7489,7 @@
}
}
- int checkComponentPermission(String permission, int pid, int uid,
+ static int checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) {
if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED;
@@ -7700,15 +7577,6 @@
}
/**
- * This can be called with or without the global lock held.
- */
- void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
- if (!mActivityTaskManager.getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
- enforceCallingPermission(permission, func);
- }
- }
-
- /**
* Determine if UID is holding permissions required to access {@link Uri} in
* the given {@link ProviderInfo}. Final permission checking is always done
* in {@link ContentProvider}.
@@ -9165,38 +9033,6 @@
mActivityTaskManager.cancelTaskWindowTransition(taskId);
}
- boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
- if (mActivityTaskManager.getRecentTasks().isCallerRecents(callingUid)) {
- // Always allow the recents component to get tasks
- return true;
- }
-
- boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
- callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
- if (!allowed) {
- if (checkPermission(android.Manifest.permission.GET_TASKS,
- callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
- // Temporary compatibility: some existing apps on the system image may
- // still be requesting the old permission and not switched to the new
- // one; if so, we'll still allow them full access. This means we need
- // to see if they are holding the old permission and are a system app.
- try {
- if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
- allowed = true;
- if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
- + " is using old GET_TASKS but privileged; allowing");
- }
- } catch (RemoteException e) {
- }
- }
- }
- if (!allowed) {
- if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
- + " does not hold REAL_GET_TASKS; limiting output");
- }
- return allowed;
- }
-
@Override
public void setTaskResizeable(int taskId, int resizeableMode) {
mActivityTaskManager.setTaskResizeable(taskId, resizeableMode);
@@ -10813,8 +10649,7 @@
// Also update state in a special way for running foreground services UI.
mServices.updateScreenStateLocked(isAwake);
reportCurWakefulnessUsageEventLocked();
- mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
- .sendToTarget();
+ mActivityTaskManager.onScreenAwakeChanged(isAwake);
}
updateOomAdjLocked();
}
@@ -10978,69 +10813,12 @@
@Override
public void stopAppSwitches() {
- enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
- synchronized(this) {
- mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
- + APP_SWITCH_DELAY_TIME;
- mDidAppSwitch = false;
- mActivityTaskManager.getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
- }
+ mActivityTaskManager.stopAppSwitches();
}
+ @Override
public void resumeAppSwitches() {
- enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
- synchronized(this) {
- // Note that we don't execute any pending app switches... we will
- // let those wait until either the timeout, or the next start
- // activity request.
- mAppSwitchesAllowedTime = 0;
- }
- }
-
- boolean checkAllowAppSwitchUid(int uid) {
- ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
- if (types != null) {
- for (int i = types.size() - 1; i >= 0; i--) {
- if (types.valueAt(i).intValue() == uid) {
- return true;
- }
- }
- }
- return false;
- }
-
- boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
- int callingPid, int callingUid, String name) {
- if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
- return true;
- }
-
- if (mActivityTaskManager.getRecentTasks().isCallerRecents(sourceUid)) {
- return true;
- }
-
- int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
- if (perm == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- if (checkAllowAppSwitchUid(sourceUid)) {
- return true;
- }
-
- // If the actual IPC caller is different from the logical source, then
- // also see if they are allowed to control app switches.
- if (callingUid != -1 && callingUid != sourceUid) {
- perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
- if (perm == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- if (checkAllowAppSwitchUid(callingUid)) {
- return true;
- }
- }
-
- Slog.w(TAG, name + " request from " + sourceUid + " stopped");
- return false;
+ mActivityTaskManager.resumeAppSwitches();
}
public void setDebugApp(String packageName, boolean waitForDebugger,
@@ -11194,13 +10972,7 @@
@Override
public void setActivityController(IActivityController controller, boolean imAMonkey) {
- enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
- "setActivityController()");
- synchronized (this) {
- mController = controller;
- mControllerIsAMonkey = imAMonkey;
- Watchdog.getInstance().setActivityController(controller);
- }
+ mActivityTaskManager.setActivityController(controller, imAMonkey);
}
@Override
@@ -11225,7 +10997,7 @@
public boolean isUserAMonkey() {
synchronized (this) {
// If there is a controller also implies the user is a monkey.
- return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
+ return mUserIsMonkey || mActivityTaskManager.isControllerAMonkey();
}
}
@@ -11532,17 +11304,6 @@
return false;
}
- /**
- * Check that we have the features required for VR-related API calls, and throw an exception if
- * not.
- */
- void enforceSystemHasVrFeature() {
- if (!mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
- throw new UnsupportedOperationException("VR mode not supported on this device!");
- }
- }
-
@Override
public void setRenderThread(int tid) {
synchronized (this) {
@@ -11597,7 +11358,7 @@
@Override
public boolean isVrModePackageEnabled(ComponentName packageName) {
- enforceSystemHasVrFeature();
+ mActivityTaskManager.enforceSystemHasVrFeature();
final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
@@ -12070,78 +11831,22 @@
private void retrieveSettings() {
final ContentResolver resolver = mContext.getContentResolver();
- final boolean freeformWindowManagement =
- mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
- || Settings.Global.getInt(
- resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
+ mActivityTaskManager.retrieveSettings(resolver);
- final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
- final boolean supportsPictureInPicture = supportsMultiWindow &&
- mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
- final boolean supportsSplitScreenMultiWindow =
- ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
- final boolean supportsMultiDisplay = mContext.getPackageManager()
- .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
final boolean alwaysFinishActivities =
Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
- final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
- final boolean forceResizable = Settings.Global.getInt(
- resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
- final boolean supportsLeanbackOnly =
- mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
mHiddenApiBlacklist.registerObserver();
- // Transfer any global setting for forcing RTL layout, into a System Property
- SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
-
- final Configuration configuration = new Configuration();
- Settings.System.getConfiguration(resolver, configuration);
- if (forceRtl) {
- // This will take care of setting the correct layout direction flags
- configuration.setLayoutDirection(configuration.locale);
- }
-
synchronized (this) {
mDebugApp = mOrigDebugApp = debugApp;
mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
mAlwaysFinishActivities = alwaysFinishActivities;
- mSupportsLeanbackOnly = supportsLeanbackOnly;
- mForceResizableActivities = forceResizable;
- final boolean multiWindowFormEnabled = freeformWindowManagement
- || supportsSplitScreenMultiWindow
- || supportsPictureInPicture
- || supportsMultiDisplay;
- if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
- mSupportsMultiWindow = true;
- mSupportsFreeformWindowManagement = freeformWindowManagement;
- mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
- mSupportsPictureInPicture = supportsPictureInPicture;
- mSupportsMultiDisplay = supportsMultiDisplay;
- } else {
- mSupportsMultiWindow = false;
- mSupportsFreeformWindowManagement = false;
- mSupportsSplitScreenMultiWindow = false;
- mSupportsPictureInPicture = false;
- mSupportsMultiDisplay = false;
- }
- mWindowManager.setForceResizableTasks(mForceResizableActivities);
- mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
- // This happens before any activities are started, so we can change global configuration
- // in-place.
- updateConfigurationLocked(configuration, null, true);
- final Configuration globalConfig = getGlobalConfiguration();
- if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
-
// Load resources only after the current configuration has been set.
final Resources res = mContext.getResources();
- mThumbnailWidth = res.getDimensionPixelSize(
- com.android.internal.R.dimen.thumbnail_width);
- mThumbnailHeight = res.getDimensionPixelSize(
- com.android.internal.R.dimen.thumbnail_height);
mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
com.android.internal.R.string.config_appsNotReportingCrashes));
mUserController.mUserSwitchUiEnabled = !res.getBoolean(
@@ -12149,14 +11854,6 @@
mUserController.mMaxRunningUsers = res.getInteger(
com.android.internal.R.integer.config_multiuserMaxRunningUsers);
- if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
- mFullscreenThumbnailScale = (float) res
- .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
- (float) globalConfig.screenWidthDp;
- } else {
- mFullscreenThumbnailScale = res.getFraction(
- com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
- }
mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
}
}
@@ -12937,7 +12634,7 @@
final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
callingUid) == PackageManager.PERMISSION_GRANTED;
final int userId = UserHandle.getUserId(callingUid);
- final boolean allUids = isGetTasksAllowed(
+ final boolean allUids = mAtmInternal.isGetTasksAllowed(
"getRunningAppProcesses", Binder.getCallingPid(), callingUid);
synchronized (this) {
@@ -13965,7 +13662,7 @@
}
if (dumpAll) {
if (dumpPackage == null) {
- pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
+ pw.println(" mConfigWillChange: " + mActivityTaskManager.getFocusedStack().mConfigWillChange);
}
if (mCompatModePackages.getPackages().size() > 0) {
boolean printed = false;
@@ -14130,10 +13827,10 @@
pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
}
}
- if (mAllowAppSwitchUids.size() > 0) {
+ if (mActivityTaskManager.mAllowAppSwitchUids.size() > 0) {
boolean printed = false;
- for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
- ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
+ for (int i = 0; i < mActivityTaskManager.mAllowAppSwitchUids.size(); i++) {
+ ArrayMap<String, Integer> types = mActivityTaskManager.mAllowAppSwitchUids.valueAt(i);
for (int j = 0; j < types.size(); j++) {
if (dumpPackage == null ||
UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
@@ -14146,7 +13843,7 @@
printed = true;
}
pw.print(" User ");
- pw.print(mAllowAppSwitchUids.keyAt(i));
+ pw.print(mActivityTaskManager.mAllowAppSwitchUids.keyAt(i));
pw.print(": Type ");
pw.print(types.keyAt(j));
pw.print(" = ");
@@ -14160,9 +13857,9 @@
if (mAlwaysFinishActivities) {
pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities);
}
- if (mController != null) {
- pw.println(" mController=" + mController
- + " mControllerIsAMonkey=" + mControllerIsAMonkey);
+ if (mActivityTaskManager.mController != null) {
+ pw.println(" mController=" + mActivityTaskManager.mController
+ + " mControllerIsAMonkey=" + mActivityTaskManager.mControllerIsAMonkey);
}
if (dumpAll) {
pw.println(" Total persistent processes: " + numPers);
@@ -14343,7 +14040,7 @@
if (dumpPackage == null) {
mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
- proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange);
+ proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, mActivityTaskManager.getFocusedStack().mConfigWillChange);
}
if (mHomeProcess != null && (dumpPackage == null
@@ -14493,10 +14190,10 @@
if (dumpPackage == null) {
proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
- if (mController != null) {
+ if (mActivityTaskManager.mController != null) {
final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
- proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString());
- proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey);
+ proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mActivityTaskManager.mController.toString());
+ proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mActivityTaskManager.mControllerIsAMonkey);
proto.end(token);
}
proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
@@ -17363,8 +17060,8 @@
final int callingUid = Binder.getCallingUid();
final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
- final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
- callingUid);
+ final boolean allowed = mAtmInternal.isGetTasksAllowed("getServices",
+ Binder.getCallingPid(), callingUid);
synchronized (this) {
return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
allowed, canInteractAcrossUsers);
@@ -19336,10 +19033,6 @@
return config;
}
- ActivityStack getFocusedStack() {
- return mStackSupervisor.getFocusedStack();
- }
-
@Override
public StackInfo getFocusedStackInfo() throws RemoteException {
return mActivityTaskManager.getFocusedStackInfo();
@@ -19369,18 +19062,7 @@
int userId = UserHandle.getCallingUserId();
- synchronized(this) {
- updatePersistentConfigurationLocked(values, userId);
- }
- }
-
- private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
- final long origId = Binder.clearCallingIdentity();
- try {
- updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
- } finally {
- Binder.restoreCallingIdentity(origId);
- }
+ mActivityTaskManager.updatePersistentConfiguration(values, userId);
}
private void updateFontScaleIfNeeded(@UserIdInt int userId) {
@@ -19395,7 +19077,7 @@
final Configuration configuration
= mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
configuration.fontScale = scaleFactor;
- updatePersistentConfigurationLocked(configuration, userId);
+ mActivityTaskManager.updatePersistentConfiguration(configuration, userId);
}
}
@@ -19423,356 +19105,6 @@
return mActivityTaskManager.updateConfiguration(values);
}
- void updateUserConfigurationLocked() {
- final Configuration configuration = new Configuration(getGlobalConfiguration());
- final int currentUserId = mUserController.getCurrentUserId();
- Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
- currentUserId, Settings.System.canWrite(mContext));
- updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
- false /* persistent */, currentUserId, false /* deferResume */);
- }
-
- boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
- boolean initLocale) {
- return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
- }
-
- boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
- boolean initLocale, boolean deferResume) {
- // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
- return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
- UserHandle.USER_NULL, deferResume);
- }
-
- // To cache the list of supported system locales
- private String[] mSupportedSystemLocales = null;
-
- private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
- boolean initLocale, boolean persistent, int userId, boolean deferResume) {
- return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
- deferResume, null /* result */);
- }
-
- /**
- * Do either or both things: (1) change the current configuration, and (2)
- * make sure the given activity is running with the (now) current
- * configuration. Returns true if the activity has been left running, or
- * false if <var>starting</var> is being destroyed to match the new
- * configuration.
- *
- * @param userId is only used when persistent parameter is set to true to persist configuration
- * for that particular user
- */
- boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
- boolean initLocale, boolean persistent, int userId, boolean deferResume,
- ActivityTaskManagerService.UpdateConfigurationResult result) {
- int changes = 0;
- boolean kept = true;
-
- if (mWindowManager != null) {
- mWindowManager.deferSurfaceLayout();
- }
- try {
- if (values != null) {
- changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
- deferResume);
- }
-
- kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
- } finally {
- if (mWindowManager != null) {
- mWindowManager.continueSurfaceLayout();
- }
- }
-
- if (result != null) {
- result.changes = changes;
- result.activityRelaunched = !kept;
- }
- return kept;
- }
-
- /**
- * Returns true if this configuration change is interesting enough to send an
- * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
- */
- private static boolean isSplitConfigurationChange(int configDiff) {
- return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
- }
-
- /** Update default (global) configuration and notify listeners about changes. */
- private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
- boolean persistent, int userId, boolean deferResume) {
- mActivityTaskManager.mTempConfig.setTo(getGlobalConfiguration());
- final int changes = mActivityTaskManager.mTempConfig.updateFrom(values);
- if (changes == 0) {
- // Since calling to Activity.setRequestedOrientation leads to freezing the window with
- // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
- // performDisplayOverrideConfigUpdate in order to send the new display configuration
- // (even if there are no actual changes) to unfreeze the window.
- performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
- return 0;
- }
-
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
- "Updating global configuration to: " + values);
-
- EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
- StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
- values.colorMode,
- values.densityDpi,
- values.fontScale,
- values.hardKeyboardHidden,
- values.keyboard,
- values.keyboardHidden,
- values.mcc,
- values.mnc,
- values.navigation,
- values.navigationHidden,
- values.orientation,
- values.screenHeightDp,
- values.screenLayout,
- values.screenWidthDp,
- values.smallestScreenWidthDp,
- values.touchscreen,
- values.uiMode);
-
-
- if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
- final LocaleList locales = values.getLocales();
- int bestLocaleIndex = 0;
- if (locales.size() > 1) {
- if (mSupportedSystemLocales == null) {
- mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
- }
- bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
- }
- SystemProperties.set("persist.sys.locale",
- locales.get(bestLocaleIndex).toLanguageTag());
- LocaleList.setDefault(locales, bestLocaleIndex);
- mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
- locales.get(bestLocaleIndex)));
- }
-
- mActivityTaskManager.mConfigurationSeq = Math.max(++mActivityTaskManager.mConfigurationSeq, 1);
- mActivityTaskManager.mTempConfig.seq = mActivityTaskManager.mConfigurationSeq;
-
- // Update stored global config and notify everyone about the change.
- mStackSupervisor.onConfigurationChanged(mActivityTaskManager.mTempConfig);
-
- Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mActivityTaskManager.mTempConfig);
- // TODO(multi-display): Update UsageEvents#Event to include displayId.
- mUsageStatsService.reportConfigurationChange(mActivityTaskManager.mTempConfig,
- mUserController.getCurrentUserId());
-
- // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
- updateShouldShowDialogsLocked(mActivityTaskManager.mTempConfig);
-
- AttributeCache ac = AttributeCache.instance();
- if (ac != null) {
- ac.updateConfiguration(mActivityTaskManager.mTempConfig);
- }
-
- // Make sure all resources in our process are updated right now, so that anyone who is going
- // to retrieve resource values after we return will be sure to get the new ones. This is
- // especially important during boot, where the first config change needs to guarantee all
- // resources have that config before following boot code is executed.
- mSystemThread.applyConfigurationToResources(mActivityTaskManager.mTempConfig);
-
- // We need another copy of global config because we're scheduling some calls instead of
- // running them in place. We need to be sure that object we send will be handled unchanged.
- final Configuration configCopy = new Configuration(mActivityTaskManager.mTempConfig);
- if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
- Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
- msg.obj = configCopy;
- msg.arg1 = userId;
- mHandler.sendMessage(msg);
- }
-
- for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
- ProcessRecord app = mLruProcesses.get(i);
- try {
- if (app.thread != null) {
- if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
- + app.processName + " new config " + configCopy);
- mActivityTaskManager.getLifecycleManager().scheduleTransaction(app.thread,
- ConfigurationChangeItem.obtain(configCopy));
- }
- } catch (Exception e) {
- Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
- }
- }
-
- Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
- | Intent.FLAG_RECEIVER_FOREGROUND
- | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
- broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
- OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
- UserHandle.USER_ALL);
- if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
- intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
- | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
- if (initLocale || !mProcessesReady) {
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- }
- broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
- OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
- UserHandle.USER_ALL);
- }
-
- // Send a broadcast to PackageInstallers if the configuration change is interesting
- // for the purposes of installing additional splits.
- if (!initLocale && isSplitConfigurationChange(changes)) {
- intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-
- // Typically only app stores will have this permission.
- String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
- broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
- OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
- }
-
- // Override configuration of the default display duplicates global config, so we need to
- // update it also. This will also notify WindowManager about changes.
- performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
- DEFAULT_DISPLAY);
-
- return changes;
- }
-
- boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
- boolean deferResume, int displayId) {
- return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
- displayId, null /* result */);
- }
-
- /**
- * Updates override configuration specific for the selected display. If no config is provided,
- * new one will be computed in WM based on current display info.
- */
- boolean updateDisplayOverrideConfigurationLocked(Configuration values,
- ActivityRecord starting, boolean deferResume, int displayId,
- ActivityTaskManagerService.UpdateConfigurationResult result) {
- int changes = 0;
- boolean kept = true;
-
- if (mWindowManager != null) {
- mWindowManager.deferSurfaceLayout();
- }
- try {
- if (values != null) {
- if (displayId == DEFAULT_DISPLAY) {
- // Override configuration of the default display duplicates global config, so
- // we're calling global config update instead for default display. It will also
- // apply the correct override config.
- changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
- false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
- } else {
- changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
- }
- }
-
- kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
- } finally {
- if (mWindowManager != null) {
- mWindowManager.continueSurfaceLayout();
- }
- }
-
- if (result != null) {
- result.changes = changes;
- result.activityRelaunched = !kept;
- }
- return kept;
- }
-
- private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
- int displayId) {
- mActivityTaskManager.mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
- final int changes = mActivityTaskManager.mTempConfig.updateFrom(values);
- if (changes != 0) {
- Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
- + mActivityTaskManager.mTempConfig + " for displayId=" + displayId);
- mStackSupervisor.setDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId);
-
- final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
- if (isDensityChange && displayId == DEFAULT_DISPLAY) {
- mAppWarnings.onDensityChanged();
-
- killAllBackgroundProcessesExcept(N,
- ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
- }
- }
-
- // Update the configuration with WM first and check if any of the stacks need to be resized
- // due to the configuration change. If so, resize the stacks now and do any relaunches if
- // necessary. This way we don't need to relaunch again afterwards in
- // ensureActivityConfiguration().
- if (mWindowManager != null) {
- final int[] resizedStacks =
- mWindowManager.setNewDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId);
- if (resizedStacks != null) {
- for (int stackId : resizedStacks) {
- resizeStackWithBoundsFromWindowManager(stackId, deferResume);
- }
- }
- }
-
- return changes;
- }
-
- /** Applies latest configuration and/or visibility updates if needed. */
- private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
- boolean kept = true;
- final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
- // mainStack is null during startup.
- if (mainStack != null) {
- if (changes != 0 && starting == null) {
- // If the configuration changed, and the caller is not already
- // in the process of starting an activity, then find the top
- // activity to check if its configuration needs to change.
- starting = mainStack.topRunningActivityLocked();
- }
-
- if (starting != null) {
- kept = starting.ensureActivityConfiguration(changes,
- false /* preserveWindow */);
- // And we need to make sure at this point that all other activities
- // are made visible with the correct configuration.
- mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
- !PRESERVE_WINDOWS);
- }
- }
-
- return kept;
- }
-
- /** Helper method that requests bounds from WM and applies them to stack. */
- private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
- final Rect newStackBounds = new Rect();
- final ActivityStack stack = mStackSupervisor.getStack(stackId);
-
- // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
- if (stack == null) {
- final StringWriter writer = new StringWriter();
- final PrintWriter printWriter = new PrintWriter(writer);
- mStackSupervisor.dumpDisplays(printWriter);
- printWriter.flush();
-
- Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
- }
-
- stack.getBoundsForNewConfiguration(newStackBounds);
- mStackSupervisor.resizeStackLocked(
- stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
- null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
- false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
- }
-
/**
* Decide based on the configuration whether we should show the ANR,
* crash, etc dialogs. The idea is that if there is no affordance to
@@ -19782,7 +19114,7 @@
* A thought: SystemUI might also want to get told about this, the Power
* dialog / global actions also might want different behaviors.
*/
- private void updateShouldShowDialogsLocked(Configuration config) {
+ void updateShouldShowDialogsLocked(Configuration config) {
final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
&& config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
&& config.navigation == Configuration.NAVIGATION_NONAV);
@@ -23233,15 +22565,6 @@
}
@Override
- public void onUserRemoved(int userId) {
- synchronized (ActivityManagerService.this) {
- ActivityManagerService.this.onUserStoppedLocked(userId);
- }
- mBatteryStatsService.onUserRemoved(userId);
- mUserController.onUserRemoved(userId);
- }
-
- @Override
public void killForegroundAppsForUser(int userHandle) {
synchronized (ActivityManagerService.this) {
final ArrayList<ProcessRecord> procs = new ArrayList<>();
@@ -23300,17 +22623,6 @@
}
@Override
- public void updatePersistentConfigurationForUser(@NonNull Configuration values,
- int userId) {
- Preconditions.checkNotNull(values, "Configuration must not be null");
- Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
- synchronized (ActivityManagerService.this) {
- updateConfigurationLocked(values, null, false, true, userId,
- false /* deferResume */);
- }
- }
-
- @Override
public int getUidProcessState(int uid) {
return getUidState(uid);
}
@@ -23428,27 +22740,6 @@
}
@Override
- public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
- synchronized (ActivityManagerService.this) {
- if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
- ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
- if (types == null) {
- if (uid < 0) {
- return;
- }
- types = new ArrayMap<>();
- mAllowAppSwitchUids.put(userId, types);
- }
- if (uid < 0) {
- types.remove(type);
- } else {
- types.put(type, uid);
- }
- }
- }
- }
-
- @Override
public boolean isRuntimeRestarted() {
return mSystemServiceManager.isRuntimeRestarted();
}
@@ -23511,6 +22802,51 @@
}
return processMemoryStates;
}
+
+ @Override
+ public int handleIncomingUser(int callingPid, int callingUid, int userId,
+ boolean allowAll, int allowMode, String name, String callerPackage) {
+ return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
+ allowMode, name, callerPackage);
+ }
+
+ @Override
+ public void enforceCallingPermission(String permission, String func) {
+ ActivityManagerService.this.enforceCallingPermission(permission, func);
+ }
+
+ @Override
+ public int getCurrentUserId() {
+ return mUserController.getCurrentUserIdLU();
+ }
+
+ @Override
+ public boolean isUserRunning(int userId, int flags) {
+ synchronized (ActivityManagerService.this) {
+ return mUserController.isUserRunning(userId, flags);
+ }
+ }
+
+ @Override
+ public void trimApplications() {
+ ActivityManagerService.this.trimApplications();
+ }
+
+ public int getPackageScreenCompatMode(ApplicationInfo ai) {
+ synchronized (ActivityManagerService.this) {
+ return mCompatModePackages.computeCompatModeLocked(ai);
+ }
+ }
+
+ public void setPackageScreenCompatMode(ApplicationInfo ai, int mode) {
+ synchronized (ActivityManagerService.this) {
+ mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode);
+ }
+ }
+
+ public void closeSystemDialogs(String reason) {
+ ActivityManagerService.this.closeSystemDialogs(reason);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 0e427d6..7f3f8f3 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1220,7 +1220,7 @@
* @return whether this activity supports PiP multi-window and can be put in the pinned stack.
*/
boolean supportsPictureInPicture() {
- return service.mAm.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
+ return service.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined()
&& info.supportsPictureInPicture();
}
@@ -1233,7 +1233,7 @@
// An activity can not be docked even if it is considered resizeable because it only
// supports picture-in-picture mode but has a non-resizeable resizeMode
return super.supportsSplitScreenWindowingMode()
- && service.mAm.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
+ && service.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow();
}
/**
@@ -1241,16 +1241,16 @@
* stack.
*/
boolean supportsFreeform() {
- return service.mAm.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
+ return service.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow();
}
/**
* @return whether this activity supports non-PiP multi-window.
*/
private boolean supportsResizeableMultiWindow() {
- return service.mAm.mSupportsMultiWindow && !isActivityTypeHome()
+ return service.mSupportsMultiWindow && !isActivityTypeHome()
&& (ActivityInfo.isResizeableMode(info.resizeMode)
- || service.mAm.mForceResizableActivities);
+ || service.mForceResizableActivities);
}
/**
@@ -2347,7 +2347,7 @@
displayId, displayConfig, mayFreezeScreenLocked(app));
if (config != null) {
frozenBeforeDestroy = true;
- if (!service.mAm.updateDisplayOverrideConfigurationLocked(config, this,
+ if (!service.updateDisplayOverrideConfigurationLocked(config, this,
false /* deferResume */, displayId)) {
mStackSupervisor.resumeFocusedStackTopActivityLocked();
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 6118131..d177702 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3956,7 +3956,9 @@
}
}
- IActivityController controller = mService.mAm.mController;
+ // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity
+ // We should consolidate.
+ IActivityController controller = mService.mController;
if (controller != null) {
ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
if (next != null) {
@@ -3965,7 +3967,7 @@
try {
resumeOK = controller.activityResuming(next.packageName);
} catch (RemoteException e) {
- mService.mAm.mController = null;
+ mService.mController = null;
Watchdog.getInstance().setActivityController(null);
}
@@ -4662,7 +4664,7 @@
// If we have a watcher, preflight the move before committing to it. First check
// for *other* available tasks, but if none are available, then try again allowing the
// current task to be selected.
- if (isTopStackOnDisplay() && mService.mAm.mController != null) {
+ if (isTopStackOnDisplay() && mService.mController != null) {
ActivityRecord next = topRunningActivityLocked(null, taskId);
if (next == null) {
next = topRunningActivityLocked(null, 0);
@@ -4671,9 +4673,9 @@
// ask watcher if this is allowed
boolean moveOK = true;
try {
- moveOK = mService.mAm.mController.activityResuming(next.packageName);
+ moveOK = mService.mController.activityResuming(next.packageName);
} catch (RemoteException e) {
- mService.mAm.mController = null;
+ mService.mController = null;
Watchdog.getInstance().setActivityController(null);
}
if (!moveOK) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a77d734..10b721e 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -488,7 +488,7 @@
// No restrictions for the default display.
return true;
}
- if (!mService.mAm.mSupportsMultiDisplay) {
+ if (!mService.mSupportsMultiDisplay) {
// Can't launch on secondary displays if feature is not supported.
return false;
}
@@ -624,7 +624,7 @@
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper());
mKeyguardController = new KeyguardController(mService.mAm, this);
- mLaunchParamsController = new LaunchParamsController(mService.mAm);
+ mLaunchParamsController = new LaunchParamsController(mService);
mLaunchParamsController.registerDefaultModifiers(this);
}
@@ -1661,7 +1661,7 @@
}
// Update the configuration of the activities on the display.
- return mService.mAm.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
+ return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume,
displayId);
}
@@ -2347,9 +2347,9 @@
if (options == null || options.getLaunchBounds() == null) {
return false;
}
- return (mService.mAm.mSupportsPictureInPicture
+ return (mService.mSupportsPictureInPicture
&& options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED)
- || mService.mAm.mSupportsFreeformWindowManagement;
+ || mService.mSupportsFreeformWindowManagement;
}
LaunchParamsController getLaunchParamsController() {
@@ -3258,21 +3258,21 @@
// Ensure that we aren't trying to move into a multi-window stack without multi-window
// support
- if (inMultiWindowMode && !mService.mAm.mSupportsMultiWindow) {
+ if (inMultiWindowMode && !mService.mSupportsMultiWindow) {
throw new IllegalArgumentException("Device doesn't support multi-window, can not"
+ " reparent task=" + task + " to stack=" + stack);
}
// Ensure that we're not moving a task to a dynamic stack if device doesn't support
// multi-display.
- if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mAm.mSupportsMultiDisplay) {
+ if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) {
throw new IllegalArgumentException("Device doesn't support multi-display, can not"
+ " reparent task=" + task + " to stackId=" + stackId);
}
// Ensure that we aren't trying to move into a freeform stack without freeform support
if (stack.getWindowingMode() == WINDOWING_MODE_FREEFORM
- && !mService.mAm.mSupportsFreeformWindowManagement) {
+ && !mService.mSupportsFreeformWindowManagement) {
throw new IllegalArgumentException("Device doesn't support freeform, can not reparent"
+ " task=" + task);
}
@@ -3305,7 +3305,7 @@
return false;
}
- if (!mService.mAm.mForceResizableActivities && !r.supportsPictureInPicture()) {
+ if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) {
Slog.w(TAG,
"moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for "
+ " r=" + r);
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index fa001df..f7ea4b2 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -21,7 +21,7 @@
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
+import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import android.app.IApplicationThread;
import android.content.ComponentName;
@@ -237,8 +237,8 @@
int checkTargetUser(int targetUserId, boolean validateIncomingUser,
int realCallingPid, int realCallingUid, String reason) {
if (validateIncomingUser) {
- return mService.mAm.mUserController.handleIncomingUser(realCallingPid, realCallingUid,
- targetUserId, false, ALLOW_FULL_ONLY, reason, null);
+ return mService.handleIncomingUser(
+ realCallingPid, realCallingUid, targetUserId, reason);
} else {
mService.mAm.mUserController.ensureNotSpecialUser(targetUserId);
return targetUserId;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index f50bb37..6f58aea 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -729,15 +729,15 @@
.getPendingRemoteAnimationRegistry()
.overrideOptionsIfNeeded(callingPackage, checkedOptions);
}
- if (mService.mAm.mController != null) {
+ if (mService.mController != null) {
try {
// The Intent we give to the watcher has the extra data
// stripped off, since it can contain private information.
Intent watchIntent = intent.cloneFilter();
- abort |= !mService.mAm.mController.activityStarting(watchIntent,
+ abort |= !mService.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
- mService.mAm.mController = null;
+ mService.mController = null;
}
}
@@ -844,7 +844,7 @@
// one, check whether app switches are allowed.
if (voiceSession == null && (stack.getResumedActivity() == null
|| stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
- if (!mService.mAm.checkAppSwitchAllowedLocked(callingPid, callingUid,
+ if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
sourceRecord, startFlags, stack, callerApp));
@@ -853,17 +853,7 @@
}
}
- if (mService.mAm.mDidAppSwitch) {
- // This is the second allowed switch since we stopped switches,
- // so now just generally allow switches. Use case: user presses
- // home (switches disabled, switch to home, mDidAppSwitch now true);
- // user taps a home icon (coming from home so allowed, we hit here
- // and now allow anyone to switch again).
- mService.mAm.mAppSwitchesAllowedTime = 0;
- } else {
- mService.mAm.mDidAppSwitch = true;
- }
-
+ mService.onStartActivitySetDidAppSwitch();
mController.doPendingActivityLaunches(false);
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
@@ -1110,12 +1100,12 @@
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
- mService.mAm.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
+ mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
stack.mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Updating to new configuration after starting activity.");
- mService.mAm.updateConfigurationLocked(globalConfig, null, false);
+ mService.updateConfigurationLocked(globalConfig, null, false);
}
if (outResult != null) {
@@ -1821,7 +1811,7 @@
}
// Get the virtual display id from ActivityManagerService.
- int displayId = mService.mAm.mVr2dDisplayId;
+ int displayId = mService.mVr2dDisplayId;
if (displayId != INVALID_DISPLAY) {
if (DEBUG_STACK) {
Slog.d(TAG, "getSourceDisplayId :" + displayId);
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 90097fd..d554e0f 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -24,6 +24,7 @@
import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.REMOVE_TASKS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
+import static android.Manifest.permission.STOP_APP_SWITCHES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
@@ -32,6 +33,7 @@
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.AppOpsManager.OP_NONE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -42,8 +44,19 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
+import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
+import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
+import static android.os.Build.VERSION_CODES.N;
import static android.os.Process.SYSTEM_UID;
+import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
+import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
+import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
+import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -60,7 +73,9 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
@@ -69,10 +84,13 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
+import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static com.android.server.am.ActivityManagerService.ANIMATE;
-import static com.android.server.am.ActivityManagerService.DISPATCH_SCREEN_KEYGUARD_MSG;
+import static com.android.server.am.ActivityManagerService.MY_PID;
+import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
+import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
+import static com.android.server.am.ActivityManagerService.checkComponentPermission;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
@@ -88,14 +106,17 @@
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
import android.Manifest;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.ActivityTaskManagerInternal;
import android.app.AppGlobals;
+import android.app.IActivityController;
import android.app.IActivityTaskManager;
import android.app.IApplicationThread;
import android.app.IAssistDataReceiver;
@@ -108,17 +129,21 @@
import android.app.admin.DevicePolicyCache;
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
+import android.app.servertransaction.ConfigurationChangeItem;
import android.app.usage.UsageEvents;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
@@ -134,21 +159,29 @@
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteException;
-import android.os.TransactionTooLargeException;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.UpdateLock;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionManagerInternal;
import android.telecom.TelecomManager;
import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.EventLog;
+import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.SparseIntArray;
+import android.util.StatsLog;
import android.util.proto.ProtoOutputStream;
import android.view.IRecentsAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AssistUtils;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.logging.MetricsLogger;
@@ -157,6 +190,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.KeyguardDismissCallback;
import com.android.internal.util.Preconditions;
+import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.Watchdog;
@@ -166,6 +200,7 @@
import java.io.File;
import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
@@ -182,10 +217,13 @@
private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
+ private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Context mContext;
H mH;
+ UiHandler mUiHandler;
ActivityManagerService mAm;
+ ActivityManagerInternal mAmInternal;
/* Global service lock used by the package the owns this service. */
Object mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
@@ -245,14 +283,77 @@
}
/** Current sequencing integer of the configuration, for skipping old configurations. */
- int mConfigurationSeq;
+ private int mConfigurationSeq;
+ // To cache the list of supported system locales
+ private String[] mSupportedSystemLocales = null;
/**
* Temp object used when global and/or display override configuration is updated. It is also
* sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
* anyone...
*/
- Configuration mTempConfig = new Configuration();
+ private Configuration mTempConfig = new Configuration();
+
+ // Amount of time after a call to stopAppSwitches() during which we will
+ // prevent further untrusted switches from happening.
+ private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
+
+ /**
+ * The time at which we will allow normal application switches again,
+ * after a call to {@link #stopAppSwitches()}.
+ */
+ long mAppSwitchesAllowedTime;
+ /**
+ * This is set to true after the first switch after mAppSwitchesAllowedTime
+ * is set; any switches after that will clear the time.
+ */
+ boolean mDidAppSwitch;
+
+ IActivityController mController = null;
+ boolean mControllerIsAMonkey = false;
+
+ /**
+ * Used to retain an update lock when the foreground activity is in
+ * immersive mode.
+ */
+ final UpdateLock mUpdateLock = new UpdateLock("immersive");
+
+ /**
+ * Packages that are being allowed to perform unrestricted app switches. Mapping is
+ * User -> Type -> uid.
+ */
+ final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
+
+ /** The dimensions of the thumbnails in the Recents UI. */
+ int mThumbnailWidth;
+ int mThumbnailHeight;
+ float mFullscreenThumbnailScale;
+
+ /**
+ * Flag that indicates if multi-window is enabled.
+ *
+ * For any particular form of multi-window to be enabled, generic multi-window must be enabled
+ * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
+ * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
+ * At least one of the forms of multi-window must be enabled in order for this flag to be
+ * initialized to 'true'.
+ *
+ * @see #mSupportsSplitScreenMultiWindow
+ * @see #mSupportsFreeformWindowManagement
+ * @see #mSupportsPictureInPicture
+ * @see #mSupportsMultiDisplay
+ */
+ boolean mSupportsMultiWindow;
+ boolean mSupportsSplitScreenMultiWindow;
+ boolean mSupportsFreeformWindowManagement;
+ boolean mSupportsPictureInPicture;
+ boolean mSupportsMultiDisplay;
+ boolean mForceResizableActivities;
+
+ final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>();
+
+ // VR Vr2d Display Id.
+ int mVr2dDisplayId = INVALID_DISPLAY;
ActivityTaskManagerService(Context context) {
mContext = context;
@@ -265,11 +366,87 @@
mRecentTasks.onSystemReadyLocked();
}
+ void retrieveSettings(ContentResolver resolver) {
+ final boolean freeformWindowManagement =
+ mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
+ || Settings.Global.getInt(
+ resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
+
+ final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext);
+ final boolean supportsPictureInPicture = supportsMultiWindow &&
+ mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+ final boolean supportsSplitScreenMultiWindow =
+ ActivityTaskManager.supportsSplitScreenMultiWindow(mContext);
+ final boolean supportsMultiDisplay = mContext.getPackageManager()
+ .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
+ final boolean alwaysFinishActivities =
+ Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
+ final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
+ final boolean forceResizable = Settings.Global.getInt(
+ resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
+
+ // Transfer any global setting for forcing RTL layout, into a System Property
+ SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
+
+ final Configuration configuration = new Configuration();
+ Settings.System.getConfiguration(resolver, configuration);
+ if (forceRtl) {
+ // This will take care of setting the correct layout direction flags
+ configuration.setLayoutDirection(configuration.locale);
+ }
+
+ synchronized (mGlobalLock) {
+ mForceResizableActivities = forceResizable;
+ final boolean multiWindowFormEnabled = freeformWindowManagement
+ || supportsSplitScreenMultiWindow
+ || supportsPictureInPicture
+ || supportsMultiDisplay;
+ if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
+ mSupportsMultiWindow = true;
+ mSupportsFreeformWindowManagement = freeformWindowManagement;
+ mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
+ mSupportsPictureInPicture = supportsPictureInPicture;
+ mSupportsMultiDisplay = supportsMultiDisplay;
+ } else {
+ mSupportsMultiWindow = false;
+ mSupportsFreeformWindowManagement = false;
+ mSupportsSplitScreenMultiWindow = false;
+ mSupportsPictureInPicture = false;
+ mSupportsMultiDisplay = false;
+ }
+ mWindowManager.setForceResizableTasks(mForceResizableActivities);
+ mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
+ // This happens before any activities are started, so we can change global configuration
+ // in-place.
+ updateConfigurationLocked(configuration, null, true);
+ final Configuration globalConfig = getGlobalConfiguration();
+ if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
+
+ // Load resources only after the current configuration has been set.
+ final Resources res = mContext.getResources();
+ mThumbnailWidth = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.thumbnail_width);
+ mThumbnailHeight = res.getDimensionPixelSize(
+ com.android.internal.R.dimen.thumbnail_height);
+
+ if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
+ mFullscreenThumbnailScale = (float) res
+ .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
+ (float) globalConfig.screenWidthDp;
+ } else {
+ mFullscreenThumbnailScale = res.getFraction(
+ com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
+ }
+ }
+ }
+
// TODO: Will be converted to WM lock once transition is complete.
void setActivityManagerService(ActivityManagerService am) {
mAm = am;
+ mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
mGlobalLock = mAm;
mH = new H(mAm.mHandlerThread.getLooper());
+ mUiHandler = new UiHandler();
mTempConfig.setToDefaults();
mTempConfig.setLocales(LocaleList.getDefault());
@@ -278,12 +455,12 @@
mStackSupervisor.onConfigurationChanged(mTempConfig);
mTaskChangeNotificationController =
- new TaskChangeNotificationController(mAm, mStackSupervisor, mH);
+ new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH);
mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH);
mActivityStartController = new ActivityStartController(this);
mRecentTasks = createRecentTasks();
mStackSupervisor.setRecentTasks(mRecentTasks);
- mVrController = new VrController(mAm);
+ mVrController = new VrController(mGlobalLock);
mKeyguardController = mStackSupervisor.getKeyguardController();
}
@@ -359,9 +536,8 @@
Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
int userId) {
final String reason = "startActivities";
- mAm.enforceNotIsolatedCaller(reason);
- userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null);
+ enforceNotIsolatedCaller(reason);
+ userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
// TODO: Switch to user app stacks here.
return getActivityStartController().startActivities(caller, -1, callingPackage, intents,
resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason);
@@ -380,7 +556,7 @@
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
- mAm.enforceNotIsolatedCaller("startActivityAsUser");
+ enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
@@ -404,9 +580,8 @@
@Override
public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
- String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
- throws TransactionTooLargeException {
- mAm.enforceNotIsolatedCaller("startActivityIntentSender");
+ String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) {
+ enforceNotIsolatedCaller("startActivityIntentSender");
// Refuse possible leaked file descriptors
if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -421,15 +596,14 @@
synchronized (mGlobalLock) {
// If this is coming from the currently resumed activity, it is
// effectively saying that app switches are allowed at this point.
- final ActivityStack stack = mAm.getFocusedStack();
+ final ActivityStack stack = getFocusedStack();
if (stack.mResumedActivity != null &&
stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
- mAm.mAppSwitchesAllowedTime = 0;
+ mAppSwitchesAllowedTime = 0;
}
}
- int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
+ return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
- return ret;
}
@Override
@@ -556,10 +730,9 @@
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
final WaitResult res = new WaitResult();
synchronized (mGlobalLock) {
- mAm.enforceNotIsolatedCaller("startActivityAndWait");
- userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
- "startActivityAndWait", null);
+ enforceNotIsolatedCaller("startActivityAndWait");
+ userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, "startActivityAndWait");
// TODO: Switch to user app stacks here.
getActivityStartController().obtainStarter(intent, "startActivityAndWait")
.setCaller(caller)
@@ -583,10 +756,9 @@
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, Configuration config, Bundle bOptions, int userId) {
synchronized (mGlobalLock) {
- mAm.enforceNotIsolatedCaller("startActivityWithConfig");
- userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY,
- "startActivityWithConfig", null);
+ enforceNotIsolatedCaller("startActivityWithConfig");
+ userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
+ "startActivityWithConfig");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityWithConfig")
.setCaller(caller)
@@ -692,17 +864,21 @@
}
}
+ int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
+ return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */,
+ ALLOW_FULL_ONLY, name, null /* callerPackage */);
+ }
+
@Override
public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
Intent intent, String resolvedType, IVoiceInteractionSession session,
IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
- mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
+ mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
if (session == null || interactor == null) {
throw new NullPointerException("null session or interactor");
}
- userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
- ALLOW_FULL_ONLY, "startVoiceActivity", null);
+ userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startVoiceActivity")
.setCallingUid(callingUid)
@@ -720,9 +896,8 @@
@Override
public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
Intent intent, String resolvedType, Bundle bOptions, int userId) {
- mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
- userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
- ALLOW_FULL_ONLY, "startAssistantActivity", null);
+ mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
+ userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
return getActivityStartController().obtainStarter(intent, "startAssistantActivity")
.setCallingUid(callingUid)
@@ -736,7 +911,7 @@
@Override
public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
IRecentsAnimationRunner recentsAnimationRunner) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
final int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
try {
@@ -745,9 +920,8 @@
final int recentsUid = mRecentTasks.getRecentsComponentUid();
// Start a new recents animation
- final RecentsAnimation anim = new RecentsAnimation(mAm, mStackSupervisor,
- getActivityStartController(), mAm.mWindowManager, mAm.mUserController,
- callingPid);
+ final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
+ getActivityStartController(), mWindowManager, callingPid);
anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
recentsUid, assistDataReceiver);
}
@@ -758,7 +932,7 @@
@Override
public final int startActivityFromRecents(int taskId, Bundle bOptions) {
- mAm.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
+ enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS,
"startActivityFromRecents()");
final int callingPid = Binder.getCallingPid();
@@ -810,16 +984,18 @@
return false;
}
- if (mAm.mController != null) {
+ // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked
+ // We should consolidate.
+ if (mController != null) {
// Find the first activity that is not finishing.
ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
try {
- resumeOK = mAm.mController.activityResuming(next.packageName);
+ resumeOK = mController.activityResuming(next.packageName);
} catch (RemoteException e) {
- mAm.mController = null;
+ mController = null;
Watchdog.getInstance().setActivityController(null);
}
@@ -907,7 +1083,7 @@
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
ActivityRecord.activityResumedLocked(token);
- mAm.mWindowManager.notifyAppResumedFinished(token);
+ mWindowManager.notifyAppResumedFinished(token);
}
Binder.restoreCallingIdentity(origId);
}
@@ -943,7 +1119,7 @@
}
}
- mAm.trimApplications();
+ mAmInternal.trimApplications();
Binder.restoreCallingIdentity(origId);
}
@@ -1022,11 +1198,30 @@
// update associated state if we're frontmost
if (r == mStackSupervisor.getResumedActivityLocked()) {
if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
- mAm.applyUpdateLockStateLocked(r);
+ applyUpdateLockStateLocked(r);
}
}
}
+ void applyUpdateLockStateLocked(ActivityRecord r) {
+ // Modifications to the UpdateLock state are done on our handler, outside
+ // the activity manager's locks. The new state is determined based on the
+ // state *now* of the relevant activity record. The object is passed to
+ // the handler solely for logging detail, not to be consulted/modified.
+ final boolean nextState = r != null && r.immersive;
+ mH.post(() -> {
+ if (mUpdateLock.isHeld() != nextState) {
+ if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
+ "Applying new update lock state '" + nextState + "' for " + r);
+ if (nextState) {
+ mUpdateLock.acquire();
+ } else {
+ mUpdateLock.release();
+ }
+ }
+ });
+ }
+
@Override
public boolean isImmersive(IBinder token) {
synchronized (mGlobalLock) {
@@ -1040,9 +1235,9 @@
@Override
public boolean isTopActivityImmersive() {
- mAm.enforceNotIsolatedCaller("isTopActivityImmersive");
+ enforceNotIsolatedCaller("isTopActivityImmersive");
synchronized (mGlobalLock) {
- final ActivityRecord r = mAm.getFocusedStack().topRunningActivityLocked();
+ final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
return (r != null) ? r.immersive : false;
}
}
@@ -1060,7 +1255,7 @@
if (self.isState(
ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) {
- mAm.mWindowManager.overridePendingAppTransition(packageName,
+ mWindowManager.overridePendingAppTransition(packageName,
enterAnim, exitAnim, null);
}
@@ -1070,19 +1265,34 @@
@Override
public int getFrontActivityScreenCompatMode() {
- mAm.enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
+ enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
+ ApplicationInfo ai;
synchronized (mGlobalLock) {
- return mAm.mCompatModePackages.getFrontActivityScreenCompatModeLocked();
+ final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
+ if (r == null) {
+ return ActivityManager.COMPAT_MODE_UNKNOWN;
+ }
+ ai = r.info.applicationInfo;
}
+
+ return mAmInternal.getPackageScreenCompatMode(ai);
}
@Override
public void setFrontActivityScreenCompatMode(int mode) {
- mAm.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
"setFrontActivityScreenCompatMode");
+ ApplicationInfo ai;
synchronized (mGlobalLock) {
- mAm.mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
+ final ActivityRecord r = getFocusedStack().topRunningActivityLocked();
+ if (r == null) {
+ Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
+ return;
+ }
+ ai = r.info.applicationInfo;
}
+
+ mAmInternal.setPackageScreenCompatMode(ai, mode);
}
@Override
@@ -1122,7 +1332,7 @@
if (translucentChanged) {
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
}
- mAm.mWindowManager.setAppFullscreen(token, true);
+ mWindowManager.setAppFullscreen(token, true);
return translucentChanged;
}
} finally {
@@ -1151,7 +1361,7 @@
r.getStack().convertActivityToTranslucent(r);
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- mAm.mWindowManager.setAppFullscreen(token, false);
+ mWindowManager.setAppFullscreen(token, false);
return translucentChanged;
}
} finally {
@@ -1194,11 +1404,11 @@
@Override
public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- ActivityStack focusedStack = mAm.getFocusedStack();
+ ActivityStack focusedStack = getFocusedStack();
if (focusedStack != null) {
return mStackSupervisor.getStackInfo(focusedStack.mStackId);
}
@@ -1211,7 +1421,7 @@
@Override
public void setFocusedStack(int stackId) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
final long callingId = Binder.clearCallingIdentity();
try {
@@ -1234,7 +1444,7 @@
@Override
public void setFocusedTask(int taskId) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
final long callingId = Binder.clearCallingIdentity();
try {
@@ -1255,7 +1465,7 @@
@Override
public boolean removeTask(int taskId) {
- mAm.enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
+ enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -1312,7 +1522,7 @@
*/
@Override
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
- mAm.enforceNotIsolatedCaller("moveActivityTaskToBack");
+ enforceNotIsolatedCaller("moveActivityTaskToBack");
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
@@ -1330,7 +1540,7 @@
@Override
public Rect getTaskBounds(int taskId) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
long ident = Binder.clearCallingIdentity();
Rect rect = new Rect();
try {
@@ -1364,7 +1574,7 @@
@Override
public ActivityManager.TaskDescription getTaskDescription(int id) {
synchronized (mGlobalLock) {
- mAm.enforceCallerIsRecentsOrHasPermission(
+ enforceCallerIsRecentsOrHasPermission(
MANAGE_ACTIVITY_STACKS, "getTaskDescription()");
final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
@@ -1382,7 +1592,7 @@
toTop, ANIMATE, null /* initialBounds */, true /* showRecents */);
return;
}
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -1414,7 +1624,7 @@
@Override
public String getCallingPackage(IBinder token) {
- synchronized (this) {
+ synchronized (mGlobalLock) {
ActivityRecord r = getCallingRecordLocked(token);
return r != null ? r.info.packageName : null;
}
@@ -1422,7 +1632,7 @@
@Override
public ComponentName getCallingActivity(IBinder token) {
- synchronized (this) {
+ synchronized (mGlobalLock) {
ActivityRecord r = getCallingRecordLocked(token);
return r != null ? r.intent.getComponent() : null;
}
@@ -1438,12 +1648,12 @@
@Override
public void unhandledBack() {
- mAm.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()");
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- mAm.getFocusedStack().unhandledBackLocked();
+ getFocusedStack().unhandledBackLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -1455,7 +1665,7 @@
*/
@Override
public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
- mAm.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
synchronized (mGlobalLock) {
@@ -1467,7 +1677,7 @@
void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options,
boolean fromRecents) {
- if (!mAm.checkAppSwitchAllowedLocked(Binder.getCallingPid(),
+ if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
Binder.getCallingUid(), -1, -1, "Task to front")) {
SafeActivityOptions.abort(options);
return;
@@ -1503,6 +1713,69 @@
SafeActivityOptions.abort(options);
}
+ boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
+ int callingPid, int callingUid, String name) {
+ if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
+ return true;
+ }
+
+ if (getRecentTasks().isCallerRecents(sourceUid)) {
+ return true;
+ }
+
+ int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
+ if (perm == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ if (checkAllowAppSwitchUid(sourceUid)) {
+ return true;
+ }
+
+ // If the actual IPC caller is different from the logical source, then
+ // also see if they are allowed to control app switches.
+ if (callingUid != -1 && callingUid != sourceUid) {
+ perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
+ if (perm == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ if (checkAllowAppSwitchUid(callingUid)) {
+ return true;
+ }
+ }
+
+ Slog.w(TAG, name + " request from " + sourceUid + " stopped");
+ return false;
+ }
+
+ private boolean checkAllowAppSwitchUid(int uid) {
+ ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
+ if (types != null) {
+ for (int i = types.size() - 1; i >= 0; i--) {
+ if (types.valueAt(i).intValue() == uid) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void setActivityController(IActivityController controller, boolean imAMonkey) {
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
+ "setActivityController()");
+ synchronized (mGlobalLock) {
+ mController = controller;
+ mControllerIsAMonkey = imAMonkey;
+ Watchdog.getInstance().setActivityController(controller);
+ }
+ }
+
+ boolean isControllerAMonkey() {
+ synchronized (mGlobalLock) {
+ return mController != null && mControllerIsAMonkey;
+ }
+ }
+
@Override
public int getTaskForActivity(IBinder token, boolean onlyRoot) {
synchronized (mGlobalLock) {
@@ -1525,7 +1798,7 @@
synchronized (mGlobalLock) {
if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum);
- final boolean allowed = mAm.isGetTasksAllowed("getTasks", Binder.getCallingPid(),
+ final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
callingUid);
mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType,
ignoreWindowingMode, callingUid, allowed);
@@ -1548,7 +1821,7 @@
@Override
public boolean willActivityBeVisible(IBinder token) {
- synchronized(this) {
+ synchronized (mGlobalLock) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
return stack.willActivityBeVisibleLocked(token);
@@ -1559,7 +1832,7 @@
@Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -1582,7 +1855,7 @@
+ taskId + " to stack " + stackId);
}
if (stack.inSplitScreenPrimaryWindowingMode()) {
- mAm.mWindowManager.setDockedStackCreateState(
+ mWindowManager.setDockedStackCreateState(
SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */);
}
task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
@@ -1596,7 +1869,7 @@
@Override
public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
boolean preserveWindows, boolean animate, int animationDuration) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
final long ident = Binder.clearCallingIdentity();
try {
@@ -1648,7 +1921,7 @@
@Override
public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode,
boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"setTaskWindowingModeSplitScreenPrimary()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
@@ -1666,7 +1939,7 @@
+ " non-standard task " + taskId + " to split-screen windowing mode");
}
- mAm.mWindowManager.setDockedStackCreateState(createMode, initialBounds);
+ mWindowManager.setDockedStackCreateState(createMode, initialBounds);
final int windowingMode = task.getWindowingMode();
final ActivityStack stack = task.getStack();
if (toTop) {
@@ -1687,7 +1960,7 @@
*/
@Override
public void removeStacksInWindowingModes(int[] windowingModes) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"removeStacksInWindowingModes()");
synchronized (mGlobalLock) {
@@ -1702,7 +1975,7 @@
@Override
public void removeStacksWithActivityTypes(int[] activityTypes) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"removeStacksWithActivityTypes()");
synchronized (mGlobalLock) {
@@ -1719,12 +1992,12 @@
public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
int userId) {
final int callingUid = Binder.getCallingUid();
- userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
- false, ALLOW_FULL_ONLY, "getRecentTasks", null);
- final boolean allowed = mAm.isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
+ userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks");
+ final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
callingUid);
- final boolean detailed = mAm.checkCallingPermission(
- android.Manifest.permission.GET_DETAILED_TASKS)
+ final boolean detailed = checkGetTasksPermission(
+ android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(),
+ UserHandle.getAppId(callingUid))
== PackageManager.PERMISSION_GRANTED;
synchronized (mGlobalLock) {
@@ -1735,7 +2008,7 @@
@Override
public List<ActivityManager.StackInfo> getAllStackInfos() {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -1748,7 +2021,7 @@
@Override
public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -1761,13 +2034,13 @@
@Override
public void cancelRecentsAnimation(boolean restoreHomeStackPosition) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()");
final long callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
// Cancel the recents animation synchronously (do not hold the WM lock)
- mAm.mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
+ mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition
? REORDER_MOVE_TO_ORIGINAL_POSITION
: REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid);
}
@@ -1789,7 +2062,7 @@
@Override
public void startSystemLockTaskMode(int taskId) throws RemoteException {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
// This makes inner call to look as if it was initiated by system.
long ident = Binder.clearCallingIdentity();
try {
@@ -1822,7 +2095,7 @@
*/
@Override
public void stopSystemLockTaskMode() throws RemoteException {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode");
stopLockTaskModeInternal(null, true /* isSystemCaller */);
}
@@ -1979,7 +2252,7 @@
@Override
public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
AssistContent content, Uri referrer) {
- PendingAssistExtras pae = (PendingAssistExtras)token;
+ PendingAssistExtras pae = (PendingAssistExtras) token;
synchronized (pae) {
pae.result = extras;
pae.structure = structure;
@@ -2003,13 +2276,13 @@
synchronized (mGlobalLock) {
buildAssistBundleLocked(pae, extras);
boolean exists = mPendingAssistExtras.remove(pae);
- mAm.mUiHandler.removeCallbacks(pae);
+ mUiHandler.removeCallbacks(pae);
if (!exists) {
// Timed out.
return;
}
- if ((sendReceiver=pae.receiver) != null) {
+ if ((sendReceiver = pae.receiver) != null) {
// Caller wants result sent back to them.
sendBundle = new Bundle();
sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras);
@@ -2037,7 +2310,7 @@
pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mAm.closeSystemDialogs("assist");
+ mAmInternal.closeSystemDialogs("assist");
try {
mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
@@ -2068,11 +2341,11 @@
throw new IllegalArgumentException("Intent " + intent
+ " must specify explicit component");
}
- if (thumbnail.getWidth() != mAm.mThumbnailWidth
- || thumbnail.getHeight() != mAm.mThumbnailHeight) {
+ if (thumbnail.getWidth() != mThumbnailWidth
+ || thumbnail.getHeight() != mThumbnailHeight) {
throw new IllegalArgumentException("Bad thumbnail size: got "
+ thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
- + mAm.mThumbnailWidth + "x" + mAm.mThumbnailHeight);
+ + mThumbnailWidth + "x" + mThumbnailHeight);
}
if (intent.getSelector() != null) {
intent.setSelector(null);
@@ -2118,7 +2391,7 @@
@Override
public Point getAppTaskThumbnailSize() {
synchronized (mGlobalLock) {
- return new Point(mAm.mThumbnailWidth, mAm.mThumbnailHeight);
+ return new Point(mThumbnailWidth, mThumbnailHeight);
}
}
@@ -2137,7 +2410,7 @@
@Override
public void resizeTask(int taskId, Rect bounds, int resizeMode) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -2215,7 +2488,7 @@
@Override
public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
int secondaryDisplayShowing) {
- if (mAm.checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
+ if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.DEVICE_POWER);
@@ -2235,14 +2508,25 @@
}
}
- mAm.mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
- .sendToTarget();
+ mH.post(() -> {
+ for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+ mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing);
+ }
+ });
+ }
+
+ void onScreenAwakeChanged(boolean isAwake) {
+ mH.post(() -> {
+ for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+ mScreenObservers.get(i).onAwakeStateChanged(isAwake);
+ }
+ });
}
@Override
public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
- userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null);
+ userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
+ userId, "getTaskDescriptionIcon");
final File passedIconFile = new File(filePath);
final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
@@ -2256,8 +2540,7 @@
}
@Override
- public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
- throws RemoteException {
+ public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) {
final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts);
final ActivityOptions activityOptions = safeOptions != null
? safeOptions.getOptions(mStackSupervisor)
@@ -2268,15 +2551,15 @@
throw new IllegalArgumentException("Expected in-place ActivityOption " +
"with valid animation");
}
- mAm.mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
- mAm.mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
+ mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
+ mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
activityOptions.getCustomInPlaceResId());
- mAm.mWindowManager.executeAppTransition();
+ mWindowManager.executeAppTransition();
}
@Override
public void removeStack(int stackId) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
@@ -2298,7 +2581,7 @@
@Override
public void moveStackToDisplay(int stackId, int displayId) {
- mAm.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
+ mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
@@ -2314,7 +2597,7 @@
@Override
public int createStackOnDisplay(int displayId) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
synchronized (mGlobalLock) {
final ActivityDisplay display =
mStackSupervisor.getActivityDisplayOrCreateLocked(displayId);
@@ -2356,7 +2639,7 @@
/** Sets the task stack listener that gets callbacks when a task stack changes. */
@Override
public void registerTaskStackListener(ITaskStackListener listener) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"registerTaskStackListener()");
mTaskChangeNotificationController.registerTaskStackListener(listener);
}
@@ -2364,7 +2647,7 @@
/** Unregister a task stack listener so that it stops receiving callbacks. */
@Override
public void unregisterTaskStackListener(ITaskStackListener listener) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"unregisterTaskStackListener()");
mTaskChangeNotificationController.unregisterTaskStackListener(listener);
}
@@ -2418,20 +2701,78 @@
synchronized (mGlobalLock) {
buildAssistBundleLocked(pae, pae.result);
mPendingAssistExtras.remove(pae);
- mAm.mUiHandler.removeCallbacks(pae);
+ mUiHandler.removeCallbacks(pae);
}
return pae.extras;
}
+ /**
+ * Binder IPC calls go through the public entry point.
+ * This can be called with or without the global lock held.
+ */
+ private static int checkCallingPermission(String permission) {
+ return checkPermission(
+ permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid()));
+ }
+
+ /** This can be called with or without the global lock held. */
+ void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
+ if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
+ mAmInternal.enforceCallingPermission(permission, func);
+ }
+ }
+
+ @VisibleForTesting
+ int checkGetTasksPermission(String permission, int pid, int uid) {
+ return checkPermission(permission, pid, uid);
+ }
+
+ static int checkPermission(String permission, int pid, int uid) {
+ if (permission == null) {
+ return PackageManager.PERMISSION_DENIED;
+ }
+ return checkComponentPermission(permission, pid, uid, -1, true);
+ }
+
+ boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
+ if (getRecentTasks().isCallerRecents(callingUid)) {
+ // Always allow the recents component to get tasks
+ return true;
+ }
+
+ boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS,
+ callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
+ if (!allowed) {
+ if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS,
+ callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
+ // Temporary compatibility: some existing apps on the system image may
+ // still be requesting the old permission and not switched to the new
+ // one; if so, we'll still allow them full access. This means we need
+ // to see if they are holding the old permission and are a system app.
+ try {
+ if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
+ allowed = true;
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ + " is using old GET_TASKS but privileged; allowing");
+ }
+ } catch (RemoteException e) {
+ }
+ }
+ if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
+ + " does not hold REAL_GET_TASKS; limiting output");
+ }
+ return allowed;
+ }
+
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken,
boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
int flags) {
- mAm.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"enqueueAssistContext()");
synchronized (mGlobalLock) {
- ActivityRecord activity = mAm.getFocusedStack().getTopActivity();
+ ActivityRecord activity = getFocusedStack().getTopActivity();
if (activity == null) {
Slog.w(TAG, "getAssistContextExtras failed: no top activity");
return null;
@@ -2482,7 +2823,7 @@
activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
mViSessionId, flags);
mPendingAssistExtras.add(pae);
- mAm.mUiHandler.postDelayed(pae, timeout);
+ mUiHandler.postDelayed(pae, timeout);
} catch (RemoteException e) {
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
return null;
@@ -2559,7 +2900,7 @@
public boolean isAssistDataAllowedOnCurrentActivity() {
int userId;
synchronized (mGlobalLock) {
- final ActivityStack focusedStack = mAm.getFocusedStack();
+ final ActivityStack focusedStack = getFocusedStack();
if (focusedStack == null || focusedStack.isActivityTypeAssistant()) {
return false;
}
@@ -2579,7 +2920,7 @@
try {
synchronized (mGlobalLock) {
ActivityRecord caller = ActivityRecord.forTokenLocked(token);
- ActivityRecord top = mAm.getFocusedStack().getTopActivity();
+ ActivityRecord top = getFocusedStack().getTopActivity();
if (top != caller) {
Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
+ " is not current top " + top);
@@ -2644,7 +2985,7 @@
@Override
public void keyguardGoingAway(int flags) {
- mAm.enforceNotIsolatedCaller("keyguardGoingAway");
+ enforceNotIsolatedCaller("keyguardGoingAway");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -2662,7 +3003,7 @@
*/
@Override
public void positionTaskInStack(int taskId, int stackId, int position) {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
synchronized (mGlobalLock) {
long ident = Binder.clearCallingIdentity();
try {
@@ -2723,7 +3064,7 @@
*/
@Override
public void dismissSplitScreenMode(boolean toTop) {
- mAm.enforceCallerIsRecentsOrHasPermission(
+ enforceCallerIsRecentsOrHasPermission(
MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
final long ident = Binder.clearCallingIdentity();
try {
@@ -2765,7 +3106,7 @@
*/
@Override
public void dismissPip(boolean animate, int animationDuration) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -2793,7 +3134,7 @@
@Override
public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
- mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
synchronized (mGlobalLock) {
mSuppressResizeConfigChanges = suppress;
}
@@ -2807,7 +3148,7 @@
@Override
// TODO: API should just be about changing windowing modes...
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"moveTasksToFullscreenStack()");
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
@@ -2837,10 +3178,10 @@
*/
@Override
public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"moveTopActivityToPinnedStack()");
synchronized (mGlobalLock) {
- if (!mAm.mSupportsPictureInPicture) {
+ if (!mSupportsPictureInPicture) {
throw new IllegalStateException("moveTopActivityToPinnedStack:"
+ "Device doesn't support picture-in-picture mode");
}
@@ -2942,8 +3283,8 @@
// device is currently locked).
dismissKeyguard(token, new KeyguardDismissCallback() {
@Override
- public void onDismissSucceeded() throws RemoteException {
- mAm.mHandler.post(enterPipRunnable);
+ public void onDismissSucceeded() {
+ mH.post(enterPipRunnable);
}
}, null /* message */);
} else {
@@ -3012,7 +3353,7 @@
*/
private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
IBinder token, PictureInPictureParams params) {
- if (!mAm.mSupportsPictureInPicture) {
+ if (!mSupportsPictureInPicture) {
throw new IllegalStateException(caller
+ ": Device doesn't support picture-in-picture mode.");
}
@@ -3029,7 +3370,7 @@
}
if (params.hasSetAspectRatio()
- && !mAm.mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
+ && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
params.getAspectRatio())) {
final float minAspectRatio = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
@@ -3048,7 +3389,7 @@
@Override
public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
- mAm.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
+ enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
synchronized (mGlobalLock) {
ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
if (r == null) {
@@ -3063,7 +3404,7 @@
public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
Rect tempDockedTaskInsetBounds,
Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -3078,7 +3419,7 @@
@Override
public void setSplitScreenResizing(boolean resizing) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()");
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -3089,9 +3430,20 @@
}
}
+ /**
+ * Check that we have the features required for VR-related API calls, and throw an exception if
+ * not.
+ */
+ void enforceSystemHasVrFeature() {
+ if (!mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) {
+ throw new UnsupportedOperationException("VR mode not supported on this device!");
+ }
+ }
+
@Override
public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
- mAm.enforceSystemHasVrFeature();
+ enforceSystemHasVrFeature();
final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
@@ -3131,7 +3483,7 @@
public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
Slog.i(TAG, "Activity tried to startLocalVoiceInteraction");
synchronized (mGlobalLock) {
- ActivityRecord activity = mAm.getFocusedStack().getTopActivity();
+ ActivityRecord activity = getFocusedStack().getTopActivity();
if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
throw new SecurityException("Only focused activity can call startVoiceInteraction");
}
@@ -3176,7 +3528,7 @@
@Override
public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()");
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -3189,7 +3541,7 @@
@Override
public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
- mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
+ mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
synchronized (mGlobalLock) {
// Check if display is initialized in AM.
@@ -3202,14 +3554,14 @@
return false;
}
- if (values == null && mAm.mWindowManager != null) {
+ if (values == null && mWindowManager != null) {
// sentinel: fetch the current configuration from the window manager
- values = mAm.mWindowManager.computeNewConfiguration(displayId);
+ values = mWindowManager.computeNewConfiguration(displayId);
}
- if (mAm.mWindowManager != null) {
+ if (mWindowManager != null) {
// Update OOM levels based on display size.
- mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
+ mAm.mProcessList.applyDisplaySize(mWindowManager);
}
final long origId = Binder.clearCallingIdentity();
@@ -3217,7 +3569,7 @@
if (values != null) {
Settings.System.clearConfiguration(values);
}
- mAm.updateDisplayOverrideConfigurationLocked(values, null /* starting */,
+ updateDisplayOverrideConfigurationLocked(values, null /* starting */,
false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
return mTmpUpdateConfigurationResult.changes != 0;
} finally {
@@ -3228,17 +3580,17 @@
@Override
public boolean updateConfiguration(Configuration values) {
- mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
+ mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
synchronized (mGlobalLock) {
- if (values == null && mAm.mWindowManager != null) {
+ if (values == null && mWindowManager != null) {
// sentinel: fetch the current configuration from the window manager
- values = mAm.mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
+ values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
}
- if (mAm.mWindowManager != null) {
+ if (mWindowManager != null) {
// Update OOM levels based on display size.
- mAm.mProcessList.applyDisplaySize(mAm.mWindowManager);
+ mAm.mProcessList.applyDisplaySize(mWindowManager);
}
final long origId = Binder.clearCallingIdentity();
@@ -3246,7 +3598,7 @@
if (values != null) {
Settings.System.clearConfiguration(values);
}
- mAm.updateConfigurationLocked(values, null, false, false /* persistent */,
+ updateConfigurationLocked(values, null, false, false /* persistent */,
UserHandle.USER_NULL, false /* deferResume */,
mTmpUpdateConfigurationResult);
return mTmpUpdateConfigurationResult.changes != 0;
@@ -3260,7 +3612,7 @@
public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback,
CharSequence message) {
if (message != null) {
- mAm.enforceCallingPermission(
+ mAmInternal.enforceCallingPermission(
Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()");
}
final long callingId = Binder.clearCallingIdentity();
@@ -3275,7 +3627,7 @@
@Override
public void cancelTaskWindowTransition(int taskId) {
- mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
+ enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS,
"cancelTaskWindowTransition()");
final long ident = Binder.clearCallingIdentity();
try {
@@ -3295,7 +3647,7 @@
@Override
public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
- mAm.enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
+ enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
final long ident = Binder.clearCallingIdentity();
try {
final TaskRecord task;
@@ -3336,11 +3688,11 @@
@Override
public @UserIdInt
int getLastResumedActivityUserId() {
- mAm.enforceCallingPermission(
+ mAmInternal.enforceCallingPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
synchronized (mGlobalLock) {
if (mAm.mLastResumedActivity == null) {
- return mAm.mUserController.getCurrentUserId();
+ return getCurrentUserId();
}
return mAm.mLastResumedActivity.userId;
}
@@ -3350,7 +3702,7 @@
public void updateLockTaskFeatures(int userId, int flags) {
final int callingUid = Binder.getCallingUid();
if (callingUid != 0 && callingUid != SYSTEM_UID) {
- mAm.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
+ mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
"updateLockTaskFeatures()");
}
synchronized (mGlobalLock) {
@@ -3394,7 +3746,7 @@
@Override
public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) {
- mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+ mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
"registerRemoteAnimations");
definition.setCallingPid(Binder.getCallingPid());
synchronized (mGlobalLock) {
@@ -3414,7 +3766,7 @@
@Override
public void registerRemoteAnimationForNextActivityStart(String packageName,
RemoteAnimationAdapter adapter) {
- mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
+ mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS,
"registerRemoteAnimationForNextActivityStart");
adapter.setCallingPid(Binder.getCallingPid());
synchronized (mGlobalLock) {
@@ -3443,7 +3795,7 @@
@Override
public void setVrThread(int tid) {
- mAm.enforceSystemHasVrFeature();
+ enforceSystemHasVrFeature();
synchronized (mGlobalLock) {
synchronized (mAm.mPidsSelfLocked) {
final int pid = Binder.getCallingPid();
@@ -3455,7 +3807,7 @@
@Override
public void setPersistentVrThread(int tid) {
- if (mAm.checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
+ if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS)
!= PERMISSION_GRANTED) {
final String msg = "Permission Denial: setPersistentVrThread() from pid="
+ Binder.getCallingPid()
@@ -3464,7 +3816,7 @@
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
- mAm.enforceSystemHasVrFeature();
+ enforceSystemHasVrFeature();
synchronized (mGlobalLock) {
synchronized (mAm.mPidsSelfLocked) {
final int pid = Binder.getCallingPid();
@@ -3474,9 +3826,41 @@
}
}
- /**
- * @return whether the system should disable UI modes incompatible with VR mode.
- */
+ @Override
+ public void stopAppSwitches() {
+ enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
+ synchronized (mGlobalLock) {
+ mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
+ mDidAppSwitch = false;
+ getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
+ }
+ }
+
+ @Override
+ public void resumeAppSwitches() {
+ enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
+ synchronized (mGlobalLock) {
+ // Note that we don't execute any pending app switches... we will
+ // let those wait until either the timeout, or the next start
+ // activity request.
+ mAppSwitchesAllowedTime = 0;
+ }
+ }
+
+ void onStartActivitySetDidAppSwitch() {
+ if (mDidAppSwitch) {
+ // This is the second allowed switch since we stopped switches, so now just generally
+ // allow switches. Use case:
+ // - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
+ // - user taps a home icon (coming from home so allowed, we hit here and now allow
+ // anyone to switch again).
+ mAppSwitchesAllowedTime = 0;
+ } else {
+ mDidAppSwitch = true;
+ }
+ }
+
+ /** @return whether the system should disable UI modes incompatible with VR mode. */
boolean shouldDisableNonVrUiLocked() {
return mVrController.shouldDisableNonVrUiLocked();
}
@@ -3512,6 +3896,10 @@
});
}
+ ActivityStack getFocusedStack() {
+ return mStackSupervisor.getFocusedStack();
+ }
+
/** Pokes the task persister. */
void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
mRecentTasks.notifyTaskPersisterLocked(task, flush);
@@ -3540,12 +3928,398 @@
mVrController.writeToProto(proto, fieldId);
}
+ int getCurrentUserId() {
+ return mAmInternal.getCurrentUserId();
+ }
+
+ private void enforceNotIsolatedCaller(String caller) {
+ if (UserHandle.isIsolated(Binder.getCallingUid())) {
+ throw new SecurityException("Isolated process not allowed to call " + caller);
+ }
+ }
+
+ /**
+ * Current global configuration information. Contains general settings for the entire system,
+ * also corresponds to the merged configuration of the default display.
+ */
+ Configuration getGlobalConfiguration() {
+ return mStackSupervisor.getConfiguration();
+ }
+
+ boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean initLocale) {
+ return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
+ }
+
+ boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean initLocale, boolean deferResume) {
+ // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
+ return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
+ UserHandle.USER_NULL, deferResume);
+ }
+
+ void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ updateConfigurationLocked(values, null, false, true, userId,
+ false /* deferResume */);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ void updateUserConfiguration() {
+ synchronized (mGlobalLock) {
+ final Configuration configuration = new Configuration(getGlobalConfiguration());
+ final int currentUserId = mAmInternal.getCurrentUserId();
+ Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
+ currentUserId, Settings.System.canWrite(mContext));
+ updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
+ false /* persistent */, currentUserId, false /* deferResume */);
+ }
+ }
+
+ private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean initLocale, boolean persistent, int userId, boolean deferResume) {
+ return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
+ deferResume, null /* result */);
+ }
+
+ /**
+ * Do either or both things: (1) change the current configuration, and (2)
+ * make sure the given activity is running with the (now) current
+ * configuration. Returns true if the activity has been left running, or
+ * false if <var>starting</var> is being destroyed to match the new
+ * configuration.
+ *
+ * @param userId is only used when persistent parameter is set to true to persist configuration
+ * for that particular user
+ */
+ boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean initLocale, boolean persistent, int userId, boolean deferResume,
+ ActivityTaskManagerService.UpdateConfigurationResult result) {
+ int changes = 0;
+ boolean kept = true;
+
+ if (mWindowManager != null) {
+ mWindowManager.deferSurfaceLayout();
+ }
+ try {
+ if (values != null) {
+ changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId,
+ deferResume);
+ }
+
+ kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
+ } finally {
+ if (mWindowManager != null) {
+ mWindowManager.continueSurfaceLayout();
+ }
+ }
+
+ if (result != null) {
+ result.changes = changes;
+ result.activityRelaunched = !kept;
+ }
+ return kept;
+ }
+
+ /**
+ * Returns true if this configuration change is interesting enough to send an
+ * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
+ */
+ private static boolean isSplitConfigurationChange(int configDiff) {
+ return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
+ }
+
+ /** Update default (global) configuration and notify listeners about changes. */
+ private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
+ boolean persistent, int userId, boolean deferResume) {
+ mTempConfig.setTo(getGlobalConfiguration());
+ final int changes = mTempConfig.updateFrom(values);
+ if (changes == 0) {
+ // Since calling to Activity.setRequestedOrientation leads to freezing the window with
+ // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
+ // performDisplayOverrideConfigUpdate in order to send the new display configuration
+ // (even if there are no actual changes) to unfreeze the window.
+ performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
+ return 0;
+ }
+
+ if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
+ "Updating global configuration to: " + values);
+
+ EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
+ StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED,
+ values.colorMode,
+ values.densityDpi,
+ values.fontScale,
+ values.hardKeyboardHidden,
+ values.keyboard,
+ values.keyboardHidden,
+ values.mcc,
+ values.mnc,
+ values.navigation,
+ values.navigationHidden,
+ values.orientation,
+ values.screenHeightDp,
+ values.screenLayout,
+ values.screenWidthDp,
+ values.smallestScreenWidthDp,
+ values.touchscreen,
+ values.uiMode);
+
+
+ if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
+ final LocaleList locales = values.getLocales();
+ int bestLocaleIndex = 0;
+ if (locales.size() > 1) {
+ if (mSupportedSystemLocales == null) {
+ mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
+ }
+ bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
+ }
+ SystemProperties.set("persist.sys.locale",
+ locales.get(bestLocaleIndex).toLanguageTag());
+ LocaleList.setDefault(locales, bestLocaleIndex);
+ mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
+ locales.get(bestLocaleIndex)));
+ }
+
+ mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
+ mTempConfig.seq = mConfigurationSeq;
+
+ // Update stored global config and notify everyone about the change.
+ mStackSupervisor.onConfigurationChanged(mTempConfig);
+
+ Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
+ // TODO(multi-display): Update UsageEvents#Event to include displayId.
+ mAm.mUsageStatsService.reportConfigurationChange(
+ mTempConfig, mAmInternal.getCurrentUserId());
+
+ // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
+ mAm.updateShouldShowDialogsLocked(mTempConfig);
+
+ AttributeCache ac = AttributeCache.instance();
+ if (ac != null) {
+ ac.updateConfiguration(mTempConfig);
+ }
+
+ // Make sure all resources in our process are updated right now, so that anyone who is going
+ // to retrieve resource values after we return will be sure to get the new ones. This is
+ // especially important during boot, where the first config change needs to guarantee all
+ // resources have that config before following boot code is executed.
+ mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
+
+ // We need another copy of global config because we're scheduling some calls instead of
+ // running them in place. We need to be sure that object we send will be handled unchanged.
+ final Configuration configCopy = new Configuration(mTempConfig);
+ if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
+ Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
+ msg.obj = configCopy;
+ msg.arg1 = userId;
+ mAm.mHandler.sendMessage(msg);
+ }
+
+ for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
+ ProcessRecord app = mAm.mLruProcesses.get(i);
+ try {
+ if (app.thread != null) {
+ if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
+ + app.processName + " new config " + configCopy);
+ getLifecycleManager().scheduleTransaction(app.thread,
+ ConfigurationChangeItem.obtain(configCopy));
+ }
+ } catch (Exception e) {
+ Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
+ }
+ }
+
+ Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_FOREGROUND
+ | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+ mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+ OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+ UserHandle.USER_ALL);
+ if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
+ intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+ | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+ if (initLocale || !mAm.mProcessesReady) {
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ }
+ mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+ OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+ UserHandle.USER_ALL);
+ }
+
+ // Send a broadcast to PackageInstallers if the configuration change is interesting
+ // for the purposes of installing additional splits.
+ if (!initLocale && isSplitConfigurationChange(changes)) {
+ intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+
+ // Typically only app stores will have this permission.
+ String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
+ mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
+ OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
+ }
+
+ // Override configuration of the default display duplicates global config, so we need to
+ // update it also. This will also notify WindowManager about changes.
+ performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
+ DEFAULT_DISPLAY);
+
+ return changes;
+ }
+
+ boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
+ boolean deferResume, int displayId) {
+ return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
+ displayId, null /* result */);
+ }
+
+ /**
+ * Updates override configuration specific for the selected display. If no config is provided,
+ * new one will be computed in WM based on current display info.
+ */
+ boolean updateDisplayOverrideConfigurationLocked(Configuration values,
+ ActivityRecord starting, boolean deferResume, int displayId,
+ ActivityTaskManagerService.UpdateConfigurationResult result) {
+ int changes = 0;
+ boolean kept = true;
+
+ if (mWindowManager != null) {
+ mWindowManager.deferSurfaceLayout();
+ }
+ try {
+ if (values != null) {
+ if (displayId == DEFAULT_DISPLAY) {
+ // Override configuration of the default display duplicates global config, so
+ // we're calling global config update instead for default display. It will also
+ // apply the correct override config.
+ changes = updateGlobalConfigurationLocked(values, false /* initLocale */,
+ false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
+ } else {
+ changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
+ }
+ }
+
+ kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
+ } finally {
+ if (mWindowManager != null) {
+ mWindowManager.continueSurfaceLayout();
+ }
+ }
+
+ if (result != null) {
+ result.changes = changes;
+ result.activityRelaunched = !kept;
+ }
+ return kept;
+ }
+
+ private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
+ int displayId) {
+ mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
+ final int changes = mTempConfig.updateFrom(values);
+ if (changes != 0) {
+ Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
+ + mTempConfig + " for displayId=" + displayId);
+ mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
+
+ final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
+ if (isDensityChange && displayId == DEFAULT_DISPLAY) {
+ mAm.mAppWarnings.onDensityChanged();
+
+ mAm.killAllBackgroundProcessesExcept(N,
+ ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+ }
+ }
+
+ // Update the configuration with WM first and check if any of the stacks need to be resized
+ // due to the configuration change. If so, resize the stacks now and do any relaunches if
+ // necessary. This way we don't need to relaunch again afterwards in
+ // ensureActivityConfiguration().
+ if (mWindowManager != null) {
+ final int[] resizedStacks =
+ mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
+ if (resizedStacks != null) {
+ for (int stackId : resizedStacks) {
+ resizeStackWithBoundsFromWindowManager(stackId, deferResume);
+ }
+ }
+ }
+
+ return changes;
+ }
+
+ /** Helper method that requests bounds from WM and applies them to stack. */
+ private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
+ final Rect newStackBounds = new Rect();
+ final ActivityStack stack = mStackSupervisor.getStack(stackId);
+
+ // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found.
+ if (stack == null) {
+ final StringWriter writer = new StringWriter();
+ final PrintWriter printWriter = new PrintWriter(writer);
+ mStackSupervisor.dumpDisplays(printWriter);
+ printWriter.flush();
+
+ Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer);
+ }
+
+ stack.getBoundsForNewConfiguration(newStackBounds);
+ mStackSupervisor.resizeStackLocked(
+ stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
+ null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
+ }
+
+ /** Applies latest configuration and/or visibility updates if needed. */
+ private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
+ boolean kept = true;
+ final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
+ // mainStack is null during startup.
+ if (mainStack != null) {
+ if (changes != 0 && starting == null) {
+ // If the configuration changed, and the caller is not already
+ // in the process of starting an activity, then find the top
+ // activity to check if its configuration needs to change.
+ starting = mainStack.topRunningActivityLocked();
+ }
+
+ if (starting != null) {
+ kept = starting.ensureActivityConfiguration(changes,
+ false /* preserveWindow */);
+ // And we need to make sure at this point that all other activities
+ // are made visible with the correct configuration.
+ mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
+ !PRESERVE_WINDOWS);
+ }
+ }
+
+ return kept;
+ }
+
final class H extends Handler {
public H(Looper looper) {
super(looper, null, true);
}
}
+ final class UiHandler extends Handler {
+
+ public UiHandler() {
+ super(com.android.server.UiThread.get().getLooper(), null, true);
+ }
+ }
+
final class LocalService extends ActivityTaskManagerInternal {
@Override
public SleepToken acquireSleepToken(String tag, int displayId) {
@@ -3657,9 +4431,9 @@
// We might change the visibilities here, so prepare an empty app transition which
// might be overridden later if we actually change visibilities.
final boolean wasTransitionSet =
- mAm.mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
+ mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
if (!wasTransitionSet) {
- mAm.mWindowManager.prepareAppTransition(TRANSIT_NONE,
+ mWindowManager.prepareAppTransition(TRANSIT_NONE,
false /* alwaysKeepCurrent */);
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
@@ -3667,7 +4441,7 @@
// If there was a transition set already we don't want to interfere with it as we
// might be starting it too early.
if (!wasTransitionSet) {
- mAm.mWindowManager.executeAppTransition();
+ mWindowManager.executeAppTransition();
}
}
if (callback != null) {
@@ -3693,7 +4467,7 @@
public void setVr2dDisplayId(int vr2dDisplayId) {
if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId);
synchronized (mGlobalLock) {
- mAm.mVr2dDisplayId = vr2dDisplayId;
+ mVr2dDisplayId = vr2dDisplayId;
}
}
@@ -3734,7 +4508,7 @@
@Override
public void registerScreenObserver(ScreenObserver observer) {
- mAm.mScreenObservers.add(observer);
+ mScreenObservers.add(observer);
}
@Override
@@ -3754,7 +4528,7 @@
@Override
public void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
- mAm.enforceCallerIsRecentsOrHasPermission(permission, func);
+ ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func);
}
@Override
@@ -3763,5 +4537,43 @@
mActiveVoiceInteractionServiceComponent = component;
}
}
+
+ @Override
+ public void setAllowAppSwitches(@NonNull String type, int uid, int userId) {
+ if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) {
+ return;
+ }
+ synchronized (mGlobalLock) {
+ ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId);
+ if (types == null) {
+ if (uid < 0) {
+ return;
+ }
+ types = new ArrayMap<>();
+ mAllowAppSwitchUids.put(userId, types);
+ }
+ if (uid < 0) {
+ types.remove(type);
+ } else {
+ types.put(type, uid);
+ }
+ }
+ }
+
+ @Override
+ public void onUserStopped(int userId) {
+ synchronized (mGlobalLock) {
+ getRecentTasks().unloadUserDataFromMemoryLocked(userId);
+ mAllowAppSwitchUids.remove(userId);
+ }
+ }
+
+ @Override
+ public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
+ synchronized (mGlobalLock) {
+ return ActivityTaskManagerService.this.isGetTasksAllowed(
+ caller, callingPid, callingUid);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index eac3501..5719490 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -532,7 +532,7 @@
String shortMsg, String longMsg,
String stackTrace, long timeMillis,
int callingPid, int callingUid) {
- if (mService.mController == null) {
+ if (mService.mActivityTaskManager.mController == null) {
return false;
}
@@ -540,7 +540,7 @@
String name = r != null ? r.processName : null;
int pid = r != null ? r.pid : callingPid;
int uid = r != null ? r.info.uid : callingUid;
- if (!mService.mController.appCrashed(name, pid,
+ if (!mService.mActivityTaskManager.mController.appCrashed(name, pid,
shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
&& "Native crash".equals(crashInfo.exceptionClassName)) {
@@ -563,7 +563,7 @@
return true;
}
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mActivityTaskManager.mController = null;
Watchdog.getInstance().setActivityController(null);
}
return false;
@@ -887,16 +887,16 @@
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
- if (mService.mController != null) {
+ if (mService.mActivityTaskManager.mController != null) {
try {
// 0 == continue, -1 = kill process immediately
- int res = mService.mController.appEarlyNotResponding(
+ int res = mService.mActivityTaskManager.mController.appEarlyNotResponding(
app.processName, app.pid, annotation);
if (res < 0 && app.pid != MY_PID) {
app.kill("anr", true);
}
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mActivityTaskManager.mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
@@ -1054,10 +1054,10 @@
mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
cpuInfo, tracesFile, null);
- if (mService.mController != null) {
+ if (mService.mActivityTaskManager.mController != null) {
try {
// 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
- int res = mService.mController.appNotResponding(
+ int res = mService.mActivityTaskManager.mController.appNotResponding(
app.processName, app.pid, info.toString());
if (res != 0) {
if (res < 0 && app.pid != MY_PID) {
@@ -1070,7 +1070,7 @@
return;
}
} catch (RemoteException e) {
- mService.mController = null;
+ mService.mActivityTaskManager.mController = null;
Watchdog.getInstance().setActivityController(null);
}
}
diff --git a/services/core/java/com/android/server/am/AppTaskImpl.java b/services/core/java/com/android/server/am/AppTaskImpl.java
index 953d3b8..c22dedc 100644
--- a/services/core/java/com/android/server/am/AppTaskImpl.java
+++ b/services/core/java/com/android/server/am/AppTaskImpl.java
@@ -20,7 +20,6 @@
import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
import android.app.ActivityManager;
-import android.app.ActivityOptions;
import android.app.IAppTask;
import android.app.IApplicationThread;
import android.content.Intent;
diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java
index b54441a..037f245 100644
--- a/services/core/java/com/android/server/am/AssistDataRequester.java
+++ b/services/core/java/com/android/server/am/AssistDataRequester.java
@@ -49,7 +49,6 @@
public static final String KEY_RECEIVER_EXTRA_COUNT = "count";
public static final String KEY_RECEIVER_EXTRA_INDEX = "index";
- private IActivityManager mService;
private IWindowManager mWindowManager;
private Context mContext;
private AppOpsManager mAppOpsManager;
@@ -118,14 +117,13 @@
* This can be {@link AppOpsManager#OP_NONE} to indicate that
* screenshots should never be fetched.
*/
- public AssistDataRequester(Context context, IActivityManager service,
+ public AssistDataRequester(Context context,
IWindowManager windowManager, AppOpsManager appOpsManager,
AssistDataRequesterCallbacks callbacks, Object callbacksLock,
int requestStructureAppOps, int requestScreenshotAppOps) {
mCallbacks = callbacks;
mCallbacksLock = callbacksLock;
mWindowManager = windowManager;
- mService = service;
mContext = context;
mAppOpsManager = appOpsManager;
mRequestStructureAppOps = requestStructureAppOps;
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index c6947ab..38254b8 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -219,25 +219,10 @@
: ActivityManager.COMPAT_MODE_DISABLED;
}
- public boolean getFrontActivityAskCompatModeLocked() {
- ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
- if (r == null) {
- return false;
- }
- return getPackageAskCompatModeLocked(r.packageName);
- }
-
public boolean getPackageAskCompatModeLocked(String packageName) {
return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0;
}
- public void setFrontActivityAskCompatModeLocked(boolean ask) {
- ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
- if (r != null) {
- setPackageAskCompatModeLocked(r.packageName, ask);
- }
- }
-
public void setPackageAskCompatModeLocked(String packageName, boolean ask) {
setPackageFlagLocked(packageName, COMPAT_FLAG_DONT_ASK, ask);
}
@@ -255,23 +240,6 @@
}
}
- public int getFrontActivityScreenCompatModeLocked() {
- ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
- if (r == null) {
- return ActivityManager.COMPAT_MODE_UNKNOWN;
- }
- return computeCompatModeLocked(r.info.applicationInfo);
- }
-
- public void setFrontActivityScreenCompatModeLocked(int mode) {
- ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked();
- if (r == null) {
- Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
- return;
- }
- setPackageScreenCompatModeLocked(r.info.applicationInfo, mode);
- }
-
public int getPackageScreenCompatModeLocked(String packageName) {
ApplicationInfo ai = null;
try {
@@ -297,7 +265,7 @@
setPackageScreenCompatModeLocked(ai, mode);
}
- private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
+ void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) {
final String packageName = ai.packageName;
int curFlags = getPackageFlags(packageName);
@@ -349,7 +317,7 @@
scheduleWrite();
- final ActivityStack stack = mService.getFocusedStack();
+ final ActivityStack stack = mService.mActivityTaskManager.getFocusedStack();
ActivityRecord starting = stack.restartPackage(packageName);
// Tell all processes that loaded this package about the change.
diff --git a/services/core/java/com/android/server/am/LaunchParamsController.java b/services/core/java/com/android/server/am/LaunchParamsController.java
index 4330d2c..6415c3e 100644
--- a/services/core/java/com/android/server/am/LaunchParamsController.java
+++ b/services/core/java/com/android/server/am/LaunchParamsController.java
@@ -38,7 +38,7 @@
* registered {@link LaunchParamsModifier}s.
*/
class LaunchParamsController {
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final List<LaunchParamsModifier> mModifiers = new ArrayList<>();
// Temporary {@link LaunchParams} for internal calculations. This is kept separate from
@@ -48,7 +48,7 @@
private final LaunchParams mTmpCurrent = new LaunchParams();
private final LaunchParams mTmpResult = new LaunchParams();
- LaunchParamsController(ActivityManagerService service) {
+ LaunchParamsController(ActivityTaskManagerService service) {
mService = service;
}
@@ -125,7 +125,7 @@
try {
if (mTmpParams.hasPreferredDisplay()
&& mTmpParams.mPreferredDisplayId != task.getStack().getDisplay().mDisplayId) {
- mService.mActivityTaskManager.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId);
+ mService.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId);
}
if (mTmpParams.hasWindowingMode()
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index bd49bd1..1c7ad3f 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -54,11 +54,10 @@
private static final String TAG = RecentsAnimation.class.getSimpleName();
private static final boolean DEBUG = false;
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mStackSupervisor;
private final ActivityStartController mActivityStartController;
private final WindowManagerService mWindowManager;
- private final UserController mUserController;
private final ActivityDisplay mDefaultDisplay;
private final int mCallingPid;
@@ -68,15 +67,14 @@
// The stack to restore the target stack behind when the animation is finished
private ActivityStack mRestoreTargetBehindStack;
- RecentsAnimation(ActivityManagerService am, ActivityStackSupervisor stackSupervisor,
+ RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor,
ActivityStartController activityStartController, WindowManagerService wm,
- UserController userController, int callingPid) {
- mService = am;
+ int callingPid) {
+ mService = atm;
mStackSupervisor = stackSupervisor;
mDefaultDisplay = stackSupervisor.getDefaultDisplay();
mActivityStartController = activityStartController;
mWindowManager = wm;
- mUserController = userController;
mCallingPid = callingPid;
}
@@ -122,7 +120,7 @@
mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
- mService.setRunningRemoteAnimation(mCallingPid, true);
+ mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true);
mWindowManager.deferSurfaceLayout();
try {
@@ -132,7 +130,7 @@
mService.mContext.getSystemService(Context.APP_OPS_SERVICE);
final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy(
assistDataReceiver, recentsComponent.getPackageName());
- mAssistDataRequester = new AssistDataRequester(mService.mContext, mService,
+ mAssistDataRequester = new AssistDataRequester(mService.mContext,
mWindowManager, appOpsManager, proxy, this, OP_ASSIST_STRUCTURE, OP_NONE);
mAssistDataRequester.requestAssistData(mStackSupervisor.getTopVisibleActivities(),
true /* fetchData */, false /* fetchScreenshots */,
@@ -165,7 +163,7 @@
.setCallingUid(recentsUid)
.setCallingPackage(recentsComponent.getPackageName())
.setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
- .setMayWait(mUserController.getCurrentUserId())
+ .setMayWait(mService.getCurrentUserId())
.execute();
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
mWindowManager.executeAppTransition();
@@ -210,7 +208,7 @@
}
private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
- synchronized (mService) {
+ synchronized (mService.mGlobalLock) {
if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller="
+ mWindowManager.getRecentsAnimationController()
+ " reorderMode=" + reorderMode);
@@ -232,7 +230,7 @@
mStackSupervisor.sendPowerHintForLaunchEndIfNeeded();
}
- mService.setRunningRemoteAnimation(mCallingPid, false);
+ mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, false);
mWindowManager.inSurfaceTransaction(() -> {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
@@ -317,7 +315,7 @@
if (runSychronously) {
finishAnimation(reorderMode);
} else {
- mService.mHandler.post(() -> finishAnimation(reorderMode));
+ mService.mH.post(() -> finishAnimation(reorderMode));
}
}
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index 778990b..b87b948 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -192,7 +192,7 @@
// component or has the START_TASKS_FROM_RECENTS permission
if (options.getLaunchTaskId() != INVALID_TASK_ID
&& !supervisor.mRecentTasks.isCallerRecents(callingUid)) {
- final int startInTaskPerm = supervisor.mService.mAm.checkPermission(
+ final int startInTaskPerm = ActivityTaskManagerService.checkPermission(
START_TASKS_FROM_RECENTS, callingPid, callingUid);
if (startInTaskPerm == PERMISSION_DENIED) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 465fa67..481bb2b 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -655,7 +655,7 @@
synchronized (mService.mGlobalLock) {
if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks);
mRecentTasks.getPersistableTaskIds(persistentTaskIds);
- mService.mAm.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds,
+ mService.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds,
mRecentTasks.usersWithRecentsLoadedLocked());
}
removeObsoleteFiles(persistentTaskIds);
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 6eac4bc..ba012ab 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1494,7 +1494,7 @@
}
private boolean isResizeable(boolean checkSupportsPip) {
- return (mService.mAm.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
+ return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
|| (checkSupportsPip && mSupportsPictureInPicture));
}
@@ -1507,8 +1507,8 @@
// A task can not be docked even if it is considered resizeable because it only supports
// picture-in-picture mode but has a non-resizeable resizeMode
return super.supportsSplitScreenWindowingMode()
- && mService.mAm.mSupportsSplitScreenMultiWindow
- && (mService.mAm.mForceResizableActivities
+ && mService.mSupportsSplitScreenMultiWindow
+ && (mService.mForceResizableActivities
|| (isResizeable(false /* checkSupportsPip */)
&& !ActivityInfo.isPreserveOrientationMode(mResizeMode)));
}
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index b500bbf..3b47844 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -28,9 +28,9 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY;
-import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL;
-import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE;
+import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
+import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE;
import static com.android.server.am.ActivityManagerService.MY_PID;
import static com.android.server.am.UserState.STATE_BOOTING;
import static com.android.server.am.UserState.STATE_RUNNING_LOCKED;
@@ -41,6 +41,7 @@
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.ActivityTaskManagerInternal;
import android.app.AppGlobals;
import android.app.AppOpsManager;
import android.app.Dialog;
@@ -80,7 +81,6 @@
import android.text.format.DateUtils;
import android.util.ArraySet;
import android.util.IntArray;
-import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -88,7 +88,6 @@
import android.util.TimingsTraceLog;
import android.util.proto.ProtoOutputStream;
-import android.view.Window;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -2097,9 +2096,7 @@
return mService.mWindowManager;
}
void activityManagerOnUserStopped(int userId) {
- synchronized (mService) {
- mService.onUserStoppedLocked(userId);
- }
+ LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId);
}
void systemServiceManagerCleanupUser(int userId) {
@@ -2174,9 +2171,7 @@
}
void updateUserConfiguration() {
- synchronized (mService) {
- mService.updateUserConfigurationLocked();
- }
+ mService.mActivityTaskManager.updateUserConfiguration();
}
void clearBroadcastQueueForUser(int userId) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 5681367..2949b92 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -516,8 +516,7 @@
static boolean isPowerOffOrToggleCommand(HdmiCecMessage message) {
byte[] params = message.getParams();
return message.getOpcode() == Constants.MESSAGE_USER_CONTROL_PRESSED
- && (params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER
- || params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION
+ && (params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_OFF_FUNCTION
|| params[0] == HdmiCecKeycode.CEC_KEYCODE_POWER_TOGGLE_FUNCTION);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 32f1744..c45d861 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4532,6 +4532,15 @@
@GuardedBy("mNotificationLock")
@VisibleForTesting
protected boolean isVisuallyInterruptive(NotificationRecord old, NotificationRecord r) {
+ // Ignore summary updates because we don't display most of the information.
+ if (r.sbn.isGroup() && r.sbn.getNotification().isGroupSummary()) {
+ if (DEBUG_INTERRUPTIVENESS) {
+ Log.v(TAG, "INTERRUPTIVENESS: "
+ + r.getKey() + " is not interruptive: summary");
+ }
+ return false;
+ }
+
if (old == null) {
if (DEBUG_INTERRUPTIVENESS) {
Log.v(TAG, "INTERRUPTIVENESS: "
@@ -4569,15 +4578,6 @@
return false;
}
- // Ignore summary updates because we don't display most of the information.
- if (r.sbn.isGroup() && r.sbn.getNotification().isGroupSummary()) {
- if (DEBUG_INTERRUPTIVENESS) {
- Log.v(TAG, "INTERRUPTIVENESS: "
- + r.getKey() + " is not interruptive: summary");
- }
- return false;
- }
-
final String oldTitle = String.valueOf(oldN.extras.get(Notification.EXTRA_TITLE));
final String newTitle = String.valueOf(newN.extras.get(Notification.EXTRA_TITLE));
if (!Objects.equals(oldTitle, newTitle)) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 407cb93..6e7eae1 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -27,11 +27,11 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
+import android.app.ActivityTaskManagerInternal;
import android.app.IActivityManager;
import android.app.IStopUserCallback;
import android.app.KeyguardManager;
import android.app.PendingIntent;
-import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -72,7 +72,6 @@
import android.os.UserManagerInternal;
import android.os.UserManagerInternal.UserRestrictionsListener;
import android.os.storage.StorageManager;
-import android.provider.Settings;
import android.security.GateKeeper;
import android.service.gatekeeper.IGateKeeperService;
import android.util.AtomicFile;
@@ -82,7 +81,6 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
-import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.Xml;
@@ -2968,9 +2966,9 @@
new Thread() {
@Override
public void run() {
- // Clean up any ActivityManager state
- LocalServices.getService(ActivityManagerInternal.class)
- .onUserRemoved(userHandle);
+ // Clean up any ActivityTaskManager state
+ LocalServices.getService(ActivityTaskManagerInternal.class)
+ .onUserStopped(userHandle);
removeUserState(userHandle);
}
}.start();
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
index f741c70..077b455 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
@@ -104,12 +104,12 @@
mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
// Does not support freeform
- mService.mSupportsFreeformWindowManagement = false;
+ mService.mActivityTaskManager.mSupportsFreeformWindowManagement = false;
assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
- mService.mSupportsFreeformWindowManagement = true;
+ mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true;
options.setLaunchBounds(new Rect());
assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
@@ -130,7 +130,7 @@
public void testBoundsExtraction() throws Exception {
// Make activity resizeable and enable freeform mode.
mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
- mService.mSupportsFreeformWindowManagement = true;
+ mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true;
ActivityOptions options = ActivityOptions.makeBasic();
final Rect proposedBounds = new Rect(20, 30, 45, 40);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index 5ee1c40..3172323 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -236,7 +236,7 @@
private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable,
boolean activityResizeable, boolean expected) {
- mService.mSupportsMultiWindow = true;
+ mService.mActivityTaskManager.mSupportsMultiWindow = true;
final TaskRecord task = taskPresent
? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null;
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
index a86372a..df31042 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java
@@ -60,8 +60,8 @@
mService = createActivityManagerService();
mFactory = mock(Factory.class);
mController = new ActivityStartController(mService.mActivityTaskManager, mService.mStackSupervisor, mFactory);
- mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager, mService.mStackSupervisor,
- mock(ActivityStartInterceptor.class)));
+ mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager,
+ mService.mStackSupervisor, mock(ActivityStartInterceptor.class)));
doReturn(mStarter).when(mFactory).obtain();
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 10d255e..274d9e5 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -236,8 +236,8 @@
}
if (containsConditions(preconditions, PRECONDITION_DISALLOW_APP_SWITCHING)) {
- doReturn(false).when(service).checkAppSwitchAllowedLocked(anyInt(), anyInt(), anyInt(),
- anyInt(), any());
+ doReturn(false).when(service.mActivityTaskManager).checkAppSwitchAllowedLocked(
+ anyInt(), anyInt(), anyInt(), anyInt(), any());
}
if (containsConditions(preconditions,PRECONDITION_CANNOT_START_ANY_ACTIVITY)) {
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 06ac3b0..dd30e70 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -29,11 +29,14 @@
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import com.android.server.wm.DisplayWindowController;
import org.junit.Rule;
+import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import android.app.IApplicationThread;
@@ -114,6 +117,7 @@
// Makes sure activity task is created with the spy object.
atm = spy(atm);
service.setActivityTaskManager(atm);
+ atm.mAmInternal = service.new LocalService();
// Makes sure the supervisor is using with the spy object.
atm.mStackSupervisor.setService(atm);
doReturn(mock(IPackageManager.class)).when(service).getPackageManager();
@@ -351,6 +355,16 @@
TestActivityTaskManagerService(Context context) {
super(context);
+ mSupportsMultiWindow = true;
+ mSupportsMultiDisplay = true;
+ mSupportsSplitScreenMultiWindow = true;
+ mSupportsFreeformWindowManagement = true;
+ mSupportsPictureInPicture = true;
+ }
+
+ @Override
+ int handleIncomingUser(int callingPid, int callingUid, int userId, String name) {
+ return userId;
}
@Override
@@ -400,11 +414,6 @@
TestActivityManagerService(Context context) {
super(context);
- mSupportsMultiWindow = true;
- mSupportsMultiDisplay = true;
- mSupportsSplitScreenMultiWindow = true;
- mSupportsFreeformWindowManagement = true;
- mSupportsPictureInPicture = true;
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index 0a436b9..f74d116 100644
--- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -113,7 +113,7 @@
mHandler = new Handler(Looper.getMainLooper());
mCallbacksLock = new Object();
mCallbacks = new Callbacks();
- mDataRequester = new AssistDataRequester(mContext, mAm, mWm, mAppOpsManager, mCallbacks,
+ mDataRequester = new AssistDataRequester(mContext, mWm, mAppOpsManager, mCallbacks,
mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT);
// Gate the continuation of the assist data callbacks until we are ready within the tests
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
index 93e0b5a..aaec238 100644
--- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -65,7 +65,7 @@
public void setUp() throws Exception {
super.setUp();
mService = createActivityManagerService();
- mController = new LaunchParamsController(mService);
+ mController = new LaunchParamsController(mService.mActivityTaskManager);
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index cd70677..982809a 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -94,7 +94,7 @@
private static int INVALID_STACK_ID = 999;
private Context mContext = InstrumentationRegistry.getContext();
- private ActivityManagerService mService;
+ private ActivityTaskManagerService mService;
private ActivityDisplay mDisplay;
private ActivityDisplay mOtherDisplay;
private ActivityStack mStack;
@@ -146,8 +146,8 @@
mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
mService = setupActivityManagerService(new MyTestActivityManagerService(mContext),
- new MyTestActivityTaskManagerService(mContext));
- mRecentTasks = (TestRecentTasks) mService.mActivityTaskManager.getRecentTasks();
+ new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager;
+ mRecentTasks = (TestRecentTasks) mService.getRecentTasks();
mRecentTasks.loadParametersFromResources(mContext.getResources());
mHomeStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
@@ -674,9 +674,8 @@
@Test
public void testNotRecentsComponent_denyApiAccess() throws Exception {
- doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(),
- anyInt(), anyInt());
-
+ doReturn(PackageManager.PERMISSION_DENIED).when(mService)
+ .checkGetTasksPermission(anyString(), anyInt(), anyInt());
// Expect the following methods to fail due to recents component not being set
mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.DENY_THROW_SECURITY_EXCEPTION);
testRecentTasksApis(false /* expectNoSecurityException */);
@@ -687,8 +686,8 @@
@Test
public void testRecentsComponent_allowApiAccessWithoutPermissions() throws Exception {
- doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(),
- anyInt(), anyInt());
+ doReturn(PackageManager.PERMISSION_DENIED).when(mService)
+ .checkGetTasksPermission(anyString(), anyInt(), anyInt());
// Set the recents component and ensure that the following calls do not fail
mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.GRANT);
@@ -697,58 +696,52 @@
}
private void testRecentTasksApis(boolean expectCallable) {
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.removeStack(INVALID_STACK_ID));
+ assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.removeStacksInWindowingModes(
- new int[] {WINDOWING_MODE_UNDEFINED}));
+ () -> mService.removeStacksInWindowingModes(new int[] {WINDOWING_MODE_UNDEFINED}));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.removeStacksWithActivityTypes(
- new int[] {ACTIVITY_TYPE_UNDEFINED}));
+ () -> mService.removeStacksWithActivityTypes(new int[] {ACTIVITY_TYPE_UNDEFINED}));
assertSecurityException(expectCallable, () -> mService.removeTask(0));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.setTaskWindowingMode(
- 0, WINDOWING_MODE_UNDEFINED, true));
+ () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true));
assertSecurityException(expectCallable,
() -> mService.moveTaskToStack(0, INVALID_STACK_ID, true));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(0,
+ () -> mService.setTaskWindowingModeSplitScreenPrimary(0,
SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissSplitScreenMode(true));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissPip(true, 0));
+ assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true));
+ assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
+ () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect()));
assertSecurityException(expectCallable,
() -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
+ () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(),
new Rect()));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.resizePinnedStack(new Rect(), new Rect()));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getAllStackInfos());
+ () -> mService.resizePinnedStack(new Rect(), new Rect()));
+ assertSecurityException(expectCallable, () -> mService.getAllStackInfos());
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
+ () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED));
assertSecurityException(expectCallable, () -> {
try {
- mService.mActivityTaskManager.getFocusedStackInfo();
+ mService.getFocusedStackInfo();
} catch (RemoteException e) {
// Ignore
}
});
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.moveTasksToFullscreenStack(INVALID_STACK_ID, true));
+ () -> mService.moveTasksToFullscreenStack(INVALID_STACK_ID, true));
assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.startActivityFromRecents(0, new Bundle()));
- assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.getTaskSnapshot(0, true));
- assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.registerTaskStackListener(null));
- assertSecurityException(expectCallable,
- () -> mService.mActivityTaskManager.unregisterTaskStackListener(null));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getTaskDescription(0));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelTaskWindowTransition(0));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.startRecentsActivity(null, null,
+ () -> mService.startActivityFromRecents(0, new Bundle()));
+ assertSecurityException(expectCallable,() -> mService.getTaskSnapshot(0, true));
+ assertSecurityException(expectCallable,() -> mService.registerTaskStackListener(null));
+ assertSecurityException(expectCallable,() -> mService.unregisterTaskStackListener(null));
+ assertSecurityException(expectCallable, () -> mService.getTaskDescription(0));
+ assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0));
+ assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null,
null));
- assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelRecentsAnimation(true));
+ assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true));
assertSecurityException(expectCallable, () -> mService.stopAppSwitches());
assertSecurityException(expectCallable, () -> mService.resumeAppSwitches());
}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
index 91a02e4..1f2bca6 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java
@@ -16,12 +16,9 @@
package com.android.server.am;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
@@ -51,10 +48,9 @@
@Presubmit
@RunWith(AndroidJUnit4.class)
public class RecentsAnimationTest extends ActivityTestsBase {
- private static final int TEST_CALLING_PID = 3;
private Context mContext = InstrumentationRegistry.getContext();
- private ActivityManagerService mService;
+ private ActivityTaskManagerService mService;
private ComponentName mRecentsComponent;
@Before
@@ -64,7 +60,7 @@
mRecentsComponent = new ComponentName(mContext.getPackageName(), "RecentsActivity");
mService = setupActivityManagerService(new TestActivityManagerService(mContext),
- new MyTestActivityTaskManagerService(mContext));
+ new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager;
AttributeCache.init(mContext);
}
@@ -74,14 +70,14 @@
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
ActivityStack recentsStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */);
- ActivityRecord recentsActivity = new ActivityBuilder(mService)
+ ActivityRecord recentsActivity = new ActivityBuilder(mService.mAm)
.setComponent(mRecentsComponent)
.setCreateTask(true)
.setStack(recentsStack)
.build();
ActivityStack fullscreenStack2 = mService.mStackSupervisor.getDefaultDisplay().createStack(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
- ActivityRecord fsActivity = new ActivityBuilder(mService)
+ ActivityRecord fsActivity = new ActivityBuilder(mService.mAm)
.setComponent(new ComponentName(mContext.getPackageName(), "App1"))
.setCreateTask(true)
.setStack(fullscreenStack2)
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index c3b2f87..bb9b1c4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -385,9 +385,12 @@
@Test
public void testAlwaysOnTopStackLocation() {
final TaskStack alwaysOnTopStack = createTaskStackOnDisplay(mDisplayContent);
+ final Task task = createTaskInStack(alwaysOnTopStack, 0 /* userId */);
alwaysOnTopStack.setAlwaysOnTop(true);
mDisplayContent.positionStackAt(POSITION_TOP, alwaysOnTopStack);
assertTrue(alwaysOnTopStack.isAlwaysOnTop());
+ // Ensure always on top state is synced to the children of the stack.
+ assertTrue(alwaysOnTopStack.getTopChild().isAlwaysOnTop());
assertEquals(alwaysOnTopStack, mDisplayContent.getTopStack());
final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
index 513c1ec..10d7aad 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -31,6 +31,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOW_CONFIG_ALWAYS_ON_TOP;
import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -81,6 +82,11 @@
assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE,
winConfig1.diff(winConfig2, false /* compareUndefined */));
+ winConfig2.setAlwaysOnTop(true);
+ assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE
+ | WINDOW_CONFIG_ALWAYS_ON_TOP,
+ winConfig1.diff(winConfig2, false /* compareUndefined */));
+
assertEquals(0, config1.diff(config3));
assertEquals(0, config1.diffPublicOnly(config3));
assertEquals(0, winConfig1.diff(winConfig3, false /* compareUndefined */));
@@ -108,6 +114,12 @@
assertNotEquals(winConfig1.compareTo(winConfig2), 0);
winConfig2.setWindowingMode(winConfig1.getWindowingMode());
+ // Different always on top state
+ winConfig2.setAlwaysOnTop(true);
+ assertNotEquals(config1.compareTo(config2), 0);
+ assertNotEquals(winConfig1.compareTo(winConfig2), 0);
+ winConfig2.setAlwaysOnTop(winConfig1.isAlwaysOnTop());
+
// Different bounds
winConfig2.setAppBounds(0, 2, 3, 4);
assertNotEquals(config1.compareTo(config2), 0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 96c948f..45a3c41 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -3003,6 +3003,20 @@
}
@Test
+ public void testVisualDifference_summaryNewNotification() {
+ Notification.Builder nb2 = new Notification.Builder(mContext, "")
+ .setGroup("bananas")
+ .setFlag(Notification.FLAG_GROUP_SUMMARY, true)
+ .setContentText("bar");
+ StatusBarNotification sbn2 = new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0,
+ nb2.build(), new UserHandle(mUid), null, 0);
+ NotificationRecord r2 =
+ new NotificationRecord(mContext, sbn2, mock(NotificationChannel.class));
+
+ assertFalse(mService.isVisuallyInterruptive(null, r2));
+ }
+
+ @Test
public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
// post 2 notification from this package
final NotificationRecord notif1 = generateNotificationRecord(
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index cd1b835..4e49782 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -433,11 +433,11 @@
if (hasComponent) {
mShortcutServiceInternal.setShortcutHostPackage(TAG,
serviceComponent.getPackageName(), mCurUser);
- mAmInternal.setAllowAppSwitches(TAG,
+ mAtmInternal.setAllowAppSwitches(TAG,
serviceInfo.applicationInfo.uid, mCurUser);
} else {
mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser);
- mAmInternal.setAllowAppSwitches(TAG, -1, mCurUser);
+ mAtmInternal.setAllowAppSwitches(TAG, -1, mCurUser);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 4eaed34..606d027 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -144,7 +144,7 @@
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
mAppOps = context.getSystemService(AppOpsManager.class);
- mAssistDataRequester = new AssistDataRequester(mContext, mAm, mIWindowManager,
+ mAssistDataRequester = new AssistDataRequester(mContext, mIWindowManager,
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE),
this, mLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT);
IBinder permOwner = null;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0940738..102d5a0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -335,11 +335,18 @@
* <p>
* The {@link #EXTRA_STATE} extra indicates the new call state.
* If a receiving app has {@link android.Manifest.permission#READ_CALL_LOG} permission, a second
- * extra {@link #EXTRA_INCOMING_NUMBER} provides the phone number for incoming and outoing calls
- * as a String. Note: If the receiving app has
+ * extra {@link #EXTRA_INCOMING_NUMBER} provides the phone number for incoming and outgoing
+ * calls as a String.
+ * <p>
+ * If the receiving app has
* {@link android.Manifest.permission#READ_CALL_LOG} and
* {@link android.Manifest.permission#READ_PHONE_STATE} permission, it will receive the
- * broadcast twice; one with the phone number and another without it.
+ * broadcast twice; one with the {@link #EXTRA_INCOMING_NUMBER} populated with the phone number,
+ * and another with it blank. Due to the nature of broadcasts, you cannot assume the order
+ * in which these broadcasts will arrive, however you are guaranteed to receive two in this
+ * case. Apps which are interested in the {@link #EXTRA_INCOMING_NUMBER} can ignore the
+ * broadcasts where {@link #EXTRA_INCOMING_NUMBER} is not present in the extras (e.g. where
+ * {@link Intent#hasExtra(String)} returns {@code false}).
* <p class="note">
* This was a {@link android.content.Context#sendStickyBroadcast sticky}
* broadcast in version 1.0, but it is no longer sticky.
@@ -488,10 +495,19 @@
public static final String EXTRA_STATE_OFFHOOK = PhoneConstants.State.OFFHOOK.toString();
/**
- * The lookup key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
- * for a String containing the incoming phone number.
- * Only valid when the new call state is RINGING.
- *
+ * Extra key used with the {@link #ACTION_PHONE_STATE_CHANGED} broadcast
+ * for a String containing the incoming or outgoing phone number.
+ * <p>
+ * This extra is only populated for receivers of the {@link #ACTION_PHONE_STATE_CHANGED}
+ * broadcast which have been granted the {@link android.Manifest.permission#READ_CALL_LOG} and
+ * {@link android.Manifest.permission#READ_PHONE_STATE} permissions.
+ * <p>
+ * For incoming calls, the phone number is only guaranteed to be populated when the
+ * {@link #EXTRA_STATE} changes from {@link #EXTRA_STATE_IDLE} to {@link #EXTRA_STATE_RINGING}.
+ * If the incoming caller is from an unknown number, the extra will be populated with an empty
+ * string.
+ * For outgoing calls, the phone number is only guaranteed to be populated when the
+ * {@link #EXTRA_STATE} changes from {@link #EXTRA_STATE_IDLE} to {@link #EXTRA_STATE_OFFHOOK}.
* <p class="note">
* Retrieve with
* {@link android.content.Intent#getStringExtra(String)}.
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index d999c13..e546917 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -63,34 +63,25 @@
public static final int EVENT_RADIO_AVAILABLE = BASE + 1;
public static final int EVENT_RECORDS_LOADED = BASE + 2;
public static final int EVENT_TRY_SETUP_DATA = BASE + 3;
- public static final int EVENT_DATA_STATE_CHANGED = BASE + 4;
- public static final int EVENT_POLL_PDP = BASE + 5;
public static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = BASE + 6;
public static final int EVENT_VOICE_CALL_STARTED = BASE + 7;
public static final int EVENT_VOICE_CALL_ENDED = BASE + 8;
public static final int EVENT_DATA_CONNECTION_DETACHED = BASE + 9;
- public static final int EVENT_LINK_STATE_CHANGED = BASE + 10;
public static final int EVENT_ROAMING_ON = BASE + 11;
public static final int EVENT_ROAMING_OFF = BASE + 12;
public static final int EVENT_ENABLE_NEW_APN = BASE + 13;
- public static final int EVENT_RESTORE_DEFAULT_APN = BASE + 14;
public static final int EVENT_DISCONNECT_DONE = BASE + 15;
public static final int EVENT_DATA_CONNECTION_ATTACHED = BASE + 16;
public static final int EVENT_DATA_STALL_ALARM = BASE + 17;
public static final int EVENT_DO_RECOVERY = BASE + 18;
public static final int EVENT_APN_CHANGED = BASE + 19;
- public static final int EVENT_CDMA_DATA_DETACHED = BASE + 20;
- public static final int EVENT_CDMA_SUBSCRIPTION_SOURCE_CHANGED = BASE + 21;
public static final int EVENT_PS_RESTRICT_ENABLED = BASE + 22;
public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
- public static final int EVENT_CDMA_OTA_PROVISION = BASE + 25;
public static final int EVENT_RESTART_RADIO = BASE + 26;
public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
- public static final int EVENT_RESET_DONE = BASE + 28;
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29;
public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30;
- public static final int CMD_SET_DEPENDENCY_MET = BASE + 31;
public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
public static final int EVENT_ICC_CHANGED = BASE + 33;
public static final int EVENT_DISCONNECT_DC_RETRYING = BASE + 34;
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 2208580..dbf81d6 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -57,6 +57,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -95,6 +96,7 @@
import android.net.ConnectivityThread;
import android.net.INetworkPolicyManager;
import android.net.INetworkStatsService;
+import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -125,6 +127,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Process;
+import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -132,6 +135,7 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.test.mock.MockContentResolver;
+import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
@@ -145,6 +149,7 @@
import com.android.server.connectivity.DnsManager;
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.connectivity.MockableSystemProperties;
+import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.Vpn;
@@ -161,10 +166,13 @@
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
+import java.net.Inet4Address;
import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
@@ -190,6 +198,7 @@
private static final int TIMEOUT_MS = 500;
private static final int TEST_LINGER_DELAY_MS = 120;
+ private static final String CLAT_PREFIX = "v4-";
private static final String MOBILE_IFNAME = "test_rmnet_data0";
private static final String WIFI_IFNAME = "test_wlan0";
@@ -950,6 +959,10 @@
return monitor;
}
+ public Nat464Xlat getNat464Xlat(MockNetworkAgent mna) {
+ return getNetworkAgentInfoForNetwork(mna.getNetwork()).clatd;
+ }
+
@Override
public MultinetworkPolicyTracker createMultinetworkPolicyTracker(
Context c, Handler h, Runnable r) {
@@ -4422,4 +4435,97 @@
mMockVpn.disconnect();
}
+
+ /**
+ * Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info.
+ */
+ private InterfaceConfiguration getClatInterfaceConfig(LinkAddress la) {
+ InterfaceConfiguration cfg = new InterfaceConfiguration();
+ cfg.setHardwareAddress("11:22:33:44:55:66");
+ cfg.setLinkAddress(la);
+ return cfg;
+ }
+
+ /**
+ * Make expected stack link properties, copied from Nat464Xlat.
+ */
+ private LinkProperties makeClatLinkProperties(LinkAddress la) {
+ LinkAddress clatAddress = la;
+ LinkProperties stacked = new LinkProperties();
+ stacked.setInterfaceName(CLAT_PREFIX + MOBILE_IFNAME);
+ RouteInfo ipv4Default = new RouteInfo(
+ new LinkAddress(Inet4Address.ANY, 0),
+ clatAddress.getAddress(), CLAT_PREFIX + MOBILE_IFNAME);
+ stacked.addRoute(ipv4Default);
+ stacked.addLinkAddress(clatAddress);
+ return stacked;
+ }
+
+ @Test
+ public void testStackedLinkProperties() throws UnknownHostException, RemoteException {
+ final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
+ final LinkAddress myIpv6 = new LinkAddress("2001:db8:1::1/64");
+ final NetworkRequest networkRequest = new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .addCapability(NET_CAPABILITY_INTERNET)
+ .build();
+ final TestNetworkCallback networkCallback = new TestNetworkCallback();
+ mCm.registerNetworkCallback(networkRequest, networkCallback);
+
+ // Prepare ipv6 only link properties and connect.
+ mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+ final LinkProperties cellLp = new LinkProperties();
+ cellLp.setInterfaceName(MOBILE_IFNAME);
+ cellLp.addLinkAddress(myIpv6);
+ cellLp.addRoute(new RouteInfo((IpPrefix) null, myIpv6.getAddress(), MOBILE_IFNAME));
+ cellLp.addRoute(new RouteInfo(myIpv6, null, MOBILE_IFNAME));
+ reset(mNetworkManagementService);
+ when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME))
+ .thenReturn(getClatInterfaceConfig(myIpv4));
+
+ // Connect with ipv6 link properties, then expect clat setup ipv4 and update link
+ // properties properly.
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ mCellNetworkAgent.connect(true);
+ networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+ verify(mNetworkManagementService, times(1)).startClatd(MOBILE_IFNAME);
+ Nat464Xlat clat = mService.getNat464Xlat(mCellNetworkAgent);
+
+ // Clat iface up, expect stack link updated.
+ clat.interfaceLinkStateChanged(CLAT_PREFIX + MOBILE_IFNAME, true);
+ waitForIdle();
+ List<LinkProperties> stackedLps = mCm.getLinkProperties(mCellNetworkAgent.getNetwork())
+ .getStackedLinks();
+ assertEquals(makeClatLinkProperties(myIpv4), stackedLps.get(0));
+
+ // Change trivial linkproperties and see if stacked link is preserved.
+ cellLp.addDnsServer(InetAddress.getByName("8.8.8.8"));
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ waitForIdle();
+ networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+
+ List<LinkProperties> stackedLpsAfterChange =
+ mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getStackedLinks();
+ assertNotEquals(stackedLpsAfterChange, Collections.EMPTY_LIST);
+ assertEquals(makeClatLinkProperties(myIpv4), stackedLpsAfterChange.get(0));
+
+ // Add ipv4 address, expect stacked linkproperties be cleaned up
+ cellLp.addLinkAddress(myIpv4);
+ cellLp.addRoute(new RouteInfo(myIpv4, null, MOBILE_IFNAME));
+ mCellNetworkAgent.sendLinkProperties(cellLp);
+ waitForIdle();
+ networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+ verify(mNetworkManagementService, times(1)).stopClatd(MOBILE_IFNAME);
+
+ // Clat iface removed, expect linkproperties revert to original one
+ clat.interfaceRemoved(CLAT_PREFIX + MOBILE_IFNAME);
+ waitForIdle();
+ networkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+ LinkProperties actualLpAfterIpv4 = mCm.getLinkProperties(mCellNetworkAgent.getNetwork());
+ assertEquals(cellLp, actualLpAfterIpv4);
+
+ // Clean up
+ mCellNetworkAgent.disconnect();
+ mCm.unregisterNetworkCallback(networkCallback);
+ }
}