Snap for 4949134 from a5f28237e4164e2cfedfbd07c0775690bd8ce81b to qt-release
Change-Id: I69d6f2776aabadc1f44ad7137191893ad284ca28
diff --git a/Android.bp b/Android.bp
index 29b6bc7..e825610 100644
--- a/Android.bp
+++ b/Android.bp
@@ -743,22 +743,24 @@
name: "framework-javastream-protos",
depfile: true,
+ tool_files: [ "tools/genprotos.sh", ],
tools: [
"aprotoc",
"protoc-gen-javastream",
"soong_zip",
],
- cmd: "mkdir -p $(genDir)/$(in) " +
- "&& $(location aprotoc) " +
- " --plugin=$(location protoc-gen-javastream) " +
- " --dependency_out=$(depfile) " +
- " --javastream_out=$(genDir)/$(in) " +
- " -Iexternal/protobuf/src " +
- " -I . " +
- " $(in) " +
- "&& $(location soong_zip) -jar -o $(out) -C $(genDir)/$(in) -D $(genDir)/$(in)",
-
+ // TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can
+ // end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to
+ // the way sbox rewrites the command. See b/70221552.
+ cmd: "$(location tools/genprotos.sh) " +
+ " $(location aprotoc) " +
+ " $(location protoc-gen-javastream) " +
+ " $(location soong_zip) " +
+ " $(genDir) " +
+ " $(depfile) " +
+ " $(in) " +
+ " $(out)",
srcs: [
"core/proto/**/*.proto",
"libs/incident/**/*.proto",
diff --git a/api/current.txt b/api/current.txt
index 897a8d9..c38d837 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -47620,6 +47620,7 @@
method public void forceLayout();
method public static int generateViewId();
method public java.lang.CharSequence getAccessibilityClassName();
+ method public android.view.View.AccessibilityDelegate getAccessibilityDelegate();
method public int getAccessibilityLiveRegion();
method public android.view.accessibility.AccessibilityNodeProvider getAccessibilityNodeProvider();
method public java.lang.CharSequence getAccessibilityPaneTitle();
diff --git a/api/system-current.txt b/api/system-current.txt
index 6a00815..cb7f7bb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6042,12 +6042,16 @@
ctor public ImsSsInfo(int, java.lang.String);
method public int describeContents();
method public java.lang.String getIcbNum();
+ method public int getProvisionStatus();
method public int getStatus();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telephony.ims.ImsSsInfo> CREATOR;
field public static final int DISABLED = 0; // 0x0
field public static final int ENABLED = 1; // 0x1
field public static final int NOT_REGISTERED = -1; // 0xffffffff
+ field public static final int SERVICE_NOT_PROVISIONED = 0; // 0x0
+ field public static final int SERVICE_PROVISIONED = 1; // 0x1
+ field public static final int SERVICE_PROVISIONING_UNKNOWN = -1; // 0xffffffff
}
public final class ImsStreamMediaProfile implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 9dc61ee..63ece40 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -228,6 +228,14 @@
}
+package android.bluetooth {
+
+ public final class BluetoothClass implements android.os.Parcelable {
+ method public int getClassOfDevice();
+ }
+
+}
+
package android.content {
public abstract class ContentResolver {
diff --git a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
index 641ae00..043b7f9 100644
--- a/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
+++ b/cmds/bmgr/src/com/android/commands/bmgr/Bmgr.java
@@ -16,10 +16,13 @@
package com.android.commands.bmgr;
+import android.annotation.IntDef;
import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
import android.app.backup.BackupProgress;
import android.app.backup.BackupTransport;
import android.app.backup.IBackupManager;
+import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
@@ -28,6 +31,7 @@
import android.content.ComponentName;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -36,10 +40,13 @@
import com.android.internal.annotations.GuardedBy;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
public final class Bmgr {
@@ -247,7 +254,7 @@
}
// IBackupObserver generically usable for any backup/init operation
- abstract class Observer extends IBackupObserver.Stub {
+ private static abstract class Observer extends IBackupObserver.Stub {
private final Object trigger = new Object();
@GuardedBy("trigger")
@@ -295,7 +302,7 @@
}
}
- class BackupObserver extends Observer {
+ private static class BackupObserver extends Observer {
@Override
public void onUpdate(String currentPackage, BackupProgress backupProgress) {
super.onUpdate(currentPackage, backupProgress);
@@ -347,7 +354,7 @@
}
}
- private void backupNowAllPackages(boolean nonIncrementalBackup) {
+ private void backupNowAllPackages(boolean nonIncrementalBackup, @Monitor int monitorState) {
int userId = UserHandle.USER_SYSTEM;
IPackageManager mPm =
IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
@@ -372,20 +379,27 @@
System.err.println(e.toString());
System.err.println(BMGR_NOT_RUNNING_ERR);
}
- backupNowPackages(Arrays.asList(filteredPackages), nonIncrementalBackup);
+ backupNowPackages(Arrays.asList(filteredPackages), nonIncrementalBackup, monitorState);
}
}
- private void backupNowPackages(List<String> packages, boolean nonIncrementalBackup) {
+ private void backupNowPackages(
+ List<String> packages, boolean nonIncrementalBackup, @Monitor int monitorState) {
int flags = 0;
if (nonIncrementalBackup) {
flags |= BackupManager.FLAG_NON_INCREMENTAL_BACKUP;
}
try {
BackupObserver observer = new BackupObserver();
- // TODO: implement monitor here?
- int err = mBmgr.requestBackup(packages.toArray(new String[packages.size()]), observer,
- null, flags);
+ BackupMonitor monitor =
+ (monitorState != Monitor.OFF)
+ ? new BackupMonitor(monitorState == Monitor.VERBOSE)
+ : null;
+ int err = mBmgr.requestBackup(
+ packages.toArray(new String[packages.size()]),
+ observer,
+ monitor,
+ flags);
if (err == 0) {
// Off and running -- wait for the backup to complete
observer.waitForCompletion();
@@ -402,6 +416,7 @@
String pkg;
boolean backupAll = false;
boolean nonIncrementalBackup = false;
+ @Monitor int monitor = Monitor.OFF;
ArrayList<String> allPkgs = new ArrayList<String>();
while ((pkg = nextArg()) != null) {
if (pkg.equals("--all")) {
@@ -410,6 +425,10 @@
nonIncrementalBackup = true;
} else if (pkg.equals("--incremental")) {
nonIncrementalBackup = false;
+ } else if (pkg.equals("--monitor")) {
+ monitor = Monitor.NORMAL;
+ } else if (pkg.equals("--monitor-verbose")) {
+ monitor = Monitor.VERBOSE;
} else {
if (!allPkgs.contains(pkg)) {
allPkgs.add(pkg);
@@ -420,14 +439,14 @@
if (allPkgs.size() == 0) {
System.out.println("Running " + (nonIncrementalBackup ? "non-" : "") +
"incremental backup for all packages.");
- backupNowAllPackages(nonIncrementalBackup);
+ backupNowAllPackages(nonIncrementalBackup, monitor);
} else {
System.err.println("Provide only '--all' flag or list of packages.");
}
} else if (allPkgs.size() > 0) {
System.out.println("Running " + (nonIncrementalBackup ? "non-" : "") +
"incremental backup for " + allPkgs.size() +" requested packages.");
- backupNowPackages(allPkgs, nonIncrementalBackup);
+ backupNowPackages(allPkgs, nonIncrementalBackup, monitor);
} else {
System.err.println("Provide '--all' flag or list of packages.");
}
@@ -824,7 +843,7 @@
System.err.println(" bmgr run");
System.err.println(" bmgr wipe TRANSPORT PACKAGE");
System.err.println(" bmgr fullbackup PACKAGE...");
- System.err.println(" bmgr backupnow --all|PACKAGE...");
+ System.err.println(" bmgr backupnow [--monitor|--monitor-verbose] --all|PACKAGE...");
System.err.println(" bmgr cancel backups");
System.err.println("");
System.err.println("The 'backup' command schedules a backup pass for the named package.");
@@ -878,9 +897,164 @@
System.err.println("");
System.err.println("The 'backupnow' command runs an immediate backup for one or more packages.");
System.err.println(" --all flag runs backup for all eligible packages.");
+ System.err.println(" --monitor flag prints monitor events.");
+ System.err.println(" --monitor-verbose flag prints monitor events with all keys.");
System.err.println("For each package it will run key/value or full data backup ");
System.err.println("depending on the package's manifest declarations.");
System.err.println("The data is sent via the currently active transport.");
System.err.println("The 'cancel backups' command cancels all running backups.");
}
+
+ private static class BackupMonitor extends IBackupManagerMonitor.Stub {
+ private final boolean mVerbose;
+
+ private BackupMonitor(boolean verbose) {
+ mVerbose = verbose;
+ }
+
+ @Override
+ public void onEvent(Bundle event) throws RemoteException {
+ StringBuilder out = new StringBuilder();
+ int id = event.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_ID);
+ int category = event.getInt(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY);
+ out.append("=> Event{").append(eventCategoryToString(category));
+ out.append(" / ").append(eventIdToString(id));
+ String packageName = event.getString(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME);
+ if (packageName != null) {
+ out.append(" : package = ").append(packageName);
+ if (event.containsKey(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION)) {
+ long version =
+ event.getLong(
+ BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION);
+ out.append("(v").append(version).append(")");
+ }
+ }
+ if (mVerbose) {
+ Set<String> remainingKeys = new ArraySet<>(event.keySet());
+ remainingKeys.remove(BackupManagerMonitor.EXTRA_LOG_EVENT_ID);
+ remainingKeys.remove(BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY);
+ remainingKeys.remove(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME);
+ remainingKeys.remove(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_LONG_VERSION);
+ remainingKeys.remove(BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_VERSION);
+ if (!remainingKeys.isEmpty()) {
+ out.append(", other keys =");
+ for (String key : remainingKeys) {
+ out.append(" ").append(key);
+ }
+ }
+ }
+ out.append("}");
+ System.out.println(out.toString());
+ }
+ }
+
+ private static String eventCategoryToString(int eventCategory) {
+ switch (eventCategory) {
+ case BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT:
+ return "TRANSPORT";
+ case BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT:
+ return "AGENT";
+ case BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY:
+ return "BACKUP_MANAGER_POLICY";
+ default:
+ return "UNKNOWN_CATEGORY";
+ }
+ }
+
+ private static String eventIdToString(int eventId) {
+ switch (eventId) {
+ case BackupManagerMonitor.LOG_EVENT_ID_FULL_BACKUP_CANCEL:
+ return "FULL_BACKUP_CANCEL";
+ case BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY:
+ return "ILLEGAL_KEY";
+ case BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND:
+ return "NO_DATA_TO_SEND";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_INELIGIBLE:
+ return "PACKAGE_INELIGIBLE";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_KEY_VALUE_PARTICIPANT:
+ return "PACKAGE_KEY_VALUE_PARTICIPANT";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_STOPPED:
+ return "PACKAGE_STOPPED";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_FOUND:
+ return "PACKAGE_NOT_FOUND";
+ case BackupManagerMonitor.LOG_EVENT_ID_BACKUP_DISABLED:
+ return "BACKUP_DISABLED";
+ case BackupManagerMonitor.LOG_EVENT_ID_DEVICE_NOT_PROVISIONED:
+ return "DEVICE_NOT_PROVISIONED";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_TRANSPORT_NOT_PRESENT:
+ return "PACKAGE_TRANSPORT_NOT_PRESENT";
+ case BackupManagerMonitor.LOG_EVENT_ID_ERROR_PREFLIGHT:
+ return "ERROR_PREFLIGHT";
+ case BackupManagerMonitor.LOG_EVENT_ID_QUOTA_HIT_PREFLIGHT:
+ return "QUOTA_HIT_PREFLIGHT";
+ case BackupManagerMonitor.LOG_EVENT_ID_EXCEPTION_FULL_BACKUP:
+ return "EXCEPTION_FULL_BACKUP";
+ case BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL:
+ return "KEY_VALUE_BACKUP_CANCEL";
+ case BackupManagerMonitor.LOG_EVENT_ID_NO_RESTORE_METADATA_AVAILABLE:
+ return "NO_RESTORE_METADATA_AVAILABLE";
+ case BackupManagerMonitor.LOG_EVENT_ID_NO_PM_METADATA_RECEIVED:
+ return "NO_PM_METADATA_RECEIVED";
+ case BackupManagerMonitor.LOG_EVENT_ID_PM_AGENT_HAS_NO_METADATA:
+ return "PM_AGENT_HAS_NO_METADATA";
+ case BackupManagerMonitor.LOG_EVENT_ID_LOST_TRANSPORT:
+ return "LOST_TRANSPORT";
+ case BackupManagerMonitor.LOG_EVENT_ID_PACKAGE_NOT_PRESENT:
+ return "PACKAGE_NOT_PRESENT";
+ case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_VERSION_HIGHER:
+ return "RESTORE_VERSION_HIGHER";
+ case BackupManagerMonitor.LOG_EVENT_ID_APP_HAS_NO_AGENT:
+ return "APP_HAS_NO_AGENT";
+ case BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH:
+ return "SIGNATURE_MISMATCH";
+ case BackupManagerMonitor.LOG_EVENT_ID_CANT_FIND_AGENT:
+ return "CANT_FIND_AGENT";
+ case BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_RESTORE_TIMEOUT:
+ return "KEY_VALUE_RESTORE_TIMEOUT";
+ case BackupManagerMonitor.LOG_EVENT_ID_RESTORE_ANY_VERSION:
+ return "RESTORE_ANY_VERSION";
+ case BackupManagerMonitor.LOG_EVENT_ID_VERSIONS_MATCH:
+ return "VERSIONS_MATCH";
+ case BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BACKUP_OLDER:
+ return "VERSION_OF_BACKUP_OLDER";
+ case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_SIGNATURE_MISMATCH:
+ return "FULL_RESTORE_SIGNATURE_MISMATCH";
+ case BackupManagerMonitor.LOG_EVENT_ID_SYSTEM_APP_NO_AGENT:
+ return "SYSTEM_APP_NO_AGENT";
+ case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_ALLOW_BACKUP_FALSE:
+ return "FULL_RESTORE_ALLOW_BACKUP_FALSE";
+ case BackupManagerMonitor.LOG_EVENT_ID_APK_NOT_INSTALLED:
+ return "APK_NOT_INSTALLED";
+ case BackupManagerMonitor.LOG_EVENT_ID_CANNOT_RESTORE_WITHOUT_APK:
+ return "CANNOT_RESTORE_WITHOUT_APK";
+ case BackupManagerMonitor.LOG_EVENT_ID_MISSING_SIGNATURE:
+ return "MISSING_SIGNATURE";
+ case BackupManagerMonitor.LOG_EVENT_ID_EXPECTED_DIFFERENT_PACKAGE:
+ return "EXPECTED_DIFFERENT_PACKAGE";
+ case BackupManagerMonitor.LOG_EVENT_ID_UNKNOWN_VERSION:
+ return "UNKNOWN_VERSION";
+ case BackupManagerMonitor.LOG_EVENT_ID_FULL_RESTORE_TIMEOUT:
+ return "FULL_RESTORE_TIMEOUT";
+ case BackupManagerMonitor.LOG_EVENT_ID_CORRUPT_MANIFEST:
+ return "CORRUPT_MANIFEST";
+ case BackupManagerMonitor.LOG_EVENT_ID_WIDGET_METADATA_MISMATCH:
+ return "WIDGET_METADATA_MISMATCH";
+ case BackupManagerMonitor.LOG_EVENT_ID_WIDGET_UNKNOWN_VERSION:
+ return "WIDGET_UNKNOWN_VERSION";
+ case BackupManagerMonitor.LOG_EVENT_ID_NO_PACKAGES:
+ return "NO_PACKAGES";
+ case BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_IS_NULL:
+ return "TRANSPORT_IS_NULL";
+ default:
+ return "UNKNOWN_ID";
+ }
+ }
+
+ @IntDef({Monitor.OFF, Monitor.NORMAL, Monitor.VERBOSE})
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface Monitor {
+ int OFF = 0;
+ int NORMAL = 1;
+ int VERBOSE = 2;
+ }
}
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 5cc4fc4..b3e287b 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -42,7 +42,6 @@
namespace uhid {
static const char* UHID_PATH = "/dev/uhid";
-static const size_t UHID_MAX_NAME_LENGTH = 128;
static struct {
jmethodID onDeviceOpen;
@@ -90,8 +89,13 @@
}
Device* Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
- std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
- std::unique_ptr<DeviceCallback> callback) {
+ std::vector<uint8_t> descriptor, std::unique_ptr<DeviceCallback> callback) {
+
+ size_t size = descriptor.size();
+ if (size > HID_MAX_DESCRIPTOR_SIZE) {
+ LOGE("Received invalid hid report with descriptor size %zu, skipping", size);
+ return nullptr;
+ }
int fd = ::open(UHID_PATH, O_RDWR | O_CLOEXEC);
if (fd < 0) {
@@ -102,10 +106,10 @@
struct uhid_event ev;
memset(&ev, 0, sizeof(ev));
ev.type = UHID_CREATE2;
- strncpy((char*)ev.u.create2.name, name, UHID_MAX_NAME_LENGTH);
- memcpy(&ev.u.create2.rd_data, descriptor.get(),
- descriptorSize * sizeof(ev.u.create2.rd_data[0]));
- ev.u.create2.rd_size = descriptorSize;
+ strlcpy(reinterpret_cast<char*>(ev.u.create2.name), name, sizeof(ev.u.create2.name));
+ memcpy(&ev.u.create2.rd_data, descriptor.data(),
+ size * sizeof(ev.u.create2.rd_data[0]));
+ ev.u.create2.rd_size = size;
ev.u.create2.bus = BUS_BLUETOOTH;
ev.u.create2.vendor = vid;
ev.u.create2.product = pid;
@@ -156,12 +160,17 @@
mFd = -1;
}
-void Device::sendReport(uint8_t* report, size_t reportSize) {
+void Device::sendReport(const std::vector<uint8_t>& report) const {
+ if (report.size() > UHID_DATA_MAX) {
+ LOGE("Received invalid report of size %zu, skipping", report.size());
+ return;
+ }
+
struct uhid_event ev;
memset(&ev, 0, sizeof(ev));
ev.type = UHID_INPUT2;
- ev.u.input2.size = reportSize;
- memcpy(&ev.u.input2.data, report, reportSize);
+ ev.u.input2.size = report.size();
+ memcpy(&ev.u.input2.data, report.data(), report.size() * sizeof(ev.u.input2.data[0]));
ssize_t ret = TEMP_FAILURE_RETRY(::write(mFd, &ev, sizeof(ev)));
if (ret < 0 || ret != sizeof(ev)) {
LOGE("Failed to send hid event: %s", strerror(errno));
@@ -191,12 +200,13 @@
} // namespace uhid
-std::unique_ptr<uint8_t[]> getData(JNIEnv* env, jbyteArray javaArray, size_t& outSize) {
+std::vector<uint8_t> getData(JNIEnv* env, jbyteArray javaArray) {
ScopedByteArrayRO scopedArray(env, javaArray);
- outSize = scopedArray.size();
- std::unique_ptr<uint8_t[]> data(new uint8_t[outSize]);
- for (size_t i = 0; i < outSize; i++) {
- data[i] = static_cast<uint8_t>(scopedArray[i]);
+ size_t size = scopedArray.size();
+ std::vector<uint8_t> data;
+ data.reserve(size);
+ for (size_t i = 0; i < size; i++) {
+ data.push_back(static_cast<uint8_t>(scopedArray[i]));
}
return data;
}
@@ -208,23 +218,20 @@
return 0;
}
- size_t size;
- std::unique_ptr<uint8_t[]> desc = getData(env, rawDescriptor, size);
+ std::vector<uint8_t> desc = getData(env, rawDescriptor);
std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
uhid::Device* d = uhid::Device::open(
- id, reinterpret_cast<const char*>(name.c_str()), vid, pid,
- std::move(desc), size, std::move(cb));
+ id, reinterpret_cast<const char*>(name.c_str()), vid, pid, desc, std::move(cb));
return reinterpret_cast<jlong>(d);
}
static void sendReport(JNIEnv* env, jclass /* clazz */, jlong ptr, jbyteArray rawReport) {
- size_t size;
- std::unique_ptr<uint8_t[]> report = getData(env, rawReport, size);
+ std::vector<uint8_t> report = getData(env, rawReport);
uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
if (d) {
- d->sendReport(report.get(), size);
+ d->sendReport(report);
} else {
LOGE("Could not send report, Device* is null!");
}
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 149456d..61a1f76 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -15,6 +15,7 @@
*/
#include <memory>
+#include <vector>
#include <jni.h>
@@ -38,13 +39,12 @@
class Device {
public:
static Device* open(int32_t id, const char* name, int32_t vid, int32_t pid,
- std::unique_ptr<uint8_t[]> descriptor, size_t descriptorSize,
- std::unique_ptr<DeviceCallback> callback);
+ std::vector<uint8_t> descriptor, std::unique_ptr<DeviceCallback> callback);
Device(int32_t id, int fd, std::unique_ptr<DeviceCallback> callback);
~Device();
- void sendReport(uint8_t* report, size_t reportSize);
+ void sendReport(const std::vector<uint8_t>& report) const;
void close();
int handleEvents(int events);
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index 61c185f..ba2aaad8 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -45,7 +45,6 @@
src/external/puller_util.cpp \
src/logd/LogEvent.cpp \
src/logd/LogListener.cpp \
- src/logd/LogReader.cpp \
src/matchers/CombinationLogMatchingTracker.cpp \
src/matchers/matcher_util.cpp \
src/matchers/SimpleLogMatchingTracker.cpp \
@@ -194,7 +193,6 @@
tests/external/puller_util_test.cpp \
tests/indexed_priority_queue_test.cpp \
tests/LogEntryMatcher_test.cpp \
- tests/LogReader_test.cpp \
tests/LogEvent_test.cpp \
tests/MetricsManager_test.cpp \
tests/StatsLogProcessor_test.cpp \
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index ab0aa25..8e02f9c 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -161,10 +161,6 @@
}
}
-void StatsLogProcessor::OnLogEvent(LogEvent* event) {
- OnLogEvent(event, false);
-}
-
void StatsLogProcessor::resetConfigs() {
std::lock_guard<std::mutex> lock(mMetricsMutex);
resetConfigsLocked(getElapsedRealtimeNs());
@@ -178,7 +174,7 @@
resetConfigsLocked(timestampNs, configKeys);
}
-void StatsLogProcessor::OnLogEvent(LogEvent* event, bool reconnected) {
+void StatsLogProcessor::OnLogEvent(LogEvent* event) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
#ifdef VERY_VERBOSE_PRINTING
@@ -188,41 +184,6 @@
#endif
const int64_t currentTimestampNs = event->GetElapsedTimestampNs();
- if (reconnected && mLastTimestampSeen != 0) {
- // LogReader tells us the connection has just been reset. Now we need
- // to enter reconnection state to find the last CP.
- mInReconnection = true;
- }
-
- if (mInReconnection) {
- // We see the checkpoint
- if (currentTimestampNs == mLastTimestampSeen) {
- mInReconnection = false;
- // Found the CP. ignore this event, and we will start to read from next event.
- return;
- }
- if (currentTimestampNs > mLargestTimestampSeen) {
- // We see a new log but CP has not been found yet. Give up now.
- mLogLossCount++;
- mInReconnection = false;
- StatsdStats::getInstance().noteLogLost(currentTimestampNs);
- // Persist the data before we reset. Do we want this?
- WriteDataToDiskLocked(CONFIG_RESET);
- // We see fresher event before we see the checkpoint. We might have lost data.
- // The best we can do is to reset.
- resetConfigsLocked(currentTimestampNs);
- } else {
- // Still in search of the CP. Keep going.
- return;
- }
- }
-
- mLogCount++;
- mLastTimestampSeen = currentTimestampNs;
- if (mLargestTimestampSeen < currentTimestampNs) {
- mLargestTimestampSeen = currentTimestampNs;
- }
-
resetIfConfigTtlExpiredLocked(currentTimestampNs);
StatsdStats::getInstance().noteAtomLogged(
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 05cf0c1..df80b8e 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -18,7 +18,6 @@
#include <gtest/gtest_prod.h>
#include "config/ConfigListener.h"
-#include "logd/LogReader.h"
#include "metrics/MetricsManager.h"
#include "packages/UidMap.h"
#include "external/StatsPullerManager.h"
@@ -52,9 +51,6 @@
const std::function<bool(const ConfigKey&)>& sendBroadcast);
virtual ~StatsLogProcessor();
- void OnLogEvent(LogEvent* event, bool reconnectionStarts);
-
- // for testing only.
void OnLogEvent(LogEvent* event);
void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
@@ -174,14 +170,6 @@
int64_t mLastTimestampSeen = 0;
- bool mInReconnection = false;
-
- // Processed log count
- uint64_t mLogCount = 0;
-
- // Log loss detected count
- int mLogLossCount = 0;
-
long mLastPullerCacheClearTimeSec = 0;
#ifdef VERY_VERBOSE_PRINTING
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 0c241fc..91d68ea 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -883,8 +883,8 @@
mConfigManager->Startup();
}
-void StatsService::OnLogEvent(LogEvent* event, bool reconnectionStarts) {
- mProcessor->OnLogEvent(event, reconnectionStarts);
+void StatsService::OnLogEvent(LogEvent* event) {
+ mProcessor->OnLogEvent(event);
}
Status StatsService::getData(int64_t key, const String16& packageName, vector<uint8_t>* output) {
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index ed90050..613f509 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -22,6 +22,7 @@
#include "anomaly/AlarmMonitor.h"
#include "config/ConfigManager.h"
#include "external/StatsPullerManager.h"
+#include "logd/LogListener.h"
#include "packages/UidMap.h"
#include "statscompanion_util.h"
@@ -75,7 +76,7 @@
/**
* Called by LogReader when there's a log event to process.
*/
- virtual void OnLogEvent(LogEvent* event, bool reconnectionStarts);
+ virtual void OnLogEvent(LogEvent* event);
/**
* Binder call for clients to request data for this configuration key.
diff --git a/cmds/statsd/src/condition/condition_util.cpp b/cmds/statsd/src/condition/condition_util.cpp
index 691356b..35e03e4 100644
--- a/cmds/statsd/src/condition/condition_util.cpp
+++ b/cmds/statsd/src/condition/condition_util.cpp
@@ -76,9 +76,9 @@
break;
}
case LogicalOperation::NOT:
- newCondition = (conditionCache[children[0]] == ConditionState::kFalse)
- ? ConditionState::kTrue
- : ConditionState::kFalse;
+ newCondition = children.empty() ? ConditionState::kUnknown :
+ ((conditionCache[children[0]] == ConditionState::kFalse) ?
+ ConditionState::kTrue : ConditionState::kFalse);
break;
case LogicalOperation::NAND:
newCondition = hasFalse ? ConditionState::kTrue : ConditionState::kFalse;
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 611c342..122e669 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -31,9 +31,6 @@
namespace os {
namespace statsd {
-// Util function to build a hard coded config with test metrics.
-StatsdConfig build_fake_config();
-
/**
* Keeps track of which configurations have been set from various sources.
*/
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index a955511..c37d0cf 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -180,12 +180,12 @@
noteConfigResetInternalLocked(key);
}
-void StatsdStats::noteLogLost(int64_t timestampNs) {
+void StatsdStats::noteLogLost(int64_t timestampNs, int32_t count) {
lock_guard<std::mutex> lock(mLock);
if (mLogLossTimestampNs.size() == kMaxLoggerErrors) {
mLogLossTimestampNs.pop_front();
}
- mLogLossTimestampNs.push_back(timestampNs);
+ mLogLossTimestampNs.push_back(std::make_pair(timestampNs, count));
}
void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
@@ -529,7 +529,8 @@
}
for (const auto& loss : mLogLossTimestampNs) {
- fprintf(out, "Log loss detected at %lld (elapsedRealtimeNs)\n", (long long)loss);
+ fprintf(out, "Log loss: %lld (elapsedRealtimeNs) - %d (count)\n", (long long)loss.first,
+ loss.second);
}
}
@@ -687,7 +688,7 @@
for (const auto& loss : mLogLossTimestampNs) {
proto.write(FIELD_TYPE_INT64 | FIELD_ID_LOG_LOSS_STATS | FIELD_COUNT_REPEATED,
- (long long)loss);
+ (long long)loss.first);
}
for (const auto& restart : mSystemServerRestartSec) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 9fb2cd8..daea027 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -284,7 +284,7 @@
/**
* Records statsd skipped an event.
*/
- void noteLogLost(int64_t timestamp);
+ void noteLogLost(int64_t timestamp, int32_t count);
/**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
@@ -341,8 +341,8 @@
// Logd errors. Size capped by kMaxLoggerErrors.
std::list<const std::pair<int, int>> mLoggerErrors;
- // Timestamps when we detect log loss after logd reconnect.
- std::list<int64_t> mLogLossTimestampNs;
+ // Timestamps when we detect log loss, and the number of logs lost.
+ std::list<std::pair<int64_t, int32_t>> mLogLossTimestampNs;
std::list<int32_t> mSystemServerRestartSec;
diff --git a/cmds/statsd/src/logd/LogListener.cpp b/cmds/statsd/src/logd/LogListener.cpp
index 6ac7978..ddb26f9 100644
--- a/cmds/statsd/src/logd/LogListener.cpp
+++ b/cmds/statsd/src/logd/LogListener.cpp
@@ -14,17 +14,7 @@
* limitations under the License.
*/
-#include "logd/LogReader.h"
-
-#include <log/log_read.h>
-
-#include <utils/Errors.h>
-
-#include <time.h>
-#include <unistd.h>
-
-using namespace android;
-using namespace std;
+#include "logd/LogListener.h"
namespace android {
namespace os {
diff --git a/cmds/statsd/src/logd/LogListener.h b/cmds/statsd/src/logd/LogListener.h
index f924040..d8b06e9 100644
--- a/cmds/statsd/src/logd/LogListener.h
+++ b/cmds/statsd/src/logd/LogListener.h
@@ -19,7 +19,6 @@
#include "logd/LogEvent.h"
#include <utils/RefBase.h>
-#include <vector>
namespace android {
namespace os {
@@ -33,7 +32,7 @@
LogListener();
virtual ~LogListener();
- virtual void OnLogEvent(LogEvent* msg, bool reconnectionStarts) = 0;
+ virtual void OnLogEvent(LogEvent* msg) = 0;
};
} // namespace statsd
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
deleted file mode 100644
index 26ae6a3..0000000
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include "logd/LogReader.h"
-
-#include "guardrail/StatsdStats.h"
-
-#include <time.h>
-#include <unistd.h>
-#include <utils/Errors.h>
-
-using namespace android;
-using namespace std;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#define SNOOZE_INITIAL_MS 100
-#define SNOOZE_MAX_MS (10 * 60 * 1000) // Ten minutes
-
-LogReader::LogReader(const sp<LogListener>& listener) : mListener(listener) {
-}
-
-LogReader::~LogReader() {
-}
-
-void LogReader::Run() {
- int nextSnoozeMs = SNOOZE_INITIAL_MS;
-
- // In an ideal world, this outer loop will only ever run one iteration, but it
- // exists to handle crashes in logd. The inner loop inside connect_and_read()
- // reads from logd forever, but if that read fails, we fall out to the outer
- // loop, do the backoff (resetting the backoff timeout if we successfully read
- // something), and then try again.
- while (true) {
- // Connect and read
- int lineCount = connect_and_read();
-
- // Figure out how long to sleep.
- if (lineCount > 0) {
- // If we managed to read at least one line, reset the backoff
- nextSnoozeMs = SNOOZE_INITIAL_MS;
- } else {
- // Otherwise, expontial backoff
- nextSnoozeMs *= 1.5f;
- if (nextSnoozeMs > 10 * 60 * 1000) {
- // Don't wait for toooo long.
- nextSnoozeMs = SNOOZE_MAX_MS;
- }
- }
-
- // Sleep
- timespec ts;
- timespec rem;
- ts.tv_sec = nextSnoozeMs / 1000;
- ts.tv_nsec = (nextSnoozeMs % 1000) * 1000000L;
- while (nanosleep(&ts, &rem) == -1) {
- if (errno == EINTR) {
- ts = rem;
- }
- // other errors are basically impossible
- }
- }
-}
-
-int LogReader::connect_and_read() {
- int lineCount = 0;
- status_t err;
- logger_list* loggers;
- logger* eventLogger;
-
- // Prepare the logging context
- loggers = android_logger_list_alloc(ANDROID_LOG_RDONLY,
- /* don't stop after N lines */ 0,
- /* no pid restriction */ 0);
-
- // Open the buffer(s)
- eventLogger = android_logger_open(loggers, LOG_ID_STATS);
-
- // Read forever
- if (eventLogger) {
- log_msg msg;
- while (true) {
- // Read a message
- err = android_logger_list_read(loggers, &msg);
- // err = 0 - no content, unexpected connection drop or EOF.
- // err = +ive number - size of retrieved data from logger
- // err = -ive number, OS supplied error _except_ for -EAGAIN
- if (err <= 0) {
- StatsdStats::getInstance().noteLoggerError(err);
- fprintf(stderr, "logcat read failure: %s\n", strerror(err));
- break;
- }
-
- // Record that we read one (used above to know how to snooze).
- lineCount++;
-
- // Wrap it in a LogEvent object
- LogEvent event(msg);
-
- // Call the listener
- mListener->OnLogEvent(&event,
- lineCount == 1 /* indicate whether it's a new connection */);
- }
- }
-
- // Free the logger list and close the individual loggers
- android_logger_list_free(loggers);
-
- return lineCount;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android
diff --git a/cmds/statsd/src/logd/LogReader.h b/cmds/statsd/src/logd/LogReader.h
deleted file mode 100644
index c51074c..0000000
--- a/cmds/statsd/src/logd/LogReader.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef LOGREADER_H
-#define LOGREADER_H
-
-#include "logd/LogListener.h"
-
-#include <utils/RefBase.h>
-
-#include <vector>
-
-namespace android {
-namespace os {
-namespace statsd {
-
-/**
- * Class to read logs from logd.
- */
-class LogReader : public virtual android::RefBase {
-public:
- /**
- * Construct the LogReader with the event listener. (Which is StatsService)
- */
- LogReader(const sp<LogListener>& listener);
-
- /**
- * Destructor.
- */
- virtual ~LogReader();
-
- /**
- * Run the main LogReader loop
- */
- void Run();
-
-private:
- /**
- * Who is going to get the events when they're read.
- */
- sp<LogListener> mListener;
-
- /**
- * Connect to a single instance of logd, and read until there's a read error.
- * Logd can crash, exit, be killed etc.
- *
- * Returns the number of lines that were read.
- */
- int connect_and_read();
-};
-
-} // namespace statsd
-} // namespace os
-} // namespace android
-
-#endif // LOGREADER_H
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 2f15d0f..9002f07 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -18,7 +18,6 @@
#include "Log.h"
#include "StatsService.h"
-#include "logd/LogReader.h"
#include "socket/StatsSocketListener.h"
#include <binder/IInterface.h>
@@ -39,9 +38,6 @@
using namespace android;
using namespace android::os::statsd;
-const bool kUseLogd = false;
-const bool kUseStatsdSocket = true;
-
/**
* Thread function data.
*/
@@ -49,58 +45,6 @@
sp<StatsService> service;
};
-/**
- * Thread func for where the log reader runs.
- */
-static void* log_reader_thread_func(void* cookie) {
- log_reader_thread_data* data = static_cast<log_reader_thread_data*>(cookie);
- sp<LogReader> reader = new LogReader(data->service);
-
- // Run the read loop. Never returns.
- reader->Run();
-
- ALOGW("statsd LogReader.Run() is not supposed to return.");
-
- delete data;
- return NULL;
-}
-
-/**
- * Creates and starts the thread to own the LogReader.
- */
-static status_t start_log_reader_thread(const sp<StatsService>& service) {
- status_t err;
- pthread_attr_t attr;
- pthread_t thread;
-
- // Thread data.
- std::unique_ptr<log_reader_thread_data> data = std::make_unique<log_reader_thread_data>();
- data->service = service;
-
- // Create the thread
- err = pthread_attr_init(&attr);
- if (err != NO_ERROR) {
- return err;
- }
- err = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- if (err != NO_ERROR) {
- pthread_attr_destroy(&attr);
- return err;
- }
- err = pthread_create(&thread, &attr, log_reader_thread_func,
- static_cast<void*>(data.get()));
- if (err != NO_ERROR) {
- pthread_attr_destroy(&attr);
- return err;
- }
- // Release here rather than in pthread_create, since an error creating the
- // thread leaves `data` ownerless.
- data.release();
- pthread_attr_destroy(&attr);
-
- return NO_ERROR;
-}
-
int main(int /*argc*/, char** /*argv*/) {
// Set up the looper
sp<Looper> looper(Looper::prepare(0 /* opts */));
@@ -124,22 +68,11 @@
sp<StatsSocketListener> socketListener = new StatsSocketListener(service);
- if (kUseLogd) {
- ALOGI("using logd");
- // Start the log reader thread
- status_t err = start_log_reader_thread(service);
- if (err != NO_ERROR) {
- return 1;
- }
- }
-
- if (kUseStatsdSocket) {
ALOGI("using statsd socket");
// Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
if (socketListener->startListener(600)) {
exit(1);
}
- }
// Loop forever -- the reports run on this thread in a handler, and the
// binder calls remain responsive in their pool of one thread.
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index fbe0b21..284c451 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -71,11 +71,14 @@
GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard, const int pullTagId,
+ const int triggerAtomId, const int atomId,
const int64_t timeBaseNs, const int64_t startTimeNs,
const sp<StatsPullerManager>& pullerManager)
: MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
mPullerManager(pullerManager),
mPullTagId(pullTagId),
+ mTriggerAtomId(triggerAtomId),
+ mAtomId(atomId),
mIsPulled(pullTagId != -1),
mMinBucketSizeNs(metric.min_bucket_size_nanos()),
mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
@@ -272,12 +275,12 @@
uint64_t atomsToken =
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
FIELD_ID_ATOM);
- writeFieldValueTreeToStream(mTagId, *(atom.mFields), protoOutput);
+ writeFieldValueTreeToStream(mAtomId, *(atom.mFields), protoOutput);
protoOutput->end(atomsToken);
}
const bool truncateTimestamp =
android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(
- mTagId) ==
+ mAtomId) ==
android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
for (const auto& atom : bucket.mGaugeAtoms) {
const int64_t elapsedTimestampNs = truncateTimestamp ?
@@ -410,7 +413,6 @@
return;
}
int64_t eventTimeNs = event.GetElapsedTimestampNs();
- mTagId = event.GetTagId();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
@@ -418,6 +420,11 @@
}
flushIfNeededLocked(eventTimeNs);
+ if (mTriggerAtomId == event.GetTagId()) {
+ pullLocked(eventTimeNs);
+ return;
+ }
+
// When gauge metric wants to randomly sample the output atom, we just simply use the first
// gauge in the given bucket.
if (mCurrentSlicedBucket->find(eventKey) != mCurrentSlicedBucket->end() &&
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index cc65440..15be1d7 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -58,7 +58,8 @@
public:
GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const int pullTagId, const int64_t timeBaseNs, const int64_t startTimeNs,
+ const int pullTagId, const int triggerAtomId, const int atomId,
+ const int64_t timeBaseNs, const int64_t startTimeNs,
const sp<StatsPullerManager>& pullerManager);
virtual ~GaugeMetricProducer();
@@ -115,12 +116,16 @@
void pullLocked(const int64_t timestampNs);
- int mTagId;
-
sp<StatsPullerManager> mPullerManager;
// tagId for pulled data. -1 if this is not pulled
const int mPullTagId;
+ // tagId for atoms that trigger the pulling, if any
+ const int mTriggerAtomId;
+
+ // tagId for output atom
+ const int mAtomId;
+
// if this is pulled metric
const bool mIsPulled;
@@ -169,6 +174,7 @@
FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 16447e8..192a54b 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define DEBUG true // STOPSHIP if true
+#define DEBUG false // STOPSHIP if true
#include "Log.h"
#include "ValueMetricProducer.h"
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index ff48d02..75d6df9 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -82,6 +82,28 @@
return true;
}
+bool handlePullMetricTriggerWithLogTrackers(
+ const int64_t trigger, const int metricIndex,
+ const vector<sp<LogMatchingTracker>>& allAtomMatchers,
+ const unordered_map<int64_t, int>& logTrackerMap,
+ unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
+ auto logTrackerIt = logTrackerMap.find(trigger);
+ if (logTrackerIt == logTrackerMap.end()) {
+ ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)trigger);
+ return false;
+ }
+ if (allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
+ ALOGE("AtomMatcher \"%lld\" has more than one tag ids."
+ "Trigger can only be one atom type.",
+ (long long)trigger);
+ return false;
+ }
+ logTrackerIndex = logTrackerIt->second;
+ auto& metric_list = trackerToMetricMap[logTrackerIndex];
+ metric_list.push_back(metricIndex);
+ return true;
+}
+
bool handleMetricWithConditions(
const int64_t condition, const int metricIndex,
const unordered_map<int64_t, int>& conditionTrackerMap,
@@ -502,13 +524,29 @@
}
sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
- // If it is pulled atom, it should be simple matcher with one tagId.
+ // For GaugeMetric atom, it should be simple matcher with one tagId.
if (atomMatcher->getAtomIds().size() != 1) {
return false;
}
int atomTagId = *(atomMatcher->getAtomIds().begin());
int pullTagId = statsPullerManager.PullerForMatcherExists(atomTagId) ? atomTagId : -1;
+ int triggerTrackerIndex;
+ int triggerAtomId = -1;
+ if (pullTagId != -1 && metric.has_trigger_event()) {
+ // event_trigger should be used with ALL_CONDITION_CHANGES
+ if (metric.sampling_type() != GaugeMetric::ALL_CONDITION_CHANGES) {
+ return false;
+ }
+ if (!handlePullMetricTriggerWithLogTrackers(metric.trigger_event(), metricIndex,
+ allAtomMatchers, logTrackerMap,
+ trackerToMetricMap, triggerTrackerIndex)) {
+ return false;
+ }
+ sp<LogMatchingTracker> triggerAtomMatcher = allAtomMatchers.at(triggerTrackerIndex);
+ triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
+ }
+
int conditionIndex = -1;
if (metric.has_condition()) {
bool good = handleMetricWithConditions(
@@ -524,9 +562,9 @@
}
}
- sp<MetricProducer> gaugeProducer =
- new GaugeMetricProducer(key, metric, conditionIndex, wizard, pullTagId,
- timeBaseTimeNs, currentTimeNs, pullerManager);
+ sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
+ key, metric, conditionIndex, wizard, pullTagId, triggerAtomId, atomTagId,
+ timeBaseTimeNs, currentTimeNs, pullerManager);
allMetricProducers.push_back(gaugeProducer);
}
for (int i = 0; i < config.no_report_metric_size(); ++i) {
diff --git a/cmds/statsd/src/socket/StatsSocketListener.cpp b/cmds/statsd/src/socket/StatsSocketListener.cpp
index 0392d67..4041da7 100755
--- a/cmds/statsd/src/socket/StatsSocketListener.cpp
+++ b/cmds/statsd/src/socket/StatsSocketListener.cpp
@@ -40,6 +40,7 @@
namespace statsd {
static const int kLogMsgHeaderSize = 28;
+static const int kLibLogTag = 1006;
StatsSocketListener::StatsSocketListener(const sp<LogListener>& listener)
: SocketListener(getLogSocket(), false /*start listen*/), mListener(listener) {
@@ -99,6 +100,22 @@
char* ptr = ((char*)buffer) + sizeof(android_log_header_t);
n -= sizeof(android_log_header_t);
+ // When a log failed to write to statsd socket (e.g., due ot EBUSY), a special message would
+ // be sent to statsd when the socket communication becomes available again.
+ // The format is android_log_event_int_t with a single integer in the payload indicating the
+ // number of logs that failed. (*FORMAT MUST BE IN SYNC WITH system/core/libstats*)
+ // Note that all normal stats logs are in the format of event_list, so there won't be confusion.
+ //
+ // TODO(b/80538532): In addition to log it in StatsdStats, we should properly reset the config.
+ if (n == sizeof(android_log_event_int_t)) {
+ android_log_event_int_t* int_event = reinterpret_cast<android_log_event_int_t*>(ptr);
+ if (int_event->header.tag == kLibLogTag && int_event->payload.type == EVENT_TYPE_INT) {
+ ALOGE("Found dropped events: %d", int_event->payload.data);
+ StatsdStats::getInstance().noteLogLost(getElapsedRealtimeNs(), int_event->payload.data);
+ return true;
+ }
+ }
+
log_msg msg;
msg.entry.len = n;
@@ -111,7 +128,7 @@
LogEvent event(msg);
// Call the listener
- mListener->OnLogEvent(&event, false /*reconnected, N/A in statsd socket*/);
+ mListener->OnLogEvent(&event);
return true;
}
diff --git a/cmds/statsd/src/stats_util.h b/cmds/statsd/src/stats_util.h
index 5fcb161..cfc411f 100644
--- a/cmds/statsd/src/stats_util.h
+++ b/cmds/statsd/src/stats_util.h
@@ -17,7 +17,6 @@
#pragma once
#include "HashableDimensionKey.h"
-#include "logd/LogReader.h"
#include <unordered_map>
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 26dfda3..d19e247 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -217,6 +217,8 @@
optional int64 what = 2;
+ optional int64 trigger_event = 12;
+
optional FieldFilter gauge_fields_filter = 3;
optional int64 condition = 4;
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index ecc57f5..b6f635c 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -238,132 +238,6 @@
EXPECT_EQ(2, report.annotation(0).field_int32());
}
-TEST(StatsLogProcessorTest, TestOutOfOrderLogs) {
- // Setup simple config key corresponding to empty config.
- sp<UidMap> m = new UidMap();
- sp<StatsPullerManager> pullerManager = new StatsPullerManager();
- sp<AlarmMonitor> anomalyAlarmMonitor;
- sp<AlarmMonitor> subscriberAlarmMonitor;
- int broadcastCount = 0;
- StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0,
- [&broadcastCount](const ConfigKey& key) {
- broadcastCount++;
- return true;
- });
-
- LogEvent event1(0, 1 /*logd timestamp*/, 1001 /*elapsedRealtime*/);
- event1.init();
-
- LogEvent event2(0, 2, 1002);
- event2.init();
-
- LogEvent event3(0, 3, 1005);
- event3.init();
-
- LogEvent event4(0, 4, 1004);
- event4.init();
-
- // <----- Reconnection happens
-
- LogEvent event5(0, 5, 999);
- event5.init();
-
- LogEvent event6(0, 6, 2000);
- event6.init();
-
- // <----- Reconnection happens
-
- LogEvent event7(0, 7, 3000);
- event7.init();
-
- // first event ever
- p.OnLogEvent(&event1, true);
- EXPECT_EQ(1UL, p.mLogCount);
- EXPECT_EQ(1001LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1001LL, p.mLastTimestampSeen);
-
- p.OnLogEvent(&event2, false);
- EXPECT_EQ(2UL, p.mLogCount);
- EXPECT_EQ(1002LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1002LL, p.mLastTimestampSeen);
-
- p.OnLogEvent(&event3, false);
- EXPECT_EQ(3UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1005LL, p.mLastTimestampSeen);
-
- p.OnLogEvent(&event4, false);
- EXPECT_EQ(4UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1004LL, p.mLastTimestampSeen);
- EXPECT_FALSE(p.mInReconnection);
-
- // Reconnect happens, event1 out of buffer. Read event2
- p.OnLogEvent(&event2, true);
- EXPECT_EQ(4UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1004LL, p.mLastTimestampSeen);
- EXPECT_TRUE(p.mInReconnection);
-
- p.OnLogEvent(&event3, false);
- EXPECT_EQ(4UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1004LL, p.mLastTimestampSeen);
- EXPECT_TRUE(p.mInReconnection);
-
- p.OnLogEvent(&event4, false);
- EXPECT_EQ(4UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(1004LL, p.mLastTimestampSeen);
- EXPECT_FALSE(p.mInReconnection);
-
- // Fresh event comes.
- p.OnLogEvent(&event5, false);
- EXPECT_EQ(5UL, p.mLogCount);
- EXPECT_EQ(1005LL, p.mLargestTimestampSeen);
- EXPECT_EQ(999LL, p.mLastTimestampSeen);
-
- p.OnLogEvent(&event6, false);
- EXPECT_EQ(6UL, p.mLogCount);
- EXPECT_EQ(2000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(2000LL, p.mLastTimestampSeen);
-
- // Reconnect happens, read from event4
- p.OnLogEvent(&event4, true);
- EXPECT_EQ(6UL, p.mLogCount);
- EXPECT_EQ(2000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(2000LL, p.mLastTimestampSeen);
- EXPECT_TRUE(p.mInReconnection);
-
- p.OnLogEvent(&event5, false);
- EXPECT_EQ(6UL, p.mLogCount);
- EXPECT_EQ(2000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(2000LL, p.mLastTimestampSeen);
- EXPECT_TRUE(p.mInReconnection);
-
- // Before we get out of reconnection state, it reconnects again.
- p.OnLogEvent(&event5, true);
- EXPECT_EQ(6UL, p.mLogCount);
- EXPECT_EQ(2000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(2000LL, p.mLastTimestampSeen);
- EXPECT_TRUE(p.mInReconnection);
-
- p.OnLogEvent(&event6, false);
- EXPECT_EQ(6UL, p.mLogCount);
- EXPECT_EQ(2000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(2000LL, p.mLastTimestampSeen);
- EXPECT_FALSE(p.mInReconnection);
- EXPECT_EQ(0, p.mLogLossCount);
-
- // it reconnects again. All old events are gone. We lose CP.
- p.OnLogEvent(&event7, true);
- EXPECT_EQ(7UL, p.mLogCount);
- EXPECT_EQ(3000LL, p.mLargestTimestampSeen);
- EXPECT_EQ(3000LL, p.mLastTimestampSeen);
- EXPECT_EQ(1, p.mLogLossCount);
- EXPECT_FALSE(p.mInReconnection);
-}
-
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
diff --git a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
index 23d6926..6529d65 100644
--- a/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
+++ b/cmds/statsd/tests/condition/CombinationConditionTracker_test.cpp
@@ -40,6 +40,7 @@
EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
ConditionState::kUnknown);
}
+
TEST(ConditionTrackerTest, TestAndCondition) {
// Set up the matcher
LogicalOperation operation = LogicalOperation::AND;
@@ -103,6 +104,11 @@
conditionResults.clear();
conditionResults.push_back(ConditionState::kFalse);
EXPECT_TRUE(evaluateCombinationCondition(children, operation, conditionResults));
+
+ children.clear();
+ conditionResults.clear();
+ EXPECT_EQ(evaluateCombinationCondition(children, operation, conditionResults),
+ ConditionState::kUnknown);
}
TEST(ConditionTrackerTest, TestNandCondition) {
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 2fda858..9471faa 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -66,7 +66,8 @@
// statsd started long ago.
// The metric starts in the middle of the bucket
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- -1, 5, 600 * NS_PER_SEC + NS_PER_SEC/2, pullerManager);
+ -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
+ pullerManager);
EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
@@ -100,8 +101,8 @@
}));
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+ tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -176,10 +177,9 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- -1 /* -1 means no pulling */, bucketStartTimeNs,
+ -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
sp<AnomalyTracker> anomalyTracker = gaugeProducer.addAnomalyTracker(alert, alarmMonitor);
EXPECT_TRUE(anomalyTracker != nullptr);
@@ -261,8 +261,8 @@
}));
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+ tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
vector<shared_ptr<LogEvent>> allData;
shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
@@ -328,9 +328,8 @@
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, -1, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
@@ -419,9 +418,8 @@
return true;
}));
- GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, -1, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
@@ -464,8 +462,8 @@
gaugeFieldMatcher->set_field(tagId);
gaugeFieldMatcher->add_child()->set_field(2);
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+ tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
Alert alert;
alert.set_id(101);
@@ -530,6 +528,83 @@
EXPECT_TRUE(gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->empty());
}
+TEST(GaugeMetricProducerTest, TestPullOnTrigger) {
+ GaugeMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.set_sampling_type(GaugeMetric::ALL_CONDITION_CHANGES);
+ metric.mutable_gauge_fields_filter()->set_include_all(false);
+ auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
+ gaugeFieldMatcher->set_field(tagId);
+ gaugeFieldMatcher->add_child()->set_field(1);
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 3);
+ event->write(3);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event->write(4);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
+ event->write(5);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ int triggerId = 5;
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ LogEvent trigger(triggerId, bucketStartTimeNs + 10);
+ trigger.init();
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
+ EXPECT_EQ(2UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+ trigger.setElapsedTimestampNs(bucketStartTimeNs + 20);
+ gaugeProducer.onMatchedLogEvent(1 /*log matcher index*/, trigger);
+ EXPECT_EQ(3UL, gaugeProducer.mCurrentSlicedBucket->begin()->second.size());
+
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event->write(10);
+ event->init();
+ allData.push_back(event);
+
+ gaugeProducer.onDataPulled(allData);
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ auto it = gaugeProducer.mCurrentSlicedBucket->begin()->second.front().mFields->begin();
+ EXPECT_EQ(INT, it->mValue.getType());
+ EXPECT_EQ(10, it->mValue.int_value);
+ EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ EXPECT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.size());
+ EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms[0].mFields->begin()->mValue.int_value);
+ EXPECT_EQ(4, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms[1].mFields->begin()->mValue.int_value);
+ EXPECT_EQ(5, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms[2].mFields->begin()->mValue.int_value);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index c30f2f5..bc4ed15 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,23 +1,5 @@
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;-><init>()V
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accessibilityservice/IAccessibilityServiceConnection;
-Landroid/accounts/Account;->accessId:Ljava/lang/String;
-Landroid/accounts/Account;->TAG:Ljava/lang/String;
-Landroid/accounts/AccountAndUser;-><init>(Landroid/accounts/Account;I)V
-Landroid/accounts/AccountAndUser;->account:Landroid/accounts/Account;
-Landroid/accounts/AccountAndUser;->userId:I
-Landroid/accounts/AccountAuthenticatorResponse;-><init>(Landroid/accounts/IAccountAuthenticatorResponse;)V
-Landroid/accounts/AccountManager$AmsTask;->mActivity:Landroid/app/Activity;
-Landroid/accounts/AccountManager$AmsTask;->mHandler:Landroid/os/Handler;
-Landroid/accounts/AccountManager$AmsTask;->mResponse:Landroid/accounts/IAccountManagerResponse;
-Landroid/accounts/AccountManager$GetAuthTokenByTypeAndFeaturesTask;->mAuthTokenType:Ljava/lang/String;
-Landroid/accounts/AccountManager$GetAuthTokenByTypeAndFeaturesTask;->mLoginOptions:Landroid/os/Bundle;
-Landroid/accounts/AccountManager$GetAuthTokenByTypeAndFeaturesTask;->mMyCallback:Landroid/accounts/AccountManagerCallback;
-Landroid/accounts/AccountManager;-><init>(Landroid/content/Context;Landroid/accounts/IAccountManager;)V
-Landroid/accounts/AccountManager;->confirmCredentialsAsUser(Landroid/accounts/Account;Landroid/os/Bundle;Landroid/app/Activity;Landroid/accounts/AccountManagerCallback;Landroid/os/Handler;Landroid/os/UserHandle;)Landroid/accounts/AccountManagerFuture;
-Landroid/accounts/AccountManager;->getAccountsByTypeAsUser(Ljava/lang/String;Landroid/os/UserHandle;)[Landroid/accounts/Account;
-Landroid/accounts/AccountManager;->mContext:Landroid/content/Context;
-Landroid/accounts/AuthenticatorDescription;-><init>(Landroid/os/Parcel;)V
-Landroid/accounts/AuthenticatorDescription;-><init>(Ljava/lang/String;)V
Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/accounts/IAccountAuthenticator$Stub;-><init>()V
@@ -982,22 +964,6 @@
Landroid/app/WallpaperManager;->setBitmap(Landroid/graphics/Bitmap;Landroid/graphics/Rect;ZII)I
Landroid/app/WallpaperManager;->setWallpaperComponent(Landroid/content/ComponentName;I)Z
Landroid/app/WallpaperManager;->sGlobals:Landroid/app/WallpaperManager$Globals;
-Landroid/appwidget/AppWidgetHost;-><init>(Landroid/content/Context;ILandroid/widget/RemoteViews$OnClickHandler;Landroid/os/Looper;)V
-Landroid/appwidget/AppWidgetHost;->HANDLE_VIEW_DATA_CHANGED:I
-Landroid/appwidget/AppWidgetHost;->mHandler:Landroid/os/Handler;
-Landroid/appwidget/AppWidgetHost;->sService:Lcom/android/internal/appwidget/IAppWidgetService;
-Landroid/appwidget/AppWidgetHostView;->getDefaultPaddingForWidget(Landroid/content/Context;Landroid/content/pm/ApplicationInfo;Landroid/graphics/Rect;)Landroid/graphics/Rect;
-Landroid/appwidget/AppWidgetHostView;->mAppWidgetId:I
-Landroid/appwidget/AppWidgetHostView;->mInfo:Landroid/appwidget/AppWidgetProviderInfo;
-Landroid/appwidget/AppWidgetHostView;->updateAppWidgetSize(Landroid/os/Bundle;IIIIZ)V
-Landroid/appwidget/AppWidgetManager;->bindAppWidgetId(ILandroid/content/ComponentName;)V
-Landroid/appwidget/AppWidgetManager;->bindAppWidgetId(ILandroid/content/ComponentName;Landroid/os/Bundle;)V
-Landroid/appwidget/AppWidgetManager;->bindAppWidgetIdIfAllowed(IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
-Landroid/appwidget/AppWidgetManager;->bindRemoteViewsService(Landroid/content/Context;ILandroid/content/Intent;Landroid/app/IServiceConnection;I)Z
-Landroid/appwidget/AppWidgetManager;->getInstalledProviders(I)Ljava/util/List;
-Landroid/appwidget/AppWidgetManager;->getInstalledProvidersForProfile(ILandroid/os/UserHandle;Ljava/lang/String;)Ljava/util/List;
-Landroid/appwidget/AppWidgetManager;->mService:Lcom/android/internal/appwidget/IAppWidgetService;
-Landroid/appwidget/AppWidgetProviderInfo;->providerInfo:Landroid/content/pm/ActivityInfo;
Landroid/bluetooth/IBluetooth$Stub$Proxy;->getAddress()Ljava/lang/String;
Landroid/bluetooth/IBluetooth$Stub$Proxy;->getConnectionState(Landroid/bluetooth/BluetoothDevice;)I
Landroid/bluetooth/IBluetooth$Stub;-><init>()V
@@ -1823,242 +1789,19 @@
Landroid/database/sqlite/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_VENDOR_BASE:I
Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_VENDOR_BASE:I
-Landroid/hardware/Camera$Parameters;->copyFrom(Landroid/hardware/Camera$Parameters;)V
-Landroid/hardware/Camera$Parameters;->dump()V
-Landroid/hardware/Camera$Parameters;->splitArea(Ljava/lang/String;)Ljava/util/ArrayList;
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
-Landroid/hardware/camera2/CameraCharacteristics$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
-Landroid/hardware/camera2/CameraCharacteristics$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->CONTROL_MAX_REGIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->LED_AVAILABLE_LEDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->LENS_INFO_SHADING_MAP_SIZE:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->LOGICAL_MULTI_CAMERA_PHYSICAL_IDS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->mProperties:Landroid/hardware/camera2/impl/CameraMetadataNative;
-Landroid/hardware/camera2/CameraCharacteristics;->QUIRKS_USE_PARTIAL_RESULT:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_CHARACTERISTICS_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_REQUEST_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_RESULT_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_AVAILABLE_SESSION_KEYS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->REQUEST_MAX_NUM_OUTPUT_STREAMS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_FORMATS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_JPEG_MIN_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_JPEG_SIZES:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_MIN_FRAME_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_PROCESSED_SIZES:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_STALL_DURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CameraCharacteristics;->SCALER_AVAILABLE_STREAM_CONFIGURATIONS:Landroid/hardware/camera2/CameraCharacteristics$Key;
-Landroid/hardware/camera2/CaptureRequest$Builder;->setPartOfCHSRequestList(Z)V
-Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
-Landroid/hardware/camera2/CaptureRequest$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CaptureRequest;->getTargets()Ljava/util/Collection;
-Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_COORDINATES:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_PROCESSING_METHOD:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->JPEG_GPS_TIMESTAMP:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->LED_TRANSMIT:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->mLogicalCameraSettings:Landroid/hardware/camera2/impl/CameraMetadataNative;
-Landroid/hardware/camera2/CaptureRequest;->REQUEST_ID:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_BLUE:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_GREEN:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureRequest;->TONEMAP_CURVE_RED:Landroid/hardware/camera2/CaptureRequest$Key;
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Landroid/hardware/camera2/utils/TypeReference;)V
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
-Landroid/hardware/camera2/CaptureResult$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;J)V
-Landroid/hardware/camera2/CaptureResult$Key;->getNativeKey()Landroid/hardware/camera2/impl/CameraMetadataNative$Key;
-Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_COORDINATES:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_PROCESSING_METHOD:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->JPEG_GPS_TIMESTAMP:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->LED_TRANSMIT:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->mResults:Landroid/hardware/camera2/impl/CameraMetadataNative;
-Landroid/hardware/camera2/CaptureResult;->QUIRKS_PARTIAL_RESULT:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->REQUEST_FRAME_COUNT:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->REQUEST_ID:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_FACE_IDS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_FACE_LANDMARKS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_FACE_RECTANGLES:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_FACE_SCORES:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_LENS_SHADING_MAP:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_TIMESTAMPS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_X_SHIFTS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_OIS_Y_SHIFTS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_PREDICTED_COLOR_GAINS:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->STATISTICS_PREDICTED_COLOR_TRANSFORM:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->SYNC_FRAME_NUMBER:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->TONEMAP_CURVE_BLUE:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->TONEMAP_CURVE_GREEN:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/CaptureResult;->TONEMAP_CURVE_RED:Landroid/hardware/camera2/CaptureResult$Key;
-Landroid/hardware/camera2/impl/CameraMetadataNative$Key;->getTag()I
-Landroid/hardware/camera2/impl/CameraMetadataNative;->mMetadataPtr:J
-Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeGetTagFromKeyLocal(Ljava/lang/String;)I
-Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeGetTypeFromTagLocal(I)I
-Landroid/hardware/camera2/impl/CameraMetadataNative;->nativeReadValues(I)[B
-Landroid/hardware/camera2/utils/SurfaceUtils;->getSurfaceSize(Landroid/view/Surface;)Landroid/util/Size;
-Landroid/hardware/camera2/utils/TypeReference;-><init>()V
-Landroid/hardware/camera2/utils/TypeReference;->createSpecializedTypeReference(Ljava/lang/reflect/Type;)Landroid/hardware/camera2/utils/TypeReference;
-Landroid/hardware/Camera;->addCallbackBuffer([BI)V
-Landroid/hardware/Camera;->addRawImageCallbackBuffer([B)V
-Landroid/hardware/Camera;->CAMERA_HAL_API_VERSION_1_0:I
-Landroid/hardware/Camera;->getEmptyParameters()Landroid/hardware/Camera$Parameters;
-Landroid/hardware/Camera;->mNativeContext:J
-Landroid/hardware/Camera;->native_getParameters()Ljava/lang/String;
-Landroid/hardware/Camera;->native_setParameters(Ljava/lang/String;)V
-Landroid/hardware/Camera;->native_setup(Ljava/lang/Object;IILjava/lang/String;)I
-Landroid/hardware/Camera;->openLegacy(II)Landroid/hardware/Camera;
-Landroid/hardware/Camera;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
-Landroid/hardware/Camera;->previewEnabled()Z
-Landroid/hardware/Camera;->setPreviewSurface(Landroid/view/Surface;)V
-Landroid/hardware/display/DisplayManager;->ACTION_WIFI_DISPLAY_STATUS_CHANGED:Ljava/lang/String;
-Landroid/hardware/display/DisplayManager;->connectWifiDisplay(Ljava/lang/String;)V
-Landroid/hardware/display/DisplayManager;->disconnectWifiDisplay()V
-Landroid/hardware/display/DisplayManager;->EXTRA_WIFI_DISPLAY_STATUS:Ljava/lang/String;
-Landroid/hardware/display/DisplayManager;->forgetWifiDisplay(Ljava/lang/String;)V
-Landroid/hardware/display/DisplayManager;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
-Landroid/hardware/display/DisplayManager;->pauseWifiDisplay()V
-Landroid/hardware/display/DisplayManager;->renameWifiDisplay(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/hardware/display/DisplayManager;->resumeWifiDisplay()V
-Landroid/hardware/display/DisplayManager;->startWifiDisplayScan()V
-Landroid/hardware/display/DisplayManager;->stopWifiDisplayScan()V
-Landroid/hardware/display/DisplayManagerGlobal;->disconnectWifiDisplay()V
-Landroid/hardware/display/DisplayManagerGlobal;->getDisplayIds()[I
-Landroid/hardware/display/DisplayManagerGlobal;->getDisplayInfo(I)Landroid/view/DisplayInfo;
-Landroid/hardware/display/DisplayManagerGlobal;->getWifiDisplayStatus()Landroid/hardware/display/WifiDisplayStatus;
-Landroid/hardware/display/DisplayManagerGlobal;->mDm:Landroid/hardware/display/IDisplayManager;
-Landroid/hardware/display/DisplayManagerGlobal;->sInstance:Landroid/hardware/display/DisplayManagerGlobal;
Landroid/hardware/display/IDisplayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/display/IDisplayManager;
Landroid/hardware/display/IDisplayManager;->getDisplayInfo(I)Landroid/view/DisplayInfo;
-Landroid/hardware/display/WifiDisplay;->canConnect()Z
-Landroid/hardware/display/WifiDisplay;->equals(Landroid/hardware/display/WifiDisplay;)Z
-Landroid/hardware/display/WifiDisplay;->getDeviceAddress()Ljava/lang/String;
-Landroid/hardware/display/WifiDisplay;->getDeviceAlias()Ljava/lang/String;
-Landroid/hardware/display/WifiDisplay;->getDeviceName()Ljava/lang/String;
-Landroid/hardware/display/WifiDisplay;->isAvailable()Z
-Landroid/hardware/display/WifiDisplay;->isRemembered()Z
-Landroid/hardware/display/WifiDisplayStatus;->DISPLAY_STATE_CONNECTED:I
-Landroid/hardware/display/WifiDisplayStatus;->DISPLAY_STATE_CONNECTING:I
-Landroid/hardware/display/WifiDisplayStatus;->DISPLAY_STATE_NOT_CONNECTED:I
-Landroid/hardware/display/WifiDisplayStatus;->FEATURE_STATE_ON:I
-Landroid/hardware/display/WifiDisplayStatus;->getActiveDisplay()Landroid/hardware/display/WifiDisplay;
-Landroid/hardware/display/WifiDisplayStatus;->getActiveDisplayState()I
-Landroid/hardware/display/WifiDisplayStatus;->getDisplays()[Landroid/hardware/display/WifiDisplay;
-Landroid/hardware/display/WifiDisplayStatus;->getFeatureState()I
-Landroid/hardware/display/WifiDisplayStatus;->getScanState()I
-Landroid/hardware/display/WifiDisplayStatus;->mActiveDisplay:Landroid/hardware/display/WifiDisplay;
-Landroid/hardware/display/WifiDisplayStatus;->mDisplays:[Landroid/hardware/display/WifiDisplay;
-Landroid/hardware/display/WifiDisplayStatus;->SCAN_STATE_NOT_SCANNING:I
-Landroid/hardware/fingerprint/FingerprintManager$AuthenticationResult;->getFingerprint()Landroid/hardware/fingerprint/Fingerprint;
-Landroid/hardware/fingerprint/FingerprintManager;->getAuthenticatorId()J
-Landroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints()Ljava/util/List;
-Landroid/hardware/fingerprint/FingerprintManager;->getEnrolledFingerprints(I)Ljava/util/List;
Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/fingerprint/IFingerprintService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/fingerprint/IFingerprintService;
-Landroid/hardware/HardwareBuffer;-><init>(J)V
-Landroid/hardware/HardwareBuffer;->mNativeObject:J
Landroid/hardware/ICameraService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/ICameraService;
Landroid/hardware/input/IInputManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
Landroid/hardware/input/IInputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
-Landroid/hardware/input/InputManager;->createInputForwarder(I)Landroid/app/IInputForwarder;
-Landroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager;
-Landroid/hardware/input/InputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
-Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I
-Landroid/hardware/input/InputManager;->mIm:Landroid/hardware/input/IInputManager;
-Landroid/hardware/input/InputManager;->setPointerIconType(I)V
Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V
Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService;
-Landroid/hardware/Sensor;->getHandle()I
-Landroid/hardware/Sensor;->mFlags:I
-Landroid/hardware/Sensor;->TYPE_DEVICE_ORIENTATION:I
-Landroid/hardware/Sensor;->TYPE_PICK_UP_GESTURE:I
-Landroid/hardware/SensorEvent;-><init>(I)V
-Landroid/hardware/SensorManager;-><init>()V
-Landroid/hardware/SerialManager;->getSerialPorts()[Ljava/lang/String;
-Landroid/hardware/SerialManager;->openSerialPort(Ljava/lang/String;I)Landroid/hardware/SerialPort;
-Landroid/hardware/SerialPort;->close()V
-Landroid/hardware/SerialPort;->mNativeContext:I
-Landroid/hardware/SerialPort;->write(Ljava/nio/ByteBuffer;I)V
-Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;-><init>(II)V
-Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->confidenceLevel:I
-Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;->userId:I
-Landroid/hardware/soundtrigger/SoundTrigger$GenericRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$GenericSoundModel;-><init>(Ljava/util/UUID;Ljava/util/UUID;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;-><init>(IILjava/lang/String;Ljava/lang/String;[I)V
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->id:I
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->locale:Ljava/lang/String;
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->recognitionModes:I
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->text:Ljava/lang/String;
-Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;->users:[I
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;)V
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionEvent;->keyphraseExtras:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;-><init>(III[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;)V
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->coarseConfidenceLevel:I
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->confidenceLevels:[Landroid/hardware/soundtrigger/SoundTrigger$ConfidenceLevel;
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->id:I
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;->recognitionModes:I
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;-><init>(Ljava/util/UUID;Ljava/util/UUID;[B[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;)V
-Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$Keyphrase;
-Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;-><init>(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIZIZIZ)V
-Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;->id:I
-Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;->maxSoundModels:I
-Landroid/hardware/soundtrigger/SoundTrigger$ModuleProperties;->uuid:Ljava/util/UUID;
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;-><init>(ZZ[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->captureRequested:Z
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->data:[B
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->captureAvailable:Z
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->captureSession:I
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->data:[B
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->soundModelHandle:I
-Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->status:I
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->vendorUuid:Ljava/util/UUID;
-Landroid/hardware/soundtrigger/SoundTrigger$SoundModelEvent;-><init>(II[B)V
-Landroid/hardware/soundtrigger/SoundTrigger;->attachModule(ILandroid/hardware/soundtrigger/SoundTrigger$StatusListener;Landroid/os/Handler;)Landroid/hardware/soundtrigger/SoundTriggerModule;
-Landroid/hardware/soundtrigger/SoundTrigger;->listModules(Ljava/util/ArrayList;)I
-Landroid/hardware/soundtrigger/SoundTriggerModule;->detach()V
-Landroid/hardware/soundtrigger/SoundTriggerModule;->loadSoundModel(Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;[I)I
-Landroid/hardware/soundtrigger/SoundTriggerModule;->mId:I
-Landroid/hardware/soundtrigger/SoundTriggerModule;->mNativeContext:J
-Landroid/hardware/soundtrigger/SoundTriggerModule;->postEventFromNative(Ljava/lang/Object;IIILjava/lang/Object;)V
-Landroid/hardware/soundtrigger/SoundTriggerModule;->startRecognition(ILandroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;)I
-Landroid/hardware/soundtrigger/SoundTriggerModule;->stopRecognition(I)I
-Landroid/hardware/soundtrigger/SoundTriggerModule;->unloadSoundModel(I)I
-Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchAdditionalInfoEvent(III[F[I)V
-Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchFlushCompleteEvent(I)V
-Landroid/hardware/SystemSensorManager$BaseEventQueue;->dispatchSensorEvent(I[FIJ)V
Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
-Landroid/hardware/usb/UsbDevice;->mInterfaces:[Landroid/hardware/usb/UsbInterface;
-Landroid/hardware/usb/UsbDeviceConnection;->mNativeContext:J
-Landroid/hardware/usb/UsbManager;-><init>(Landroid/content/Context;Landroid/hardware/usb/IUsbManager;)V
-Landroid/hardware/usb/UsbManager;->ACTION_USB_STATE:Ljava/lang/String;
-Landroid/hardware/usb/UsbManager;->getPorts()[Landroid/hardware/usb/UsbPort;
-Landroid/hardware/usb/UsbManager;->getPortStatus(Landroid/hardware/usb/UsbPort;)Landroid/hardware/usb/UsbPortStatus;
-Landroid/hardware/usb/UsbManager;->isFunctionEnabled(Ljava/lang/String;)Z
-Landroid/hardware/usb/UsbManager;->setCurrentFunction(Ljava/lang/String;Z)V
-Landroid/hardware/usb/UsbManager;->setPortRoles(Landroid/hardware/usb/UsbPort;II)V
-Landroid/hardware/usb/UsbManager;->USB_CONNECTED:Ljava/lang/String;
-Landroid/hardware/usb/UsbManager;->USB_DATA_UNLOCKED:Ljava/lang/String;
-Landroid/hardware/usb/UsbManager;->USB_FUNCTION_NONE:Ljava/lang/String;
-Landroid/hardware/usb/UsbPortStatus;->getCurrentDataRole()I
-Landroid/hardware/usb/UsbPortStatus;->getCurrentMode()I
-Landroid/hardware/usb/UsbPortStatus;->getCurrentPowerRole()I
-Landroid/hardware/usb/UsbPortStatus;->getSupportedRoleCombinations()I
-Landroid/hardware/usb/UsbPortStatus;->isConnected()Z
-Landroid/hardware/usb/UsbPortStatus;->isRoleCombinationSupported(II)Z
-Landroid/hardware/usb/UsbRequest;->mBuffer:Ljava/nio/ByteBuffer;
-Landroid/hardware/usb/UsbRequest;->mLength:I
-Landroid/hardware/usb/UsbRequest;->mNativeContext:J
Landroid/icu/impl/CurrencyData;-><init>()V
Landroid/icu/text/ArabicShaping;-><init>(I)V
Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z
@@ -2090,18 +1833,6 @@
Landroid/icu/util/UResourceBundle;->getType()I
Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
-Landroid/location/Country;-><init>(Ljava/lang/String;I)V
-Landroid/location/Country;->getCountryIso()Ljava/lang/String;
-Landroid/location/Country;->getSource()I
-Landroid/location/CountryDetector;-><init>(Landroid/location/ICountryDetector;)V
-Landroid/location/CountryDetector;->addCountryListener(Landroid/location/CountryListener;Landroid/os/Looper;)V
-Landroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
-Landroid/location/CountryDetector;->removeCountryListener(Landroid/location/CountryListener;)V
-Landroid/location/CountryListener;->onCountryDetected(Landroid/location/Country;)V
-Landroid/location/GeocoderParams;->getClientPackage()Ljava/lang/String;
-Landroid/location/GeocoderParams;->getLocale()Ljava/util/Locale;
-Landroid/location/Geofence;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/location/GpsStatus;->setTimeToFirstFix(I)V
Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
Landroid/location/ICountryListener$Stub;-><init>()V
Landroid/location/IGeocodeProvider$Stub;-><init>()V
@@ -2120,25 +1851,6 @@
Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
-Landroid/location/Location;->mElapsedRealtimeNanos:J
-Landroid/location/Location;->mProvider:Ljava/lang/String;
-Landroid/location/LocationManager;->mService:Landroid/location/ILocationManager;
-Landroid/location/LocationManager;->requestLocationUpdates(Landroid/location/LocationRequest;Landroid/location/LocationListener;Landroid/os/Looper;Landroid/app/PendingIntent;)V
-Landroid/location/LocationManager;->sendNiResponse(II)Z
-Landroid/location/LocationRequest;->checkDisplacement(F)V
-Landroid/location/LocationRequest;->checkInterval(J)V
-Landroid/location/LocationRequest;->checkProvider(Ljava/lang/String;)V
-Landroid/location/LocationRequest;->checkQuality(I)V
-Landroid/location/LocationRequest;->mExpireAt:J
-Landroid/location/LocationRequest;->mExplicitFastestInterval:Z
-Landroid/location/LocationRequest;->mFastestInterval:J
-Landroid/location/LocationRequest;->mHideFromAppOps:Z
-Landroid/location/LocationRequest;->mInterval:J
-Landroid/location/LocationRequest;->mNumUpdates:I
-Landroid/location/LocationRequest;->mProvider:Ljava/lang/String;
-Landroid/location/LocationRequest;->mQuality:I
-Landroid/location/LocationRequest;->mSmallestDisplacement:F
-Landroid/location/LocationRequest;->mWorkSource:Landroid/os/WorkSource;
Landroid/media/AmrInputStream;-><init>(Ljava/io/InputStream;)V
Landroid/media/AsyncPlayer;->setUsesWakeLock(Landroid/content/Context;)V
Landroid/media/AudioAttributes$Builder;->addTag(Ljava/lang/String;)Landroid/media/AudioAttributes$Builder;
@@ -2607,10 +2319,6 @@
Landroid/media/VolumeShaper$State;->mVolume:F
Landroid/media/VolumeShaper$State;->mXOffset:F
Landroid/media/WebVttRenderer;-><init>(Landroid/content/Context;)V
-Landroid/mtp/MtpPropertyList;->append(IIIJ)V
-Landroid/mtp/MtpPropertyList;->append(IILjava/lang/String;)V
-Landroid/mtp/MtpStorage;->getPath()Ljava/lang/String;
-Landroid/mtp/MtpStorage;->getStorageId()I
Landroid/net/ConnectivityManager;->ACTION_TETHER_STATE_CHANGED:Ljava/lang/String;
Landroid/net/ConnectivityManager;->EXTRA_ACTIVE_TETHER:Ljava/lang/String;
Landroid/net/ConnectivityManager;->EXTRA_AVAILABLE_TETHER:Ljava/lang/String;
@@ -3088,13 +2796,6 @@
Landroid/nfc/INfcAdapterExtras;->open(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
Landroid/nfc/INfcAdapterExtras;->setCardEmulationRoute(Ljava/lang/String;I)V
Landroid/nfc/INfcAdapterExtras;->transceive(Ljava/lang/String;[B)Landroid/os/Bundle;
-Landroid/opengl/EGL14;->eglGetDisplay(J)Landroid/opengl/EGLDisplay;
-Landroid/opengl/GLES20;->glGetActiveAttrib(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
-Landroid/opengl/GLES20;->glGetActiveUniform(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
-Landroid/opengl/GLSurfaceView$EglHelper;->mEglContext:Ljavax/microedition/khronos/egl/EGLContext;
-Landroid/opengl/GLSurfaceView$GLThread;->mEglHelper:Landroid/opengl/GLSurfaceView$EglHelper;
-Landroid/opengl/GLSurfaceView;->mGLThread:Landroid/opengl/GLSurfaceView$GLThread;
-Landroid/opengl/GLSurfaceView;->mRenderer:Landroid/opengl/GLSurfaceView$Renderer;
Landroid/os/AsyncResult;->forMessage(Landroid/os/Message;)Landroid/os/AsyncResult;
Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask;
Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status;
@@ -5474,7 +5175,6 @@
Landroid/view/View;->findViewByAccessibilityId(I)Landroid/view/View;
Landroid/view/View;->fitsSystemWindows()Z
Landroid/view/View;->gatherTransparentRegion(Landroid/graphics/Region;)Z
-Landroid/view/View;->getAccessibilityDelegate()Landroid/view/View$AccessibilityDelegate;
Landroid/view/View;->getAccessibilityViewId()I
Landroid/view/View;->getBoundsOnScreen(Landroid/graphics/Rect;)V
Landroid/view/View;->getBoundsOnScreen(Landroid/graphics/Rect;Z)V
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 0353e65..2808166 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -1,4 +1,3 @@
-Landroid/accounts/AccountManager;-><init>(Landroid/content/Context;Landroid/accounts/IAccountManager;Landroid/os/Handler;)V
Landroid/app/Activity;->managedQuery(Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
Landroid/app/Activity;->registerRemoteAnimations(Landroid/view/RemoteAnimationDefinition;)V
Landroid/app/ActivityManager$TaskDescription;->loadTaskDescriptionIcon(Ljava/lang/String;I)Landroid/graphics/Bitmap;
@@ -56,15 +55,6 @@
Landroid/app/TaskStackListener;->onTaskStackChanged()V
Landroid/app/WallpaperColors;-><init>(Landroid/graphics/Color;Landroid/graphics/Color;Landroid/graphics/Color;I)V
Landroid/bluetooth/IBluetooth;->sendConnectionStateChange(Landroid/bluetooth/BluetoothDevice;III)V
-Landroid/companion/AssociationRequest;->getDeviceFilters()Ljava/util/List;
-Landroid/companion/AssociationRequest;->isSingleDevice()Z
-Landroid/companion/BluetoothDeviceFilter;->getAddress()Ljava/lang/String;
-Landroid/companion/BluetoothDeviceFilterUtils;->getDeviceDisplayNameInternal(Landroid/bluetooth/BluetoothDevice;)Ljava/lang/String;
-Landroid/companion/BluetoothDeviceFilterUtils;->getDeviceDisplayNameInternal(Landroid/net/wifi/ScanResult;)Ljava/lang/String;
-Landroid/companion/BluetoothDeviceFilterUtils;->getDeviceMacAddress(Landroid/os/Parcelable;)Ljava/lang/String;
-Landroid/companion/BluetoothLeDeviceFilter;->getScanFilter()Landroid/bluetooth/le/ScanFilter;
-Landroid/companion/DeviceFilter;->getDeviceDisplayName(Landroid/os/Parcelable;)Ljava/lang/String;
-Landroid/companion/DeviceFilter;->matches(Landroid/os/Parcelable;)Z
Landroid/companion/ICompanionDeviceDiscoveryService$Stub;-><init>()V
Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelected(Ljava/lang/String;ILjava/lang/String;)V
Landroid/companion/ICompanionDeviceDiscoveryServiceCallback;->onDeviceSelectionCancel()V
@@ -92,10 +82,6 @@
Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
Landroid/database/sqlite/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
Landroid/database/sqlite/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
-Landroid/hardware/display/DisplayManagerGlobal;->getInstance()Landroid/hardware/display/DisplayManagerGlobal;
-Landroid/hardware/display/DisplayManagerGlobal;->getRealDisplay(I)Landroid/view/Display;
-Landroid/hardware/location/GeofenceHardware;-><init>(Landroid/hardware/location/IGeofenceHardware;)V
Landroid/hardware/location/IActivityRecognitionHardwareClient;->onAvailabilityChanged(ZLandroid/hardware/location/IActivityRecognitionHardware;)V
Landroid/location/IGeocodeProvider;->getFromLocation(DDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
Landroid/location/IGeocodeProvider;->getFromLocationName(Ljava/lang/String;DDDDILandroid/location/GeocoderParams;Ljava/util/List;)Ljava/lang/String;
@@ -104,7 +90,6 @@
Landroid/location/ILocationManager;->reportLocation(Landroid/location/Location;Z)V
Landroid/location/INetInitiatedListener$Stub;-><init>()V
Landroid/location/INetInitiatedListener;->sendNiResponse(II)Z
-Landroid/location/Location;->setExtraLocation(Ljava/lang/String;Landroid/location/Location;)V
Landroid/media/AudioManager;->registerAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
Landroid/media/AudioManager;->unregisterAudioPortUpdateListener(Landroid/media/AudioManager$OnAudioPortUpdateListener;)V
Landroid/media/AudioSystem;->checkAudioFlinger()I
diff --git a/core/java/android/accounts/Account.java b/core/java/android/accounts/Account.java
index b6e85f1..f07f5ec 100644
--- a/core/java/android/accounts/Account.java
+++ b/core/java/android/accounts/Account.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Parcelable;
import android.os.Parcel;
@@ -36,6 +37,7 @@
* suitable for use as the key of a {@link java.util.Map}
*/
public class Account implements Parcelable {
+ @UnsupportedAppUsage
private static final String TAG = "Account";
@GuardedBy("sAccessedAccounts")
@@ -43,6 +45,7 @@
public final String name;
public final String type;
+ @UnsupportedAppUsage
private final @Nullable String accessId;
public boolean equals(Object o) {
diff --git a/core/java/android/accounts/AccountAndUser.java b/core/java/android/accounts/AccountAndUser.java
index 04157cc..b0d5343 100644
--- a/core/java/android/accounts/AccountAndUser.java
+++ b/core/java/android/accounts/AccountAndUser.java
@@ -16,15 +16,20 @@
package android.accounts;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Used to store the Account and the UserId this account is associated with.
*
* @hide
*/
public class AccountAndUser {
+ @UnsupportedAppUsage
public Account account;
+ @UnsupportedAppUsage
public int userId;
+ @UnsupportedAppUsage
public AccountAndUser(Account account, int userId) {
this.account = account;
this.userId = userId;
diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java
index 41f26ac..bcc9f90 100644
--- a/core/java/android/accounts/AccountAuthenticatorResponse.java
+++ b/core/java/android/accounts/AccountAuthenticatorResponse.java
@@ -16,6 +16,7 @@
package android.accounts;
+import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Parcel;
@@ -33,6 +34,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) {
mAccountAuthenticatorResponse = response;
}
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index 5176d71e..3189d08 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -27,6 +27,7 @@
import android.annotation.SystemService;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.BroadcastBehavior;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -336,6 +337,7 @@
public static final String ACCOUNT_ACCESS_TOKEN_TYPE =
"com.android.AccountManager.ACCOUNT_ACCESS_TOKEN_TYPE";
+ @UnsupportedAppUsage
private final Context mContext;
private final IAccountManager mService;
private final Handler mMainHandler;
@@ -409,6 +411,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public AccountManager(Context context, IAccountManager service) {
mContext = context;
mService = service;
@@ -418,6 +421,7 @@
/**
* @hide used for testing only
*/
+ @UnsupportedAppUsage
public AccountManager(Context context, IAccountManager service, Handler handler) {
mContext = context;
mService = service;
@@ -685,6 +689,7 @@
/** @hide Same as {@link #getAccountsByType(String)} but for a specific user. */
@NonNull
+ @UnsupportedAppUsage
public Account[] getAccountsByTypeAsUser(String type, UserHandle userHandle) {
try {
return mService.getAccountsAsUser(type, userHandle.getIdentifier(),
@@ -2014,6 +2019,7 @@
* Same as {@link #confirmCredentials(Account, Bundle, Activity, AccountManagerCallback, Handler)}
* but for the specified user.
*/
+ @UnsupportedAppUsage
public AccountManagerFuture<Bundle> confirmCredentialsAsUser(final Account account,
final Bundle options,
final Activity activity,
@@ -2225,9 +2231,12 @@
}
private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
+ @UnsupportedAppUsage
final IAccountManagerResponse mResponse;
+ @UnsupportedAppUsage
final Handler mHandler;
final AccountManagerCallback<Bundle> mCallback;
+ @UnsupportedAppUsage
final Activity mActivity;
public AmsTask(Activity activity, Handler handler, AccountManagerCallback<Bundle> callback) {
super(new Callable<Bundle>() {
@@ -2552,10 +2561,13 @@
}
volatile AccountManagerFuture<Bundle> mFuture = null;
final String mAccountType;
+ @UnsupportedAppUsage
final String mAuthTokenType;
final String[] mFeatures;
final Bundle mAddAccountOptions;
+ @UnsupportedAppUsage
final Bundle mLoginOptions;
+ @UnsupportedAppUsage
final AccountManagerCallback<Bundle> mMyCallback;
private volatile int mNumAccounts = 0;
diff --git a/core/java/android/accounts/AuthenticatorDescription.java b/core/java/android/accounts/AuthenticatorDescription.java
index 5d9abb0..6875867 100644
--- a/core/java/android/accounts/AuthenticatorDescription.java
+++ b/core/java/android/accounts/AuthenticatorDescription.java
@@ -16,6 +16,7 @@
package android.accounts;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcelable;
import android.os.Parcel;
@@ -76,6 +77,7 @@
return new AuthenticatorDescription(type);
}
+ @UnsupportedAppUsage
private AuthenticatorDescription(String type) {
this.type = type;
this.packageName = null;
@@ -86,6 +88,7 @@
this.customTokens = false;
}
+ @UnsupportedAppUsage
private AuthenticatorDescription(Parcel source) {
this.type = source.readString();
this.packageName = source.readString();
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index cbd8741..dfdb7eb 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -7722,6 +7722,9 @@
* LockTask mode will be registered, but will only take effect when the device leaves LockTask
* mode.
*
+ * <p>This policy does not have any effect while on the lock screen, where the status bar will
+ * not be disabled. Using LockTask instead of this method is recommended.
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param disabled {@code true} disables the status bar, {@code false} reenables it.
* @return {@code false} if attempting to disable the status bar failed. {@code true} otherwise.
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 49cc498..f003d4b 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Context;
@@ -53,14 +54,17 @@
static final int HANDLE_UPDATE = 1;
static final int HANDLE_PROVIDER_CHANGED = 2;
static final int HANDLE_PROVIDERS_CHANGED = 3;
+ @UnsupportedAppUsage
static final int HANDLE_VIEW_DATA_CHANGED = 4;
final static Object sServiceLock = new Object();
+ @UnsupportedAppUsage
static IAppWidgetService sService;
static boolean sServiceInitialized = false;
private DisplayMetrics mDisplayMetrics;
private String mContextOpPackageName;
+ @UnsupportedAppUsage
private final Handler mHandler;
private final int mHostId;
private final Callbacks mCallbacks;
@@ -156,6 +160,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public AppWidgetHost(Context context, int hostId, OnClickHandler handler, Looper looper) {
mContextOpPackageName = context.getOpPackageName();
mHostId = hostId;
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index ab0eb92..a9187b6 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -16,6 +16,7 @@
package android.appwidget;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -70,7 +71,9 @@
Context mContext;
Context mRemoteContext;
+ @UnsupportedAppUsage
int mAppWidgetId;
+ @UnsupportedAppUsage
AppWidgetProviderInfo mInfo;
View mView;
int mViewMode = VIEW_MODE_NOINIT;
@@ -174,6 +177,7 @@
return getDefaultPaddingForWidget(context, appInfo, padding);
}
+ @UnsupportedAppUsage
private static Rect getDefaultPaddingForWidget(Context context, ApplicationInfo appInfo,
Rect padding) {
if (padding == null) {
@@ -284,6 +288,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth,
int maxHeight, boolean ignorePadding) {
if (newOptions == null) {
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 20248b9..dbc1c19 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -23,6 +23,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.IServiceConnection;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -463,6 +464,7 @@
private final Context mContext;
private final String mPackageName;
+ @UnsupportedAppUsage
private final IAppWidgetService mService;
private final DisplayMetrics mDisplayMetrics;
@@ -816,6 +818,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
if (mService == null) {
return Collections.emptyList();
@@ -842,6 +845,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
@Nullable UserHandle profile, @Nullable String packageName) {
if (mService == null) {
@@ -902,6 +906,7 @@
* provider for this AppWidget.
* @hide
*/
+ @UnsupportedAppUsage
public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
if (mService == null) {
return;
@@ -924,6 +929,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
if (mService == null) {
return;
@@ -1094,6 +1100,7 @@
* @see Context#getServiceDispatcher(ServiceConnection, Handler, int)
* @hide
*/
+ @UnsupportedAppUsage
public boolean bindRemoteViewsService(Context context, int appWidgetId, Intent intent,
IServiceConnection connection, @Context.BindServiceFlags int flags) {
if (mService == null) {
@@ -1139,6 +1146,7 @@
}
}
+ @UnsupportedAppUsage
private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId,
ComponentName provider, Bundle options) {
if (mService == null) {
diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java
index 7ab3d8b..5694ca8 100644
--- a/core/java/android/appwidget/AppWidgetManagerInternal.java
+++ b/core/java/android/appwidget/AppWidgetManagerInternal.java
@@ -16,12 +16,9 @@
package android.appwidget;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.ArraySet;
-import java.util.Set;
-
/**
* App widget manager local system service interface.
*
@@ -36,4 +33,13 @@
* @return Whether the UID hosts widgets from the package.
*/
public abstract @Nullable ArraySet<String> getHostedWidgetPackages(int uid);
+
+ /**
+ * Execute the widget-related work of unlocking a user. This is intentionally
+ * invoked just <em>before</em> the boot-completed broadcast is issued, after
+ * the data-related work of unlock has completed.
+ *
+ * @param userId The user that is being unlocked.
+ */
+ public abstract void unlockUser(int userId);
}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 6dd85ca..53315cc 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -270,6 +271,7 @@
public int widgetFeatures;
/** @hide */
+ @UnsupportedAppUsage
public ActivityInfo providerInfo;
public AppWidgetProviderInfo() {
diff --git a/core/java/android/bluetooth/BluetoothClass.java b/core/java/android/bluetooth/BluetoothClass.java
index 8557f38..3a78cbd 100755
--- a/core/java/android/bluetooth/BluetoothClass.java
+++ b/core/java/android/bluetooth/BluetoothClass.java
@@ -16,6 +16,7 @@
package android.bluetooth;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -293,6 +294,7 @@
*
* @hide
*/
+ @TestApi
public int getClassOfDevice() {
return mClass;
}
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 0fb4ba1..13c5ff6 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -411,7 +411,14 @@
try {
gatt = mBluetoothManager.getBluetoothGatt();
} catch (RemoteException e) {
- Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
+ Log.e(TAG, "Failed to get Bluetooth GATT - ", e);
+ postStartSetFailure(handler, callback,
+ AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
+ return;
+ }
+
+ if (gatt == null) {
+ Log.e(TAG, "Bluetooth GATT is null");
postStartSetFailure(handler, callback,
AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
return;
diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java
index 922224a..db54f08 100644
--- a/core/java/android/companion/AssociationRequest.java
+++ b/core/java/android/companion/AssociationRequest.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.OneTimeUseBuilder;
@@ -59,12 +60,14 @@
}
/** @hide */
+ @UnsupportedAppUsage
public boolean isSingleDevice() {
return mSingleDevice;
}
/** @hide */
@NonNull
+ @UnsupportedAppUsage
public List<DeviceFilter<?>> getDeviceFilters() {
return mDeviceFilters;
}
diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java
index 84e1536..7507e17 100644
--- a/core/java/android/companion/BluetoothDeviceFilter.java
+++ b/core/java/android/companion/BluetoothDeviceFilter.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.bluetooth.BluetoothDevice;
import android.os.Parcel;
import android.os.ParcelUuid;
@@ -99,6 +100,7 @@
/** @hide */
@Nullable
+ @UnsupportedAppUsage
public String getAddress() {
return mAddress;
}
diff --git a/core/java/android/companion/BluetoothDeviceFilterUtils.java b/core/java/android/companion/BluetoothDeviceFilterUtils.java
index 4ee38fe..bd507a6 100644
--- a/core/java/android/companion/BluetoothDeviceFilterUtils.java
+++ b/core/java/android/companion/BluetoothDeviceFilterUtils.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
import android.net.wifi.ScanResult;
@@ -124,14 +125,17 @@
Log.i(LOG_TAG, getDeviceDisplayNameInternal(device) + (result ? " ~ " : " !~ ") + criteria);
}
+ @UnsupportedAppUsage
public static String getDeviceDisplayNameInternal(@NonNull BluetoothDevice device) {
return firstNotEmpty(device.getAliasName(), device.getAddress());
}
+ @UnsupportedAppUsage
public static String getDeviceDisplayNameInternal(@NonNull ScanResult device) {
return firstNotEmpty(device.SSID, device.BSSID);
}
+ @UnsupportedAppUsage
public static String getDeviceMacAddress(@NonNull Parcelable device) {
if (device instanceof BluetoothDevice) {
return ((BluetoothDevice) device).getAddress();
diff --git a/core/java/android/companion/BluetoothLeDeviceFilter.java b/core/java/android/companion/BluetoothLeDeviceFilter.java
index 7fb768c..1de931e 100644
--- a/core/java/android/companion/BluetoothLeDeviceFilter.java
+++ b/core/java/android/companion/BluetoothLeDeviceFilter.java
@@ -25,6 +25,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
@@ -92,6 +93,7 @@
/** @hide */
@NonNull
+ @UnsupportedAppUsage
public ScanFilter getScanFilter() {
return mScanFilter;
}
diff --git a/core/java/android/companion/DeviceFilter.java b/core/java/android/companion/DeviceFilter.java
index 10135a4..dc7cf82 100644
--- a/core/java/android/companion/DeviceFilter.java
+++ b/core/java/android/companion/DeviceFilter.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcelable;
import java.lang.annotation.Retention;
@@ -44,9 +45,11 @@
*
* @hide
*/
+ @UnsupportedAppUsage
boolean matches(D device);
/** @hide */
+ @UnsupportedAppUsage
String getDeviceDisplayName(D device);
/** @hide */
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
index 93fa403..b06dd7a 100644
--- a/core/java/android/content/ContentValues.java
+++ b/core/java/android/content/ContentValues.java
@@ -21,9 +21,12 @@
import android.util.ArrayMap;
import android.util.Log;
+import com.android.internal.util.Preconditions;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -55,6 +58,7 @@
* @param size the initial size of the set of values
*/
public ContentValues(int size) {
+ Preconditions.checkArgumentNonnegative(size);
mMap = new ArrayMap<>(size);
}
@@ -64,6 +68,7 @@
* @param from the values to copy
*/
public ContentValues(ContentValues from) {
+ Objects.requireNonNull(from);
mMap = new ArrayMap<>(from.mMap);
}
diff --git a/core/java/android/database/RedactingCursor.java b/core/java/android/database/RedactingCursor.java
new file mode 100644
index 0000000..6322d56
--- /dev/null
+++ b/core/java/android/database/RedactingCursor.java
@@ -0,0 +1,181 @@
+/*
+ * 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.database;
+
+import android.annotation.NonNull;
+import android.util.SparseArray;
+
+import java.util.Map;
+
+/**
+ * Cursor that offers to redact values of requested columns.
+ *
+ * @hide
+ */
+public class RedactingCursor extends CrossProcessCursorWrapper {
+ private final SparseArray<Object> mRedactions;
+
+ private RedactingCursor(@NonNull Cursor cursor, SparseArray<Object> redactions) {
+ super(cursor);
+ mRedactions = redactions;
+ }
+
+ /**
+ * Create a wrapped instance of the given {@link Cursor} which redacts the
+ * requested columns so they always return specific values when accessed.
+ * <p>
+ * If a redacted column appears multiple times in the underlying cursor, all
+ * instances will be redacted. If none of the redacted columns appear in the
+ * given cursor, the given cursor will be returned untouched to improve
+ * performance.
+ */
+ public static Cursor create(@NonNull Cursor cursor, @NonNull Map<String, Object> redactions) {
+ final SparseArray<Object> internalRedactions = new SparseArray<>();
+
+ final String[] columns = cursor.getColumnNames();
+ for (int i = 0; i < columns.length; i++) {
+ if (redactions.containsKey(columns[i])) {
+ internalRedactions.put(i, redactions.get(columns[i]));
+ }
+ }
+
+ if (internalRedactions.size() == 0) {
+ return cursor;
+ } else {
+ return new RedactingCursor(cursor, internalRedactions);
+ }
+ }
+
+ @Override
+ public void fillWindow(int position, CursorWindow window) {
+ // Fill window directly to ensure data is redacted
+ DatabaseUtils.cursorFillWindow(this, position, window);
+ }
+
+ @Override
+ public CursorWindow getWindow() {
+ // Returning underlying window risks leaking redacted data
+ return null;
+ }
+
+ @Override
+ public Cursor getWrappedCursor() {
+ throw new UnsupportedOperationException(
+ "Returning underlying cursor risks leaking redacted data");
+ }
+
+ @Override
+ public double getDouble(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (double) mRedactions.valueAt(i);
+ } else {
+ return super.getDouble(columnIndex);
+ }
+ }
+
+ @Override
+ public float getFloat(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (float) mRedactions.valueAt(i);
+ } else {
+ return super.getFloat(columnIndex);
+ }
+ }
+
+ @Override
+ public int getInt(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (int) mRedactions.valueAt(i);
+ } else {
+ return super.getInt(columnIndex);
+ }
+ }
+
+ @Override
+ public long getLong(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (long) mRedactions.valueAt(i);
+ } else {
+ return super.getLong(columnIndex);
+ }
+ }
+
+ @Override
+ public short getShort(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (short) mRedactions.valueAt(i);
+ } else {
+ return super.getShort(columnIndex);
+ }
+ }
+
+ @Override
+ public String getString(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (String) mRedactions.valueAt(i);
+ } else {
+ return super.getString(columnIndex);
+ }
+ }
+
+ @Override
+ public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ buffer.data = ((String) mRedactions.valueAt(i)).toCharArray();
+ buffer.sizeCopied = buffer.data.length;
+ } else {
+ super.copyStringToBuffer(columnIndex, buffer);
+ }
+ }
+
+ @Override
+ public byte[] getBlob(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return (byte[]) mRedactions.valueAt(i);
+ } else {
+ return super.getBlob(columnIndex);
+ }
+ }
+
+ @Override
+ public int getType(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return DatabaseUtils.getTypeOfObject(mRedactions.valueAt(i));
+ } else {
+ return super.getType(columnIndex);
+ }
+ }
+
+ @Override
+ public boolean isNull(int columnIndex) {
+ final int i = mRedactions.indexOfKey(columnIndex);
+ if (i >= 0) {
+ return mRedactions.valueAt(i) == null;
+ } else {
+ return super.isNull(columnIndex);
+ }
+ }
+}
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index d6d9764..e6b6acf 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -39,11 +39,18 @@
public final class SQLiteGlobal {
private static final String TAG = "SQLiteGlobal";
+ /** @hide */
+ public static final String SYNC_MODE_FULL = "FULL";
+
private static final Object sLock = new Object();
+
private static int sDefaultPageSize;
private static native int nativeReleaseMemory();
+ /** @hide */
+ public static volatile String sDefaultSyncMode;
+
private SQLiteGlobal() {
}
@@ -103,6 +110,11 @@
* Gets the default database synchronization mode when WAL is not in use.
*/
public static String getDefaultSyncMode() {
+ // Use the FULL synchronous mode for system processes by default.
+ String defaultMode = sDefaultSyncMode;
+ if (defaultMode != null) {
+ return defaultMode;
+ }
return SystemProperties.get("debug.sqlite.syncmode",
Resources.getSystem().getString(
com.android.internal.R.string.db_default_sync_mode));
@@ -112,6 +124,11 @@
* Gets the database synchronization mode when in WAL mode.
*/
public static String getWALSyncMode() {
+ // Use the FULL synchronous mode for system processes by default.
+ String defaultMode = sDefaultSyncMode;
+ if (defaultMode != null) {
+ return defaultMode;
+ }
return SystemProperties.get("debug.sqlite.wal.syncmode",
Resources.getSystem().getString(
com.android.internal.R.string.db_wal_sync_mode));
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 22e1f45..8e96f56 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.content.Context;
@@ -164,6 +165,7 @@
private static final int CAMERA_MSG_PREVIEW_METADATA = 0x400;
private static final int CAMERA_MSG_FOCUS_MOVE = 0x800;
+ @UnsupportedAppUsage
private long mNativeContext; // accessed by native methods
private EventHandler mEventHandler;
private ShutterCallback mShutterCallback;
@@ -236,6 +238,7 @@
* Camera HAL device API version 1.0
* @hide
*/
+ @UnsupportedAppUsage
public static final int CAMERA_HAL_API_VERSION_1_0 = 0x100;
/**
@@ -451,6 +454,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static Camera openLegacy(int cameraId, int halVersion) {
if (halVersion < CAMERA_HAL_API_VERSION_1_0) {
throw new IllegalArgumentException("Invalid HAL version " + halVersion);
@@ -604,6 +608,7 @@
release();
}
+ @UnsupportedAppUsage
private native final int native_setup(Object camera_this, int cameraId, int halVersion,
String packageName);
@@ -716,6 +721,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public native final void setPreviewSurface(Surface surface) throws IOException;
/**
@@ -839,6 +845,7 @@
* FIXME: Unhide before release
* @hide
*/
+ @UnsupportedAppUsage
public native final boolean previewEnabled();
/**
@@ -1012,11 +1019,13 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public final void addRawImageCallbackBuffer(byte[] callbackBuffer)
{
addCallbackBuffer(callbackBuffer, CAMERA_MSG_RAW_IMAGE);
}
+ @UnsupportedAppUsage
private final void addCallbackBuffer(byte[] callbackBuffer, int msgType)
{
// CAMERA_MSG_VIDEO_FRAME may be allowed in the future.
@@ -1263,6 +1272,7 @@
}
}
+ @UnsupportedAppUsage
private static void postEventFromNative(Object camera_ref,
int what, int arg1, int arg2, Object obj)
{
@@ -2075,7 +2085,9 @@
mDetailedErrorCallback = cb;
}
+ @UnsupportedAppUsage
private native final void native_setParameters(String params);
+ @UnsupportedAppUsage
private native final String native_getParameters();
/**
@@ -2124,6 +2136,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static Parameters getEmptyParameters() {
Camera camera = new Camera();
return camera.new Parameters();
@@ -2658,6 +2671,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void copyFrom(Parameters other) {
if (other == null) {
throw new NullPointerException("other must not be null");
@@ -2689,6 +2703,7 @@
* @deprecated
*/
@Deprecated
+ @UnsupportedAppUsage
public void dump() {
Log.e(TAG, "dump: size=" + mMap.size());
for (String k : mMap.keySet()) {
@@ -4407,6 +4422,7 @@
// Splits a comma delimited string to an ArrayList of Area objects.
// Example string: "(-10,-10,0,0,300),(0,0,10,10,700)". Return null if
// the passing string is null or the size is 0 or (0,0,0,0,0).
+ @UnsupportedAppUsage
private ArrayList<Area> splitArea(String str) {
if (str == null || str.charAt(0) != '('
|| str.charAt(str.length() - 1) != ')') {
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index 9aa3f40..c17aabb 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.LongDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -89,6 +90,7 @@
public static final int S_UI8 = 0x35;
// Note: do not rename, this field is used by native code
+ @UnsupportedAppUsage
private long mNativeObject;
// Invoked on destruction
@@ -182,6 +184,7 @@
* Private use only. See {@link #create(int, int, int, int, long)}. May also be
* called from JNI using an already allocated native <code>HardwareBuffer</code>.
*/
+ @UnsupportedAppUsage
private HardwareBuffer(long nativeObject) {
mNativeObject = nativeObject;
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index 7297426..4aa6fab 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -18,6 +18,7 @@
package android.hardware;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Build;
/**
@@ -504,6 +505,7 @@
*
* @hide Expected to be used internally for always on display.
*/
+ @UnsupportedAppUsage
public static final int TYPE_PICK_UP_GESTURE = 25;
/**
@@ -543,6 +545,7 @@
* @hide Expected to be used internally for auto-rotate and speaker rotation.
*
*/
+ @UnsupportedAppUsage
public static final int TYPE_DEVICE_ORIENTATION = 27;
/**
@@ -891,6 +894,7 @@
private String mStringType;
private String mRequiredPermission;
private int mMaxDelay;
+ @UnsupportedAppUsage
private int mFlags;
private int mId;
@@ -1014,6 +1018,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public int getHandle() {
return mHandle;
}
diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java
index bbd04a3..8c910b2 100644
--- a/core/java/android/hardware/SensorEvent.java
+++ b/core/java/android/hardware/SensorEvent.java
@@ -16,6 +16,8 @@
package android.hardware;
+import android.annotation.UnsupportedAppUsage;
+
/**
* This class represents a {@link android.hardware.Sensor Sensor} event and
* holds information such as the sensor's type, the time-stamp, accuracy and of
@@ -649,6 +651,7 @@
*/
public long timestamp;
+ @UnsupportedAppUsage
SensorEvent(int valueSize) {
values = new float[valueSize];
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index cbddc91..3250428 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -18,6 +18,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
@@ -368,6 +369,7 @@
/**
* {@hide}
*/
+ @UnsupportedAppUsage
public SensorManager() {
}
diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java
index 610f6a5..571c3cc 100644
--- a/core/java/android/hardware/SerialManager.java
+++ b/core/java/android/hardware/SerialManager.java
@@ -17,6 +17,7 @@
package android.hardware;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -46,6 +47,7 @@
*
* @return names of available serial ports
*/
+ @UnsupportedAppUsage
public String[] getSerialPorts() {
try {
return mService.getSerialPorts();
@@ -65,6 +67,7 @@
* @param speed at which to open the serial port
* @return the serial port
*/
+ @UnsupportedAppUsage
public SerialPort openSerialPort(String name, int speed) throws IOException {
try {
ParcelFileDescriptor pfd = mService.openSerialPort(name);
diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java
index 5d83d9c..78ac3c0 100644
--- a/core/java/android/hardware/SerialPort.java
+++ b/core/java/android/hardware/SerialPort.java
@@ -16,6 +16,7 @@
package android.hardware;
+import android.annotation.UnsupportedAppUsage;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
@@ -31,6 +32,7 @@
private static final String TAG = "SerialPort";
// used by the JNI code
+ @UnsupportedAppUsage
private int mNativeContext;
private final String mName;
private ParcelFileDescriptor mFileDescriptor;
@@ -59,6 +61,7 @@
/**
* Closes the serial port
*/
+ @UnsupportedAppUsage
public void close() throws IOException {
if (mFileDescriptor != null) {
mFileDescriptor.close();
@@ -102,6 +105,7 @@
* @param buffer to write
* @param length number of bytes to write
*/
+ @UnsupportedAppUsage
public void write(ByteBuffer buffer, int length) throws IOException {
if (buffer.isDirect()) {
native_write_direct(buffer, length);
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 1174cb6..7abfabf 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -16,6 +16,7 @@
package android.hardware;
+import android.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -758,10 +759,13 @@
if (sensor == null) throw new NullPointerException();
return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle());
}
+ @UnsupportedAppUsage
protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy,
long timestamp);
+ @UnsupportedAppUsage
protected abstract void dispatchFlushCompleteEvent(int handle);
+ @UnsupportedAppUsage
protected void dispatchAdditionalInfoEvent(
int handle, int type, int serial, float[] floatValues, int[] intValues) {
// default implementation is do nothing
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index d027fd9..f7d1b8d 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.PublicKey;
import android.hardware.camera2.impl.SyntheticKey;
@@ -72,6 +73,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type, long vendorId) {
mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
}
@@ -90,6 +92,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -99,6 +102,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, TypeReference<T> typeReference) {
mKey = new CameraMetadataNative.Key<T>(name, typeReference);
}
@@ -168,6 +172,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public CameraMetadataNative.Key<T> getNativeKey() {
return mKey;
}
@@ -180,6 +185,7 @@
}
}
+ @UnsupportedAppUsage
private final CameraMetadataNative mProperties;
private List<CameraCharacteristics.Key<?>> mKeys;
private List<CaptureRequest.Key<?>> mAvailableRequestKeys;
@@ -767,6 +773,7 @@
* @see CaptureRequest#CONTROL_AWB_REGIONS
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> CONTROL_MAX_REGIONS =
new Key<int[]>("android.control.maxRegions", int[].class);
@@ -872,6 +879,7 @@
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]> CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS =
new Key<android.hardware.camera2.params.HighSpeedVideoConfiguration[]>("android.control.availableHighSpeedVideoConfigurations", android.hardware.camera2.params.HighSpeedVideoConfiguration[].class);
@@ -1140,6 +1148,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.util.Size> LENS_INFO_SHADING_MAP_SIZE =
new Key<android.util.Size>("android.lens.info.shadingMapSize", android.util.Size.class);
@@ -1491,6 +1500,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<Byte> QUIRKS_USE_PARTIAL_RESULT =
new Key<Byte>("android.quirks.usePartialResult", byte.class);
@@ -1528,6 +1538,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_MAX_NUM_OUTPUT_STREAMS =
new Key<int[]>("android.request.maxNumOutputStreams", int[].class);
@@ -1767,6 +1778,7 @@
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_AVAILABLE_REQUEST_KEYS =
new Key<int[]>("android.request.availableRequestKeys", int[].class);
@@ -1792,6 +1804,7 @@
* @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_AVAILABLE_RESULT_KEYS =
new Key<int[]>("android.request.availableResultKeys", int[].class);
@@ -1804,6 +1817,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =
new Key<int[]>("android.request.availableCharacteristicsKeys", int[].class);
@@ -1850,6 +1864,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_AVAILABLE_SESSION_KEYS =
new Key<int[]>("android.request.availableSessionKeys", int[].class);
@@ -1870,6 +1885,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS =
new Key<int[]>("android.request.availablePhysicalCameraRequestKeys", int[].class);
@@ -1885,6 +1901,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<int[]> SCALER_AVAILABLE_FORMATS =
new Key<int[]>("android.scaler.availableFormats", int[].class);
@@ -1907,6 +1924,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<long[]> SCALER_AVAILABLE_JPEG_MIN_DURATIONS =
new Key<long[]>("android.scaler.availableJpegMinDurations", long[].class);
@@ -1925,6 +1943,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<android.util.Size[]> SCALER_AVAILABLE_JPEG_SIZES =
new Key<android.util.Size[]>("android.scaler.availableJpegSizes", android.util.Size[].class);
@@ -1966,6 +1985,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<long[]> SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS =
new Key<long[]>("android.scaler.availableProcessedMinDurations", long[].class);
@@ -1990,6 +2010,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<android.util.Size[]> SCALER_AVAILABLE_PROCESSED_SIZES =
new Key<android.util.Size[]>("android.scaler.availableProcessedSizes", android.util.Size[].class);
@@ -2045,6 +2066,7 @@
* @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.ReprocessFormatsMap> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =
new Key<android.hardware.camera2.params.ReprocessFormatsMap>("android.scaler.availableInputOutputFormatsMap", android.hardware.camera2.params.ReprocessFormatsMap.class);
@@ -2137,6 +2159,7 @@
* @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfiguration[]> SCALER_AVAILABLE_STREAM_CONFIGURATIONS =
new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.scaler.availableStreamConfigurations", android.hardware.camera2.params.StreamConfiguration[].class);
@@ -2159,6 +2182,7 @@
* @see CaptureRequest#SENSOR_FRAME_DURATION
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_MIN_FRAME_DURATIONS =
new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableMinFrameDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
@@ -2227,6 +2251,7 @@
* @see CaptureRequest#SENSOR_FRAME_DURATION
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> SCALER_AVAILABLE_STALL_DURATIONS =
new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.scaler.availableStallDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
@@ -3134,6 +3159,7 @@
* @see #LED_AVAILABLE_LEDS_TRANSMIT
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> LED_AVAILABLE_LEDS =
new Key<int[]>("android.led.availableLeds", int[].class);
@@ -3320,6 +3346,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfiguration[]> DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS =
new Key<android.hardware.camera2.params.StreamConfiguration[]>("android.depth.availableDepthStreamConfigurations", android.hardware.camera2.params.StreamConfiguration[].class);
@@ -3346,6 +3373,7 @@
* @see CaptureRequest#SENSOR_FRAME_DURATION
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DEPTH_MIN_FRAME_DURATIONS =
new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDepthMinFrameDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
@@ -3369,6 +3397,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.hardware.camera2.params.StreamConfigurationDuration[]> DEPTH_AVAILABLE_DEPTH_STALL_DURATIONS =
new Key<android.hardware.camera2.params.StreamConfigurationDuration[]>("android.depth.availableDepthStallDurations", android.hardware.camera2.params.StreamConfigurationDuration[].class);
@@ -3412,6 +3441,7 @@
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<byte[]> LOGICAL_MULTI_CAMERA_PHYSICAL_IDS =
new Key<byte[]>("android.logicalMultiCamera.physicalIds", byte[].class);
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 0c3fe77..47bef12 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.PublicKey;
import android.hardware.camera2.impl.SyntheticKey;
@@ -107,6 +108,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type, long vendorId) {
mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
}
@@ -116,6 +118,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -125,6 +128,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, TypeReference<T> typeReference) {
mKey = new CameraMetadataNative.Key<T>(name, typeReference);
}
@@ -194,6 +198,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public CameraMetadataNative.Key<T> getNativeKey() {
return mKey;
}
@@ -223,6 +228,7 @@
private static final ArraySet<Surface> mEmptySurfaceSet = new ArraySet<Surface>();
private String mLogicalCameraId;
+ @UnsupportedAppUsage
private CameraMetadataNative mLogicalCameraSettings;
private final HashMap<String, CameraMetadataNative> mPhysicalCameraSettings =
new HashMap<String, CameraMetadataNative>();
@@ -598,6 +604,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public Collection<Surface> getTargets() {
return Collections.unmodifiableCollection(mSurfaceSet);
}
@@ -886,6 +893,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setPartOfCHSRequestList(boolean partOfCHSList) {
mRequest.mIsPartOfCHSRequestList = partOfCHSList;
}
@@ -2132,6 +2140,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<double[]> JPEG_GPS_COORDINATES =
new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
@@ -2142,6 +2151,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
@@ -2152,6 +2162,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Long> JPEG_GPS_TIMESTAMP =
new Key<Long>("android.jpeg.gpsTimestamp", long.class);
@@ -2487,6 +2498,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Integer> REQUEST_ID =
new Key<Integer>("android.request.id", int.class);
@@ -2902,6 +2914,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_BLUE =
new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -2919,6 +2932,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_GREEN =
new Key<float[]>("android.tonemap.curveGreen", float[].class);
@@ -2981,6 +2995,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_RED =
new Key<float[]>("android.tonemap.curveRed", float[].class);
@@ -3155,6 +3170,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Boolean> LED_TRANSMIT =
new Key<Boolean>("android.led.transmit", boolean.class);
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 5836288..007794f 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.hardware.camera2.impl.CameraMetadataNative;
import android.hardware.camera2.impl.CaptureResultExtras;
import android.hardware.camera2.impl.PublicKey;
@@ -78,6 +79,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type, long vendorId) {
mKey = new CameraMetadataNative.Key<T>(name, type, vendorId);
}
@@ -96,6 +98,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, Class<T> type) {
mKey = new CameraMetadataNative.Key<T>(name, type);
}
@@ -105,6 +108,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Key(String name, TypeReference<T> typeReference) {
mKey = new CameraMetadataNative.Key<T>(name, typeReference);
}
@@ -174,6 +178,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public CameraMetadataNative.Key<T> getNativeKey() {
return mKey;
}
@@ -184,6 +189,7 @@
}
}
+ @UnsupportedAppUsage
private final CameraMetadataNative mResults;
private final CaptureRequest mRequest;
private final int mSequenceId;
@@ -2458,6 +2464,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<double[]> JPEG_GPS_COORDINATES =
new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
@@ -2468,6 +2475,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<String> JPEG_GPS_PROCESSING_METHOD =
new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
@@ -2478,6 +2486,7 @@
* <p>This key is available on all devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Long> JPEG_GPS_TIMESTAMP =
new Key<Long>("android.jpeg.gpsTimestamp", long.class);
@@ -3116,6 +3125,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<Boolean> QUIRKS_PARTIAL_RESULT =
new Key<Boolean>("android.quirks.partialResult", boolean.class);
@@ -3134,6 +3144,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<Integer> REQUEST_FRAME_COUNT =
new Key<Integer>("android.request.frameCount", int.class);
@@ -3147,6 +3158,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Integer> REQUEST_ID =
new Key<Integer>("android.request.id", int.class);
@@ -3708,6 +3720,7 @@
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> STATISTICS_FACE_IDS =
new Key<int[]>("android.statistics.faceIds", int[].class);
@@ -3734,6 +3747,7 @@
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<int[]> STATISTICS_FACE_LANDMARKS =
new Key<int[]>("android.statistics.faceLandmarks", int[].class);
@@ -3760,6 +3774,7 @@
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<android.graphics.Rect[]> STATISTICS_FACE_RECTANGLES =
new Key<android.graphics.Rect[]>("android.statistics.faceRectangles", android.graphics.Rect[].class);
@@ -3774,6 +3789,7 @@
* @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<byte[]> STATISTICS_FACE_SCORES =
new Key<byte[]>("android.statistics.faceScores", byte[].class);
@@ -3933,6 +3949,7 @@
* @see CameraCharacteristics#SENSOR_INFO_LENS_SHADING_APPLIED
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> STATISTICS_LENS_SHADING_MAP =
new Key<float[]>("android.statistics.lensShadingMap", float[].class);
@@ -3956,6 +3973,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<float[]> STATISTICS_PREDICTED_COLOR_GAINS =
new Key<float[]>("android.statistics.predictedColorGains", float[].class);
@@ -3982,6 +4000,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static final Key<Rational[]> STATISTICS_PREDICTED_COLOR_TRANSFORM =
new Key<Rational[]>("android.statistics.predictedColorTransform", Rational[].class);
@@ -4124,6 +4143,7 @@
* @see CaptureResult#SENSOR_TIMESTAMP
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<long[]> STATISTICS_OIS_TIMESTAMPS =
new Key<long[]>("android.statistics.oisTimestamps", long[].class);
@@ -4143,6 +4163,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> STATISTICS_OIS_X_SHIFTS =
new Key<float[]>("android.statistics.oisXShifts", float[].class);
@@ -4162,6 +4183,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> STATISTICS_OIS_Y_SHIFTS =
new Key<float[]>("android.statistics.oisYShifts", float[].class);
@@ -4202,6 +4224,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_BLUE =
new Key<float[]>("android.tonemap.curveBlue", float[].class);
@@ -4219,6 +4242,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_GREEN =
new Key<float[]>("android.tonemap.curveGreen", float[].class);
@@ -4281,6 +4305,7 @@
* @see CaptureRequest#TONEMAP_MODE
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<float[]> TONEMAP_CURVE_RED =
new Key<float[]>("android.tonemap.curveRed", float[].class);
@@ -4455,6 +4480,7 @@
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Boolean> LED_TRANSMIT =
new Key<Boolean>("android.led.transmit", boolean.class);
@@ -4544,6 +4570,7 @@
* @see #SYNC_FRAME_NUMBER_UNKNOWN
* @hide
*/
+ @UnsupportedAppUsage
public static final Key<Long> SYNC_FRAME_NUMBER =
new Key<Long>("android.sync.frameNumber", long.class);
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 86bd30c..0610d7a 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -16,6 +16,7 @@
package android.hardware.camera2.impl;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.Rect;
@@ -231,6 +232,7 @@
*
* @return The tag numeric value corresponding to the string
*/
+ @UnsupportedAppUsage
public final int getTag() {
if (!mHasTag) {
mTag = CameraMetadataNative.getTag(mName, mVendorId);
@@ -1188,6 +1190,7 @@
return true;
}
+ @UnsupportedAppUsage
private long mMetadataPtr; // native CameraMetadata*
private native long nativeAllocate();
@@ -1202,13 +1205,16 @@
private native synchronized boolean nativeIsEmpty();
private native synchronized int nativeGetEntryCount();
+ @UnsupportedAppUsage
private native synchronized byte[] nativeReadValues(int tag);
private native synchronized void nativeWriteValues(int tag, byte[] src);
private native synchronized void nativeDump() throws IOException; // dump to ALOGD
private native synchronized ArrayList nativeGetAllVendorKeys(Class keyClass);
+ @UnsupportedAppUsage
private native synchronized int nativeGetTagFromKeyLocal(String keyName)
throws IllegalArgumentException;
+ @UnsupportedAppUsage
private native synchronized int nativeGetTypeFromTagLocal(int tag)
throws IllegalArgumentException;
private static native int nativeGetTagFromKey(String keyName, long vendorId)
diff --git a/core/java/android/hardware/camera2/utils/SurfaceUtils.java b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
index 9247844..d3c4505 100644
--- a/core/java/android/hardware/camera2/utils/SurfaceUtils.java
+++ b/core/java/android/hardware/camera2/utils/SurfaceUtils.java
@@ -16,6 +16,7 @@
package android.hardware.camera2.utils;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.ImageFormat;
import android.hardware.camera2.legacy.LegacyCameraDevice;
import android.hardware.camera2.legacy.LegacyExceptionUtils.BufferQueueAbandonedException;
@@ -77,6 +78,7 @@
*
* @throws IllegalArgumentException if the surface is already abandoned.
*/
+ @UnsupportedAppUsage
public static Size getSurfaceSize(Surface surface) {
try {
return LegacyCameraDevice.getSurfaceSize(surface);
diff --git a/core/java/android/hardware/camera2/utils/TypeReference.java b/core/java/android/hardware/camera2/utils/TypeReference.java
index 24ce124..d9ba31b 100644
--- a/core/java/android/hardware/camera2/utils/TypeReference.java
+++ b/core/java/android/hardware/camera2/utils/TypeReference.java
@@ -16,6 +16,7 @@
package android.hardware.camera2.utils;
+import android.annotation.UnsupportedAppUsage;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
@@ -55,6 +56,7 @@
*
* @see TypeReference
*/
+ @UnsupportedAppUsage
protected TypeReference() {
ParameterizedType thisType = (ParameterizedType)getClass().getGenericSuperclass();
@@ -136,6 +138,7 @@
*
* @throws IllegalArgumentException if {@code type} had any type variables
*/
+ @UnsupportedAppUsage
public static TypeReference<?> createSpecializedTypeReference(Type type) {
return new SpecializedBaseTypeReference(type);
}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index b182fa2..e700cac 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -23,6 +23,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.KeyguardManager;
import android.content.Context;
import android.graphics.Point;
@@ -62,6 +63,7 @@
* </p>
* @hide
*/
+ @UnsupportedAppUsage
public static final String ACTION_WIFI_DISPLAY_STATUS_CHANGED =
"android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED";
@@ -69,6 +71,7 @@
* Contains a {@link WifiDisplayStatus} object.
* @hide
*/
+ @UnsupportedAppUsage
public static final String EXTRA_WIFI_DISPLAY_STATUS =
"android.hardware.display.extra.WIFI_DISPLAY_STATUS";
@@ -437,6 +440,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void startWifiDisplayScan() {
mGlobal.startWifiDisplayScan();
}
@@ -449,6 +453,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void stopWifiDisplayScan() {
mGlobal.stopWifiDisplayScan();
}
@@ -466,16 +471,19 @@
* @param deviceAddress The MAC address of the device to which we should connect.
* @hide
*/
+ @UnsupportedAppUsage
public void connectWifiDisplay(String deviceAddress) {
mGlobal.connectWifiDisplay(deviceAddress);
}
/** @hide */
+ @UnsupportedAppUsage
public void pauseWifiDisplay() {
mGlobal.pauseWifiDisplay();
}
/** @hide */
+ @UnsupportedAppUsage
public void resumeWifiDisplay() {
mGlobal.resumeWifiDisplay();
}
@@ -485,6 +493,7 @@
* The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
* @hide
*/
+ @UnsupportedAppUsage
public void disconnectWifiDisplay() {
mGlobal.disconnectWifiDisplay();
}
@@ -504,6 +513,7 @@
* or empty if no alias should be used.
* @hide
*/
+ @UnsupportedAppUsage
public void renameWifiDisplay(String deviceAddress, String alias) {
mGlobal.renameWifiDisplay(deviceAddress, alias);
}
@@ -519,6 +529,7 @@
* @param deviceAddress The MAC address of the device to forget.
* @hide
*/
+ @UnsupportedAppUsage
public void forgetWifiDisplay(String deviceAddress) {
mGlobal.forgetWifiDisplay(deviceAddress);
}
@@ -531,6 +542,7 @@
* @return The current Wifi display status.
* @hide
*/
+ @UnsupportedAppUsage
public WifiDisplayStatus getWifiDisplayStatus() {
return mGlobal.getWifiDisplayStatus();
}
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index d968a3e..7304ab4 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -16,6 +16,7 @@
package android.hardware.display;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
@@ -66,10 +67,12 @@
public static final int EVENT_DISPLAY_CHANGED = 2;
public static final int EVENT_DISPLAY_REMOVED = 3;
+ @UnsupportedAppUsage
private static DisplayManagerGlobal sInstance;
private final Object mLock = new Object();
+ @UnsupportedAppUsage
private final IDisplayManager mDm;
private DisplayManagerCallback mCallback;
@@ -91,6 +94,7 @@
* @return The display manager instance, may be null early in system startup
* before the display manager has been fully initialized.
*/
+ @UnsupportedAppUsage
public static DisplayManagerGlobal getInstance() {
synchronized (DisplayManagerGlobal.class) {
if (sInstance == null) {
@@ -110,6 +114,7 @@
* @return Information about the specified display, or null if it does not exist.
* This object belongs to an internal cache and should be treated as if it were immutable.
*/
+ @UnsupportedAppUsage
public DisplayInfo getDisplayInfo(int displayId) {
try {
synchronized (mLock) {
@@ -146,6 +151,7 @@
*
* @return An array containing all display ids.
*/
+ @UnsupportedAppUsage
public int[] getDisplayIds() {
try {
synchronized (mLock) {
@@ -209,6 +215,7 @@
* @param displayId The logical display id.
* @return The display object, or null if there is no display with the given id.
*/
+ @UnsupportedAppUsage
public Display getRealDisplay(int displayId) {
return getCompatibleDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
}
@@ -337,6 +344,7 @@
}
}
+ @UnsupportedAppUsage
public void disconnectWifiDisplay() {
try {
mDm.disconnectWifiDisplay();
@@ -369,6 +377,7 @@
}
}
+ @UnsupportedAppUsage
public WifiDisplayStatus getWifiDisplayStatus() {
try {
return mDm.getWifiDisplayStatus();
diff --git a/core/java/android/hardware/display/WifiDisplay.java b/core/java/android/hardware/display/WifiDisplay.java
index bb32c19..12486e8 100644
--- a/core/java/android/hardware/display/WifiDisplay.java
+++ b/core/java/android/hardware/display/WifiDisplay.java
@@ -16,6 +16,7 @@
package android.hardware.display;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -76,6 +77,7 @@
/**
* Gets the MAC address of the Wifi display device.
*/
+ @UnsupportedAppUsage
public String getDeviceAddress() {
return mDeviceAddress;
}
@@ -83,6 +85,7 @@
/**
* Gets the name of the Wifi display device.
*/
+ @UnsupportedAppUsage
public String getDeviceName() {
return mDeviceName;
}
@@ -94,6 +97,7 @@
* provided by the user when renaming the device.
* </p>
*/
+ @UnsupportedAppUsage
public String getDeviceAlias() {
return mDeviceAlias;
}
@@ -101,6 +105,7 @@
/**
* Returns true if device is available, false otherwise.
*/
+ @UnsupportedAppUsage
public boolean isAvailable() {
return mIsAvailable;
}
@@ -108,6 +113,7 @@
/**
* Returns true if device can be connected to (not in use), false otherwise.
*/
+ @UnsupportedAppUsage
public boolean canConnect() {
return mCanConnect;
}
@@ -115,6 +121,7 @@
/**
* Returns true if device has been remembered, false otherwise.
*/
+ @UnsupportedAppUsage
public boolean isRemembered() {
return mIsRemembered;
}
@@ -136,6 +143,7 @@
* Returns true if the two displays have the same identity (address, name and alias).
* This method does not compare the current status of the displays.
*/
+ @UnsupportedAppUsage
public boolean equals(WifiDisplay other) {
return other != null
&& mDeviceAddress.equals(other.mDeviceAddress)
diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java
index b645662..c267834 100644
--- a/core/java/android/hardware/display/WifiDisplayStatus.java
+++ b/core/java/android/hardware/display/WifiDisplayStatus.java
@@ -16,6 +16,7 @@
package android.hardware.display;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -34,7 +35,9 @@
private final int mFeatureState;
private final int mScanState;
private final int mActiveDisplayState;
+ @UnsupportedAppUsage
private final WifiDisplay mActiveDisplay;
+ @UnsupportedAppUsage
private final WifiDisplay[] mDisplays;
/** Session info needed for Miracast Certification */
@@ -47,18 +50,23 @@
/** Feature state: Wifi display is turned off in settings. */
public static final int FEATURE_STATE_OFF = 2;
/** Feature state: Wifi display is turned on in settings. */
+ @UnsupportedAppUsage
public static final int FEATURE_STATE_ON = 3;
/** Scan state: Not currently scanning. */
+ @UnsupportedAppUsage
public static final int SCAN_STATE_NOT_SCANNING = 0;
/** Scan state: Currently scanning. */
public static final int SCAN_STATE_SCANNING = 1;
/** Display state: Not connected. */
+ @UnsupportedAppUsage
public static final int DISPLAY_STATE_NOT_CONNECTED = 0;
/** Display state: Connecting to active display. */
+ @UnsupportedAppUsage
public static final int DISPLAY_STATE_CONNECTING = 1;
/** Display state: Connected to active display. */
+ @UnsupportedAppUsage
public static final int DISPLAY_STATE_CONNECTED = 2;
public static final Creator<WifiDisplayStatus> CREATOR = new Creator<WifiDisplayStatus>() {
@@ -117,6 +125,7 @@
* connecting to displays have been met.
* </p>
*/
+ @UnsupportedAppUsage
public int getFeatureState() {
return mFeatureState;
}
@@ -126,6 +135,7 @@
*
* @return One of: {@link #SCAN_STATE_NOT_SCANNING} or {@link #SCAN_STATE_SCANNING}.
*/
+ @UnsupportedAppUsage
public int getScanState() {
return mScanState;
}
@@ -136,6 +146,7 @@
* @return One of: {@link #DISPLAY_STATE_NOT_CONNECTED}, {@link #DISPLAY_STATE_CONNECTING},
* or {@link #DISPLAY_STATE_CONNECTED}.
*/
+ @UnsupportedAppUsage
public int getActiveDisplayState() {
return mActiveDisplayState;
}
@@ -144,6 +155,7 @@
* Gets the Wifi display that is currently active. It may be connecting or
* connected.
*/
+ @UnsupportedAppUsage
public WifiDisplay getActiveDisplay() {
return mActiveDisplay;
}
@@ -153,6 +165,7 @@
* Wifi displays as reported by the most recent scan, and all remembered
* Wifi displays (not necessarily available at the time).
*/
+ @UnsupportedAppUsage
public WifiDisplay[] getDisplays() {
return mDisplays;
}
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 9192652..bf5ab90 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -27,6 +27,7 @@
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -189,6 +190,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Fingerprint getFingerprint() { return mFingerprint; }
/**
@@ -718,6 +720,7 @@
* @hide
*/
@RequiresPermission(USE_FINGERPRINT)
+ @UnsupportedAppUsage
public List<Fingerprint> getEnrolledFingerprints(int userId) {
if (mService != null) try {
return mService.getEnrolledFingerprints(userId, mContext.getOpPackageName());
@@ -734,6 +737,7 @@
* @hide
*/
@RequiresPermission(USE_FINGERPRINT)
+ @UnsupportedAppUsage
public List<Fingerprint> getEnrolledFingerprints() {
return getEnrolledFingerprints(mContext.getUserId());
}
@@ -801,6 +805,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public long getAuthenticatorId() {
if (mService != null) {
try {
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 4d2841d..6ca5f0c 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -20,6 +20,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.IInputForwarder;
import android.content.Context;
import android.media.AudioAttributes;
@@ -64,6 +65,7 @@
private static InputManager sInstance;
+ @UnsupportedAppUsage
private final IInputManager mIm;
// Guarded by mInputDevicesLock
@@ -181,6 +183,7 @@
* Waits for the event to be delivered to the application and handled.
* @hide
*/
+ @UnsupportedAppUsage
public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h
/** @hide */
@@ -223,6 +226,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static InputManager getInstance() {
synchronized (InputManager.class) {
if (sInstance == null) {
@@ -866,6 +870,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean injectInputEvent(InputEvent event, int mode) {
if (event == null) {
throw new IllegalArgumentException("event must not be null");
@@ -891,6 +896,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setPointerIconType(int iconId) {
try {
mIm.setPointerIconType(iconId);
@@ -938,6 +944,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public IInputForwarder createInputForwarder(int displayId) {
try {
return mIm.createInputForwarder(displayId);
diff --git a/core/java/android/hardware/location/GeofenceHardware.java b/core/java/android/hardware/location/GeofenceHardware.java
index 66dd9fc..23d8d01 100644
--- a/core/java/android/hardware/location/GeofenceHardware.java
+++ b/core/java/android/hardware/location/GeofenceHardware.java
@@ -16,6 +16,7 @@
package android.hardware.location;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.location.Location;
import android.os.Build;
import android.os.RemoteException;
@@ -168,6 +169,7 @@
GeofenceHardwareMonitorCallbackWrapper>();
/** @hide */
+ @UnsupportedAppUsage
public GeofenceHardware(IGeofenceHardware service) {
mService = service;
}
diff --git a/core/java/android/hardware/soundtrigger/SoundTrigger.java b/core/java/android/hardware/soundtrigger/SoundTrigger.java
index dde8a33..007f4bc 100644
--- a/core/java/android/hardware/soundtrigger/SoundTrigger.java
+++ b/core/java/android/hardware/soundtrigger/SoundTrigger.java
@@ -24,6 +24,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.media.AudioFormat;
import android.os.Handler;
import android.os.Parcel;
@@ -72,6 +73,7 @@
****************************************************************************/
public static class ModuleProperties implements Parcelable {
/** Unique module ID provided by the native service */
+ @UnsupportedAppUsage
public final int id;
/** human readable voice detection engine implementor */
@@ -81,12 +83,14 @@
public final String description;
/** Unique voice engine Id (changes with each version) */
+ @UnsupportedAppUsage
public final UUID uuid;
/** Voice detection engine version */
public final int version;
/** Maximum number of active sound models */
+ @UnsupportedAppUsage
public final int maxSoundModels;
/** Maximum number of key phrases */
@@ -114,6 +118,7 @@
* recognition callback event */
public final boolean returnsTriggerInEvent;
+ @UnsupportedAppUsage
ModuleProperties(int id, String implementor, String description,
String uuid, int version, int maxSoundModels, int maxKeyphrases,
int maxUsers, int recognitionModes, boolean supportsCaptureTransition,
@@ -225,15 +230,18 @@
public static final int TYPE_GENERIC_SOUND = 1;
/** Unique sound model identifier */
+ @UnsupportedAppUsage
public final UUID uuid;
/** Sound model type (e.g. TYPE_KEYPHRASE); */
public final int type;
/** Unique sound model vendor identifier */
+ @UnsupportedAppUsage
public final UUID vendorUuid;
/** Opaque data. For use by vendor implementation and enrollment application */
+ @UnsupportedAppUsage
public final byte[] data;
public SoundModel(UUID uuid, UUID vendorUuid, int type, byte[] data) {
@@ -289,21 +297,27 @@
****************************************************************************/
public static class Keyphrase implements Parcelable {
/** Unique identifier for this keyphrase */
+ @UnsupportedAppUsage
public final int id;
/** Recognition modes supported for this key phrase in the model */
+ @UnsupportedAppUsage
public final int recognitionModes;
/** Locale of the keyphrase. JAVA Locale string e.g en_US */
+ @UnsupportedAppUsage
public final String locale;
/** Key phrase text */
+ @UnsupportedAppUsage
public final String text;
/** Users this key phrase has been trained for. countains sound trigger specific user IDs
* derived from system user IDs {@link android.os.UserHandle#getIdentifier()}. */
+ @UnsupportedAppUsage
public final int[] users;
+ @UnsupportedAppUsage
public Keyphrase(int id, int recognitionModes, String locale, String text, int[] users) {
this.id = id;
this.recognitionModes = recognitionModes;
@@ -412,8 +426,10 @@
****************************************************************************/
public static class KeyphraseSoundModel extends SoundModel implements Parcelable {
/** Key phrases in this sound model */
+ @UnsupportedAppUsage
public final Keyphrase[] keyphrases; // keyword phrases in model
+ @UnsupportedAppUsage
public KeyphraseSoundModel(
UUID uuid, UUID vendorUuid, byte[] data, Keyphrase[] keyphrases) {
super(uuid, vendorUuid, TYPE_KEYPHRASE, data);
@@ -511,6 +527,7 @@
}
};
+ @UnsupportedAppUsage
public GenericSoundModel(UUID uuid, UUID vendorUuid, byte[] data) {
super(uuid, vendorUuid, TYPE_GENERIC_SOUND, data);
}
@@ -606,6 +623,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public final int status;
/**
*
@@ -613,12 +631,14 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public final int soundModelHandle;
/**
* True if it is possible to capture audio from this utterance buffered by the hardware
*
* @hide
*/
+ @UnsupportedAppUsage
public final boolean captureAvailable;
/**
* Audio session ID to be used when capturing the utterance with an AudioRecord
@@ -626,6 +646,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public final int captureSession;
/**
* Delay in ms between end of model detection and start of audio available for capture.
@@ -659,9 +680,11 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public final byte[] data;
/** @hide */
+ @UnsupportedAppUsage
public RecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
int captureSession, int captureDelayMs, int capturePreambleMs,
boolean triggerInData, AudioFormat captureFormat, byte[] data) {
@@ -865,6 +888,7 @@
public static class RecognitionConfig implements Parcelable {
/** True if the DSP should capture the trigger sound and make it available for further
* capture. */
+ @UnsupportedAppUsage
public final boolean captureRequested;
/**
* True if the service should restart listening after the DSP triggers.
@@ -873,11 +897,14 @@
public final boolean allowMultipleTriggers;
/** List of all keyphrases in the sound model for which recognition should be performed with
* options for each keyphrase. */
+ @UnsupportedAppUsage
public final KeyphraseRecognitionExtra keyphrases[];
/** Opaque data for use by system applications who know about voice engine internals,
* typically during enrollment. */
+ @UnsupportedAppUsage
public final byte[] data;
+ @UnsupportedAppUsage
public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
KeyphraseRecognitionExtra[] keyphrases, byte[] data) {
this.captureRequested = captureRequested;
@@ -938,9 +965,12 @@
* @hide
*/
public static class ConfidenceLevel implements Parcelable {
+ @UnsupportedAppUsage
public final int userId;
+ @UnsupportedAppUsage
public final int confidenceLevel;
+ @UnsupportedAppUsage
public ConfidenceLevel(int userId, int confidenceLevel) {
this.userId = userId;
this.confidenceLevel = confidenceLevel;
@@ -1014,19 +1044,24 @@
*/
public static class KeyphraseRecognitionExtra implements Parcelable {
/** The keyphrase ID */
+ @UnsupportedAppUsage
public final int id;
/** Recognition modes matched for this event */
+ @UnsupportedAppUsage
public final int recognitionModes;
/** Confidence level for mode RECOGNITION_MODE_VOICE_TRIGGER when user identification
* is not performed */
+ @UnsupportedAppUsage
public final int coarseConfidenceLevel;
/** Confidence levels for all users recognized (KeyphraseRecognitionEvent) or to
* be recognized (RecognitionConfig) */
+ @UnsupportedAppUsage
public final ConfidenceLevel[] confidenceLevels;
+ @UnsupportedAppUsage
public KeyphraseRecognitionExtra(int id, int recognitionModes, int coarseConfidenceLevel,
ConfidenceLevel[] confidenceLevels) {
this.id = id;
@@ -1114,8 +1149,10 @@
*/
public static class KeyphraseRecognitionEvent extends RecognitionEvent implements Parcelable {
/** Indicates if the key phrase is present in the buffered audio available for capture */
+ @UnsupportedAppUsage
public final KeyphraseRecognitionExtra[] keyphraseExtras;
+ @UnsupportedAppUsage
public KeyphraseRecognitionEvent(int status, int soundModelHandle, boolean captureAvailable,
int captureSession, int captureDelayMs, int capturePreambleMs,
boolean triggerInData, AudioFormat captureFormat, byte[] data,
@@ -1236,6 +1273,7 @@
* @hide
*/
public static class GenericRecognitionEvent extends RecognitionEvent implements Parcelable {
+ @UnsupportedAppUsage
public GenericRecognitionEvent(int status, int soundModelHandle,
boolean captureAvailable, int captureSession, int captureDelayMs,
int capturePreambleMs, boolean triggerInData, AudioFormat captureFormat,
@@ -1305,6 +1343,7 @@
/** New sound model data */
public final byte[] data;
+ @UnsupportedAppUsage
SoundModelEvent(int status, int soundModelHandle, byte[] data) {
this.status = status;
this.soundModelHandle = soundModelHandle;
@@ -1405,6 +1444,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static native int listModules(ArrayList <ModuleProperties> modules);
/**
@@ -1418,6 +1458,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static SoundTriggerModule attachModule(int moduleId,
StatusListener listener,
Handler handler) {
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index e23a2bb..838765b 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -16,6 +16,7 @@
package android.hardware.soundtrigger;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -28,8 +29,10 @@
* @hide
*/
public class SoundTriggerModule {
+ @UnsupportedAppUsage
private long mNativeContext;
+ @UnsupportedAppUsage
private int mId;
private NativeEventHandlerDelegate mEventHandlerDelegate;
@@ -56,6 +59,7 @@
* Detach from this module. The {@link SoundTrigger.StatusListener} callback will not be called
* anymore and associated resources will be released.
* */
+ @UnsupportedAppUsage
public native void detach();
/**
@@ -73,6 +77,7 @@
* service fails
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
*/
+ @UnsupportedAppUsage
public native int loadSoundModel(SoundTrigger.SoundModel model, int[] soundModelHandle);
/**
@@ -87,6 +92,7 @@
* - {@link SoundTrigger#STATUS_DEAD_OBJECT} if the binder transaction to the native
* service fails
*/
+ @UnsupportedAppUsage
public native int unloadSoundModel(int soundModelHandle);
/**
@@ -106,6 +112,7 @@
* service fails
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
*/
+ @UnsupportedAppUsage
public native int startRecognition(int soundModelHandle, SoundTrigger.RecognitionConfig config);
/**
@@ -121,6 +128,7 @@
* service fails
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence
*/
+ @UnsupportedAppUsage
public native int stopRecognition(int soundModelHandle);
private class NativeEventHandlerDelegate {
@@ -181,6 +189,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
private static void postEventFromNative(Object module_ref,
int what, int arg1, int arg2, Object obj) {
SoundTriggerModule module = (SoundTriggerModule)((WeakReference)module_ref).get();
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 1e98301..26c5a95 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.Preconditions;
@@ -60,6 +61,7 @@
private @Nullable Parcelable[] mConfigurations;
/** All interfaces on the device. Initialized on first call to getInterfaceList */
+ @UnsupportedAppUsage
private @Nullable UsbInterface[] mInterfaces;
/**
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 9e5174a..71297c1 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Build;
import android.os.ParcelFileDescriptor;
@@ -46,6 +47,7 @@
private Context mContext;
// used by the JNI code
+ @UnsupportedAppUsage
private long mNativeContext;
private final CloseGuard mCloseGuard = CloseGuard.get();
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 46142e3..3141be4 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -25,6 +25,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
@@ -87,6 +88,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public static final String ACTION_USB_STATE =
"android.hardware.usb.action.USB_STATE";
@@ -163,6 +165,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public static final String USB_CONNECTED = "connected";
/**
@@ -189,6 +192,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public static final String USB_DATA_UNLOCKED = "unlocked";
/**
@@ -197,6 +201,7 @@
*
* {@hide}
*/
+ @UnsupportedAppUsage
public static final String USB_FUNCTION_NONE = "none";
/**
@@ -363,6 +368,7 @@
/**
* {@hide}
*/
+ @UnsupportedAppUsage
public UsbManager(Context context, IUsbManager service) {
mContext = context;
mService = service;
@@ -645,6 +651,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public boolean isFunctionEnabled(String function) {
try {
return mService.isFunctionEnabled(function);
@@ -693,6 +700,7 @@
* {@hide}
*/
@Deprecated
+ @UnsupportedAppUsage
public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
try {
mService.setCurrentFunction(functions, usbDataUnlocked);
@@ -774,6 +782,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public UsbPort[] getPorts() {
if (mService == null) {
return null;
@@ -793,6 +802,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public UsbPortStatus getPortStatus(UsbPort port) {
Preconditions.checkNotNull(port, "port must not be null");
@@ -822,6 +832,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setPortRoles(UsbPort port, int powerRole, int dataRole) {
Preconditions.checkNotNull(port, "port must not be null");
UsbPort.checkRoles(powerRole, dataRole);
diff --git a/core/java/android/hardware/usb/UsbPortStatus.java b/core/java/android/hardware/usb/UsbPortStatus.java
index 5c0e81a..2cd8209 100644
--- a/core/java/android/hardware/usb/UsbPortStatus.java
+++ b/core/java/android/hardware/usb/UsbPortStatus.java
@@ -16,6 +16,7 @@
package android.hardware.usb;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -47,6 +48,7 @@
*
* @return True if there is anything connected to the port.
*/
+ @UnsupportedAppUsage
public boolean isConnected() {
return mCurrentMode != 0;
}
@@ -57,6 +59,7 @@
* @return The current mode: {@link UsbPort#MODE_DFP}, {@link UsbPort#MODE_UFP},
* or 0 if nothing is connected.
*/
+ @UnsupportedAppUsage
public int getCurrentMode() {
return mCurrentMode;
}
@@ -67,6 +70,7 @@
* @return The current power role: {@link UsbPort#POWER_ROLE_SOURCE},
* {@link UsbPort#POWER_ROLE_SINK}, or 0 if nothing is connected.
*/
+ @UnsupportedAppUsage
public int getCurrentPowerRole() {
return mCurrentPowerRole;
}
@@ -77,6 +81,7 @@
* @return The current data role: {@link UsbPort#DATA_ROLE_HOST},
* {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if nothing is connected.
*/
+ @UnsupportedAppUsage
public int getCurrentDataRole() {
return mCurrentDataRole;
}
@@ -90,12 +95,14 @@
* @param dataRole The data role to check: either {@link UsbPort#DATA_ROLE_HOST}
* or {@link UsbPort#DATA_ROLE_DEVICE}, or 0 if no data role.
*/
+ @UnsupportedAppUsage
public boolean isRoleCombinationSupported(int powerRole, int dataRole) {
return (mSupportedRoleCombinations &
UsbPort.combineRolesAsBit(powerRole, dataRole)) != 0;
}
/** @hide */
+ @UnsupportedAppUsage
public int getSupportedRoleCombinations() {
return mSupportedRoleCombinations;
}
diff --git a/core/java/android/hardware/usb/UsbRequest.java b/core/java/android/hardware/usb/UsbRequest.java
index f59c87e..7abf3e9 100644
--- a/core/java/android/hardware/usb/UsbRequest.java
+++ b/core/java/android/hardware/usb/UsbRequest.java
@@ -17,6 +17,7 @@
package android.hardware.usb;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.util.Log;
@@ -47,14 +48,17 @@
static final int MAX_USBFS_BUFFER_SIZE = 16384;
// used by the JNI code
+ @UnsupportedAppUsage
private long mNativeContext;
private UsbEndpoint mEndpoint;
/** The buffer that is currently being read / written */
+ @UnsupportedAppUsage
private ByteBuffer mBuffer;
/** The amount of data to read / write when using {@link #queue} */
+ @UnsupportedAppUsage
private int mLength;
// for client use
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 52a2354..081d8d1 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -372,7 +372,7 @@
if (score < 0) {
throw new IllegalArgumentException("Score must be >= 0");
}
- queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, score, 0);
}
/**
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 5752b6f..591370f 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -241,6 +241,9 @@
} else {
try {
key = bp.getInterfaceDescriptor();
+ if ((key == null || key.isEmpty()) && !bp.isBinderAlive()) {
+ key = "<proxy to dead node>";
+ }
} catch (Throwable t) {
key = "<exception during getDescriptor>";
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9c3a409..68572dd 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -469,6 +469,12 @@
* The height of the image/video in pixels.
*/
public static final String HEIGHT = "height";
+
+ /**
+ * Package that contributed this media.
+ * @hide
+ */
+ public static final String OWNER_PACKAGE_NAME = "owner_package_name";
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 788579f..fec8ccc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8273,7 +8273,6 @@
CLONE_TO_MANAGED_PROFILE.add(ACCESSIBILITY_ENABLED);
CLONE_TO_MANAGED_PROFILE.add(ALLOW_MOCK_LOCATION);
CLONE_TO_MANAGED_PROFILE.add(ALLOWED_GEOLOCATION_ORIGINS);
- CLONE_TO_MANAGED_PROFILE.add(AUTOFILL_SERVICE);
CLONE_TO_MANAGED_PROFILE.add(DEFAULT_INPUT_METHOD);
CLONE_TO_MANAGED_PROFILE.add(ENABLED_ACCESSIBILITY_SERVICES);
CLONE_TO_MANAGED_PROFILE.add(ENABLED_INPUT_METHODS);
@@ -10659,6 +10658,15 @@
public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
/**
+ * Feature flag to enable or disable the activity starts logging feature.
+ * Type: int (0 for false, 1 for true)
+ * Default: 0
+ * @hide
+ */
+ public static final String ACTIVITY_STARTS_LOGGING_ENABLED
+ = "activity_starts_logging_enabled";
+
+ /**
* App ops specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
*
diff --git a/core/java/android/util/MemoryIntArray.java b/core/java/android/util/MemoryIntArray.java
index bf33519..d5bec0f 100644
--- a/core/java/android/util/MemoryIntArray.java
+++ b/core/java/android/util/MemoryIntArray.java
@@ -20,9 +20,10 @@
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
-import libcore.io.IoUtils;
import dalvik.system.CloseGuard;
+import libcore.io.IoUtils;
+
import java.io.Closeable;
import java.io.IOException;
import java.util.UUID;
@@ -56,7 +57,7 @@
private final boolean mIsOwner;
private final long mMemoryAddr;
- private int mFd = -1;
+ private ParcelFileDescriptor mFd;
/**
* Creates a new instance.
@@ -71,8 +72,8 @@
}
mIsOwner = true;
final String name = UUID.randomUUID().toString();
- mFd = nativeCreate(name, size);
- mMemoryAddr = nativeOpen(mFd, mIsOwner);
+ mFd = ParcelFileDescriptor.adoptFd(nativeCreate(name, size));
+ mMemoryAddr = nativeOpen(mFd.getFd(), mIsOwner);
mCloseGuard.open("close");
}
@@ -82,8 +83,8 @@
if (pfd == null) {
throw new IOException("No backing file descriptor");
}
- mFd = pfd.detachFd();
- mMemoryAddr = nativeOpen(mFd, mIsOwner);
+ mFd = ParcelFileDescriptor.adoptFd(pfd.detachFd());
+ mMemoryAddr = nativeOpen(mFd.getFd(), mIsOwner);
mCloseGuard.open("close");
}
@@ -105,7 +106,7 @@
public int get(int index) throws IOException {
enforceNotClosed();
enforceValidIndex(index);
- return nativeGet(mFd, mMemoryAddr, index);
+ return nativeGet(mFd.getFd(), mMemoryAddr, index);
}
/**
@@ -121,7 +122,7 @@
enforceNotClosed();
enforceWritable();
enforceValidIndex(index);
- nativeSet(mFd, mMemoryAddr, index, value);
+ nativeSet(mFd.getFd(), mMemoryAddr, index, value);
}
/**
@@ -131,7 +132,7 @@
*/
public int size() throws IOException {
enforceNotClosed();
- return nativeSize(mFd);
+ return nativeSize(mFd.getFd());
}
/**
@@ -142,8 +143,9 @@
@Override
public void close() throws IOException {
if (!isClosed()) {
- nativeClose(mFd, mMemoryAddr, mIsOwner);
- mFd = -1;
+ nativeClose(mFd.getFd(), mMemoryAddr, mIsOwner);
+ mFd.close();
+ mFd = null;
mCloseGuard.close();
}
}
@@ -152,7 +154,7 @@
* @return Whether this array is closed and shouldn't be used.
*/
public boolean isClosed() {
- return mFd == -1;
+ return mFd == null;
}
@Override
@@ -175,13 +177,8 @@
@Override
public void writeToParcel(Parcel parcel, int flags) {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.adoptFd(mFd);
- try {
- // Don't let writing to a parcel to close our fd - plz
- parcel.writeParcelable(pfd, flags & ~Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } finally {
- pfd.detachFd();
- }
+ // Don't let writing to a parcel to close our fd - plz
+ parcel.writeParcelable(mFd, flags & ~Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
@Override
@@ -195,13 +192,13 @@
if (getClass() != obj.getClass()) {
return false;
}
- MemoryIntArray other = (MemoryIntArray) obj;
- return mFd == other.mFd;
+
+ return false;
}
@Override
public int hashCode() {
- return mFd;
+ return mFd.hashCode();
}
private void enforceNotClosed() {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 131fe13..092702c 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -421,8 +421,8 @@
boolean isWindowTraceEnabled();
/**
- * Requests that the WindowManager sends WindowManagerPolicy#ACTION_USER_ACTIVITY_NOTIFICATION
- * on the next user activity.
+ * Requests that the WindowManager sends
+ * WindowManagerPolicyConstants#ACTION_USER_ACTIVITY_NOTIFICATION on the next user activity.
*/
void requestUserActivityNotification();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e2e2b00..65ab3ac 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9008,8 +9008,6 @@
* composition. For more details see {@link AccessibilityDelegate}.
*
* @return The delegate, or null if none set.
- *
- * @hide
*/
public AccessibilityDelegate getAccessibilityDelegate() {
return mAccessibilityDelegate;
diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java
index f63c43f..115ba18 100644
--- a/core/java/com/android/internal/app/procstats/AssociationState.java
+++ b/core/java/com/android/internal/app/procstats/AssociationState.java
@@ -20,9 +20,12 @@
import android.os.Parcel;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.service.procstats.ProcessStatsAssociationStateProto;
+import android.service.procstats.ProcessStatsStateProto;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -656,6 +659,55 @@
}
}
+ public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ final long token = proto.start(fieldId);
+
+ proto.write(ProcessStatsAssociationStateProto.COMPONENT_NAME, mName);
+ final int NSRC = mSources.size();
+ for (int isrc = 0; isrc < NSRC; isrc++) {
+ final SourceKey key = mSources.keyAt(isrc);
+ final SourceState src = mSources.valueAt(isrc);
+ final long sourceToken = proto.start(ProcessStatsAssociationStateProto.SOURCES);
+ proto.write(ProcessStatsAssociationStateProto.Source.PROCESS, key.mProcess);
+ proto.write(ProcessStatsAssociationStateProto.Source.UID, key.mUid);
+ proto.write(ProcessStatsAssociationStateProto.Source.TOTAL_COUNT, src.mCount);
+ long duration = src.mDuration;
+ if (src.mNesting > 0) {
+ duration += now - src.mStartUptime;
+ }
+ proto.write(ProcessStatsAssociationStateProto.Source.TOTAL_DURATION_MS, duration);
+ if (src.mActiveCount != 0) {
+ proto.write(ProcessStatsAssociationStateProto.Source.ACTIVE_COUNT,
+ src.mActiveCount);
+ }
+ final long timeNow = src.mActiveStartUptime != 0 ? (now-src.mActiveStartUptime) : 0;
+ if (src.mDurations != null) {
+ final int N = src.mDurations.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int dkey = src.mDurations.getKeyAt(i);
+ duration = src.mDurations.getValue(dkey);
+ if (dkey == src.mActiveProcState) {
+ duration += timeNow;
+ }
+ final int procState = SparseMappingTable.getIdFromKey(dkey);
+ DumpUtils.printProcStateDurationProto(proto,
+ ProcessStatsAssociationStateProto.Source.ACTIVE_STATES,
+ procState, duration);
+ }
+ } else {
+ duration = src.mActiveDuration + timeNow;
+ if (duration != 0) {
+ DumpUtils.printProcStateDurationProto(proto,
+ ProcessStatsAssociationStateProto.Source.ACTIVE_STATES,
+ src.mActiveProcState, duration);
+ }
+ }
+ proto.end(sourceToken);
+ }
+
+ proto.end(token);
+ }
+
public String toString() {
return "AssociationState{" + Integer.toHexString(System.identityHashCode(this))
+ " " + mName + " pkg=" + mPackageState.mPackageName + " proc="
diff --git a/core/java/com/android/internal/app/procstats/DumpUtils.java b/core/java/com/android/internal/app/procstats/DumpUtils.java
index e6073e5..701391d 100644
--- a/core/java/com/android/internal/app/procstats/DumpUtils.java
+++ b/core/java/com/android/internal/app/procstats/DumpUtils.java
@@ -16,32 +16,15 @@
package com.android.internal.app.procstats;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.os.SystemProperties;
import android.os.UserHandle;
-import android.service.procstats.ProcessStatsProto;
-import android.text.format.DateFormat;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.DebugUtils;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
+import android.service.procstats.ProcessStatsStateProto;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import static com.android.internal.app.procstats.ProcessStats.*;
-import java.io.IOException;
-import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Objects;
/**
* Utilities for dumping.
@@ -124,20 +107,20 @@
STATE_TAGS[STATE_CACHED_EMPTY] = "e";
STATE_PROTO_ENUMS = new int[STATE_COUNT];
- STATE_PROTO_ENUMS[STATE_PERSISTENT] = ProcessStatsProto.State.PERSISTENT;
- STATE_PROTO_ENUMS[STATE_TOP] = ProcessStatsProto.State.TOP;
- STATE_PROTO_ENUMS[STATE_IMPORTANT_FOREGROUND] = ProcessStatsProto.State.IMPORTANT_FOREGROUND;
- STATE_PROTO_ENUMS[STATE_IMPORTANT_BACKGROUND] = ProcessStatsProto.State.IMPORTANT_BACKGROUND;
- STATE_PROTO_ENUMS[STATE_BACKUP] = ProcessStatsProto.State.BACKUP;
- STATE_PROTO_ENUMS[STATE_SERVICE] = ProcessStatsProto.State.SERVICE;
- STATE_PROTO_ENUMS[STATE_SERVICE_RESTARTING] = ProcessStatsProto.State.SERVICE_RESTARTING;
- STATE_PROTO_ENUMS[STATE_RECEIVER] = ProcessStatsProto.State.RECEIVER;
- STATE_PROTO_ENUMS[STATE_HEAVY_WEIGHT] = ProcessStatsProto.State.HEAVY_WEIGHT;
- STATE_PROTO_ENUMS[STATE_HOME] = ProcessStatsProto.State.HOME;
- STATE_PROTO_ENUMS[STATE_LAST_ACTIVITY] = ProcessStatsProto.State.LAST_ACTIVITY;
- STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY] = ProcessStatsProto.State.CACHED_ACTIVITY;
- STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY_CLIENT] = ProcessStatsProto.State.CACHED_ACTIVITY_CLIENT;
- STATE_PROTO_ENUMS[STATE_CACHED_EMPTY] = ProcessStatsProto.State.CACHED_EMPTY;
+ STATE_PROTO_ENUMS[STATE_PERSISTENT] = ProcessStatsStateProto.PERSISTENT;
+ STATE_PROTO_ENUMS[STATE_TOP] = ProcessStatsStateProto.TOP;
+ STATE_PROTO_ENUMS[STATE_IMPORTANT_FOREGROUND] = ProcessStatsStateProto.IMPORTANT_FOREGROUND;
+ STATE_PROTO_ENUMS[STATE_IMPORTANT_BACKGROUND] = ProcessStatsStateProto.IMPORTANT_BACKGROUND;
+ STATE_PROTO_ENUMS[STATE_BACKUP] = ProcessStatsStateProto.BACKUP;
+ STATE_PROTO_ENUMS[STATE_SERVICE] = ProcessStatsStateProto.SERVICE;
+ STATE_PROTO_ENUMS[STATE_SERVICE_RESTARTING] = ProcessStatsStateProto.SERVICE_RESTARTING;
+ STATE_PROTO_ENUMS[STATE_RECEIVER] = ProcessStatsStateProto.RECEIVER;
+ STATE_PROTO_ENUMS[STATE_HEAVY_WEIGHT] = ProcessStatsStateProto.HEAVY_WEIGHT;
+ STATE_PROTO_ENUMS[STATE_HOME] = ProcessStatsStateProto.HOME;
+ STATE_PROTO_ENUMS[STATE_LAST_ACTIVITY] = ProcessStatsStateProto.LAST_ACTIVITY;
+ STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY] = ProcessStatsStateProto.CACHED_ACTIVITY;
+ STATE_PROTO_ENUMS[STATE_CACHED_ACTIVITY_CLIENT] = ProcessStatsStateProto.CACHED_ACTIVITY_CLIENT;
+ STATE_PROTO_ENUMS[STATE_CACHED_EMPTY] = ProcessStatsStateProto.CACHED_EMPTY;
}
public static final String[] ADJ_SCREEN_NAMES_CSV = new String[] {
@@ -155,8 +138,8 @@
};
static final int[] ADJ_SCREEN_PROTO_ENUMS = new int[] {
- ProcessStatsProto.State.OFF,
- ProcessStatsProto.State.ON
+ ProcessStatsStateProto.OFF,
+ ProcessStatsStateProto.ON
};
static final String[] ADJ_MEM_TAGS = new String[] {
@@ -164,10 +147,10 @@
};
static final int[] ADJ_MEM_PROTO_ENUMS = new int[] {
- ProcessStatsProto.State.NORMAL,
- ProcessStatsProto.State.MODERATE,
- ProcessStatsProto.State.LOW,
- ProcessStatsProto.State.CRITICAL
+ ProcessStatsStateProto.NORMAL,
+ ProcessStatsStateProto.MODERATE,
+ ProcessStatsStateProto.LOW,
+ ProcessStatsStateProto.CRITICAL
};
static final String CSV_SEP = "\t";
@@ -281,6 +264,23 @@
printArrayEntry(pw, ADJ_MEM_TAGS, state, 1);
}
+ public static void printProcStateAdjTagProto(ProtoOutputStream proto, long screenId, long memId,
+ int state) {
+ state = printProto(proto, screenId, ADJ_SCREEN_PROTO_ENUMS,
+ state, ADJ_SCREEN_MOD * STATE_COUNT);
+ printProto(proto, memId, ADJ_MEM_PROTO_ENUMS, state, STATE_COUNT);
+ }
+
+ public static void printProcStateDurationProto(ProtoOutputStream proto, long fieldId,
+ int procState, long duration) {
+ final long stateToken = proto.start(fieldId);
+ DumpUtils.printProto(proto, ProcessStatsStateProto.PROCESS_STATE,
+ DumpUtils.STATE_PROTO_ENUMS, procState, 1);
+ proto.write(ProcessStatsStateProto.DURATION_MS, duration);
+ proto.end(stateToken);
+
+ }
+
public static void printProcStateTagAndValue(PrintWriter pw, int state, long value) {
pw.print(',');
printProcStateTag(pw, state);
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 943c8bd..d7f4736 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -20,6 +20,7 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.service.procstats.ProcessStatsProto;
+import android.service.procstats.ProcessStatsStateProto;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.Log;
@@ -1377,14 +1378,14 @@
}
final long stateToken = proto.start(ProcessStatsProto.STATES);
DumpUtils.printProcStateTagProto(proto,
- ProcessStatsProto.State.SCREEN_STATE,
- ProcessStatsProto.State.MEMORY_STATE,
- ProcessStatsProto.State.PROCESS_STATE,
+ ProcessStatsStateProto.SCREEN_STATE,
+ ProcessStatsStateProto.MEMORY_STATE,
+ ProcessStatsStateProto.PROCESS_STATE,
type);
long duration = durationByState.get(type);
durationByState.delete(type); // remove the key since it is already being dumped.
- proto.write(ProcessStatsProto.State.DURATION_MS, duration);
+ proto.write(ProcessStatsStateProto.DURATION_MS, duration);
mPssTable.writeStatsToProtoForKey(proto, key);
@@ -1394,18 +1395,18 @@
for (int i = 0; i < durationByState.size(); i++) {
final long stateToken = proto.start(ProcessStatsProto.STATES);
DumpUtils.printProcStateTagProto(proto,
- ProcessStatsProto.State.SCREEN_STATE,
- ProcessStatsProto.State.MEMORY_STATE,
- ProcessStatsProto.State.PROCESS_STATE,
+ ProcessStatsStateProto.SCREEN_STATE,
+ ProcessStatsStateProto.MEMORY_STATE,
+ ProcessStatsStateProto.PROCESS_STATE,
durationByState.keyAt(i));
- proto.write(ProcessStatsProto.State.DURATION_MS, durationByState.valueAt(i));
+ proto.write(ProcessStatsStateProto.DURATION_MS, durationByState.valueAt(i));
proto.end(stateToken);
}
final long totalRunningDuration = getTotalRunningDuration(now);
if (totalRunningDuration > 0) {
final long stateToken = proto.start(ProcessStatsProto.TOTAL_RUNNING_STATE);
- proto.write(ProcessStatsProto.State.DURATION_MS, totalRunningDuration);
+ proto.write(ProcessStatsStateProto.DURATION_MS, totalRunningDuration);
if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
PssTable.writeStatsToProto(proto, mTotalRunningPss, 0);
}
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index d088354..14faf66 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -23,6 +23,7 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.service.procstats.ProcessStatsPackageProto;
import android.service.procstats.ProcessStatsSectionProto;
import android.text.format.DateFormat;
import android.util.ArrayMap;
@@ -2013,10 +2014,8 @@
}
public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
- final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
- mPackages.getMap();
-
final long token = proto.start(fieldId);
+
proto.write(ProcessStatsSectionProto.START_REALTIME_MS, mTimePeriodStartRealtime);
proto.write(ProcessStatsSectionProto.END_REALTIME_MS,
mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
@@ -2041,16 +2040,31 @@
proto.write(ProcessStatsSectionProto.STATUS, ProcessStatsSectionProto.STATUS_PARTIAL);
}
- ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
+ final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
for (int ip=0; ip<procMap.size(); ip++) {
- String procName = procMap.keyAt(ip);
- SparseArray<ProcessState> uids = procMap.valueAt(ip);
+ final String procName = procMap.keyAt(ip);
+ final SparseArray<ProcessState> uids = procMap.valueAt(ip);
for (int iu=0; iu<uids.size(); iu++) {
final int uid = uids.keyAt(iu);
final ProcessState procState = uids.valueAt(iu);
- procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName, uid, now);
+ procState.writeToProto(proto, ProcessStatsSectionProto.PROCESS_STATS, procName,
+ uid, now);
}
}
+
+ final ArrayMap<String, SparseArray<LongSparseArray<PackageState>>> pkgMap =
+ mPackages.getMap();
+ for (int ip = 0; ip < pkgMap.size(); ip++) {
+ final SparseArray<LongSparseArray<PackageState>> uids = pkgMap.valueAt(ip);
+ for (int iu = 0; iu < uids.size(); iu++) {
+ final LongSparseArray<PackageState> vers = uids.valueAt(iu);
+ for (int iv = 0; iv < vers.size(); iv++) {
+ final PackageState pkgState = vers.valueAt(iv);
+ pkgState.writeToProto(proto, ProcessStatsSectionProto.PACKAGE_STATS, now);
+ }
+ }
+ }
+
proto.end(token);
}
@@ -2095,6 +2109,33 @@
if (DEBUG) Slog.d(TAG, "GETASC: creating " + as + " in " + proc.getName());
return as;
}
+
+ public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ final long token = proto.start(fieldId);
+
+ proto.write(ProcessStatsPackageProto.PACKAGE, mPackageName);
+ proto.write(ProcessStatsPackageProto.UID, mUid);
+ proto.write(ProcessStatsPackageProto.VERSION, mVersionCode);
+
+ for (int ip = 0; ip < mProcesses.size(); ip++) {
+ final String procName = mProcesses.keyAt(ip);
+ final ProcessState procState = mProcesses.valueAt(ip);
+ procState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, procName,
+ mUid, now);
+ }
+
+ for (int is = 0; is < mServices.size(); is++) {
+ final ServiceState serviceState = mServices.valueAt(is);
+ serviceState.writeToProto(proto, ProcessStatsPackageProto.PROCESS_STATS, now);
+ }
+
+ for (int ia=0; ia<mAssociations.size(); ia++) {
+ final AssociationState ascState = mAssociations.valueAt(ia);
+ ascState.writeToProto(proto, ProcessStatsPackageProto.ASSOCIATION_STATS, now);
+ }
+
+ proto.end(token);
+ }
}
public static final class ProcessDataCollection {
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
index f858e55..fc93c3a 100644
--- a/core/java/com/android/internal/app/procstats/PssTable.java
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -28,7 +28,7 @@
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
-import android.service.procstats.ProcessStatsProto;
+import android.service.procstats.ProcessStatsStateProto;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;
@@ -153,16 +153,16 @@
public static void writeStatsToProto(ProtoOutputStream proto, final long[] stats,
final int statsIndex) {
- proto.write(ProcessStatsProto.State.SAMPLE_SIZE, stats[statsIndex + PSS_SAMPLE_COUNT]);
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.PSS,
+ proto.write(ProcessStatsStateProto.SAMPLE_SIZE, stats[statsIndex + PSS_SAMPLE_COUNT]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.PSS,
stats[statsIndex + PSS_MINIMUM],
stats[statsIndex + PSS_AVERAGE],
stats[statsIndex + PSS_MAXIMUM]);
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.USS,
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.USS,
stats[statsIndex + PSS_USS_MINIMUM],
stats[statsIndex + PSS_USS_AVERAGE],
stats[statsIndex + PSS_USS_MAXIMUM]);
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsStateProto.RSS,
stats[statsIndex + PSS_RSS_MINIMUM],
stats[statsIndex + PSS_RSS_AVERAGE],
stats[statsIndex + PSS_RSS_MAXIMUM]);
diff --git a/core/java/com/android/internal/app/procstats/ServiceState.java b/core/java/com/android/internal/app/procstats/ServiceState.java
index 04e61e0..16975a4 100644
--- a/core/java/com/android/internal/app/procstats/ServiceState.java
+++ b/core/java/com/android/internal/app/procstats/ServiceState.java
@@ -19,9 +19,16 @@
import android.os.Parcel;
import android.os.SystemClock;
+import android.service.procstats.ProcessStatsProto;
+import android.service.procstats.ProcessStatsServiceStateProto;
+import android.service.procstats.ProcessStatsStateProto;
import android.util.Slog;
+import android.util.SparseLongArray;
import android.util.TimeUtils;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+import static com.android.internal.app.procstats.ProcessStats.PSS_SAMPLE_COUNT;
import static com.android.internal.app.procstats.ProcessStats.STATE_NOTHING;
import java.io.PrintWriter;
@@ -550,6 +557,66 @@
pw.println();
}
+ public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
+ final long token = proto.start(fieldId);
+ proto.write(ProcessStatsServiceStateProto.SERVICE_NAME, mName);
+ writeTypeToProto(proto, ProcessStatsServiceStateProto.RUNNING_OP,
+ ServiceState.SERVICE_RUN, mRunCount, mRunState, mRunStartTime, now);
+ writeTypeToProto(proto, ProcessStatsServiceStateProto.STARTED_OP,
+ ServiceState.SERVICE_STARTED, mStartedCount, mStartedState, mStartedStartTime, now);
+ writeTypeToProto(proto, ProcessStatsServiceStateProto.FOREGROUND_OP,
+ ServiceState.SERVICE_FOREGROUND, mForegroundCount, mForegroundState,
+ mForegroundStartTime, now);
+ writeTypeToProto(proto, ProcessStatsServiceStateProto.BOUND_OP,
+ ServiceState.SERVICE_BOUND, mBoundCount, mBoundState, mBoundStartTime, now);
+ writeTypeToProto(proto, ProcessStatsServiceStateProto.EXECUTING_OP,
+ ServiceState.SERVICE_EXEC, mExecCount, mExecState, mExecStartTime, now);
+ proto.end(token);
+ }
+
+ public void writeTypeToProto(ProtoOutputStream proto, long fieldId, int serviceType,
+ int opCount, int curState, long curStartTime, long now) {
+ if (opCount <= 0) {
+ return;
+ }
+ final long token = proto.start(fieldId);
+
+ proto.write(ProcessStatsServiceStateProto.OperationInfo.COUNT, opCount);
+ boolean didCurState = false;
+ final int N = mDurations.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int key = mDurations.getKeyAt(i);
+ long time = mDurations.getValue(key);
+ int type = SparseMappingTable.getIdFromKey(key);
+ int memFactor = type / ServiceState.SERVICE_COUNT;
+ type %= ServiceState.SERVICE_COUNT;
+ if (type != serviceType) {
+ continue;
+ }
+ if (curState == memFactor) {
+ didCurState = true;
+ time += now - curStartTime;
+ }
+ final long stateToken = proto.start(ProcessStatsServiceStateProto.OperationInfo.STATES);
+ DumpUtils.printProcStateAdjTagProto(proto,
+ ProcessStatsStateProto.SCREEN_STATE,
+ ProcessStatsStateProto.MEMORY_STATE,
+ type);
+ proto.write(ProcessStatsStateProto.DURATION_MS, time);
+ proto.end(stateToken);
+ }
+ if (!didCurState && curState != STATE_NOTHING) {
+ final long stateToken = proto.start(ProcessStatsServiceStateProto.OperationInfo.STATES);
+ DumpUtils.printProcStateAdjTagProto(proto,
+ ProcessStatsStateProto.SCREEN_STATE,
+ ProcessStatsStateProto.MEMORY_STATE,
+ curState);
+ proto.write(ProcessStatsStateProto.DURATION_MS, now - curStartTime);
+ proto.end(stateToken);
+ }
+
+ proto.end(token);
+ }
public String toString() {
return "ServiceState{" + Integer.toHexString(System.identityHashCode(this))
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 0ba9a8c..b1bb555 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1748,19 +1748,20 @@
}
}
-
- size_t listSize = builder.getSize();
- uint8_t opcodeListBuf[listSize];
- err = builder.buildOpList(opcodeListBuf);
- if (err == OK) {
- BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST2, listSize, opcodeListBuf,
- TIFF_IFD_0), env, TAG_OPCODELIST2, writer);
- } else {
- ALOGE("%s: Could not build list of opcodes for distortion correction and lens shading"
- "map.", __FUNCTION__);
- jniThrowRuntimeException(env, "failed to construct opcode list for distortion"
- " correction and lens shading map");
- return nullptr;
+ if (builder.getCount() > 0) {
+ size_t listSize = builder.getSize();
+ uint8_t opcodeListBuf[listSize];
+ err = builder.buildOpList(opcodeListBuf);
+ if (err == OK) {
+ BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST2, listSize,
+ opcodeListBuf, TIFF_IFD_0), env, TAG_OPCODELIST2, writer);
+ } else {
+ ALOGE("%s: Could not build list of opcodes for lens shading map and bad pixel "
+ "correction.", __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to construct opcode list for lens shading "
+ "map and bad pixel correction");
+ return nullptr;
+ }
}
}
@@ -1846,18 +1847,20 @@
}
}
- size_t listSize = builder.getSize();
- uint8_t opcodeListBuf[listSize];
- err = builder.buildOpList(opcodeListBuf);
- if (err == OK) {
- BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST3, listSize, opcodeListBuf,
- TIFF_IFD_0), env, TAG_OPCODELIST3, writer);
- } else {
- ALOGE("%s: Could not build list of opcodes for distortion correction and lens shading"
- "map.", __FUNCTION__);
- jniThrowRuntimeException(env, "failed to construct opcode list for distortion"
- " correction and lens shading map");
- return nullptr;
+ if (builder.getCount() > 0) {
+ size_t listSize = builder.getSize();
+ uint8_t opcodeListBuf[listSize];
+ err = builder.buildOpList(opcodeListBuf);
+ if (err == OK) {
+ BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_OPCODELIST3, listSize,
+ opcodeListBuf, TIFF_IFD_0), env, TAG_OPCODELIST3, writer);
+ } else {
+ ALOGE("%s: Could not build list of opcodes for distortion correction.",
+ __FUNCTION__);
+ jniThrowRuntimeException(env, "failed to construct opcode list for distortion"
+ " correction");
+ return nullptr;
+ }
}
}
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 17ab956..e64d2af 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -96,7 +96,7 @@
return toJavaStringArray(env, cStrings);
}
-static jint verify(JNIEnv* env, jobjectArray packageInfo, android::vintf::DisabledChecks checks) {
+static jint verify(JNIEnv* env, jobjectArray packageInfo, android::vintf::CheckFlags::Type checks) {
std::vector<std::string> cPackageInfo;
if (packageInfo) {
size_t count = env->GetArrayLength(packageInfo);
@@ -116,11 +116,11 @@
}
static jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) {
- return verify(env, packageInfo, ::android::vintf::ENABLE_ALL_CHECKS);
+ return verify(env, packageInfo, ::android::vintf::CheckFlags::ENABLE_ALL_CHECKS);
}
static jint android_os_VintfObject_verifyWithoutAvb(JNIEnv* env, jclass) {
- return verify(env, nullptr, ::android::vintf::DISABLE_AVB_CHECK);
+ return verify(env, nullptr, ::android::vintf::CheckFlags::DISABLE_AVB_CHECK);
}
static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index b0ea5e0..3db7f9d 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -24,6 +24,7 @@
import "frameworks/base/core/proto/android/server/surfaceanimator.proto";
import "frameworks/base/core/proto/android/view/displaycutout.proto";
import "frameworks/base/core/proto/android/view/displayinfo.proto";
+import "frameworks/base/core/proto/android/view/enums.proto";
import "frameworks/base/core/proto/android/view/surface.proto";
import "frameworks/base/core/proto/android/view/windowlayoutparams.proto";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
@@ -134,32 +135,8 @@
APP_STATE_TIMEOUT = 3;
}
optional AppState app_transition_state = 1;
- /* definitions for constants found in {@link com.android.server.wm.AppTransition} */
- enum TransitionType {
- TRANSIT_NONE = 0;
- TRANSIT_UNSET = -1;
- TRANSIT_ACTIVITY_OPEN = 6;
- TRANSIT_ACTIVITY_CLOSE = 7;
- TRANSIT_TASK_OPEN = 8;
- TRANSIT_TASK_CLOSE = 9;
- TRANSIT_TASK_TO_FRONT = 10;
- TRANSIT_TASK_TO_BACK = 11;
- TRANSIT_WALLPAPER_CLOSE = 12;
- TRANSIT_WALLPAPER_OPEN = 13;
- TRANSIT_WALLPAPER_INTRA_OPEN = 14;
- TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
- TRANSIT_TASK_OPEN_BEHIND = 16;
- TRANSIT_TASK_IN_PLACE = 17;
- TRANSIT_ACTIVITY_RELAUNCH = 18;
- TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
- TRANSIT_KEYGUARD_GOING_AWAY = 20;
- TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
- TRANSIT_KEYGUARD_OCCLUDE = 22;
- TRANSIT_KEYGUARD_UNOCCLUDE = 23;
- TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24;
- TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
- }
- optional TransitionType last_used_app_transition = 2;
+
+ optional .android.view.TransitionTypeEnum last_used_app_transition = 2;
}
/* represents DisplayContent */
@@ -288,11 +265,10 @@
optional int32 stack_id = 4;
optional .android.view.WindowLayoutParamsProto attributes = 5;
optional .android.graphics.RectProto given_content_insets = 6;
- reserved 7 to 10;
-// optional .android.graphics.RectProto frame = 7;
-// optional .android.graphics.RectProto containing_frame = 8;
-// optional .android.graphics.RectProto parent_frame = 9;
-// optional .android.graphics.RectProto content_frame = 10;
+ optional .android.graphics.RectProto frame = 7 [deprecated=true];
+ optional .android.graphics.RectProto containing_frame = 8 [deprecated=true];
+ optional .android.graphics.RectProto parent_frame = 9 [deprecated=true];
+ optional .android.graphics.RectProto content_frame = 10 [deprecated=true];
optional .android.graphics.RectProto content_insets = 11;
optional .android.graphics.RectProto surface_insets = 12;
optional WindowStateAnimatorProto animator = 13;
@@ -305,18 +281,16 @@
optional int32 system_ui_visibility = 21;
optional bool has_surface = 22;
optional bool is_ready_for_display = 23;
- reserved 24 to 28;
-// optional .android.graphics.RectProto display_frame = 24;
-// optional .android.graphics.RectProto overscan_frame = 25;
-// optional .android.graphics.RectProto visible_frame = 26;
-// optional .android.graphics.RectProto decor_frame = 27;
-// optional .android.graphics.RectProto outset_frame = 28;
+ optional .android.graphics.RectProto display_frame = 24 [deprecated=true];
+ optional .android.graphics.RectProto overscan_frame = 25 [deprecated=true];
+ optional .android.graphics.RectProto visible_frame = 26 [deprecated=true];
+ optional .android.graphics.RectProto decor_frame = 27 [deprecated=true];
+ optional .android.graphics.RectProto outset_frame = 28 [deprecated=true];
optional .android.graphics.RectProto overscan_insets = 29;
optional .android.graphics.RectProto visible_insets = 30;
optional .android.graphics.RectProto stable_insets = 31;
optional .android.graphics.RectProto outsets = 32;
- reserved 33;
-// optional .android.view.DisplayCutoutProto cutout = 33;
+ optional .android.view.DisplayCutoutProto cutout = 33 [deprecated=true];
optional bool remove_on_exit = 34;
optional bool destroying = 35;
optional bool removed = 36;
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index b2a88b7..41282da 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -42,7 +42,7 @@
* Data model from /frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
* This proto is defined based on the writeToParcel method.
*
- * Next Tag: 9
+ * Next Tag: 10
*/
message ProcessStatsSectionProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -77,9 +77,86 @@
// Stats for each process.
repeated ProcessStatsProto process_stats = 8;
+
+ // Stats for each package.
+ repeated ProcessStatsPackageProto package_stats = 9;
}
-// Next Tag: 6
+// Next Tag: 10
+message ProcessStatsStateProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ enum ScreenState {
+ SCREEN_UNKNOWN = 0;
+ OFF = 1;
+ ON = 2;
+ }
+ optional ScreenState screen_state = 1;
+
+ enum MemoryState {
+ MEMORY_UNKNOWN = 0;
+ NORMAL = 1; // normal.
+ MODERATE = 2; // moderate memory pressure.
+ LOW = 3; // low memory.
+ CRITICAL = 4; // critical memory.
+ }
+ optional MemoryState memory_state = 2;
+
+ // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
+ // and not frameworks/base/core/java/android/app/ActivityManager.java
+ enum ProcessState {
+ PROCESS_UNKNOWN = 0;
+ // Persistent system process.
+ PERSISTENT = 1;
+ // Top activity; actually any visible activity.
+ TOP = 2;
+ // Important foreground process (ime, wallpaper, etc).
+ IMPORTANT_FOREGROUND = 3;
+ // Important background process.
+ IMPORTANT_BACKGROUND = 4;
+ // Performing backup operation.
+ BACKUP = 5;
+ // Background process running a service.
+ SERVICE = 6;
+ // Process not running, but would be if there was enough RAM.
+ SERVICE_RESTARTING = 7;
+ // Process running a receiver.
+ RECEIVER = 8;
+ // Heavy-weight process (currently not used).
+ HEAVY_WEIGHT = 9;
+ // Process hosting home/launcher app when not on top.
+ HOME = 10;
+ // Process hosting the last app the user was in.
+ LAST_ACTIVITY = 11;
+ // Cached process hosting a previous activity.
+ CACHED_ACTIVITY = 12;
+ // Cached process hosting a client activity.
+ CACHED_ACTIVITY_CLIENT = 13;
+ // Cached process that is empty.
+ CACHED_EMPTY = 14;
+ }
+ optional ProcessState process_state = 3;
+
+ // Millisecond uptime duration spent in this state
+ optional int64 duration_ms = 4;
+
+ // Millisecond elapsed realtime duration spent in this state
+ optional int64 realtime_duration_ms = 9;
+
+ // # of samples taken
+ optional int32 sample_size = 5;
+
+ // PSS is memory reserved for this process
+ optional android.util.AggStats pss = 6;
+
+ // USS is memory shared between processes, divided evenly for accounting
+ optional android.util.AggStats uss = 7;
+
+ // RSS is memory resident for this process
+ optional android.util.AggStats rss = 8;
+}
+
+// Next Tag: 7
message ProcessStatsProto {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
@@ -104,78 +181,103 @@
}
optional Kill kill = 3;
- message State {
- option (android.msg_privacy).dest = DEST_AUTOMATIC;
-
- enum ScreenState {
- SCREEN_UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- }
- optional ScreenState screen_state = 1;
-
- enum MemoryState {
- MEMORY_UNKNOWN = 0;
- NORMAL = 1; // normal.
- MODERATE = 2; // moderate memory pressure.
- LOW = 3; // low memory.
- CRITICAL = 4; // critical memory.
- }
- optional MemoryState memory_state = 2;
-
- // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
- // and not frameworks/base/core/java/android/app/ActivityManager.java
- enum ProcessState {
- PROCESS_UNKNOWN = 0;
- // Persistent system process.
- PERSISTENT = 1;
- // Top activity; actually any visible activity.
- TOP = 2;
- // Important foreground process (ime, wallpaper, etc).
- IMPORTANT_FOREGROUND = 3;
- // Important background process.
- IMPORTANT_BACKGROUND = 4;
- // Performing backup operation.
- BACKUP = 5;
- // Background process running a service.
- SERVICE = 6;
- // Process not running, but would be if there was enough RAM.
- SERVICE_RESTARTING = 7;
- // Process running a receiver.
- RECEIVER = 8;
- // Heavy-weight process (currently not used).
- HEAVY_WEIGHT = 9;
- // Process hosting home/launcher app when not on top.
- HOME = 10;
- // Process hosting the last app the user was in.
- LAST_ACTIVITY = 11;
- // Cached process hosting a previous activity.
- CACHED_ACTIVITY = 12;
- // Cached process hosting a client activity.
- CACHED_ACTIVITY_CLIENT = 13;
- // Cached process that is empty.
- CACHED_EMPTY = 14;
- }
- optional ProcessState process_state = 3;
-
- // Millisecond duration spent in this state
- optional int64 duration_ms = 4;
-
- // # of samples taken
- optional int32 sample_size = 5;
-
- // PSS is memory reserved for this process
- optional android.util.AggStats pss = 6;
-
- // USS is memory shared between processes, divided evenly for accounting
- optional android.util.AggStats uss = 7;
-
- // RSS is memory resident for this process
- optional android.util.AggStats rss = 8;
- }
- repeated State states = 5;
+ // Time and memory spent in various states.
+ repeated ProcessStatsStateProto states = 5;
// Total time process has been running... screen_state, memory_state, and process_state
// will not be set.
- optional State total_running_state = 6;
+ optional ProcessStatsStateProto total_running_state = 6;
+}
+
+// Next Tag: 7
+message ProcessStatsServiceStateProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of service component.
+ optional string service_name = 1;
+
+ // Information about a state the service can be in.
+ message OperationInfo {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Number of times the service was in this operation.
+ optional int32 count = 1;
+
+ // Time this operation was active in various states. process_state will not be set;
+ // includes only uptime, not memory info.
+ repeated ProcessStatsStateProto states = 2;
+ }
+
+ // Information about when the service was operating as running (that is how long it was
+ // running for any reason, such as the finer-grained started, bound, and executing times
+ // also reported in this proto).
+ optional OperationInfo running_op = 2;
+
+ // Information about when the service was operating as started.
+ optional OperationInfo started_op = 3;
+
+ // Information about when the service was operating as foreground.
+ optional OperationInfo foreground_op = 4;
+
+ // Information about when the service was operating as bound.
+ optional OperationInfo bound_op = 5;
+
+ // Information about when the service was operating as executing.
+ optional OperationInfo executing_op = 6;
+}
+
+// Next Tag: 7
+message ProcessStatsAssociationStateProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of the target component.
+ optional string component_name = 1;
+
+ // Information on one source in this association.
+ message Source {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of source process.
+ optional string process = 1;
+
+ // Uid of the source process.
+ optional int32 uid = 2;
+
+ // Total count of the times this association appeared.
+ optional int32 total_count = 3;
+
+ // Millisecond uptime total duration this association was around.
+ optional int64 total_duration_ms = 4;
+
+ // Total count of the times this association became actively impacting its target process.
+ optional int32 active_count = 5;
+
+ // Time association was active in various states. screen_state and memory_state will not
+ // be set; includes only uptime, not memory info.
+ repeated ProcessStatsStateProto active_states = 6;
+ }
+ repeated Source sources = 3;
+}
+
+// Next Tag: 7
+message ProcessStatsPackageProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Name of package.
+ optional string package = 1;
+
+ // Uid of the package.
+ optional int32 uid = 2;
+
+ // Version of the package.
+ optional int64 version = 3;
+
+ // Stats for each process running with the package loaded in to it.
+ repeated ProcessStatsProto process_stats = 4;
+
+ // Stats for each of the package's services.
+ repeated ProcessStatsServiceStateProto service_stats = 5;
+
+ // Stats for each association with the package.
+ repeated ProcessStatsAssociationStateProto association_stats = 6;
}
diff --git a/core/proto/android/view/enums.proto b/core/proto/android/view/enums.proto
index 10785ce..0172e78 100644
--- a/core/proto/android/view/enums.proto
+++ b/core/proto/android/view/enums.proto
@@ -42,3 +42,30 @@
// CPU is not updating it.
DISPLAY_STATE_ON_SUSPEND = 6;
}
+
+// Constants found in android.view.WindowManager.
+enum TransitionTypeEnum {
+ TRANSIT_NONE = 0;
+ TRANSIT_UNSET = -1;
+ TRANSIT_ACTIVITY_OPEN = 6;
+ TRANSIT_ACTIVITY_CLOSE = 7;
+ TRANSIT_TASK_OPEN = 8;
+ TRANSIT_TASK_CLOSE = 9;
+ TRANSIT_TASK_TO_FRONT = 10;
+ TRANSIT_TASK_TO_BACK = 11;
+ TRANSIT_WALLPAPER_CLOSE = 12;
+ TRANSIT_WALLPAPER_OPEN = 13;
+ TRANSIT_WALLPAPER_INTRA_OPEN = 14;
+ TRANSIT_WALLPAPER_INTRA_CLOSE = 15;
+ TRANSIT_TASK_OPEN_BEHIND = 16;
+ TRANSIT_TASK_IN_PLACE = 17;
+ TRANSIT_ACTIVITY_RELAUNCH = 18;
+ TRANSIT_DOCK_TASK_FROM_RECENTS = 19;
+ TRANSIT_KEYGUARD_GOING_AWAY = 20;
+ TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER = 21;
+ TRANSIT_KEYGUARD_OCCLUDE = 22;
+ TRANSIT_KEYGUARD_UNOCCLUDE = 23;
+ TRANSIT_TRANSLUCENT_ACTIVITY_OPEN = 24;
+ TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE = 25;
+ TRANSIT_CRASHING_ACTIVITY_CLOSE = 26;
+}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index fddb904..c8343e2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2491,6 +2491,7 @@
<item>com.android.server.notification.VisibilityExtractor</item>
<!-- Depends on ZenModeExtractor -->
<item>com.android.server.notification.BadgeExtractor</item>
+ <item>com.android.server.notification.CriticalNotificationExtractor</item>
</string-array>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 2a906ae..d704957 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1301,6 +1301,11 @@
android:process=":MemoryFileProvider">
</provider>
+ <provider android:name="android.content.RedactingProvider"
+ android:authorities="android.content.RedactingProvider"
+ android:process=":RedactingProvider">
+ </provider>
+
<!-- Application components used for os tests -->
<service android:name="android.os.MessengerService"
diff --git a/core/tests/coretests/src/android/content/RedactingProvider.java b/core/tests/coretests/src/android/content/RedactingProvider.java
new file mode 100644
index 0000000..e2ad448
--- /dev/null
+++ b/core/tests/coretests/src/android/content/RedactingProvider.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.database.RedactingCursor;
+import android.net.Uri;
+import android.util.ArrayMap;
+
+public class RedactingProvider extends ContentProvider {
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ switch (uri.getLastPathSegment()) {
+ case "missing": {
+ final MatrixCursor cursor = new MatrixCursor(
+ new String[] { "name", "size", "_data" });
+ cursor.addRow(new Object[] { "foo", 10, "/path/to/foo" });
+ cursor.addRow(new Object[] { "bar", 20, "/path/to/bar" });
+
+ final ArrayMap<String, Object> redactions = new ArrayMap<>();
+ redactions.put("missing", null);
+ return RedactingCursor.create(cursor, redactions);
+ }
+ case "single": {
+ final MatrixCursor cursor = new MatrixCursor(
+ new String[] { "name", "size", "_data" });
+ cursor.addRow(new Object[] { "foo", 10, "/path/to/foo" });
+ cursor.addRow(new Object[] { "bar", 20, "/path/to/bar" });
+
+ final ArrayMap<String, Object> redactions = new ArrayMap<>();
+ redactions.put("name", null);
+ redactions.put("_data", "/dev/null");
+ return RedactingCursor.create(cursor, redactions);
+ }
+ case "multiple": {
+ final MatrixCursor cursor = new MatrixCursor(
+ new String[] { "_data", "name", "_data" });
+ cursor.addRow(new Object[] { "/path", "foo", "/path" });
+
+ final ArrayMap<String, Object> redactions = new ArrayMap<>();
+ redactions.put("_data", null);
+ return RedactingCursor.create(cursor, redactions);
+ }
+ }
+
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/core/tests/coretests/src/android/database/RedactingCursorTest.java b/core/tests/coretests/src/android/database/RedactingCursorTest.java
new file mode 100644
index 0000000..93998f3
--- /dev/null
+++ b/core/tests/coretests/src/android/database/RedactingCursorTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class RedactingCursorTest {
+ private Context getContext() {
+ return InstrumentationRegistry.getContext();
+ }
+
+ @Test
+ public void testMissing() throws Exception {
+ final Cursor redacting = getContext().getContentResolver().query(
+ Uri.parse("content://android.content.RedactingProvider/missing"), null, null, null);
+
+ redacting.moveToNext();
+ assertEquals("foo", redacting.getString(0));
+ assertEquals(10, redacting.getInt(1));
+ assertEquals("/path/to/foo", redacting.getString(2));
+ redacting.moveToNext();
+ assertEquals("bar", redacting.getString(0));
+ assertEquals(20, redacting.getInt(1));
+ assertEquals("/path/to/bar", redacting.getString(2));
+ }
+
+ @Test
+ public void testSingle() throws Exception {
+ final Cursor redacting = getContext().getContentResolver().query(
+ Uri.parse("content://android.content.RedactingProvider/single"), null, null, null);
+
+ redacting.moveToNext();
+ assertEquals(null, redacting.getString(0));
+ assertEquals(10, redacting.getInt(1));
+ assertEquals("/dev/null", redacting.getString(2));
+ assertEquals(Cursor.FIELD_TYPE_NULL, redacting.getType(0));
+ assertEquals(Cursor.FIELD_TYPE_INTEGER, redacting.getType(1));
+ assertEquals(Cursor.FIELD_TYPE_STRING, redacting.getType(2));
+ assertTrue(redacting.isNull(0));
+ assertFalse(redacting.isNull(1));
+ assertFalse(redacting.isNull(2));
+
+ redacting.moveToNext();
+ assertEquals(null, redacting.getString(0));
+ assertEquals(20, redacting.getInt(1));
+ assertEquals("/dev/null", redacting.getString(2));
+ }
+
+ @Test
+ public void testMultiple() throws Exception {
+ final Cursor redacting = getContext().getContentResolver().query(
+ Uri.parse("content://android.content.RedactingProvider/multiple"),
+ null, null, null);
+
+ redacting.moveToNext();
+ assertEquals(null, redacting.getString(0));
+ assertEquals("foo", redacting.getString(1));
+ assertEquals(null, redacting.getString(2));
+ }
+}
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 5542f00..71627ab 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -97,6 +97,7 @@
private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS =
newHashSet(
Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
+ Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED,
Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
Settings.Global.ADB_ENABLED,
Settings.Global.ADD_USERS_WHEN_LOCKED,
diff --git a/core/tests/utiltests/jni/android_util_MemoryIntArrayTest.cpp b/core/tests/utiltests/jni/android_util_MemoryIntArrayTest.cpp
index 57ee2d5..4b14284 100644
--- a/core/tests/utiltests/jni/android_util_MemoryIntArrayTest.cpp
+++ b/core/tests/utiltests/jni/android_util_MemoryIntArrayTest.cpp
@@ -21,36 +21,6 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
-jint android_util_MemoryIntArrayTest_createAshmem(__attribute__((unused)) JNIEnv* env,
- __attribute__((unused)) jobject clazz,
- jstring name, jint size)
-{
-
- if (name == NULL) {
- return -1;
- }
-
- if (size < 0) {
- return -1;
- }
-
- const char* nameStr = env->GetStringUTFChars(name, NULL);
- const int ashmemSize = sizeof(std::atomic_int) * size;
- int fd = ashmem_create_region(nameStr, ashmemSize);
- env->ReleaseStringUTFChars(name, nameStr);
-
- if (fd < 0) {
- return -1;
- }
-
- int setProtResult = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
- if (setProtResult < 0) {
- return -1;
- }
-
- return fd;
-}
-
void android_util_MemoryIntArrayTest_setAshmemSize(__attribute__((unused)) JNIEnv* env,
__attribute__((unused)) jobject clazz, jint fd, jint size)
{
diff --git a/core/tests/utiltests/jni/registration.cpp b/core/tests/utiltests/jni/registration.cpp
index 0c84d98..d4fc2fb 100644
--- a/core/tests/utiltests/jni/registration.cpp
+++ b/core/tests/utiltests/jni/registration.cpp
@@ -16,25 +16,14 @@
#include <jni.h>
-extern jint android_util_MemoryIntArrayTest_createAshmem(JNIEnv* env,
- jobject clazz, jstring name, jint size);
extern void android_util_MemoryIntArrayTest_setAshmemSize(JNIEnv* env,
jobject clazz, jint fd, jint size);
extern "C" {
- JNIEXPORT jint JNICALL Java_android_util_MemoryIntArrayTest_nativeCreateAshmem(
- JNIEnv * env, jobject obj, jstring name, jint size);
JNIEXPORT void JNICALL Java_android_util_MemoryIntArrayTest_nativeSetAshmemSize(
JNIEnv * env, jobject obj, jint fd, jint size);
};
-JNIEXPORT jint JNICALL Java_android_util_MemoryIntArrayTest_nativeCreateAshmem(
- __attribute__((unused)) JNIEnv * env,__attribute__((unused)) jobject obj,
- jstring name, jint size)
-{
- return android_util_MemoryIntArrayTest_createAshmem(env, obj, name, size);
-}
-
JNIEXPORT void JNICALL Java_android_util_MemoryIntArrayTest_nativeSetAshmemSize(
__attribute__((unused)) JNIEnv * env,__attribute__((unused)) jobject obj,
jint fd, jint size)
diff --git a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
index 85817bb..24b33ef 100644
--- a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
+++ b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
@@ -23,6 +23,7 @@
import static org.junit.Assert.fail;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.support.test.runner.AndroidJUnit4;
import libcore.io.IoUtils;
import org.junit.Test;
@@ -251,13 +252,11 @@
// Create a MemoryIntArray to muck with
MemoryIntArray array = new MemoryIntArray(1);
- // Create the fd to stuff in the MemoryIntArray
- final int fd = nativeCreateAshmem("foo", 1);
-
- // Replace the fd with our ahsmem region
- Field fdFiled = MemoryIntArray.class.getDeclaredField("mFd");
- fdFiled.setAccessible(true);
- fdFiled.set(array, fd);
+ // Grab the internal ashmem fd.
+ Field fdField = MemoryIntArray.class.getDeclaredField("mFd");
+ fdField.setAccessible(true);
+ int fd = ((ParcelFileDescriptor)fdField.get(array)).getFd();
+ assertTrue("fd must be valid", fd != -1);
CountDownLatch countDownLatch = new CountDownLatch(2);
@@ -292,10 +291,9 @@
}
if (!success) {
- fail("MemoryIntArray should catch ahshmem size changing under it");
+ fail("MemoryIntArray should catch ashmem size changing under it");
}
}
- private native int nativeCreateAshmem(String name, int size);
private native void nativeSetAshmemSize(int fd, int size);
}
diff --git a/location/java/android/location/Country.java b/location/java/android/location/Country.java
index 7c1485d..6f82b78 100644
--- a/location/java/android/location/Country.java
+++ b/location/java/android/location/Country.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -78,6 +79,7 @@
* <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
* </ul>
*/
+ @UnsupportedAppUsage
public Country(final String countryIso, final int source) {
if (countryIso == null || source < COUNTRY_SOURCE_NETWORK
|| source > COUNTRY_SOURCE_LOCALE) {
@@ -107,6 +109,7 @@
/**
* @return the ISO 3166-1 two letters country code
*/
+ @UnsupportedAppUsage
public final String getCountryIso() {
return mCountryIso;
}
@@ -121,6 +124,7 @@
* <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
* </ul>
*/
+ @UnsupportedAppUsage
public final int getSource() {
return mSource;
}
diff --git a/location/java/android/location/CountryDetector.java b/location/java/android/location/CountryDetector.java
index ec6dfb7..119d1e0 100644
--- a/location/java/android/location/CountryDetector.java
+++ b/location/java/android/location/CountryDetector.java
@@ -19,6 +19,7 @@
import java.util.HashMap;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
@@ -87,6 +88,7 @@
* create an instance of this class is using the factory
* Context.getSystemService.
*/
+ @UnsupportedAppUsage
public CountryDetector(ICountryDetector service) {
mService = service;
mListeners = new HashMap<CountryListener, ListenerTransport>();
@@ -98,6 +100,7 @@
* @return the country if it is available immediately, otherwise null will
* be returned.
*/
+ @UnsupportedAppUsage
public Country detectCountry() {
try {
return mService.detectCountry();
@@ -116,6 +119,7 @@
* implement the callback mechanism. If looper is null then the
* callbacks will be called on the main thread.
*/
+ @UnsupportedAppUsage
public void addCountryListener(CountryListener listener, Looper looper) {
synchronized (mListeners) {
if (!mListeners.containsKey(listener)) {
@@ -133,6 +137,7 @@
/**
* Remove the listener
*/
+ @UnsupportedAppUsage
public void removeCountryListener(CountryListener listener) {
synchronized (mListeners) {
ListenerTransport transport = mListeners.get(listener);
diff --git a/location/java/android/location/CountryListener.java b/location/java/android/location/CountryListener.java
index e36db41..70a83c5 100644
--- a/location/java/android/location/CountryListener.java
+++ b/location/java/android/location/CountryListener.java
@@ -16,6 +16,8 @@
package android.location;
+import android.annotation.UnsupportedAppUsage;
+
/**
* The listener for receiving the notification when the country is detected or
* changed
@@ -26,5 +28,6 @@
/**
* @param country the changed or detected country.
*/
+ @UnsupportedAppUsage
void onCountryDetected(Country country);
}
diff --git a/location/java/android/location/GeocoderParams.java b/location/java/android/location/GeocoderParams.java
index 174fe3e..d90e4b5 100644
--- a/location/java/android/location/GeocoderParams.java
+++ b/location/java/android/location/GeocoderParams.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
@@ -53,6 +54,7 @@
/**
* returns the Geocoder's locale
*/
+ @UnsupportedAppUsage
public Locale getLocale() {
return mLocale;
}
@@ -60,6 +62,7 @@
/**
* returns the package name of the Geocoder's client
*/
+ @UnsupportedAppUsage
public String getClientPackage() {
return mPackageName;
}
diff --git a/location/java/android/location/Geofence.java b/location/java/android/location/Geofence.java
index 5de779a..ed2aa64 100644
--- a/location/java/android/location/Geofence.java
+++ b/location/java/android/location/Geofence.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -98,6 +99,7 @@
}
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<Geofence> CREATOR = new Parcelable.Creator<Geofence>() {
@Override
public Geofence createFromParcel(Parcel in) {
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index b601cde..d90a597 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -16,6 +16,7 @@
package android.location;
+import android.annotation.UnsupportedAppUsage;
import android.util.SparseArray;
import java.util.Iterator;
@@ -206,6 +207,7 @@
status.mAzimuths);
}
+ @UnsupportedAppUsage
void setTimeToFirstFix(int ttff) {
mTimeToFirstFix = ttff;
}
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 684cafa..70a97e1 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -18,6 +18,7 @@
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -123,8 +124,10 @@
}
};
+ @UnsupportedAppUsage
private String mProvider;
private long mTime = 0;
+ @UnsupportedAppUsage
private long mElapsedRealtimeNanos = 0;
private double mLatitude = 0.0;
private double mLongitude = 0.0;
@@ -1156,6 +1159,7 @@
* @param value the Location to attach
* @hide
*/
+ @UnsupportedAppUsage
public void setExtraLocation(String key, Location value) {
if (mExtras == null) {
mExtras = new Bundle();
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 30a07ef..b5d9431 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -29,6 +29,7 @@
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -68,6 +69,7 @@
private static final String TAG = "LocationManager";
private final Context mContext;
+ @UnsupportedAppUsage
private final ILocationManager mService;
private final GnssMeasurementCallbackTransport mGnssMeasurementCallbackTransport;
private final GnssNavigationMessageCallbackTransport mGnssNavigationMessageCallbackTransport;
@@ -1004,6 +1006,7 @@
}
}
+ @UnsupportedAppUsage
private void requestLocationUpdates(LocationRequest request, LocationListener listener,
Looper looper, PendingIntent intent) {
@@ -2328,6 +2331,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public boolean sendNiResponse(int notifId, int userResponse) {
try {
return mService.sendNiResponse(notifId, userResponse);
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 96a0817..2d7f7e3 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -17,6 +17,7 @@
package android.location;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
@@ -141,16 +142,26 @@
*/
private static final double FASTEST_INTERVAL_FACTOR = 6.0; // 6x
+ @UnsupportedAppUsage
private int mQuality = POWER_LOW;
+ @UnsupportedAppUsage
private long mInterval = 60 * 60 * 1000; // 60 minutes
+ @UnsupportedAppUsage
private long mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR); // 10 minutes
+ @UnsupportedAppUsage
private boolean mExplicitFastestInterval = false;
+ @UnsupportedAppUsage
private long mExpireAt = Long.MAX_VALUE; // no expiry
+ @UnsupportedAppUsage
private int mNumUpdates = Integer.MAX_VALUE; // no expiry
+ @UnsupportedAppUsage
private float mSmallestDisplacement = 0.0f; // meters
+ @UnsupportedAppUsage
private WorkSource mWorkSource = null;
+ @UnsupportedAppUsage
private boolean mHideFromAppOps = false; // True if this request shouldn't be counted by AppOps
+ @UnsupportedAppUsage
private String mProvider = LocationManager.FUSED_PROVIDER;
// for deprecated APIs that explicitly request a provider
@@ -592,12 +603,14 @@
return mHideFromAppOps;
}
+ @UnsupportedAppUsage
private static void checkInterval(long millis) {
if (millis < 0) {
throw new IllegalArgumentException("invalid interval: " + millis);
}
}
+ @UnsupportedAppUsage
private static void checkQuality(int quality) {
switch (quality) {
case ACCURACY_FINE:
@@ -612,12 +625,14 @@
}
}
+ @UnsupportedAppUsage
private static void checkDisplacement(float meters) {
if (meters < 0.0f) {
throw new IllegalArgumentException("invalid displacement: " + meters);
}
}
+ @UnsupportedAppUsage
private static void checkProvider(String name) {
if (name == null) {
throw new IllegalArgumentException("invalid provider: " + name);
diff --git a/media/java/android/mtp/MtpPropertyList.java b/media/java/android/mtp/MtpPropertyList.java
index ede90da..557f099 100644
--- a/media/java/android/mtp/MtpPropertyList.java
+++ b/media/java/android/mtp/MtpPropertyList.java
@@ -16,6 +16,7 @@
package android.mtp;
+import android.annotation.UnsupportedAppUsage;
import java.util.ArrayList;
import java.util.List;
@@ -49,6 +50,7 @@
mStringValues = new ArrayList<>();
}
+ @UnsupportedAppUsage
public void append(int handle, int property, int type, long value) {
mObjectHandles.add(handle);
mPropertyCodes.add(property);
@@ -57,6 +59,7 @@
mStringValues.add(null);
}
+ @UnsupportedAppUsage
public void append(int handle, int property, String value) {
mObjectHandles.add(handle);
mPropertyCodes.add(property);
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index 2625e0c..c714b3c 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -16,6 +16,7 @@
package android.mtp;
+import android.annotation.UnsupportedAppUsage;
import android.os.storage.StorageVolume;
/**
@@ -46,6 +47,7 @@
*
* @return the storage ID
*/
+ @UnsupportedAppUsage
public final int getStorageId() {
return mStorageId;
}
@@ -55,6 +57,7 @@
*
* @return the storage file path
*/
+ @UnsupportedAppUsage
public final String getPath() {
return mPath;
}
diff --git a/opengl/java/android/opengl/EGL14.java b/opengl/java/android/opengl/EGL14.java
index 53ec6c8..728e6e1 100644
--- a/opengl/java/android/opengl/EGL14.java
+++ b/opengl/java/android/opengl/EGL14.java
@@ -18,6 +18,7 @@
package android.opengl;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.SurfaceTexture;
import android.view.Surface;
import android.view.SurfaceView;
@@ -163,6 +164,7 @@
/**
* {@hide}
*/
+ @UnsupportedAppUsage
public static native EGLDisplay eglGetDisplay(
long display_id
);
diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java
index 137f2f5..d66e7ac 100644
--- a/opengl/java/android/opengl/GLES20.java
+++ b/opengl/java/android/opengl/GLES20.java
@@ -19,6 +19,8 @@
package android.opengl;
+import android.annotation.UnsupportedAppUsage;
+
/** OpenGL ES 2.0
*/
public class GLES20 {
@@ -824,6 +826,7 @@
// C function void glGetActiveAttrib ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
/** @hide Method is broken, but used to be public (b/6006380) */
+ @UnsupportedAppUsage
public static native void glGetActiveAttrib(
int program,
int index,
@@ -872,6 +875,7 @@
// C function void glGetActiveUniform ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
/** @hide Method is broken, but used to be public (b/6006380) */
+ @UnsupportedAppUsage
public static native void glGetActiveUniform(
int program,
int index,
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 0f0a7e9d..8a3e6a0 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -16,6 +16,7 @@
package android.opengl;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.os.Trace;
import android.util.AttributeSet;
@@ -1235,6 +1236,7 @@
EGLDisplay mEglDisplay;
EGLSurface mEglSurface;
EGLConfig mEglConfig;
+ @UnsupportedAppUsage
EGLContext mEglContext;
}
@@ -1844,6 +1846,7 @@
// End of member variables protected by the sGLThreadManager monitor.
+ @UnsupportedAppUsage
private EglHelper mEglHelper;
/**
@@ -1919,7 +1922,9 @@
private final WeakReference<GLSurfaceView> mThisWeakRef =
new WeakReference<GLSurfaceView>(this);
+ @UnsupportedAppUsage
private GLThread mGLThread;
+ @UnsupportedAppUsage
private Renderer mRenderer;
private boolean mDetached;
private EGLConfigChooser mEGLConfigChooser;
diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml
index e9ddbaf..df8f8db 100644
--- a/packages/CarSystemUI/res/values/colors.xml
+++ b/packages/CarSystemUI/res/values/colors.xml
@@ -19,7 +19,7 @@
<color name="car_accent">#356FE5</color>
<!-- colors for user switcher -->
<color name="car_user_switcher_background_color">#000000</color>
- <color name="car_user_switcher_name_text_color">@color/car_title2_light</color>
+ <color name="car_user_switcher_name_text_color">@color/car_body1_light</color>
<color name="car_user_switcher_add_user_background_color">#131313</color>
<color name="car_nav_icon_fill_color">@color/car_grey_50</color>
<!-- colors for seekbar -->
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index 3829aa3..07ecca2 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -29,7 +29,7 @@
<dimen name="car_primary_icon_size">36dp</dimen>
<!-- dimensions for the car user switcher -->
- <dimen name="car_user_switcher_name_text_size">@dimen/car_title2_size</dimen>
+ <dimen name="car_user_switcher_name_text_size">@dimen/car_body1_size</dimen>
<dimen name="car_user_switcher_vertical_spacing_between_users">124dp</dimen>
<!--These values represent MIN and MAX for hvac-->
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java
index 27d3106..6473f0d 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/AnimatedTemperatureView.java
@@ -23,8 +23,6 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
-import com.android.systemui.statusbar.car.hvac.TemperatureView;
-import com.android.systemui.statusbar.car.hvac.HvacController;
import android.util.AttributeSet;
import android.util.Property;
import android.view.Gravity;
@@ -36,8 +34,8 @@
import android.widget.TextSwitcher;
import android.widget.TextView;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.statusbar.car.hvac.TemperatureView;
/**
* Simple text display of HVAC properties, It is designed to show mTemperature and is configured in
@@ -47,8 +45,6 @@
* hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
* hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol)
* hvacOrientaion = Example: left
- * <p>
- * Note: It registers itself with {@link HvacController}
*/
public class AnimatedTemperatureView extends FrameLayout implements TemperatureView {
@@ -158,12 +154,9 @@
ViewGroup.LayoutParams.MATCH_PARENT);
typedArray.recycle();
-
- // register with controller
- HvacController hvacController = Dependency.get(HvacController.class);
- hvacController.addHvacTextView(this);
}
+
private TextView generateTextView() {
TextView textView = new TextView(getContext());
textView.setTextAppearance(mTextAppearanceRes);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java
index 0bc94b5..3c6d623 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/hvac/TemperatureBackgroundAnimator.java
@@ -131,7 +131,9 @@
}
void animateOpen() {
- if (!mAnimationsReady || mCircleState == CircleState.ENTERING) {
+ if (!mAnimationsReady
+ || !mAnimatedView.isAttachedToWindow()
+ || mCircleState == CircleState.ENTERING) {
return;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index f39b851..e2c8ecd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -126,6 +126,12 @@
*/
public static final String META_DATA_PREFERENCE_ICON_BACKGROUND_HINT =
"com.android.settings.bg.hint";
+ /**
+ * Name of the meta-data item that should be set in the AndroidManifest.xml
+ * to specify the icon background color as raw ARGB.
+ */
+ public static final String META_DATA_PREFERENCE_ICON_BACKGROUND_ARGB =
+ "com.android.settings.bg.argb";
/**
* Name of the meta-data item that should be set in the AndroidManifest.xml
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
index 01df0ec..dddfa7a 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/graph/BatteryMeterDrawableBaseTest.java
@@ -102,17 +102,4 @@
private boolean isRectZero(Rect r) {
return r.left == 0 && r.top == 0 && r.right == 0 && r.bottom == 0;
}
-
- @Test
- public void testPlusPaint_isEqualToBoltPaint() {
- // Before setting color
- assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
-
- final int fakeFillColor = 123;
- final int fakeBackgrundColor = 456;
-
- // After
- mBatteryDrawable.setColors(fakeFillColor, fakeBackgrundColor);
- assertTrue(mBatteryDrawable.mPlusPaint.hasEqualAttributes(mBatteryDrawable.mBoltPaint));
- }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
index 914d182..dde1746 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/SettingsLibRobolectricTestRunner.java
@@ -54,7 +54,7 @@
final List<ResourcePath> paths = super.getIncludedResourcePaths();
paths.add(resourcePath("file:frameworks/base/packages/SettingsLib/res"));
paths.add(resourcePath("file:frameworks/base/core/res/res"));
- paths.add(resourcePath("file:frameworks/support/appcompat/res"));
+ paths.add(resourcePath("file:out/soong/.intermediates/prebuilts/sdk/current/androidx/androidx.appcompat_appcompat-nodeps/android_common/aar/res/"));
return paths;
}
};
diff --git a/packages/SystemUI/docs/plugin_hooks.md b/packages/SystemUI/docs/plugin_hooks.md
index 5b08bfc..9fe2e18 100644
--- a/packages/SystemUI/docs/plugin_hooks.md
+++ b/packages/SystemUI/docs/plugin_hooks.md
@@ -51,6 +51,10 @@
Use: Control over swipes/input for notification views, can be used to control what happens when you swipe/long-press
+### Action: com.android.systemui.action.PLUGIN_CLOCK
+Expected interface: [ClockPlugin](/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java)
+
+Use: Allows replacement of the keyguard main clock.
# Global plugin dependencies
These classes can be accessed by any plugin using PluginDependency as long as they @Requires them.
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
new file mode 100644
index 0000000..b4fc820
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockPlugin.java
@@ -0,0 +1,47 @@
+/*
+ * 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.plugins;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+import android.graphics.Paint.Style;
+import android.view.View;
+
+/**
+ * This plugin is used to replace main clock in keyguard.
+ */
+@ProvidesInterface(action = ClockPlugin.ACTION, version = ClockPlugin.VERSION)
+public interface ClockPlugin extends Plugin {
+
+ String ACTION = "com.android.systemui.action.PLUGIN_CLOCK";
+ int VERSION = 1;
+
+ /**
+ * Get clock view.
+ * @return clock view from plugin.
+ */
+ View getView();
+
+ /**
+ * Set clock paint style.
+ * @param style The new style to set in the paint.
+ */
+ void setStyle(Style style);
+
+ /**
+ * Set clock text color.
+ * @param color A color value.
+ */
+ void setTextColor(int color);
+}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
new file mode 100644
index 0000000..89b873e
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_clock_switch.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<!-- This is a view that shows clock information in Keyguard. -->
+<com.android.keyguard.KeyguardClockSwitch
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_alignParentTop="true">
+ <TextClock
+ android:id="@+id/default_clock_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:letterSpacing="0.03"
+ android:textColor="?attr/wallpaperTextColor"
+ android:singleLine="true"
+ style="@style/widget_big_thin"
+ android:format12Hour="@string/keyguard_widget_12_hours_format"
+ android:format24Hour="@string/keyguard_widget_24_hours_format" />
+</com.android.keyguard.KeyguardClockSwitch>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index 87983b9..a795442 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -38,19 +38,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top">
- <TextClock
- android:id="@+id/clock_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_centerHorizontal="true"
- android:layout_alignParentTop="true"
- android:letterSpacing="0.03"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_big_thin"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format" />
+ <include layout="@layout/keyguard_clock_switch"
+ android:id="@+id/clock_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
<View
android:id="@+id/clock_separator"
android:layout_width="@dimen/widget_separator_width"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index ba05ccf..4ae2d41 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -55,19 +55,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top">
- <TextClock
- android:id="@+id/clock_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:layout_centerHorizontal="true"
- android:layout_alignParentTop="true"
- android:letterSpacing="0.03"
- android:textColor="?attr/wallpaperTextColor"
- android:singleLine="true"
- style="@style/widget_big_thin"
- android:format12Hour="@string/keyguard_widget_12_hours_format"
- android:format24Hour="@string/keyguard_widget_24_hours_format" />
+ <include layout="@layout/keyguard_clock_switch"
+ android:id="@+id/clock_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
<View
android:id="@+id/clock_separator"
android:layout_width="@dimen/widget_separator_width"
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index baaf699..d72021e 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,14 +18,16 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layout_marginStart="@dimen/rounded_corner_content_padding"
+ android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+ android:paddingStart="@dimen/nav_content_padding"
+ android:paddingEnd="@dimen/nav_content_padding">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingStart="@dimen/rounded_corner_content_padding"
- android:paddingEnd="@dimen/rounded_corner_content_padding"
android:clipChildren="false"
android:clipToPadding="false">
@@ -34,8 +36,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
- android:paddingStart="@dimen/nav_content_padding"
- android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
@@ -46,8 +46,6 @@
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
- android:paddingStart="@dimen/nav_content_padding"
- android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 6d5b7788..24a0c71 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,14 +18,16 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layout_marginTop="@dimen/rounded_corner_content_padding"
+ android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+ android:paddingTop="@dimen/nav_content_padding"
+ android:paddingBottom="@dimen/nav_content_padding">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingTop="@dimen/rounded_corner_content_padding"
- android:paddingBottom="@dimen/rounded_corner_content_padding"
android:clipChildren="false"
android:clipToPadding="false">
@@ -34,10 +36,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:paddingTop="@dimen/nav_content_padding"
- android:paddingBottom="@dimen/nav_content_padding"
- android:clipChildren="false"
- android:clipToPadding="false" />
+ android:clipToPadding="false"
+ android:clipChildren="false" />
<com.android.systemui.statusbar.phone.ReverseLinearLayout
android:id="@+id/center_group"
@@ -45,10 +45,8 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- android:paddingTop="@dimen/nav_content_padding"
- android:paddingBottom="@dimen/nav_content_padding"
- android:clipChildren="false"
- android:clipToPadding="false" />
+ android:clipToPadding="false"
+ android:clipChildren="false" />
</com.android.systemui.statusbar.phone.NearestTouchFrame>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
new file mode 100644
index 0000000..5bbbc52
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -0,0 +1,155 @@
+package com.android.keyguard;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.TextClock;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
+/**
+ * Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
+ */
+public class KeyguardClockSwitch extends FrameLayout {
+ /**
+ * Optional/alternative clock injected via plugin.
+ */
+ private ClockPlugin mClockPlugin;
+ /**
+ * Default clock.
+ */
+ private TextClock mClockView;
+
+ private final PluginListener<ClockPlugin> mClockPluginListener =
+ new PluginListener<ClockPlugin>() {
+ @Override
+ public void onPluginConnected(ClockPlugin plugin, Context pluginContext) {
+ View view = plugin.getView();
+ if (view != null) {
+ mClockPlugin = plugin;
+ addView(view, -1,
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ initPluginParams();
+ mClockView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override
+ public void onPluginDisconnected(ClockPlugin plugin) {
+ View view = plugin.getView();
+ if (view != null) {
+ mClockPlugin = null;
+ removeView(view);
+ mClockView.setVisibility(View.VISIBLE);
+ }
+ }
+ };
+
+ public KeyguardClockSwitch(Context context) {
+ this(context, null);
+ }
+
+ public KeyguardClockSwitch(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mClockView = findViewById(R.id.default_clock_view);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ Dependency.get(PluginManager.class).addPluginListener(mClockPluginListener,
+ ClockPlugin.class);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ Dependency.get(PluginManager.class).removePluginListener(mClockPluginListener);
+ }
+
+ /**
+ * It will also update plugin setStyle if plugin is connected.
+ */
+ public void setStyle(Style style) {
+ mClockView.getPaint().setStyle(style);
+ if (mClockPlugin != null) {
+ mClockPlugin.setStyle(style);
+ }
+ }
+
+ /**
+ * It will also update plugin setTextColor if plugin is connected.
+ */
+ public void setTextColor(int color) {
+ mClockView.setTextColor(color);
+ if (mClockPlugin != null) {
+ mClockPlugin.setTextColor(color);
+ }
+ }
+
+ public void setShowCurrentUserTime(boolean showCurrentUserTime) {
+ mClockView.setShowCurrentUserTime(showCurrentUserTime);
+ }
+
+ public void setElegantTextHeight(boolean elegant) {
+ mClockView.setElegantTextHeight(elegant);
+ }
+
+ public void setTextSize(int unit, float size) {
+ mClockView.setTextSize(unit, size);
+ }
+
+ public void setFormat12Hour(CharSequence format) {
+ mClockView.setFormat12Hour(format);
+ }
+
+ public void setFormat24Hour(CharSequence format) {
+ mClockView.setFormat24Hour(format);
+ }
+
+ public Paint getPaint() {
+ return mClockView.getPaint();
+ }
+
+ public int getCurrentTextColor() {
+ return mClockView.getCurrentTextColor();
+ }
+
+ public float getTextSize() {
+ return mClockView.getTextSize();
+ }
+
+ public void refresh() {
+ mClockView.refresh();
+ }
+
+ /**
+ * When plugin changes, set all kept parameters into newer plugin.
+ */
+ private void initPluginParams() {
+ if (mClockPlugin != null) {
+ mClockPlugin.setStyle(getPaint().getStyle());
+ mClockPlugin.setTextColor(getCurrentTextColor());
+ }
+ }
+
+ @VisibleForTesting (otherwise = VisibleForTesting.NONE)
+ PluginListener getClockPluginListener() {
+ return mClockPluginListener;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 6da143c..6d1313c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -39,7 +39,6 @@
import android.view.View;
import android.widget.GridLayout;
import android.widget.RelativeLayout;
-import android.widget.TextClock;
import android.widget.TextView;
import com.android.internal.widget.LockPatternUtils;
@@ -64,7 +63,7 @@
private final float mSmallClockScale;
private TextView mLogoutView;
- private TextClock mClockView;
+ private KeyguardClockSwitch mClockView;
private View mClockSeparator;
private TextView mOwnerInfo;
private KeyguardSliceView mKeyguardSlice;
@@ -248,7 +247,7 @@
.scaleX(clockScale)
.scaleY(clockScale)
.withEndAction(() -> {
- mClockView.getPaint().setStyle(style);
+ mClockView.setStyle(style);
mClockView.invalidate();
})
.start();
@@ -256,7 +255,7 @@
mClockView.setY(top);
mClockView.setScaleX(clockScale);
mClockView.setScaleY(clockScale);
- mClockView.getPaint().setStyle(style);
+ mClockView.setStyle(style);
mClockView.invalidate();
}
} else if (view == mClockSeparator) {
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 3c44eb4..0864ff0 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -55,6 +55,7 @@
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
+import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
/**
@@ -69,6 +70,10 @@
private static final long BACKOFF_MILLIS = 1000;
private static final long DEFERRED_CALLBACK_MILLIS = 5000;
+ // Default interaction flags if swipe up is disabled before connecting to launcher
+ private static final int DEFAULT_DISABLE_SWIPE_UP_STATE = FLAG_DISABLE_SWIPE_UP
+ | FLAG_SHOW_OVERVIEW_BUTTON;
+
private final Context mContext;
private final Handler mHandler;
private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
@@ -220,7 +225,7 @@
// When launcher service is disabled, reset interaction flags because it is inactive
if (!isEnabled()) {
- mInteractionFlags = 0;
+ mInteractionFlags = getDefaultInteractionFlags();
Prefs.remove(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS);
}
@@ -300,7 +305,8 @@
com.android.internal.R.string.config_recentsComponentName));
mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(mRecentsComponentName.getPackageName());
- mInteractionFlags = Prefs.getInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS, 0);
+ mInteractionFlags = Prefs.getInt(mContext, Prefs.Key.QUICK_STEP_INTERACTION_FLAGS,
+ getDefaultInteractionFlags());
// Listen for the package update changes.
if (SystemServicesProxy.getInstance(context)
@@ -397,6 +403,15 @@
}
}
+ private int getDefaultInteractionFlags() {
+ // If there is no settings available use device default or get it from settings
+ final boolean defaultState = getSwipeUpDefaultValue();
+ final boolean swipeUpEnabled = getSwipeUpSettingAvailable()
+ ? getSwipeUpEnabledFromSettings(defaultState)
+ : defaultState;
+ return swipeUpEnabled ? 0 : DEFAULT_DISABLE_SWIPE_UP_STATE;
+ }
+
private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
for (int i = mConnectionCallbacks.size() - 1; i >= 0; --i) {
mConnectionCallbacks.get(i).onBackButtonAlphaChanged(alpha, animate);
@@ -427,6 +442,21 @@
ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
}
+ private boolean getSwipeUpDefaultValue() {
+ return mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default);
+ }
+
+ private boolean getSwipeUpSettingAvailable() {
+ return mContext.getResources()
+ .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_setting_available);
+ }
+
+ private boolean getSwipeUpEnabledFromSettings(boolean defaultValue) {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue ? 1 : 0) == 1;
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(TAG_OPS + " state:");
@@ -440,12 +470,10 @@
pw.print(" quickStepIntent="); pw.println(mQuickStepIntent);
pw.print(" quickStepIntentResolved="); pw.println(isEnabled());
- final int swipeUpDefaultValue = mContext.getResources()
- .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default) ? 1 : 0;
- final int swipeUpEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, swipeUpDefaultValue);
- pw.print(" swipeUpSetting="); pw.println(swipeUpEnabled != 0);
- pw.print(" swipeUpSettingDefault="); pw.println(swipeUpDefaultValue != 0);
+ final boolean swipeUpDefaultValue = getSwipeUpDefaultValue();
+ final boolean swipeUpEnabled = getSwipeUpEnabledFromSettings(swipeUpDefaultValue);
+ pw.print(" swipeUpSetting="); pw.println(swipeUpEnabled);
+ pw.print(" swipeUpSettingDefault="); pw.println(swipeUpDefaultValue);
}
public interface OverviewProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index fe8ea34..c96aa73 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -45,6 +45,7 @@
import java.util.Locale;
import java.util.concurrent.TimeUnit;
+import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.SliceProvider;
import androidx.slice.builders.ListBuilder;
@@ -127,8 +128,8 @@
@Override
public Slice onBindSlice(Uri sliceUri) {
- ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
- builder.addRow(new RowBuilder(builder, mDateUri).setTitle(mLastText));
+ ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
+ builder.addRow(new RowBuilder(mDateUri).setTitle(mLastText));
addNextAlarm(builder);
addZenMode(builder);
addPrimaryAction(builder);
@@ -139,11 +140,13 @@
// Add simple action because API requires it; Keyguard handles presenting
// its own slices so this action + icon are actually never used.
PendingIntent pi = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
- Icon icon = Icon.createWithResource(getContext(), R.drawable.ic_access_alarms_big);
- SliceAction action = new SliceAction(pi, icon, mLastText);
+ IconCompat icon = IconCompat.createWithResource(getContext(),
+ R.drawable.ic_access_alarms_big);
+ SliceAction action = SliceAction.createDeeplink(pi, icon,
+ ListBuilder.ICON_IMAGE, mLastText);
- RowBuilder primaryActionRow = new RowBuilder(builder, Uri.parse(KEYGUARD_ACTION_URI))
- .setPrimaryAction(action);
+ RowBuilder primaryActionRow = new RowBuilder(Uri.parse(KEYGUARD_ACTION_URI))
+ .setPrimaryAction(action);
builder.addRow(primaryActionRow);
}
@@ -152,10 +155,11 @@
return;
}
- Icon alarmIcon = Icon.createWithResource(getContext(), R.drawable.ic_access_alarms_big);
- RowBuilder alarmRowBuilder = new RowBuilder(builder, mAlarmUri)
+ IconCompat alarmIcon = IconCompat.createWithResource(getContext(),
+ R.drawable.ic_access_alarms_big);
+ RowBuilder alarmRowBuilder = new RowBuilder(mAlarmUri)
.setTitle(mNextAlarm)
- .addEndItem(alarmIcon);
+ .addEndItem(alarmIcon, ListBuilder.ICON_IMAGE);
builder.addRow(alarmRowBuilder);
}
@@ -167,10 +171,11 @@
if (!isDndSuppressingNotifications()) {
return;
}
- RowBuilder dndBuilder = new RowBuilder(builder, mDndUri)
+ RowBuilder dndBuilder = new RowBuilder(mDndUri)
.setContentDescription(getContext().getResources()
.getString(R.string.accessibility_quick_settings_dnd))
- .addEndItem(Icon.createWithResource(getContext(), R.drawable.stat_sys_dnd));
+ .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.stat_sys_dnd),
+ ListBuilder.ICON_IMAGE);
builder.addRow(dndBuilder);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 38d266d..55dfd44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
import android.content.Context;
@@ -26,9 +27,11 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
+import android.view.DisplayCutout;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo;
import com.android.systemui.Interpolators;
@@ -89,6 +92,7 @@
private boolean mShowNotificationShelf;
private float mFirstElementRoundness;
private Rect mClipRect = new Rect();
+ private int mCutoutHeight;
public NotificationShelf(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -200,8 +204,12 @@
0 : mAmbientState.getDarkAmount();
mShelfState.yTranslation = MathUtils.lerp(awakenTranslation, darkTranslation, yRatio);
mShelfState.zTranslation = ambientState.getBaseZHeight();
+ // For the small display size, it's not enough to make the icon not covered by
+ // the top cutout so the denominator add the height of cutout.
+ // Totally, (getIntrinsicHeight() * 2 + mCutoutHeight) should be smaller then
+ // mAmbientState.getTopPadding().
float openedAmount = (mShelfState.yTranslation - getFullyClosedTranslation())
- / (getIntrinsicHeight() * 2);
+ / (getIntrinsicHeight() * 2 + mCutoutHeight);
openedAmount = Math.min(1.0f, openedAmount);
mShelfState.openedAmount = openedAmount;
mShelfState.clipTopAmount = 0;
@@ -745,6 +753,22 @@
mRelativeOffset -= mTmp[0];
}
+ @Override
+ public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ WindowInsets ret = super.onApplyWindowInsets(insets);
+
+ // NotificationShelf drag from the status bar and the status bar dock on the top
+ // of the display for current design so just focus on the top of ScreenDecorations.
+ // In landscape or multiple window split mode, the NotificationShelf still drag from
+ // the top and the physical notch/cutout goes to the right, left, or both side of the
+ // display so it doesn't matter for the NotificationSelf in landscape.
+ DisplayCutout displayCutout = insets.getDisplayCutout();
+ mCutoutHeight = displayCutout == null || displayCutout.getSafeInsetTop() < 0
+ ? 0 : displayCutout.getSafeInsetTop();
+
+ return ret;
+ }
+
private void setOpenedAmount(float openedAmount) {
mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
mOpenedAmount = openedAmount;
@@ -759,7 +783,7 @@
int width = (int) NotificationUtils.interpolate(
start + mCollapsedIcons.getFinalTranslationX(),
mShelfIcons.getWidth(),
- openedAmount);
+ FAST_OUT_SLOW_IN_REVERSE.getInterpolation(openedAmount));
mShelfIcons.setActualLayoutWidth(width);
boolean hasOverflow = mCollapsedIcons.hasOverflow();
int collapsedPadding = mCollapsedIcons.getPaddingEnd();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index aa07c70..6920d10 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -41,6 +41,7 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.car.hvac.HvacController;
+import com.android.systemui.statusbar.car.hvac.TemperatureView;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.BatteryController;
@@ -82,6 +83,7 @@
private ActivityManagerWrapper mActivityManagerWrapper;
private DeviceProvisionedController mDeviceProvisionedController;
private boolean mDeviceIsProvisioned = true;
+ private HvacController mHvacController;
@Override
public void start() {
@@ -95,8 +97,7 @@
createBatteryController();
mCarBatteryController.startListening();
- Log.d(TAG, "Connecting to HVAC service");
- Dependency.get(HvacController.class).connectToCarService();
+ mHvacController.connectToCarService();
mCarFacetButtonController = Dependency.get(CarFacetButtonController.class);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
@@ -119,10 +120,11 @@
* before and after the device is provisioned
*/
private void restartNavBars() {
+ // remove and reattach all hvac components such that we don't keep a reference to unused
+ // ui elements
+ mHvacController.removeAllComponents();
+ addTemperatureViewToController(mStatusBarWindow);
mCarFacetButtonController.removeAll();
-
- Dependency.get(HvacController.class).removeAllComponents();
-
if (mNavigationBarWindow != null) {
mNavigationBarWindow.removeAllViews();
mNavigationBarView = null;
@@ -137,9 +139,22 @@
mRightNavigationBarWindow.removeAllViews();
mRightNavigationBarView = null;
}
+
buildNavBarContent();
}
+ private void addTemperatureViewToController(View v) {
+ if (v instanceof TemperatureView) {
+ Log.d(TAG, "addTemperatureViewToController: found ");
+ mHvacController.addHvacTextView((TemperatureView) v);
+ } else if (v instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) v;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ addTemperatureViewToController(viewGroup.getChildAt(i));
+ }
+ }
+ }
+
/**
* Allows for showing or hiding just the navigation bars. This is indented to be used when
* the full screen user selector is shown.
@@ -214,6 +229,7 @@
@Override
protected void makeStatusBarView() {
super.makeStatusBarView();
+ mHvacController = Dependency.get(HvacController.class);
mNotificationPanelBackground = getDefaultWallpaper();
mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
@@ -226,6 +242,7 @@
// when a device has connected by bluetooth.
mBatteryMeterView.setVisibility(View.GONE);
});
+ addTemperatureViewToController(mStatusBarWindow);
}
private BatteryController createBatteryController() {
@@ -264,7 +281,6 @@
private void buildNavBarWindows() {
if (mShowBottom) {
-
mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
R.layout.navigation_bar_window, null);
}
@@ -342,6 +358,7 @@
throw new RuntimeException("Unable to build botom nav bar due to missing layout");
}
mNavigationBarView.setStatusBar(this);
+ addTemperatureViewToController(mNavigationBarView);
}
private void buildLeft(int layout) {
@@ -352,6 +369,7 @@
throw new RuntimeException("Unable to build left nav bar due to missing layout");
}
mLeftNavigationBarView.setStatusBar(this);
+ addTemperatureViewToController(mLeftNavigationBarView);
}
@@ -362,6 +380,8 @@
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
throw new RuntimeException("Unable to build right nav bar due to missing layout");
}
+ mRightNavigationBarView.setStatusBar(this);
+ addTemperatureViewToController(mRightNavigationBarView);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index af0ed284..506d697 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -40,7 +40,6 @@
private final int mShortAnimDuration;
private final StatusBar mStatusBar;
private final UserManagerHelper mUserManagerHelper;
- private int mCurrentForegroundUserId;
private boolean mShowing;
public FullscreenUserSwitcher(StatusBar statusBar, ViewStub containerStub, Context context) {
@@ -55,7 +54,6 @@
mUserGridView.setUserSelectionListener(this::onUserSelected);
mUserManagerHelper = new UserManagerHelper(context);
- updateCurrentForegroundUser();
mShortAnimDuration = mContainer.getResources()
.getInteger(android.R.integer.config_shortAnimTime);
@@ -78,22 +76,8 @@
}
public void onUserSwitched(int newUserId) {
- // The logic for foreground user change is needed here to exclude the reboot case. On
- // reboot, system fires ACTION_USER_SWITCHED change from -1 to 0 user. This is not an actual
- // user switch. We only want to trigger keyguard dismissal when foreground user changes.
- if (foregroundUserChanged()) {
- toggleSwitchInProgress(false);
- updateCurrentForegroundUser();
- mParent.post(this::dismissKeyguard);
- }
- }
-
- private boolean foregroundUserChanged() {
- return mCurrentForegroundUserId != mUserManagerHelper.getForegroundUserId();
- }
-
- private void updateCurrentForegroundUser() {
- mCurrentForegroundUserId = mUserManagerHelper.getForegroundUserId();
+ toggleSwitchInProgress(false);
+ mParent.post(this::dismissKeyguard);
}
private void onUserSelected(UserGridRecyclerView.UserRecord record) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 32fd054..6c924e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.car.hvac;
import android.car.Car;
-import android.car.CarNotConnectedException;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.hvac.CarHvacManager;
import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
index 8143c13..4d8ce43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/TemperatureTextView.java
@@ -21,7 +21,6 @@
import android.util.AttributeSet;
import android.widget.TextView;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
/**
@@ -31,8 +30,6 @@
* hvacPropertyId - Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385)
* hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1)
* hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol)
- *
- * Note: It registers itself with {@link HvacController}
*/
public class TemperatureTextView extends TextView implements TemperatureView {
@@ -47,10 +44,6 @@
mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1);
String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat);
mTempFormat = (format == null) ? "%.1f\u00B0" : format;
-
- // register with controller
- HvacController hvacController = Dependency.get(HvacController.class);
- hvacController.addHvacTextView(this);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index 8f552e3..92a9efe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -40,6 +40,8 @@
public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
public static final boolean FORCE_NO_BLANKING =
SystemProperties.getBoolean("debug.force_no_blanking", false);
+ public static final boolean FORCE_BLANKING =
+ SystemProperties.getBoolean("debug.force_blanking", false);
private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
private static DozeParameters sInstance;
@@ -183,7 +185,7 @@
* @return {@code true} if screen needs to be completely black before a power transition.
*/
public boolean getDisplayNeedsBlanking() {
- return !FORCE_NO_BLANKING && mContext.getResources().getBoolean(
+ return FORCE_BLANKING || !FORCE_NO_BLANKING && mContext.getResources().getBoolean(
com.android.internal.R.bool.config_displayBlanksAfterDoze);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index 0db408c..0a724bd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -536,7 +536,8 @@
return 0;
}
- int translation = (int) (mLastVisibleIconState.xTranslation + mIconSize);
+ int translation = (int) (isLayoutRtl() ? getWidth() - mLastVisibleIconState.xTranslation
+ : mLastVisibleIconState.xTranslation + mIconSize);
// There's a chance that last translation goes beyond the edge maybe
return Math.min(getWidth(), translation);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index be8bf02..7476963 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -92,6 +92,21 @@
private static final boolean DEBUG = false;
+ /**
+ * Fling expanding QS.
+ */
+ public static final int FLING_EXPAND = 0;
+
+ /**
+ * Fling collapsing QS, potentially stopping when QS becomes QQS.
+ */
+ public static final int FLING_COLLAPSE = 1;
+
+ /**
+ * Fing until QS is completely hidden.
+ */
+ public static final int FLING_HIDE = 2;
+
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
// changed.
private static final int CAP_HEIGHT = 1456;
@@ -623,7 +638,7 @@
}
@Override
- public void resetViews() {
+ public void resetViews(boolean animate) {
mIsLaunchTransitionFinished = false;
mBlockTouches = false;
mUnlockIconActive = false;
@@ -631,11 +646,15 @@
mAffordanceHelper.reset(false);
mLastCameraLaunchSource = KeyguardBottomAreaView.CAMERA_LAUNCH_SOURCE_AFFORDANCE;
}
- closeQs();
mStatusBar.getGutsManager().closeAndSaveGuts(true /* leavebehind */, true /* force */,
true /* controls */, -1 /* x */, -1 /* y */, true /* resetMenu */);
- mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */,
- true /* cancelAnimators */);
+ if (animate) {
+ animateCloseQs(true /* animateAway */);
+ } else {
+ closeQs();
+ }
+ mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, animate,
+ !animate /* cancelAnimators */);
mNotificationStackScroller.resetScrollPosition();
}
@@ -657,7 +676,13 @@
setQsExpansion(mQsMinExpansionHeight);
}
- public void animateCloseQs() {
+ /**
+ * Animate QS closing by flinging it.
+ * If QS is expanded, it will collapse into QQS and stop.
+ *
+ * @param animateAway Do not stop when QS becomes QQS. Fling until QS isn't visible anymore.
+ */
+ public void animateCloseQs(boolean animateAway) {
if (mQsExpansionAnimator != null) {
if (!mQsAnimatorExpand) {
return;
@@ -666,14 +691,7 @@
mQsExpansionAnimator.cancel();
setQsExpansion(height);
}
- flingSettings(0 /* vel */, false);
- }
-
- public void openQs() {
- cancelQsAnimation();
- if (mQsExpansionEnabled) {
- setQsExpansion(mQsMaxExpansionHeight);
- }
+ flingSettings(0 /* vel */, animateAway ? FLING_HIDE : FLING_COLLAPSE);
}
public void expandWithQs() {
@@ -686,7 +704,7 @@
public void expandWithoutQs() {
if (isQsExpanded()) {
- flingSettings(0 /* velocity */, false /* expand */);
+ flingSettings(0 /* velocity */, FLING_COLLAPSE);
} else {
expand(true /* animate */);
}
@@ -830,7 +848,7 @@
if (expandsQs) {
logQsSwipeDown(y);
}
- flingSettings(vel, expandsQs && !isCancelMotionEvent);
+ flingSettings(vel, expandsQs && !isCancelMotionEvent ? FLING_EXPAND : FLING_COLLAPSE);
}
private void logQsSwipeDown(float y) {
@@ -1099,7 +1117,8 @@
mLastOverscroll = 0f;
mQsExpansionFromOverscroll = false;
setQsExpansion(mQsExpansionHeight);
- flingSettings(!mQsExpansionEnabled && open ? 0f : velocity, open && mQsExpansionEnabled,
+ flingSettings(!mQsExpansionEnabled && open ? 0f : velocity,
+ open && mQsExpansionEnabled ? FLING_EXPAND : FLING_COLLAPSE,
new Runnable() {
@Override
public void run() {
@@ -1466,13 +1485,35 @@
}
}
- public void flingSettings(float vel, boolean expand) {
- flingSettings(vel, expand, null, false /* isClick */);
+ /**
+ * @see #flingSettings(float, int, Runnable, boolean)
+ */
+ public void flingSettings(float vel, int type) {
+ flingSettings(vel, type, null, false /* isClick */);
}
- protected void flingSettings(float vel, boolean expand, final Runnable onFinishRunnable,
+ /**
+ * Animates QS or QQS as if the user had swiped up or down.
+ *
+ * @param vel Finger velocity or 0 when not initiated by touch events.
+ * @param type Either {@link #FLING_EXPAND}, {@link #FLING_COLLAPSE} or {@link #FLING_HIDE}.
+ * @param onFinishRunnable Runnable to be executed at the end of animation.
+ * @param isClick If originated by click (different interpolator and duration.)
+ */
+ protected void flingSettings(float vel, int type, final Runnable onFinishRunnable,
boolean isClick) {
- float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight;
+ float target;
+ switch (type) {
+ case FLING_EXPAND:
+ target = mQsMaxExpansionHeight;
+ break;
+ case FLING_COLLAPSE:
+ target = mQsMinExpansionHeight;
+ break;
+ case FLING_HIDE:
+ default:
+ target = 0;
+ }
if (target == mQsExpansionHeight) {
if (onFinishRunnable != null) {
onFinishRunnable.run();
@@ -1482,7 +1523,8 @@
// If we move in the opposite direction, reset velocity and use a different duration.
boolean oppositeDirection = false;
- if (vel > 0 && !expand || vel < 0 && expand) {
+ boolean expanding = type == FLING_EXPAND;
+ if (vel > 0 && !expanding || vel < 0 && expanding) {
vel = 0;
oppositeDirection = true;
}
@@ -1496,11 +1538,8 @@
if (oppositeDirection) {
animator.setDuration(350);
}
- animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- setQsExpansion((Float) animation.getAnimatedValue());
- }
+ animator.addUpdateListener(animation -> {
+ setQsExpansion((Float) animation.getAnimatedValue());
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
@@ -1514,7 +1553,7 @@
});
animator.start();
mQsExpansionAnimator = animator;
- mQsAnimatorExpand = expand;
+ mQsAnimatorExpand = expanding;
}
/**
@@ -2000,10 +2039,12 @@
public void onClick(View v) {
onQsExpansionStarted();
if (mQsExpanded) {
- flingSettings(0 /* vel */, false /* expand */, null, true /* isClick */);
+ flingSettings(0 /* vel */, FLING_COLLAPSE, null /* onFinishRunnable */,
+ true /* isClick */);
} else if (mQsExpansionEnabled) {
mLockscreenGestureLogger.write(MetricsEvent.ACTION_SHADE_QS_TAP, 0, 0);
- flingSettings(0 /* vel */, true /* expand */, null, true /* isClick */);
+ flingSettings(0 /* vel */, FLING_EXPAND, null /* onFinishRunnable */,
+ true /* isClick */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 5d23494..deac669e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -194,7 +194,7 @@
pv.collapse(delayed, speedUpFactor);
waiting = true;
} else {
- pv.resetViews();
+ pv.resetViews(false /* animate */);
pv.setExpandedFraction(0); // just in case
pv.cancelPeek();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index e4eeec1..1f09835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -1240,7 +1240,7 @@
));
}
- public abstract void resetViews();
+ public abstract void resetViews(boolean animate);
protected abstract float getPeekHeight();
/**
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 4c91a9d..3c351ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -2239,7 +2239,8 @@
mNotificationPanel.expand(true /* animate */);
mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN, 1);
} else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
- mNotificationPanel.flingSettings(0 /* velocity */, true /* expand */);
+ mNotificationPanel.flingSettings(0 /* velocity */,
+ NotificationPanelView.FLING_EXPAND);
mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
}
}
@@ -3689,7 +3690,7 @@
Log.w(TAG, "Launch transition: Timeout!");
mNotificationPanel.onAffordanceLaunchEnded();
releaseGestureWakeLock();
- mNotificationPanel.resetViews();
+ mNotificationPanel.resetViews(false /* animate */);
}
private void runLaunchTransitionEndRunnable() {
@@ -3842,7 +3843,9 @@
Trace.beginSection("StatusBar#updateKeyguardState");
if (mState == StatusBarState.KEYGUARD) {
mKeyguardIndicationController.setVisible(true);
- mNotificationPanel.resetViews();
+ boolean dozingAnimated = mDozingRequested
+ && DozeParameters.getInstance(mContext).shouldControlScreenOff();
+ mNotificationPanel.resetViews(dozingAnimated);
if (mKeyguardUserSwitcher != null) {
mKeyguardUserSwitcher.setKeyguard(true, fromShadeLocked);
}
@@ -3987,7 +3990,7 @@
if (mNotificationPanel.isQsDetailShowing()) {
mNotificationPanel.closeQsDetail();
} else {
- mNotificationPanel.animateCloseQs();
+ mNotificationPanel.animateCloseQs(false /* animateAway */);
}
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 8dbdd21..cf39404 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -979,7 +979,7 @@
private SubscriptionInfo addSignalController(int id, int simSlotIndex) {
SubscriptionInfo info = new SubscriptionInfo(id, "", simSlotIndex, "", "", 0, 0, "", 0,
- null, null, null, "");
+ null, null, null, "", false, null, null);
MobileSignalController controller = new MobileSignalController(mContext,
mConfig, mHasMobileDataFeature, mPhone, mCallbackHandler, this, info,
mSubDefaults, mReceiverHandler.getLooper());
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index 1bdb7ad..196d9bc 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -119,7 +119,9 @@
// 3 Removed because of a revert.
if (oldVersion < 4) {
// Delay this so that we can wait for everything to be registered first.
- new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(() -> clearAll(), 5000);
+ final int user = mCurrentUser;
+ new Handler(Dependency.get(Dependency.BG_LOOPER)).postDelayed(
+ () -> clearAllFromUser(user), 5000);
}
setValue(TUNER_VERSION, newVersion);
}
@@ -221,6 +223,10 @@
@Override
public void clearAll() {
+ clearAllFromUser(mCurrentUser);
+ }
+
+ public void clearAllFromUser(int user) {
// A couple special cases.
Settings.Global.putString(mContentResolver, DemoMode.DEMO_MODE_ALLOWED, null);
Intent intent = new Intent(DemoMode.ACTION_DEMO);
@@ -231,7 +237,7 @@
if (ArrayUtils.contains(RESET_BLACKLIST, key)) {
continue;
}
- Settings.Secure.putString(mContentResolver, key, null);
+ Settings.Secure.putStringForUser(mContentResolver, key, null, user);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
new file mode 100644
index 0000000..e6e4857
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.keyguard;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Color;
+import android.graphics.Paint.Style;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.text.TextPaint;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+import android.widget.TextClock;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ClockPlugin;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWithLooper(setAsMainLooper = true)
+@RunWith(AndroidTestingRunner.class)
+public class KeyguardClockSwitchTest extends SysuiTestCase {
+ private PluginManager mPluginManager;
+
+ @Mock
+ TextClock mClockView;
+ @InjectMocks
+ KeyguardClockSwitch mKeyguardClockSwitch;
+
+ @Before
+ public void setUp() {
+ mPluginManager = mDependency.injectMockDependency(PluginManager.class);
+ LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ mKeyguardClockSwitch =
+ (KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void onAttachToWindow_addPluginListener() {
+ mKeyguardClockSwitch.onAttachedToWindow();
+
+ ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+ verify(mPluginManager).addPluginListener(listener.capture(), eq(ClockPlugin.class));
+ }
+
+ @Test
+ public void onDetachToWindow_removePluginListener() {
+ mKeyguardClockSwitch.onDetachedFromWindow();
+
+ ArgumentCaptor<PluginListener> listener = ArgumentCaptor.forClass(PluginListener.class);
+ verify(mPluginManager).removePluginListener(listener.capture());
+ }
+
+ @Test
+ public void onPluginConnected_showPluginClock() {
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ TextClock pluginView = new TextClock(getContext());
+ when(plugin.getView()).thenReturn(pluginView);
+ TextPaint paint = mock(TextPaint.class);
+ doReturn(paint).when(mClockView).getPaint();
+ PluginListener listener = mKeyguardClockSwitch.getClockPluginListener();
+
+ listener.onPluginConnected(plugin, null);
+
+ verify(mClockView).setVisibility(GONE);
+ assertThat(plugin.getView().getParent()).isEqualTo(mKeyguardClockSwitch);
+ }
+
+ @Test
+ public void onPluginDisconnected_showDefaultClock() {
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ TextClock pluginView = new TextClock(getContext());
+ when(plugin.getView()).thenReturn(pluginView);
+ mClockView.setVisibility(GONE);
+ mKeyguardClockSwitch.addView(plugin.getView(), -1,
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ PluginListener listener = mKeyguardClockSwitch.getClockPluginListener();
+
+ listener.onPluginDisconnected(plugin);
+
+ verify(mClockView).setVisibility(VISIBLE);
+ assertThat(plugin.getView().getParent()).isNull();
+ }
+
+ @Test
+ public void setTextColor_defaultClockSetTextColor() {
+ mKeyguardClockSwitch.setTextColor(Color.YELLOW);
+
+ verify(mClockView).setTextColor(Color.YELLOW);
+ }
+
+ @Test
+ public void setTextColor_pluginClockSetTextColor() {
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ TextClock pluginView = new TextClock(getContext());
+ when(plugin.getView()).thenReturn(pluginView);
+ TextPaint paint = mock(TextPaint.class);
+ doReturn(paint).when(mClockView).getPaint();
+ PluginListener listener = mKeyguardClockSwitch.getClockPluginListener();
+ listener.onPluginConnected(plugin, null);
+
+ mKeyguardClockSwitch.setTextColor(Color.WHITE);
+
+ verify(plugin).setTextColor(Color.WHITE);
+ }
+
+ @Test
+ public void setStyle_defaultClockSetStyle() {
+ TextPaint paint = mock(TextPaint.class);
+ Style style = mock(Style.class);
+ doReturn(paint).when(mClockView).getPaint();
+
+ mKeyguardClockSwitch.setStyle(style);
+
+ verify(paint).setStyle(style);
+ }
+
+ @Test
+ public void setStyle_pluginClockSetStyle() {
+ ClockPlugin plugin = mock(ClockPlugin.class);
+ TextClock pluginView = new TextClock(getContext());
+ when(plugin.getView()).thenReturn(pluginView);
+ TextPaint paint = mock(TextPaint.class);
+ doReturn(paint).when(mClockView).getPaint();
+ Style style = mock(Style.class);
+ PluginListener listener = mKeyguardClockSwitch.getClockPluginListener();
+ listener.onPluginConnected(plugin, null);
+
+ mKeyguardClockSwitch.setStyle(style);
+
+ verify(plugin).setStyle(style);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
index d2e8371..4ec30fd 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSliceViewTest.java
@@ -55,7 +55,7 @@
@Test
public void showSlice_notifiesListener() {
- ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
+ ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
AtomicBoolean notified = new AtomicBoolean();
mKeyguardSliceView.setContentChangeListener(()-> notified.set(true));
mKeyguardSliceView.onChanged(builder.build());
@@ -74,13 +74,11 @@
@Test
public void hasHeader_readsSliceData() {
- ListBuilder builder = new ListBuilder(getContext(), mSliceUri);
+ ListBuilder builder = new ListBuilder(getContext(), mSliceUri, ListBuilder.INFINITY);
mKeyguardSliceView.onChanged(builder.build());
Assert.assertFalse("View should not have a header", mKeyguardSliceView.hasHeader());
- builder.setHeader((ListBuilder.HeaderBuilder headerBuilder) -> {
- headerBuilder.setTitle("header title!");
- });
+ builder.setHeader(new ListBuilder.HeaderBuilder().setTitle("header title!"));
mKeyguardSliceView.onChanged(builder.build());
Assert.assertTrue("View should have a header", mKeyguardSliceView.hasHeader());
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 1d8de2f..9e96df2 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -22,7 +22,6 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
-import android.widget.TextClock;
import com.android.systemui.SysuiTestCase;
@@ -40,7 +39,7 @@
@Mock
KeyguardSliceView mKeyguardSlice;
@Mock
- TextClock mClockView;
+ KeyguardClockSwitch mClockView;
@InjectMocks
KeyguardStatusView mKeyguardStatusView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 46e2bfb..a26b1b5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -137,7 +137,8 @@
@Test
public void addZenMode_addedToSlice() {
- ListBuilder listBuilder = spy(new ListBuilder(getContext(), mProvider.getUri()));
+ ListBuilder listBuilder = spy(new ListBuilder(getContext(), mProvider.getUri(),
+ ListBuilder.INFINITY));
mProvider.addZenMode(listBuilder);
verify(listBuilder, never()).addRow(any(ListBuilder.RowBuilder.class));
diff --git a/packages/WAPPushManager/AndroidManifest.xml b/packages/WAPPushManager/AndroidManifest.xml
index 89e9d6a..14e6e91 100644
--- a/packages/WAPPushManager/AndroidManifest.xml
+++ b/packages/WAPPushManager/AndroidManifest.xml
@@ -24,7 +24,8 @@
android:protectionLevel="signatureOrSystem" />
<original-package android:name="com.android.smspush" />
- <application>
+ <application
+ android:allowClearUserData="false">
<service android:name=".WapPushManager"
android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
android:exported="true">
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 02f0439..f8b4d74 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -941,9 +941,10 @@
// OS: 6.0
NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
- // ACTION: App notification settings > Block Notifications
+ // ACTION: App notification settings > Block Notifications or long press on
+ // notification blocks.
// CATEGORY: SETTINGS
- // OS: 6.0
+ // OS: 9.0
ACTION_BAN_APP_NOTES = 147;
// ACTION: Notification shade > Dismiss all button
@@ -6180,6 +6181,254 @@
// OS: Q
DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
+ // ACTION: Activity start
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ ACTION_ACTIVITY_START = 1513;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Calling UID
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_CALLING_UID = 1514;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Calling package name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_CALLING_PACKAGE_NAME = 1515;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Calling UID proc state
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_CALLING_UID_PROC_STATE = 1516;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Calling UID has any visible window
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1517;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Real calling UID
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_REAL_CALLING_UID = 1518;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Real calling UID proc state
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_REAL_CALLING_UID_PROC_STATE = 1519;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Real calling UID has any visible window
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1520;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target UID
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_UID = 1521;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target UID package name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_PACKAGE_NAME = 1522;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target UID proc state
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_UID_PROC_STATE = 1523;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target UID has any visible window
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW = 1524;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target doze whitelist tag
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_WHITELIST_TAG = 1525;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Target short component name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_TARGET_SHORT_COMPONENT_NAME = 1526;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Coming from pending intent
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_COMING_FROM_PENDING_INTENT = 1527;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Intent action
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_INTENT_ACTION = 1528;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record process name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_PROCESS_NAME = 1529;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record current proc state
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_CUR_PROC_STATE = 1530;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record has client activities
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES = 1531;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record has foreground services
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES = 1532;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record has foreground activities
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES = 1533;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record has top UI
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_HAS_TOP_UI = 1534;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record has overlay UI
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_HAS_OVERLAY_UI = 1535;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Caller app process record pending UI clean
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_PENDING_UI_CLEAN = 1536;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Millis since caller app's process record last interaction event
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT = 1537;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Millis since caller app's process record fg interaction
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION = 1538;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Millis since caller app's process record last became unimportant
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT = 1539;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record launch mode
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_LAUNCH_MODE = 1540;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record target activity
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY = 1541;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record flags
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_FLAGS = 1542;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record real activity
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_REAL_ACTIVITY = 1543;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record short component name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME = 1544;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record process name
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_PROCESS_NAME = 1545;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record is fullscreen
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_IS_FULLSCREEN = 1546;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record is no display
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY = 1547;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Millis since activity was last visible
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE = 1548;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record's resultTo packageName
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME = 1549;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record's resultTo shortComponentName
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME = 1550;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record is visible
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_IS_VISIBLE = 1551;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Activity record is visible ignoring keyguard
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD = 1552;
+
+ // Tagged data for ACTION_ACTIVITY_START.
+ // FIELD: Millis since activity's last launch
+ // CATEGORY: OTHER
+ // OS: Q (will also ship in PQ1A)
+ FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553;
+
+ // OPEN: Settings > Add face
+ // OS: Q
+ FACE_ENROLL_PREVIEW = 1554;
// ---- End Q Constants, all Q constants go above this line ----
diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
index 1229c58..347a084 100644
--- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java
@@ -375,6 +375,7 @@
return false;
}
+ mAms.onTouchInteractionEnd();
// Remove pending event deliveries.
mSendHoverEnterAndMoveDelayed.cancel();
mSendHoverExitDelayed.cancel();
@@ -382,9 +383,9 @@
if (mSendTouchExplorationEndDelayed.isPending()) {
mSendTouchExplorationEndDelayed.forceSendAndRemove();
}
- if (mSendTouchInteractionEndDelayed.isPending()) {
- mSendTouchInteractionEndDelayed.forceSendAndRemove();
- }
+
+ // Announce the end of a new touch interaction.
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_END);
// Try to use the standard accessibility API to click
if (mAms.performActionOnAccessibilityFocusedItem(
@@ -487,20 +488,25 @@
case MotionEvent.ACTION_DOWN: {
mAms.onTouchInteractionStart();
- sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
-
// If we still have not notified the user for the last
// touch, we figure out what to do. If were waiting
// we resent the delayed callback and wait again.
mSendHoverEnterAndMoveDelayed.cancel();
mSendHoverExitDelayed.cancel();
- if (mSendTouchExplorationEndDelayed.isPending()) {
- mSendTouchExplorationEndDelayed.forceSendAndRemove();
+ // If a touch exploration gesture is in progress send events for its end.
+ if(mTouchExplorationInProgress) {
+ sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
- if (mSendTouchInteractionEndDelayed.isPending()) {
+ // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap.
+ if (!mGestureDetector.firstTapDetected()) {
+ mSendTouchExplorationEndDelayed.forceSendAndRemove();
mSendTouchInteractionEndDelayed.forceSendAndRemove();
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+ } else {
+ // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
+ mSendTouchInteractionEndDelayed.cancel();
}
if (!mGestureDetector.firstTapDetected() && !mTouchExplorationInProgress) {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index c9c7adc..f69b638 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -48,11 +48,6 @@
}
@Override
- public void onUnlockUser(int userHandle) {
- FgThread.getHandler().post(() -> mImpl.onUserUnlocked(userHandle));
- }
-
- @Override
public void onStopUser(int userHandle) {
mImpl.onUserStopped(userHandle);
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index db8ad12..b71d7a7 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,7 +19,6 @@
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import android.annotation.UserIdInt;
@@ -2697,7 +2696,12 @@
}
}
- void onUserUnlocked(int userId) {
+ /**
+ * This does not use the usual onUserUnlocked() listener mechanism because it is
+ * invoked at a choreographed point in the middle of the user unlock sequence,
+ * before the boot-completed broadcast is issued and the listeners notified.
+ */
+ void handleUserUnlocked(int userId) {
if (isProfileWithLockedParent(userId)) {
return;
}
@@ -2734,7 +2738,7 @@
}
}
}
- Slog.i(TAG, "Async processing of onUserUnlocked u" + userId + " took "
+ Slog.i(TAG, "Processing of handleUserUnlocked u" + userId + " took "
+ (SystemClock.elapsedRealtime() - time) + " ms");
}
@@ -4801,5 +4805,11 @@
return widgetPackages;
}
}
+
+ @Override
+ public void unlockUser(int userId) {
+ handleUserUnlocked(userId);
+ }
+
}
}
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index a40afc3..f7c1c10 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -136,7 +136,7 @@
CountDownLatch mLatch;
FullBackupJob mJob; // if a scheduled job needs to be finished afterwards
IBackupObserver mBackupObserver;
- IBackupManagerMonitor mMonitor;
+ @Nullable private IBackupManagerMonitor mMonitor;
boolean mUserInitiated;
SinglePackageBackupRunner mBackupRunner;
private final int mBackupRunnerOpToken;
@@ -154,7 +154,7 @@
IFullBackupRestoreObserver observer,
String[] whichPackages, boolean updateSchedule,
FullBackupJob runningJob, CountDownLatch latch, IBackupObserver backupObserver,
- IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
+ @Nullable IBackupManagerMonitor monitor, @Nullable OnTaskFinishedListener listener,
boolean userInitiated) {
super(observer);
this.backupManagerService = backupManagerService;
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java
new file mode 100644
index 0000000..8c83e67
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupReporter.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.keyvalue;
+
+import android.annotation.Nullable;
+import android.app.backup.BackupManager;
+import android.app.backup.BackupManagerMonitor;
+import android.app.backup.BackupTransport;
+import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
+import android.content.pm.PackageInfo;
+import android.util.EventLog;
+import android.util.Slog;
+
+import com.android.server.EventLogTags;
+import com.android.server.backup.BackupManagerService;
+import com.android.server.backup.DataChangedJournal;
+import com.android.server.backup.remote.RemoteResult;
+import com.android.server.backup.utils.BackupManagerMonitorUtils;
+import com.android.server.backup.utils.BackupObserverUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+/**
+ * Reports events that happen during a key-value backup task to:
+ *
+ * <ul>
+ * <li>Logcat (main and event buffers).
+ * <li>Backup observer (see {@link IBackupObserver}).
+ * <li>Backup manager monitor (see {@link IBackupManagerMonitor}).
+ * </ul>
+ */
+// TODO: In KeyValueBackupTaskTest, remove direct assertions on logcat, observer or monitor and
+// verify calls to this object. Add these and more assertions to the test of this class.
+class KeyValueBackupReporter {
+ private static final String TAG = "KeyValueBackupTask";
+ private static final boolean DEBUG = BackupManagerService.DEBUG;
+ private static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || true;
+
+ private final BackupManagerService mBackupManagerService;
+ private final IBackupObserver mObserver;
+ @Nullable private IBackupManagerMonitor mMonitor;
+
+ KeyValueBackupReporter(
+ BackupManagerService backupManagerService,
+ IBackupObserver observer,
+ IBackupManagerMonitor monitor) {
+ mBackupManagerService = backupManagerService;
+ mObserver = observer;
+ mMonitor = monitor;
+ }
+
+ /** Returns the monitor or {@code null} if we lost connection to it. */
+ @Nullable
+ IBackupManagerMonitor getMonitor() {
+ return mMonitor;
+ }
+
+ void onSkipBackup() {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping backup since one is already in progress");
+ }
+ }
+
+ void onEmptyQueueAtStart() {
+ Slog.w(TAG, "Backup begun with an empty queue, nothing to do");
+ }
+
+ void onPmFoundInQueue() {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "PM metadata in queue, removing");
+ }
+ }
+
+ void onQueueReady(List<BackupRequest> queue) {
+ if (DEBUG) {
+ Slog.v(TAG, "Beginning backup of " + queue.size() + " targets");
+ }
+ }
+
+ void onTransportReady(String transportName) {
+ EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
+ }
+
+ void onInitializeTransport(String transportName) {
+ Slog.i(TAG, "Initializing transport and resetting backup state");
+ }
+
+ void onTransportInitialized(int status) {
+ if (status == BackupTransport.TRANSPORT_OK) {
+ EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
+ } else {
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
+ Slog.e(TAG, "Transport error in initializeDevice()");
+ }
+ }
+
+ void onInitializeTransportError(Exception e) {
+ Slog.e(TAG, "Error during initialization", e);
+ }
+
+ void onSkipPm() {
+ Slog.d(TAG, "Skipping backup of PM metadata");
+ }
+
+ void onInvokePmAgentError(Exception e) {
+ Slog.e(TAG, "Error during PM metadata backup", e);
+ }
+
+ void onEmptyQueue() {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Queue now empty");
+ }
+ }
+
+ void onStartPackageBackup(String packageName) {
+ Slog.d(TAG, "Starting key-value backup of " + packageName);
+ }
+
+ void onPackageNotEligibleForBackup(String packageName) {
+ Slog.i(TAG, "Package " + packageName + " no longer supports backup, skipping");
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ }
+
+ void onPackageEligibleForFullBackup(String packageName) {
+ Slog.i(
+ TAG,
+ "Package " + packageName + " performs full-backup rather than key-value, skipping");
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ }
+
+ void onPackageStopped(String packageName) {
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ }
+
+ void onBindAgentError(SecurityException e) {
+ Slog.d(TAG, "Error in bind/backup", e);
+ }
+
+ void onAgentUnknown(String packageName) {
+ Slog.d(TAG, "Package does not exist, skipping");
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_PACKAGE_NOT_FOUND);
+ }
+
+ void onAgentError(String packageName) {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Agent failure for " + packageName + ", re-staging");
+ }
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_AGENT_FAILURE);
+ }
+
+ void onInvokeAgent(String packageName) {
+ if (DEBUG) {
+ Slog.d(TAG, "Invoking agent on " + packageName);
+ }
+ }
+
+ void onAgentFilesReady(File backupDataFile) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Data file: " + backupDataFile);
+ }
+ }
+
+ void onRestoreconFailed(File backupDataFile) {
+ Slog.e(TAG, "SELinux restorecon failed on " + backupDataFile);
+ }
+
+ void onCallAgentDoBackupError(String packageName, boolean callingAgent, Exception e) {
+ if (callingAgent) {
+ Slog.e(TAG, "Error invoking agent on " + packageName + ": " + e);
+ } else {
+ Slog.e(TAG, "Error before invoking agent on " + packageName + ": " + e);
+ }
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName, e.toString());
+ }
+
+ void onFailAgentError(String packageName) {
+ Slog.w(TAG, "Error conveying failure to " + packageName);
+ }
+
+ void onAgentIllegalKey(PackageInfo packageInfo, String key) {
+ String packageName = packageInfo.packageName;
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName, "bad key");
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
+ packageInfo,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY, key));
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_AGENT_FAILURE);
+ if (MORE_DEBUG) {
+ Slog.i(
+ TAG,
+ "Agent failure for " + packageName + " with illegal key " + key + ", dropped");
+ }
+ }
+
+ void onReadAgentDataError(String packageName, IOException e) {
+ Slog.w(TAG, "Unable read backup data for " + packageName + ": " + e);
+ }
+
+ void onWriteWidgetDataError(String packageName, IOException e) {
+ Slog.w(TAG, "Unable to save widget data for " + packageName + ": " + e);
+ }
+
+ void onDigestError(NoSuchAlgorithmException e) {
+ Slog.e(TAG, "Unable to use SHA-1!");
+ }
+
+ void onWriteWidgetData(boolean priorStateExists, @Nullable byte[] widgetState) {
+ if (MORE_DEBUG) {
+ Slog.i(
+ TAG,
+ "Checking widget update: state="
+ + (widgetState != null)
+ + " prior="
+ + priorStateExists);
+ }
+ }
+
+ void onTruncateDataError() {
+ Slog.w(TAG, "Unable to roll back");
+ }
+
+ void onSendDataToTransport(String packageName) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Sending non-empty data to transport for " + packageName);
+ }
+ }
+
+ void onNonIncrementalAndNonIncrementalRequired() {
+ Slog.e(TAG, "Transport requested non-incremental but already the case");
+ }
+
+ void onEmptyData(PackageInfo packageInfo) {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "No backup data written, not calling transport");
+ }
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
+ packageInfo,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ null);
+ }
+
+ void onPackageBackupComplete(String packageName, long size) {
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.SUCCESS);
+ EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, packageName, size);
+ mBackupManagerService.logBackupComplete(packageName);
+ }
+
+ void onPackageBackupRejected(String packageName) {
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+ EventLogTags.writeBackupAgentFailure(packageName, "Transport rejected");
+ }
+
+ void onPackageBackupQuotaExceeded(String packageName) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + packageName + " hit quota limit on key-value backup");
+ }
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+ EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, packageName);
+ }
+
+ void onAgentDoQuotaExceededError(Exception e) {
+ Slog.e(TAG, "Unable to notify about quota exceeded: " + e);
+ }
+
+ void onPackageBackupNonIncrementalRequired(PackageInfo packageInfo) {
+ Slog.i(TAG, "Transport lost data, retrying package");
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
+ packageInfo,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+ /* extras */ null);
+ }
+
+ void onPackageBackupTransportFailure(String packageName) {
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_TRANSPORT_ABORTED);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, packageName);
+ }
+
+ void onPackageBackupError(String packageName, Exception e) {
+ Slog.e(TAG, "Transport error backing up " + packageName, e);
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, packageName, BackupManager.ERROR_TRANSPORT_ABORTED);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, packageName);
+ }
+
+ void onCloseFileDescriptorError(String logName) {
+ Slog.w(TAG, "Error closing " + logName + " file-descriptor");
+ }
+
+ void onCancel() {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Cancel received");
+ }
+ }
+
+ void onAgentTimedOut(@Nullable PackageInfo packageInfo) {
+ String packageName = getPackageName(packageInfo);
+ Slog.i(TAG, "Agent " + packageName + " timed out");
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ // Time-out used to be implemented as cancel w/ cancelAll = false.
+ // TODO: Change monitoring event to reflect time-out as an event itself.
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ packageInfo,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, false));
+ }
+
+ void onAgentCancelled(@Nullable PackageInfo packageInfo) {
+ String packageName = getPackageName(packageInfo);
+ Slog.i(TAG, "Cancel backing up " + packageName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ packageInfo,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, true));
+ }
+
+ private String getPackageName(@Nullable PackageInfo packageInfo) {
+ return (packageInfo != null) ? packageInfo.packageName : "no_package_yet";
+ }
+
+ void onRevertBackup() {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Reverting backup queue, re-staging everything");
+ }
+ }
+
+ void onTransportRequestBackupTimeError(Exception e) {
+ Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e);
+ }
+
+ void onRemoteCallReturned(RemoteResult result) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Agent call returned " + result);
+ }
+ }
+
+ void onJournalDeleteFailed(DataChangedJournal journal) {
+ Slog.e(TAG, "Unable to remove backup journal file " + journal);
+ }
+
+ void onSetCurrentTokenError(Exception e) {
+ Slog.e(TAG, "Transport threw reporting restore set: " + e);
+ }
+
+ void onTransportNotInitialized() {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Transport requires initialization, rerunning");
+ }
+ }
+
+ void onPendingInitializeTransportError(Exception e) {
+ Slog.w(TAG, "Failed to query transport name for pending init: " + e);
+ }
+
+ void onBackupFinished(int status) {
+ BackupObserverUtils.sendBackupFinished(mObserver, status);
+ }
+
+ void onStartFullBackup(List<String> pendingFullBackups) {
+ Slog.d(TAG, "Starting full backups for: " + pendingFullBackups);
+ }
+
+ void onKeyValueBackupFinished() {
+ Slog.i(TAG, "K/V backup pass finished");
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 113e2b6..41013aa 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -16,7 +16,11 @@
package com.android.server.backup.keyvalue;
-import static com.android.server.backup.BackupManagerService.DEBUG_BACKUP_TRACE;
+import static android.os.ParcelFileDescriptor.MODE_CREATE;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
+
import static com.android.server.backup.BackupManagerService.KEY_WIDGET_STATE;
import static com.android.server.backup.BackupManagerService.OP_PENDING;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
@@ -29,7 +33,6 @@
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManager;
-import android.app.backup.BackupManagerMonitor;
import android.app.backup.BackupTransport;
import android.app.backup.IBackupCallback;
import android.app.backup.IBackupManager;
@@ -47,7 +50,6 @@
import android.os.WorkSource;
import android.system.ErrnoException;
import android.system.Os;
-import android.util.EventLog;
import android.util.Pair;
import android.util.Slog;
@@ -55,12 +57,12 @@
import com.android.internal.backup.IBackupTransport;
import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
-import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
+import com.android.server.backup.TransportManager;
import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
import com.android.server.backup.internal.OnTaskFinishedListener;
import com.android.server.backup.internal.Operation;
@@ -69,9 +71,8 @@
import com.android.server.backup.remote.RemoteResult;
import com.android.server.backup.transport.TransportClient;
import com.android.server.backup.utils.AppBackupUtils;
-import com.android.server.backup.utils.BackupManagerMonitorUtils;
-import com.android.server.backup.utils.BackupObserverUtils;
+import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
@@ -172,7 +173,7 @@
// TODO: Distinguish between cancel and time-out where possible for logging/monitoring/observing
public class KeyValueBackupTask implements BackupRestoreTask, Runnable {
private static final String TAG = "KeyValueBackupTask";
- private static final boolean DEBUG = BackupManagerService.DEBUG || true;
+ private static final boolean DEBUG = BackupManagerService.DEBUG;
private static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || false;
private static final int THREAD_PRIORITY = Process.THREAD_PRIORITY_BACKGROUND;
private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
@@ -212,8 +213,8 @@
List<BackupRequest> queue,
@Nullable DataChangedJournal dataChangedJournal,
IBackupObserver observer,
- IBackupManagerMonitor monitor,
- @Nullable OnTaskFinishedListener listener,
+ @Nullable IBackupManagerMonitor monitor,
+ OnTaskFinishedListener listener,
List<String> pendingFullBackups,
boolean userInitiated,
boolean nonIncremental) {
@@ -239,10 +240,13 @@
}
private final BackupManagerService mBackupManagerService;
+ private final PackageManager mPackageManager;
+ private final TransportManager mTransportManager;
private final TransportClient mTransportClient;
private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
private final IBackupObserver mObserver;
- private final OnTaskFinishedListener mListener;
+ private final KeyValueBackupReporter mReporter;
+ private final OnTaskFinishedListener mTaskFinishedListener;
private final boolean mUserInitiated;
private final boolean mNonIncremental;
private final int mCurrentOpToken;
@@ -251,7 +255,6 @@
private final List<BackupRequest> mQueue;
private final List<String> mPendingFullBackups;
@Nullable private final DataChangedJournal mJournal;
- private IBackupManagerMonitor mMonitor;
@Nullable private PerformFullTransportBackupTask mFullBackupTask;
private IBackupAgent mAgentBinder;
@@ -294,20 +297,22 @@
List<BackupRequest> queue,
@Nullable DataChangedJournal journal,
IBackupObserver observer,
- IBackupManagerMonitor monitor,
- @Nullable OnTaskFinishedListener listener,
+ @Nullable IBackupManagerMonitor monitor,
+ OnTaskFinishedListener taskFinishedListener,
List<String> pendingFullBackups,
boolean userInitiated,
boolean nonIncremental) {
mBackupManagerService = backupManagerService;
+ mTransportManager = backupManagerService.getTransportManager();
+ mPackageManager = backupManagerService.getPackageManager();
mTransportClient = transportClient;
mOriginalQueue = queue;
// We need to retain the original queue contents in case of transport failure
- mQueue = new ArrayList<>(mOriginalQueue);
+ mQueue = new ArrayList<>(queue);
mJournal = journal;
mObserver = observer;
- mMonitor = monitor;
- mListener = (listener != null) ? listener : OnTaskFinishedListener.NOP;
+ mReporter = new KeyValueBackupReporter(backupManagerService, observer, monitor);
+ mTaskFinishedListener = taskFinishedListener;
mPendingFullBackups = pendingFullBackups;
mUserInitiated = userInitiated;
mNonIncremental = nonIncremental;
@@ -332,7 +337,7 @@
public void run() {
Process.setThreadPriority(THREAD_PRIORITY);
- BackupState state = beginBackup();
+ BackupState state = startBackup();
while (state == BackupState.RUNNING_QUEUE || state == BackupState.BACKUP_PM) {
if (mCancelled) {
state = BackupState.CANCELLED;
@@ -342,24 +347,24 @@
state = backupPm();
break;
case RUNNING_QUEUE:
- Pair<BackupState, RemoteResult> stateAndResult = invokeNextAgent();
+ Pair<BackupState, RemoteResult> stateAndResult = extractNextAgentData();
state = stateAndResult.first;
if (state == null) {
- state = processAgentInvocation(stateAndResult.second);
+ state = handleAgentResult(stateAndResult.second);
}
break;
}
}
if (state == BackupState.CANCELLED) {
- finalizeCancelledBackup();
+ finishCancelledBackup();
} else {
- finalizeBackup();
+ finishBackup();
}
}
- private BackupState processAgentInvocation(RemoteResult result) {
+ private BackupState handleAgentResult(RemoteResult result) {
if (result == RemoteResult.FAILED_THREAD_INTERRUPTED) {
- // Not an explicit cancel, we need to flag it
+ // Not an explicit cancel, we need to flag it.
mCancelled = true;
handleAgentCancelled();
return BackupState.CANCELLED;
@@ -373,7 +378,7 @@
return BackupState.RUNNING_QUEUE;
}
Preconditions.checkState(result.succeeded());
- return handleAgentResult(result.get());
+ return sendDataToTransport(result.get());
}
@Override
@@ -382,24 +387,10 @@
@Override
public void operationComplete(long unusedResult) {}
- private BackupState beginBackup() {
- if (DEBUG_BACKUP_TRACE) {
- mBackupManagerService.clearBackupTrace();
- StringBuilder b = new StringBuilder(256);
- b.append("beginBackup: [");
- for (BackupRequest req : mOriginalQueue) {
- b.append(' ');
- b.append(req.packageName);
- }
- b.append(" ]");
- mBackupManagerService.addBackupTrace(b.toString());
- }
+ private BackupState startBackup() {
synchronized (mBackupManagerService.getCurrentOpLock()) {
if (mBackupManagerService.isBackupOperationInProgress()) {
- if (DEBUG) {
- Slog.d(TAG, "Skipping backup since one is already in progress");
- }
- mBackupManagerService.addBackupTrace("Skipped. Backup already in progress.");
+ mReporter.onSkipBackup();
return BackupState.FINAL;
}
}
@@ -415,19 +406,17 @@
/* runningJob */ null,
new CountDownLatch(1),
mObserver,
- mMonitor,
- mListener,
+ mReporter.getMonitor(),
+ mTaskFinishedListener,
mUserInitiated);
registerTask();
- mBackupManagerService.addBackupTrace("STATE => INITIAL");
mAgentBinder = null;
mStatus = BackupTransport.TRANSPORT_OK;
// Sanity check: if the queue is empty we have no work to do.
if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
- Slog.w(TAG, "Backup begun with an empty queue, nothing to do.");
- mBackupManagerService.addBackupTrace("queue empty at begin");
+ mReporter.onEmptyQueueAtStart();
return BackupState.FINAL;
}
@@ -441,55 +430,39 @@
// we're committed to evaluating it for backup regardless.
for (int i = 0; i < mQueue.size(); i++) {
if (PACKAGE_MANAGER_SENTINEL.equals(mQueue.get(i).packageName)) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "PM metadata in queue, removing");
- }
+ mReporter.onPmFoundInQueue();
mQueue.remove(i);
skipPm = false;
break;
}
}
+ mReporter.onQueueReady(mQueue);
- if (DEBUG) {
- Slog.v(TAG, "Beginning backup of " + mQueue.size() + " targets");
- }
File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
try {
- IBackupTransport transport = mTransportClient.connectOrThrow("KVBT.beginBackup()");
+ IBackupTransport transport = mTransportClient.connectOrThrow("KVBT.startBackup()");
String transportName = transport.name();
- EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
+ mReporter.onTransportReady(transportName);
- // If we haven't stored package manager metadata yet, we must init the transport.
+ // If we haven't stored PM metadata yet, we must initialize the transport.
if (pmState.length() <= 0) {
- Slog.i(TAG, "Initializing transport and resetting backup state");
- mBackupManagerService.addBackupTrace("initializing transport " + transportName);
- mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ mReporter.onInitializeTransport(transportName);
+ mBackupManagerService.resetBackupState(mStateDir);
mStatus = transport.initializeDevice();
-
- mBackupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
- } else {
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, "(initialize)");
- Slog.e(TAG, "Transport error in initializeDevice()");
- }
+ mReporter.onTransportInitialized(mStatus);
}
} catch (Exception e) {
- Slog.e(TAG, "Error during initialization", e);
- mBackupManagerService.addBackupTrace("Exception in backup thread during init: " + e);
+ mReporter.onInitializeTransportError(e);
mStatus = BackupTransport.TRANSPORT_ERROR;
}
- mBackupManagerService.addBackupTrace("exiting prelim: " + mStatus);
if (mStatus != BackupTransport.TRANSPORT_OK) {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ mBackupManagerService.resetBackupState(mStateDir);
return BackupState.FINAL;
}
if (skipPm) {
- Slog.d(TAG, "Skipping backup of PM metadata");
+ mReporter.onSkipPm();
return BackupState.RUNNING_QUEUE;
}
@@ -498,38 +471,27 @@
private BackupState backupPm() {
RemoteResult agentResult = null;
- BackupState nextState;
try {
- // The package manager doesn't have a proper <application> etc, but since it's running
- // here in the system process we can just set up its agent directly and use a synthetic
- // BackupRequest.
+ // Since PM is running in the system process we can set up its agent directly.
BackupAgent pmAgent = mBackupManagerService.makeMetadataAgent();
Pair<Integer, RemoteResult> statusAndResult =
- invokeAgentForBackup(
+ extractAgentData(
PACKAGE_MANAGER_SENTINEL,
IBackupAgent.Stub.asInterface(pmAgent.onBind()));
mStatus = statusAndResult.first;
agentResult = statusAndResult.second;
-
- mBackupManagerService.addBackupTrace("PM agent invoke: " + mStatus);
} catch (Exception e) {
- Slog.e(TAG, "Error during PM metadata backup", e);
- mBackupManagerService.addBackupTrace("Exception in backup thread during pm: " + e);
+ mReporter.onInvokePmAgentError(e);
mStatus = BackupTransport.TRANSPORT_ERROR;
}
- mBackupManagerService.addBackupTrace("exiting backupPm: " + mStatus);
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- Preconditions.checkNotNull(agentResult);
- nextState = processAgentInvocation(agentResult);
- } else {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
- nextState = BackupState.FINAL;
+ if (mStatus != BackupTransport.TRANSPORT_OK) {
+ mBackupManagerService.resetBackupState(mStateDir);
+ return BackupState.FINAL;
}
- return nextState;
+ Preconditions.checkNotNull(agentResult);
+ return handleAgentResult(agentResult);
}
/**
@@ -540,248 +502,183 @@
* <li>({@code null}, agent result): In case we successfully called the agent.
* </ul>
*/
- private Pair<BackupState, RemoteResult> invokeNextAgent() {
+ private Pair<BackupState, RemoteResult> extractNextAgentData() {
mStatus = BackupTransport.TRANSPORT_OK;
- mBackupManagerService.addBackupTrace("invoke q=" + mQueue.size());
- // Sanity check that we have work to do. If not, skip to the end where
- // we reestablish the wakelock invariants etc.
if (mQueue.isEmpty()) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Queue now empty");
- }
+ mReporter.onEmptyQueue();
return Pair.create(BackupState.FINAL, null);
}
- // pop the entry we're going to process on this step
BackupRequest request = mQueue.remove(0);
+ String packageName = request.packageName;
+ mReporter.onStartPackageBackup(packageName);
- Slog.d(TAG, "Starting key-value backup of " + request);
- mBackupManagerService.addBackupTrace("launch agent for " + request.packageName);
-
- // Verify that the requested app exists; it might be something that
- // requested a backup but was then uninstalled. The request was
- // journalled and rather than tamper with the journal it's safer
- // to sanity-check here. This also gives us the classname of the
- // package's backup agent.
+ // Verify that the requested app is eligible for key-value backup.
RemoteResult agentResult = null;
try {
- PackageManager pm = mBackupManagerService.getPackageManager();
- mCurrentPackage = pm.getPackageInfo(request.packageName,
- PackageManager.GET_SIGNING_CERTIFICATES);
- if (!AppBackupUtils.appIsEligibleForBackup(mCurrentPackage.applicationInfo, pm)) {
- // The manifest has changed but we had a stale backup request pending. This won't
- // happen again because the app won't be requesting further backups.
- Slog.i(TAG, "Package " + request.packageName
- + " no longer supports backup, skipping");
- mBackupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
- // Shouldn't happen in case of requested backup, as pre-check was done in
- // #requestBackup(), except to app update done concurrently
- BackupObserverUtils.sendBackupOnPackageResult(mObserver,
- mCurrentPackage.packageName,
- BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ mCurrentPackage = mPackageManager.getPackageInfo(
+ request.packageName, PackageManager.GET_SIGNING_CERTIFICATES);
+ ApplicationInfo applicationInfo = mCurrentPackage.applicationInfo;
+ if (!AppBackupUtils.appIsEligibleForBackup(applicationInfo, mPackageManager)) {
+ // The manifest has changed. This won't happen again because the app won't be
+ // requesting further backups.
+ mReporter.onPackageNotEligibleForBackup(packageName);
return Pair.create(BackupState.RUNNING_QUEUE, null);
}
if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
- // It's possible that this app *formerly* was enqueued for key-value backup, but has
- // since been updated and now only supports the full-backup path. Don't proceed with
- // a key-value backup for it in this case.
- Slog.i(TAG, "Package " + request.packageName
- + " performs full-backup rather than key-value, skipping");
- mBackupManagerService.addBackupTrace(
- "skipping - fullBackupOnly, completion is noop");
- // Shouldn't happen in case of requested backup, as pre-check was done in
- // #requestBackup()
- BackupObserverUtils.sendBackupOnPackageResult(mObserver,
- mCurrentPackage.packageName,
- BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ // Initially enqueued for key-value backup, but only supports full-backup now.
+ mReporter.onPackageEligibleForFullBackup(packageName);
return Pair.create(BackupState.RUNNING_QUEUE, null);
}
- if (AppBackupUtils.appIsStopped(mCurrentPackage.applicationInfo)) {
- // The app has been force-stopped or cleared or just installed,
- // and not yet launched out of that state, so just as it won't
- // receive broadcasts, we won't run it for backup.
- mBackupManagerService.addBackupTrace("skipping - stopped");
- BackupObserverUtils.sendBackupOnPackageResult(mObserver,
- mCurrentPackage.packageName,
- BackupManager.ERROR_BACKUP_NOT_ALLOWED);
+ if (AppBackupUtils.appIsStopped(applicationInfo)) {
+ // Just as it won't receive broadcasts, we won't run it for backup.
+ mReporter.onPackageStopped(packageName);
return Pair.create(BackupState.RUNNING_QUEUE, null);
}
try {
- mBackupManagerService.setWorkSource(
- new WorkSource(mCurrentPackage.applicationInfo.uid));
+ mBackupManagerService.setWorkSource(new WorkSource(applicationInfo.uid));
IBackupAgent agent =
mBackupManagerService.bindToAgentSynchronous(
- mCurrentPackage.applicationInfo,
+ applicationInfo,
ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
- mBackupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
if (agent != null) {
mAgentBinder = agent;
Pair<Integer, RemoteResult> statusAndResult =
- invokeAgentForBackup(request.packageName, agent);
+ extractAgentData(request.packageName, agent);
mStatus = statusAndResult.first;
agentResult = statusAndResult.second;
} else {
- // Timeout waiting for the agent
+ // Timeout waiting for the agent to bind.
mStatus = BackupTransport.AGENT_ERROR;
}
- } catch (SecurityException se) {
- // Try for the next one.
- Slog.d(TAG, "Error in bind/backup", se);
+ } catch (SecurityException e) {
+ mReporter.onBindAgentError(e);
mStatus = BackupTransport.AGENT_ERROR;
- mBackupManagerService.addBackupTrace("agent SE");
}
} catch (PackageManager.NameNotFoundException e) {
- Slog.d(TAG, "Package does not exist, skipping");
- mBackupManagerService.addBackupTrace("no such package");
mStatus = BackupTransport.AGENT_UNKNOWN;
} finally {
mBackupManagerService.setWorkSource(null);
}
if (mStatus != BackupTransport.TRANSPORT_OK) {
- BackupState nextState = BackupState.RUNNING_QUEUE;
mAgentBinder = null;
- // An agent-level failure means we re-enqueue this one agent for
- // a later retry, but otherwise proceed normally.
if (mStatus == BackupTransport.AGENT_ERROR) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + request.packageName + ", re-staging");
- }
+ mReporter.onAgentError(packageName);
mBackupManagerService.dataChangedImpl(request.packageName);
mStatus = BackupTransport.TRANSPORT_OK;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
- BackupManager.ERROR_AGENT_FAILURE);
- } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
- // Failed lookup of the app, so we couldn't bring up an agent, but
- // we're otherwise fine. Just drop it and go on to the next as usual.
- mStatus = BackupTransport.TRANSPORT_OK;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, request.packageName,
- BackupManager.ERROR_PACKAGE_NOT_FOUND);
- } else {
- // Transport-level failure means we re-enqueue everything
- revertAndEndBackup();
- nextState = BackupState.FINAL;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
- return Pair.create(nextState, null);
+ if (mStatus == BackupTransport.AGENT_UNKNOWN) {
+ mReporter.onAgentUnknown(packageName);
+ mStatus = BackupTransport.TRANSPORT_OK;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
+ }
+
+ // Transport-level failure, re-enqueue everything.
+ revertBackup();
+ return Pair.create(BackupState.FINAL, null);
}
// Success: caller will figure out the state based on call result
- mBackupManagerService.addBackupTrace("call made; result = " + agentResult);
return Pair.create(null, agentResult);
}
- private void finalizeBackup() {
- mBackupManagerService.addBackupTrace("finishing");
-
- // Mark packages that we didn't backup (because backup was cancelled, etc.) as needing
- // backup.
- for (BackupRequest req : mQueue) {
- mBackupManagerService.dataChangedImpl(req.packageName);
+ private void finishBackup() {
+ // Mark packages that we couldn't backup as pending backup.
+ for (BackupRequest request : mQueue) {
+ mBackupManagerService.dataChangedImpl(request.packageName);
}
- // Either backup was successful, in which case we of course do not need
- // this pass's journal any more; or it failed, in which case we just
- // re-enqueued all of these packages in the current active journal.
- // Either way, we no longer need this pass's journal.
+ // If backup succeeded, we just invalidated this journal. If not, we've already re-enqueued
+ // the packages and also don't need the journal.
if (mJournal != null && !mJournal.delete()) {
- Slog.e(TAG, "Unable to remove backup journal file " + mJournal);
+ mReporter.onJournalDeleteFailed(mJournal);
}
- // If everything actually went through and this is the first time we've
- // done a backup, we can now record what the current backup dataset token
- // is.
- String callerLogString = "KVBT.finalizeBackup()";
- if ((mBackupManagerService.getCurrentToken() == 0) && (mStatus
- == BackupTransport.TRANSPORT_OK)) {
- mBackupManagerService.addBackupTrace("success; recording token");
+ String callerLogString = "KVBT.finishBackup()";
+
+ // If we succeeded and this is the first time we've done a backup, we can record the current
+ // backup dataset token.
+ long currentToken = mBackupManagerService.getCurrentToken();
+ if ((mStatus == BackupTransport.TRANSPORT_OK) && (currentToken == 0)) {
try {
IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString);
mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
mBackupManagerService.writeRestoreTokens();
} catch (Exception e) {
- // nothing for it at this point, unfortunately, but this will be
- // recorded the next time we fully succeed.
- Slog.e(TAG, "Transport threw reporting restore set: " + e);
- mBackupManagerService.addBackupTrace("transport threw returning token");
+ // This will be recorded the next time we succeed.
+ mReporter.onSetCurrentTokenError(e);
}
}
- // Set up the next backup pass - at this point we can set mBackupRunning
- // to false to allow another pass to fire
synchronized (mBackupManagerService.getQueueLock()) {
mBackupManagerService.setBackupRunning(false);
if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
- if (MORE_DEBUG) {
- Slog.d(TAG, "Transport requires initialization, rerunning");
- }
- mBackupManagerService.addBackupTrace("init required; rerunning");
+ mReporter.onTransportNotInitialized();
try {
- String name = mBackupManagerService.getTransportManager()
- .getTransportName(mTransportClient.getTransportComponent());
- mBackupManagerService.getPendingInits().add(name);
+ IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString);
+ mBackupManagerService.getPendingInits().add(transport.name());
+ clearPmMetadata();
+ mBackupManagerService.backupNow();
} catch (Exception e) {
- Slog.w(TAG, "Failed to query transport name for init: " + e);
- // swallow it and proceed; we don't rely on this
+ mReporter.onPendingInitializeTransportError(e);
}
- clearMetadata();
- mBackupManagerService.backupNow();
}
}
- mBackupManagerService.clearBackupTrace();
-
unregisterTask();
+ mReporter.onKeyValueBackupFinished();
- if (!mCancelled && mStatus == BackupTransport.TRANSPORT_OK &&
- mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
- Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
- // Acquiring wakelock for PerformFullTransportBackupTask before its start.
- mBackupManagerService.getWakelock().acquire();
- // The full-backup task is now responsible for calling onFinish() on mListener, which
- // was the listener we passed it.
+ if (!mCancelled
+ && mStatus == BackupTransport.TRANSPORT_OK
+ && mFullBackupTask != null
+ && !mPendingFullBackups.isEmpty()) {
+ mReporter.onStartFullBackup(mPendingFullBackups);
+ // The key-value backup has finished but not the overall backup. Full-backup task will:
+ // * Call mObserver.backupFinished() (which is called by mReporter below).
+ // * Call mTaskFinishedListener.onFinished().
+ // * Release the wakelock.
(new Thread(mFullBackupTask, "full-transport-requested")).start();
- } else if (mCancelled) {
- mListener.onFinished(callerLogString);
- if (mFullBackupTask != null) {
- mFullBackupTask.unregisterTask();
- }
- BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.ERROR_BACKUP_CANCELLED);
- } else {
- mListener.onFinished(callerLogString);
- mFullBackupTask.unregisterTask();
- switch (mStatus) {
- case BackupTransport.TRANSPORT_OK:
- case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
- case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
- BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
- break;
- case BackupTransport.TRANSPORT_NOT_INITIALIZED:
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- break;
- case BackupTransport.TRANSPORT_ERROR:
- default:
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- break;
- }
+ return;
}
- Slog.i(TAG, "K/V backup pass finished");
+
+ if (mFullBackupTask != null) {
+ mFullBackupTask.unregisterTask();
+ }
+ mTaskFinishedListener.onFinished(callerLogString);
+ mReporter.onBackupFinished(getBackupFinishedStatus(mCancelled, mStatus));
mBackupManagerService.getWakelock().release();
}
- // Remove the PM metadata state. This will generate an init on the next pass.
- private void clearMetadata() {
- final File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
- if (pmState.exists()) pmState.delete();
+ private int getBackupFinishedStatus(boolean cancelled, int transportStatus) {
+ if (cancelled) {
+ return BackupManager.ERROR_BACKUP_CANCELLED;
+ }
+ switch (transportStatus) {
+ case BackupTransport.TRANSPORT_OK:
+ case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
+ case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
+ return BackupManager.SUCCESS;
+ case BackupTransport.TRANSPORT_NOT_INITIALIZED:
+ case BackupTransport.TRANSPORT_ERROR:
+ default:
+ return BackupManager.ERROR_TRANSPORT_ABORTED;
+ }
+ }
+
+ /** Removes PM state, triggering initialization in the next key-value task. */
+ private void clearPmMetadata() {
+ File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
+ if (pmState.exists()) {
+ pmState.delete();
+ }
}
/**
@@ -789,22 +686,16 @@
* {@link BackupTransport#TRANSPORT_OK}, the second of the pair contains the agent result,
* otherwise {@code null}.
*/
- private Pair<Integer, RemoteResult> invokeAgentForBackup(
- String packageName, IBackupAgent agent) {
- if (DEBUG) {
- Slog.d(TAG, "Invoking agent on " + packageName);
- }
- mBackupManagerService.addBackupTrace("invoking " + packageName);
+ private Pair<Integer, RemoteResult> extractAgentData(String packageName, IBackupAgent agent) {
+ mReporter.onInvokeAgent(packageName);
File blankStateFile = new File(mStateDir, BLANK_STATE_FILE_NAME);
mSavedStateFile = new File(mStateDir, packageName);
+ File savedStateFileForAgent = (mNonIncremental) ? blankStateFile : mSavedStateFile;
mBackupDataFile =
new File(mBackupManagerService.getDataDir(), packageName + STAGING_FILE_SUFFIX);
mNewStateFile = new File(mStateDir, packageName + NEW_STATE_FILE_SUFFIX);
- if (MORE_DEBUG) {
- Slog.d(TAG, "Data file: " + mBackupDataFile);
- }
-
+ mReporter.onAgentFilesReady(mBackupDataFile);
mSavedState = null;
mBackupData = null;
@@ -813,46 +704,31 @@
boolean callingAgent = false;
final RemoteResult agentResult;
try {
- // Look up the package info & signatures. This is first so that if it
- // throws an exception, there's no file setup yet that would need to
- // be unraveled.
+ // TODO: Move this to backupPm()
if (packageName.equals(PACKAGE_MANAGER_SENTINEL)) {
- // The metadata 'package' is synthetic; construct one and make
- // sure our global state is pointed at it
mCurrentPackage = new PackageInfo();
mCurrentPackage.packageName = packageName;
}
+ // MODE_CREATE to make an empty file if necessary
mSavedState = ParcelFileDescriptor.open(
- (mNonIncremental) ? blankStateFile : mSavedStateFile,
- ParcelFileDescriptor.MODE_READ_ONLY |
- ParcelFileDescriptor.MODE_CREATE); // Make an empty file if necessary
-
- mBackupData = ParcelFileDescriptor.open(mBackupDataFile,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE |
- ParcelFileDescriptor.MODE_TRUNCATE);
+ savedStateFileForAgent, MODE_READ_ONLY | MODE_CREATE);
+ mBackupData = ParcelFileDescriptor.open(
+ mBackupDataFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
+ mNewState = ParcelFileDescriptor.open(
+ mNewStateFile, MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
if (!SELinux.restorecon(mBackupDataFile)) {
- Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataFile);
+ mReporter.onRestoreconFailed(mBackupDataFile);
}
- mNewState = ParcelFileDescriptor.open(mNewStateFile,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE |
- ParcelFileDescriptor.MODE_TRUNCATE);
-
- IBackupTransport transport =
- mTransportClient.connectOrThrow("KVBT.invokeAgentForBackup()");
-
- final long quota = transport.getBackupQuota(packageName, false /* isFullBackup */);
- callingAgent = true;
-
- // Initiate the target's backup pass
+ IBackupTransport transport = mTransportClient.connectOrThrow("KVBT.extractAgentData()");
+ long quota = transport.getBackupQuota(packageName, /* isFullBackup */ false);
+ int transportFlags = transport.getTransportFlags();
long kvBackupAgentTimeoutMillis =
mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
- mBackupManagerService.addBackupTrace("calling agent doBackup()");
+ callingAgent = true;
agentResult =
remoteCall(
callback ->
@@ -862,22 +738,19 @@
mNewState,
quota,
callback,
- transport.getTransportFlags()),
+ transportFlags),
kvBackupAgentTimeoutMillis);
} catch (Exception e) {
- Slog.e(TAG, "Error invoking agent on " + packageName + ": " + e);
- mBackupManagerService.addBackupTrace("exception: " + e);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName, e.toString());
+ mReporter.onCallAgentDoBackupError(packageName, callingAgent, e);
errorCleanup();
+ // TODO: Remove the check on callingAgent when RemoteCall supports local agent calls.
int status =
callingAgent ? BackupTransport.AGENT_ERROR : BackupTransport.TRANSPORT_ERROR;
return Pair.create(status, null);
- } finally {
- if (mNonIncremental) {
- blankStateFile.delete();
- }
}
-
+ if (mNonIncremental) {
+ blankStateFile.delete();
+ }
return Pair.create(BackupTransport.TRANSPORT_OK, agentResult);
}
@@ -885,7 +758,7 @@
try {
agent.fail(message);
} catch (Exception e) {
- Slog.w(TAG, "Error conveying failure to " + mCurrentPackage.packageName);
+ mReporter.onFailAgentError(mCurrentPackage.packageName);
}
}
@@ -896,36 +769,27 @@
MessageDigest md = MessageDigest.getInstance("SHA-1");
checksum = md.digest(input);
} catch (NoSuchAlgorithmException e) {
- Slog.e(TAG, "Unable to use SHA-1!");
+ mReporter.onDigestError(e);
return "00";
}
- StringBuffer sb = new StringBuffer(checksum.length * 2);
+ StringBuilder string = new StringBuilder(checksum.length * 2);
for (byte item : checksum) {
- sb.append(Integer.toHexString(item));
+ string.append(Integer.toHexString(item));
}
- return sb.toString();
+ return string.toString();
}
private void writeWidgetPayloadIfAppropriate(FileDescriptor fd, String pkgName)
throws IOException {
// TODO: http://b/22388012
byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName, UserHandle.USER_SYSTEM);
- // has the widget state changed since last time?
- final File widgetFile = new File(mStateDir, pkgName + "_widget");
- final boolean priorStateExists = widgetFile.exists();
-
- if (MORE_DEBUG) {
- if (priorStateExists || widgetState != null) {
- Slog.i(TAG, "Checking widget update: state=" + (widgetState != null)
- + " prior=" + priorStateExists);
- }
- }
-
+ File widgetFile = new File(mStateDir, pkgName + "_widget");
+ boolean priorStateExists = widgetFile.exists();
if (!priorStateExists && widgetState == null) {
- // no prior state, no new state => nothing to do
return;
}
+ mReporter.onWriteWidgetData(priorStateExists, widgetState);
// if the new state is not null, we might need to compare checksums to
// determine whether to update the widget blob in the archive. If the
@@ -967,93 +831,67 @@
}
}
- private BackupState handleAgentResult(long unusedResult) {
+ private BackupState sendDataToTransport(long agentResult) {
Preconditions.checkState(mBackupData != null);
- final String pkgName = mCurrentPackage.packageName;
- final long filepos = mBackupDataFile.length();
+ String packageName = mCurrentPackage.packageName;
+ ApplicationInfo applicationInfo = mCurrentPackage.applicationInfo;
+ long filePos = mBackupDataFile.length();
FileDescriptor fd = mBackupData.getFileDescriptor();
+ boolean writingWidgetData = false;
try {
- // If it's a 3rd party app, see whether they wrote any protected keys
- // and complain mightily if they are attempting shenanigans.
- if (mCurrentPackage.applicationInfo != null &&
- (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- == 0) {
- ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataFile,
- ParcelFileDescriptor.MODE_READ_ONLY);
+ // If it's a 3rd party app, crash them if they wrote any protected keys.
+ if (applicationInfo != null &&
+ (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ ParcelFileDescriptor readFd =
+ ParcelFileDescriptor.open(mBackupDataFile, MODE_READ_ONLY);
BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
try {
while (in.readNextHeader()) {
- final String key = in.getKey();
+ String key = in.getKey();
if (key != null && key.charAt(0) >= 0xff00) {
- // Not okay: crash them and bail.
+ mReporter.onAgentIllegalKey(mCurrentPackage, key);
failAgent(mAgentBinder, "Illegal backup key: " + key);
- mBackupManagerService
- .addBackupTrace("illegal key " + key + " from " + pkgName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
- "bad key");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
- mCurrentPackage,
- BackupManagerMonitor
- .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- BackupManagerMonitorUtils.putMonitoringExtra(null,
- BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
- key));
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_AGENT_FAILURE);
errorCleanup();
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + pkgName
- + " with illegal key " + key + ", dropped");
- }
-
return BackupState.RUNNING_QUEUE;
}
in.skipEntityData();
}
} finally {
- if (readFd != null) {
- readFd.close();
- }
+ readFd.close();
}
}
- // Piggyback the widget state payload, if any
- writeWidgetPayloadIfAppropriate(fd, pkgName);
+ writingWidgetData = true;
+ writeWidgetPayloadIfAppropriate(fd, packageName);
} catch (IOException e) {
- // Hard disk error; recovery/failure policy TBD. For now roll back,
- // but we may want to consider this a transport-level failure (i.e.
- // we're in such a bad state that we can't contemplate doing backup
- // operations any more during this pass).
- Slog.w(TAG, "Unable read backup data or to save widget state for " + pkgName);
+ if (writingWidgetData) {
+ mReporter.onWriteWidgetDataError(packageName, e);
+ } else {
+ mReporter.onReadAgentDataError(packageName, e);
+ }
try {
- Os.ftruncate(fd, filepos);
+ Os.ftruncate(fd, filePos);
} catch (ErrnoException ee) {
- Slog.w(TAG, "Unable to roll back");
+ mReporter.onTruncateDataError();
}
}
clearAgentState();
- mBackupManagerService.addBackupTrace("operation complete");
ParcelFileDescriptor backupData = null;
mStatus = BackupTransport.TRANSPORT_OK;
long size = 0;
try {
- IBackupTransport transport = mTransportClient.connectOrThrow("KVBT.handleAgentResult()");
+ IBackupTransport transport =
+ mTransportClient.connectOrThrow("KVBT.sendDataToTransport()");
size = mBackupDataFile.length();
if (size > 0) {
- if (MORE_DEBUG) {
- Slog.v(TAG, "Sending non-empty data to transport for " + pkgName);
- }
boolean isNonIncremental = mSavedStateFile.length() == 0;
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- backupData = ParcelFileDescriptor.open(mBackupDataFile,
- ParcelFileDescriptor.MODE_READ_ONLY);
- mBackupManagerService.addBackupTrace("sending data to transport");
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ mReporter.onSendDataToTransport(packageName);
+ backupData = ParcelFileDescriptor.open(mBackupDataFile, MODE_READ_ONLY);
int userInitiatedFlag =
mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
int incrementalFlag =
@@ -1067,114 +905,58 @@
if (isNonIncremental
&& mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was
- // incremental, as if the backup is non-incremental there is no state to
- // clear. This avoids us ending up in a retry loop if the transport always
- // returns this code.
- Slog.e(TAG, "Transport requested non-incremental but already the case");
- mBackupManagerService.addBackupTrace(
- "Transport requested non-incremental but already the case, error");
+ mReporter.onNonIncrementalAndNonIncrementalRequired();
mStatus = BackupTransport.TRANSPORT_ERROR;
}
- mBackupManagerService.addBackupTrace("data delivered: " + mStatus);
if (mStatus == BackupTransport.TRANSPORT_OK) {
- mBackupManagerService.addBackupTrace("finishing op on transport");
mStatus = transport.finishBackup();
- mBackupManagerService.addBackupTrace("finished: " + mStatus);
- } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- mBackupManagerService.addBackupTrace("transport rejected package");
}
} else {
- if (MORE_DEBUG) {
- Slog.i(TAG, "No backup data written, not calling transport");
- }
- mBackupManagerService.addBackupTrace("no data to send");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- null);
+ mReporter.onEmptyData(mCurrentPackage);
}
if (mStatus == BackupTransport.TRANSPORT_OK) {
- // After successful transport, delete the now-stale data
- // and juggle the files so that next time we supply the agent
- // with the new state file it just created.
mBackupDataFile.delete();
mNewStateFile.renameTo(mSavedStateFile);
- BackupObserverUtils.sendBackupOnPackageResult(
- mObserver, pkgName, BackupManager.SUCCESS);
- EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
- mBackupManagerService.logBackupComplete(pkgName);
+ mReporter.onPackageBackupComplete(packageName, size);
} else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // The transport has rejected backup of this specific package. Roll it
- // back but proceed with running the rest of the queue.
mBackupDataFile.delete();
mNewStateFile.delete();
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
- EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+ mReporter.onPackageBackupRejected(packageName);
} else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
- EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
-
+ // TODO: Should reset files like above?
+ mReporter.onPackageBackupQuotaExceeded(packageName);
} else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- Slog.i(TAG, "Transport lost data, retrying package");
- mBackupManagerService.addBackupTrace(
- "Transport lost data, retrying package:" + pkgName);
- BackupManagerMonitorUtils.monitorEvent(
- mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
- /*extras=*/ null);
-
+ mReporter.onPackageBackupNonIncrementalRequired(mCurrentPackage);
mBackupDataFile.delete();
mSavedStateFile.delete();
mNewStateFile.delete();
// Immediately retry the package by adding it back to the front of the queue.
// We cannot add @pm@ to the queue because we back it up separately at the start
- // of the backup pass in state BACKUP_PM. Instead we retry this state (see
- // below).
- if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
- mQueue.add(0, new BackupRequest(pkgName));
+ // of the backup pass in state BACKUP_PM. See below.
+ if (!PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
+ mQueue.add(0, new BackupRequest(packageName));
}
-
} else {
- // Actual transport-level failure to communicate the data to the backend
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mReporter.onPackageBackupTransportFailure(packageName);
}
} catch (Exception e) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- Slog.e(TAG, "Transport error backing up " + pkgName, e);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mReporter.onPackageBackupError(packageName, e);
mStatus = BackupTransport.TRANSPORT_ERROR;
} finally {
- try {
- if (backupData != null) {
- backupData.close();
- }
- } catch (IOException e) {
- Slog.w(TAG, "Error closing backup data file-descriptor");
- }
+ tryCloseFileDescriptor(backupData, "backup data");
}
final BackupState nextState;
if (mStatus == BackupTransport.TRANSPORT_OK
|| mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // Success or single-package rejection. Proceed with the next app if any,
- // otherwise we're done.
nextState = BackupState.RUNNING_QUEUE;
} else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
// We want to immediately retry the current package.
- if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
+ if (PACKAGE_MANAGER_SENTINEL.equals(packageName)) {
nextState = BackupState.BACKUP_PM;
} else {
// This is an ordinary package so we will have added it back into the queue
@@ -1183,25 +965,21 @@
}
} else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- if (MORE_DEBUG) {
- Slog.d(TAG, "Package " + mCurrentPackage.packageName +
- " hit quota limit on key-value backup");
- }
if (mAgentBinder != null) {
try {
IBackupTransport transport =
- mTransportClient.connectOrThrow("KVBT.handleAgentResult()");
+ mTransportClient.connectOrThrow("KVBT.sendDataToTransport()");
long quota = transport.getBackupQuota(mCurrentPackage.packageName, false);
mAgentBinder.doQuotaExceeded(size, quota);
} catch (Exception e) {
- Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
+ mReporter.onAgentDoQuotaExceededError(e);
}
}
nextState = BackupState.RUNNING_QUEUE;
} else {
// Any other error here indicates a transport-level failure. That means
// we need to halt everything and reschedule everything for next time.
- revertAndEndBackup();
+ revertBackup();
nextState = BackupState.FINAL;
}
@@ -1221,10 +999,9 @@
*/
@Override
public void handleCancel(boolean cancelAll) {
+ // This is called in a thread different from the one that executes method run().
Preconditions.checkArgument(cancelAll, "Can't partially cancel a key-value backup task");
- if (MORE_DEBUG) {
- Slog.v(TAG, "Cancel received");
- }
+ mReporter.onCancel();
mCancelled = true;
RemoteCall pendingCall = mPendingCall;
if (pendingCall != null) {
@@ -1234,66 +1011,35 @@
}
private void handleAgentTimeout() {
- String packageName = getPackageNameForLog();
- Slog.i(TAG, "Agent " + packageName + " timed out");
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
- mBackupManagerService.addBackupTrace("timeout of " + packageName);
- mMonitor =
- BackupManagerMonitorUtils.monitorEvent(
- mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
- BackupManagerMonitorUtils.putMonitoringExtra(
- null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, false));
+ mReporter.onAgentTimedOut(mCurrentPackage);
errorCleanup();
}
private void handleAgentCancelled() {
- String packageName = getPackageNameForLog();
- Slog.i(TAG, "Cancel backing up " + packageName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
- mBackupManagerService.addBackupTrace("cancel of " + packageName);
+ mReporter.onAgentCancelled(mCurrentPackage);
errorCleanup();
}
- private void finalizeCancelledBackup() {
- mMonitor =
- BackupManagerMonitorUtils.monitorEvent(
- mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
- BackupManagerMonitorUtils.putMonitoringExtra(
- null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, true));
- finalizeBackup();
+ private void finishCancelledBackup() {
+ finishBackup();
// finalizeBackup() may call the transport, so we only acknowledge the cancellation here.
mCancelAcknowledged.open();
}
- private String getPackageNameForLog() {
- return (mCurrentPackage != null) ? mCurrentPackage.packageName : "no_package_yet";
- }
-
- private void revertAndEndBackup() {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Reverting backup queue, re-staging everything");
- }
- mBackupManagerService.addBackupTrace("transport error; reverting");
-
- // We want to reset the backup schedule based on whatever the transport suggests
- // by way of retry/backoff time.
+ private void revertBackup() {
+ mReporter.onRevertBackup();
long delay;
try {
IBackupTransport transport =
- mTransportClient.connectOrThrow("KVBT.revertAndEndBackup()");
+ mTransportClient.connectOrThrow("KVBT.revertBackup()");
delay = transport.requestBackupTime();
} catch (Exception e) {
- Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e);
- delay = 0; // use the scheduler's default
+ mReporter.onTransportRequestBackupTimeError(e);
+ // Use the scheduler's default.
+ delay = 0;
}
- KeyValueBackupJob.schedule(mBackupManagerService.getContext(), delay,
- mBackupManagerService.getConstants());
+ KeyValueBackupJob.schedule(
+ mBackupManagerService.getContext(), delay, mBackupManagerService.getConstants());
for (BackupRequest request : mOriginalQueue) {
mBackupManagerService.dataChangedImpl(request.packageName);
@@ -1306,50 +1052,37 @@
clearAgentState();
}
- // Cleanup common to both success and failure cases
private void clearAgentState() {
- try {
- if (mSavedState != null) {
- mSavedState.close();
- }
- } catch (IOException e) {
- Slog.w(TAG, "Error closing old state file-descriptor");
- }
- try {
- if (mBackupData != null) {
- mBackupData.close();
- }
- } catch (IOException e) {
- Slog.w(TAG, "Error closing backup data file-descriptor");
- }
- try {
- if (mNewState != null) {
- mNewState.close();
- }
- } catch (IOException e) {
- Slog.w(TAG, "Error closing new state file-descriptor");
- }
+ // Cleanup common to both success and failure cases.
+ tryCloseFileDescriptor(mSavedState, "old state");
+ tryCloseFileDescriptor(mBackupData, "backup data");
+ tryCloseFileDescriptor(mNewState, "new state");
synchronized (mBackupManagerService.getCurrentOpLock()) {
- // Current-operation callback handling requires the validity of these various
- // bits of internal state as an invariant of the operation still being live.
- // This means we make sure to clear all of the state in unison inside the lock.
+ // TODO: Do we still need this?
mSavedState = mBackupData = mNewState = null;
}
- // If this was a pseudo-package there's no associated Activity Manager state
+ // For PM metadata (for which applicationInfo is null) there is no agent-bound state.
if (mCurrentPackage.applicationInfo != null) {
- mBackupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
mBackupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
}
}
+ private void tryCloseFileDescriptor(@Nullable Closeable closeable, String logName) {
+ if (closeable != null) {
+ try {
+ closeable.close();
+ } catch (IOException e) {
+ mReporter.onCloseFileDescriptorError(logName);
+ }
+ }
+ }
+
private RemoteResult remoteCall(RemoteCallable<IBackupCallback> remoteCallable, long timeoutMs)
throws RemoteException {
mPendingCall = new RemoteCall(mCancelled, remoteCallable, timeoutMs);
RemoteResult result = mPendingCall.call();
- if (MORE_DEBUG) {
- Slog.v(TAG, "Agent call returned " + result);
- }
+ mReporter.onRemoteCallReturned(result);
mPendingCall = null;
return result;
}
diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
index 28e9b77..9af952d 100644
--- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java
@@ -136,7 +136,14 @@
/**
* Checks if the app is in a stopped state. This is not part of the general "eligible for
* backup?" check because we *do* still need to restore data to apps in this state (e.g.
- * newly-installing ones)
+ * newly-installing ones).
+ *
+ * <p>Reasons for such state:
+ * <ul>
+ * <li>The app has been force-stopped.
+ * <li>The app has been cleared.
+ * <li>The app has just been installed.
+ * </ul>
*/
public static boolean appIsStopped(ApplicationInfo app) {
return ((app.flags & ApplicationInfo.FLAG_STOPPED) != 0);
diff --git a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
index b23781d..6f08376 100644
--- a/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
+++ b/services/backup/java/com/android/server/backup/utils/BackupManagerMonitorUtils.java
@@ -21,6 +21,7 @@
import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;
+import android.annotation.Nullable;
import android.app.backup.BackupManagerMonitor;
import android.app.backup.IBackupManagerMonitor;
import android.content.pm.PackageInfo;
@@ -44,8 +45,13 @@
* @param extras - additional event data.
* @return <code>monitor</code> if call succeeded and <code>null</code> otherwise.
*/
- public static IBackupManagerMonitor monitorEvent(IBackupManagerMonitor monitor, int id,
- PackageInfo pkg, int category, Bundle extras) {
+ @Nullable
+ public static IBackupManagerMonitor monitorEvent(
+ @Nullable IBackupManagerMonitor monitor,
+ int id,
+ PackageInfo pkg,
+ int category,
+ Bundle extras) {
if (monitor != null) {
try {
Bundle bundle = new Bundle();
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 5c14459..50f15ca0 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -624,7 +624,7 @@
// them will get the new sequence number at that point. (See for example how testing
// of JobScheduler's BatteryController works.)
sendBatteryChangedIntentLocked();
- if (mLastBatteryLevel != mHealthInfo.batteryLevel) {
+ if (mLastBatteryLevel != mHealthInfo.batteryLevel || mLastPlugType != mPlugType) {
sendBatteryLevelChangedIntentLocked();
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6b3f8f8..914404b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2194,8 +2194,7 @@
break;
}
case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
- Integer score = (Integer) msg.obj;
- if (score != null) updateNetworkScore(nai, score.intValue());
+ updateNetworkScore(nai, msg.arg1);
break;
}
case NetworkAgent.EVENT_SET_EXPLICITLY_SELECTED: {
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index a05a3e7..0deaee7 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -43,6 +43,7 @@
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.Settings;
import android.system.ErrnoException;
@@ -104,6 +105,7 @@
private final Context mContext;
private final ActivityManagerInternal mAmInternal;
private final IActivityManager mAm;
+ private final UserManager mUserManager;
/** The list of the statically pinned files. */
@GuardedBy("this")
@@ -165,6 +167,8 @@
mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
mAm = ActivityManager.getService();
+ mUserManager = mContext.getSystemService(UserManager.class);
+
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
filter.addDataScheme("package");
@@ -195,12 +199,16 @@
*/
@Override
public void onSwitchUser(int userHandle) {
- sendPinAppsMessage(userHandle);
+ if (!mUserManager.isManagedProfile(userHandle)) {
+ sendPinAppsMessage(userHandle);
+ }
}
@Override
public void onUnlockUser(int userHandle) {
- sendPinAppsMessage(userHandle);
+ if (!mUserManager.isManagedProfile(userHandle)) {
+ sendPinAppsMessage(userHandle);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 6550d06..9bf72fb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -207,6 +207,10 @@
// Indicates if the processes need to be started asynchronously.
public boolean FLAG_PROCESS_START_ASYNC = DEFAULT_PROCESS_START_ASYNC;
+ // Indicates whether the activity starts logging is enabled.
+ // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
+ boolean mFlagActivityStartsLoggingEnabled;
+
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -235,6 +239,12 @@
// memory trimming.
public int CUR_TRIM_CACHED_PROCESSES;
+ private static final Uri ACTIVITY_MANAGER_CONSTANTS_URI = Settings.Global.getUriFor(
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS);
+
+ private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor(
+ Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED);
+
public ActivityManagerConstants(ActivityManagerService service, Handler handler) {
super(handler);
mService = service;
@@ -243,9 +253,10 @@
public void start(ContentResolver resolver) {
mResolver = resolver;
- mResolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.ACTIVITY_MANAGER_CONSTANTS), false, this);
+ mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
+ mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
updateConstants();
+ updateActivityStartsLoggingEnabled();
}
public void setOverrideMaxCachedProcesses(int value) {
@@ -263,7 +274,12 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- updateConstants();
+ if (uri == null) return;
+ if (ACTIVITY_MANAGER_CONSTANTS_URI.equals(uri)) {
+ updateConstants();
+ } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
+ updateActivityStartsLoggingEnabled();
+ }
}
private void updateConstants() {
@@ -337,6 +353,11 @@
}
}
+ private void updateActivityStartsLoggingEnabled() {
+ mFlagActivityStartsLoggingEnabled = Settings.Global.getInt(mResolver,
+ Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 0) == 1;
+ }
+
private void updateMaxCachedProcesses() {
CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
? MAX_CACHED_PROCESSES : mOverrideMaxCachedProcesses;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 65f3154..1d01a572 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7214,6 +7214,20 @@
|| mPendingTempWhitelist.indexOfKey(uid) >= 0;
}
+ /**
+ * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
+ * the whitelist
+ */
+ String getPendingTempWhitelistTagForUidLocked(int uid) {
+ final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
+ return ptw != null ? ptw.tag : null;
+ }
+
+ @VisibleForTesting
+ boolean isActivityStartsLoggingEnabled() {
+ return mConstants.mFlagActivityStartsLoggingEnabled;
+ }
+
private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
ProviderInfo pi = null;
ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index d3e3af3..263c34f 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -2,6 +2,7 @@
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.processStateAmToProto;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -9,6 +10,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ACTIVITY_START;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
@@ -21,8 +23,48 @@
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_PROC_STATE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_COMING_FROM_PENDING_INTENT;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INTENT_ACTION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_CUR_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_OVERLAY_UI;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_TOP_UI;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PENDING_UI_CLEAN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PROCESS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
@@ -37,6 +79,7 @@
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.dex.ArtManagerInternal;
import android.content.pm.dex.PackageOptimizationInfo;
@@ -612,6 +655,95 @@
startupTimeMs);
}
+ void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
+ int callingUid, String callingPackage, int callingUidProcState,
+ boolean callingUidHasAnyVisibleWindow,
+ int realCallingUid, int realCallingUidProcState,
+ boolean realCallingUidHasAnyVisibleWindow,
+ int targetUid, String targetPackage, int targetUidProcState,
+ boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
+ boolean comingFromPendingIntent) {
+
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ final long nowUptime = SystemClock.uptimeMillis();
+ final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
+ builder.setTimestamp(System.currentTimeMillis());
+ builder.addTaggedData(FIELD_CALLING_UID, callingUid);
+ builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
+ builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
+ processStateAmToProto(callingUidProcState));
+ builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
+ callingUidHasAnyVisibleWindow ? 1 : 0);
+ builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
+ builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
+ processStateAmToProto(realCallingUidProcState));
+ builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
+ realCallingUidHasAnyVisibleWindow ? 1 : 0);
+ builder.addTaggedData(FIELD_TARGET_UID, targetUid);
+ builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
+ builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
+ processStateAmToProto(targetUidProcState));
+ builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
+ targetUidHasAnyVisibleWindow ? 1 : 0);
+ builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
+ builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
+ builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
+ builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
+ if (callerApp != null) {
+ builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
+ processStateAmToProto(callerApp.curProcState));
+ builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
+ callerApp.hasClientActivities ? 1 : 0);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
+ callerApp.hasForegroundServices() ? 1 : 0);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
+ callerApp.foregroundActivities ? 1 : 0);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
+ callerApp.hasOverlayUi ? 1 : 0);
+ builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
+ callerApp.pendingUiClean ? 1 : 0);
+ if (callerApp.interactionEventTime != 0) {
+ builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
+ (nowElapsed - callerApp.interactionEventTime));
+ }
+ if (callerApp.fgInteractionTime != 0) {
+ builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
+ (nowElapsed - callerApp.fgInteractionTime));
+ }
+ if (callerApp.whenUnimportant != 0) {
+ builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
+ (nowUptime - callerApp.whenUnimportant));
+ }
+ }
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
+ if (r.lastVisibleTime != 0) {
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
+ (nowUptime - r.lastVisibleTime));
+ }
+ if (r.resultTo != null) {
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
+ r.resultTo.shortComponentName);
+ }
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
+ r.visibleIgnoringKeyguard ? 1 : 0);
+ if (r.lastLaunchTime != 0) {
+ builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
+ (nowUptime - r.lastLaunchTime));
+ }
+ mMetricsLogger.write(builder);
+ }
+
private int getTransitionType(WindowingModeTransitionInfo info) {
if (info.currentTransitionProcessRunning) {
if (info.startResult == START_SUCCESS) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 27a4460..9809bfa 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -4863,7 +4863,7 @@
return mService.getActivityStartController().startActivityInPackage(
task.mCallingUid, callingPid, callingUid, callingPackage, intent, null, null,
null, 0, 0, options, userId, task, "startActivityFromRecents",
- false /* validateIncomingUser */);
+ false /* validateIncomingUser */, null /* originatingPendingIntent */);
} finally {
if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && task != null) {
// If we are launching the task in the docked stack, put it into resizing mode so
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 2cba720..6e3a79c 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -249,7 +249,8 @@
final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
- int userId, TaskRecord inTask, String reason, boolean validateIncomingUser) {
+ int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
+ PendingIntentRecord originatingPendingIntent) {
userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid,
reason);
@@ -268,6 +269,7 @@
.setActivityOptions(options)
.setMayWait(userId)
.setInTask(inTask)
+ .setOriginatingPendingIntent(originatingPendingIntent)
.execute();
}
@@ -279,10 +281,12 @@
* @param intents Intents to start.
* @param userId Start the intents on this user.
* @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
+ * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
+ * null if not originated by PendingIntent
*/
final int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
- boolean validateIncomingUser) {
+ boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
final String reason = "startActivityInPackage";
@@ -291,12 +295,12 @@
// TODO: Switch to user app stacks here.
return startActivities(null, uid, callingPackage, intents, resolvedTypes, resultTo, options,
- userId, reason);
+ userId, reason, originatingPendingIntent);
}
int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options,
- int userId, String reason) {
+ int userId, String reason, PendingIntentRecord originatingPendingIntent) {
if (intents == null) {
throw new NullPointerException("intents is null");
}
@@ -375,6 +379,7 @@
// Top activity decides on animation being run, so we allow only for the
// top one as otherwise an activity below might consume it.
.setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
+ .setOriginatingPendingIntent(originatingPendingIntent)
.execute();
if (res < 0) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 05fae83..dcf9344 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -99,6 +99,7 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.service.voice.IVoiceInteractionSession;
@@ -313,6 +314,7 @@
int userId;
WaitResult waitResult;
int filterCallingUid;
+ PendingIntentRecord originatingPendingIntent;
/**
* If set to {@code true}, allows this activity start to look into
@@ -369,6 +371,7 @@
avoidMoveToFront = false;
allowPendingRemoteAnimationRegistryLookup = true;
filterCallingUid = UserHandle.USER_NULL;
+ originatingPendingIntent = null;
}
/**
@@ -407,6 +410,7 @@
allowPendingRemoteAnimationRegistryLookup
= request.allowPendingRemoteAnimationRegistryLookup;
filterCallingUid = request.filterCallingUid;
+ originatingPendingIntent = request.originatingPendingIntent;
}
}
@@ -490,7 +494,8 @@
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
- mRequest.allowPendingRemoteAnimationRegistryLookup);
+ mRequest.allowPendingRemoteAnimationRegistryLookup,
+ mRequest.originatingPendingIntent);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
@@ -500,7 +505,8 @@
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
- mRequest.allowPendingRemoteAnimationRegistryLookup);
+ mRequest.allowPendingRemoteAnimationRegistryLookup,
+ mRequest.originatingPendingIntent);
}
} finally {
onExecutionComplete();
@@ -532,7 +538,8 @@
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason,
- boolean allowPendingRemoteAnimationRegistryLookup) {
+ boolean allowPendingRemoteAnimationRegistryLookup,
+ PendingIntentRecord originatingPendingIntent) {
if (TextUtils.isEmpty(reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
@@ -545,7 +552,7 @@
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
- inTask, allowPendingRemoteAnimationRegistryLookup);
+ inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
if (outActivity != null) {
// mLastStartActivityRecord[0] is set in the call to startActivity above.
@@ -575,7 +582,8 @@
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
- TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
+ TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
+ PendingIntentRecord originatingPendingIntent) {
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
@@ -857,10 +865,58 @@
mService.onStartActivitySetDidAppSwitch();
mController.doPendingActivityLaunches(false);
+ maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
+ originatingPendingIntent);
+
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity);
}
+ private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
+ Intent intent, ProcessRecord callerApp, ActivityRecord r,
+ PendingIntentRecord originatingPendingIntent) {
+ boolean callerAppHasForegroundActivity = (callerApp != null)
+ ? callerApp.foregroundActivities
+ : false;
+ if (!mService.mAm.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
+ || r == null) {
+ // skip logging in this case
+ return;
+ }
+
+ try {
+ Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
+ final int callingUidProcState = mService.mAm.getUidStateLocked(callingUid);
+ final boolean callingUidHasAnyVisibleWindow =
+ mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
+ final int realCallingUidProcState = (callingUid == realCallingUid)
+ ? callingUidProcState
+ : mService.mAm.getUidStateLocked(realCallingUid);
+ final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
+ ? callingUidHasAnyVisibleWindow
+ : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
+ final String targetPackage = r.packageName;
+ final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1;
+ final int targetUidProcState = mService.mAm.getUidStateLocked(targetUid);
+ final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
+ ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
+ : false;
+ final String targetWhitelistTag = (targetUid != -1)
+ ? mService.mAm.getPendingTempWhitelistTagForUidLocked(targetUid)
+ : null;
+
+ mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
+ callingUid, callingPackage, callingUidProcState,
+ callingUidHasAnyVisibleWindow,
+ realCallingUid, realCallingUidProcState,
+ realCallingUidHasAnyVisibleWindow,
+ targetUid, targetPackage, targetUidProcState,
+ targetUidHasAnyVisibleWindow, targetWhitelistTag,
+ (originatingPendingIntent != null));
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ }
+ }
/**
* Creates a launch intent for the given auxiliary resolution data.
@@ -941,7 +997,8 @@
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
- boolean allowPendingRemoteAnimationRegistryLookup) {
+ boolean allowPendingRemoteAnimationRegistryLookup,
+ PendingIntentRecord originatingPendingIntent) {
// Refuse possible leaked file descriptors
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -1087,7 +1144,7 @@
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
- allowPendingRemoteAnimationRegistryLookup);
+ allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
Binder.restoreCallingIdentity(origId);
@@ -2615,6 +2672,11 @@
return this;
}
+ ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
+ mRequest.originatingPendingIntent = originatingPendingIntent;
+ return this;
+ }
+
void dump(PrintWriter pw, String prefix) {
prefix = prefix + " ";
pw.print(prefix);
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 68b1d76..11f8bb1 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -727,7 +727,8 @@
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);
+ resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason,
+ null /* originatingPendingIntent */);
}
@Override
@@ -5093,7 +5094,7 @@
packageUid, packageName,
intents, resolvedTypes, null /* resultTo */,
SafeActivityOptions.fromBundle(bOptions), userId,
- false /* validateIncomingUser */);
+ false /* validateIncomingUser */, null /* originatingPendingIntent */);
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 3b98f37..162f344 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -491,7 +491,8 @@
task.intent, null, null, null, 0, 0,
new SafeActivityOptions(ActivityOptions.makeBasic()),
task.userId, null,
- "AppErrors", false /*validateIncomingUser*/);
+ "AppErrors", false /*validateIncomingUser*/,
+ null /* originatingPendingIntent */);
}
}
}
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index db09165..ee1166e 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -307,7 +307,7 @@
} else if (finalIntent.getComponent() != null) {
finalIntent.getComponent().appendShortString(tag);
} else if (finalIntent.getData() != null) {
- tag.append(finalIntent.getData());
+ tag.append(finalIntent.getData().toSafeString());
}
owner.tempWhitelistForPendingIntentLocked(callingPid,
callingUid, uid, duration, tag.toString());
@@ -346,13 +346,15 @@
res = owner.mActivityTaskManager.getActivityStartController().startActivitiesInPackage(
uid, key.packageName, allIntents, allResolvedTypes,
resultTo, mergedOptions, userId,
- false /* validateIncomingUser */);
+ false /* validateIncomingUser */,
+ this /* originatingPendingIntent */);
} else {
res = owner.mActivityTaskManager.getActivityStartController().startActivityInPackage(uid,
callingPid, callingUid, key.packageName, finalIntent,
resolvedType, resultTo, resultWho, requestCode, 0,
mergedOptions, userId, null, "PendingIntentRecord",
- false /* validateIncomingUser */);
+ false /* validateIncomingUser */,
+ this /* originatingPendingIntent */);
}
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startActivity intent", e);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index f854df6..257e119 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -24,7 +24,6 @@
import static android.app.ActivityManager.USER_OP_SUCCESS;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
-
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;
@@ -49,6 +48,7 @@
import android.app.IUserSwitchObserver;
import android.app.KeyguardManager;
import android.app.usage.UsageEvents;
+import android.appwidget.AppWidgetManagerInternal;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
@@ -535,6 +535,9 @@
}
}
+ // Spin up app widgets prior to boot-complete, so they can be ready promptly
+ mInjector.startUserWidgets(userId);
+
Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
// Do not report secondary users, runtime restarts or first boot/upgrade
if (userId == UserHandle.USER_SYSTEM
@@ -2174,6 +2177,11 @@
}
}
+ void startUserWidgets(int userId) {
+ AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
+ awm.unlockUser(userId);
+ }
+
void updateUserConfiguration() {
mService.mActivityTaskManager.updateUserConfiguration();
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index d06e785..f4d20b3 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1014,12 +1014,7 @@
Bundle finalExtras = new Bundle(extras);
String packageName = syncAdapterInfo.componentName.getPackageName();
// If the app did not run and has no account access, done
- try {
- if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) {
- continue;
- }
- } catch (IllegalArgumentException e) {
- // Package not found, race with an uninstall
+ if (!wasPackageEverLaunched(packageName, userId)) {
continue;
}
mAccountManagerInternal.requestAccountAccess(account.account,
@@ -3352,7 +3347,7 @@
String packageName = op.owningPackage;
final int userId = UserHandle.getUserId(op.owningUid);
// If the app did not run and has no account access, done
- if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) {
+ if (!wasPackageEverLaunched(packageName, userId)) {
return;
}
mAccountManagerInternal.requestAccountAccess(op.target.account,
@@ -4059,4 +4054,12 @@
public void resetTodayStats() {
mSyncStorageEngine.resetTodayStats(/*force=*/ true);
}
+
+ private boolean wasPackageEverLaunched(String packageName, int userId) {
+ try {
+ return mPackageManagerInternal.wasPackageEverLaunched(packageName, userId);
+ } catch (IllegalArgumentException e) {
+ return false; // Package has been removed.
+ }
+ }
}
diff --git a/services/core/java/com/android/server/notification/CriticalNotificationExtractor.java b/services/core/java/com/android/server/notification/CriticalNotificationExtractor.java
new file mode 100644
index 0000000..a899a08
--- /dev/null
+++ b/services/core/java/com/android/server/notification/CriticalNotificationExtractor.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.notification;
+
+import android.app.Notification;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.util.Slog;
+
+/**
+ * Sets the criticality of a notification record. This is used to allow a bypass to all other
+ * ranking signals. It is required in the automotive use case to facilitate placing emergency and
+ * warning notifications above all others. It does not process notifications unless the system
+ * has the automotive feature flag set.
+ * <p>
+ * Note: it is up to the notification ranking system to determine the effect of criticality values
+ * on a notification record
+ *
+ */
+public class CriticalNotificationExtractor implements NotificationSignalExtractor {
+
+ private static final String TAG = "CriticalNotificationExt";
+ private static final boolean DBG = false;
+ private boolean mSupportsCriticalNotifications = false;
+ /**
+ * Intended to bypass all other ranking, notification should be placed above all others.
+ * In the automotive case, the notification would be used to tell a driver to pull over
+ * immediately
+ */
+ static final int CRITICAL = 0;
+ /**
+ * Indicates a notification should be place above all notifications except those marked as
+ * critical. In the automotive case this is a check engine light.
+ */
+ static final int CRITICAL_LOW = 1;
+ /** Normal notification. */
+ static final int NORMAL = 2;
+
+ @Override
+ public void initialize(Context context, NotificationUsageStats usageStats) {
+ if (DBG) Slog.d(TAG, "Initializing " + getClass().getSimpleName() + ".");
+ mSupportsCriticalNotifications = supportsCriticalNotifications(context);
+ }
+
+ private boolean supportsCriticalNotifications(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0);
+ }
+
+ @Override
+ public RankingReconsideration process(NotificationRecord record) {
+ if (!mSupportsCriticalNotifications) {
+ if (DBG) Slog.d(TAG, "skipping since system does not support critical notification");
+ return null;
+ }
+ if (record == null || record.getNotification() == null) {
+ if (DBG) Slog.d(TAG, "skipping empty notification");
+ return null;
+ }
+ // Note: The use of both CATEGORY_CAR_EMERGENCY and CATEGORY_CAR_WARNING is restricted to
+ // System apps
+ if (record.isCategory(Notification.CATEGORY_CAR_EMERGENCY)) {
+ record.setCriticality(CRITICAL);
+ } else if (record.isCategory(Notification.CATEGORY_CAR_WARNING)) {
+ record.setCriticality(CRITICAL_LOW);
+ } else {
+ record.setCriticality(NORMAL);
+ }
+ return null;
+ }
+
+ @Override
+ public void setConfig(RankingConfig config) {
+ }
+
+ @Override
+ public void setZenHelper(ZenModeHelper helper) {
+ }
+
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 3f57faf..f487200 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2144,6 +2144,10 @@
enforceSystemOrSystemUI("setNotificationsEnabledForPackage");
mPreferencesHelper.setEnabled(pkg, uid, enabled);
+ mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setPackageName(pkg)
+ .setSubtype(enabled ? 1 : 0));
// Now, cancel any outstanding notifications that are part of a just-disabled app
if (!enabled) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkg, null, 0, 0, true,
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index 469828b..b3716f2 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -144,6 +144,8 @@
private int mPackageVisibility;
private int mUserImportance = IMPORTANCE_UNSPECIFIED;
private int mImportance = IMPORTANCE_UNSPECIFIED;
+ // Field used in global sort key to bypass normal notifications
+ private int mCriticality = CriticalNotificationExtractor.NORMAL;
private CharSequence mImportanceExplanation = null;
private int mSuppressedVisualEffects = 0;
@@ -746,6 +748,19 @@
return mIntercept;
}
+ /**
+ * Set to affect global sort key.
+ *
+ * @param criticality used in a string based sort thus 0 is the most critical
+ */
+ public void setCriticality(int criticality) {
+ mCriticality = criticality;
+ }
+
+ public int getCriticality() {
+ return mCriticality;
+ }
+
public boolean isIntercepted() {
return mIntercept;
}
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index f5e58ea..b1e9144 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -106,6 +106,8 @@
synchronized (mProxyByGroupTmp) {
// record individual ranking result and nominate proxies for each group
+ // Note: iteration is done backwards such that the index can be used as a sort key
+ // in a string compare below
for (int i = N - 1; i >= 0; i--) {
final NotificationRecord record = notificationList.get(i);
record.setAuthoritativeRank(i);
@@ -138,7 +140,8 @@
boolean isGroupSummary = record.getNotification().isGroupSummary();
record.setGlobalSortKey(
- String.format("intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
+ String.format("crtcl=0x%04x:intrsv=%c:grnk=0x%04x:gsmry=%c:%s:rnk=0x%04x",
+ record.getCriticality(),
record.isRecentlyIntrusive()
&& record.getImportance() > NotificationManager.IMPORTANCE_MIN
? '0' : '1',
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 12e1adb..5769207 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -917,6 +917,7 @@
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.USER_ACTIVITY);
+ break;
case MSG_RINGER_TOGGLE_CHORD:
handleRingerChordGesture();
break;
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 3ae5ced..b55adeb 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -1711,8 +1711,8 @@
}
/**
- * Requests that the WindowManager sends WindowManagerPolicy#ACTION_USER_ACTIVITY_NOTIFICATION
- * on the next user activity.
+ * Requests that the WindowManager sends
+ * WindowManagerPolicyConstants#ACTION_USER_ACTIVITY_NOTIFICATION on the next user activity.
*/
public void requestUserActivityNotification();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 44d0187..ae2256a 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2128,6 +2128,8 @@
}
}
mService.mAnimator.removeDisplayLocked(mDisplayId);
+ mWindowingLayer.release();
+ mOverlayLayer.release();
} finally {
mRemovingDisplay = false;
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index b5566a7..dea4076 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -361,6 +361,11 @@
new RemoteAnimationTarget[appAnimations.size()]);
mPendingStart = false;
+ // Perform layout if it was scheduled before to make sure that we get correct content
+ // insets for the target app window after a rotation
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(mDisplayId);
+ displayContent.performLayout(false /* initial */, false /* updateInputWindows */);
+
final Rect minimizedHomeBounds = mTargetAppToken != null
&& mTargetAppToken.inSplitScreenSecondaryWindowingMode()
? mMinimizedHomeBounds
@@ -369,8 +374,7 @@
&& mTargetAppToken.findMainWindow() != null
? mTargetAppToken.findMainWindow().mContentInsets
: null;
- mRunner.onAnimationStart(mController, appTargets, contentInsets,
- minimizedHomeBounds);
+ mRunner.onAnimationStart(mController, appTargets, contentInsets, minimizedHomeBounds);
if (DEBUG_RECENTS_ANIMATIONS) {
Slog.d(TAG, "startAnimation(): Notify animation start:");
for (int i = 0; i < mPendingAnimations.size(); i++) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0015693..3acecba 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -6204,6 +6204,17 @@
}
/**
+ * Returns true if the callingUid has any window currently visible to the user.
+ */
+ public boolean isAnyWindowVisibleForUid(int callingUid) {
+ synchronized (mWindowMap) {
+ return mRoot.forAllWindows(w -> {
+ return w.getOwningUid() == callingUid && w.isVisible();
+ }, true /* traverseTopToBottom */);
+ }
+ }
+
+ /**
* Called when a task has been removed from the recent tasks list.
* <p>
* Note: This doesn't go through {@link TaskWindowContainerController} yet as the window
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b6f3d3b..c82c242 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -28,6 +28,7 @@
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
import android.database.sqlite.SQLiteCompatibilityWalFlags;
+import android.database.sqlite.SQLiteGlobal;
import android.os.BaseBundle;
import android.os.Binder;
import android.os.Build;
@@ -355,6 +356,10 @@
Binder.setWarnOnBlocking(true);
// The system server should always load safe labels
PackageItemInfo.setForceSafeLabels(true);
+
+ // Default to FULL within the system server.
+ SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
+
// Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized
SQLiteCompatibilityWalFlags.init(null);
diff --git a/services/robotests/README b/services/robotests/README
new file mode 100644
index 0000000..3c68292
--- /dev/null
+++ b/services/robotests/README
@@ -0,0 +1,23 @@
+This folder is for Robolectric tests inside the platform.
+
+To add a test class annotate it as follows:
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderClasses({ClassUnderTest.class, DependencyClasses.class})
+@SystemLoaderPackages({"com.android.server.yourmodule"})
+
+Robolectric loads some classes that it decides from versioned jars of the framework. Since we are
+part of the framework some of our classes get loaded from these jars. This is NOT what we want, we
+want to test against what we wrote in the tree. Because of this we use a custom test runner,
+FrameworkRobolectricTestRunner, that bypasses these jars and loads certain classes from the system
+class loader.
+
+To specify which classes to load use either @SystemLoaderClasses or @SystemLoaderPackages. In
+practice:
+* You MUST put the class under test here.
+* If you encounter any exceptions that might be caused by a different version of the class being
+loaded, such as NoSuchMethodException, put the class involved in the exception in this annotation
+and try again.
+
+Check Android.mk file for more info.
diff --git a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index fde9bc8..e316d5b 100644
--- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -1382,6 +1382,7 @@
verify(agentMock.agent).onQuotaExceeded(anyLong(), eq(1234L));
assertEventLogged(EventLogTags.BACKUP_QUOTA_EXCEEDED, PACKAGE_1.packageName);
assertBackupNotPendingFor(PACKAGE_1);
+ // TODO: Assert about state/staging files (possible bug)
}
@Test
@@ -1584,6 +1585,17 @@
new RuntimeException().toString());
}
+ @Test
+ public void testRunTask_whenBackupRunning_doesNotThrow() throws Exception {
+ TransportMock transportMock = setUpInitializedTransport(mTransport);
+ when(mBackupManagerService.isBackupOperationInProgress()).thenReturn(true);
+ KeyValueBackupTask task =
+ createKeyValueBackupTask(
+ transportMock.transportClient, mTransport.transportDirName);
+
+ runTask(task);
+ }
+
private void runTask(KeyValueBackupTask task) {
// Pretend we are not on the main-thread to prevent RemoteCall from complaining
mShadowMainLooper.setCurrentThread(false);
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 409a2a8..90607ad 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -54,6 +54,7 @@
import org.junit.runner.RunWith;
import org.junit.Test;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
import static com.android.server.am.ActivityManagerService.ANIMATE;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
@@ -64,11 +65,13 @@
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
@@ -92,6 +95,7 @@
private ActivityTaskManagerService mService;
private ActivityStarter mStarter;
private ActivityStartController mController;
+ private ActivityMetricsLogger mActivityMetricsLogger;
private static final int PRECONDITION_NO_CALLER_APP = 1;
private static final int PRECONDITION_NO_INTENT_COMPONENT = 1 << 1;
@@ -105,11 +109,17 @@
private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9;
private static final int PRECONDITION_DISALLOW_APP_SWITCHING = 1 << 10;
+ private static final int FAKE_CALLING_UID = 666;
+ private static final int FAKE_REAL_CALLING_UID = 667;
+ private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude";
+
@Override
public void setUp() throws Exception {
super.setUp();
mService = createActivityTaskManagerService();
mController = mock(ActivityStartController.class);
+ mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
+ clearInvocations(mActivityMetricsLogger);
mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor,
mock(ActivityStartInterceptor.class));
}
@@ -480,4 +490,46 @@
assertTrue(stack.getAllTasks().isEmpty());
}
}
+
+ /**
+ * This test ensures that activity starts are not being logged when the logging is disabled.
+ */
+ @Test
+ public void testActivityStartsLogging_noLoggingWhenDisabled() {
+ doReturn(false).when(mService.mAm).isActivityStartsLoggingEnabled();
+ doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+
+ ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK);
+ starter.setReason("testActivityStartsLogging_noLoggingWhenDisabled").execute();
+
+ // verify logging wasn't done
+ verify(mActivityMetricsLogger, never()).logActivityStart(any(), any(), any(), anyInt(),
+ any(), anyInt(), anyBoolean(), anyInt(), anyInt(), anyBoolean(), anyInt(), any(),
+ anyInt(), anyBoolean(), any(), anyBoolean());
+ }
+
+ /**
+ * This test ensures that activity starts are being logged when the logging is enabled.
+ */
+ @Test
+ public void testActivityStartsLogging_logsWhenEnabled() {
+ // note: conveniently this package doesn't have any activity visible
+ doReturn(true).when(mService.mAm).isActivityStartsLoggingEnabled();
+ doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+
+ ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
+ .setCallingUid(FAKE_CALLING_UID)
+ .setRealCallingUid(FAKE_REAL_CALLING_UID)
+ .setCallingPackage(FAKE_CALLING_PACKAGE)
+ .setOriginatingPendingIntent(null);
+
+ starter.setReason("testActivityStartsLogging_logsWhenEnabled").execute();
+
+ // verify the above activity start was logged
+ verify(mActivityMetricsLogger, times(1)).logActivityStart(any(), any(), any(),
+ eq(FAKE_CALLING_UID), eq(FAKE_CALLING_PACKAGE), anyInt(), anyBoolean(),
+ eq(FAKE_REAL_CALLING_UID), anyInt(), anyBoolean(), anyInt(),
+ eq(ActivityBuilder.getDefaultComponent().getPackageName()), anyInt(), anyBoolean(),
+ any(), eq(false));
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/CriticalNotificationExtractorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/CriticalNotificationExtractorTest.java
new file mode 100644
index 0000000..1409da1
--- /dev/null
+++ b/services/tests/uiservicestests/src/com/android/server/notification/CriticalNotificationExtractorTest.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 com.android.server.notification;
+
+import static android.app.NotificationManager.IMPORTANCE_LOW;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.content.pm.PackageManager;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.testing.TestableContext;
+
+import com.android.server.UiServiceTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+public class CriticalNotificationExtractorTest extends UiServiceTestCase {
+ @Mock
+ private PackageManager mPackageManagerClient;
+ private TestableContext mContext = spy(getContext());
+ private CriticalNotificationExtractor mExtractor;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext.setMockPackageManager(mPackageManagerClient);
+ mExtractor = new CriticalNotificationExtractor();
+ }
+
+ /** confirm there is no affect on notifcations if the automotive feature flag is not set */
+ @Test
+ public void testExtractCritically_nonsupporting() throws Exception {
+ when(mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(false);
+ mExtractor.initialize(mContext, null);
+
+ assertCriticality(Notification.CATEGORY_CAR_EMERGENCY,
+ CriticalNotificationExtractor.NORMAL);
+
+ assertCriticality(Notification.CATEGORY_CAR_WARNING, CriticalNotificationExtractor.NORMAL);
+
+ assertCriticality(Notification.CATEGORY_CAR_INFORMATION,
+ CriticalNotificationExtractor.NORMAL);
+
+ assertCriticality(Notification.CATEGORY_CALL,
+ CriticalNotificationExtractor.NORMAL);
+ }
+
+ @Test
+ public void testExtractCritically() throws Exception {
+ when(mPackageManagerClient.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(true);
+ mExtractor.initialize(mContext, null);
+
+ assertCriticality(Notification.CATEGORY_CAR_EMERGENCY,
+ CriticalNotificationExtractor.CRITICAL);
+
+ assertCriticality(Notification.CATEGORY_CAR_WARNING,
+ CriticalNotificationExtractor.CRITICAL_LOW);
+
+ assertCriticality(Notification.CATEGORY_CAR_INFORMATION,
+ CriticalNotificationExtractor.NORMAL);
+
+ assertCriticality(Notification.CATEGORY_CALL,
+ CriticalNotificationExtractor.NORMAL);
+ }
+
+ private void assertCriticality(String cat, int criticality) {
+ NotificationRecord info = generateRecord(cat);
+ mExtractor.process(info);
+ assertThat(info.getCriticality(), is(criticality));
+ }
+
+
+ private NotificationRecord generateRecord(String category) {
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ final Notification.Builder builder = new Notification.Builder(getContext())
+ .setContentTitle("foo")
+ .setCategory(category)
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+ 0, n, UserHandle.ALL, null, System.currentTimeMillis());
+ return new NotificationRecord(getContext(), sbn, channel);
+ }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
index 7e0fcc9..5638cb36 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RankingHelperTest.java
@@ -203,8 +203,42 @@
}
@Test
+ public void testSortShouldRespectCritical() throws Exception {
+ ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(7);
+ NotificationRecord critical = generateRecord(0);
+ NotificationRecord critical_ish = generateRecord(1);
+ NotificationRecord critical_notAtAll = generateRecord(100);
+
+ notificationList.add(critical_ish);
+ notificationList.add(mRecordGroupGSortA);
+ notificationList.add(critical_notAtAll);
+ notificationList.add(mRecordGroupGSortB);
+ notificationList.add(mRecordNoGroup);
+ notificationList.add(mRecordNoGroupSortA);
+ notificationList.add(critical);
+ mHelper.sort(notificationList);
+
+ assertTrue(mHelper.indexOf(notificationList, critical) == 0);
+ assertTrue(mHelper.indexOf(notificationList, critical_ish) == 1);
+ assertTrue(mHelper.indexOf(notificationList, critical_notAtAll) == 6);
+ }
+
+ private NotificationRecord generateRecord(int criticality) {
+ NotificationChannel channel = new NotificationChannel("a", "a", IMPORTANCE_LOW);
+ final Notification.Builder builder = new Notification.Builder(getContext())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon);
+ Notification n = builder.build();
+ StatusBarNotification sbn = new StatusBarNotification("", "", 0, "", 0,
+ 0, n, UserHandle.ALL, null, System.currentTimeMillis());
+ NotificationRecord notificationRecord = new NotificationRecord(getContext(), sbn, channel);
+ notificationRecord.setCriticality(criticality);
+ return notificationRecord;
+ }
+
+ @Test
public void testFindAfterRankingWithASplitGroup() throws Exception {
- ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
+ ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(4);
notificationList.add(mRecordGroupGSortA);
notificationList.add(mRecordGroupGSortB);
notificationList.add(mRecordNoGroup);
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 2a41829..c240dbb 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -17,14 +17,11 @@
package android.telephony;
import android.annotation.CallSuper;
-import android.annotation.IntDef;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -32,44 +29,6 @@
* CellIdentityXxx which represents cell identity for specific network access technology.
*/
public abstract class CellIdentity implements Parcelable {
- /**
- * Cell identity type
- * @hide
- */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = "TYPE_", value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA})
- public @interface Type {}
-
- /**
- * Unknown cell identity type
- * @hide
- */
- public static final int TYPE_UNKNOWN = 0;
- /**
- * GSM cell identity type
- * @hide
- */
- public static final int TYPE_GSM = 1;
- /**
- * CDMA cell identity type
- * @hide
- */
- public static final int TYPE_CDMA = 2;
- /**
- * LTE cell identity type
- * @hide
- */
- public static final int TYPE_LTE = 3;
- /**
- * WCDMA cell identity type
- * @hide
- */
- public static final int TYPE_WCDMA = 4;
- /**
- * TDS-CDMA cell identity type
- * @hide
- */
- public static final int TYPE_TDSCDMA = 5;
/** @hide */
public static final int INVALID_CHANNEL_NUMBER = -1;
@@ -138,7 +97,9 @@
* @hide
* @return The type of the cell identity
*/
- public @Type int getType() { return mType; }
+ public @CellInfo.Type int getType() {
+ return mType;
+ }
/**
* Returns the channel number of the cell identity.
@@ -217,11 +178,12 @@
public CellIdentity createFromParcel(Parcel in) {
int type = in.readInt();
switch (type) {
- case TYPE_GSM: return CellIdentityGsm.createFromParcelBody(in);
- case TYPE_WCDMA: return CellIdentityWcdma.createFromParcelBody(in);
- case TYPE_CDMA: return CellIdentityCdma.createFromParcelBody(in);
- case TYPE_LTE: return CellIdentityLte.createFromParcelBody(in);
- case TYPE_TDSCDMA: return CellIdentityTdscdma.createFromParcelBody(in);
+ case CellInfo.TYPE_GSM: return CellIdentityGsm.createFromParcelBody(in);
+ case CellInfo.TYPE_WCDMA: return CellIdentityWcdma.createFromParcelBody(in);
+ case CellInfo.TYPE_CDMA: return CellIdentityCdma.createFromParcelBody(in);
+ case CellInfo.TYPE_LTE: return CellIdentityLte.createFromParcelBody(in);
+ case CellInfo.TYPE_TDSCDMA:
+ return CellIdentityTdscdma.createFromParcelBody(in);
default: throw new IllegalArgumentException("Bad Cell identity Parcel");
}
}
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 58a2c45..2809066 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -54,7 +54,7 @@
* @hide
*/
public CellIdentityCdma() {
- super(TAG, TYPE_CDMA, null, null, null, null);
+ super(TAG, CellInfo.TYPE_CDMA, null, null, null, null);
mNetworkId = Integer.MAX_VALUE;
mSystemId = Integer.MAX_VALUE;
mBasestationId = Integer.MAX_VALUE;
@@ -94,7 +94,7 @@
*/
public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat, String alphal,
String alphas) {
- super(TAG, TYPE_CDMA, null, null, alphal, alphas);
+ super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
mNetworkId = nid;
mSystemId = sid;
mBasestationId = bid;
@@ -213,7 +213,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- super.writeToParcel(dest, TYPE_CDMA);
+ super.writeToParcel(dest, CellInfo.TYPE_CDMA);
dest.writeInt(mNetworkId);
dest.writeInt(mSystemId);
dest.writeInt(mBasestationId);
@@ -223,7 +223,7 @@
/** Construct from Parcel, type has already been processed */
private CellIdentityCdma(Parcel in) {
- super(TAG, TYPE_CDMA, in);
+ super(TAG, CellInfo.TYPE_CDMA, in);
mNetworkId = in.readInt();
mSystemId = in.readInt();
mBasestationId = in.readInt();
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index c697880fa..4031254 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -42,7 +42,7 @@
* @hide
*/
public CellIdentityGsm() {
- super(TAG, TYPE_GSM, null, null, null, null);
+ super(TAG, CellInfo.TYPE_GSM, null, null, null, null);
mLac = Integer.MAX_VALUE;
mCid = Integer.MAX_VALUE;
mArfcn = Integer.MAX_VALUE;
@@ -92,7 +92,7 @@
*/
public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, String mccStr,
String mncStr, String alphal, String alphas) {
- super(TAG, TYPE_GSM, mccStr, mncStr, alphal, alphas);
+ super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
mLac = lac;
mCid = cid;
mArfcn = arfcn;
@@ -237,7 +237,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- super.writeToParcel(dest, TYPE_GSM);
+ super.writeToParcel(dest, CellInfo.TYPE_GSM);
dest.writeInt(mLac);
dest.writeInt(mCid);
dest.writeInt(mArfcn);
@@ -246,7 +246,7 @@
/** Construct from Parcel, type has already been processed */
private CellIdentityGsm(Parcel in) {
- super(TAG, TYPE_GSM, in);
+ super(TAG, CellInfo.TYPE_GSM, in);
mLac = in.readInt();
mCid = in.readInt();
mArfcn = in.readInt();
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 177fced..5257372 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -44,7 +44,7 @@
* @hide
*/
public CellIdentityLte() {
- super(TAG, TYPE_LTE, null, null, null, null);
+ super(TAG, CellInfo.TYPE_LTE, null, null, null, null);
mCi = Integer.MAX_VALUE;
mPci = Integer.MAX_VALUE;
mTac = Integer.MAX_VALUE;
@@ -99,7 +99,7 @@
*/
public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, String mccStr,
String mncStr, String alphal, String alphas) {
- super(TAG, TYPE_LTE, mccStr, mncStr, alphal, alphas);
+ super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
mCi = ci;
mPci = pci;
mTac = tac;
@@ -241,7 +241,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- super.writeToParcel(dest, TYPE_LTE);
+ super.writeToParcel(dest, CellInfo.TYPE_LTE);
dest.writeInt(mCi);
dest.writeInt(mPci);
dest.writeInt(mTac);
@@ -251,7 +251,7 @@
/** Construct from Parcel, type has already been processed */
private CellIdentityLte(Parcel in) {
- super(TAG, TYPE_LTE, in);
+ super(TAG, CellInfo.TYPE_LTE, in);
mCi = in.readInt();
mPci = in.readInt();
mTac = in.readInt();
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index b99fe46..21b9601 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -40,7 +40,7 @@
* @hide
*/
public CellIdentityTdscdma() {
- super(TAG, TYPE_TDSCDMA, null, null, null, null);
+ super(TAG, CellInfo.TYPE_TDSCDMA, null, null, null, null);
mLac = Integer.MAX_VALUE;
mCid = Integer.MAX_VALUE;
mCpid = Integer.MAX_VALUE;
@@ -75,7 +75,7 @@
*/
public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn,
String alphal, String alphas) {
- super(TAG, TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
+ super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
mLac = lac;
mCid = cid;
mCpid = cpid;
@@ -175,7 +175,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- super.writeToParcel(dest, TYPE_TDSCDMA);
+ super.writeToParcel(dest, CellInfo.TYPE_TDSCDMA);
dest.writeInt(mLac);
dest.writeInt(mCid);
dest.writeInt(mCpid);
@@ -184,7 +184,7 @@
/** Construct from Parcel, type has already been processed */
private CellIdentityTdscdma(Parcel in) {
- super(TAG, TYPE_TDSCDMA, in);
+ super(TAG, CellInfo.TYPE_TDSCDMA, in);
mLac = in.readInt();
mCid = in.readInt();
mCpid = in.readInt();
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 43f9406..a4ac8e3 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -42,7 +42,7 @@
* @hide
*/
public CellIdentityWcdma() {
- super(TAG, TYPE_TDSCDMA, null, null, null, null);
+ super(TAG, CellInfo.TYPE_WCDMA, null, null, null, null);
mLac = Integer.MAX_VALUE;
mCid = Integer.MAX_VALUE;
mPsc = Integer.MAX_VALUE;
@@ -93,7 +93,7 @@
*/
public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn,
String mccStr, String mncStr, String alphal, String alphas) {
- super(TAG, TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
+ super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
mLac = lac;
mCid = cid;
mPsc = psc;
@@ -227,7 +227,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- super.writeToParcel(dest, TYPE_WCDMA);
+ super.writeToParcel(dest, CellInfo.TYPE_WCDMA);
dest.writeInt(mLac);
dest.writeInt(mCid);
dest.writeInt(mPsc);
@@ -236,7 +236,7 @@
/** Construct from Parcel, type has already been processed */
private CellIdentityWcdma(Parcel in) {
- super(TAG, TYPE_WCDMA, in);
+ super(TAG, CellInfo.TYPE_WCDMA, in);
mLac = in.readInt();
mCid = in.readInt();
mPsc = in.readInt();
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index bffeb17..6b320f4 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -29,17 +29,43 @@
*/
public abstract class CellInfo implements Parcelable {
- // Type fields for parceling
- /** @hide */
- protected static final int TYPE_GSM = 1;
- /** @hide */
- protected static final int TYPE_CDMA = 2;
- /** @hide */
- protected static final int TYPE_LTE = 3;
- /** @hide */
- protected static final int TYPE_WCDMA = 4;
- /** @hide */
- protected static final int TYPE_TDCDMA = 5;
+ /**
+ * Cell identity type
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "TYPE_", value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA})
+ public @interface Type {}
+ /**
+ * Unknown cell identity type
+ * @hide
+ */
+ public static final int TYPE_UNKNOWN = 0;
+ /**
+ * GSM cell identity type
+ * @hide
+ */
+ public static final int TYPE_GSM = 1;
+ /**
+ * CDMA cell identity type
+ * @hide
+ */
+ public static final int TYPE_CDMA = 2;
+ /**
+ * LTE cell identity type
+ * @hide
+ */
+ public static final int TYPE_LTE = 3;
+ /**
+ * WCDMA cell identity type
+ * @hide
+ */
+ public static final int TYPE_WCDMA = 4;
+ /**
+ * TD-SCDMA cell identity type
+ * @hide
+ */
+ public static final int TYPE_TDSCDMA = 5;
// Type to distinguish where time stamp gets recorded.
@@ -161,6 +187,7 @@
public int getTimeStampType() {
return mTimeStampType;
}
+
/** @hide */
public void setTimeStampType(int timeStampType) {
if (timeStampType < TIMESTAMP_TYPE_UNKNOWN || timeStampType > TIMESTAMP_TYPE_JAVA_RIL) {
@@ -272,7 +299,7 @@
case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in);
case TYPE_LTE: return CellInfoLte.createFromParcelBody(in);
case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in);
- case TYPE_TDCDMA: return CellInfoTdscdma.createFromParcelBody(in);
+ case TYPE_TDSCDMA: return CellInfoTdscdma.createFromParcelBody(in);
default: throw new RuntimeException("Bad CellInfo Parcel");
}
}
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 4fb1bce..40cadde 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -110,7 +110,7 @@
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
- super.writeToParcel(dest, flags, TYPE_TDCDMA);
+ super.writeToParcel(dest, flags, TYPE_TDSCDMA);
mCellIdentityTdscdma.writeToParcel(dest, flags);
mCellSignalStrengthTdscdma.writeToParcel(dest, flags);
}
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 25851e3..b7ccee58 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -16,16 +16,16 @@
package android.telephony;
-import android.os.Parcel;
-import android.os.Parcelable;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
-import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
+import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
+import android.os.Parcel;
+import android.os.Parcelable;
/**
@@ -100,6 +100,39 @@
mCid = cid;
}
+ /** @hide */
+ public NeighboringCellInfo(final CellInfoGsm info) {
+ mNetworkType = TelephonyManager.NETWORK_TYPE_GPRS;
+
+ mRssi = info.getCellSignalStrength().getAsuLevel();
+ if (mRssi == Integer.MAX_VALUE) mRssi = UNKNOWN_RSSI;
+
+ mLac = info.getCellIdentity().getLac();
+ if (mLac == Integer.MAX_VALUE) mLac = UNKNOWN_CID;
+
+ mCid = info.getCellIdentity().getCid();
+ if (mCid == Integer.MAX_VALUE) mCid = UNKNOWN_CID;
+
+ mPsc = UNKNOWN_CID;
+ }
+
+ /** @hide */
+ public NeighboringCellInfo(final CellInfoWcdma info) {
+ mNetworkType = TelephonyManager.NETWORK_TYPE_UMTS;
+
+ mRssi = info.getCellSignalStrength().getAsuLevel();
+ if (mRssi == Integer.MAX_VALUE) mRssi = UNKNOWN_RSSI;
+
+ mLac = info.getCellIdentity().getLac();
+ if (mLac == Integer.MAX_VALUE) mLac = UNKNOWN_CID;
+
+ mCid = info.getCellIdentity().getCid();
+ if (mCid == Integer.MAX_VALUE) mCid = UNKNOWN_CID;
+
+ mPsc = info.getCellIdentity().getPsc();
+ if (mPsc == Integer.MAX_VALUE) mPsc = UNKNOWN_CID;
+ }
+
/**
* Initialize the object from rssi, location string, and radioType
* radioType is one of following
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index d76e39b..667ad91 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -139,28 +139,6 @@
*/
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
- Bitmap icon, String mcc, String mnc, String countryIso) {
- this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
- roaming, icon, mcc, mnc, countryIso, false /* isEmbedded */,
- null /* accessRules */, null /* accessRules */);
- }
-
- /**
- * @hide
- */
- public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
- CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
- Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
- @Nullable UiccAccessRule[] accessRules) {
- this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
- roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, null /* cardId */);
- }
-
- /**
- * @hide
- */
- public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
- CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
@Nullable UiccAccessRule[] accessRules, String cardId) {
this.mId = id;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b2eb5e0..ae3f7a2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1544,7 +1544,7 @@
* @return List of NeighboringCellInfo or null if info unavailable.
*
* @deprecated Use {@link #getAllCellInfo} which returns a superset of the information
- * from NeighboringCellInfo.
+ * from NeighboringCellInfo, including LTE cell information.
*/
@Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
@@ -6648,14 +6648,12 @@
@Deprecated
public boolean isTtyModeSupported() {
try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- return telephony.isTtyModeSupported();
+ TelecomManager telecomManager = TelecomManager.from(mContext);
+ if (telecomManager != null) {
+ return telecomManager.isTtySupported();
}
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#isTtyModeSupported", e);
} catch (SecurityException e) {
- Log.e(TAG, "Permission error calling ITelephony#isTtyModeSupported", e);
+ Log.e(TAG, "Permission error calling TelecomManager#isTtySupported", e);
}
return false;
}
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index c6f8622..e924a25 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -16,10 +16,14 @@
package android.telephony.ims;
+import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Provides the result to the update operation for the supplementary service configuration.
*
@@ -34,6 +38,30 @@
public static final int DISABLED = 0;
public static final int ENABLED = 1;
+ /**
+ * Provision status of service
+ */
+ /** @hide */
+ @IntDef({
+ SERVICE_PROVISIONING_UNKNOWN,
+ SERVICE_NOT_PROVISIONED,
+ SERVICE_PROVISIONED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ServiceProvisionStatus {}
+ /**
+ * Unknown provision status for the service.
+ */
+ public static final int SERVICE_PROVISIONING_UNKNOWN = (-1);
+ /**
+ * Service is not provisioned.
+ */
+ public static final int SERVICE_NOT_PROVISIONED = 0;
+ /**
+ * Service is provisioned.
+ */
+ public static final int SERVICE_PROVISIONED = 1;
+
// 0: disabled, 1: enabled
/** @hide */
// TODO: Make private, do not modify this field directly, use getter!
@@ -41,6 +69,8 @@
/** @hide */
// TODO: Make private, do not modify this field directly, use getter!
public String mIcbNum;
+ /** @hide */
+ public int mProvisionStatus = SERVICE_PROVISIONING_UNKNOWN;
/**@hide*/
// TODO: Remove! Do not use this constructor, instead use public version.
@@ -74,16 +104,30 @@
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mStatus);
out.writeString(mIcbNum);
+ out.writeInt(mProvisionStatus);
}
@Override
public String toString() {
- return super.toString() + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled");
+ return super.toString() + ", Status: " + ((mStatus == 0) ? "disabled" : "enabled")
+ + ", ProvisionStatus: " + provisionStatusToString(mProvisionStatus);
+ }
+
+ private static String provisionStatusToString(int pStatus) {
+ switch (pStatus) {
+ case SERVICE_NOT_PROVISIONED:
+ return "Service not provisioned";
+ case SERVICE_PROVISIONED:
+ return "Service provisioned";
+ default:
+ return "Service provisioning unknown";
+ }
}
private void readFromParcel(Parcel in) {
mStatus = in.readInt();
mIcbNum = in.readString();
+ mProvisionStatus = in.readInt();
}
public static final Creator<ImsSsInfo> CREATOR =
@@ -112,4 +156,15 @@
public String getIcbNum() {
return mIcbNum;
}
+
+ /**
+ * @return Supplementary Service Provision status. Valid Values are:
+ * {@link #SERVICE_PROVISIONING_UNKNOWN},
+ * {@link #SERVICE_NOT_PROVISIONED},
+ * {@link #SERVICE_PROVISIONED}
+ */
+ @ServiceProvisionStatus
+ public int getProvisionStatus() {
+ return mProvisionStatus;
+ }
}
diff --git a/tools/genprotos.sh b/tools/genprotos.sh
new file mode 100755
index 0000000..f901c9f
--- /dev/null
+++ b/tools/genprotos.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+# TODO This should not be needed. If you set a custom OUT_DIR or OUT_DIR_COMMON_BASE you can
+# end up with a command that is extremely long, potentially going passed MAX_ARG_STRLEN due to
+# the way sbox rewrites the command. See b/70221552.
+
+set -e
+
+location_aprotoc=$1
+location_protoc=$2
+location_soong_zip=$3
+genDir=$4
+depfile=$5
+in=$6
+out=$7
+
+mkdir -p ${genDir}/${in} && \
+ ${location_aprotoc} --plugin=${location_protoc} \
+ --dependency_out=${depfile} \
+ --javastream_out=${genDir}/${in} \
+ -Iexternal/protobuf/src \
+ -I . \
+ ${in} && \
+ ${location_soong_zip} -jar -o ${out} -C ${genDir}/${in} -D ${genDir}/${in}