Merge "Remove NDK exports" into main
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index d991da5..b3a674f 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -890,7 +890,7 @@
cmd: "rm -f $(genDir)/framework.aidl.merged && " +
"for i in $(in); do " +
" rm -f $(genDir)/framework.aidl.tmp && " +
- " $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp && " +
+ " $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp --guarantee_stable && " +
" cat $(genDir)/framework.aidl.tmp >> $(genDir)/framework.aidl.merged; " +
"done && " +
"sort -u $(genDir)/framework.aidl.merged > $(out)",
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index 92b630f..80f39bf 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -46,13 +46,13 @@
* a {@link Message} object containing a bundle of data that will be
* processed by the Handler's {@link #handleMessage} method (requiring that
* you implement a subclass of Handler).
- *
+ *
* <p>When posting or sending to a Handler, you can either
* allow the item to be processed as soon as the message queue is ready
* to do so, or specify a delay before it gets processed or absolute time for
* it to be processed. The latter two allow you to implement timeouts,
* ticks, and other timing-based behavior.
- *
+ *
* <p>When a
* process is created for your application, its main thread is dedicated to
* running a message queue that takes care of managing the top-level
@@ -85,13 +85,13 @@
*/
boolean handleMessage(@NonNull Message msg);
}
-
+
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(@NonNull Message msg) {
}
-
+
/**
* Handle system messages here.
*/
@@ -343,8 +343,8 @@
* The default implementation will either return the class name of the
* message callback if any, or the hexadecimal representation of the
* message "what" field.
- *
- * @param message The message whose name is being queried
+ *
+ * @param message The message whose name is being queried
*/
@NonNull
public String getMessageName(@NonNull Message message) {
@@ -367,7 +367,7 @@
/**
* Same as {@link #obtainMessage()}, except that it also sets the what member of the returned Message.
- *
+ *
* @param what Value to assign to the returned Message.what field.
* @return A Message from the global message pool.
*/
@@ -376,12 +376,12 @@
{
return Message.obtain(this, what);
}
-
+
/**
- *
- * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
+ *
+ * Same as {@link #obtainMessage()}, except that it also sets the what and obj members
* of the returned Message.
- *
+ *
* @param what Value to assign to the returned Message.what field.
* @param obj Value to assign to the returned Message.obj field.
* @return A Message from the global message pool.
@@ -392,7 +392,7 @@
}
/**
- *
+ *
* Same as {@link #obtainMessage()}, except that it also sets the what, arg1 and arg2 members of the returned
* Message.
* @param what Value to assign to the returned Message.what field.
@@ -405,10 +405,10 @@
{
return Message.obtain(this, what, arg1, arg2);
}
-
+
/**
- *
- * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
+ *
+ * Same as {@link #obtainMessage()}, except that it also sets the what, obj, arg1,and arg2 values on the
* returned Message.
* @param what Value to assign to the returned Message.what field.
* @param arg1 Value to assign to the returned Message.arg1 field.
@@ -423,19 +423,19 @@
/**
* Causes the Runnable r to be added to the message queue.
- * The runnable will be run on the thread to which this handler is
- * attached.
- *
+ * The runnable will be run on the thread to which this handler is
+ * attached.
+ *
* @param r The Runnable that will be executed.
- *
- * @return Returns true if the Runnable was successfully placed in to the
+ *
+ * @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
public final boolean post(@NonNull Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);
}
-
+
/**
* Causes the Runnable r to be added to the message queue, to be run
* at a specific time given by <var>uptimeMillis</var>.
@@ -446,8 +446,8 @@
* @param r The Runnable that will be executed.
* @param uptimeMillis The absolute time at which the callback should run,
* using the {@link android.os.SystemClock#uptimeMillis} time-base.
- *
- * @return Returns true if the Runnable was successfully placed in to the
+ *
+ * @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed -- if
@@ -457,7 +457,7 @@
public final boolean postAtTime(@NonNull Runnable r, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r), uptimeMillis);
}
-
+
/**
* Causes the Runnable r to be added to the message queue, to be run
* at a specific time given by <var>uptimeMillis</var>.
@@ -470,21 +470,21 @@
* {@link #removeCallbacksAndMessages}.
* @param uptimeMillis The absolute time at which the callback should run,
* using the {@link android.os.SystemClock#uptimeMillis} time-base.
- *
- * @return Returns true if the Runnable was successfully placed in to the
+ *
+ * @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed -- if
* the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
- *
+ *
* @see android.os.SystemClock#uptimeMillis
*/
public final boolean postAtTime(
@NonNull Runnable r, @Nullable Object token, long uptimeMillis) {
return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
}
-
+
/**
* Causes the Runnable r to be added to the message queue, to be run
* after the specified amount of time elapses.
@@ -492,12 +492,12 @@
* is attached.
* <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
* Time spent in deep sleep will add an additional delay to execution.
- *
+ *
* @param r The Runnable that will be executed.
* @param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
- *
- * @return Returns true if the Runnable was successfully placed in to the
+ *
+ * @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed --
@@ -507,7 +507,7 @@
public final boolean postDelayed(@NonNull Runnable r, long delayMillis) {
return sendMessageDelayed(getPostMessage(r), delayMillis);
}
-
+
/** @hide */
public final boolean postDelayed(Runnable r, int what, long delayMillis) {
return sendMessageDelayed(getPostMessage(r).setWhat(what), delayMillis);
@@ -547,10 +547,10 @@
* <b>This method is only for use in very special circumstances -- it
* can easily starve the message queue, cause ordering problems, or have
* other unexpected side-effects.</b>
- *
+ *
* @param r The Runnable that will be executed.
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -635,8 +635,8 @@
* Pushes a message onto the end of the message queue after all pending messages
* before the current time. It will be received in {@link #handleMessage},
* in the thread attached to this handler.
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -646,8 +646,8 @@
/**
* Sends a Message containing only the what value.
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -659,9 +659,9 @@
/**
* Sends a Message containing only the what value, to be delivered
* after the specified amount of time elapses.
- * @see #sendMessageDelayed(android.os.Message, long)
- *
- * @return Returns true if the message was successfully placed in to the
+ * @see #sendMessageDelayed(android.os.Message, long)
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -672,11 +672,11 @@
}
/**
- * Sends a Message containing only the what value, to be delivered
+ * Sends a Message containing only the what value, to be delivered
* at a specific time.
* @see #sendMessageAtTime(android.os.Message, long)
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -691,8 +691,8 @@
* Enqueue a message into the message queue after all pending messages
* before (current time + delayMillis). You will receive it in
* {@link #handleMessage}, in the thread attached to this handler.
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
@@ -713,12 +713,12 @@
* Time spent in deep sleep will add an additional delay to execution.
* You will receive it in {@link #handleMessage}, in the thread attached
* to this handler.
- *
+ *
* @param uptimeMillis The absolute time at which the message should be
* delivered, using the
* {@link android.os.SystemClock#uptimeMillis} time-base.
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the message will be processed -- if
@@ -743,8 +743,8 @@
* <b>This method is only for use in very special circumstances -- it
* can easily starve the message queue, cause ordering problems, or have
* other unexpected side-effects.</b>
- *
- * @return Returns true if the message was successfully placed in to the
+ *
+ * @return Returns true if the message was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
@@ -798,6 +798,12 @@
/**
* Remove any pending posts of messages with code 'what' that are in the
* message queue.
+ *
+ * Note that `Message#what` is 0 unless otherwise set.
+ * When calling `postMessage(Runnable)` or `postAtTime(Runnable, long)`,
+ * the `Runnable` is internally wrapped with a `Message` whose `what` is 0.
+ * Calling `removeMessages(0)` will remove all messages without a `what`,
+ * including posted `Runnable`s.
*/
public final void removeMessages(int what) {
mQueue.removeMessages(this, what, null);
@@ -889,7 +895,7 @@
}
// if we can get rid of this method, the handler need not remember its loop
- // we could instead export a getMessageQueue() method...
+ // we could instead export a getMessageQueue() method...
@NonNull
public final Looper getLooper() {
return mLooper;
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 161951e..09a43b0 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -41,6 +41,9 @@
* what this message is about. Each {@link Handler} has its own name-space
* for message codes, so you do not need to worry about yours conflicting
* with other handlers.
+ *
+ * If not specified, this value is 0.
+ * Use values other than 0 to indicate custom message codes.
*/
public int what;
diff --git a/core/java/android/os/TransactionTooLargeException.java b/core/java/android/os/TransactionTooLargeException.java
index 79892e0..6b7cb33 100644
--- a/core/java/android/os/TransactionTooLargeException.java
+++ b/core/java/android/os/TransactionTooLargeException.java
@@ -47,7 +47,7 @@
* If possible, try to break up big requests into smaller pieces.
* </p><p>
* If you are implementing a service, it may help to impose size or complexity
- * contraints on the queries that clients can perform. For example, if the result set
+ * constraints on the queries that clients can perform. For example, if the result set
* could become large, then don't allow the client to request more than a few records
* at a time. Alternately, instead of returning all of the available data all at once,
* return the essential information first and make the client ask for additional information
diff --git a/core/java/android/permission/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING
index 69113ef..1337bcb 100644
--- a/core/java/android/permission/TEST_MAPPING
+++ b/core/java/android/permission/TEST_MAPPING
@@ -1,15 +1,7 @@
{
"presubmit": [
{
- "name": "CtsPermissionTestCases",
- "options": [
- {
- "include-filter": "android.permission.cts.PermissionControllerTest"
- },
- {
- "include-filter": "android.permission.cts.RuntimePermissionPresentationInfoTest"
- }
- ]
+ "name": "CtsPermissionTestCases_Platform"
}
]
-}
\ No newline at end of file
+}
diff --git a/core/java/com/android/internal/infra/TEST_MAPPING b/core/java/com/android/internal/infra/TEST_MAPPING
index e4550c0..35f0553 100644
--- a/core/java/com/android/internal/infra/TEST_MAPPING
+++ b/core/java/com/android/internal/infra/TEST_MAPPING
@@ -9,15 +9,7 @@
]
},
{
- "name": "CtsPermissionTestCases",
- "options": [
- {
- "include-filter": "android.permission.cts.PermissionControllerTest"
- },
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- }
- ]
+ "name": "CtsPermissionTestCases_Platform"
},
{
"name": "FrameworksCoreTests_internal_infra"
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 7af1965..3958488 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -623,21 +623,20 @@
*/
private static Runnable forkSystemServer(String abiList, String socketName,
ZygoteServer zygoteServer) {
- long capabilities = posixCapabilitiesAsBits(
- OsConstants.CAP_IPC_LOCK,
- OsConstants.CAP_KILL,
- OsConstants.CAP_NET_ADMIN,
- OsConstants.CAP_NET_BIND_SERVICE,
- OsConstants.CAP_NET_BROADCAST,
- OsConstants.CAP_NET_RAW,
- OsConstants.CAP_SYS_MODULE,
- OsConstants.CAP_SYS_NICE,
- OsConstants.CAP_SYS_PTRACE,
- OsConstants.CAP_SYS_TIME,
- OsConstants.CAP_SYS_TTY_CONFIG,
- OsConstants.CAP_WAKE_ALARM,
- OsConstants.CAP_BLOCK_SUSPEND
- );
+ long capabilities =
+ (1L << OsConstants.CAP_IPC_LOCK) |
+ (1L << OsConstants.CAP_KILL) |
+ (1L << OsConstants.CAP_NET_ADMIN) |
+ (1L << OsConstants.CAP_NET_BIND_SERVICE) |
+ (1L << OsConstants.CAP_NET_BROADCAST) |
+ (1L << OsConstants.CAP_NET_RAW) |
+ (1L << OsConstants.CAP_SYS_MODULE) |
+ (1L << OsConstants.CAP_SYS_NICE) |
+ (1L << OsConstants.CAP_SYS_PTRACE) |
+ (1L << OsConstants.CAP_SYS_TIME) |
+ (1L << OsConstants.CAP_SYS_TTY_CONFIG) |
+ (1L << OsConstants.CAP_WAKE_ALARM) |
+ (1L << OsConstants.CAP_BLOCK_SUSPEND);
/* Containers run without some capabilities, so drop any caps that are not available. */
StructCapUserHeader header = new StructCapUserHeader(
OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
@@ -734,20 +733,6 @@
}
/**
- * Gets the bit array representation of the provided list of POSIX capabilities.
- */
- private static long posixCapabilitiesAsBits(int... capabilities) {
- long result = 0;
- for (int capability : capabilities) {
- if ((capability < 0) || (capability > OsConstants.CAP_LAST_CAP)) {
- throw new IllegalArgumentException(String.valueOf(capability));
- }
- result |= (1L << capability);
- }
- return result;
- }
-
- /**
* This is the entry point for a Zygote process. It creates the Zygote server, loads resources,
* and handles other tasks related to preparing the process for forking into applications.
*
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 2068bd7..46b4695 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -466,10 +466,25 @@
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
- AutoMutex _l(mLock);
- sp<JavaBBinder> b = mBinder.promote();
- if (b == NULL) {
- b = new JavaBBinder(env, obj);
+ sp<JavaBBinder> b;
+ {
+ AutoMutex _l(mLock);
+ // must take lock to promote because we set the same wp<>
+ // on another thread.
+ b = mBinder.promote();
+ }
+
+ if (b) return b;
+
+ // b/360067751: constructor may trigger GC, so call outside lock
+ b = new JavaBBinder(env, obj);
+
+ {
+ AutoMutex _l(mLock);
+ // if it was constructed on another thread in the meantime,
+ // return that. 'b' will just get destructed.
+ if (sp<JavaBBinder> b2 = mBinder.promote(); b2) return b2;
+
if (mVintf) {
::android::internal::Stability::markVintf(b.get());
}
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index fba0d81..7ad18b8 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "NativeLibraryHelper"
//#define LOG_NDEBUG 0
+#include <android-base/properties.h>
#include <androidfw/ApkParsing.h>
#include <androidfw/ZipFileRO.h>
#include <androidfw/ZipUtils.h>
@@ -36,6 +37,7 @@
#include <zlib.h>
#include <memory>
+#include <string>
#include "com_android_internal_content_FileSystemUtils.h"
#include "core_jni_helpers.h"
@@ -125,72 +127,10 @@
return INSTALL_SUCCEEDED;
}
-/*
- * Copy the native library if needed.
- *
- * This function assumes the library and path names passed in are considered safe.
- */
-static install_status_t
-copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
-{
- static const size_t kPageSize = getpagesize();
- void** args = reinterpret_cast<void**>(arg);
- jstring* javaNativeLibPath = (jstring*) args[0];
- jboolean extractNativeLibs = *(jboolean*) args[1];
- jboolean debuggable = *(jboolean*) args[2];
-
- ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
-
- uint32_t uncompLen;
- uint32_t when;
- uint32_t crc;
-
- uint16_t method;
- off64_t offset;
- uint16_t extraFieldLength;
- if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, nullptr, &offset, &when, &crc,
- &extraFieldLength)) {
- ALOGE("Couldn't read zip entry info\n");
- return INSTALL_FAILED_INVALID_APK;
- }
-
- // Always extract wrap.sh for debuggable, even if extractNativeLibs=false. This makes it
- // easier to use wrap.sh because it only works when it is extracted, see
- // frameworks/base/services/core/java/com/android/server/am/ProcessList.java.
- bool forceExtractCurrentFile = debuggable && strcmp(fileName, "wrap.sh") == 0;
-
- if (!extractNativeLibs && !forceExtractCurrentFile) {
- // check if library is uncompressed and page-aligned
- if (method != ZipFileRO::kCompressStored) {
- ALOGE("Library '%s' is compressed - will not be able to open it directly from apk.\n",
- fileName);
- return INSTALL_FAILED_INVALID_APK;
- }
-
- if (offset % kPageSize != 0) {
- ALOGE("Library '%s' is not PAGE(%zu)-aligned - will not be able to open it directly "
- "from apk.\n", fileName, kPageSize);
- return INSTALL_FAILED_INVALID_APK;
- }
-
-#ifdef ENABLE_PUNCH_HOLES
- // if library is uncompressed, punch hole in it in place
- if (!punchHolesInElf64(zipFile->getZipFileName(), offset)) {
- ALOGW("Failed to punch uncompressed elf file :%s inside apk : %s at offset: "
- "%" PRIu64 "",
- fileName, zipFile->getZipFileName(), offset);
- }
-
- // if extra field for this zip file is present with some length, possibility is that it is
- // padding added for zip alignment. Punch holes there too.
- if (!punchHolesInZip(zipFile->getZipFileName(), offset, extraFieldLength)) {
- ALOGW("Failed to punch apk : %s at extra field", zipFile->getZipFileName());
- }
-#endif // ENABLE_PUNCH_HOLES
-
- return INSTALL_SUCCEEDED;
- }
-
+static install_status_t extractNativeLibFromApk(ZipFileRO* zipFile, ZipEntryRO zipEntry,
+ const char* fileName,
+ const std::string nativeLibPath, uint32_t when,
+ uint32_t uncompLen, uint32_t crc) {
// Build local file path
const size_t fileNameLen = strlen(fileName);
char localFileName[nativeLibPath.size() + fileNameLen + 2];
@@ -313,6 +253,88 @@
}
/*
+ * Copy the native library if needed.
+ *
+ * This function assumes the library and path names passed in are considered safe.
+ */
+static install_status_t copyFileIfChanged(JNIEnv* env, void* arg, ZipFileRO* zipFile,
+ ZipEntryRO zipEntry, const char* fileName) {
+ static const size_t kPageSize = getpagesize();
+ void** args = reinterpret_cast<void**>(arg);
+ jstring* javaNativeLibPath = (jstring*)args[0];
+ jboolean extractNativeLibs = *(jboolean*)args[1];
+ jboolean debuggable = *(jboolean*)args[2];
+ jboolean app_compat_16kb = *(jboolean*)args[3];
+ install_status_t ret = INSTALL_SUCCEEDED;
+
+ ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
+
+ uint32_t uncompLen;
+ uint32_t when;
+ uint32_t crc;
+
+ uint16_t method;
+ off64_t offset;
+ uint16_t extraFieldLength;
+ if (!zipFile->getEntryInfo(zipEntry, &method, &uncompLen, nullptr, &offset, &when, &crc,
+ &extraFieldLength)) {
+ ALOGE("Couldn't read zip entry info\n");
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+ // Always extract wrap.sh for debuggable, even if extractNativeLibs=false. This makes it
+ // easier to use wrap.sh because it only works when it is extracted, see
+ // frameworks/base/services/core/java/com/android/server/am/ProcessList.java.
+ bool forceExtractCurrentFile = debuggable && strcmp(fileName, "wrap.sh") == 0;
+
+ if (!extractNativeLibs && !forceExtractCurrentFile) {
+ // check if library is uncompressed and page-aligned
+ if (method != ZipFileRO::kCompressStored) {
+ ALOGE("Library '%s' is compressed - will not be able to open it directly from apk.\n",
+ fileName);
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+ if (offset % kPageSize != 0) {
+ // If the library is zip-aligned correctly for 4kb devices and app compat is
+ // enabled, on 16kb devices fallback to extraction
+ if (offset % 0x1000 == 0 && app_compat_16kb) {
+ ALOGI("16kB AppCompat: Library '%s' is not PAGE(%zu)-aligned - falling back to "
+ "extraction from apk\n",
+ fileName, kPageSize);
+ return extractNativeLibFromApk(zipFile, zipEntry, fileName, nativeLibPath.c_str(),
+ when, uncompLen, crc);
+ }
+
+ ALOGE("Library '%s' is not PAGE(%zu)-aligned - will not be able to open it directly "
+ "from apk.\n",
+ fileName, kPageSize);
+ return INSTALL_FAILED_INVALID_APK;
+ }
+
+#ifdef ENABLE_PUNCH_HOLES
+ // if library is uncompressed, punch hole in it in place
+ if (!punchHolesInElf64(zipFile->getZipFileName(), offset)) {
+ ALOGW("Failed to punch uncompressed elf file :%s inside apk : %s at offset: "
+ "%" PRIu64 "",
+ fileName, zipFile->getZipFileName(), offset);
+ }
+
+ // if extra field for this zip file is present with some length, possibility is that it is
+ // padding added for zip alignment. Punch holes there too.
+ if (!punchHolesInZip(zipFile->getZipFileName(), offset, extraFieldLength)) {
+ ALOGW("Failed to punch apk : %s at extra field", zipFile->getZipFileName());
+ }
+#endif // ENABLE_PUNCH_HOLES
+
+ return INSTALL_SUCCEEDED;
+ }
+
+ return extractNativeLibFromApk(zipFile, zipEntry, fileName, nativeLibPath.c_str(), when,
+ uncompLen, crc);
+}
+
+/*
* An iterator over all shared libraries in a zip file. An entry is
* considered to be a shared library if all of the conditions below are
* satisfied :
@@ -498,12 +520,24 @@
return status;
}
+static inline bool app_compat_16kb_enabled() {
+ static const size_t kPageSize = getpagesize();
+
+ // App compat is only applicable on 16kb-page-size devices.
+ if (kPageSize != 0x4000) {
+ return false;
+ }
+
+ return android::base::GetBoolProperty("bionic.linker.16kb.app_compat.enabled", false);
+}
+
static jint
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
jboolean extractNativeLibs, jboolean debuggable)
{
- void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable };
+ jboolean app_compat_16kb = app_compat_16kb_enabled();
+ void* args[] = { &javaNativeLibPath, &extractNativeLibs, &debuggable, &app_compat_16kb };
return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable,
copyFileIfChanged, reinterpret_cast<void*>(args));
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 038d008..122e86a 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -852,7 +852,8 @@
@NonNull TaskContainer taskContainer) {
// Update all TaskFragments in the Task. Make a copy of the list since some may be
// removed on updating.
- final List<TaskFragmentContainer> containers = taskContainer.getTaskFragmentContainers();
+ final List<TaskFragmentContainer> containers
+ = new ArrayList<>(taskContainer.getTaskFragmentContainers());
for (int i = containers.size() - 1; i >= 0; i--) {
final TaskFragmentContainer container = containers.get(i);
// Wait until onTaskFragmentAppeared to update new container.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
index fad3dee..1929729 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/ScreenshotUtils.java
@@ -42,6 +42,7 @@
.setSourceCrop(crop)
.setCaptureSecureLayers(true)
.setAllowProtected(true)
+ .setHintForSeamlessTransition(true)
.build()));
}
@@ -78,6 +79,9 @@
mTransaction.setColorSpace(mScreenshot, buffer.getColorSpace());
mTransaction.reparent(mScreenshot, mParentSurfaceControl);
mTransaction.setLayer(mScreenshot, mLayer);
+ if (buffer.containsHdrLayers()) {
+ mTransaction.setDimmingEnabled(mScreenshot, false);
+ }
mTransaction.show(mScreenshot);
mTransaction.apply();
}
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 43a70c1..5a4cff0 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -309,9 +309,8 @@
return NULL;
}
- // We succeeded, so relinquish control of dataMap
pAsset->mAccessMode = mode;
- return std::move(pAsset);
+ return pAsset;
}
/*
@@ -328,9 +327,8 @@
return NULL;
}
- // We succeeded, so relinquish control of dataMap
pAsset->mAccessMode = mode;
- return std::move(pAsset);
+ return pAsset;
}
/*
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 447e980..5b6b6c0 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -220,14 +220,15 @@
field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
field public static final String CATEGORY_OTHER = "other";
field public static final String CATEGORY_PAYMENT = "payment";
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final String DH = "DH";
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final String ESE = "ESE";
field public static final String EXTRA_CATEGORY = "category";
field public static final String EXTRA_SERVICE_COMPONENT = "component";
+ field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
+ field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1; // 0xffffffff
field public static final int SELECTION_MODE_ALWAYS_ASK = 1; // 0x1
field public static final int SELECTION_MODE_ASK_IF_CONFLICT = 2; // 0x2
field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
- field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final String UICC = "UICC";
}
public abstract class HostApduService extends android.app.Service {
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 25a01b9..0f97b2c 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -73,6 +73,7 @@
method public void onApplyRouting(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onBootFinished(int);
method public void onBootStarted();
+ method public void onCardEmulationActivated(boolean);
method public void onDisable(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onDisableFinished(int);
method public void onDisableStarted();
@@ -81,6 +82,8 @@
method public void onEnableStarted();
method public void onHceEventReceived(int);
method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method public void onRfDiscoveryStarted(boolean);
+ method public void onRfFieldActivated(boolean);
method public void onRoutingChanged();
method public void onStateUpdated(int);
method public void onTagConnected(boolean, @NonNull android.nfc.Tag);
@@ -94,7 +97,7 @@
public final class CardEmulation {
method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
- method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, @Nullable String, @Nullable String);
+ method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity);
}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index 6c0f933..e2ec952 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -62,7 +62,7 @@
void dispatch(in Tag tag);
- void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras);
+ void setReaderMode (IBinder b, IAppCallback callback, int flags, in Bundle extras, String pkg);
void addNfcUnlockHandler(INfcUnlockHandler unlockHandler, in int[] techList);
void removeNfcUnlockHandler(INfcUnlockHandler unlockHandler);
@@ -100,7 +100,7 @@
void unregisterWlcStateListener(in INfcWlcStateListener listener);
WlcListenerDeviceInfo getWlcListenerDeviceInfo();
- void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags);
+ void updateDiscoveryTechnology(IBinder b, int pollFlags, int listenFlags, String pkg);
void notifyPollingLoop(in PollingFrame frame);
void notifyHceDeactivated();
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index c19a44b..b65c837 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -37,4 +37,7 @@
void onTagDispatch(in ResultReceiver isSkipped);
void onRoutingChanged();
void onHceEventReceived(int action);
+ void onCardEmulationActivated(boolean isActivated);
+ void onRfFieldActivated(boolean isActivated);
+ void onRfDiscoveryStarted(boolean isDiscoveryStarted);
}
diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java
index 0eb846d..909eca7 100644
--- a/nfc/java/android/nfc/NfcActivityManager.java
+++ b/nfc/java/android/nfc/NfcActivityManager.java
@@ -236,7 +236,8 @@
public void setReaderMode(Binder token, int flags, Bundle extras) {
if (DBG) Log.d(TAG, "Setting reader mode");
- NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(token, this, flags, extras));
+ NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(
+ token, this, flags, extras, mAdapter.getContext().getPackageName()));
}
/**
@@ -395,7 +396,8 @@
private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) {
NfcAdapter.callService(
- () -> NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech));
+ () -> NfcAdapter.sService.updateDiscoveryTechnology(
+ token, pollTech, listenTech, mAdapter.getContext().getPackageName()));
}
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 525e2c5..22ae612 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -1731,7 +1731,8 @@
}
Binder token = new Binder();
int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS;
- callService(() -> sService.setReaderMode(token, null, flags, null));
+ callService(() -> sService.setReaderMode(
+ token, null, flags, null, mContext.getPackageName()));
}
/**
@@ -1804,7 +1805,8 @@
|| (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) {
Binder token = new Binder();
callService( () ->
- sService.updateDiscoveryTechnology(token, pollTechnology, listenTechnology));
+ sService.updateDiscoveryTechnology(
+ token, pollTechnology, listenTechnology, mContext.getPackageName()));
} else {
mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology);
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 6c02edd..632f693 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -32,7 +32,9 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
@@ -40,6 +42,7 @@
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -58,10 +61,13 @@
private static final int OEM_EXTENSION_RESPONSE_THRESHOLD_MS = 2000;
private final NfcAdapter mAdapter;
private final NfcOemExtensionCallback mOemNfcExtensionCallback;
+ private boolean mIsRegistered = false;
+ private final Map<Callback, Executor> mCallbackMap = new HashMap<>();
private final Context mContext;
- private Executor mExecutor = null;
- private Callback mCallback = null;
private final Object mLock = new Object();
+ private boolean mCardEmulationActivated = false;
+ private boolean mRfFieldActivated = false;
+ private boolean mRfDiscoveryStarted = false;
/**
* Event that Host Card Emulation is activated.
@@ -215,6 +221,32 @@
* @param action Flag indicating actions to activate, start and stop cpu boost.
*/
void onHceEventReceived(@HostCardEmulationAction int action);
+
+ /**
+ * Notifies NFC is activated in listen mode.
+ * NFC Forum NCI-2.3 ch.5.2.6 specification
+ *
+ * <p>NFCC is ready to communicate with a Card reader
+ *
+ * @param isActivated true, if card emulation activated, else de-activated.
+ */
+ void onCardEmulationActivated(boolean isActivated);
+
+ /**
+ * Notifies the Remote NFC Endpoint RF Field is activated.
+ * NFC Forum NCI-2.3 ch.5.3 specification
+ *
+ * @param isActivated true, if RF Field is ON, else RF Field is OFF.
+ */
+ void onRfFieldActivated(boolean isActivated);
+
+ /**
+ * Notifies the NFC RF discovery is started or in the IDLE state.
+ * NFC Forum NCI-2.3 ch.5.2 specification
+ *
+ * @param isDiscoveryStarted true, if RF discovery started, else RF state is Idle.
+ */
+ void onRfDiscoveryStarted(boolean isDiscoveryStarted);
}
@@ -229,7 +261,12 @@
/**
* Register an {@link Callback} to listen for NFC oem extension callbacks
+ * Multiple clients can register and callbacks will be invoked asynchronously.
+ *
* <p>The provided callback will be invoked by the given {@link Executor}.
+ * As part of {@link #registerCallback(Executor, Callback)} the
+ * {@link Callback} will be invoked with current NFC state
+ * before the {@link #registerCallback(Executor, Callback)} function completes.
*
* @param executor an {@link Executor} to execute given callback
* @param callback oem implementation of {@link Callback}
@@ -239,15 +276,35 @@
public void registerCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) {
synchronized (mLock) {
- if (mCallback != null) {
+ if (executor == null || callback == null) {
+ Log.e(TAG, "Executor and Callback must not be null!");
+ throw new IllegalArgumentException();
+ }
+
+ if (mCallbackMap.containsKey(callback)) {
Log.e(TAG, "Callback already registered. Unregister existing callback before"
+ "registering");
throw new IllegalArgumentException();
}
- NfcAdapter.callService(() -> {
- NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
- mCallback = callback;
- mExecutor = executor;
+ mCallbackMap.put(callback, executor);
+ if (!mIsRegistered) {
+ NfcAdapter.callService(() -> {
+ NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback);
+ mIsRegistered = true;
+ });
+ } else {
+ updateNfCState(callback, executor);
+ }
+ }
+ }
+
+ private void updateNfCState(Callback callback, Executor executor) {
+ if (callback != null) {
+ Log.i(TAG, "updateNfCState");
+ executor.execute(() -> {
+ callback.onCardEmulationActivated(mCardEmulationActivated);
+ callback.onRfFieldActivated(mRfFieldActivated);
+ callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
});
}
}
@@ -266,15 +323,19 @@
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
public void unregisterCallback(@NonNull Callback callback) {
synchronized (mLock) {
- if (mCallback == null || mCallback != callback) {
+ if (!mCallbackMap.containsKey(callback) || !mIsRegistered) {
Log.e(TAG, "Callback not registered");
throw new IllegalArgumentException();
}
- NfcAdapter.callService(() -> {
- NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
- mCallback = null;
- mExecutor = null;
- });
+ if (mCallbackMap.size() == 1) {
+ NfcAdapter.callService(() -> {
+ NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback);
+ mIsRegistered = false;
+ mCallbackMap.remove(callback);
+ });
+ } else {
+ mCallbackMap.remove(callback);
+ }
}
}
@@ -322,90 +383,133 @@
}
private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
+
@Override
public void onTagConnected(boolean connected, Tag tag) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoid2ArgCallback(connected, tag, cb::onTagConnected, ex));
+ }
+
+ @Override
+ public void onCardEmulationActivated(boolean isActivated) throws RemoteException {
+ mCardEmulationActivated = isActivated;
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(isActivated, cb::onCardEmulationActivated, ex));
+ }
+
+ @Override
+ public void onRfFieldActivated(boolean isActivated) throws RemoteException {
+ mRfFieldActivated = isActivated;
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(isActivated, cb::onRfFieldActivated, ex));
+ }
+
+ @Override
+ public void onRfDiscoveryStarted(boolean isDiscoveryStarted) throws RemoteException {
+ mRfDiscoveryStarted = isDiscoveryStarted;
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(isDiscoveryStarted, cb::onRfDiscoveryStarted, ex));
+ }
+
+ @Override
+ public void onStateUpdated(int state) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(state, cb::onStateUpdated, ex));
+ }
+
+ @Override
+ public void onApplyRouting(ResultReceiver isSkipped) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(
+ new ReceiverWrapper(isSkipped), cb::onApplyRouting, ex));
+ }
+ @Override
+ public void onNdefRead(ResultReceiver isSkipped) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(
+ new ReceiverWrapper(isSkipped), cb::onNdefRead, ex));
+ }
+ @Override
+ public void onEnable(ResultReceiver isAllowed) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(
+ new ReceiverWrapper(isAllowed), cb::onEnable, ex));
+ }
+ @Override
+ public void onDisable(ResultReceiver isAllowed) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(
+ new ReceiverWrapper(isAllowed), cb::onDisable, ex));
+ }
+ @Override
+ public void onBootStarted() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onBootStarted(), ex));
+ }
+ @Override
+ public void onEnableStarted() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onEnableStarted(), ex));
+ }
+ @Override
+ public void onDisableStarted() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onDisableStarted(), ex));
+ }
+ @Override
+ public void onBootFinished(int status) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(status, cb::onBootFinished, ex));
+ }
+ @Override
+ public void onEnableFinished(int status) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(status, cb::onEnableFinished, ex));
+ }
+ @Override
+ public void onDisableFinished(int status) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(status, cb::onDisableFinished, ex));
+ }
+ @Override
+ public void onTagDispatch(ResultReceiver isSkipped) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(
+ new ReceiverWrapper(isSkipped), cb::onTagDispatch, ex));
+ }
+ @Override
+ public void onRoutingChanged() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onRoutingChanged(), ex));
+ }
+ @Override
+ public void onHceEventReceived(int action) throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(action, cb::onHceEventReceived, ex));
+ }
+
+ private <T> void handleVoidCallback(
+ T input, Consumer<T> callbackMethod, Executor executor) {
synchronized (mLock) {
- if (mCallback == null || mExecutor == null) {
- return;
- }
final long identity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() -> mCallback.onTagConnected(connected, tag));
+ executor.execute(() -> callbackMethod.accept(input));
+ } catch (RuntimeException ex) {
+ throw ex;
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
- @Override
- public void onStateUpdated(int state) throws RemoteException {
- handleVoidCallback(state, mCallback::onStateUpdated);
- }
- @Override
- public void onApplyRouting(ResultReceiver isSkipped) throws RemoteException {
- handleVoidCallback(
- new ReceiverWrapper(isSkipped), mCallback::onApplyRouting);
- }
- @Override
- public void onNdefRead(ResultReceiver isSkipped) throws RemoteException {
- handleVoidCallback(
- new ReceiverWrapper(isSkipped), mCallback::onNdefRead);
- }
- @Override
- public void onEnable(ResultReceiver isAllowed) throws RemoteException {
- handleVoidCallback(
- new ReceiverWrapper(isAllowed), mCallback::onEnable);
- }
- @Override
- public void onDisable(ResultReceiver isAllowed) throws RemoteException {
- handleVoidCallback(
- new ReceiverWrapper(isAllowed), mCallback::onDisable);
- }
- @Override
- public void onBootStarted() throws RemoteException {
- handleVoidCallback(null, (Object input) -> mCallback.onBootStarted());
- }
- @Override
- public void onEnableStarted() throws RemoteException {
- handleVoidCallback(null, (Object input) -> mCallback.onEnableStarted());
- }
- @Override
- public void onDisableStarted() throws RemoteException {
- handleVoidCallback(null, (Object input) -> mCallback.onDisableStarted());
- }
- @Override
- public void onBootFinished(int status) throws RemoteException {
- handleVoidCallback(status, mCallback::onBootFinished);
- }
- @Override
- public void onEnableFinished(int status) throws RemoteException {
- handleVoidCallback(status, mCallback::onEnableFinished);
- }
- @Override
- public void onDisableFinished(int status) throws RemoteException {
- handleVoidCallback(status, mCallback::onDisableFinished);
- }
- @Override
- public void onTagDispatch(ResultReceiver isSkipped) throws RemoteException {
- handleVoidCallback(
- new ReceiverWrapper(isSkipped), mCallback::onTagDispatch);
- }
- @Override
- public void onRoutingChanged() throws RemoteException {
- handleVoidCallback(null, (Object input) -> mCallback.onRoutingChanged());
- }
- @Override
- public void onHceEventReceived(int action) throws RemoteException {
- handleVoidCallback(action, mCallback::onHceEventReceived);
- }
- private <T> void handleVoidCallback(T input, Consumer<T> callbackMethod) {
+ private <T1, T2> void handleVoid2ArgCallback(
+ T1 input1, T2 input2, BiConsumer<T1, T2> callbackMethod, Executor executor) {
synchronized (mLock) {
- if (mCallback == null || mExecutor == null) {
- return;
- }
final long identity = Binder.clearCallingIdentity();
try {
- mExecutor.execute(() -> callbackMethod.accept(input));
+ executor.execute(() -> callbackMethod.accept(input1, input2));
+ } catch (RuntimeException ex) {
+ throw ex;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -415,17 +519,12 @@
private <S, T> S handleNonVoidCallbackWithInput(
S defaultValue, T input, Function<T, S> callbackMethod) throws RemoteException {
synchronized (mLock) {
- if (mCallback == null) {
- return defaultValue;
- }
final long identity = Binder.clearCallingIdentity();
S result = defaultValue;
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
- FutureTask<S> futureTask = new FutureTask<>(
- () -> callbackMethod.apply(input)
- );
- executor.submit(futureTask);
+ FutureTask<S> futureTask = new FutureTask<>(() -> callbackMethod.apply(input));
+ var unused = executor.submit(futureTask);
try {
result = futureTask.get(
OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
@@ -447,17 +546,12 @@
private <T> T handleNonVoidCallbackWithoutInput(T defaultValue, Supplier<T> callbackMethod)
throws RemoteException {
synchronized (mLock) {
- if (mCallback == null) {
- return defaultValue;
- }
final long identity = Binder.clearCallingIdentity();
T result = defaultValue;
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
- FutureTask<T> futureTask = new FutureTask<>(
- callbackMethod::get
- );
- executor.submit(futureTask);
+ FutureTask<T> futureTask = new FutureTask<>(callbackMethod::get);
+ var unused = executor.submit(futureTask);
try {
result = futureTask.get(
OEM_EXTENSION_RESPONSE_THRESHOLD_MS, TimeUnit.MILLISECONDS);
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 0605dbe..497309c 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -18,12 +18,12 @@
import android.Manifest;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.annotation.UserHandleAware;
import android.annotation.UserIdInt;
@@ -155,17 +155,23 @@
* Route to Device Host (DH).
*/
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final String DH = "DH";
+ public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0;
/**
* Route to eSE.
*/
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final String ESE = "ESE";
+ public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1;
/**
* Route to UICC.
*/
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
- public static final String UICC = "UICC";
+ public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC = 2;
+
+ /**
+ * Route unset.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
+ public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1;
static boolean sIsInitialized = false;
static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
@@ -734,7 +740,7 @@
*
* @return the preferred payment service description
*/
- @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
+ @RequiresPermission(Manifest.permission.NFC_PREFERRED_PAYMENT_INFO)
@Nullable
public CharSequence getDescriptionForPreferredPaymentService() {
ApduServiceInfo serviceInfo = callServiceReturn(() ->
@@ -884,10 +890,12 @@
}
/** @hide */
- @StringDef({
- DH,
- ESE,
- UICC
+ @IntDef(prefix = "PROTOCOL_AND_TECHNOLOGY_ROUTE_",
+ value = {
+ PROTOCOL_AND_TECHNOLOGY_ROUTE_DH,
+ PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE,
+ PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC,
+ PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET
})
@Retention(RetentionPolicy.SOURCE)
public @interface ProtocolAndTechnologyRoute {}
@@ -896,29 +904,32 @@
* Setting NFC controller routing table, which includes Protocol Route and Technology Route,
* while this Activity is in the foreground.
*
- * The parameter set to null can be used to keep current values for that entry. Either
+ * The parameter set to {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET}
+ * can be used to keep current values for that entry. Either
* Protocol Route or Technology Route should be override when calling this API, otherwise
* throw {@link IllegalArgumentException}.
* <p>
* Example usage in an Activity that requires to set proto route to "ESE" and keep tech route:
* <pre>
* protected void onResume() {
- * mNfcAdapter.overrideRoutingTable(this , "ESE" , null);
+ * mNfcAdapter.overrideRoutingTable(
+ * this, {@link #PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE}, null);
* }</pre>
* </p>
* Also activities must call {@link #recoverRoutingTable(Activity)}
* when it goes to the background. Only the package of the
* currently preferred service (the service set as preferred by the current foreground
* application via {@link CardEmulation#setPreferredService(Activity, ComponentName)} or the
- * current Default Wallet Role Holder {@link android.app.role.RoleManager#ROLE_WALLET}),
+ * current Default Wallet Role Holder {@link RoleManager#ROLE_WALLET}),
* otherwise a call to this method will fail and throw {@link SecurityException}.
* @param activity The Activity that requests NFC controller routing table to be changed.
- * @param protocol ISO-DEP route destination, which can be "DH" or "UICC" or "ESE".
- * @param technology Tech-A, Tech-B and Tech-F route destination, which can be "DH" or "UICC"
- * or "ESE".
+ * @param protocol ISO-DEP route destination, where the possible inputs are defined
+ * in {@link ProtocolAndTechnologyRoute}.
+ * @param technology Tech-A, Tech-B and Tech-F route destination, where the possible inputs
+ * are defined in {@link ProtocolAndTechnologyRoute}
* @throws SecurityException if the caller is not the preferred NFC service
* @throws IllegalArgumentException if the activity is not resumed or the caller is not in the
- * foreground, or both protocol route and technology route are null.
+ * foreground.
* <p>
* This is a high risk API and only included to support mainline effort
* @hide
@@ -926,25 +937,36 @@
@SystemApi
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
public void overrideRoutingTable(
- @NonNull Activity activity, @ProtocolAndTechnologyRoute @Nullable String protocol,
- @ProtocolAndTechnologyRoute @Nullable String technology) {
+ @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
+ @ProtocolAndTechnologyRoute int technology) {
if (!activity.isResumed()) {
throw new IllegalArgumentException("Activity must be resumed.");
}
- if (protocol == null && technology == null) {
- throw new IllegalArgumentException(("Both Protocol and Technology are null."));
- }
+ String protocolRoute = switch (protocol) {
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_DH -> "DH";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE -> "ESE";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC -> "UICC";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET -> null;
+ default -> throw new IllegalStateException("Unexpected value: " + protocol);
+ };
+ String technologyRoute = switch (technology) {
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_DH -> "DH";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE -> "ESE";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_UICC -> "UICC";
+ case PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET -> null;
+ default -> throw new IllegalStateException("Unexpected value: " + protocol);
+ };
callService(() ->
sService.overrideRoutingTable(
mContext.getUser().getIdentifier(),
- protocol,
- technology,
+ protocolRoute,
+ technologyRoute,
mContext.getPackageName()));
}
/**
* Restore the NFC controller routing table,
- * which was changed by {@link #overrideRoutingTable(Activity, String, String)}
+ * which was changed by {@link #overrideRoutingTable(Activity, int, int)}
*
* @param activity The Activity that requested NFC controller routing table to be changed.
* @throws IllegalArgumentException if the caller is not in the foreground.
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 468147f..9a4ee2f 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -140,3 +140,11 @@
description: "Enable override and recover routing table"
bug: "329043523"
}
+
+flag {
+ name: "nfc_watchdog"
+ is_exported: true
+ namespace: "nfc"
+ description: "Enable watchdog for the NFC system process"
+ bug: "362937338"
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS
new file mode 100644
index 0000000..134a56e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS
@@ -0,0 +1 @@
+include /packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS
new file mode 100644
index 0000000..f6f98e9
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
index 443e9876..208a17c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
@@ -9,3 +9,4 @@
jglazier@google.com
mpietal@google.com
tsuji@google.com
+yuandizhou@google.com
diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS
index a90328c..3d46520 100644
--- a/ravenwood/OWNERS
+++ b/ravenwood/OWNERS
@@ -1,7 +1,9 @@
set noparent
-jsharkey@google.com
omakoto@google.com
+topjohnwu@google.com
+hackbod@google.com #{LAST_RESORT_SUGGESTION}
+
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/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7395c05..40fd837 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12190,7 +12190,7 @@
opts.dumpProto = true;
} else if ("--logstats".equals(opt)) {
opts.mDumpAllocatorStats = true;
- } else if ("-h".equals(opt)) {
+ } else if ("-h".equals(opt) || "--help".equals(opt)) {
pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
pw.println(" -a: include all available information for each process.");
pw.println(" -d: include dalvik details.");
@@ -12200,10 +12200,13 @@
pw.println(" -p: dump also private dirty memory usage.");
pw.println(" --oom: only show processes organized by oom adj.");
pw.println(" --local: only collect details locally, don't call process.");
+ pw.println(" --logstats: dump native allocator stats to log");
pw.println(" --package: interpret process arg as package, dumping all");
pw.println(" processes that have loaded that package.");
pw.println(" --checkin: dump data for a checkin");
pw.println(" --proto: dump data to proto");
+ pw.println(" --logstats: log native allocator statistics.");
+ pw.println(" --unreachable: dump unreachable native memory with libmemunreachable.");
pw.println("If [process] is specified it can be the name or ");
pw.println("pid of a specific process to dump.");
return;
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index 2a9dfa2..9317c1e 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -18,24 +18,7 @@
"name": "FrameworksMockingServicesTests_android_server_appop"
},
{
- "name": "CtsPermissionTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "include-filter": "android.permission.cts.BackgroundPermissionsTest"
- },
- {
- "include-filter": "android.permission.cts.SplitPermissionTest"
- },
- {
- "include-filter": "android.permission.cts.PermissionFlagsTest"
- },
- {
- "include-filter": "android.permission.cts.SharedUidPermissionsTest"
- }
- ]
+ "name": "CtsPermissionTestCases_Platform"
},
{
"name": "CtsAppTestCases",
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 33ad49e..e3cd993 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -127,8 +127,7 @@
private final Object mDeviceStateLock = new Object();
// Request to override default use of A2DP for media.
- @GuardedBy("mDeviceStateLock")
- private boolean mBluetoothA2dpEnabled;
+ private AtomicBoolean mBluetoothA2dpEnabled = new AtomicBoolean(false);
// lock always taken when accessing AudioService.mSetModeDeathHandlers
// TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055
@@ -263,7 +262,7 @@
* Handle BluetoothHeadset intents where the action is one of
* {@link BluetoothHeadset#ACTION_ACTIVE_DEVICE_CHANGED} or
* {@link BluetoothHeadset#ACTION_AUDIO_STATE_CHANGED}.
- * @param intent
+ * @param intent the Intent received from BT service
*/
private void onReceiveBtEvent(@NonNull Intent intent) {
mBtHelper.onReceiveBtEvent(intent);
@@ -275,22 +274,16 @@
}
/*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) {
- synchronized (mDeviceStateLock) {
- if (mBluetoothA2dpEnabled == on) {
- return;
- }
- mBluetoothA2dpEnabled = on;
- mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
- sendIILMsgNoDelay(MSG_IIL_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE,
- AudioSystem.FOR_MEDIA,
- mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
- source);
- }
+ boolean wasOn = mBluetoothA2dpEnabled.getAndSet(on);
+ // do not mute music if we do not anticipate a change in A2DP ON state
+ sendLMsgNoDelay(wasOn == on
+ ? MSG_L_SET_FORCE_BT_A2DP_USE_NO_MUTE : MSG_L_SET_FORCE_BT_A2DP_USE,
+ SENDMSG_REPLACE, source);
}
/**
* Turns speakerphone on/off
- * @param on
+ * @param on true to enable speakerphone
* @param eventSource for logging purposes
*/
/*package*/ void setSpeakerphoneOn(
@@ -304,21 +297,21 @@
on, BtHelper.SCO_MODE_UNDEFINED, eventSource, isPrivileged));
}
+ private static final long SET_COMMUNICATION_DEVICE_TIMEOUT_MS = 3000;
+
+ /** synchronization for setCommunicationDevice() and getCommunicationDevice */
+ private final Object mCommunicationDeviceLock = new Object();
+ @GuardedBy("mCommunicationDeviceLock")
+ private int mCommunicationDeviceUpdateCount = 0;
+
/**
* Select device for use for communication use cases.
* @param cb Client binder for death detection
* @param uid Client uid
* @param device Device selected or null to unselect.
* @param eventSource for logging purposes
+ * @return false if there is no device and no communication client
*/
-
- private static final long SET_COMMUNICATION_DEVICE_TIMEOUT_MS = 3000;
-
- /** synchronization for setCommunicationDevice() and getCommunicationDevice */
- private Object mCommunicationDeviceLock = new Object();
- @GuardedBy("mCommunicationDeviceLock")
- private int mCommunicationDeviceUpdateCount = 0;
-
/*package*/ boolean setCommunicationDevice(IBinder cb, int uid, AudioDeviceInfo device,
boolean isPrivileged, String eventSource) {
@@ -349,7 +342,6 @@
* Sets or resets the communication device for matching client. If no client matches and the
* request is to reset for a given device (deviceInfo.mOn == false), the method is a noop.
* @param deviceInfo information on the device and requester {@link #CommunicationDeviceInfo}
- * @return true if the communication device is set or reset
*/
@GuardedBy("mDeviceStateLock")
/*package*/ void onSetCommunicationDeviceForClient(CommunicationDeviceInfo deviceInfo) {
@@ -736,15 +728,6 @@
}
/**
- * Helper method on top of isDeviceRequestedForCommunication() indicating if
- * speakerphone ON is currently requested or not.
- * @return true if speakerphone ON requested, false otherwise.
- */
- private boolean isSpeakerphoneRequested() {
- return isDeviceRequestedForCommunication(AudioDeviceInfo.TYPE_BUILTIN_SPEAKER);
- }
-
- /**
* Indicates if preferred route selection for communication is speakerphone.
* @return true if speakerphone is active, false otherwise.
*/
@@ -931,6 +914,12 @@
}
@Override
+ public int hashCode() {
+ // only hashing on the fields used in equals()
+ return Objects.hash(mProfile, mDevice);
+ }
+
+ @Override
public String toString() {
return "BtDeviceInfo: device=" + mDevice.toString()
+ " state=" + mState
@@ -987,7 +976,7 @@
/**
* will block on mDeviceStateLock, which is held during an A2DP (dis) connection
* not just a simple message post
- * @param info struct with the (dis)connection information
+ * @param data struct with the (dis)connection information
*/
/*package*/ void queueOnBluetoothActiveDeviceChanged(@NonNull BtDeviceChangedData data) {
if (data.mPreviousDevice != null
@@ -1231,16 +1220,8 @@
}
}
- /*package*/ boolean isAvrcpAbsoluteVolumeSupported() {
- synchronized (mDeviceStateLock) {
- return mBtHelper.isAvrcpAbsoluteVolumeSupported();
- }
- }
-
/*package*/ boolean isBluetoothA2dpOn() {
- synchronized (mDeviceStateLock) {
- return mBluetoothA2dpEnabled;
- }
+ return mBluetoothA2dpEnabled.get();
}
/*package*/ void postSetAvrcpAbsoluteVolumeIndex(int index) {
@@ -1384,6 +1365,7 @@
mCommDevDispatchers.getBroadcastItem(i)
.dispatchCommunicationDeviceChanged(portId);
} catch (RemoteException e) {
+ Log.e(TAG, "dispatchCommunicationDevice error", e);
}
}
mCommDevDispatchers.finishBroadcast();
@@ -1543,8 +1525,9 @@
sendLMsgNoDelay(MSG_L_SYNCHRONIZE_ADI_DEVICES_IN_INVENTORY, SENDMSG_QUEUE, deviceState);
}
- /*package*/ void postUpdatedAdiDeviceState(AdiDeviceState deviceState) {
- sendLMsgNoDelay(MSG_L_UPDATED_ADI_DEVICE_STATE, SENDMSG_QUEUE, deviceState);
+ /*package*/ void postUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
+ sendILMsgNoDelay(
+ MSG_IL_UPDATED_ADI_DEVICE_STATE, SENDMSG_QUEUE, initSA ? 1 : 0, deviceState);
}
/*package*/ static final class CommunicationDeviceInfo {
@@ -1586,6 +1569,12 @@
}
@Override
+ public int hashCode() {
+ // only hashing on the fields used in equals()
+ return Objects.hash(mCb.hashCode(), mUid);
+ }
+
+ @Override
public String toString() {
return "CommunicationDeviceInfo mCb=" + mCb.toString()
+ " mUid=" + mUid
@@ -1605,19 +1594,16 @@
//@GuardedBy("mConnectedDevices")
/*package*/ void setBluetoothA2dpOnInt(boolean on, boolean fromA2dp, String source) {
// for logging only
- final String eventSource = new StringBuilder("setBluetoothA2dpOn(").append(on)
- .append(") from u/pid:").append(Binder.getCallingUid()).append("/")
- .append(Binder.getCallingPid()).append(" src:").append(source).toString();
+ final String eventSource = "setBluetoothA2dpOn(" + on
+ + ") from u/pid:" + Binder.getCallingUid() + "/"
+ + Binder.getCallingPid() + " src:" + source;
- synchronized (mDeviceStateLock) {
- mBluetoothA2dpEnabled = on;
- mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
- onSetForceUse(
- AudioSystem.FOR_MEDIA,
- mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
- fromA2dp,
- eventSource);
- }
+ mBluetoothA2dpEnabled.set(on);
+ onSetForceUse(
+ AudioSystem.FOR_MEDIA,
+ on ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
+ fromA2dp,
+ eventSource);
}
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
@@ -1654,6 +1640,10 @@
sendIILMsg(MSG_IIL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, codec, address, delayMs);
}
+ /*package*/ void setHearingAidTimeout(String address, int delayMs) {
+ sendLMsg(MSG_IL_BT_HEARING_AID_TIMEOUT, SENDMSG_QUEUE, address, delayMs);
+ }
+
/*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
synchronized (mDeviceStateLock) {
mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
@@ -1666,9 +1656,7 @@
}
/*package*/ boolean getBluetoothA2dpEnabled() {
- synchronized (mDeviceStateLock) {
- return mBluetoothA2dpEnabled;
- }
+ return mBluetoothA2dpEnabled.get();
}
/*package*/ int getLeAudioDeviceGroupId(BluetoothDevice device) {
@@ -1829,9 +1817,13 @@
}
break;
case MSG_IIL_SET_FORCE_USE: // intended fall-through
- case MSG_IIL_SET_FORCE_BT_A2DP_USE:
- onSetForceUse(msg.arg1, msg.arg2,
- (msg.what == MSG_IIL_SET_FORCE_BT_A2DP_USE), (String) msg.obj);
+ onSetForceUse(msg.arg1, msg.arg2, false, (String) msg.obj);
+ break;
+ case MSG_L_SET_FORCE_BT_A2DP_USE:
+ case MSG_L_SET_FORCE_BT_A2DP_USE_NO_MUTE:
+ int forcedUsage = mBluetoothA2dpEnabled.get()
+ ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP;
+ onSetForceUse(AudioSystem.FOR_MEDIA, forcedUsage, true, (String) msg.obj);
break;
case MSG_REPORT_NEW_ROUTES:
case MSG_REPORT_NEW_ROUTES_A2DP:
@@ -1839,35 +1831,38 @@
mDeviceInventory.onReportNewRoutes();
}
break;
- case MSG_L_SET_BT_ACTIVE_DEVICE:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
- if (btInfo.mState == BluetoothProfile.STATE_CONNECTED
- && !mBtHelper.isProfilePoxyConnected(btInfo.mProfile)) {
- AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
- "msg: MSG_L_SET_BT_ACTIVE_DEVICE "
- + "received with null profile proxy: "
- + btInfo)).printLog(TAG));
- } else {
- @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
- mBtHelper.getCodecWithFallback(btInfo.mDevice,
- btInfo.mProfile, btInfo.mIsLeOutput,
- "MSG_L_SET_BT_ACTIVE_DEVICE");
+ case MSG_L_SET_BT_ACTIVE_DEVICE: {
+ final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
+ if (btInfo.mState == BluetoothProfile.STATE_CONNECTED
+ && !mBtHelper.isProfilePoxyConnected(btInfo.mProfile)) {
+ AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
+ "msg: MSG_L_SET_BT_ACTIVE_DEVICE "
+ + "received with null profile proxy: "
+ + btInfo)).printLog(TAG));
+ } else {
+ @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
+ mBtHelper.getCodecWithFallback(btInfo.mDevice,
+ btInfo.mProfile, btInfo.mIsLeOutput,
+ "MSG_L_SET_BT_ACTIVE_DEVICE");
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
mDeviceInventory.onSetBtActiveDevice(btInfo, codec,
(btInfo.mProfile
- != BluetoothProfile.LE_AUDIO || btInfo.mIsLeOutput)
+ != BluetoothProfile.LE_AUDIO
+ || btInfo.mIsLeOutput)
? mAudioService.getBluetoothContextualVolumeStream()
: AudioSystem.STREAM_DEFAULT);
if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
- || btInfo.mProfile == BluetoothProfile.HEARING_AID) {
- onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
+ || btInfo.mProfile
+ == BluetoothProfile.HEARING_AID) {
+ onUpdateCommunicationRouteClient(
+ isBluetoothScoRequested(),
"setBluetoothActiveDevice");
}
}
}
}
- break;
+ } break;
case MSG_BT_HEADSET_CNCT_FAILED:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
@@ -1889,13 +1884,20 @@
(String) msg.obj, msg.arg1, msg.arg2);
}
break;
+ case MSG_IL_BT_HEARING_AID_TIMEOUT:
+ // msg.obj == address of Hearing Aid device
+ synchronized (mDeviceStateLock) {
+ mDeviceInventory.onMakeHearingAidDeviceUnavailableNow(
+ (String) msg.obj);
+ }
+ break;
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: {
final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
+ @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
+ mBtHelper.getCodecWithFallback(btInfo.mDevice,
+ btInfo.mProfile, btInfo.mIsLeOutput,
+ "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
synchronized (mDeviceStateLock) {
- @AudioSystem.AudioFormatNativeEnumForBtCodec final int codec =
- mBtHelper.getCodecWithFallback(btInfo.mDevice,
- btInfo.mProfile, btInfo.mIsLeOutput,
- "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
mDeviceInventory.onBluetoothDeviceConfigChange(
btInfo, codec, BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
}
@@ -2074,8 +2076,8 @@
}
} break;
- case MSG_L_UPDATED_ADI_DEVICE_STATE:
- mAudioService.onUpdatedAdiDeviceState((AdiDeviceState) msg.obj);
+ case MSG_IL_UPDATED_ADI_DEVICE_STATE:
+ mAudioService.onUpdatedAdiDeviceState((AdiDeviceState) msg.obj, msg.arg1 == 1);
break;
default:
@@ -2106,7 +2108,7 @@
private static final int MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE = 2;
private static final int MSG_I_BROADCAST_BT_CONNECTION_STATE = 3;
private static final int MSG_IIL_SET_FORCE_USE = 4;
- private static final int MSG_IIL_SET_FORCE_BT_A2DP_USE = 5;
+ private static final int MSG_L_SET_FORCE_BT_A2DP_USE = 5;
private static final int MSG_TOGGLE_HDMI = 6;
private static final int MSG_L_SET_BT_ACTIVE_DEVICE = 7;
private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
@@ -2162,9 +2164,9 @@
private static final int MSG_CHECK_COMMUNICATION_ROUTE_CLIENT_STATE = 56;
private static final int MSG_I_UPDATE_LE_AUDIO_GROUP_ADDRESSES = 57;
private static final int MSG_L_SYNCHRONIZE_ADI_DEVICES_IN_INVENTORY = 58;
- private static final int MSG_L_UPDATED_ADI_DEVICE_STATE = 59;
-
-
+ private static final int MSG_IL_UPDATED_ADI_DEVICE_STATE = 59;
+ private static final int MSG_L_SET_FORCE_BT_A2DP_USE_NO_MUTE = 60;
+ private static final int MSG_IL_BT_HEARING_AID_TIMEOUT = 61;
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {
@@ -2177,6 +2179,7 @@
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT:
case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT:
case MSG_CHECK_MUTE_MUSIC:
+ case MSG_IL_BT_HEARING_AID_TIMEOUT:
return true;
default:
return false;
@@ -2205,10 +2208,6 @@
sendIILMsg(msg, existingMsgPolicy, 0, 0, obj, delay);
}
- private void sendIMsg(int msg, int existingMsgPolicy, int arg, int delay) {
- sendIILMsg(msg, existingMsgPolicy, arg, 0, null, delay);
- }
-
private void sendMsgNoDelay(int msg, int existingMsgPolicy) {
sendIILMsg(msg, existingMsgPolicy, 0, 0, null, 0);
}
@@ -2265,6 +2264,7 @@
case MSG_IL_BTA2DP_TIMEOUT:
case MSG_IIL_BTLEAUDIO_TIMEOUT:
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE:
+ case MSG_IL_BT_HEARING_AID_TIMEOUT:
if (sLastDeviceConnectMsgTime >= time) {
// add a little delay to make sure messages are ordered as expected
time = sLastDeviceConnectMsgTime + 30;
@@ -2303,7 +2303,7 @@
MESSAGES_MUTE_MUSIC.add(MSG_L_SET_BT_ACTIVE_DEVICE);
MESSAGES_MUTE_MUSIC.add(MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE);
MESSAGES_MUTE_MUSIC.add(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT);
- MESSAGES_MUTE_MUSIC.add(MSG_IIL_SET_FORCE_BT_A2DP_USE);
+ MESSAGES_MUTE_MUSIC.add(MSG_L_SET_FORCE_BT_A2DP_USE);
}
private AtomicBoolean mMusicMuted = new AtomicBoolean(false);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index da13ad0..1f0f8c4 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -169,7 +169,7 @@
if (ads != null) {
if (ads.getAudioDeviceCategory() != category) {
ads.setAudioDeviceCategory(category);
- mDeviceBroker.postUpdatedAdiDeviceState(ads);
+ mDeviceBroker.postUpdatedAdiDeviceState(ads, false /*initSA*/);
mDeviceBroker.postPersistAudioDeviceSettings();
}
mDeviceBroker.postSynchronizeAdiDevicesInInventory(ads);
@@ -182,7 +182,7 @@
mDeviceInventory.put(ads.getDeviceId(), ads);
checkDeviceInventorySize_l();
- mDeviceBroker.postUpdatedAdiDeviceState(ads);
+ mDeviceBroker.postUpdatedAdiDeviceState(ads, true /*initSA*/);
mDeviceBroker.postPersistAudioDeviceSettings();
}
}
@@ -212,7 +212,7 @@
checkDeviceInventorySize_l();
}
if (updatedCategory.get()) {
- mDeviceBroker.postUpdatedAdiDeviceState(deviceState);
+ mDeviceBroker.postUpdatedAdiDeviceState(deviceState, false /*initSA*/);
}
mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState);
}
@@ -314,7 +314,7 @@
}
ads2.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
- mDeviceBroker.postUpdatedAdiDeviceState(ads2);
+ mDeviceBroker.postUpdatedAdiDeviceState(ads2, false /*initSA*/);
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"synchronizeBleDeviceInInventory synced device pair ads1="
+ updatedDevice + " ads2=" + ads2).printLog(TAG));
@@ -335,7 +335,7 @@
}
ads2.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
- mDeviceBroker.postUpdatedAdiDeviceState(ads2);
+ mDeviceBroker.postUpdatedAdiDeviceState(ads2, false /*initSA*/);
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"synchronizeBleDeviceInInventory synced device pair ads1="
+ updatedDevice + " peer ads2=" + ads2).printLog(TAG));
@@ -360,7 +360,7 @@
}
ads.setAudioDeviceCategory(updatedDevice.getAudioDeviceCategory());
- mDeviceBroker.postUpdatedAdiDeviceState(ads);
+ mDeviceBroker.postUpdatedAdiDeviceState(ads, false /*initSA*/);
AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
"synchronizeDeviceProfilesInInventory synced device pair ads1="
+ updatedDevice + " ads2=" + ads).printLog(TAG));
@@ -444,7 +444,7 @@
@Override
public DeviceInfo put(String key, DeviceInfo value) {
final DeviceInfo result = super.put(key, value);
- record("put", true /* connected */, key, value);
+ record("put", true /* connected */, value);
return result;
}
@@ -452,7 +452,7 @@
public DeviceInfo putIfAbsent(String key, DeviceInfo value) {
final DeviceInfo result = super.putIfAbsent(key, value);
if (result == null) {
- record("putIfAbsent", true /* connected */, key, value);
+ record("putIfAbsent", true /* connected */, value);
}
return result;
}
@@ -461,7 +461,7 @@
public DeviceInfo remove(Object key) {
final DeviceInfo result = super.remove(key);
if (result != null) {
- record("remove", false /* connected */, (String) key, result);
+ record("remove", false /* connected */, result);
}
return result;
}
@@ -470,7 +470,7 @@
public boolean remove(Object key, Object value) {
final boolean result = super.remove(key, value);
if (result) {
- record("remove", false /* connected */, (String) key, (DeviceInfo) value);
+ record("remove", false /* connected */, (DeviceInfo) value);
}
return result;
}
@@ -484,7 +484,7 @@
// putAll
// replace
// replaceAll
- private void record(String event, boolean connected, String key, DeviceInfo value) {
+ private void record(String event, boolean connected, DeviceInfo value) {
// DeviceInfo - int mDeviceType;
// DeviceInfo - int mDeviceCodecFormat;
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE
@@ -657,7 +657,7 @@
/**
* A class just for packaging up a set of connection parameters.
*/
- /*package*/ class WiredDeviceConnectionState {
+ /*package*/ static class WiredDeviceConnectionState {
public final AudioDeviceAttributes mAttributes;
public final @AudioService.ConnectionState int mState;
public final String mCaller;
@@ -961,6 +961,11 @@
}
}
+ /*package*/ void onMakeHearingAidDeviceUnavailableNow(String address) {
+ synchronized (mDevicesLock) {
+ makeHearingAidDeviceUnavailable(address);
+ }
+ }
/**
* Goes over all connected LE Audio devices in the provided group ID and
@@ -1021,7 +1026,9 @@
IAudioRoutesObserver obs = mRoutesObservers.getBroadcastItem(n);
try {
obs.dispatchAudioRoutesChanged(routes);
- } catch (RemoteException e) { }
+ } catch (RemoteException e) {
+ Log.e(TAG, "onReportNewRoutes", e);
+ }
}
}
mRoutesObservers.finishBroadcast();
@@ -1805,8 +1812,7 @@
final int delay = checkSendBecomingNoisyIntentInt(DEVICE_OUT_HEARING_AID,
AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE);
toRemove.stream().forEach(deviceAddress ->
- // TODO delay not used?
- makeHearingAidDeviceUnavailable(deviceAddress /*, delay*/)
+ makeHearingAidDeviceUnavailableLater(deviceAddress, delay)
);
}
}
@@ -2385,6 +2391,15 @@
mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
}
+ @GuardedBy("mDevicesLock")
+ private void makeHearingAidDeviceUnavailableLater(
+ String address, int delayMs) {
+ // the device will be made unavailable later, so consider it disconnected right away
+ mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(DEVICE_OUT_HEARING_AID, address));
+ // send the delayed message to make the device unavailable later
+ mDeviceBroker.setHearingAidTimeout(address, delayMs);
+ }
+
/**
* Returns whether a device of type DEVICE_OUT_HEARING_AID is connected.
* Visibility by APM plays no role
@@ -2664,10 +2679,6 @@
private static final String CONNECT_INTENT_KEY_PORT_NAME = "portName";
private static final String CONNECT_INTENT_KEY_STATE = "state";
private static final String CONNECT_INTENT_KEY_ADDRESS = "address";
- private static final String CONNECT_INTENT_KEY_HAS_PLAYBACK = "hasPlayback";
- private static final String CONNECT_INTENT_KEY_HAS_CAPTURE = "hasCapture";
- private static final String CONNECT_INTENT_KEY_HAS_MIDI = "hasMIDI";
- private static final String CONNECT_INTENT_KEY_DEVICE_CLASS = "class";
private void sendDeviceConnectionIntent(int device, int state, String address,
String deviceName) {
@@ -2830,6 +2841,7 @@
mPrefDevDispatchers.getBroadcastItem(i).dispatchPrefDevicesChanged(
strategy, devices);
} catch (RemoteException e) {
+ Log.e(TAG, "dispatchPreferredDevice ", e);
}
}
mPrefDevDispatchers.finishBroadcast();
@@ -2846,6 +2858,7 @@
mNonDefDevDispatchers.getBroadcastItem(i).dispatchNonDefDevicesChanged(
strategy, devices);
} catch (RemoteException e) {
+ Log.e(TAG, "dispatchNonDefaultDevice ", e);
}
}
mNonDefDevDispatchers.finishBroadcast();
@@ -2862,6 +2875,7 @@
mDevRoleCapturePresetDispatchers.getBroadcastItem(i).dispatchDevicesRoleChanged(
capturePreset, role, devices);
} catch (RemoteException e) {
+ Log.e(TAG, "dispatchDevicesRoleForCapturePreset ", e);
}
}
mDevRoleCapturePresetDispatchers.finishBroadcast();
@@ -2927,7 +2941,7 @@
/**
* Check if device is in the list of connected devices
- * @param device
+ * @param device the device to query
* @return true if connected
*/
@VisibleForTesting
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 6787fa6..8543a16 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -11265,7 +11265,8 @@
mDeviceBroker.addOrUpdateBtAudioDeviceCategoryInInventory(deviceState);
mDeviceBroker.postPersistAudioDeviceSettings();
- mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
+ mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(),
+ false /* initState */);
mSoundDoseHelper.setAudioDeviceCategory(addr, internalType,
btAudioDeviceCategory == AUDIO_DEVICE_CATEGORY_HEADPHONES);
}
@@ -11336,11 +11337,11 @@
/** Update the sound dose and spatializer state based on the new AdiDeviceState. */
@VisibleForTesting(visibility = PACKAGE)
- public void onUpdatedAdiDeviceState(AdiDeviceState deviceState) {
+ public void onUpdatedAdiDeviceState(AdiDeviceState deviceState, boolean initSA) {
if (deviceState == null) {
return;
}
- mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes());
+ mSpatializerHelper.refreshDevice(deviceState.getAudioDeviceAttributes(), initSA);
mSoundDoseHelper.setAudioDeviceCategory(deviceState.getDeviceAddress(),
deviceState.getInternalDeviceType(),
deviceState.getAudioDeviceCategory() == AUDIO_DEVICE_CATEGORY_HEADPHONES);
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 73ca6fb..8dc8af5 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -235,10 +235,6 @@
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_MEDIA, forMed, "onAudioServerDied()");
}
- /*package*/ synchronized boolean isAvrcpAbsoluteVolumeSupported() {
- return (mA2dp != null && mAvrcpAbsVolSupported);
- }
-
/*package*/ synchronized void setAvrcpAbsoluteVolumeSupported(boolean supported) {
mAvrcpAbsVolSupported = supported;
Log.i(TAG, "setAvrcpAbsoluteVolumeSupported supported=" + supported);
@@ -653,8 +649,6 @@
}
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
/*package*/ synchronized boolean isProfilePoxyConnected(int profile) {
switch (profile) {
case BluetoothProfile.HEADSET:
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 4426f8d..831679b 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -295,11 +295,11 @@
// could have been called another time after boot in case of audioserver restart
addCompatibleAudioDevice(
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_SPEAKER, ""),
- false /*forceEnable*/);
+ false /*forceEnable*/, false /*forceInit*/);
// not force-enabling as this device might already be in the device list
addCompatibleAudioDevice(
new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, ""),
- false /*forceEnable*/);
+ false /*forceEnable*/, false /*forceInit*/);
} catch (RemoteException e) {
resetCapabilities();
} finally {
@@ -523,7 +523,7 @@
}
synchronized void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada) {
- addCompatibleAudioDevice(ada, true /*forceEnable*/);
+ addCompatibleAudioDevice(ada, true /*forceEnable*/, false /*forceInit*/);
}
/**
@@ -537,7 +537,7 @@
*/
@GuardedBy("this")
private void addCompatibleAudioDevice(@NonNull AudioDeviceAttributes ada,
- boolean forceEnable) {
+ boolean forceEnable, boolean forceInit) {
if (!isDeviceCompatibleWithSpatializationModes(ada)) {
return;
}
@@ -545,6 +545,9 @@
final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada);
AdiDeviceState updatedDevice = null; // non-null on update.
if (deviceState != null) {
+ if (forceInit) {
+ initSAState(deviceState);
+ }
if (forceEnable && !deviceState.isSAEnabled()) {
updatedDevice = deviceState;
updatedDevice.setSAEnabled(true);
@@ -753,10 +756,10 @@
}
}
- synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada) {
+ synchronized void refreshDevice(@NonNull AudioDeviceAttributes ada, boolean initState) {
final AdiDeviceState deviceState = findSACompatibleDeviceStateForAudioDeviceAttributes(ada);
if (isAvailableForAdiDeviceState(deviceState)) {
- addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled());
+ addCompatibleAudioDevice(ada, /*forceEnable=*/deviceState.isSAEnabled(), initState);
setHeadTrackerEnabled(deviceState.isHeadTrackerEnabled(), ada);
} else {
removeCompatibleAudioDevice(ada);
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index d0b8990..f44b852 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -142,7 +142,6 @@
ERROR_KEYSTORE_FAILURE,
ERROR_NO_NETWORK,
ERROR_TIMEOUT_EXHAUSTED,
- ERROR_NO_REBOOT_ESCROW_DATA,
})
@Retention(RetentionPolicy.SOURCE)
@interface RebootEscrowErrorCode {
@@ -158,7 +157,6 @@
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;
@@ -507,9 +505,6 @@
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/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 200d004..d9fa1b8 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -5435,18 +5435,18 @@
}
if (!paths.getOverlayPaths().isEmpty()) {
pw.print(prefix);
- pw.println(" ");
+ pw.print(" ");
pw.print(libOverlayPaths.getKey());
pw.println(" overlay paths:");
for (String path : paths.getOverlayPaths()) {
pw.print(prefix);
- pw.print(" ");
+ pw.print(" ");
pw.println(path);
}
}
if (!paths.getResourceDirs().isEmpty()) {
pw.print(prefix);
- pw.println(" ");
+ pw.print(" ");
pw.print(libOverlayPaths.getKey());
pw.println(" legacy overlay paths:");
for (String path : paths.getResourceDirs()) {
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index 24323c8..8a3c74b 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -1,24 +1,7 @@
{
"presubmit": [
{
- "name": "CtsPermissionTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "include-filter": "android.permission.cts.BackgroundPermissionsTest"
- },
- {
- "include-filter": "android.permission.cts.SplitPermissionTest"
- },
- {
- "include-filter": "android.permission.cts.PermissionFlagsTest"
- },
- {
- "include-filter": "android.permission.cts.SharedUidPermissionsTest"
- }
- ]
+ "name": "CtsPermissionTestCases_Platform"
},
{
"name": "CtsAppSecurityHostTestCases",
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 338b479..bdb174d 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -46,18 +46,7 @@
]
},
{
- "name": "CtsPermissionTestCases",
- "options": [
- {
- "exclude-annotation": "androidx.test.filters.FlakyTest"
- },
- {
- "include-filter": "android.permission.cts.SplitPermissionTest"
- },
- {
- "include-filter": "android.permission.cts.BackgroundPermissionsTest"
- }
- ]
+ "name": "CtsPermissionTestCases_Platform"
},
{
"name": "CtsBackupTestCases",
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index d0b70c3..da8b01a 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -176,8 +176,9 @@
final DreamManagerInternal dreamManager =
LocalServices.getService(DreamManagerInternal.class);
-
- dreamManager.registerDreamManagerStateListener(mDreamManagerStateListener);
+ if(dreamManager != null){
+ dreamManager.registerDreamManagerStateListener(mDreamManagerStateListener);
+ }
}
private final ServiceConnection mKeyguardConnection = new ServiceConnection() {
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index feaf181..e83c5f1 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1356,8 +1356,10 @@
new DisplayGroupPowerChangeListener();
mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
- // This DreamManager method does not acquire a lock, so it should be safe to call.
- mDreamManager.registerDreamManagerStateListener(new DreamManagerStateListener());
+ if(mDreamManager != null){
+ // This DreamManager method does not acquire a lock, so it should be safe to call.
+ mDreamManager.registerDreamManagerStateListener(new DreamManagerStateListener());
+ }
mWirelessChargerDetector = mInjector.createWirelessChargerDetector(sensorManager,
mInjector.createSuspendBlocker(
@@ -3463,7 +3465,7 @@
}
// Stop dream.
- if (isDreaming) {
+ if (isDreaming && mDreamManager != null) {
mDreamManager.stopDream(/* immediate= */ false, "power manager request" /*reason*/);
}
}
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 24d7acd..226e5fe 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -1609,8 +1609,7 @@
if (Flags.allowThermalHeadroomThresholds()) {
for (int severity = ThrottlingSeverity.LIGHT;
severity <= ThrottlingSeverity.SHUTDOWN; severity++) {
- if (severity != ThrottlingSeverity.SEVERE
- && threshold.hotThrottlingThresholds.length > severity) {
+ if (threshold.hotThrottlingThresholds.length > severity) {
updateHeadroomThreshold(severity,
threshold.hotThrottlingThresholds[severity],
severeThreshold);
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index 60454fc..5d2c50c 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -24,6 +24,7 @@
per-file Background*Start* = set noparent
per-file Background*Start* = file:/BAL_OWNERS
per-file Background*Start* = ogunwale@google.com, louischang@google.com
+per-file BackgroundLaunchProcessController.java = file:/BAL_OWNERS
# File related to activity callers
per-file ActivityCallerState.java = file:/core/java/android/app/COMPONENT_CALLER_OWNERS
diff --git a/services/tests/appfunctions/OWNERS b/services/tests/appfunctions/OWNERS
new file mode 100644
index 0000000..7fa8917
--- /dev/null
+++ b/services/tests/appfunctions/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 1627156
+include platform/frameworks/base:/core/java/android/app/appfunctions/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
index f1c1dc3..59f4d56b 100644
--- a/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/AudioDeviceBrokerTest.java
@@ -24,6 +24,7 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
@@ -315,7 +316,7 @@
mFakeBtDevice.getAddress()));
verify(mMockAudioService,
timeout(MAX_MESSAGE_HANDLING_DELAY_MS).times(0)).onUpdatedAdiDeviceState(
- eq(devState));
+ eq(devState), anyBoolean());
}
// metadata set
@@ -326,7 +327,7 @@
mFakeBtDevice.getAddress()));
verify(mMockAudioService,
timeout(MAX_MESSAGE_HANDLING_DELAY_MS)).onUpdatedAdiDeviceState(
- any());
+ any(), anyBoolean());
}
} finally {
// reset the metadata device type
@@ -354,7 +355,7 @@
verify(mMockAudioService,
timeout(MAX_MESSAGE_HANDLING_DELAY_MS).atLeast(1)).onUpdatedAdiDeviceState(
ArgumentMatchers.argThat(devState -> devState.getAudioDeviceCategory()
- == AudioManager.AUDIO_DEVICE_CATEGORY_OTHER));
+ == AudioManager.AUDIO_DEVICE_CATEGORY_OTHER), anyBoolean());
}
private void doTestConnectionDisconnectionReconnection(int delayAfterDisconnection,
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 17b499e..d6f7e21 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java
@@ -625,25 +625,10 @@
// 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
diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
index 0b61948..9c44332 100644
--- a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
+++ b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
@@ -23,13 +23,21 @@
import java.util.zip.ZipFile
fun main(args: Array<String>) {
- if (args.size != 2) {
+ if (args.size < 2 || args.size > 3) {
usage()
}
val zipFileName = args[0]
val aidlFileName = args[1]
+ var stable = false
+ if (args.size == 3) {
+ if (args[2] != "--guarantee_stable") {
+ usage()
+ }
+ stable = true
+ }
+
val zipFile: ZipFile
try {
@@ -55,6 +63,9 @@
val outFile = File(aidlFileName)
val outWriter = outFile.bufferedWriter()
for (parcelable in parcelables) {
+ if (stable) {
+ outWriter.write("@JavaOnlyStableParcelable ")
+ }
outWriter.write("parcelable ")
outWriter.write(parcelable.replace('/', '.').replace('$', '.'))
outWriter.write(";\n")