Merge "Do not build com_android_internal_util_ArrayUtils for host" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index f69fd55..e40b6bd 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -272,7 +272,7 @@
name: "android.nfc.flags-aconfig",
package: "android.nfc",
container: "system",
- srcs: ["nfc/java/android/nfc/*.aconfig"],
+ srcs: ["nfc-non-updatable/flags/*.aconfig"],
}
cc_aconfig_library {
diff --git a/Android.bp b/Android.bp
index 68048c6..35e59df 100644
--- a/Android.bp
+++ b/Android.bp
@@ -517,6 +517,50 @@
],
},
jarjar_prefix: "com.android.internal.hidden_from_bootclasspath",
+
+ jarjar_shards: select(release_flag("RELEASE_USE_SHARDED_JARJAR_ON_FRAMEWORK_MINUS_APEX"), {
+ true: "10",
+ default: "1",
+ }),
+}
+
+// This is identical to "framework-minus-apex" but with "jarjar_shards" hardcodd.
+// (also "stem" is commented out to avoid a conflict with the "framework-minus-apex")
+// TODO(b/383559945) This module is just for local testing / verification. It's not used
+// by anything. Remove it once we roll out RELEASE_USE_SHARDED_JARJAR_ON_FRAMEWORK_MINUS_APEX.
+java_library {
+ name: "framework-minus-apex_jarjar-sharded",
+ defaults: [
+ "framework-minus-apex-with-libs-defaults",
+ "framework-non-updatable-lint-defaults",
+ ],
+ installable: true,
+ // For backwards compatibility.
+ // stem: "framework",
+ apex_available: ["//apex_available:platform"],
+ visibility: [
+ "//frameworks/base",
+ "//frameworks/base/location",
+ // TODO(b/147128803) remove the below lines
+ "//frameworks/base/apex/blobstore/framework",
+ "//frameworks/base/apex/jobscheduler/framework",
+ "//frameworks/base/packages/Tethering/tests/unit",
+ "//packages/modules/Connectivity/Tethering/tests/unit",
+ ],
+ errorprone: {
+ javacflags: [
+ "-Xep:AndroidFrameworkCompatChange:ERROR",
+ "-Xep:AndroidFrameworkUid:ERROR",
+ ],
+ },
+ lint: {
+ baseline_filename: "lint-baseline.xml",
+ warning_checks: [
+ "FlaggedApi",
+ ],
+ },
+ jarjar_prefix: "com.android.internal.hidden_from_bootclasspath",
+ jarjar_shards: "10",
}
java_library {
diff --git a/boot/preloaded-classes b/boot/preloaded-classes
index afd9984..b83bd4e 100644
--- a/boot/preloaded-classes
+++ b/boot/preloaded-classes
@@ -6583,6 +6583,7 @@
android.permission.PermissionCheckerManager
android.permission.PermissionControllerManager$1
android.permission.PermissionControllerManager
+android.permission.PermissionManager
android.permission.PermissionManager$1
android.permission.PermissionManager$2
android.permission.PermissionManager$OnPermissionsChangeListenerDelegate
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 343de0b..e53c78f 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6587,6 +6587,7 @@
android.permission.PermissionCheckerManager
android.permission.PermissionControllerManager$1
android.permission.PermissionControllerManager
+android.permission.PermissionManager
android.permission.PermissionManager$1
android.permission.PermissionManager$2
android.permission.PermissionManager$OnPermissionsChangeListenerDelegate
diff --git a/config/preloaded-classes-denylist b/config/preloaded-classes-denylist
index 16f0693..e3e929c 100644
--- a/config/preloaded-classes-denylist
+++ b/config/preloaded-classes-denylist
@@ -3,7 +3,6 @@
android.net.ConnectivityThread$Singleton
android.os.FileObserver
android.os.NullVibrator
-android.permission.PermissionManager
android.provider.MediaStore
android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask
android.view.HdrRenderState
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 901326d..2b8780c 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -149,6 +149,13 @@
}
flag {
+ name: "cache_sdk_system_features"
+ namespace: "system_performance"
+ description: "Feature flag to enable optimized cache for SDK-defined system feature lookups."
+ bug: "375000483"
+}
+
+flag {
name: "provide_info_of_apk_in_apex"
is_exported: true
namespace: "package_manager_service"
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index bde16c3..696288f 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -234,3 +234,11 @@
is_fixed_read_only: true
bug: "377557749"
}
+
+flag {
+ name: "api_for_backported_fixes"
+ namespace: "media_reliability"
+ description: "Public API app developers use to check if a known issue is fixed on a device."
+ bug: "308461809"
+ is_exported: true
+}
diff --git a/core/java/android/os/health/OWNERS b/core/java/android/os/health/OWNERS
index 6045344..26fc8fa 100644
--- a/core/java/android/os/health/OWNERS
+++ b/core/java/android/os/health/OWNERS
@@ -2,3 +2,6 @@
dplotnikov@google.com
mwachens@google.com
+
+# for headroom API only
+xwxw@google.com
\ No newline at end of file
diff --git a/framework-jarjar-rules.txt b/framework-jarjar-rules.txt
index 087378b..3da69e8 100644
--- a/framework-jarjar-rules.txt
+++ b/framework-jarjar-rules.txt
@@ -10,3 +10,6 @@
# For Perfetto proto dependencies
rule perfetto.protos.** android.internal.perfetto.protos.@1
+
+# For aconfig storage classes
+rule android.aconfig.storage.** android.internal.aconfig.storage.@1
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 4287daa..4f22c14 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -2871,7 +2871,8 @@
mSplitLayout.update(startTransaction, false /* resetImePosition */);
}
- if (mMixedHandler.isEnteringPip(change, transitType)) {
+ if (mMixedHandler.isEnteringPip(change, transitType)
+ && getSplitItemStage(change.getLastParent()) != STAGE_TYPE_UNDEFINED) {
pipChange = change;
}
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index d6fe6825..486063e 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -180,6 +180,15 @@
* a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
* </td>
* </tr>
+ * <tr>
+ * <td>{@link android.graphics.ImageFormat#YCBCR_P210 YCBCR_P210}</td>
+ * <td>3</td>
+ * <td>P210 is a 4:2:2 YCbCr semiplanar format comprised of a WxH Y plane
+ * followed by a WxH Cb and Cr planes. Each sample is represented by a 16-bit
+ * little-endian value, with the lower 6 bits set to zero. Since this is guaranteed to be
+ * a semi-planar format, the Cb plane can also be treated as an interleaved Cb/Cr plane.
+ * </td>
+ * </tr>
* </table>
*
* @see android.graphics.ImageFormat
diff --git a/media/java/android/media/ImageUtils.java b/media/java/android/media/ImageUtils.java
index f4caad7..83b056f 100644
--- a/media/java/android/media/ImageUtils.java
+++ b/media/java/android/media/ImageUtils.java
@@ -49,6 +49,7 @@
case ImageFormat.YUV_420_888:
case ImageFormat.NV21:
case ImageFormat.YCBCR_P010:
+ case ImageFormat.YCBCR_P210:
return 3;
case ImageFormat.NV16:
return 2;
@@ -88,6 +89,7 @@
switch(hardwareBufferFormat) {
case HardwareBuffer.YCBCR_420_888:
case HardwareBuffer.YCBCR_P010:
+ case HardwareBuffer.YCBCR_P210:
return 3;
case HardwareBuffer.RGBA_8888:
case HardwareBuffer.RGBX_8888:
@@ -269,6 +271,7 @@
case PixelFormat.RGBA_8888:
case PixelFormat.RGBX_8888:
case PixelFormat.RGBA_1010102:
+ case ImageFormat.YCBCR_P210:
estimatedBytePerPixel = 4.0;
break;
default:
@@ -318,6 +321,12 @@
return new Size(image.getWidth(), image.getHeight());
case ImageFormat.PRIVATE:
return new Size(0, 0);
+ case ImageFormat.YCBCR_P210:
+ if (planeIdx == 0) {
+ return new Size(image.getWidth(), image.getHeight());
+ } else {
+ return new Size(image.getWidth() / 2, image.getHeight());
+ }
default:
if (Log.isLoggable(IMAGEUTILS_LOG_TAG, Log.VERBOSE)) {
Log.v(IMAGEUTILS_LOG_TAG, "getEffectivePlaneSizeForImage() uses"
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 82e9503..36f62da 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -6158,11 +6158,14 @@
buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
+ (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
- if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010)
+ if ((mFormat == ImageFormat.YUV_420_888 || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
&& ix == 1) {
cbPlaneOffset = planeOffset;
} else if ((mFormat == ImageFormat.YUV_420_888
- || mFormat == ImageFormat.YCBCR_P010) && ix == 2) {
+ || mFormat == ImageFormat.YCBCR_P010
+ || mFormat == ImageFormat.YCBCR_P210)
+ && ix == 2) {
crPlaneOffset = planeOffset;
}
}
@@ -6172,7 +6175,7 @@
}
// Validate chroma semiplanerness.
- if (mFormat == ImageFormat.YCBCR_P010) {
+ if (mFormat == ImageFormat.YCBCR_P010 || mFormat == ImageFormat.YCBCR_P210) {
if (crPlaneOffset != cbPlaneOffset + planeOffsetInc) {
throw new UnsupportedOperationException("Invalid plane offsets"
+ " cbPlaneOffset: " + cbPlaneOffset + " crPlaneOffset: " + crPlaneOffset);
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp
index fbebbdc..e8f8644 100644
--- a/media/jni/android_media_Utils.cpp
+++ b/media/jni/android_media_Utils.cpp
@@ -17,13 +17,14 @@
// #define LOG_NDEBUG 0
#define LOG_TAG "AndroidMediaUtils"
+#include "android_media_Utils.h"
+
+#include <aidl/android/hardware/graphics/common/PixelFormat.h>
#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/GraphicTypes.h>
#include <utils/Log.h>
-#include "android_media_Utils.h"
-
#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
// Must be in sync with the value in HeicCompositeStream.cpp
@@ -33,6 +34,8 @@
// -----------Utility functions used by ImageReader/Writer JNI-----------------
+using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat;
+
enum {
IMAGE_MAX_NUM_PLANES = 3,
};
@@ -74,6 +77,7 @@
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
return false;
case HAL_PIXEL_FORMAT_YV12:
@@ -105,6 +109,7 @@
return false;
case HAL_PIXEL_FORMAT_YCBCR_P010:
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
default:
return true;
}
@@ -340,6 +345,47 @@
cb = buffer->data + ySize;
cr = cb + 2;
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
+ dataSize = (idx == 0) ? ySize : cSize;
+ rStride = buffer->stride * 2;
+ break;
+ case static_cast<int>(AidlPixelFormat::YCBCR_P210):
+ if (buffer->height % 2 != 0) {
+ ALOGE("YCBCR_P210: height (%d) should be a multiple of 2", buffer->height);
+ return BAD_VALUE;
+ }
+
+ if (buffer->width <= 0) {
+ ALOGE("YCBCR_P210: width (%d) should be a > 0", buffer->width);
+ return BAD_VALUE;
+ }
+
+ if (buffer->height <= 0) {
+ ALOGE("YCBCR_210: height (%d) should be a > 0", buffer->height);
+ return BAD_VALUE;
+ }
+ if (buffer->dataCb && buffer->dataCr) {
+ pData = (idx == 0) ? buffer->data : (idx == 1) ? buffer->dataCb : buffer->dataCr;
+ // only map until last pixel
+ if (idx == 0) {
+ pStride = 2;
+ rStride = buffer->stride;
+ dataSize = buffer->stride * (buffer->height - 1) + buffer->width * 2;
+ } else {
+ pStride = buffer->chromaStep;
+ rStride = buffer->chromaStride;
+ dataSize = buffer->chromaStride * (buffer->height - 1) +
+ buffer->chromaStep * (buffer->width / 2);
+ }
+ break;
+ }
+
+ ySize = (buffer->stride * 2) * buffer->height;
+ cSize = ySize;
+ pStride = (idx == 0) ? 2 : 4;
+ cb = buffer->data + ySize;
+ cr = cb + 2;
+
pData = (idx == 0) ? buffer->data : (idx == 1) ? cb : cr;
dataSize = (idx == 0) ? ySize : cSize;
rStride = buffer->stride * 2;
@@ -544,6 +590,80 @@
return OK;
}
+static status_t extractP210Gralloc4PlaneLayout(sp<GraphicBuffer> buffer, void *pData, int format,
+ LockedImage *outputImage) {
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
+ using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+ std::vector<ui::PlaneLayout> planeLayouts;
+ status_t res = mapper.getPlaneLayouts(buffer->handle, &planeLayouts);
+ if (res != OK) {
+ return res;
+ }
+ constexpr int64_t Y_PLANE_COMPONENTS = int64_t(PlaneLayoutComponentType::Y);
+ constexpr int64_t CBCR_PLANE_COMPONENTS =
+ int64_t(PlaneLayoutComponentType::CB) | int64_t(PlaneLayoutComponentType::CR);
+ uint8_t *dataY = nullptr;
+ uint8_t *dataCb = nullptr;
+ uint8_t *dataCr = nullptr;
+ uint32_t strideY = 0;
+ uint32_t strideCbCr = 0;
+ for (const ui::PlaneLayout &layout : planeLayouts) {
+ ALOGV("gralloc4 plane: %s", layout.toString().c_str());
+ int64_t components = 0;
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.sizeInBits != 10) {
+ return BAD_VALUE;
+ }
+ components |= component.type.value;
+ }
+ if (components == Y_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 16) {
+ return BAD_VALUE;
+ }
+ if (layout.components[0].offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ dataY = (uint8_t *)pData + layout.offsetInBytes;
+ strideY = layout.strideInBytes;
+ } else if (components == CBCR_PLANE_COMPONENTS) {
+ if (layout.sampleIncrementInBits != 32) {
+ return BAD_VALUE;
+ }
+ for (const PlaneLayoutComponent &component : layout.components) {
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CB) &&
+ component.offsetInBits != 6) {
+ return BAD_VALUE;
+ }
+ if (component.type.value == int64_t(PlaneLayoutComponentType::CR) &&
+ component.offsetInBits != 22) {
+ return BAD_VALUE;
+ }
+ }
+ dataCb = (uint8_t *)pData + layout.offsetInBytes;
+ dataCr = (uint8_t *)pData + layout.offsetInBytes + 2;
+ strideCbCr = layout.strideInBytes;
+ } else {
+ return BAD_VALUE;
+ }
+ }
+
+ outputImage->data = dataY;
+ outputImage->width = buffer->getWidth();
+ outputImage->height = buffer->getHeight();
+ outputImage->format = format;
+ outputImage->flexFormat =
+ static_cast<int>(AidlPixelFormat::YCBCR_P210);
+ outputImage->stride = strideY;
+
+ outputImage->dataCb = dataCb;
+ outputImage->dataCr = dataCr;
+ outputImage->chromaStride = strideCbCr;
+ outputImage->chromaStep = 4;
+ return OK;
+}
+
status_t lockImageFromBuffer(sp<GraphicBuffer> buffer, uint32_t inUsage,
const Rect& rect, int fenceFd, LockedImage* outputImage) {
ALOGV("%s: Try to lock the GraphicBuffer", __FUNCTION__);
@@ -581,10 +701,17 @@
ALOGE("Lock buffer failed!");
return res;
}
- if (isPossibly10BitYUV(format)
- && OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
- ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
- return OK;
+ if (isPossibly10BitYUV(format)) {
+ if (format == HAL_PIXEL_FORMAT_YCBCR_P010 &&
+ OK == extractP010Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P010 image", __FUNCTION__);
+ return OK;
+ } else if ((format ==
+ static_cast<int>(AidlPixelFormat::YCBCR_P210)) &&
+ OK == extractP210Gralloc4PlaneLayout(buffer, pData, format, outputImage)) {
+ ALOGV("%s: Successfully locked the P210 image", __FUNCTION__);
+ return OK;
+ }
}
}
diff --git a/nfc-non-updatable/Android.bp b/nfc-non-updatable/Android.bp
new file mode 100644
index 0000000..ff987bb
--- /dev/null
+++ b/nfc-non-updatable/Android.bp
@@ -0,0 +1,23 @@
+package {
+ default_team: "trendy_team_fwk_nfc",
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "framework-nfc-non-updatable-sources",
+ path: "java",
+ srcs: [
+ "java/android/nfc/NfcServiceManager.java",
+ "java/android/nfc/cardemulation/ApduServiceInfo.aidl",
+ "java/android/nfc/cardemulation/ApduServiceInfo.java",
+ "java/android/nfc/cardemulation/NfcFServiceInfo.aidl",
+ "java/android/nfc/cardemulation/NfcFServiceInfo.java",
+ "java/android/nfc/cardemulation/AidGroup.aidl",
+ "java/android/nfc/cardemulation/AidGroup.java",
+ ],
+}
diff --git a/nfc-non-updatable/OWNERS b/nfc-non-updatable/OWNERS
new file mode 100644
index 0000000..f46dccd
--- /dev/null
+++ b/nfc-non-updatable/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 48448
+include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc-non-updatable/flags/flags.aconfig
similarity index 100%
rename from nfc/java/android/nfc/flags.aconfig
rename to nfc-non-updatable/flags/flags.aconfig
diff --git a/nfc/java/android/nfc/NfcServiceManager.java b/nfc-non-updatable/java/android/nfc/NfcServiceManager.java
similarity index 100%
rename from nfc/java/android/nfc/NfcServiceManager.java
rename to nfc-non-updatable/java/android/nfc/NfcServiceManager.java
diff --git a/nfc/java/android/nfc/cardemulation/AidGroup.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/AidGroup.aidl
rename to nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl
diff --git a/nfc/java/android/nfc/cardemulation/AidGroup.java b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/AidGroup.java
rename to nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/ApduServiceInfo.aidl
rename to nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
rename to nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java
diff --git a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
rename to nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl
diff --git a/nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java
similarity index 100%
rename from nfc/java/android/nfc/cardemulation/NfcFServiceInfo.java
rename to nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java
diff --git a/nfc/Android.bp b/nfc/Android.bp
index c33665a..ff9588f 100644
--- a/nfc/Android.bp
+++ b/nfc/Android.bp
@@ -9,29 +9,12 @@
}
filegroup {
- name: "framework-nfc-non-updatable-sources",
- path: "java",
- srcs: [
- "java/android/nfc/NfcServiceManager.java",
- "java/android/nfc/cardemulation/ApduServiceInfo.aidl",
- "java/android/nfc/cardemulation/ApduServiceInfo.java",
- "java/android/nfc/cardemulation/NfcFServiceInfo.aidl",
- "java/android/nfc/cardemulation/NfcFServiceInfo.java",
- "java/android/nfc/cardemulation/AidGroup.aidl",
- "java/android/nfc/cardemulation/AidGroup.java",
- ],
-}
-
-filegroup {
name: "framework-nfc-updatable-sources",
path: "java",
srcs: [
"java/**/*.java",
"java/**/*.aidl",
],
- exclude_srcs: [
- ":framework-nfc-non-updatable-sources",
- ],
}
java_sdk_library {
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 0ee81cb..c8c479a 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -211,7 +211,7 @@
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
- method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
method public boolean removeAidsForService(android.content.ComponentName, String);
@@ -221,7 +221,7 @@
method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
method public boolean supportsAidPrefixRegistration();
- method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventListener(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
+ method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventCallback(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventCallback);
method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
method public boolean unsetPreferredService(android.app.Activity);
field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
@@ -244,7 +244,7 @@
field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
}
- @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener {
+ @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventCallback {
method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String);
method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String);
method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int);
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index bb9fe95..00ceaa9 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -17,7 +17,7 @@
package android.nfc;
import android.content.ComponentName;
-import android.nfc.INfcEventListener;
+import android.nfc.INfcEventCallback;
import android.nfc.cardemulation.AidGroup;
import android.nfc.cardemulation.ApduServiceInfo;
@@ -60,6 +60,6 @@
List<String> getRoutingStatus();
void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);
- void registerNfcEventListener(in INfcEventListener listener);
- void unregisterNfcEventListener(in INfcEventListener listener);
+ void registerNfcEventCallback(in INfcEventCallback listener);
+ void unregisterNfcEventCallback(in INfcEventCallback listener);
}
diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventCallback.aidl
similarity index 92%
rename from nfc/java/android/nfc/INfcEventListener.aidl
rename to nfc/java/android/nfc/INfcEventCallback.aidl
index 774d8f8..af1fa2fb 100644
--- a/nfc/java/android/nfc/INfcEventListener.aidl
+++ b/nfc/java/android/nfc/INfcEventCallback.aidl
@@ -5,7 +5,7 @@
/**
* @hide
*/
-oneway interface INfcEventListener {
+oneway interface INfcEventCallback {
void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
void onObserveModeStateChanged(boolean isEnabled);
void onAidConflictOccurred(in String aid);
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 89ce423..63397c2 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -1789,6 +1789,11 @@
* @param listenTechnology Flags indicating listen technologies.
* @throws UnsupportedOperationException if FEATURE_NFC,
* FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF are unavailable.
+ *
+ * NOTE: This API overrides all technology flags regardless of the current device state,
+ * it is incompatible with enableReaderMode() API and the others that either update
+ * or assume any techlology flag set by the OS.
+ * Please use with care.
*/
@FlaggedApi(Flags.FLAG_ENABLE_NFC_SET_DISCOVERY_TECH)
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index baae05b..fee9c5b 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -39,7 +39,7 @@
import android.nfc.Constants;
import android.nfc.Flags;
import android.nfc.INfcCardEmulation;
-import android.nfc.INfcEventListener;
+import android.nfc.INfcEventCallback;
import android.nfc.NfcAdapter;
import android.os.Build;
import android.os.RemoteException;
@@ -1304,7 +1304,7 @@
/** Listener for preferred service state changes. */
@FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- public interface NfcEventListener {
+ public interface NfcEventCallback {
/**
* This method is called when this package gains or loses preferred Nfc service status,
* either the Default Wallet Role holder (see {@link
@@ -1380,10 +1380,10 @@
default void onInternalErrorReported(@NfcInternalErrorType int errorType) {}
}
- private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>();
+ private final ArrayMap<NfcEventCallback, Executor> mNfcEventCallbacks = new ArrayMap<>();
- final INfcEventListener mINfcEventListener =
- new INfcEventListener.Stub() {
+ final INfcEventCallback mINfcEventCallback =
+ new INfcEventCallback.Stub() {
public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) {
if (!android.nfc.Flags.nfcEventListener()) {
return;
@@ -1443,12 +1443,12 @@
}
interface ListenerCall {
- void invoke(NfcEventListener listener);
+ void invoke(NfcEventCallback listener);
}
private void callListeners(ListenerCall listenerCall) {
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.forEach(
+ synchronized (mNfcEventCallbacks) {
+ mNfcEventCallbacks.forEach(
(listener, executor) -> {
executor.execute(() -> listenerCall.invoke(listener));
});
@@ -1463,34 +1463,34 @@
* @param listener The listener to register
*/
@FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- public void registerNfcEventListener(
- @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventListener listener) {
+ public void registerNfcEventCallback(
+ @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventCallback listener) {
if (!android.nfc.Flags.nfcEventListener()) {
return;
}
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.put(listener, executor);
- if (mNfcEventListeners.size() == 1) {
- callService(() -> sService.registerNfcEventListener(mINfcEventListener));
+ synchronized (mNfcEventCallbacks) {
+ mNfcEventCallbacks.put(listener, executor);
+ if (mNfcEventCallbacks.size() == 1) {
+ callService(() -> sService.registerNfcEventCallback(mINfcEventCallback));
}
}
}
/**
* Unregister a preferred service listener that was previously registered with {@link
- * #registerNfcEventListener(Executor, NfcEventListener)}
+ * #registerNfcEventCallback(Executor, NfcEventCallback)}
*
* @param listener The previously registered listener to unregister
*/
@FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
- public void unregisterNfcEventListener(@NonNull NfcEventListener listener) {
+ public void unregisterNfcEventCallback(@NonNull NfcEventCallback listener) {
if (!android.nfc.Flags.nfcEventListener()) {
return;
}
- synchronized (mNfcEventListeners) {
- mNfcEventListeners.remove(listener);
- if (mNfcEventListeners.size() == 0) {
- callService(() -> sService.unregisterNfcEventListener(mINfcEventListener));
+ synchronized (mNfcEventCallbacks) {
+ mNfcEventCallbacks.remove(listener);
+ if (mNfcEventCallbacks.size() == 0) {
+ callService(() -> sService.unregisterNfcEventCallback(mINfcEventCallback));
}
}
}
diff --git a/nfc/tests/Android.bp b/nfc/tests/Android.bp
index b6090e8..17fb810 100644
--- a/nfc/tests/Android.bp
+++ b/nfc/tests/Android.bp
@@ -29,7 +29,6 @@
"androidx.test.rules",
"androidx.test.runner",
"androidx.test.ext.junit",
- "framework-nfc.impl",
"mockito-target-extended-minus-junit4",
"frameworks-base-testutils",
"truth",
@@ -40,16 +39,25 @@
"testables",
],
libs: [
+ "androidx.annotation_annotation",
+ "unsupportedappusage", // for android.compat.annotation.UnsupportedAppUsage
+ "framework-permission-s.stubs.module_lib",
+ "framework-permission.stubs.module_lib",
"android.test.base.stubs.system",
"android.test.mock.stubs.system",
"android.test.runner.stubs.system",
+ "framework-nfc.impl",
],
jni_libs: [
// Required for ExtendedMockito
"libdexmakerjvmtiagent",
"libstaticjvmtiagent",
],
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ ":framework-nfc-updatable-sources",
+ ":framework-nfc-non-updatable-sources",
+ ],
platform_apis: true,
certificate: "platform",
test_suites: [
diff --git a/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java b/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
new file mode 100644
index 0000000..c24816d
--- /dev/null
+++ b/nfc/tests/src/android/nfc/NfcAntennaInfoTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NfcAntennaInfoTest {
+ private NfcAntennaInfo mNfcAntennaInfo;
+
+
+ @Before
+ public void setUp() {
+ AvailableNfcAntenna availableNfcAntenna = mock(AvailableNfcAntenna.class);
+ List<AvailableNfcAntenna> antennas = new ArrayList<>();
+ antennas.add(availableNfcAntenna);
+ mNfcAntennaInfo = new NfcAntennaInfo(1, 1, false, antennas);
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testGetDeviceHeight() {
+ int height = mNfcAntennaInfo.getDeviceHeight();
+ assertThat(height).isEqualTo(1);
+ }
+
+ @Test
+ public void testGetDeviceWidth() {
+ int width = mNfcAntennaInfo.getDeviceWidth();
+ assertThat(width).isEqualTo(1);
+ }
+
+ @Test
+ public void testIsDeviceFoldable() {
+ boolean foldable = mNfcAntennaInfo.isDeviceFoldable();
+ assertThat(foldable).isFalse();
+ }
+
+ @Test
+ public void testGetAvailableNfcAntennas() {
+ List<AvailableNfcAntenna> antennas = mNfcAntennaInfo.getAvailableNfcAntennas();
+ assertThat(antennas).isNotNull();
+ assertThat(antennas.size()).isEqualTo(1);
+ }
+
+}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 2d3b7f3..e600d45 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -10917,7 +10917,7 @@
private AudioDeviceAttributes anonymizeAudioDeviceAttributesUnchecked(
AudioDeviceAttributes ada) {
- if (!AudioSystem.isBluetoothDevice(ada.getInternalType())) {
+ if (ada == null || !AudioSystem.isBluetoothDevice(ada.getInternalType())) {
return ada;
}
AudioDeviceAttributes res = new AudioDeviceAttributes(ada);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 4c5f652..ac0892b 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1960,6 +1960,10 @@
public void onUserAdded(int userId) {
// If the user is restricted tie them to the parent user's VPN
UserInfo user = mUserManager.getUserInfo(userId);
+ if (user == null) {
+ Log.e(TAG, "Can not retrieve UserInfo for userId=" + userId);
+ return;
+ }
if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
synchronized(Vpn.this) {
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
@@ -1989,6 +1993,14 @@
public void onUserRemoved(int userId) {
// clean up if restricted
UserInfo user = mUserManager.getUserInfo(userId);
+ // TODO: Retrieving UserInfo upon receiving the USER_REMOVED intent is not guaranteed.
+ // This could prevent the removal of associated ranges. To ensure proper range removal,
+ // store the user info when adding ranges. This allows using the user ID in the
+ // USER_REMOVED intent to handle the removal process.
+ if (user == null) {
+ Log.e(TAG, "Can not retrieve UserInfo for userId=" + userId);
+ return;
+ }
if (user.isRestricted() && user.restrictedProfileParentId == mUserId) {
synchronized(Vpn.this) {
final Set<Range<Integer>> existingRanges = mNetworkCapabilities.getUids();
diff --git a/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
index 5636718..50a2b98 100644
--- a/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
+++ b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
@@ -193,11 +193,7 @@
@Override
public String toString() {
- if (mComponentName == null) {
- return "none";
- } else {
- return mUid + "/" + mComponentName.flattenToShortString();
- }
+ return mUid + "/" + mComponentName.flattenToShortString();
}
}
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 5db6a8f..9117cc8 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -918,6 +918,30 @@
}
@Test
+ public void testOnUserAddedAndRemoved_nullUserInfo() throws Exception {
+ final Vpn vpn = createVpn(PRIMARY_USER.id);
+ final Set<Range<Integer>> initialRange = rangeSet(PRIMARY_USER_RANGE);
+ // Note since mVpnProfile is a Ikev2VpnProfile, this starts an IkeV2VpnRunner.
+ startLegacyVpn(vpn, mVpnProfile);
+ // Set an initial Uid range and mock the network agent
+ vpn.mNetworkCapabilities.setUids(initialRange);
+ vpn.mNetworkAgent = mMockNetworkAgent;
+
+ // Add the restricted user and then remove it immediately. So the getUserInfo() will return
+ // null for the given restricted user id.
+ setMockedUsers(PRIMARY_USER, RESTRICTED_PROFILE_A);
+ doReturn(null).when(mUserManager).getUserInfo(RESTRICTED_PROFILE_A.id);
+ vpn.onUserAdded(RESTRICTED_PROFILE_A.id);
+ // Expect no range change to the NetworkCapabilities.
+ assertEquals(initialRange, vpn.mNetworkCapabilities.getUids());
+
+ // Remove the restricted user
+ vpn.onUserRemoved(RESTRICTED_PROFILE_A.id);
+ // Expect no range change to the NetworkCapabilities.
+ assertEquals(initialRange, vpn.mNetworkCapabilities.getUids());
+ }
+
+ @Test
public void testPrepare_throwSecurityExceptionWhenGivenPackageDoesNotBelongToTheCaller()
throws Exception {
mTestDeps.mIgnoreCallingUidChecks = false;