Merge "flag_check: use project name instead of project path to determine the project" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 54baae5..86bcdea 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -258,6 +258,11 @@
defaults: ["framework-minus-apex-aconfig-java-defaults"],
}
+cc_aconfig_library {
+ name: "android_security_flags_aconfig_c_lib",
+ aconfig_declarations: "android.security.flags-aconfig",
+}
+
// UsageStats
aconfig_declarations {
name: "android.app.usage.flags-aconfig",
diff --git a/DREAM_MANAGER_OWNERS b/DREAM_MANAGER_OWNERS
deleted file mode 100644
index 48bde60..0000000
--- a/DREAM_MANAGER_OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-brycelee@google.com
diff --git a/apct-tests/perftests/OWNERS b/apct-tests/perftests/OWNERS
index 8ff3f9b..f4346b1 100644
--- a/apct-tests/perftests/OWNERS
+++ b/apct-tests/perftests/OWNERS
@@ -8,4 +8,3 @@
shayba@google.com
shombert@google.com
timmurray@google.com
-wessam@google.com
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 6383ed8..a49ad98 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -618,6 +618,7 @@
* List of end times for app-IDs that are temporarily marked as being allowed to access
* the network and acquire wakelocks. Times are in milliseconds.
*/
+ @GuardedBy("this")
private final SparseArray<Pair<MutableLong, String>> mTempWhitelistAppIdEndTimes
= new SparseArray<>();
@@ -4999,7 +5000,9 @@
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) {
return -1;
}
- dumpTempWhitelistSchedule(pw, false);
+ synchronized (this) {
+ dumpTempWhitelistScheduleLocked(pw, false);
+ }
}
} else if ("except-idle-whitelist".equals(cmd)) {
getContext().enforceCallingOrSelfPermission(
@@ -5283,7 +5286,7 @@
pw.println();
}
}
- dumpTempWhitelistSchedule(pw, true);
+ dumpTempWhitelistScheduleLocked(pw, true);
size = mTempWhitelistAppIdArray != null ? mTempWhitelistAppIdArray.length : 0;
if (size > 0) {
@@ -5411,7 +5414,8 @@
}
}
- void dumpTempWhitelistSchedule(PrintWriter pw, boolean printTitle) {
+ @GuardedBy("this")
+ void dumpTempWhitelistScheduleLocked(PrintWriter pw, boolean printTitle) {
final int size = mTempWhitelistAppIdEndTimes.size();
if (size > 0) {
String prefix = "";
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java
index adee322..f722e41 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/IdleController.java
@@ -48,6 +48,7 @@
private static final String TAG = "JobScheduler.IdleController";
// Policy: we decide that we're "idle" if the device has been unused /
// screen off or dreaming or wireless charging dock idle for at least this long
+ @GuardedBy("mLock")
final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
IdlenessTracker mIdleTracker;
private final FlexibilityController mFlexibilityController;
@@ -118,8 +119,10 @@
for (int i = mTrackedTasks.size()-1; i >= 0; i--) {
mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle);
}
+ if (!mTrackedTasks.isEmpty()) {
+ mStateChangedListener.onControllerStateChanged(mTrackedTasks);
+ }
}
- mStateChangedListener.onControllerStateChanged(mTrackedTasks);
}
/**
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index f2c39be..f77f1c6 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -44,13 +44,13 @@
removed_api_file: ":non-updatable-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.public.latest",
- removed_api_file: ":android-non-updatable-removed.api.public.latest",
+ api_file: ":android-non-updatable.api.combined.public.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.public.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.public.latest",
},
api_lint: {
enabled: true,
- new_since: ":android.api.public.latest",
+ new_since: ":android.api.combined.public.latest",
baseline_file: ":non-updatable-lint-baseline.txt",
},
},
@@ -124,13 +124,13 @@
removed_api_file: ":non-updatable-system-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.system.latest",
- removed_api_file: ":android-non-updatable-removed.api.system.latest",
+ api_file: ":android-non-updatable.api.combined.system.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.system.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.system.latest",
},
api_lint: {
enabled: true,
- new_since: ":android.api.system.latest",
+ new_since: ":android.api.combined.system.latest",
baseline_file: ":non-updatable-system-lint-baseline.txt",
},
},
@@ -185,7 +185,7 @@
},
api_lint: {
enabled: true,
- new_since: ":android.api.test.latest",
+ new_since: ":android.api.combined.test.latest",
baseline_file: ":non-updatable-test-lint-baseline.txt",
},
},
@@ -263,13 +263,13 @@
removed_api_file: ":non-updatable-module-lib-removed.txt",
},
last_released: {
- api_file: ":android-non-updatable.api.module-lib.latest",
- removed_api_file: ":android-non-updatable-removed.api.module-lib.latest",
+ api_file: ":android-non-updatable.api.combined.module-lib.latest",
+ removed_api_file: ":android-non-updatable-removed.api.combined.module-lib.latest",
baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest",
},
api_lint: {
enabled: true,
- new_since: ":android.api.module-lib.latest",
+ new_since: ":android.api.combined.module-lib.latest",
baseline_file: ":non-updatable-module-lib-lint-baseline.txt",
},
},
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 5adcd93..7eb9d0f 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -1335,7 +1335,8 @@
if (path.string() == animation.parts[j].path.c_str()) {
uint16_t method;
// supports only stored png files
- if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) {
+ if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr,
+ nullptr, nullptr)) {
if (method == ZipFileRO::kCompressStored) {
FileMap* map = zip->createEntryFileMap(entry);
if (map) {
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 8b8d361..a142450 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -134,8 +134,9 @@
return env;
}
-std::unique_ptr<Device> Device::open(int32_t id, const char* name, int32_t vid, int32_t pid,
- uint16_t bus, const std::vector<uint8_t>& descriptor,
+std::unique_ptr<Device> Device::open(int32_t id, const char* name, const char* uniq, int32_t vid,
+ int32_t pid, uint16_t bus,
+ const std::vector<uint8_t>& descriptor,
std::unique_ptr<DeviceCallback> callback) {
size_t size = descriptor.size();
if (size > HID_MAX_DESCRIPTOR_SIZE) {
@@ -152,8 +153,7 @@
struct uhid_event ev = {};
ev.type = UHID_CREATE2;
strlcpy(reinterpret_cast<char*>(ev.u.create2.name), name, sizeof(ev.u.create2.name));
- std::string uniq = android::base::StringPrintf("Id: %d", id);
- strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq.c_str(), sizeof(ev.u.create2.uniq));
+ strlcpy(reinterpret_cast<char*>(ev.u.create2.uniq), uniq, sizeof(ev.u.create2.uniq));
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;
@@ -314,19 +314,31 @@
return data;
}
-static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jint id, jint vid,
- jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) {
+static jlong openDevice(JNIEnv* env, jclass /* clazz */, jstring rawName, jstring rawUniq, jint id,
+ jint vid, jint pid, jint bus, jbyteArray rawDescriptor, jobject callback) {
ScopedUtfChars name(env, rawName);
if (name.c_str() == nullptr) {
return 0;
}
+ std::string uniq;
+ if (rawUniq != nullptr) {
+ uniq = ScopedUtfChars(env, rawUniq);
+ } else {
+ uniq = android::base::StringPrintf("Id: %d", id);
+ }
+
+ if (uniq.c_str() == nullptr) {
+ return 0;
+ }
+
std::vector<uint8_t> desc = getData(env, rawDescriptor);
std::unique_ptr<uhid::DeviceCallback> cb(new uhid::DeviceCallback(env, callback));
std::unique_ptr<uhid::Device> d =
- uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()), vid, pid, bus, desc,
+ uhid::Device::open(id, reinterpret_cast<const char*>(name.c_str()),
+ reinterpret_cast<const char*>(uniq.c_str()), vid, pid, bus, desc,
std::move(cb));
return reinterpret_cast<jlong>(d.release());
}
@@ -370,7 +382,7 @@
static JNINativeMethod sMethods[] = {
{"nativeOpenDevice",
- "(Ljava/lang/String;IIII[B"
+ "(Ljava/lang/String;Ljava/lang/String;IIII[B"
"Lcom/android/commands/hid/Device$DeviceCallback;)J",
reinterpret_cast<void*>(openDevice)},
{"nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport)},
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index 9c6060d..bc7a909 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -42,8 +42,9 @@
class Device {
public:
- static std::unique_ptr<Device> open(int32_t id, const char* name, int32_t vid, int32_t pid,
- uint16_t bus, const std::vector<uint8_t>& descriptor,
+ static std::unique_ptr<Device> open(int32_t id, const char* name, const char* uniq, int32_t vid,
+ int32_t pid, uint16_t bus,
+ const std::vector<uint8_t>& descriptor,
std::unique_ptr<DeviceCallback> callback);
~Device();
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index 0415037..4e8adc3 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -71,6 +71,7 @@
private static native long nativeOpenDevice(
String name,
+ String uniq,
int id,
int vid,
int pid,
@@ -89,6 +90,7 @@
public Device(
int id,
String name,
+ String uniq,
int vid,
int pid,
int bus,
@@ -113,8 +115,9 @@
} else {
args.arg1 = id + ":" + vid + ":" + pid;
}
- args.arg2 = descriptor;
- args.arg3 = report;
+ args.arg2 = uniq;
+ args.arg3 = descriptor;
+ args.arg4 = report;
mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget();
mTimeToSend = SystemClock.uptimeMillis();
}
@@ -167,11 +170,12 @@
mPtr =
nativeOpenDevice(
(String) args.arg1,
+ (String) args.arg2,
args.argi1,
args.argi2,
args.argi3,
args.argi4,
- (byte[]) args.arg2,
+ (byte[]) args.arg3,
new DeviceCallback());
pauseEvents();
break;
diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java
index 3efb797..3b02279 100644
--- a/cmds/hid/src/com/android/commands/hid/Event.java
+++ b/cmds/hid/src/com/android/commands/hid/Event.java
@@ -56,6 +56,7 @@
private int mId;
private String mCommand;
private String mName;
+ private String mUniq;
private byte[] mDescriptor;
private int mVid;
private int mPid;
@@ -78,6 +79,10 @@
return mName;
}
+ public String getUniq() {
+ return mUniq;
+ }
+
public byte[] getDescriptor() {
return mDescriptor;
}
@@ -116,8 +121,9 @@
public String toString() {
return "Event{id=" + mId
- + ", command=" + String.valueOf(mCommand)
- + ", name=" + String.valueOf(mName)
+ + ", command=" + mCommand
+ + ", name=" + mName
+ + ", uniq=" + mUniq
+ ", descriptor=" + Arrays.toString(mDescriptor)
+ ", vid=" + mVid
+ ", pid=" + mPid
@@ -149,6 +155,10 @@
mEvent.mName = name;
}
+ public void setUniq(String uniq) {
+ mEvent.mUniq = uniq;
+ }
+
public void setDescriptor(byte[] descriptor) {
mEvent.mDescriptor = descriptor;
}
@@ -247,6 +257,9 @@
case "name":
eb.setName(mReader.nextString());
break;
+ case "uniq":
+ eb.setUniq(mReader.nextString());
+ break;
case "vid":
eb.setVid(readInt());
break;
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
index 2db791fe..5ebfd95 100644
--- a/cmds/hid/src/com/android/commands/hid/Hid.java
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -117,8 +117,17 @@
"Tried to send command \"" + e.getCommand() + "\" to an unregistered device!");
}
int id = e.getId();
- Device d = new Device(id, e.getName(), e.getVendorId(), e.getProductId(), e.getBus(),
- e.getDescriptor(), e.getReport(), e.getFeatureReports(), e.getOutputs());
+ Device d = new Device(
+ id,
+ e.getName(),
+ e.getUniq(),
+ e.getVendorId(),
+ e.getProductId(),
+ e.getBus(),
+ e.getDescriptor(),
+ e.getReport(),
+ e.getFeatureReports(),
+ e.getOutputs());
mDevices.append(id, d);
}
diff --git a/core/java/android/animation/OWNERS b/core/java/android/animation/OWNERS
index 822a35c..f3b330a 100644
--- a/core/java/android/animation/OWNERS
+++ b/core/java/android/animation/OWNERS
@@ -2,5 +2,4 @@
romainguy@google.com
tianliu@google.com
-alanv@google.com
adamp@google.com
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 287d2bd..b38f76e 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2593,6 +2593,9 @@
try {
Objects.requireNonNull(packageName);
return mPM.isAppArchivable(packageName, new UserHandle(getUserId()));
+ } catch (ParcelableException e) {
+ e.maybeRethrow(NameNotFoundException.class);
+ throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index 02f00ba..cb490da 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -61,7 +61,7 @@
per-file ComponentCaller.java = file:COMPONENT_CALLER_OWNERS
# DreamManager
-per-file DreamManager.java = file:/DREAM_MANAGER_OWNERS
+per-file DreamManager.java = file:/core/java/android/service/dreams/OWNERS
# GrammaticalInflectionManager
per-file *GrammaticalInflection* = file:/services/core/java/com/android/server/grammaticalinflection/OWNERS
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 6600ca9..649b812 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -44,6 +44,16 @@
}
flag {
+ name: "hsum_unlock_notification_fix"
+ namespace: "enterprise"
+ description: "Using the right userId when starting the work profile unlock flow "
+ bug: "327350831"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+}
+
+flag {
name: "dumpsys_policy_engine_migration_enabled"
namespace: "enterprise"
description: "Update DumpSys to include information about migrated APIs in DPE"
diff --git a/core/java/android/app/pinner/OWNERS b/core/java/android/app/pinner/OWNERS
index 3e3fa66..fe5da9f 100644
--- a/core/java/android/app/pinner/OWNERS
+++ b/core/java/android/app/pinner/OWNERS
@@ -5,6 +5,5 @@
philipcuadra@google.com
shombert@google.com
timmurray@google.com
-wessam@google.com
jdduke@google.com
-shayba@google.com
\ No newline at end of file
+shayba@google.com
diff --git a/core/java/android/app/prediction/OWNERS b/core/java/android/app/prediction/OWNERS
index fe012da..73168fb 100644
--- a/core/java/android/app/prediction/OWNERS
+++ b/core/java/android/app/prediction/OWNERS
@@ -1,2 +1,4 @@
+pinyaoting@google.com
+hyunyoungs@google.com
adamcohen@google.com
sunnygoyal@google.com
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 64042235..b18c7be 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -2360,6 +2360,7 @@
new UserHandle(mUserId), flags);
} catch (ParcelableException e) {
e.maybeRethrow(PackageManager.NameNotFoundException.class);
+ throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2396,6 +2397,7 @@
} catch (ParcelableException e) {
e.maybeRethrow(IOException.class);
e.maybeRethrow(PackageManager.NameNotFoundException.class);
+ throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -2427,6 +2429,7 @@
userActionIntent, new UserHandle(mUserId));
} catch (ParcelableException e) {
e.maybeRethrow(PackageManager.NameNotFoundException.class);
+ throw new RuntimeException(e);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/gesture/OWNERS b/core/java/android/gesture/OWNERS
index b3b8775..168630a 100644
--- a/core/java/android/gesture/OWNERS
+++ b/core/java/android/gesture/OWNERS
@@ -1,7 +1,6 @@
# Bug component: 25700
romainguy@google.com
-alanv@google.com
adamp@google.com
aurimas@google.com
nduca@google.com
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 40e03db..3273780 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -518,23 +518,25 @@
Handler mainHandler = new Handler(mContext.getMainLooper());
- for (Map.Entry<DynamicSensorCallback, Handler> entry :
- mDynamicSensorCallbacks.entrySet()) {
- final DynamicSensorCallback callback = entry.getKey();
- Handler handler =
- entry.getValue() == null ? mainHandler : entry.getValue();
+ synchronized (mDynamicSensorCallbacks) {
+ for (Map.Entry<DynamicSensorCallback, Handler> entry :
+ mDynamicSensorCallbacks.entrySet()) {
+ final DynamicSensorCallback callback = entry.getKey();
+ Handler handler =
+ entry.getValue() == null ? mainHandler : entry.getValue();
- handler.post(new Runnable() {
- @Override
- public void run() {
- for (Sensor s: addedList) {
- callback.onDynamicSensorConnected(s);
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ for (Sensor s: addedList) {
+ callback.onDynamicSensorConnected(s);
+ }
+ for (Sensor s: removedList) {
+ callback.onDynamicSensorDisconnected(s);
+ }
}
- for (Sensor s: removedList) {
- callback.onDynamicSensorDisconnected(s);
- }
- }
- });
+ });
+ }
}
for (Sensor s: removedList) {
@@ -653,13 +655,15 @@
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
- if (mDynamicSensorCallbacks.containsKey(callback)) {
- // has been already registered, ignore
- return;
- }
+ synchronized (mDynamicSensorCallbacks) {
+ if (mDynamicSensorCallbacks.containsKey(callback)) {
+ // has been already registered, ignore
+ return;
+ }
- setupDynamicSensorBroadcastReceiver();
- mDynamicSensorCallbacks.put(callback, handler);
+ setupDynamicSensorBroadcastReceiver();
+ mDynamicSensorCallbacks.put(callback, handler);
+ }
}
/** @hide */
@@ -668,7 +672,9 @@
if (DEBUG_DYNAMIC_SENSOR) {
Log.i(TAG, "Removing dynamic sensor listener");
}
- mDynamicSensorCallbacks.remove(callback);
+ synchronized (mDynamicSensorCallbacks) {
+ mDynamicSensorCallbacks.remove(callback);
+ }
}
/*
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 4dc32d5..f3d743d 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -580,6 +580,8 @@
", copied:" + progress +
", read:" + (count - countToRead) +
", in pipe: " + countInPipe);
+ Os.close(pipes[0]);
+ Os.close(pipes[1]);
throw new ErrnoException("splice, pipe --> fdOut", EIO);
} else {
progress += t;
@@ -607,6 +609,8 @@
listener.onProgress(progressSnapshot);
});
}
+ Os.close(pipes[0]);
+ Os.close(pipes[1]);
return progress;
}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 91c2965..c9f207c 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -305,15 +305,28 @@
/**
* Interface for receiving a callback when the process hosting an IBinder
* has gone away.
- *
+ *
* @see #linkToDeath
*/
public interface DeathRecipient {
public void binderDied();
/**
- * Interface for receiving a callback when the process hosting an IBinder
+ * The function called when the process hosting an IBinder
* has gone away.
+ *
+ * This callback will be called from any binder thread like any other binder
+ * transaction. If the process receiving this notification is multithreaded
+ * then synchronization may be required because other threads may be executing
+ * at the same time.
+ *
+ * No locks are held in libbinder when {@link binderDied} is called.
+ *
+ * There is no need to call {@link unlinkToDeath} in the binderDied callback.
+ * The binder is already dead so {@link unlinkToDeath} is a no-op.
+ * It will be unlinked when the last local reference of that binder proxy is
+ * dropped.
+ *
* @param who The IBinder that has become invalid
*/
default void binderDied(@NonNull IBinder who) {
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 9f3364f..04d4970 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -107,4 +107,8 @@
per-file ProfilingServiceManager.java = file:/PERFORMANCE_OWNERS
# Memory
-per-file OomKillRecord.java = file:/MEMORY_OWNERS
\ No newline at end of file
+per-file OomKillRecord.java = file:/MEMORY_OWNERS
+
+# MessageQueue
+per-file MessageQueue.java = mfasheh@google.com, shayba@google.com
+per-file Message.java = mfasheh@google.com, shayba@google.com
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 5056557..bb89e07 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -17,8 +17,11 @@
package android.os;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.app.ActivityThread;
+import java.io.IOException;
import java.util.Map;
/**
@@ -113,5 +116,20 @@
@TestApi
public static native Long getTargetFrameworkCompatibilityMatrixVersion();
+ /**
+ * Executes a shell command using shell user identity, and return the standard output in string.
+ *
+ * @hide
+ */
+ private static @Nullable String runShellCommand(@NonNull String command) throws IOException {
+ var activityThread = ActivityThread.currentActivityThread();
+ var instrumentation = activityThread.getInstrumentation();
+ var automation = instrumentation.getUiAutomation();
+ var pfd = automation.executeShellCommand(command);
+ try (var is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
+ return new String(is.readAllBytes());
+ }
+ }
+
private VintfObject() {}
}
diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS
index 77bcee8..119ca55 100644
--- a/core/java/android/service/dreams/OWNERS
+++ b/core/java/android/service/dreams/OWNERS
@@ -1,10 +1,11 @@
-# Bug component: 78010
+# Bug component: 66910
brycelee@google.com
-dsandler@google.com
-galinap@google.com
-jjaggi@google.com
lusilva@google.com
-michaelwr@google.com
-santoscordon@google.com
wxyz@google.com
+justinkoh@google.com
+
+rgl@google.com
+santoscordon@google.com
+
+dsandler@google.com
diff --git a/core/java/android/transition/OWNERS b/core/java/android/transition/OWNERS
index eb5a581..2a8d940 100644
--- a/core/java/android/transition/OWNERS
+++ b/core/java/android/transition/OWNERS
@@ -2,5 +2,4 @@
romainguy@google.com
mount@google.com
-alanv@google.com
adamp@google.com
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index 07d05a4..31a8dfa 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -1,7 +1,6 @@
# Bug component: 25700
romainguy@google.com
-alanv@google.com
adamp@google.com
aurimas@google.com
nduca@google.com
diff --git a/core/java/android/view/accessibility/OWNERS b/core/java/android/view/accessibility/OWNERS
index b0943e9..f62b33f 100644
--- a/core/java/android/view/accessibility/OWNERS
+++ b/core/java/android/view/accessibility/OWNERS
@@ -5,7 +5,6 @@
# Android members outside of Accessibility
adamp@google.com #{LAST_RESORT_SUGGESTION}
-alanv@google.com #{LAST_RESORT_SUGGESTION}
aurimas@google.com #{LAST_RESORT_SUGGESTION}
jjaggi@google.com #{LAST_RESORT_SUGGESTION}
ogunwale@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/core/java/android/view/animation/OWNERS b/core/java/android/view/animation/OWNERS
index 9b8f4d9..2fa01c3 100644
--- a/core/java/android/view/animation/OWNERS
+++ b/core/java/android/view/animation/OWNERS
@@ -2,5 +2,4 @@
romainguy@google.com
tianliu@google.com
-alanv@google.com
adamp@google.com
diff --git a/core/java/android/view/textclassifier/intent/OWNERS b/core/java/android/view/textclassifier/intent/OWNERS
index ac80d9f..3465fe6 100644
--- a/core/java/android/view/textclassifier/intent/OWNERS
+++ b/core/java/android/view/textclassifier/intent/OWNERS
@@ -4,5 +4,4 @@
toki@google.com
svetoslavganov@android.com
svetoslavganov@google.com
-augale@google.com
joannechung@google.com
diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS
index 1dc90ed..8b8090b 100644
--- a/core/java/android/widget/OWNERS
+++ b/core/java/android/widget/OWNERS
@@ -1,7 +1,6 @@
# Bug component: 25700
romainguy@google.com
-alanv@google.com
adamp@google.com
aurimas@google.com
siyamed@google.com
diff --git a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
index 9fc7ddb..0e5049e 100644
--- a/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
+++ b/core/java/com/android/internal/pm/pkg/parsing/ParsingPackageUtils.java
@@ -1911,12 +1911,16 @@
} else if (parser.getName().equals("package")) {
final TypedArray sa = res.obtainAttributes(parser,
R.styleable.AndroidManifestQueriesPackage);
- final String packageName = sa.getNonConfigurationString(
- R.styleable.AndroidManifestQueriesPackage_name, 0);
- if (TextUtils.isEmpty(packageName)) {
- return input.error("Package name is missing from package tag.");
+ try {
+ final String packageName = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestQueriesPackage_name, 0);
+ if (TextUtils.isEmpty(packageName)) {
+ return input.error("Package name is missing from package tag.");
+ }
+ pkg.addQueriesPackage(packageName.intern());
+ } finally {
+ sa.recycle();
}
- pkg.addQueriesPackage(packageName.intern());
} else if (parser.getName().equals("provider")) {
final TypedArray sa = res.obtainAttributes(parser,
R.styleable.AndroidManifestQueriesProvider);
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 8566263..e08443b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -861,7 +861,7 @@
final MenuHelper helper;
final boolean isPopup = !Float.isNaN(x) && !Float.isNaN(y);
if (isPopup) {
- helper = mWindow.mContextMenu.showPopup(getContext(), originalView, x, y);
+ helper = mWindow.mContextMenu.showPopup(originalView.getContext(), originalView, x, y);
} else {
helper = mWindow.mContextMenu.showDialog(originalView, originalView.getWindowToken());
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 6412ddb..3024b94 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -478,4 +478,8 @@
"libnativehelper",
"libvintf",
],
+
+ required: [
+ "vintf",
+ ],
}
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 8dc9d0a..7a4854b 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -32,6 +32,8 @@
static jmethodID gHashMapPut;
static jclass gLongClazz;
static jmethodID gLongValueOf;
+static jclass gVintfObjectClazz;
+static jmethodID gRunCommand;
namespace android {
@@ -47,6 +49,56 @@
using vintf::Vndk;
using vintf::CheckFlags::ENABLE_ALL_CHECKS;
+// Instead of VintfObject::GetXxx(), we construct
+// HalManifest/CompatibilityMatrix objects by calling `vintf` through
+// UiAutomation.executeShellCommand() so that the commands are executed
+// using shell identity. Otherwise, we would need to allow "apps" to access
+// files like apex-info-list.xml which we don't want to open to apps.
+// This is okay because VintfObject is @TestApi and only used in CTS tests.
+
+static std::string runCmd(JNIEnv* env, const char* cmd) {
+ jstring jstr = (jstring)env->CallStaticObjectMethod(gVintfObjectClazz, gRunCommand,
+ env->NewStringUTF(cmd));
+ std::string output;
+ if (jstr) {
+ auto cstr = env->GetStringUTFChars(jstr, nullptr);
+ output = std::string(cstr);
+ env->ReleaseStringUTFChars(jstr, cstr);
+ } else {
+ LOG(WARNING) << "Failed to run " << cmd;
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+ return output;
+}
+
+template <typename T>
+static std::shared_ptr<const T> fromXml(const std::string& content) {
+ std::shared_ptr<T> object = std::make_unique<T>();
+ std::string error;
+ if (fromXml(object.get(), content, &error)) {
+ return object;
+ }
+ LOG(WARNING) << "Unabled to parse: " << error;
+ return nullptr;
+}
+
+static std::shared_ptr<const HalManifest> getDeviceHalManifest(JNIEnv* env) {
+ return fromXml<HalManifest>(runCmd(env, "vintf dm"));
+}
+
+static std::shared_ptr<const HalManifest> getFrameworkHalManifest(JNIEnv* env) {
+ return fromXml<HalManifest>(runCmd(env, "vintf fm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix(JNIEnv* env) {
+ return fromXml<CompatibilityMatrix>(runCmd(env, "vintf dcm"));
+}
+
+static std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix(JNIEnv* env) {
+ return fromXml<CompatibilityMatrix>(runCmd(env, "vintf fcm"));
+}
+
template<typename V>
static inline jobjectArray toJavaStringArray(JNIEnv* env, const V& v) {
size_t i;
@@ -83,12 +135,10 @@
{
std::vector<std::string> cStrings;
- tryAddSchema(VintfObject::GetDeviceHalManifest(), "device manifest", &cStrings);
- tryAddSchema(VintfObject::GetFrameworkHalManifest(), "framework manifest", &cStrings);
- tryAddSchema(VintfObject::GetDeviceCompatibilityMatrix(), "device compatibility matrix",
- &cStrings);
- tryAddSchema(VintfObject::GetFrameworkCompatibilityMatrix(), "framework compatibility matrix",
- &cStrings);
+ tryAddSchema(getDeviceHalManifest(env), "device manifest", &cStrings);
+ tryAddSchema(getFrameworkHalManifest(env), "framework manifest", &cStrings);
+ tryAddSchema(getDeviceCompatibilityMatrix(env), "device compatibility matrix", &cStrings);
+ tryAddSchema(getFrameworkCompatibilityMatrix(env), "framework compatibility matrix", &cStrings);
return toJavaStringArray(env, cStrings);
}
@@ -108,15 +158,13 @@
static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
std::set<std::string> halNames;
- tryAddHalNamesAndVersions(VintfObject::GetDeviceHalManifest(),
- "device manifest", &halNames);
- tryAddHalNamesAndVersions(VintfObject::GetFrameworkHalManifest(),
- "framework manifest", &halNames);
+ tryAddHalNamesAndVersions(getDeviceHalManifest(env), "device manifest", &halNames);
+ tryAddHalNamesAndVersions(getFrameworkHalManifest(env), "framework manifest", &halNames);
return toJavaStringArray(env, halNames);
}
static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::DEVICE) {
LOG(WARNING) << __FUNCTION__ << "Cannot get device manifest";
return nullptr;
@@ -126,8 +174,7 @@
}
static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const CompatibilityMatrix> matrix =
- VintfObject::GetFrameworkCompatibilityMatrix();
+ std::shared_ptr<const CompatibilityMatrix> matrix = getFrameworkCompatibilityMatrix(env);
if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
return nullptr;
@@ -148,7 +195,7 @@
}
static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getFrameworkHalManifest(env);
if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
LOG(WARNING) << __FUNCTION__ << "Cannot get framework manifest";
return nullptr;
@@ -163,7 +210,7 @@
}
static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion(JNIEnv* env, jclass) {
- std::shared_ptr<const HalManifest> manifest = VintfObject::GetDeviceHalManifest();
+ std::shared_ptr<const HalManifest> manifest = getDeviceHalManifest(env);
if (manifest == nullptr || manifest->level() == Level::UNSPECIFIED) {
return nullptr;
}
@@ -188,19 +235,20 @@
const char* const kVintfObjectPathName = "android/os/VintfObject";
-int register_android_os_VintfObject(JNIEnv* env)
-{
-
+int register_android_os_VintfObject(JNIEnv* env) {
gString = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/String"));
gHashMapClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/HashMap"));
gHashMapInit = GetMethodIDOrDie(env, gHashMapClazz, "<init>", "()V");
- gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz,
- "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ gHashMapPut = GetMethodIDOrDie(env, gHashMapClazz, "put",
+ "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
gLongClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/lang/Long"));
gLongValueOf = GetStaticMethodIDOrDie(env, gLongClazz, "valueOf", "(J)Ljava/lang/Long;");
+ gVintfObjectClazz = MakeGlobalRefOrDie(env, FindClassOrDie(env, kVintfObjectPathName));
+ gRunCommand = GetStaticMethodIDOrDie(env, gVintfObjectClazz, "runShellCommand",
+ "(Ljava/lang/String;)Ljava/lang/String;");
return RegisterMethodsOrDie(env, kVintfObjectPathName, gVintfObjectMethods,
- NELEM(gVintfObjectMethods));
+ NELEM(gVintfObjectMethods));
}
extern int register_android_os_VintfRuntimeInfo(JNIEnv* env);
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index 31f4e64..d426f12 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -88,7 +88,7 @@
ALOGD("Total number of LOAD segments %zu", programHeaders.size());
ALOGD("Size before punching holes st_blocks: %" PRIu64
- ", st_blksize: %ld, st_size: %" PRIu64 "",
+ ", st_blksize: %d, st_size: %" PRIu64 "",
beforePunch.st_blocks, beforePunch.st_blksize,
static_cast<uint64_t>(beforePunch.st_size));
}
@@ -193,7 +193,7 @@
ALOGD("lstat64 failed for filePath %s, error:%d", filePath, errno);
return false;
}
- ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %ld, st_size: %" PRIu64
+ ALOGD("Size after punching holes st_blocks: %" PRIu64 ", st_blksize: %d, st_size: %" PRIu64
"",
afterPunch.st_blocks, afterPunch.st_blksize,
static_cast<uint64_t>(afterPunch.st_size));
@@ -271,7 +271,7 @@
uint64_t blockSize = beforePunch.st_blksize;
IF_ALOGD() {
ALOGD("Extra field length: %hu, Size before punching holes st_blocks: %" PRIu64
- ", st_blksize: %ld, st_size: %" PRIu64 "",
+ ", st_blksize: %d, st_size: %" PRIu64 "",
extraFieldLen, beforePunch.st_blocks, beforePunch.st_blksize,
static_cast<uint64_t>(beforePunch.st_size));
}
@@ -346,7 +346,7 @@
return false;
}
ALOGD("punchHolesInApk:: Size after punching holes st_blocks: %" PRIu64
- ", st_blksize: %ld, st_size: %" PRIu64 "",
+ ", st_blksize: %d, st_size: %" PRIu64 "",
afterPunch.st_blocks, afterPunch.st_blksize,
static_cast<uint64_t>(afterPunch.st_size));
}
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 9b8dab7..fba0d81 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -115,7 +115,8 @@
size_t* total = (size_t*) arg;
uint32_t uncompLen;
- if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr)) {
+ if (!zipFile->getEntryInfo(zipEntry, nullptr, &uncompLen, nullptr, nullptr, nullptr, nullptr,
+ nullptr)) {
return INSTALL_FAILED_INVALID_APK;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ee7baa1..cf552da 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2258,6 +2258,11 @@
<permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED"
android:protectionLevel="signature|privileged" />
+ <!-- @hide Allows access to Thread network APIs or shell commands ("cmd thread_network") which
+ are only for testing. -->
+ <permission android:name="android.permission.THREAD_NETWORK_TESTING"
+ android:protectionLevel="signature" />
+
<!-- #SystemApi @hide Allows an app to bypass Private DNS.
<p>Not for use by third-party applications.
TODO: publish as system API in next API release. -->
diff --git a/core/res/OWNERS b/core/res/OWNERS
index dce578a..22ea9da 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -66,6 +66,11 @@
per-file res/xml/power_profile.xml = file:/BATTERY_STATS_OWNERS
per-file res/xml/power_profile_test.xml = file:/BATTERY_STATS_OWNERS
+# RemoteView color resources
+per-file remote_color_resources_res/symbols.xml = pbdr@google.com
+per-file remote_color_resources_res/values/public.xml = pbdr@google.com
+per-file remote_color_resources_res/values/colors.xml = pbdr@google.com
+
# Telephony
per-file res/values/config_telephony.xml = file:/platform/frameworks/opt/telephony:/OWNERS
per-file res/xml/sms_short_codes.xml = file:/platform/frameworks/opt/telephony:/OWNERS
@@ -79,4 +84,4 @@
per-file res/values/styles.xml = arteiro@google.com
per-file res/values/symbols.xml = arteiro@google.com
per-file res/values/themes_device_defaults.xml = arteiro@google.com
-per-file res/values/styles_material.xml = arteiro@google.com
\ No newline at end of file
+per-file res/values/styles_material.xml = arteiro@google.com
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 4d7c009..67cceb5 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -60,6 +60,9 @@
<!-- Belgium: 4 digits, plus EU: http://www.mobileweb.be/en/mobileweb/sms-numberplan.asp -->
<shortcode country="be" premium="\\d{4}" free="8\\d{3}|116\\d{3}" />
+ <!-- Burkina Faso: 1-4 digits (standard system default, not country specific) -->
+ <shortcode country="bf" pattern="\\d{1,4}" free="3558" />
+
<!-- Bulgaria: 4-5 digits, plus EU -->
<shortcode country="bg" pattern="\\d{4,5}" premium="18(?:16|423)|19(?:1[56]|35)" free="116\\d{3}|1988|1490" />
@@ -175,8 +178,8 @@
<!-- Israel: 1-5 digits, known premium codes listed -->
<shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477|6681" />
- <!-- Iran: 4-6 digits, known premium codes listed -->
- <shortcode country="ir" pattern="\\d{4,6}" free="700791|700792" />
+ <!-- Iran: 4-8 digits, known premium codes listed -->
+ <shortcode country="ir" pattern="\\d{4,8}" free="700791|700792|100016|30008360" />
<!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU:
https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf -->
@@ -352,7 +355,7 @@
<shortcode country="za" pattern="\\d{1,5}" free="44136|30791|36056|33009" />
<!-- Yemen -->
- <shortcode country="ye" pattern="\\d{1,4}" free="5081" />
+ <shortcode country="ye" pattern="\\d{1,4}" free="5079" />
<!-- Zimbabwe -->
<shortcode country="zw" pattern="\\d{1,5}" free="33679" />
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index 99909a1..5a051ad 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -103,6 +103,7 @@
sdk_version: "core_platform",
test_suites: [
"device-tests",
+ "device-platinum-tests",
"automotive-tests",
],
diff --git a/core/tests/coretests/OWNERS b/core/tests/coretests/OWNERS
index b7e008b..b669e3b 100644
--- a/core/tests/coretests/OWNERS
+++ b/core/tests/coretests/OWNERS
@@ -3,3 +3,4 @@
per-file BinderTest.java = file:platform/frameworks/native:/libs/binder/OWNERS
per-file ParcelTest.java = file:platform/frameworks/native:/libs/binder/OWNERS
per-file SurfaceControlRegistryTests.java = file:/services/core/java/com/android/server/wm/OWNERS
+per-file VintfObjectTest.java = file:platform/system/libvintf:/OWNERS
diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java
index 6c8b69f..9767d67 100644
--- a/core/tests/coretests/src/android/os/BinderTest.java
+++ b/core/tests/coretests/src/android/os/BinderTest.java
@@ -20,6 +20,8 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.testng.Assert.assertThrows;
import android.platform.test.annotations.IgnoreUnderRavenwood;
@@ -27,6 +29,9 @@
import androidx.test.filters.SmallTest;
+import com.android.internal.os.BinderInternal;
+
+
import org.junit.Rule;
import org.junit.Test;
@@ -81,4 +86,27 @@
binder.setExtension(null);
assertNull(binder.getExtension());
}
+
+ @SmallTest
+ @Test(expected = java.lang.SecurityException.class)
+ public void testServiceManagerNativeSecurityException() throws RemoteException {
+ // Find the service manager
+ IServiceManager sServiceManager = ServiceManagerNative
+ .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
+
+ Binder binder = new Binder();
+ sServiceManager.addService("ValidName", binder,
+ anyBoolean(), anyInt());
+ }
+
+ @SmallTest
+ @Test(expected = java.lang.NullPointerException.class)
+ public void testServiceManagerNativeNullptrException() throws RemoteException {
+ // Find the service manager
+ IServiceManager sServiceManager = ServiceManagerNative
+ .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
+
+ sServiceManager.addService("ValidName", null,
+ anyBoolean(), anyInt());
+ }
}
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index f34b8fd..f81b31d 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -16,16 +16,25 @@
package android.os;
-import static org.junit.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
+
+import static java.util.stream.Collectors.toList;
import android.platform.test.annotations.IgnoreUnderRavenwood;
import android.platform.test.ravenwood.RavenwoodRule;
+import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.xml.sax.InputSource;
+
+import java.io.StringReader;
+import java.util.stream.Stream;
+
+import javax.xml.parsers.DocumentBuilderFactory;
@RunWith(AndroidJUnit4.class)
@IgnoreUnderRavenwood(blockedBy = VintfObject.class)
@@ -39,12 +48,26 @@
@Test
public void testReport() {
String[] xmls = VintfObject.report();
- assertTrue(xmls.length > 0);
- // From /system/manifest.xml
- assertTrue(String.join("", xmls).contains(
- "<manifest version=\"1.0\" type=\"framework\">"));
- // From /system/compatibility-matrix.xml
- assertTrue(String.join("", xmls).contains(
- "<compatibility-matrix version=\"1.0\" type=\"framework\""));
+
+ assertThat(Stream.of(xmls).map(xml -> rootAndType(xml)).collect(toList()))
+ .containsExactly(
+ Pair.create("manifest", "framework"),
+ Pair.create("compatibility-matrix", "framework"),
+ Pair.create("manifest", "device"),
+ Pair.create("compatibility-matrix", "device")
+ );
+ }
+
+ private static Pair<String, String> rootAndType(String content) {
+ try {
+ var factory = DocumentBuilderFactory.newInstance();
+ var builder = factory.newDocumentBuilder();
+ var inputSource = new InputSource(new StringReader(content));
+ var document = builder.parse(inputSource);
+ var root = document.getDocumentElement();
+ return Pair.create(root.getTagName(), root.getAttribute("type"));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/keystore/OWNERS b/keystore/OWNERS
index 913f655..6891777 100644
--- a/keystore/OWNERS
+++ b/keystore/OWNERS
@@ -1,4 +1,5 @@
# Bug component: 189335
+drysdale@google.com
eranm@google.com
jbires@google.com
swillden@google.com
diff --git a/keystore/java/android/security/AndroidProtectedConfirmation.java b/keystore/java/android/security/AndroidProtectedConfirmation.java
index 268e0a5..dfe485a 100644
--- a/keystore/java/android/security/AndroidProtectedConfirmation.java
+++ b/keystore/java/android/security/AndroidProtectedConfirmation.java
@@ -59,10 +59,6 @@
/**
* Requests keystore call into the confirmationui HAL to display a prompt.
- * @deprecated Android Protected Confirmation had a low adoption rate among Android device
- * makers and developers alike. Given the lack of devices supporting the
- * feature, it is deprecated. Developers can use auth-bound Keystore keys
- * as a partial replacement.
*
* @param listener the binder to use for callbacks.
* @param promptText the prompt to display.
@@ -72,7 +68,6 @@
* @return one of the {@code CONFIRMATIONUI_*} constants, for
* example {@code KeyStore.CONFIRMATIONUI_OK}.
*/
- @Deprecated
public int presentConfirmationPrompt(IConfirmationCallback listener, String promptText,
byte[] extraData, String locale, int uiOptionsAsFlags) {
try {
@@ -89,16 +84,11 @@
/**
* Requests keystore call into the confirmationui HAL to cancel displaying a prompt.
- * @deprecated Android Protected Confirmation had a low adoption rate among Android device
- * makers and developers alike. Given the lack of devices supporting the
- * feature, it is deprecated. Developers can use auth-bound Keystore keys
- * as a partial replacement.
*
* @param listener the binder passed to the {@link #presentConfirmationPrompt} method.
* @return one of the {@code CONFIRMATIONUI_*} constants, for
* example {@code KeyStore.CONFIRMATIONUI_OK}.
*/
- @Deprecated
public int cancelConfirmationPrompt(IConfirmationCallback listener) {
try {
getService().cancelPrompt(listener);
@@ -113,14 +103,9 @@
/**
* Requests keystore to check if the confirmationui HAL is available.
- * @deprecated Android Protected Confirmation had a low adoption rate among Android device
- * makers and developers alike. Given the lack of devices supporting the
- * feature, it is deprecated. Developers can use auth-bound Keystore keys
- * as a partial replacement.
*
* @return whether the confirmationUI HAL is available.
*/
- @Deprecated
public boolean isConfirmationPromptSupported() {
try {
return getService().isSupported();
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index d359a90..3cff915 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -1149,6 +1149,8 @@
/**
* Sets the serial number used for the certificate of the generated key pair.
+ * To ensure compatibility with devices and certificate parsers, the value
+ * should be 20 bytes or shorter (see RFC 5280 section 4.1.2.2).
*
* <p>By default, the serial number is {@code 1}.
*/
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS
new file mode 100644
index 0000000..3f3308c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/protolog/OWNERS
@@ -0,0 +1 @@
+include platform/development:/tools/winscope/OWNERS
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index af69b52..54a98c1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -1470,7 +1470,7 @@
public void setHomeTransitionListener(IHomeTransitionListener listener) {
executeRemoteCallWithTaskPermission(mTransitions, "setHomeTransitionListener",
(transitions) -> {
- transitions.mHomeTransitionObserver.setHomeTransitionListener(mTransitions,
+ transitions.mHomeTransitionObserver.setHomeTransitionListener(transitions,
listener);
});
}
diff --git a/libs/WindowManager/Shell/tests/flicker/service/Android.bp b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
index 4f1a68a..a5bc261 100644
--- a/libs/WindowManager/Shell/tests/flicker/service/Android.bp
+++ b/libs/WindowManager/Shell/tests/flicker/service/Android.bp
@@ -65,6 +65,10 @@
package_name: "com.android.wm.shell.flicker.service",
instrumentation_target_package: "com.android.wm.shell.flicker.service",
test_config_template: "AndroidTestTemplate.xml",
+ test_suites: [
+ "device-tests",
+ "device-platinum-tests",
+ ],
srcs: [":WMShellFlickerServicePlatinumTests-src"],
static_libs: ["WMShellFlickerTestsBase"],
data: ["trace_config/*"],
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 68befff..e618245 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -926,8 +926,8 @@
//printf("USING Zip '%s'\n", pEntry->getFileName());
- if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, NULL, NULL,
- NULL, NULL))
+ if (!pZipFile->getEntryInfo(entry, &method, &uncompressedLen, nullptr, nullptr,
+ nullptr, nullptr, nullptr))
{
ALOGW("getEntryInfo failed\n");
return NULL;
diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
index 839c7b6..10651cd 100644
--- a/libs/androidfw/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -119,14 +119,6 @@
* appear to be bogus.
*/
bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
- uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
- uint32_t* pModWhen, uint32_t* pCrc32) const
-{
- return getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset, pModWhen,
- pCrc32, nullptr);
-}
-
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const
{
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index f7c5007..0f3f19c 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -147,10 +147,6 @@
* Returns "false" if "entry" is bogus or if the data in the Zip file
* appears to be bad.
*/
- bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,
- uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
- uint32_t* pCrc32) const;
-
bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod,
uint32_t* pUncompLen, uint32_t* pCompLen, off64_t* pOffset,
uint32_t* pModWhen, uint32_t* pCrc32, uint16_t* pExtraFieldSize) const;
diff --git a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
index 48c51af..61670e9 100644
--- a/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
+++ b/media/tests/AudioPolicyTest/src/com/android/audiopolicytest/AudioPolicyDeathTest.java
@@ -128,7 +128,7 @@
res.getInt(mContext.getResources().getString(R.string.status_key)));
});
- // Launch process registering a dynamic auido policy and dying after RECORD_TIME_MS ms
+ // Launch process registering a dynamic audio policy and dying after RECORD_TIME_MS ms
// RECORD_TIME_MS must be shorter than PLAYBACK_TIME_MS
Intent intent = new Intent(mContext, AudioPolicyDeathTestActivity.class);
intent.putExtra(mContext.getResources().getString(R.string.capture_duration_key),
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
index f03fc0a..0e40db6 100644
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ b/nfc/java/android/nfc/NfcActivityManager.java
@@ -195,16 +195,25 @@
Bundle extras) {
boolean isResumed;
Binder token;
+ int pollTech, listenTech;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
state.readerCallback = callback;
state.readerModeFlags = flags;
state.readerModeExtras = extras;
+ pollTech = state.mPollTech;
+ listenTech = state.mListenTech;
token = state.token;
isResumed = state.resumed;
}
if (isResumed) {
- setReaderMode(token, flags, extras);
+ if (listenTech != NfcAdapter.FLAG_USE_ALL_TECH
+ || pollTech != NfcAdapter.FLAG_USE_ALL_TECH) {
+ throw new IllegalStateException(
+ "Cannot be used when alternative DiscoveryTechnology is set");
+ } else {
+ setReaderMode(token, flags, extras);
+ }
}
}
@@ -385,15 +394,12 @@
boolean readerModeFlagsSet;
synchronized (NfcActivityManager.this) {
NfcActivityState state = getActivityState(activity);
- readerModeFlagsSet = state.readerModeFlags != 0;
state.mListenTech = NfcAdapter.FLAG_USE_ALL_TECH;
state.mPollTech = NfcAdapter.FLAG_USE_ALL_TECH;
token = state.token;
isResumed = state.resumed;
}
- if (readerModeFlagsSet) {
- disableReaderMode(activity);
- } else if (isResumed) {
+ if (isResumed) {
changeDiscoveryTech(token, NfcAdapter.FLAG_USE_ALL_TECH, NfcAdapter.FLAG_USE_ALL_TECH);
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 7e0a111..e1c18843 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -1846,10 +1846,7 @@
throw new UnsupportedOperationException();
}
}
- mNfcActivityManager.enableReaderMode(activity, null, pollTechnology, null);
- return;
- }
- if (pollTechnology == FLAG_READER_DISABLE) {
+ } else if (pollTechnology == FLAG_READER_DISABLE) {
synchronized (sLock) {
if (!sHasCeFeature) {
throw new UnsupportedOperationException();
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index 7cd2533..ea3fd0d 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -481,6 +482,7 @@
*
* @param frame A description of the polling frame.
*/
+ @SuppressLint("OnNameExpected")
@FlaggedApi(android.nfc.Flags.FLAG_NFC_READ_POLLING_LOOP)
public void processPollingFrames(@NonNull List<Bundle> frame) {
}
diff --git a/packages/DynamicSystemInstallationService/Android.bp b/packages/DynamicSystemInstallationService/Android.bp
index b8f54b3..ae69019 100644
--- a/packages/DynamicSystemInstallationService/Android.bp
+++ b/packages/DynamicSystemInstallationService/Android.bp
@@ -30,10 +30,6 @@
certificate: "platform",
privileged: true,
platform_apis: true,
-
- optimize: {
- enabled: false,
- },
}
java_library {
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
index 635dc42..5a530c4 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java
@@ -60,7 +60,6 @@
import android.os.image.DynamicSystemClient;
import android.os.image.DynamicSystemManager;
import android.text.TextUtils;
-import android.util.EventLog;
import android.util.Log;
import android.widget.Toast;
@@ -104,14 +103,6 @@
private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem";
private static final int NOTIFICATION_ID = 1;
- /*
- * Event log tags
- */
- private static final int EVENT_DSU_PROGRESS_UPDATE = 120000;
- private static final int EVENT_DSU_INSTALL_COMPLETE = 120001;
- private static final int EVENT_DSU_INSTALL_FAILED = 120002;
- private static final int EVENT_DSU_INSTALL_INSUFFICIENT_SPACE = 120003;
-
protected static void logEventProgressUpdate(
String partitionName,
long installedBytes,
@@ -119,8 +110,7 @@
int partitionNumber,
int totalPartitionNumber,
int totalProgressPercentage) {
- EventLog.writeEvent(
- EVENT_DSU_PROGRESS_UPDATE,
+ EventLogTags.writeDsuProgressUpdate(
partitionName,
installedBytes,
totalBytes,
@@ -130,15 +120,15 @@
}
protected static void logEventComplete() {
- EventLog.writeEvent(EVENT_DSU_INSTALL_COMPLETE);
+ EventLogTags.writeDsuInstallComplete();
}
protected static void logEventFailed(String cause) {
- EventLog.writeEvent(EVENT_DSU_INSTALL_FAILED, cause);
+ EventLogTags.writeDsuInstallFailed(cause);
}
protected static void logEventInsufficientSpace() {
- EventLog.writeEvent(EVENT_DSU_INSTALL_INSUFFICIENT_SPACE);
+ EventLogTags.writeDsuInstallInsufficientSpace();
}
/*
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index bacab0f..00e17f5 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -602,6 +602,8 @@
<!-- Permission required for CTS test - CtsThreadNetworkTestCases -->
<uses-permission android:name="android.permission.THREAD_NETWORK_PRIVILEGED"/>
+ <!-- Permission required to access Thread network shell commands for testing -->
+ <uses-permission android:name="android.permission.THREAD_NETWORK_TESTING"/>
<!-- Permission required for CTS tests to enable/disable rate limiting toasts. -->
<uses-permission android:name="android.permission.MANAGE_TOAST_RATE_LIMITING" />
diff --git a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
index ee81813..0dd9275 100644
--- a/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
+++ b/packages/SoundPicker/src/com/android/soundpicker/RingtonePickerActivity.java
@@ -36,6 +36,7 @@
import android.os.UserManager;
import android.provider.MediaStore;
import android.provider.Settings;
+import android.text.Html;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
@@ -253,6 +254,9 @@
} else {
p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title);
}
+ } else {
+ // Make sure intents don't inject HTML elements.
+ p.mTitle = Html.escapeHtml(p.mTitle.toString());
}
setupAlert();
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 796e391..3a5ec92 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -4,7 +4,6 @@
dsandler@android.com
-aaronjli@google.com
achalke@google.com
acul@google.com
adamcohen@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 95f7c94a..73eeed8 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -619,6 +619,7 @@
private int mDreamingToLockscreenTransitionTranslationY;
private int mLockscreenToDreamingTransitionTranslationY;
private int mGoneToDreamingTransitionTranslationY;
+ private boolean mForceFlingAnimationForTest = false;
private SplitShadeStateController mSplitShadeStateController;
private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */);
@@ -2174,11 +2175,19 @@
}
}
});
+ if (!mScrimController.isScreenOn() && !mForceFlingAnimationForTest) {
+ animator.setDuration(1);
+ }
setAnimator(animator);
animator.start();
}
@VisibleForTesting
+ void setForceFlingAnimationForTest(boolean force) {
+ mForceFlingAnimationForTest = force;
+ }
+
+ @VisibleForTesting
void onFlingEnd(boolean cancelled) {
mIsFlinging = false;
// No overshoot when the animation ends
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index ae04eaf..dd42ba99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -1588,6 +1588,10 @@
mScreenOn = false;
}
+ public boolean isScreenOn() {
+ return mScreenOn;
+ }
+
public void setExpansionAffectsAlpha(boolean expansionAffectsAlpha) {
mExpansionAffectsAlpha = expansionAffectsAlpha;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 28fe8e4..c131c32 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -387,6 +387,7 @@
public void testOnTouchEvent_expansionResumesAfterBriefTouch() {
mFalsingManager.setIsClassifierEnabled(true);
mFalsingManager.setIsFalseTouch(false);
+ mNotificationPanelViewController.setForceFlingAnimationForTest(true);
// Start shade collapse with swipe up
onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
@@ -415,6 +416,7 @@
// fling should still be called after a touch that does not exceed touch slop
assertThat(mNotificationPanelViewController.isClosing()).isTrue();
assertThat(mNotificationPanelViewController.isFlinging()).isTrue();
+ mNotificationPanelViewController.setForceFlingAnimationForTest(false);
}
@Test
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index 7fcef9c..c0b354c 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -2373,7 +2373,7 @@
public Plane[] getPlanes() {
throwISEIfImageIsInvalid();
if (mPlanes == null) {
- int fenceFd = mParcelImage.fence != null ? mParcelImage.fence.getFd() : -1;
+ int fenceFd = mParcelImage.fence != null ? mParcelImage.fence.detachFd() : -1;
mGraphicBuffer = GraphicBuffer.createFromHardwareBuffer(mParcelImage.buffer);
mPlanes = ImageReader.initializeImagePlanes(mParcelImage.planeCount, mGraphicBuffer,
fenceFd, mParcelImage.format, mParcelImage.timestamp,
diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS
index 41fd68e..a90328c 100644
--- a/ravenwood/OWNERS
+++ b/ravenwood/OWNERS
@@ -2,4 +2,6 @@
jsharkey@google.com
omakoto@google.com
-jaggies@google.com
+
+per-file ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com
+per-file texts/ravenwood-annotation-allowed-classes.txt = dplotnikov@google.com
diff --git a/services/core/java/com/android/server/BootReceiver.java b/services/core/java/com/android/server/BootReceiver.java
index 9f279b1..23cee9d 100644
--- a/services/core/java/com/android/server/BootReceiver.java
+++ b/services/core/java/com/android/server/BootReceiver.java
@@ -34,6 +34,7 @@
import android.provider.Downloads;
import android.system.ErrnoException;
import android.system.Os;
+import android.system.OsConstants;
import android.text.TextUtils;
import android.util.AtomicFile;
import android.util.EventLog;
@@ -140,6 +141,10 @@
private static final int MAX_ERROR_REPORTS = 8;
private static int sSentReports = 0;
+ // Max tombstone file size to add to dropbox.
+ private static final long MAX_TOMBSTONE_SIZE_BYTES =
+ DropBoxManagerService.DEFAULT_QUOTA_KB * 1024;
+
@Override
public void onReceive(final Context context, Intent intent) {
// Log boot events in the background to avoid blocking the main thread with I/O
@@ -230,16 +235,23 @@
}
private static String getCurrentBootHeaders() throws IOException {
- return new StringBuilder(512)
- .append("Build: ").append(Build.FINGERPRINT).append("\n")
- .append("Hardware: ").append(Build.BOARD).append("\n")
- .append("Revision: ")
- .append(SystemProperties.get("ro.revision", "")).append("\n")
- .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
- .append("Radio: ").append(Build.getRadioVersion()).append("\n")
- .append("Kernel: ")
- .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"))
- .append("\n").toString();
+ StringBuilder builder = new StringBuilder(512)
+ .append("Build: ").append(Build.FINGERPRINT).append("\n")
+ .append("Hardware: ").append(Build.BOARD).append("\n")
+ .append("Revision: ")
+ .append(SystemProperties.get("ro.revision", "")).append("\n")
+ .append("Bootloader: ").append(Build.BOOTLOADER).append("\n")
+ .append("Radio: ").append(Build.getRadioVersion()).append("\n")
+ .append("Kernel: ")
+ .append(FileUtils.readTextFile(new File("/proc/version"), 1024, "...\n"));
+
+ // If device is not using 4KB pages, add the PageSize
+ long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+ if (pageSize != 4096) {
+ builder.append("PageSize: ").append(pageSize).append("\n");
+ }
+ builder.append("\n");
+ return builder.toString();
}
@@ -382,6 +394,12 @@
private static void addAugmentedProtoToDropbox(
File tombstone, DropBoxManager db,
DropboxRateLimiter.RateLimitResult rateLimitResult) throws IOException {
+ // Do not add proto files larger than 20Mb to DropBox as they can cause OOMs when
+ // processing large tombstones. The text tombstone is still added to DropBox.
+ if (tombstone.length() > MAX_TOMBSTONE_SIZE_BYTES) {
+ Slog.w(TAG, "Tombstone too large to add to DropBox: " + tombstone.toPath());
+ return;
+ }
// Read the proto tombstone file as bytes.
final byte[] tombstoneBytes = Files.readAllBytes(tombstone.toPath());
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index f82a6aa..70b3bde 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -106,7 +106,7 @@
private static final int DEFAULT_AGE_SECONDS = 3 * 86400;
private static final int DEFAULT_MAX_FILES = 1000;
private static final int DEFAULT_MAX_FILES_LOWRAM = 300;
- private static final int DEFAULT_QUOTA_KB = 10 * 1024;
+ public static final int DEFAULT_QUOTA_KB = Build.IS_USERDEBUG ? 20 * 1024 : 10 * 1024;
private static final int DEFAULT_QUOTA_PERCENT = 10;
private static final int DEFAULT_RESERVE_PERCENT = 0;
private static final int QUOTA_RESCAN_MILLIS = 5000;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index a619257..966478e 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -138,6 +138,12 @@
static final long DEFAULT_BOOT_LOOP_TRIGGER_WINDOW_MS = TimeUnit.MINUTES.toMillis(10);
+ // Time needed to apply mitigation
+ private static final String MITIGATION_WINDOW_MS =
+ "persist.device_config.configuration.mitigation_window_ms";
+ @VisibleForTesting
+ static final long DEFAULT_MITIGATION_WINDOW_MS = TimeUnit.SECONDS.toMillis(5);
+
// Threshold level at which or above user might experience significant disruption.
private static final String MAJOR_USER_IMPACT_LEVEL_THRESHOLD =
"persist.device_config.configuration.major_user_impact_level_threshold";
@@ -210,6 +216,9 @@
@GuardedBy("mLock")
private boolean mSyncRequired = false;
+ @GuardedBy("mLock")
+ private long mLastMitigation = -1000000;
+
@FunctionalInterface
@VisibleForTesting
interface SystemClock {
@@ -400,6 +409,16 @@
Slog.w(TAG, "Could not resolve a list of failing packages");
return;
}
+ synchronized (mLock) {
+ final long now = mSystemClock.uptimeMillis();
+ if (Flags.recoverabilityDetection()) {
+ if (now >= mLastMitigation
+ && (now - mLastMitigation) < getMitigationWindowMs()) {
+ Slog.i(TAG, "Skipping onPackageFailure mitigation");
+ return;
+ }
+ }
+ }
mLongTaskHandler.post(() -> {
synchronized (mLock) {
if (mAllObservers.isEmpty()) {
@@ -500,10 +519,17 @@
int currentObserverImpact,
int mitigationCount) {
if (currentObserverImpact < getUserImpactLevelLimit()) {
+ synchronized (mLock) {
+ mLastMitigation = mSystemClock.uptimeMillis();
+ }
currentObserverToNotify.execute(versionedPackage, failureReason, mitigationCount);
}
}
+ private long getMitigationWindowMs() {
+ return SystemProperties.getLong(MITIGATION_WINDOW_MS, DEFAULT_MITIGATION_WINDOW_MS);
+ }
+
/**
* Called when the system server boots. If the system server is detected to be in a boot loop,
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 79620cf..1c1190f 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1638,7 +1638,13 @@
String gidStr = parser.getAttributeValue(null, "gid");
if (gidStr != null) {
int gid = Process.getGidForName(gidStr);
- perm.gids = appendInt(perm.gids, gid);
+ if (gid != -1) {
+ perm.gids = appendInt(perm.gids, gid);
+ } else {
+ Slog.w(TAG, "<group> with unknown gid \""
+ + gidStr + " for permission " + name + " in "
+ + parser.getPositionDescription());
+ }
} else {
Slog.w(TAG, "<group> without gid at "
+ parser.getPositionDescription());
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 28d840b..11e4a03 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -369,6 +369,8 @@
import android.provider.Settings;
import android.server.ServerProtoEnums;
import android.sysprop.InitProperties;
+import android.system.Os;
+import android.system.OsConstants;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.style.SuggestionSpan;
@@ -9618,6 +9620,13 @@
sb.append("ErrorId: ").append(errorId.toString()).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
+
+ // If device is not using 4KB pages, add the PageSize
+ long pageSize = Os.sysconf(OsConstants._SC_PAGESIZE);
+ if (pageSize != 4096) {
+ sb.append("PageSize: ").append(pageSize).append("\n");
+ }
+
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
}
diff --git a/services/core/java/com/android/server/dreams/OWNERS b/services/core/java/com/android/server/dreams/OWNERS
index 7302f6e..b9286f8 100644
--- a/services/core/java/com/android/server/dreams/OWNERS
+++ b/services/core/java/com/android/server/dreams/OWNERS
@@ -1,4 +1,3 @@
-brycelee@google.com
-dsandler@android.com
-michaelwr@google.com
-roosa@google.com
+# Bug component: 66910
+include /core/java/android/service/dreams/OWNERS
+
diff --git a/services/core/java/com/android/server/locales/OWNERS b/services/core/java/com/android/server/locales/OWNERS
index e1e946b..7e35dac 100644
--- a/services/core/java/com/android/server/locales/OWNERS
+++ b/services/core/java/com/android/server/locales/OWNERS
@@ -1,5 +1,4 @@
roosa@google.com
-pratyushmore@google.com
goldmanj@google.com
ankitavyas@google.com
allenwtsu@google.com
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ba99d2e..1ad0abf 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -581,7 +581,7 @@
public RebootEscrowManager getRebootEscrowManager(RebootEscrowManager.Callbacks callbacks,
LockSettingsStorage storage) {
return new RebootEscrowManager(mContext, callbacks, storage,
- getHandler(getServiceThread()));
+ getHandler(getServiceThread()), getUserManagerInternal());
}
public int binderGetCallingUid() {
@@ -724,12 +724,13 @@
!mUserManager.isQuietModeEnabled(userHandle)) {
// Only show notifications for managed profiles once their parent
// user is unlocked.
- showEncryptionNotificationForProfile(userHandle, reason);
+ showEncryptionNotificationForProfile(userHandle, parent.getUserHandle(), reason);
}
}
}
- private void showEncryptionNotificationForProfile(UserHandle user, String reason) {
+ private void showEncryptionNotificationForProfile(UserHandle user, UserHandle parent,
+ String reason) {
CharSequence title = getEncryptionNotificationTitle();
CharSequence message = getEncryptionNotificationMessage();
CharSequence detail = getEncryptionNotificationDetail();
@@ -746,8 +747,15 @@
unlockIntent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- PendingIntent intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ PendingIntent intent;
+ if (android.app.admin.flags.Flags.hsumUnlockNotificationFix()) {
+ intent = PendingIntent.getActivityAsUser(mContext, 0, unlockIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED,
+ null, parent);
+ } else {
+ intent = PendingIntent.getActivity(mContext, 0, unlockIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ }
Slogf.d(TAG, "Showing encryption notification for user %d; reason: %s",
user.getIdentifier(), reason);
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index e1cd2c5..d0b8990 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -51,16 +51,20 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.widget.RebootEscrowListener;
+import com.android.server.pm.UserManagerInternal;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
+import java.util.Set;
import javax.crypto.SecretKey;
@@ -138,6 +142,7 @@
ERROR_KEYSTORE_FAILURE,
ERROR_NO_NETWORK,
ERROR_TIMEOUT_EXHAUSTED,
+ ERROR_NO_REBOOT_ESCROW_DATA,
})
@Retention(RetentionPolicy.SOURCE)
@interface RebootEscrowErrorCode {
@@ -153,6 +158,7 @@
static final int ERROR_KEYSTORE_FAILURE = 7;
static final int ERROR_NO_NETWORK = 8;
static final int ERROR_TIMEOUT_EXHAUSTED = 9;
+ static final int ERROR_NO_REBOOT_ESCROW_DATA = 10;
private @RebootEscrowErrorCode int mLoadEscrowDataErrorCode = ERROR_NONE;
@@ -222,11 +228,16 @@
private final RebootEscrowKeyStoreManager mKeyStoreManager;
private final LockSettingsStorage mStorage;
private RebootEscrowProviderInterface mRebootEscrowProvider;
+ private final UserManagerInternal mUserManagerInternal;
- Injector(Context context, LockSettingsStorage storage) {
+ Injector(
+ Context context,
+ LockSettingsStorage storage,
+ UserManagerInternal userManagerInternal) {
mContext = context;
mStorage = storage;
mKeyStoreManager = new RebootEscrowKeyStoreManager();
+ mUserManagerInternal = userManagerInternal;
}
private RebootEscrowProviderInterface createRebootEscrowProvider() {
@@ -326,6 +337,10 @@
return (UserManager) mContext.getSystemService(Context.USER_SERVICE);
}
+ public UserManagerInternal getUserManagerInternal() {
+ return mUserManagerInternal;
+ }
+
public RebootEscrowKeyStoreManager getKeyStoreManager() {
return mKeyStoreManager;
}
@@ -402,8 +417,8 @@
}
RebootEscrowManager(Context context, Callbacks callbacks, LockSettingsStorage storage,
- Handler handler) {
- this(new Injector(context, storage), callbacks, storage, handler);
+ Handler handler, UserManagerInternal userManagerInternal) {
+ this(new Injector(context, storage, userManagerInternal), callbacks, storage, handler);
}
@VisibleForTesting
@@ -451,18 +466,50 @@
onEscrowRestoreComplete(false, attemptCount, retryHandler);
}
- void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
- List<UserInfo> users = mUserManager.getUsers();
- List<UserInfo> rebootEscrowUsers = new ArrayList<>();
+ private List<UserInfo> getUsersToUnlock(List<UserInfo> users) {
+ // System user must be unlocked to unlock any other user
+ if (mCallbacks.isUserSecure(USER_SYSTEM) && !mStorage.hasRebootEscrow(USER_SYSTEM)) {
+ Slog.i(TAG, "No reboot escrow data found for system user");
+ return Collections.emptyList();
+ }
+
+ Set<Integer> noEscrowDataUsers = new HashSet<>();
for (UserInfo user : users) {
- if (mCallbacks.isUserSecure(user.id) && mStorage.hasRebootEscrow(user.id)) {
- rebootEscrowUsers.add(user);
+ if (mCallbacks.isUserSecure(user.id)
+ && !mStorage.hasRebootEscrow(user.id)) {
+ Slog.d(TAG, "No reboot escrow data found for user " + user);
+ noEscrowDataUsers.add(user.id);
}
}
+ List<UserInfo> rebootEscrowUsers = new ArrayList<>();
+ for (UserInfo user : users) {
+ // No lskf, no need to unlock.
+ if (!mCallbacks.isUserSecure(user.id)) {
+ continue;
+ }
+ // Don't unlock if user or user's parent does not have reboot data
+ int userId = user.id;
+ if (noEscrowDataUsers.contains(userId)
+ || noEscrowDataUsers.contains(
+ mInjector.getUserManagerInternal().getProfileParentId(userId))) {
+ continue;
+ }
+ rebootEscrowUsers.add(user);
+ }
+ return rebootEscrowUsers;
+ }
+
+ void loadRebootEscrowDataIfAvailable(Handler retryHandler) {
+ List<UserInfo> users = mUserManager.getUsers();
+ List<UserInfo> rebootEscrowUsers = getUsersToUnlock(users);
+
if (rebootEscrowUsers.isEmpty()) {
Slog.i(TAG, "No reboot escrow data found for users,"
+ " skipping loading escrow data");
+ setLoadEscrowDataErrorCode(ERROR_NO_REBOOT_ESCROW_DATA, retryHandler);
+ reportMetricOnRestoreComplete(
+ /* success= */ false, /* attemptCount= */ 1, retryHandler);
clearMetricsStorage();
return;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4d05c36..4e029fd 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2291,7 +2291,7 @@
@VisibleForTesting
void clearNotifications() {
- synchronized (mNotificationList) {
+ synchronized (mNotificationLock) {
mEnqueuedNotifications.clear();
mNotificationList.clear();
mNotificationsByKey.clear();
@@ -2301,21 +2301,27 @@
@VisibleForTesting
void addNotification(NotificationRecord r) {
- mNotificationList.add(r);
- mNotificationsByKey.put(r.getSbn().getKey(), r);
- if (r.getSbn().isGroup()) {
- mSummaryByGroupKey.put(r.getGroupKey(), r);
+ synchronized (mNotificationLock) {
+ mNotificationList.add(r);
+ mNotificationsByKey.put(r.getSbn().getKey(), r);
+ if (r.getSbn().isGroup()) {
+ mSummaryByGroupKey.put(r.getGroupKey(), r);
+ }
}
}
@VisibleForTesting
void addEnqueuedNotification(NotificationRecord r) {
- mEnqueuedNotifications.add(r);
+ synchronized (mNotificationLock) {
+ mEnqueuedNotifications.add(r);
+ }
}
@VisibleForTesting
NotificationRecord getNotificationRecord(String key) {
- return mNotificationsByKey.get(key);
+ synchronized (mNotificationLock) {
+ return mNotificationsByKey.get(key);
+ }
}
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index dc0cf4e..017a96e 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -66,7 +66,7 @@
+ " disallow_listener COMPONENT [user_id (current user if not specified)]\n"
+ " allow_assistant COMPONENT [user_id (current user if not specified)]\n"
+ " remove_assistant COMPONENT [user_id (current user if not specified)]\n"
- + " set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]"
+ + " set_dnd [on|none (same as on)|priority|alarms|all|off (same as all)]\n"
+ " allow_dnd PACKAGE [user_id (current user if not specified)]\n"
+ " disallow_dnd PACKAGE [user_id (current user if not specified)]\n"
+ " reset_assistant_user_set [user_id (current user if not specified)]\n"
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index f6e7ef3..3bcaf58 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -56,6 +56,7 @@
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.lang.ref.Reference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Optional;
@@ -73,6 +74,9 @@
private final Context mContext;
private final Handler mHandler;
+ // TODO(b/339371242): The garbage collector is misbehaving, and we must have
+ // a reference to this member outside the constructor. More details in the
+ // corresponding comment elsewhere in this class.
private final TombstoneWatcher mWatcher;
private final ReentrantLock mTmpFileLock = new ReentrantLock();
@@ -139,6 +143,14 @@
processName = parsedTombstone.get().getProcessName();
}
BootReceiver.addTombstoneToDropBox(mContext, path, isProtoFile, processName, mTmpFileLock);
+
+ // TODO(b/339371242): An optimizer on WearOS is misbehaving and this member is being garbage
+ // collected as it's never referenced inside this class outside of the constructor. But,
+ // it's a file watcher, and needs to stay alive to do its job. So, add a cheap check here to
+ // force the GC to behave itself. From a technical perspective, it's possible that we need
+ // to add this trick to every single member function, but this seems to work correctly in
+ // practice and avoids polluting a lot more of this class.
+ Reference.reachabilityFence(mWatcher);
}
private Optional<TombstoneFile> handleProtoTombstone(File path, boolean addToList) {
diff --git a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
index 4eea8c6..8b286ad 100644
--- a/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
+++ b/services/core/java/com/android/server/power/stats/BatteryStatsImpl.java
@@ -3377,7 +3377,7 @@
}
return mTotalTimeUs + (mNesting > 0
? (curBatteryRealtimeUs - mUpdateTimeUs)
- / (mTimerPool != null ? mTimerPool.size() : 1)
+ / (mTimerPool != null && mTimerPool.size() > 0 ? mTimerPool.size() : 1)
: 0);
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index c8bcc51..e753ce8 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -926,7 +926,9 @@
}
Slog.i(TAG, "Enabling rollback for install of " + packageName
+ ", session:" + session.sessionId
- + ", rollbackDataPolicy=" + rollbackDataPolicy);
+ + ", rollbackDataPolicy=" + rollbackDataPolicy
+ + ", rollbackId:" + rollback.info.getRollbackId()
+ + ", originalSessionId:" + rollback.getOriginalSessionId());
final String installerPackageName = session.getInstallerPackageName();
if (!enableRollbackAllowed(installerPackageName, packageName)) {
diff --git a/services/core/java/com/android/server/tracing/TracingServiceProxy.java b/services/core/java/com/android/server/tracing/TracingServiceProxy.java
index c1d92cf..68eb8eb 100644
--- a/services/core/java/com/android/server/tracing/TracingServiceProxy.java
+++ b/services/core/java/com/android/server/tracing/TracingServiceProxy.java
@@ -93,6 +93,7 @@
private final Context mContext;
private final PackageManager mPackageManager;
private final LruCache<ComponentName, ServiceConnector<IMessenger>> mCachedReporterServices;
+ private boolean mServicePublished = false;
private final ITracingServiceProxy.Stub mTracingServiceProxy = new ITracingServiceProxy.Stub() {
/**
@@ -122,9 +123,12 @@
public void onStart() {}
@Override
- public void onBootPhase(int phase) {
- if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+ public void onUserUnlocking(@NonNull TargetUser user) {
+ // We need the device storage to be unlocked before we can accept and forward
+ // requests.
+ if (!mServicePublished) {
publishBinderService(TRACING_SERVICE_PROXY_BINDER_NAME, mTracingServiceProxy);
+ mServicePublished = true;
}
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
index 3cf19dd..dd53d32 100644
--- a/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
+++ b/services/core/java/com/android/server/wm/AccessibilityWindowsPopulator.java
@@ -561,32 +561,35 @@
}
void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.println("AccessibilityWindowsPopulator");
- String prefix2 = prefix + " ";
+ synchronized (mLock) {
+ pw.print(prefix); pw.println("AccessibilityWindowsPopulator");
+ String prefix2 = prefix + " ";
- pw.print(prefix2); pw.print("mWindowsNotificationEnabled: ");
- pw.println(mWindowsNotificationEnabled);
+ pw.print(prefix2); pw.print("mWindowsNotificationEnabled: ");
+ pw.println(mWindowsNotificationEnabled);
- if (mVisibleWindows.isEmpty()) {
- pw.print(prefix2); pw.println("No visible windows");
- } else {
- pw.print(prefix2); pw.print(mVisibleWindows.size());
- pw.print(" visible windows: "); pw.println(mVisibleWindows);
+ if (mVisibleWindows.isEmpty()) {
+ pw.print(prefix2); pw.println("No visible windows");
+ } else {
+ pw.print(prefix2); pw.print(mVisibleWindows.size());
+ pw.print(" visible windows: "); pw.println(mVisibleWindows);
+ }
+ KeyDumper noKeyDumper = (i, k) -> {}; // display id is already shown on value;
+ KeyDumper displayDumper = (i, d) -> pw.printf("%sDisplay #%d: ", prefix, d);
+ // Ideally magnificationSpecDumper should use spec.dump(pw), but there is no such method
+ ValueDumper<MagnificationSpec> magnificationSpecDumper = spec -> pw.print(spec);
+
+ dumpSparseArray(pw, prefix2, mDisplayInfos,
+ "display info", noKeyDumper, d -> pw.print(d));
+ dumpSparseArray(pw, prefix2, mInputWindowHandlesOnDisplays,
+ "window handles on display", displayDumper, list -> pw.print(list));
+ dumpSparseArray(pw, prefix2, mMagnificationSpecInverseMatrix,
+ "magnification spec matrix", noKeyDumper, matrix -> matrix.dump(pw));
+ dumpSparseArray(pw, prefix2, mCurrentMagnificationSpec,
+ "current magnification spec", noKeyDumper, magnificationSpecDumper);
+ dumpSparseArray(pw, prefix2, mPreviousMagnificationSpec,
+ "previous magnification spec", noKeyDumper, magnificationSpecDumper);
}
- KeyDumper noKeyDumper = (i, k) -> {}; // display id is already shown on value;
- KeyDumper displayDumper = (i, d) -> pw.printf("%sDisplay #%d: ", prefix, d);
- // Ideally magnificationSpecDumper should use spec.dump(pw), but there is no such method
- ValueDumper<MagnificationSpec> magnificationSpecDumper = spec -> pw.print(spec);
-
- dumpSparseArray(pw, prefix2, mDisplayInfos, "display info", noKeyDumper, d -> pw.print(d));
- dumpSparseArray(pw, prefix2, mInputWindowHandlesOnDisplays, "window handles on display",
- displayDumper, list -> pw.print(list));
- dumpSparseArray(pw, prefix2, mMagnificationSpecInverseMatrix, "magnification spec matrix",
- noKeyDumper, matrix -> matrix.dump(pw));
- dumpSparseArray(pw, prefix2, mCurrentMagnificationSpec, "current magnification spec",
- noKeyDumper, magnificationSpecDumper);
- dumpSparseArray(pw, prefix2, mPreviousMagnificationSpec, "previous magnification spec",
- noKeyDumper, magnificationSpecDumper);
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 4b0177a..f249cb0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2643,7 +2643,7 @@
// If a target task is specified, try to reuse that one
if (mOptions != null && mOptions.getLaunchTaskId() != INVALID_TASK_ID) {
Task launchTask = mRootWindowContainer.anyTaskForId(mOptions.getLaunchTaskId());
- if (launchTask != null) {
+ if (launchTask != null && launchTask.isLeafTask()) {
return launchTask;
}
return null;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 5d01912..76be8ae 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1257,10 +1257,13 @@
// In a multi-resumed environment, like in a freeform device, the top
// activity can be resumed, but it might not be the focused app.
- // Set focused app when top activity is resumed
- if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null
- && taskDisplayArea.mDisplayContent.mFocusedApp != next) {
- taskDisplayArea.mDisplayContent.setFocusedApp(next);
+ // Set focused app when top activity is resumed. However, we shouldn't do it for a
+ // same task because it can break focused state. (e.g. activity embedding)
+ if (taskDisplayArea.inMultiWindowMode() && taskDisplayArea.mDisplayContent != null) {
+ final ActivityRecord focusedApp = taskDisplayArea.mDisplayContent.mFocusedApp;
+ if (focusedApp == null || focusedApp.getTask() != next.getTask()) {
+ taskDisplayArea.mDisplayContent.setFocusedApp(next);
+ }
}
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Top activity "
+ "resumed %s", next);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
index 0e448cd..a1bf040 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NonRequiredPackageDeleteObserver.java
@@ -25,7 +25,6 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* Awaits the deletion of all the non-required apps.
@@ -33,38 +32,38 @@
final class NonRequiredPackageDeleteObserver extends IPackageDeleteObserver.Stub {
private static final int PACKAGE_DELETE_TIMEOUT_SEC = 30;
- private final AtomicInteger mPackageCount = new AtomicInteger(/* initialValue= */ 0);
private final CountDownLatch mLatch;
- private boolean mSuccess;
+ private boolean mFailed = false;
NonRequiredPackageDeleteObserver(int packageCount) {
this.mLatch = new CountDownLatch(packageCount);
- this.mPackageCount.set(packageCount);
}
@Override
public void packageDeleted(String packageName, int returnCode) {
if (returnCode != PackageManager.DELETE_SUCCEEDED) {
Slog.e(LOG_TAG, "Failed to delete package: " + packageName);
- mLatch.notifyAll();
- return;
- }
- int currentPackageCount = mPackageCount.decrementAndGet();
- if (currentPackageCount == 0) {
- mSuccess = true;
- Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
- + "and all disallowed apps have been uninstalled.");
+ mFailed = true;
}
mLatch.countDown();
}
public boolean awaitPackagesDeletion() {
try {
- mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS);
+ if (mLatch.await(PACKAGE_DELETE_TIMEOUT_SEC, TimeUnit.SECONDS)) {
+ if (!mFailed) {
+ Slog.i(LOG_TAG, "All non-required system apps with launcher icon, "
+ + "and all disallowed apps have been uninstalled.");
+ }
+ return !mFailed;
+ } else {
+ Slog.i(LOG_TAG, "Waiting time elapsed before all package deletion finished");
+ return false;
+ }
} catch (InterruptedException e) {
Log.w(LOG_TAG, "Interrupted while waiting for package deletion", e);
Thread.currentThread().interrupt();
+ return false;
}
- return mSuccess;
}
}
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 54d101a..cd70ed2 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -25,6 +25,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.Looper;
@@ -58,11 +59,13 @@
public final class ProfcollectForwardingService extends SystemService {
public static final String LOG_TAG = "ProfcollectForwardingService";
- private static final boolean DEBUG = Log.isLoggable(LOG_TAG, Log.DEBUG);
private static final String INTENT_UPLOAD_PROFILES =
"com.android.server.profcollect.UPLOAD_PROFILES";
private static final long BG_PROCESS_INTERVAL = TimeUnit.HOURS.toMillis(4); // every 4 hours.
+ private int mUsageSetting;
+ private boolean mUploadEnabled;
+
private IProfCollectd mIProfcollect;
private static ProfcollectForwardingService sSelfService;
private final Handler mHandler = new ProfcollectdHandler(IoThread.getHandler().getLooper());
@@ -78,7 +81,7 @@
public void onReceive(Context context, Intent intent) {
if (INTENT_UPLOAD_PROFILES.equals(intent.getAction())) {
Log.d(LOG_TAG, "Received broadcast to pack and upload reports");
- packAndUploadReport();
+ createAndUploadReport(sSelfService);
}
}
};
@@ -91,6 +94,17 @@
}
sSelfService = this;
+ // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for disabled.
+ try {
+ mUsageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb");
+ } catch (SettingNotFoundException e) {
+ Log.e(LOG_TAG, "Usage setting not found: " + e.getMessage());
+ mUsageSetting = -1;
+ }
+
+ mUploadEnabled =
+ context.getResources().getBoolean(R.bool.config_profcollectReportUploaderEnabled);
+
final IntentFilter filter = new IntentFilter();
filter.addAction(INTENT_UPLOAD_PROFILES);
context.registerReceiver(mBroadcastReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
@@ -106,9 +120,6 @@
@Override
public void onStart() {
- if (DEBUG) {
- Log.d(LOG_TAG, "Profcollect forwarding service start");
- }
connectNativeService();
}
@@ -221,7 +232,6 @@
*/
public static void schedule(Context context) {
JobScheduler js = context.getSystemService(JobScheduler.class);
-
js.schedule(new JobInfo.Builder(JOB_IDLE_PROCESS, JOB_SERVICE_NAME)
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
@@ -232,22 +242,7 @@
@Override
public boolean onStartJob(JobParameters params) {
- if (DEBUG) {
- Log.d(LOG_TAG, "Starting background process job");
- }
-
- BackgroundThread.get().getThreadHandler().post(
- () -> {
- try {
- if (sSelfService.mIProfcollect == null) {
- return;
- }
- sSelfService.mIProfcollect.process();
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to process profiles in background: "
- + e.getMessage());
- }
- });
+ createAndUploadReport(sSelfService);
jobFinished(params, false);
return true;
}
@@ -264,6 +259,7 @@
BackgroundThread.get().getThreadHandler().post(
() -> {
registerAppLaunchObserver();
+ registerCameraOpenObserver();
registerDex2oatObserver();
registerOTAObserver();
});
@@ -288,9 +284,6 @@
"applaunch_trace_freq", 2);
int randomNum = ThreadLocalRandom.current().nextInt(100);
if (randomNum < traceFrequency) {
- if (DEBUG) {
- Log.d(LOG_TAG, "Tracing on app launch event: " + packageName);
- }
BackgroundThread.get().getThreadHandler().post(() -> {
try {
mIProfcollect.trace_once("applaunch");
@@ -330,19 +323,14 @@
"dex2oat_trace_freq", 25);
int randomNum = ThreadLocalRandom.current().nextInt(100);
if (randomNum < traceFrequency) {
- if (DEBUG) {
- Log.d(LOG_TAG, "Tracing on dex2oat event");
- }
- BackgroundThread.get().getThreadHandler().post(() -> {
+ // Dex2oat could take a while before it starts. Add a short delay before start tracing.
+ BackgroundThread.get().getThreadHandler().postDelayed(() -> {
try {
- // Dex2oat could take a while before it starts. Add a short delay before start
- // tracing.
- Thread.sleep(1000);
mIProfcollect.trace_once("dex2oat");
- } catch (RemoteException | InterruptedException e) {
+ } catch (RemoteException e) {
Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
}
- });
+ }, 1000);
}
}
@@ -351,13 +339,8 @@
updateEngine.bind(new UpdateEngineCallback() {
@Override
public void onStatusUpdate(int status, float percent) {
- if (DEBUG) {
- Log.d(LOG_TAG, "Received OTA status update, status: " + status + ", percent: "
- + percent);
- }
-
if (status == UpdateEngine.UpdateStatusConstants.UPDATED_NEED_REBOOT) {
- packAndUploadReport();
+ createAndUploadReport(sSelfService);
}
}
@@ -368,41 +351,56 @@
});
}
- private void packAndUploadReport() {
- if (mIProfcollect == null) {
- return;
- }
-
- Context context = getContext();
+ private static void createAndUploadReport(ProfcollectForwardingService pfs) {
BackgroundThread.get().getThreadHandler().post(() -> {
+ String reportName;
try {
- int usageSetting = -1;
- try {
- // Get "Usage & diagnostics" checkbox status. 1 is for enabled, 0 is for
- // disabled.
- usageSetting = Settings.Global.getInt(context.getContentResolver(), "multi_cb");
- } catch (SettingNotFoundException e) {
- Log.i(LOG_TAG, "Usage setting not found: " + e.getMessage());
- }
+ reportName = pfs.mIProfcollect.report(pfs.mUsageSetting) + ".zip";
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Failed to create report: " + e.getMessage());
+ return;
+ }
+ if (!pfs.mUploadEnabled) {
+ Log.i(LOG_TAG, "Upload is not enabled.");
+ return;
+ }
+ Intent intent = new Intent()
+ .setPackage("com.android.shell")
+ .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
+ .putExtra("filename", reportName);
+ pfs.getContext().sendBroadcast(intent);
+ });
+ }
- // Prepare profile report
- String reportName = mIProfcollect.report(usageSetting) + ".zip";
-
- if (!context.getResources().getBoolean(
- R.bool.config_profcollectReportUploaderEnabled)) {
- Log.i(LOG_TAG, "Upload is not enabled.");
+ private void registerCameraOpenObserver() {
+ CameraManager cm = getContext().getSystemService(CameraManager.class);
+ cm.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() {
+ @Override
+ public void onCameraOpened(String cameraId, String packageId) {
+ Log.d(LOG_TAG, "Received camera open event from: " + packageId);
+ // Skip face auth and Android System Intelligence, since they trigger way too
+ // often.
+ if (packageId.startsWith("client.pid")
+ || packageId.equals("com.google.android.as")) {
return;
}
-
- // Upload the report
- Intent intent = new Intent()
- .setPackage("com.android.shell")
- .setAction("com.android.shell.action.PROFCOLLECT_UPLOAD")
- .putExtra("filename", reportName);
- context.sendBroadcast(intent);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Failed to upload report: " + e.getMessage());
+ // Sample for a fraction of camera events.
+ final int traceFrequency =
+ DeviceConfig.getInt(DeviceConfig.NAMESPACE_PROFCOLLECT_NATIVE_BOOT,
+ "camera_trace_freq", 10);
+ int randomNum = ThreadLocalRandom.current().nextInt(100);
+ if (randomNum >= traceFrequency) {
+ return;
+ }
+ // Wait for 1s before starting tracing.
+ BackgroundThread.get().getThreadHandler().postDelayed(() -> {
+ try {
+ mIProfcollect.trace_once("camera");
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Failed to initiate trace: " + e.getMessage());
+ }
+ }, 1000);
}
- });
+ }, null);
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
index 72c0a9e..2cbc226 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/am/OWNERS
@@ -1 +1,3 @@
include /services/core/java/com/android/server/am/OWNERS
+
+per-file ApplicationStartInfoTest.java = yforta@google.com, carmenjackson@google.com, jji@google.com
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
index 64e6236..17b499e 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -19,6 +19,7 @@
import static android.content.pm.UserInfo.FLAG_FULL;
import static android.content.pm.UserInfo.FLAG_PRIMARY;
import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.NO_PROFILE_GROUP_ID;
import static android.os.UserHandle.USER_SYSTEM;
import static com.android.internal.widget.LockSettingsInternal.ARM_REBOOT_ERROR_ESCROW_NOT_READY;
@@ -32,6 +33,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyByte;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
@@ -65,6 +67,7 @@
import com.android.internal.widget.RebootEscrowListener;
import com.android.server.locksettings.ResumeOnRebootServiceProvider.ResumeOnRebootServiceConnection;
+import com.android.server.pm.UserManagerInternal;
import org.junit.Before;
import org.junit.Test;
@@ -107,6 +110,7 @@
private Context mContext;
private UserManager mUserManager;
+ private UserManagerInternal mUserManagerInternal;
private RebootEscrowManager.Callbacks mCallbacks;
private IRebootEscrow mRebootEscrow;
private ResumeOnRebootServiceConnection mServiceConnection;
@@ -126,13 +130,15 @@
long getCurrentTimeMillis();
void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
- int escrowDurationInSeconds, int vbmetaDigestStatus, int durationSinceBootComplete);
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootComplete);
}
static class MockInjector extends RebootEscrowManager.Injector {
private final IRebootEscrow mRebootEscrow;
private final RebootEscrowProviderInterface mDefaultRebootEscrowProvider;
private final UserManager mUserManager;
+ private final UserManagerInternal mUserManagerInternal;
private final MockableRebootEscrowInjected mInjected;
private final RebootEscrowKeyStoreManager mKeyStoreManager;
private boolean mServerBased;
@@ -141,12 +147,16 @@
private Consumer<ConnectivityManager.NetworkCallback> mNetworkConsumer;
private boolean mWaitForInternet;
- MockInjector(Context context, UserManager userManager,
+ MockInjector(
+ Context context,
+ UserManager userManager,
+ UserManagerInternal userManagerInternal,
IRebootEscrow rebootEscrow,
RebootEscrowKeyStoreManager keyStoreManager,
LockSettingsStorageTestable storage,
MockableRebootEscrowInjected injected) {
- super(context, storage);
+ // TODO: change this
+ super(context, storage, userManagerInternal);
mRebootEscrow = rebootEscrow;
mServerBased = false;
mWaitForInternet = false;
@@ -159,16 +169,20 @@
};
mDefaultRebootEscrowProvider = new RebootEscrowProviderHalImpl(halInjector);
mUserManager = userManager;
+ mUserManagerInternal = userManagerInternal;
mKeyStoreManager = keyStoreManager;
mInjected = injected;
}
- MockInjector(Context context, UserManager userManager,
+ MockInjector(
+ Context context,
+ UserManager userManager,
+ UserManagerInternal userManagerInternal,
ResumeOnRebootServiceConnection serviceConnection,
RebootEscrowKeyStoreManager keyStoreManager,
LockSettingsStorageTestable storage,
MockableRebootEscrowInjected injected) {
- super(context, storage);
+ super(context, storage, userManagerInternal);
mRebootEscrow = null;
mServerBased = true;
mWaitForInternet = false;
@@ -187,6 +201,7 @@
mDefaultRebootEscrowProvider = new RebootEscrowProviderServerBasedImpl(
storage, injector);
mUserManager = userManager;
+ mUserManagerInternal = userManagerInternal;
mKeyStoreManager = keyStoreManager;
mInjected = injected;
}
@@ -202,6 +217,11 @@
}
@Override
+ public UserManagerInternal getUserManagerInternal() {
+ return mUserManagerInternal;
+ }
+
+ @Override
public boolean serverBasedResumeOnReboot() {
return mServerBased;
}
@@ -289,8 +309,8 @@
@Override
public void reportMetric(boolean success, int errorCode, int serviceType, int attemptCount,
- int escrowDurationInSeconds, int vbmetaDigestStatus,
- int durationSinceBootComplete) {
+ int escrowDurationInSeconds, int vbmetaDigestStatus,
+ int durationSinceBootComplete) {
mInjected.reportMetric(success, errorCode, serviceType, attemptCount,
escrowDurationInSeconds, vbmetaDigestStatus, durationSinceBootComplete);
@@ -301,6 +321,7 @@
public void setUp_baseServices() throws Exception {
mContext = new ContextWrapper(InstrumentationRegistry.getContext());
mUserManager = mock(UserManager.class);
+ mUserManagerInternal = mock(UserManagerInternal.class);
mCallbacks = mock(RebootEscrowManager.Callbacks.class);
mRebootEscrow = mock(IRebootEscrow.class);
mServiceConnection = mock(ResumeOnRebootServiceConnection.class);
@@ -314,28 +335,43 @@
new File(InstrumentationRegistry.getContext().getFilesDir(), "locksettings"));
ArrayList<UserInfo> users = new ArrayList<>();
- users.add(new UserInfo(PRIMARY_USER_ID, "primary", FLAG_PRIMARY));
- users.add(new UserInfo(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE));
- users.add(new UserInfo(NONSECURE_SECONDARY_USER_ID, "non-secure", FLAG_FULL));
- users.add(new UserInfo(SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL));
+ users.add(createUser(PRIMARY_USER_ID, "primary", FLAG_PRIMARY, PRIMARY_USER_ID));
+ users.add(createUser(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE, PRIMARY_USER_ID));
+ users.add(
+ createUser(
+ NONSECURE_SECONDARY_USER_ID, "non-secure", FLAG_FULL, NO_PROFILE_GROUP_ID));
+ users.add(createUser(SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL, NO_PROFILE_GROUP_ID));
when(mUserManager.getUsers()).thenReturn(users);
when(mCallbacks.isUserSecure(PRIMARY_USER_ID)).thenReturn(true);
when(mCallbacks.isUserSecure(WORK_PROFILE_USER_ID)).thenReturn(true);
when(mCallbacks.isUserSecure(NONSECURE_SECONDARY_USER_ID)).thenReturn(false);
when(mCallbacks.isUserSecure(SECURE_SECONDARY_USER_ID)).thenReturn(true);
mInjected = mock(MockableRebootEscrowInjected.class);
- mMockInjector = new MockInjector(mContext, mUserManager, mRebootEscrow,
- mKeyStoreManager, mStorage, mInjected);
+ mMockInjector =
+ new MockInjector(
+ mContext,
+ mUserManager,
+ mUserManagerInternal,
+ mRebootEscrow,
+ mKeyStoreManager,
+ mStorage,
+ mInjected);
HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
thread.start();
mHandler = new Handler(thread.getLooper());
mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage, mHandler);
-
}
private void setServerBasedRebootEscrowProvider() throws Exception {
- mMockInjector = new MockInjector(mContext, mUserManager, mServiceConnection,
- mKeyStoreManager, mStorage, mInjected);
+ mMockInjector =
+ new MockInjector(
+ mContext,
+ mUserManager,
+ mUserManagerInternal,
+ mServiceConnection,
+ mKeyStoreManager,
+ mStorage,
+ mInjected);
mService = new RebootEscrowManager(mMockInjector, mCallbacks, mStorage, mHandler);
}
@@ -352,6 +388,12 @@
waitForHandler();
}
+ private UserInfo createUser(int id, String name, int flag, int profileGroupId) {
+ UserInfo user = new UserInfo(id, name, flag);
+ when(mUserManagerInternal.getProfileParentId(eq(id))).thenReturn(profileGroupId);
+ return user;
+ }
+
@Test
public void prepareRebootEscrow_Success() throws Exception {
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
@@ -559,6 +601,172 @@
}
@Test
+ public void loadRebootEscrowDataIfAvailable_noDataPrimaryUser_Failure() throws Exception {
+ setServerBasedRebootEscrowProvider();
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+
+ // escrow secondary user, don't escrow primary user
+ callToRebootEscrowIfNeededAndWait(SECURE_SECONDARY_USER_ID);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+
+ assertTrue(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID));
+ assertFalse(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<Integer> metricsErrorCodeCaptor = ArgumentCaptor.forClass(Integer.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ metricsErrorCodeCaptor.capture(),
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+ mService.loadRebootEscrowDataIfAvailable(null);
+ verify(mServiceConnection, never()).unwrap(any(), anyLong());
+ verify(mCallbacks, never()).onRebootEscrowRestored(anyByte(), any(), anyInt());
+ assertFalse(metricsSuccessCaptor.getValue());
+ assertEquals(
+ Integer.valueOf(RebootEscrowManager.ERROR_NO_REBOOT_ESCROW_DATA),
+ metricsErrorCodeCaptor.getValue());
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_noDataSecondaryUser_Success() throws Exception {
+ setServerBasedRebootEscrowProvider();
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+
+ // Setup work profile with secondary user as parent.
+ ArrayList<UserInfo> users = new ArrayList<>();
+ users.add(createUser(PRIMARY_USER_ID, "primary", FLAG_PRIMARY, NO_PROFILE_GROUP_ID));
+ users.add(createUser(WORK_PROFILE_USER_ID, "work", FLAG_PROFILE, SECURE_SECONDARY_USER_ID));
+ users.add(
+ createUser(
+ SECURE_SECONDARY_USER_ID, "secure", FLAG_FULL, SECURE_SECONDARY_USER_ID));
+ when(mUserManager.getUsers()).thenReturn(users);
+
+ // escrow primary user and work profile, don't escrow secondary user
+ callToRebootEscrowIfNeededAndWait(PRIMARY_USER_ID);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+ callToRebootEscrowIfNeededAndWait(WORK_PROFILE_USER_ID);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+
+ assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
+ assertFalse(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID));
+ assertTrue(mStorage.hasRebootEscrow(WORK_PROFILE_USER_ID));
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ eq(0) /* error code */,
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+ when(mServiceConnection.unwrap(any(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+
+ mService.loadRebootEscrowDataIfAvailable(null);
+
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(PRIMARY_USER_ID));
+ verify(mCallbacks, never())
+ .onRebootEscrowRestored(anyByte(), any(), eq(SECURE_SECONDARY_USER_ID));
+ verify(mCallbacks, never())
+ .onRebootEscrowRestored(anyByte(), any(), eq(WORK_PROFILE_USER_ID));
+ verify(mCallbacks, never())
+ .onRebootEscrowRestored(anyByte(), any(), eq(NONSECURE_SECONDARY_USER_ID));
+ assertTrue(metricsSuccessCaptor.getValue());
+ }
+
+ @Test
+ public void loadRebootEscrowDataIfAvailable_noDataWorkProfile_Success() throws Exception {
+ setServerBasedRebootEscrowProvider();
+ RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
+ mService.setRebootEscrowListener(mockListener);
+ mService.prepareRebootEscrow();
+
+ clearInvocations(mServiceConnection);
+
+ // escrow primary user and secondary user, don't escrow work profile
+ callToRebootEscrowIfNeededAndWait(PRIMARY_USER_ID);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+ callToRebootEscrowIfNeededAndWait(SECURE_SECONDARY_USER_ID);
+ verify(mockListener).onPreparedForReboot(eq(true));
+ verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
+
+ when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+ assertEquals(ARM_REBOOT_ERROR_NONE, mService.armRebootEscrowIfNeeded());
+ verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
+
+ assertTrue(mStorage.hasRebootEscrow(PRIMARY_USER_ID));
+ assertTrue(mStorage.hasRebootEscrow(SECURE_SECONDARY_USER_ID));
+ assertFalse(mStorage.hasRebootEscrow(WORK_PROFILE_USER_ID));
+ assertTrue(mStorage.hasRebootEscrowServerBlob());
+
+ // pretend reboot happens here
+ when(mInjected.getBootCount()).thenReturn(1);
+ ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
+ doNothing()
+ .when(mInjected)
+ .reportMetric(
+ metricsSuccessCaptor.capture(),
+ eq(0) /* error code */,
+ eq(2) /* Server based */,
+ eq(1) /* attempt count */,
+ anyInt(),
+ eq(0) /* vbmeta status */,
+ anyInt());
+ when(mServiceConnection.unwrap(any(), anyLong()))
+ .thenAnswer(invocation -> invocation.getArgument(0));
+
+ mService.loadRebootEscrowDataIfAvailable(null);
+
+ verify(mServiceConnection).unwrap(any(), anyLong());
+ verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(PRIMARY_USER_ID));
+ verify(mCallbacks).onRebootEscrowRestored(anyByte(), any(), eq(SECURE_SECONDARY_USER_ID));
+ verify(mCallbacks, never())
+ .onRebootEscrowRestored(anyByte(), any(), eq(WORK_PROFILE_USER_ID));
+ verify(mCallbacks, never())
+ .onRebootEscrowRestored(anyByte(), any(), eq(NONSECURE_SECONDARY_USER_ID));
+ assertTrue(metricsSuccessCaptor.getValue());
+ }
+
+ @Test
public void loadRebootEscrowDataIfAvailable_ServerBased_Success() throws Exception {
setServerBasedRebootEscrowProvider();
diff --git a/tests/BinderLeakTest/Android.bp b/tests/BinderLeakTest/Android.bp
index 78b0ede..3747d04 100644
--- a/tests/BinderLeakTest/Android.bp
+++ b/tests/BinderLeakTest/Android.bp
@@ -24,6 +24,9 @@
"androidx.test.rules",
"androidx.test.runner",
],
+ test_suites: [
+ "general-tests",
+ ],
}
// Built with target_sdk_version: current
diff --git a/tests/FlickerTests/IME/Android.bp b/tests/FlickerTests/IME/Android.bp
index 1141e5f..b10006f 100644
--- a/tests/FlickerTests/IME/Android.bp
+++ b/tests/FlickerTests/IME/Android.bp
@@ -38,6 +38,10 @@
defaults: ["FlickerTestsDefault"],
manifest: "AndroidManifest.xml",
test_config_template: "AndroidTestTemplate.xml",
+ test_suites: [
+ "device-tests",
+ "device-platinum-tests",
+ ],
srcs: ["src/**/*"],
static_libs: ["FlickerTestsBase"],
data: ["trace_config/*"],
@@ -55,6 +59,10 @@
defaults: ["FlickerTestsDefault"],
manifest: "AndroidManifest.xml",
test_config_template: "AndroidTestTemplate.xml",
+ test_suites: [
+ "device-tests",
+ "device-platinum-tests",
+ ],
srcs: [":FlickerTestsIme1-src"],
static_libs: [
"FlickerTestsBase",
diff --git a/tests/FlickerTests/Rotation/Android.bp b/tests/FlickerTests/Rotation/Android.bp
index 233a276..6a0d9ef 100644
--- a/tests/FlickerTests/Rotation/Android.bp
+++ b/tests/FlickerTests/Rotation/Android.bp
@@ -28,6 +28,10 @@
defaults: ["FlickerTestsDefault"],
manifest: "AndroidManifest.xml",
test_config_template: "AndroidTestTemplate.xml",
+ test_suites: [
+ "device-tests",
+ "device-platinum-tests",
+ ],
srcs: ["src/**/*"],
static_libs: ["FlickerTestsBase"],
data: ["trace_config/*"],
diff --git a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
index 3a2a3be..ae32bda 100644
--- a/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
+++ b/tests/Input/src/android/hardware/input/KeyboardLayoutPreviewTests.kt
@@ -16,6 +16,8 @@
package android.hardware.input
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
import android.content.ContextWrapper
import android.graphics.drawable.Drawable
import android.platform.test.annotations.Presubmit
@@ -54,16 +56,16 @@
}
@Test
+ @EnableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
fun testKeyboardLayoutDrawable_hasCorrectDimensions() {
- setFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
val drawable = createDrawable()!!
assertEquals(WIDTH, drawable.intrinsicWidth)
assertEquals(HEIGHT, drawable.intrinsicHeight)
}
@Test
+ @DisableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
fun testKeyboardLayoutDrawable_isNull_ifFlagOff() {
- setFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_LAYOUT_PREVIEW_FLAG)
assertNull(createDrawable())
}
}
\ No newline at end of file
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 093923f..a8b383c 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -101,8 +101,8 @@
private static final String OBSERVER_NAME_2 = "observer2";
private static final String OBSERVER_NAME_3 = "observer3";
private static final String OBSERVER_NAME_4 = "observer4";
- private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(1);
- private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(5);
+ private static final long SHORT_DURATION = TimeUnit.SECONDS.toMillis(10);
+ private static final long LONG_DURATION = TimeUnit.SECONDS.toMillis(50);
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -1453,7 +1453,8 @@
raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
VERSION_CODE)), PackageWatchdog.FAILURE_REASON_UNKNOWN);
- moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS);
+ moveTimeForwardAndDispatch(PackageWatchdog.DEFAULT_DEESCALATION_WINDOW_MS
+ - TimeUnit.MINUTES.toMillis(1));
// The first failure will be outside the threshold.
raiseFatalFailureAndDispatch(watchdog, Arrays.asList(new VersionedPackage(APP_A,
@@ -1712,6 +1713,9 @@
watchdog.onPackageFailure(packages, failureReason);
}
mTestLooper.dispatchAll();
+ if (Flags.recoverabilityDetection()) {
+ moveTimeForwardAndDispatch(watchdog.DEFAULT_MITIGATION_WINDOW_MS);
+ }
}
private PackageWatchdog createWatchdog() {
diff --git a/tools/hoststubgen/OWNERS b/tools/hoststubgen/OWNERS
index a8c5321..3d8888d 100644
--- a/tools/hoststubgen/OWNERS
+++ b/tools/hoststubgen/OWNERS
@@ -1,3 +1 @@
-omakoto@google.com
-jsharkey@google.com
-jaggies@google.com
+file:platform/frameworks/base:/ravenwood/OWNERS