Merge "Revert "nfc(framework): Split non-updatable portion to a separat..."" into main
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/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/jni/Android.bp b/core/jni/Android.bp
index e71f607..7935ee5 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -90,7 +90,6 @@
"android_view_VelocityTracker.cpp",
"android_view_VerifiedKeyEvent.cpp",
"android_view_VerifiedMotionEvent.cpp",
- "com_android_internal_util_ArrayUtils.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
"core_jni_helpers.cpp",
":deviceproductinfoconstants_aidl",
@@ -271,6 +270,7 @@
"com_android_internal_os_ZygoteCommandBuffer.cpp",
"com_android_internal_os_ZygoteInit.cpp",
"com_android_internal_security_VerityUtils.cpp",
+ "com_android_internal_util_ArrayUtils.cpp",
"hwbinder/EphemeralStorage.cpp",
"fd_utils.cpp",
"android_hardware_input_InputWindowHandle.cpp",
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/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;