diff --git a/aosp_diff/aaos_iasw/packages/services/Car/0002-enable-virtio-camera-based-evs-app-for-A15.patch b/aosp_diff/aaos_iasw/packages/services/Car/0002-enable-virtio-camera-based-evs-app-for-A15.patch new file mode 100644 index 0000000000..037dfa0efa --- /dev/null +++ b/aosp_diff/aaos_iasw/packages/services/Car/0002-enable-virtio-camera-based-evs-app-for-A15.patch @@ -0,0 +1,2300 @@ +From 525f6f76bf4835381dea3af99304806d8f651e0e Mon Sep 17 00:00:00 2001 +From: shivasku82 +Date: Wed, 28 Aug 2024 12:50:32 +0530 +Subject: [PATCH] enable virtio camera evs in A15 + +--- + cpp/evs/apps/default/evs_app.rc | 1 - + cpp/evs/apps/default/res/config.json | 10 +- + cpp/evs/apps/default/src/EvsStateControl.cpp | 2 +- + cpp/evs/apps/default/src/RenderDirectView.cpp | 5 + + cpp/evs/manager/aidl/evsmanagerd.rc | 1 - + .../sampleDriver/aidl/include/EvsEnumerator.h | 2 + + .../sampleDriver/aidl/include/MediaControl.h | 244 ++++++ + cpp/evs/sampleDriver/aidl/include/NodeInfo.h | 51 ++ + cpp/evs/sampleDriver/aidl/include/SysCall.h | 81 ++ + .../sampleDriver/aidl/include/VideoCapture.h | 8 + + .../sampleDriver/aidl/include/bufferCopy.h | 3 + + .../sampleDriver/aidl/include/v4l2-subdev.h | 171 ++++ + ...ndroid.hardware.automotive.evs-default.xml | 1 + + .../sampleDriver/aidl/src/EvsEnumerator.cpp | 23 +- + .../sampleDriver/aidl/src/EvsV4lCamera.cpp | 5 +- + .../sampleDriver/aidl/src/MediaControl.cpp | 799 ++++++++++++++++++ + cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp | 57 ++ + cpp/evs/sampleDriver/aidl/src/SysCall.cpp | 171 ++++ + .../sampleDriver/aidl/src/VideoCapture.cpp | 212 +++-- + cpp/evs/sampleDriver/aidl/src/bufferCopy.cpp | 27 + + 20 files changed, 1810 insertions(+), 64 deletions(-) + create mode 100644 cpp/evs/sampleDriver/aidl/include/MediaControl.h + create mode 100644 cpp/evs/sampleDriver/aidl/include/NodeInfo.h + create mode 100644 cpp/evs/sampleDriver/aidl/include/SysCall.h + create mode 100644 cpp/evs/sampleDriver/aidl/include/v4l2-subdev.h + create mode 100644 cpp/evs/sampleDriver/aidl/src/MediaControl.cpp + create mode 100644 cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp + create mode 100644 cpp/evs/sampleDriver/aidl/src/SysCall.cpp + +diff --git a/cpp/evs/apps/default/evs_app.rc b/cpp/evs/apps/default/evs_app.rc +index 35cb73045..4ce1bce31 100644 +--- a/cpp/evs/apps/default/evs_app.rc ++++ b/cpp/evs/apps/default/evs_app.rc +@@ -3,7 +3,6 @@ service evs_app /system/bin/evs_app + priority -20 + user automotive_evs + group automotive_evs +- disabled # will not automatically start with its class; must be explictly started. + + on late-init + start evs_app +diff --git a/cpp/evs/apps/default/res/config.json b/cpp/evs/apps/default/res/config.json +index a6ab7484b..333afd8c7 100644 +--- a/cpp/evs/apps/default/res/config.json ++++ b/cpp/evs/apps/default/res/config.json +@@ -9,7 +9,7 @@ + "displays" : [ + { + "_comment": "Seahawk", +- "displayPort" : 129, ++ "displayPort" : 0, + "frontRange" : 100, + "rearRange" : 100 + }, +@@ -26,7 +26,7 @@ + }, + "cameras" : [ + { +- "cameraId" : "/dev/video10", ++ "cameraId" : "/dev/video0", + "function" : "reverse,park", + "x" : 0.0, + "y" : 20.0, +@@ -40,7 +40,7 @@ + "vflip" : false + }, + { +- "cameraId" : "/dev/video11", ++ "cameraId" : "/dev/video1", + "function" : "front,park", + "x" : 0.0, + "y" : 100.0, +@@ -54,7 +54,7 @@ + "vflip" : false + }, + { +- "cameraId" : "/dev/video12", ++ "cameraId" : "/dev/video2", + "function" : "right,park", + "x" : -25.0, + "y" : 60.0, +@@ -68,7 +68,7 @@ + "vflip" : false + }, + { +- "cameraId" : "/dev/video13", ++ "cameraId" : "/dev/video3", + "function" : "left, park", + "x" : 20.0, + "y" : 60.0, +diff --git a/cpp/evs/apps/default/src/EvsStateControl.cpp b/cpp/evs/apps/default/src/EvsStateControl.cpp +index 0192563ac..91dd7abda 100644 +--- a/cpp/evs/apps/default/src/EvsStateControl.cpp ++++ b/cpp/evs/apps/default/src/EvsStateControl.cpp +@@ -323,7 +323,7 @@ bool EvsStateControl::configureEvsPipeline(State desiredState) { + // Used by CarStats to accurately compute stats, it needs to be close to the beginning. + auto desiredStateTimeMillis = android::uptimeMillis(); + +- LOG(DEBUG) << "Switching to state " << desiredState; ++ LOG(INFO) << "Switching to state " << desiredState; + LOG(DEBUG) << " Current state " << mCurrentState << " has " + << mCameraList[mCurrentState].size() << " cameras"; + LOG(DEBUG) << " Desired state " << desiredState << " has " << mCameraList[desiredState].size() +diff --git a/cpp/evs/apps/default/src/RenderDirectView.cpp b/cpp/evs/apps/default/src/RenderDirectView.cpp +index e31957a10..dd8e29f27 100644 +--- a/cpp/evs/apps/default/src/RenderDirectView.cpp ++++ b/cpp/evs/apps/default/src/RenderDirectView.cpp +@@ -122,7 +122,12 @@ bool RenderDirectView::activate() { + LOG(WARNING) << "No stream configuration data is found; " + << "default parameters will be used."; + } ++ // This client always wants below input data format ++ targetCfg->format = aidl::android::hardware::graphics::common::PixelFormat::RGBA_8888; ++ foundCfg = true; + ++ targetCfg->width = 1920; ++ targetCfg->height = 1080; + // Construct our video texture + mTexture.reset(createVideoTexture(mEnumerator, mCameraDesc.id.c_str(), std::move(targetCfg), + sDisplay, mConfig.getUseExternalMemory(), +diff --git a/cpp/evs/manager/aidl/evsmanagerd.rc b/cpp/evs/manager/aidl/evsmanagerd.rc +index b2af31f54..f6c773a70 100644 +--- a/cpp/evs/manager/aidl/evsmanagerd.rc ++++ b/cpp/evs/manager/aidl/evsmanagerd.rc +@@ -3,4 +3,3 @@ service evsmanagerd /system/bin/evsmanagerd + priority -20 + user automotive_evs + group automotive_evs system +- disabled # will not automatically start with its class; must be explicitly started. +diff --git a/cpp/evs/sampleDriver/aidl/include/EvsEnumerator.h b/cpp/evs/sampleDriver/aidl/include/EvsEnumerator.h +index 313ecb7e5..84f24ec3d 100644 +--- a/cpp/evs/sampleDriver/aidl/include/EvsEnumerator.h ++++ b/cpp/evs/sampleDriver/aidl/include/EvsEnumerator.h +@@ -20,6 +20,7 @@ + #include "ConfigManager.h" + #include "EvsGlDisplay.h" + #include "EvsV4lCamera.h" ++#include "MediaControl.h" + + #include + #include +@@ -74,6 +75,7 @@ public: + EvsEnumerator(const std::shared_ptr< + ::aidl::android::frameworks::automotive::display::ICarDisplayProxy>& + proxyService); ++ virtual ~EvsEnumerator(); + + void notifyDeviceStatusChange(const std::string_view& deviceName, + aidlevs::DeviceStatusType type); +diff --git a/cpp/evs/sampleDriver/aidl/include/MediaControl.h b/cpp/evs/sampleDriver/aidl/include/MediaControl.h +new file mode 100644 +index 000000000..3383deec3 +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/include/MediaControl.h +@@ -0,0 +1,244 @@ ++/* ++ * Copyright (C) 2015-2021 Intel Corporation. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include "NodeInfo.h" ++ ++struct MediaEntity; ++struct MediaPad; ++struct MediaLink; ++ ++#define MEDIA_CTL_DEV_NAME "/dev/media" ++#define MEDIA_DRIVER_NAME "intel-ipu" ++#define MEDIA_DEVICE_MAX_NUM 256 ++ ++enum { ++ FC_FORMAT = 0, ++ FC_SELECTION = 1, ++}; ++ ++enum ResolutionType { ++ RESOLUTION_MAX = 0, ++ RESOLUTION_COMPOSE, ++ RESOLUTION_CROP, ++ RESOLUTION_TARGET, ++ ++}; ++ ++struct McFormat { ++ int entity; ++ int pad; ++ int stream; ++ int formatType; ++ int selCmd; ++ int top; ++ int left; ++ int width; ++ int height; ++ enum ResolutionType type; ++ std::string entityName; ++ unsigned int pixelCode; ++}; ++ ++struct McOutput { ++ int port; ++ unsigned int v4l2Format; ++ int width; ++ int height; ++ McOutput() { ++ port = -1; ++ v4l2Format = 0; ++ width = 0; ++ height = 0; ++ } ++}; ++ ++struct McCtl { ++ int entity; ++ int ctlCmd; ++ int ctlValue; ++ std::string ctlName; ++ std::string entityName; ++ McCtl() { ++ entity = 0; ++ ctlCmd = 0; ++ ctlValue = 0; ++ } ++}; ++ ++struct McLink { ++ int srcEntity; ++ int srcPad; ++ int sinkEntity; ++ int sinkPad; ++ bool enable; ++ std::string srcEntityName; ++ std::string sinkEntityName; ++}; ++ ++struct McRoute { ++ int entity; ++ uint32_t sinkPad; ++ uint32_t sinkStream; ++ uint32_t srcPad; ++ uint32_t srcStream; ++ uint32_t flag; ++ std::string entityName; ++ McRoute() { ++ entity = 0; ++ sinkPad = 0; ++ srcPad = 0; ++ sinkStream = 0; ++ srcStream = 0; ++ flag = 0; ++ entityName.clear(); ++ } ++}; ++ ++struct McVideoNode { ++ std::string name; ++ VideoNodeType videoNodeType; ++ McVideoNode() { videoNodeType = VIDEO_GENERIC; } ++}; ++ ++struct MediaCtlConf { ++ std::vector ctls; ++ std::vector links; ++ std::vector routes; ++ std::vector formats; ++ std::vector outputs; ++ std::vector videoNodes; ++ int mcId; ++ int outputWidth; ++ int outputHeight; ++ int format; ++ /* ++ * The outputWidth or outputHeight is 0 if there isn't this setting ++ * in MediaCtlConf. It means the isys output size is dynamic, and ++ * we don't use stream size to select MC. ++ */ ++ MediaCtlConf() { ++ mcId = -1; ++ outputWidth = 0; ++ outputHeight = 0; ++ format = -1; ++ } ++}; ++ ++/** ++ * \class MediaController ++ * ++ * This class is used for discovering and configuring the internal topology ++ * of a media device. Devices are modelled as an oriented graph of building ++ * blocks called media entities. The media entities are connected to each other ++ * through pads. ++ * ++ * Each media entity corresponds to a V4L2 subdevice. This class is also used ++ * for configuring the V4L2 subdevices. ++ */ ++ ++class MediaControl { ++ public: ++ /** ++ * \brief Get the singleton instance of MediaControl ++ */ ++ static MediaControl* getInstance(); ++ ++ /** ++ * \brief Release the singleton instance of MediaControl. ++ */ ++ static void releaseInstance(); ++ ++ /** ++ * \brief Enum entities and link, and reset all links ++ * ++ * \return 0 if succeed, other value indicates failed ++ */ ++ int initEntities(); ++ ++ /** ++ * \brief Free all entities and links memory ++ */ ++ void clearEntities(); ++ ++ /** ++ * \brief Get the entity by name ++ * ++ * \return entity id if succeed or -1 if error ++ */ ++ int getEntityIdByName(const char* name); ++ ++ int resetAllLinks(); ++ // VIRTUAL_CHANNEL_S ++ int resetAllRoutes(); ++ // VIRTUAL_CHANNEL_E ++ int createLink(); ++ ++ private: ++ MediaControl& operator=(const MediaControl&); ++ MediaControl(const char* devName); ++ ~MediaControl(); ++ ++ static MediaControl* getMediaControlInstance(); ++ int openDevice(); ++ void closeDevice(int fd); ++ void getDeviceName(const char* entityName, std::string& deviceNodeName, bool isSubDev); ++ int SetRouting(int fd, v4l2_subdev_route* routes, uint32_t numRoutes); ++ int GetRouting(int fd, v4l2_subdev_route* routes, uint32_t* numRoutes); ++ ++ // enum MediaControl info. ++ int enumInfo(); ++ int enumLinks(int fd); ++ int enumEntities(int fd); ++ ++ // get entity info. ++ int getDevnameFromSysfs(MediaEntity* entity); ++ MediaEntity* getEntityById(uint32_t id); ++ MediaEntity* getEntityByName(const char* name); ++ ++ // set up entity link. ++ ++ MediaLink* entityAddLink(MediaEntity* entity); ++ int setupLink(uint32_t srcEntity, uint32_t srcPad, uint32_t sinkEntity, uint32_t sinkPad, ++ bool enable); ++ int setupLink(MediaPad* source, MediaPad* sink, uint32_t flags); ++ ++ int SetFormat(int fd, const struct v4l2_subdev_format& format); ++ int setSelection(int cameraId, const McFormat* format, int targetWidth, int targetHeight); ++ ++ std::string mDevName; ++ std::vector mEntities; ++ ++ static MediaControl* sInstance; ++ static std::mutex sLock; ++}; +diff --git a/cpp/evs/sampleDriver/aidl/include/NodeInfo.h b/cpp/evs/sampleDriver/aidl/include/NodeInfo.h +new file mode 100644 +index 000000000..8e8401266 +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/include/NodeInfo.h +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (C) 2020 Intel Corporation ++ * ++ * 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. ++ */ ++ ++#pragma once ++ ++enum VideoNodeType { ++ // video node device ++ VIDEO_GENERIC, ++ VIDEO_GENERIC_MEDIUM_EXPO, ++ VIDEO_GENERIC_SHORT_EXPO, ++ // CSI_META_S ++ VIDEO_CSI_META, ++ // CSI_META_E ++ ++ // sensor subdevice ++ VIDEO_PIXEL_ARRAY, ++ VIDEO_PIXEL_BINNER, ++ VIDEO_PIXEL_SCALER, ++ ++ // ISP subdevice ++ VIDEO_ISYS_RECEIVER, ++ VIDEO_ISYS_RECEIVER_BACKEND, ++}; ++ ++struct VideoNodeInfo { ++ VideoNodeType type; ++ const char* fullName; ++ const char* shortName; ++}; ++ ++enum EncodeBufferType { ++ ENCODE_ISA_CONFIG = 0, ++ ENCODE_STATS = 1, ++}; ++ ++extern const VideoNodeInfo gVideoNodeInfos[]; ++extern const char* GetNodeName(VideoNodeType nodeType); ++extern VideoNodeType GetNodeType(const char* nodeName); +diff --git a/cpp/evs/sampleDriver/aidl/include/SysCall.h b/cpp/evs/sampleDriver/aidl/include/SysCall.h +new file mode 100644 +index 000000000..116a635fa +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/include/SysCall.h +@@ -0,0 +1,81 @@ ++/* ++ * Copyright (C) 2015-2021 Intel Corporation. ++ * ++ * 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. ++ */ ++ ++#pragma once ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++class SysCall { ++ protected: ++ SysCall(); ++ virtual ~SysCall(); ++ ++ public: ++ virtual int open(const char* pathname, int flags); ++ virtual int close(int fd); ++ virtual void* mmap(void* addr, size_t len, int prot, int flag, int filedes, off_t off); ++ virtual int munmap(void* addr, size_t len); ++ ++ virtual int ioctl(int fd, int request, struct media_device_info* arg); ++ virtual int ioctl(int fd, int request, struct media_link_desc* arg); ++ virtual int ioctl(int fd, int request, struct media_links_enum* arg); ++ virtual int ioctl(int fd, int request, struct media_links_desc* arg); ++ virtual int ioctl(int fd, int request, struct media_entity_desc* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_capability* arg); ++ virtual int ioctl(int fd, int request, v4l2_fmtdesc* arg); ++ virtual int ioctl(int fd, int request, enum v4l2_buf_type* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_format* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_requestbuffers* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_buffers* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_buffer* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_subdev_format* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_subdev_stream* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_streamon_info* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_ext_controls* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_control* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_queryctrl* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_subdev_selection* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_subdev_routing* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_querymenu* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_event_subscription* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_event* arg); ++ virtual int ioctl(int fd, int request, struct v4l2_exportbuffer* arg); ++ ++ virtual int poll(struct pollfd* pfd, nfds_t nfds, int timeout); ++ ++ static SysCall* getInstance(); ++ static void updateInstance(SysCall* newSysCall); ++ ++ private: ++ int ioctl(int fd, int request, void* arg); ++ ++ SysCall& operator=(const SysCall&); // Don't call me ++ ++ static bool sIsInitialized; ++ static SysCall* sInstance; ++ static std::mutex sLock; ++}; +diff --git a/cpp/evs/sampleDriver/aidl/include/VideoCapture.h b/cpp/evs/sampleDriver/aidl/include/VideoCapture.h +index 18537ad15..92ec2c5ab 100644 +--- a/cpp/evs/sampleDriver/aidl/include/VideoCapture.h ++++ b/cpp/evs/sampleDriver/aidl/include/VideoCapture.h +@@ -25,6 +25,11 @@ + + typedef v4l2_buffer imageBuffer; + ++#define VIDEO_PLANES 1 ++#define BUFFER_COUNT 6 ++#define WIDTH 1920 ++#define HEIGHT 1080 ++ + class VideoCapture final { + public: + bool open(const char* deviceName, const int32_t width = 0, const int32_t height = 0); +@@ -65,8 +70,11 @@ private: + bool returnFrame(int id); + + int mDeviceFd = -1; ++ uint32_t mBufferType = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + + int mNumBuffers = 0; ++ uint32_t mBufferSize; ++ + std::unique_ptr mBufferInfos = nullptr; + std::unique_ptr mPixelBuffers = nullptr; + +diff --git a/cpp/evs/sampleDriver/aidl/include/bufferCopy.h b/cpp/evs/sampleDriver/aidl/include/bufferCopy.h +index 21484cc88..eeabc5c41 100644 +--- a/cpp/evs/sampleDriver/aidl/include/bufferCopy.h ++++ b/cpp/evs/sampleDriver/aidl/include/bufferCopy.h +@@ -31,6 +31,9 @@ void fillNV21FromYUYV(const ::aidl::android::hardware::automotive::evs::BufferDe + void fillRGBAFromYUYV(const ::aidl::android::hardware::automotive::evs::BufferDesc& tgtBuff, + uint8_t* tgt, void* imgData, unsigned imgStride); + ++void fillRGBAFromUYVY(const BufferDesc& tgtBuff, uint8_t* tgt, ++ void* imgData, unsigned imgStride); ++ + void fillYUYVFromYUYV(const ::aidl::android::hardware::automotive::evs::BufferDesc& tgtBuff, + uint8_t* tgt, void* imgData, unsigned imgStride); + +diff --git a/cpp/evs/sampleDriver/aidl/include/v4l2-subdev.h b/cpp/evs/sampleDriver/aidl/include/v4l2-subdev.h +new file mode 100644 +index 000000000..94a89b636 +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/include/v4l2-subdev.h +@@ -0,0 +1,171 @@ ++/**************************************************************************** ++ **************************************************************************** ++ *** ++ *** This header was automatically generated from a Linux kernel header ++ *** of the same name, to make information necessary for userspace to ++ *** call into the kernel available to libc. It contains only constants, ++ *** structures, and macros generated from the original header, and thus, ++ *** contains no copyrightable information. ++ *** ++ *** To edit the content of this header, modify the corresponding ++ *** source file (e.g. under external/kernel-headers/original/) then ++ *** run bionic/libc/kernel/tools/update_all.py ++ *** ++ *** Any manual change here will be lost the next time this script will ++ *** be run. You've been warned! ++ *** ++ **************************************************************************** ++ ****************************************************************************/ ++#ifndef __LINUX_V4L2_SUBDEV_H ++#define __LINUX_V4L2_SUBDEV_H ++#include ++#include ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#include ++#include ++enum v4l2_subdev_format_whence { ++ V4L2_SUBDEV_FORMAT_TRY = 0, ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ V4L2_SUBDEV_FORMAT_ACTIVE = 1, ++}; ++struct v4l2_subdev_format { ++ __u32 which; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 pad; ++ struct v4l2_mbus_framefmt format; ++ __u32 stream; ++ __u32 reserved[7]; ++}; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++struct v4l2_subdev_crop { ++ __u32 which; ++ __u32 pad; ++ struct v4l2_rect rect; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 reserved[8]; ++}; ++struct v4l2_subdev_mbus_code_enum { ++ __u32 pad; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 index; ++ __u32 code; ++ __u32 which; ++ __u32 reserved[8]; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++}; ++struct v4l2_subdev_frame_size_enum { ++ __u32 index; ++ __u32 pad; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 code; ++ __u32 min_width; ++ __u32 max_width; ++ __u32 min_height; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 max_height; ++ __u32 which; ++ __u32 reserved[8]; ++}; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++struct v4l2_subdev_frame_interval { ++ __u32 pad; ++ struct v4l2_fract interval; ++ __u32 reserved[9]; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++}; ++struct v4l2_subdev_frame_interval_enum { ++ __u32 index; ++ __u32 pad; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 code; ++ __u32 width; ++ __u32 height; ++ struct v4l2_fract interval; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 which; ++ __u32 reserved[8]; ++}; ++struct v4l2_subdev_selection { ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ __u32 which; ++ __u32 pad; ++ __u32 target; ++ __u32 flags; ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++ struct v4l2_rect r; ++ __u32 reserved[8]; ++}; ++#define v4l2_subdev_edid v4l2_edid ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format) ++#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format) ++#define VIDIOC_SUBDEV_G_FRAME_INTERVAL _IOWR('V', 21, struct v4l2_subdev_frame_interval) ++#define VIDIOC_SUBDEV_S_FRAME_INTERVAL _IOWR('V', 22, struct v4l2_subdev_frame_interval) ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_ENUM_MBUS_CODE _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum) ++#define VIDIOC_SUBDEV_ENUM_FRAME_SIZE _IOWR('V', 74, struct v4l2_subdev_frame_size_enum) ++#define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum) ++#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop) ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop) ++#define VIDIOC_SUBDEV_G_SELECTION _IOWR('V', 61, struct v4l2_subdev_selection) ++#define VIDIOC_SUBDEV_S_SELECTION _IOWR('V', 62, struct v4l2_subdev_selection) ++#define VIDIOC_SUBDEV_G_STD _IOR('V', 23, v4l2_std_id) ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_S_STD _IOW('V', 24, v4l2_std_id) ++#define VIDIOC_SUBDEV_ENUMSTD _IOWR('V', 25, struct v4l2_standard) ++#define VIDIOC_SUBDEV_G_EDID _IOWR('V', 40, struct v4l2_edid) ++#define VIDIOC_SUBDEV_S_EDID _IOWR('V', 41, struct v4l2_edid) ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_QUERYSTD _IOR('V', 63, v4l2_std_id) ++#define VIDIOC_SUBDEV_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings) ++#define VIDIOC_SUBDEV_G_DV_TIMINGS _IOWR('V', 88, struct v4l2_dv_timings) ++#define VIDIOC_SUBDEV_ENUM_DV_TIMINGS _IOWR('V', 98, struct v4l2_enum_dv_timings) ++/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */ ++#define VIDIOC_SUBDEV_QUERY_DV_TIMINGS _IOR('V', 99, struct v4l2_dv_timings) ++#define VIDIOC_SUBDEV_DV_TIMINGS_CAP _IOWR('V', 100, struct v4l2_dv_timings_cap) ++#define VIDIOC_SUBDEV_S_ROUTING _IOWR('V', 39, struct v4l2_subdev_routing) ++#define VIDIOC_SUBDEV_G_ROUTING _IOWR('V', 38, struct v4l2_subdev_routing) ++#define V4L2_SUBDEV_ROUTE_FL_ACTIVE (1 << 0) ++#define V4L2_SUBDEV_ROUTE_FL_IMMUTABLE (1 << 1) ++#define V4L2_SUBDEV_ROUTE_FL_SOURCE (1 << 2) ++/** ++ * struct v4l2_subdev_route - A signal route inside a subdev ++ * @sink_pad: the sink pad ++ * @sink_stream: the sink stream ++ * @source_pad: the source pad ++ * @source_stream: the source stream ++ * @flags: route flags: ++ * ++ * V4L2_SUBDEV_ROUTE_FL_ACTIVE: Is the stream in use or not? An ++ * active stream will start when streaming is enabled on a video ++ * node. Set by the user. ++ * ++ * V4L2_SUBDEV_ROUTE_FL_SOURCE: Is the sub-device the source of a ++ * stream? In this case the sink information is unused (and ++ * zero). Set by the driver. ++ * ++ * V4L2_SUBDEV_ROUTE_FL_IMMUTABLE: Is the stream immutable, i.e. ++ * can it be activated and inactivated? Set by the driver. ++ */ ++struct v4l2_subdev_route { ++ __u32 sink_pad; ++ __u32 sink_stream; ++ __u32 source_pad; ++ __u32 source_stream; ++ __u32 flags; ++ __u32 reserved[5]; ++}; ++ ++/** ++ * struct v4l2_subdev_routing - Routing information ++ * @routes: the routes array ++ * @num_routes: the total number of routes in the routes array ++ */ ++struct v4l2_subdev_routing { ++ struct v4l2_subdev_route *routes; ++ __u32 num_routes; ++ __u32 reserved[5]; ++}; ++ ++#endif +diff --git a/cpp/evs/sampleDriver/aidl/manifest_android.hardware.automotive.evs-default.xml b/cpp/evs/sampleDriver/aidl/manifest_android.hardware.automotive.evs-default.xml +index ae37ad3f6..78a32a627 100644 +--- a/cpp/evs/sampleDriver/aidl/manifest_android.hardware.automotive.evs-default.xml ++++ b/cpp/evs/sampleDriver/aidl/manifest_android.hardware.automotive.evs-default.xml +@@ -1,6 +1,7 @@ + + + android.hardware.automotive.evs ++ 2 + IEvsEnumerator/hw/1 + + +diff --git a/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp b/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp +index b79ed101a..7924ff43c 100644 +--- a/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp ++++ b/cpp/evs/sampleDriver/aidl/src/EvsEnumerator.cpp +@@ -146,11 +146,26 @@ EvsEnumerator::EvsEnumerator(const std::shared_ptr& proxyServi + sDisplayProxy = proxyService; + } + ++ MediaControl* mc = MediaControl::getInstance(); ++ if (mc) { ++ mc->initEntities(); ++ mc->resetAllRoutes(); ++ mc->createLink(); ++ } ++ + // Enumerate existing devices + enumerateCameras(); + mInternalDisplayId = enumerateDisplays(); + } + ++EvsEnumerator::~EvsEnumerator() { ++ MediaControl* mc = MediaControl::getInstance(); ++ if (mc) { ++ mc->clearEntities(); ++ MediaControl::releaseInstance(); ++ } ++} ++ + bool EvsEnumerator::checkPermission() { + const auto uid = AIBinder_getCallingUid(); + if (kAllowedUids.find(uid) == kAllowedUids.end()) { +@@ -613,14 +628,15 @@ bool EvsEnumerator::qualifyCaptureDevice(const char* deviceName) { + if (result < 0) { + return false; + } +- if (((caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) || ++ if (((caps.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) == 0) || + ((caps.capabilities & V4L2_CAP_STREAMING) == 0)) { + return false; + } + + // Enumerate the available capture formats (if any) + v4l2_fmtdesc formatDescription; +- formatDescription.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ formatDescription.type = (caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) ? V4L2_BUF_TYPE_VIDEO_CAPTURE : V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ + bool found = false; + for (int i = 0; !found; ++i) { + formatDescription.index = i; +@@ -631,6 +647,7 @@ bool EvsEnumerator::qualifyCaptureDevice(const char* deviceName) { + << formatDescription.flags; + switch (formatDescription.pixelformat) { + case V4L2_PIX_FMT_YUYV: ++ case V4L2_PIX_FMT_UYVY: + found = true; + break; + case V4L2_PIX_FMT_NV21: +@@ -654,7 +671,7 @@ bool EvsEnumerator::qualifyCaptureDevice(const char* deviceName) { + break; + #endif // V4L2_PIX_FMT_ARGB32 + default: +- LOG(WARNING) << "Unsupported, " << std::hex << formatDescription.pixelformat; ++ LOG(WARNING) << "Shiva Unsupported, " << std::hex << formatDescription.pixelformat; + break; + } + } else { +diff --git a/cpp/evs/sampleDriver/aidl/src/EvsV4lCamera.cpp b/cpp/evs/sampleDriver/aidl/src/EvsV4lCamera.cpp +index f9338c641..1a6816d34 100644 +--- a/cpp/evs/sampleDriver/aidl/src/EvsV4lCamera.cpp ++++ b/cpp/evs/sampleDriver/aidl/src/EvsV4lCamera.cpp +@@ -39,7 +39,7 @@ using ::android::base::Result; + using ::ndk::ScopedAStatus; + + // Default camera output image resolution +-constexpr std::array kDefaultResolution = {640, 480}; ++const std::array kDefaultResolution = {WIDTH, HEIGHT}; + + // Arbitrary limit on number of graphics buffers allowed to be allocated + // Safeguards against unreasonable resource consumption and provides a testable limit +@@ -185,6 +185,9 @@ ScopedAStatus EvsV4lCamera::startVideoStream(const std::shared_ptr ++#include ++ ++#include ++#include ++#include ++#include ++#include "SysCall.h" ++ ++using std::string; ++using std::vector; ++ ++#define MAX_SYS_NAME 64 ++#define MAX_TARGET_NAME 256 ++#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) ++ ++struct MediaLink { ++ MediaPad* source; ++ MediaPad* sink; ++ MediaLink* twin; ++ uint32_t flags; ++ uint32_t padding[3]; ++}; ++ ++struct MediaPad { ++ MediaEntity* entity; ++ uint32_t index; ++ uint32_t flags; ++ uint32_t padding[3]; ++}; ++ ++struct MediaEntity { ++ media_entity_desc info; ++ MediaPad* pads; ++ MediaLink* links; ++ unsigned int maxLinks; ++ unsigned int numLinks; ++ ++ char devname[32]; ++}; ++ ++MediaControl* MediaControl::sInstance = nullptr; ++std::mutex MediaControl::sLock; ++ ++int MediaControl::createLink() { ++ int ret = 0; ++ McFormat formats[] = { ++ {.entityName = "Intel IPU6 CSI-2 1", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI-2 1", ++ .pad = 1, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "isx031 a", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "isx031 b", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "isx031 c", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "isx031 d", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "TI960 a", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "TI960 a", ++ .pad = 1, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "TI960 a", ++ .pad = 2, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "TI960 a", ++ .pad = 3, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "TI960 a", ++ .pad = 4, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI2 BE SOC 0", ++ .pad = 0, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI2 BE SOC 0", ++ .pad = 1, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI2 BE SOC 0", ++ .pad = 2, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI2 BE SOC 0", ++ .pad = 3, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ {.entityName = "Intel IPU6 CSI2 BE SOC 0", ++ .pad = 4, ++ .pixelCode = V4L2_MBUS_FMT_UYVY8_1X16, ++ .width = WIDTH, ++ .height = HEIGHT}, ++ }; ++ ++ McLink links[] = { ++ {.srcEntityName = "isx031 a", .srcPad = 0, .sinkEntityName = "TI960 a", .sinkPad = 0}, ++ {.srcEntityName = "isx031 b", .srcPad = 0, .sinkEntityName = "TI960 a", .sinkPad = 1}, ++ {.srcEntityName = "isx031 c", .srcPad = 0, .sinkEntityName = "TI960 a", .sinkPad = 2}, ++ {.srcEntityName = "isx031 d", .srcPad = 0, .sinkEntityName = "TI960 a", .sinkPad = 3}, ++ {.srcEntityName = "TI960 a", ++ .srcPad = 4, ++ .sinkEntityName = "Intel IPU6 CSI-2 1", ++ .sinkPad = 0}, ++ {.srcEntityName = "Intel IPU6 CSI-2 1", ++ .srcPad = 1, ++ .sinkEntityName = "Intel IPU6 CSI2 BE SOC 0", ++ .sinkPad = 0}, ++ {.srcEntityName = "Intel IPU6 CSI2 BE SOC 0", ++ .srcPad = 1, ++ .sinkEntityName = "Intel IPU6 BE SOC capture 0", ++ .sinkPad = 0}, ++ {.srcEntityName = "Intel IPU6 CSI2 BE SOC 0", ++ .srcPad = 2, ++ .sinkEntityName = "Intel IPU6 BE SOC capture 1", ++ .sinkPad = 0}, ++ {.srcEntityName = "Intel IPU6 CSI2 BE SOC 0", ++ .srcPad = 3, ++ .sinkEntityName = "Intel IPU6 BE SOC capture 2", ++ .sinkPad = 0}, ++ {.srcEntityName = "Intel IPU6 CSI2 BE SOC 0", ++ .srcPad = 4, ++ .sinkEntityName = "Intel IPU6 BE SOC capture 3", ++ .sinkPad = 0}, ++ }; ++ ++ for (McFormat& format : formats) { ++ MediaEntity* entity = getEntityByName(format.entityName.c_str()); ++ int fd = -1; ++ if (entity) fd = ::open(entity->devname, O_RDWR); ++ ++ ALOGD("@%s, set format for %s pad: %d", __func__, format.entityName.c_str(), format.pad); ++ if (fd >= 0) { ++ v4l2_mbus_framefmt mbusfmt; ++ memset(&mbusfmt, 0, sizeof(mbusfmt)); ++ mbusfmt.width = format.width; ++ mbusfmt.height = format.height; ++ mbusfmt.code = format.pixelCode; ++ ++ struct v4l2_subdev_format fmt = {}; ++ fmt.pad = format.pad; ++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; ++ fmt.format = mbusfmt; ++ fmt.stream = format.stream; ++ ret = ::ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt); ++ close(fd); ++ if (ret < 0) { ++ ALOGE("@%s, Fail set format for %s pad: %d", __func__, format.entityName.c_str(), ++ format.pad); ++ } ++ } else { ++ // continue link others when fails ++ ALOGE("@%s, Fail set open device %s", __func__, format.entityName.c_str()); ++ } ++ } ++ ++ for (McLink& link : links) { ++ ALOGD("@%s, set link : %s --> %s", __func__, link.srcEntityName.c_str(), ++ link.sinkEntityName.c_str()); ++ ret = -1; ++ int srcEntity = getEntityIdByName(link.srcEntityName.c_str()); ++ int sinkEntity = getEntityIdByName(link.sinkEntityName.c_str()); ++ if (srcEntity >= 0 && sinkEntity >= 0) { ++ ret = setupLink(srcEntity, link.srcPad, sinkEntity, link.sinkPad, true); ++ } ++ if (ret < 0) { ++ ALOGE("@%s, Fail set link : %s --> %s", __func__, link.srcEntityName.c_str(), ++ link.sinkEntityName.c_str()); ++ } ++ } ++ return ret; ++} ++ ++void MediaControl::getDeviceName(const char* entityName, string& deviceNodeName, bool isSubDev) { ++ const char* filePrefix = "video"; ++ const char* dirPath = "/sys/class/video4linux/"; ++ if (isSubDev) filePrefix = "v4l-subdev"; ++ ++ DIR* dp = opendir(dirPath); ++ if (dp == nullptr) { ++ ALOGE("@%s, Fail open : %s", __func__, dirPath); ++ } ++ ++ struct dirent* dirp = nullptr; ++ while ((dirp = readdir(dp)) != nullptr) { ++ if ((dirp->d_type == DT_LNK) && ++ (strncmp(dirp->d_name, filePrefix, strlen(filePrefix)) == 0)) { ++ string subDeviceName = dirPath; ++ subDeviceName += dirp->d_name; ++ subDeviceName += "/name"; ++ int fd = open(subDeviceName.c_str(), O_RDONLY); ++ if (fd < 0) { ++ ALOGE("@%s, Fail open : %s", __func__, subDeviceName.c_str()); ++ } ++ ++ char buf[128] = {'\0'}; ++ int len = read(fd, buf, sizeof(buf)); ++ close(fd); ++ len--; // remove "\n" ++ if (len == (int)strlen(entityName) && memcmp(buf, entityName, len) == 0) { ++ deviceNodeName = "/dev/"; ++ deviceNodeName += dirp->d_name; ++ break; ++ } ++ } ++ } ++ closedir(dp); ++} ++ ++MediaControl* MediaControl::getMediaControlInstance() { ++ MediaControl* mediaControlInstance = nullptr; ++ ++ for (int i = 0; i < MEDIA_DEVICE_MAX_NUM; i++) { ++ std::string fileName = MEDIA_CTL_DEV_NAME; ++ fileName.append(std::to_string(i)); ++ ++ struct stat fileStat = {}; ++ int ret = stat(fileName.c_str(), &fileStat); ++ if (ret != 0) { ++ ALOGE("%s: There is no file %s", __func__, fileName.c_str()); ++ continue; ++ } ++ ++ SysCall* sc = SysCall::getInstance(); ++ int fd = sc->open(fileName.c_str(), O_RDWR); ++ if (fd < 0) { ++ ALOGE("%s, Open media device(%s) failed: %s", __func__, fileName.c_str(), ++ strerror(errno)); ++ break; ++ } ++ ++ media_device_info info; ++ ret = sc->ioctl(fd, MEDIA_IOC_DEVICE_INFO, &info); ++ if ((ret != -1) && ++ (0 == strncmp(info.driver, MEDIA_DRIVER_NAME, strlen(MEDIA_DRIVER_NAME)))) { ++ mediaControlInstance = new MediaControl(fileName.c_str()); ++ } ++ ++ if (sc->close(fd) < 0) { ++ ALOGE("Failed to close media device %s:%s", fileName.c_str(), strerror(errno)); ++ } ++ ++ if (mediaControlInstance) { ++ ALOGE("%s: media device name:%s", __func__, fileName.c_str()); ++ break; ++ } ++ } ++ ++ return mediaControlInstance; ++} ++ ++MediaControl* MediaControl::getInstance() { ++ std::unique_lock lock(sLock); ++ if (!sInstance) { ++ sInstance = getMediaControlInstance(); ++ } ++ return sInstance; ++} ++ ++void MediaControl::releaseInstance() { ++ std::unique_lock lock(sLock); ++ ++ if (sInstance) { ++ delete sInstance; ++ sInstance = nullptr; ++ } ++} ++ ++MediaControl::MediaControl(const char* devName) : mDevName(devName) {} ++ ++MediaControl::~MediaControl() {} ++ ++int MediaControl::initEntities() { ++ mEntities.reserve(100); ++ ++ int ret = enumInfo(); ++ if (ret != 0) { ++ ALOGE("Enum Info failed.\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++void MediaControl::clearEntities() { ++ auto entity = mEntities.begin(); ++ while (entity != mEntities.end()) { ++ delete[] entity->pads; ++ entity->pads = nullptr; ++ delete[] entity->links; ++ entity->links = nullptr; ++ entity = mEntities.erase(entity); ++ } ++} ++ ++MediaEntity* MediaControl::getEntityByName(const char* name) { ++ for (auto& entity : mEntities) { ++ if (strcmp(name, entity.info.name) == 0) { ++ return &entity; ++ } ++ } ++ ++ return nullptr; ++} ++ ++int MediaControl::getEntityIdByName(const char* name) { ++ MediaEntity* entity = getEntityByName(name); ++ if (!entity) { ++ return -1; ++ } ++ ++ return entity->info.id; ++} ++ ++int MediaControl::resetAllLinks() { ++ for (auto& entity : mEntities) { ++ for (uint32_t j = 0; j < entity.numLinks; j++) { ++ MediaLink* link = &entity.links[j]; ++ ++ if (link->flags & MEDIA_LNK_FL_IMMUTABLE || ++ link->source->entity->info.id != entity.info.id) { ++ continue; ++ } ++ int ret = setupLink(link->source, link->sink, link->flags & ~MEDIA_LNK_FL_ENABLED); ++ ++ if (ret < 0) return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++int MediaControl::SetRouting(int fd, v4l2_subdev_route* routes, uint32_t numRoutes) { ++ if (!routes) { ++ ALOGE("%s: Device node %d routes is nullptr", __func__, fd); ++ return -EINVAL; ++ } ++ ++ v4l2_subdev_routing r = {routes, numRoutes, {0}}; ++ ++ int ret = ::ioctl(fd, VIDIOC_SUBDEV_S_ROUTING, &r); ++ if (ret < 0) { ++ ALOGE("%s: Device node %d IOCTL VIDIOC_SUBDEV_S_ROUTING error: %s", __func__, fd, ++ strerror(errno)); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++int MediaControl::GetRouting(int fd, v4l2_subdev_route* routes, uint32_t* numRoutes) { ++ if (!routes || !numRoutes) { ++ ALOGE("%s: Device node %d routes or numRoutes is nullptr", __func__, fd); ++ return -EINVAL; ++ } ++ ++ v4l2_subdev_routing r = {routes, *numRoutes, {0}}; ++ ++ int ret = ::ioctl(fd, VIDIOC_SUBDEV_G_ROUTING, &r); ++ if (ret < 0) { ++ ALOGE("%s: Device node %d IOCTL VIDIOC_SUBDEV_G_ROUTING error: %s", __func__, fd, ++ strerror(errno)); ++ return ret; ++ } ++ ++ *numRoutes = r.num_routes; ++ ++ return ret; ++} ++ ++int MediaControl::resetAllRoutes() { ++ for (MediaEntity& entity : mEntities) { ++ struct v4l2_subdev_route routes[entity.info.pads]; ++ uint32_t numRoutes = entity.info.pads; ++ ++ string subDeviceNodeName; ++ subDeviceNodeName.clear(); ++ getDeviceName(entity.info.name, subDeviceNodeName, true); ++ if (subDeviceNodeName.find("/dev/") == std::string::npos) { ++ continue; ++ } ++ ++ int fd = ::open(subDeviceNodeName.c_str(), O_RDWR); ++ int ret = GetRouting(fd, routes, &numRoutes); ++ if (ret != 0) { ++ close(fd); ++ continue; ++ } ++ ++ for (uint32_t j = 0; j < numRoutes; j++) { ++ routes[j].flags &= ~V4L2_SUBDEV_ROUTE_FL_ACTIVE; ++ } ++ ++ ret = SetRouting(fd, routes, numRoutes); ++ if (ret < 0) { ++ ALOGW("@%s, setRouting ret:%d", __func__, ret); ++ } ++ close(fd); ++ } ++ ++ return 0; ++} ++ ++int MediaControl::setupLink(MediaPad* source, MediaPad* sink, uint32_t flags) { ++ MediaLink* link = nullptr; ++ media_link_desc ulink; ++ uint32_t i; ++ int ret = 0; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ int fd = openDevice(); ++ if (fd < 0) goto done; ++ ++ for (i = 0; i < source->entity->numLinks; i++) { ++ link = &source->entity->links[i]; ++ ++ if (link->source->entity == source->entity && link->source->index == source->index && ++ link->sink->entity == sink->entity && link->sink->index == sink->index) ++ break; ++ } ++ ++ if (i == source->entity->numLinks) { ++ ALOGE("%s: Link not found", __func__); ++ ret = -ENOENT; ++ goto done; ++ } ++ ++ /* source pad */ ++ memset(&ulink, 0, sizeof(media_link_desc)); ++ ulink.source.entity = source->entity->info.id; ++ ulink.source.index = source->index; ++ ulink.source.flags = MEDIA_PAD_FL_SOURCE; ++ ++ /* sink pad */ ++ ulink.sink.entity = sink->entity->info.id; ++ ulink.sink.index = sink->index; ++ ulink.sink.flags = MEDIA_PAD_FL_SINK; ++ ++ if (link) ulink.flags = flags | (link->flags & MEDIA_LNK_FL_IMMUTABLE); ++ ++ ret = sc->ioctl(fd, MEDIA_IOC_SETUP_LINK, &ulink); ++ if (ret == -1) { ++ ret = -errno; ++ ALOGE("Unable to setup link (%s)", strerror(errno)); ++ goto done; ++ } ++ ++ if (link) { ++ link->flags = ulink.flags; ++ link->twin->flags = ulink.flags; ++ } ++ ++ ret = 0; ++ ++done: ++ closeDevice(fd); ++ return ret; ++} ++ ++int MediaControl::setupLink(uint32_t srcEntity, uint32_t srcPad, uint32_t sinkEntity, ++ uint32_t sinkPad, bool enable) { ++ ALOGD("@%s srcEntity %d srcPad %d sinkEntity %d sinkPad %d enable %d", __func__, srcEntity, ++ srcPad, sinkEntity, sinkPad, enable); ++ ++ for (auto& entity : mEntities) { ++ for (uint32_t j = 0; j < entity.numLinks; j++) { ++ MediaLink* link = &entity.links[j]; ++ ++ if ((link->source->entity->info.id == srcEntity) && (link->source->index == srcPad) && ++ (link->sink->entity->info.id == sinkEntity) && (link->sink->index == sinkPad)) { ++ if (enable) ++ link->flags |= MEDIA_LNK_FL_ENABLED; ++ else ++ link->flags &= ~MEDIA_LNK_FL_ENABLED; ++ ++ return setupLink(link->source, link->sink, link->flags); ++ } ++ } ++ } ++ ++ return -1; ++} ++ ++int MediaControl::openDevice() { ++ int fd; ++ SysCall* sc = SysCall::getInstance(); ++ ++ fd = sc->open(mDevName.c_str(), O_RDWR); ++ if (fd < 0) { ++ ALOGE("Failed to open media device %s: %s", mDevName.c_str(), strerror(errno)); ++ return -1; ++ } ++ ++ return fd; ++} ++ ++void MediaControl::closeDevice(int fd) { ++ if (fd < 0) return; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ if (sc->close(fd) < 0) { ++ ALOGE("Failed to close media device %s: %s", mDevName.c_str(), strerror(errno)); ++ } ++} ++ ++int MediaControl::enumInfo() { ++ SysCall* sc = SysCall::getInstance(); ++ ++ if (mEntities.size() > 0) return 0; ++ ++ int fd = openDevice(); ++ if (fd < 0) { ++ ALOGE("Open device failed."); ++ return fd; ++ } ++ ++ media_device_info info; ++ int ret = sc->ioctl(fd, MEDIA_IOC_DEVICE_INFO, &info); ++ if (ret < 0) { ++ ALOGE("Unable to retrieve media device information for device %s (%s)", mDevName.c_str(), ++ strerror(errno)); ++ goto done; ++ } ++ ++ ret = enumEntities(fd); ++ if (ret < 0) { ++ ALOGE("Unable to enumerate entities for device %s", mDevName.c_str()); ++ goto done; ++ } ++ ++ ALOGD("Found %lu entities, enumerating pads and links", mEntities.size()); ++ ++ ret = enumLinks(fd); ++ if (ret < 0) { ++ ALOGE("Unable to enumerate pads and linksfor device %s", mDevName.c_str()); ++ goto done; ++ } ++ ++ ret = 0; ++ ++done: ++ closeDevice(fd); ++ return ret; ++} ++ ++int MediaControl::enumEntities(int fd) { ++ MediaEntity entity; ++ uint32_t id; ++ int ret; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ for (id = 0, ret = 0;; id = entity.info.id) { ++ memset(&entity, 0, sizeof(MediaEntity)); ++ entity.info.id = id | MEDIA_ENT_ID_FLAG_NEXT; ++ ++ ret = sc->ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity.info); ++ if (ret < 0) { ++ ret = errno != EINVAL ? -errno : 0; ++ break; ++ } ++ ++ /* Number of links (for outbound links) plus number of pads (for ++ * inbound links) is a good safe initial estimate of the total ++ * number of links. ++ */ ++ entity.maxLinks = entity.info.pads + entity.info.links; ++ ++ entity.pads = new MediaPad[entity.info.pads]; ++ entity.links = new MediaLink[entity.maxLinks]; ++ getDevnameFromSysfs(&entity); ++ mEntities.push_back(entity); ++ ++ /* Note: carefully to move the follow setting. It must be behind of ++ * push_back to mEntities: ++ * 1. if entity is not pushed back to mEntities, getEntityById will ++ * return NULL. ++ * 2. we can't set entity.pads[i].entity to &entity direct. Because, ++ * entity is stack variable, its scope is just this function. ++ */ ++ for (uint32_t i = 0; i < entity.info.pads; ++i) { ++ entity.pads[i].entity = getEntityById(entity.info.id); ++ } ++ } ++ ++ return ret; ++} ++ ++int MediaControl::getDevnameFromSysfs(MediaEntity* entity) { ++ char sysName[MAX_SYS_NAME] = {'\0'}; ++ char target[MAX_TARGET_NAME] = {'\0'}; ++ int ret; ++ ++ if (!entity) { ++ ALOGE("entity is null."); ++ return -EINVAL; ++ } ++ ++ ret = snprintf(sysName, MAX_SYS_NAME, "/sys/dev/char/%u:%u", entity->info.v4l.major, ++ entity->info.v4l.minor); ++ if (ret <= 0) { ++ ALOGE("create sysName failed ret %d.", ret); ++ return -EINVAL; ++ } ++ ++ ret = readlink(sysName, target, MAX_TARGET_NAME); ++ if (ret <= 0) { ++ ALOGE("readlink sysName %s failed ret %d.", sysName, ret); ++ return -EINVAL; ++ } ++ ++ char* d = strrchr(target, '/'); ++ if (!d) { ++ ALOGE("target is invalid %s.", target); ++ return -EINVAL; ++ } ++ d++; /* skip '/' */ ++ ++ char* t = strstr(d, "dvb"); ++ if (t && t == d) { ++ t = strchr(t, '.'); ++ if (!t) { ++ ALOGE("target is invalid %s.", target); ++ return -EINVAL; ++ } ++ *t = '/'; ++ d += 3; /* skip "dvb" */ ++ snprintf(entity->devname, sizeof(entity->devname), "/dev/dvb/adapter%s", d); ++ } else { ++ snprintf(entity->devname, sizeof(entity->devname), "/dev/%s", d); ++ } ++ ++ return 0; ++} ++ ++int MediaControl::enumLinks(int fd) { ++ int ret = 0; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ for (auto& entity : mEntities) { ++ media_links_enum links; ++ uint32_t i; ++ ++ links.entity = entity.info.id; ++ links.pads = new media_pad_desc[entity.info.pads]; ++ links.links = new media_link_desc[entity.info.links]; ++ ++ if (sc->ioctl(fd, MEDIA_IOC_ENUM_LINKS, &links) < 0) { ++ ret = -errno; ++ ALOGE("Unable to enumerate pads and links (%s).", strerror(errno)); ++ delete[] links.pads; ++ delete[] links.links; ++ return ret; ++ } ++ ++ for (i = 0; i < entity.info.pads; ++i) { ++ entity.pads[i].entity = getEntityById(entity.info.id); ++ entity.pads[i].index = links.pads[i].index; ++ entity.pads[i].flags = links.pads[i].flags; ++ } ++ ++ for (i = 0; i < entity.info.links; ++i) { ++ media_link_desc* link = &links.links[i]; ++ MediaLink* fwdlink; ++ MediaLink* backlink; ++ MediaEntity* source; ++ MediaEntity* sink; ++ ++ source = getEntityById(link->source.entity); ++ sink = getEntityById(link->sink.entity); ++ ++ if (source == nullptr || sink == nullptr) { ++ ALOGE("WARNING entity %u link %u src %u/%u to %u/%u is invalid!", entity.info.id, i, ++ link->source.entity, link->source.index, link->sink.entity, link->sink.index); ++ ret = -EINVAL; ++ } else if (link->source.index < 0 || link->source.index >= source->info.pads) { ++ ALOGE("WARNING entity %u link %u src %u/%u index out of range!", entity.info.id, i, ++ link->source.entity, link->source.index); ++ ret = -EINVAL; ++ } else if (link->sink.index < 0 || link->sink.index >= sink->info.pads) { ++ ALOGE("WARNING entity %u link %u to %u/%u index out of range!", entity.info.id, i, ++ link->sink.entity, link->sink.index); ++ ret = -EINVAL; ++ } else { ++ fwdlink = entityAddLink(source); ++ if (fwdlink) { ++ fwdlink->source = &source->pads[link->source.index]; ++ fwdlink->sink = &sink->pads[link->sink.index]; ++ fwdlink->flags = link->flags; ++ } ++ ++ backlink = entityAddLink(sink); ++ if (backlink) { ++ backlink->source = &source->pads[link->source.index]; ++ backlink->sink = &sink->pads[link->sink.index]; ++ backlink->flags = link->flags; ++ } ++ ++ if (fwdlink) fwdlink->twin = backlink; ++ if (backlink) backlink->twin = fwdlink; ++ } ++ } ++ ++ delete[] links.pads; ++ delete[] links.links; ++ } ++ ++ return ret; ++} ++ ++MediaLink* MediaControl::entityAddLink(MediaEntity* entity) { ++ if (entity->numLinks >= entity->maxLinks) { ++ uint32_t maxLinks = entity->maxLinks * 2; ++ MediaLink* links = new MediaLink[maxLinks]; ++ ++ memcpy(links, entity->links, sizeof(MediaLink) * entity->maxLinks); ++ delete[] entity->links; ++ ++ for (uint32_t i = 0; i < entity->numLinks; ++i) { ++ links[i].twin->twin = &links[i]; ++ } ++ ++ entity->maxLinks = maxLinks; ++ entity->links = links; ++ } ++ ++ return &entity->links[entity->numLinks++]; ++} ++ ++MediaEntity* MediaControl::getEntityById(uint32_t id) { ++ bool next = id & MEDIA_ENT_ID_FLAG_NEXT; ++ ++ id &= ~MEDIA_ENT_ID_FLAG_NEXT; ++ ++ for (uint32_t i = 0; i < mEntities.size(); i++) { ++ if ((mEntities[i].info.id == id && !next) || (mEntities[0].info.id > id && next)) { ++ return &mEntities[i]; ++ } ++ } ++ ++ return nullptr; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp b/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp +new file mode 100644 +index 000000000..bc5a61842 +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2020 Intel Corporation ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include "NodeInfo.h" ++#include ++ ++#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) ++ ++const VideoNodeInfo gVideoNodeInfos[] = { ++ {VIDEO_GENERIC, "VIDEO_GENERIC", "Generic"}, ++ {VIDEO_GENERIC_MEDIUM_EXPO, "VIDEO_GENERIC_MEDIUM_EXPO", "GenericMediumExpo"}, ++ {VIDEO_GENERIC_SHORT_EXPO, "VIDEO_GENERIC_SHORT_EXPO", "GenericShortExpo"}, ++ // CSI_META_S ++ {VIDEO_CSI_META, "VIDEO_CSI_META", "CsiMeta"}, ++ // CSI_META_E ++ ++ {VIDEO_PIXEL_ARRAY, "VIDEO_PIXEL_ARRAY", "PixelArray"}, ++ {VIDEO_PIXEL_BINNER, "VIDEO_PIXEL_BINNER", "PixelBinner"}, ++ {VIDEO_PIXEL_SCALER, "VIDEO_PIXEL_SCALER", "PixelScaler"}, ++ ++ {VIDEO_ISYS_RECEIVER, "VIDEO_ISYS_RECEIVER", "ISysReceiver"}, ++ {VIDEO_ISYS_RECEIVER_BACKEND, "VIDEO_ISYS_RECEIVER_BACKEND", "CsiBE"}, ++}; ++ ++const char* GetNodeName(VideoNodeType nodeType) { ++ int size = ARRAY_SIZE(gVideoNodeInfos); ++ for (int i = 0; i < size; i++) { ++ if (gVideoNodeInfos[i].type == nodeType) { ++ return gVideoNodeInfos[i].shortName; ++ } ++ } ++ return "InvalidNode"; ++} ++ ++VideoNodeType GetNodeType(const char* nodeName) { ++ int size = ARRAY_SIZE(gVideoNodeInfos); ++ for (int i = 0; i < size; i++) { ++ if (strcmp(gVideoNodeInfos[i].fullName, nodeName) == 0) { ++ return gVideoNodeInfos[i].type; ++ } ++ } ++ ++ return VIDEO_GENERIC; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/SysCall.cpp b/cpp/evs/sampleDriver/aidl/src/SysCall.cpp +new file mode 100644 +index 000000000..b66e0e60b +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/src/SysCall.cpp +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (C) 2015-2021 Intel Corporation. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include "SysCall.h" ++#include ++#include ++ ++static int sCreatedCount = 0; ++bool SysCall::sIsInitialized = false; ++SysCall* SysCall::sInstance = nullptr; ++// Guard for singleton instance creation ++std::mutex SysCall::sLock; ++ ++/*static*/ SysCall* SysCall::getInstance() { ++ std::unique_lock lock(sLock); ++ if (!sIsInitialized) { ++ // Use real sys call as default ++ sInstance = new SysCall(); ++ sIsInitialized = true; ++ } ++ return sInstance; ++} ++ ++void SysCall::updateInstance(SysCall* newSysCall) { ++ ALOGI("%s", __func__); ++ std::unique_lock lock(sLock); ++ if (sIsInitialized) { ++ sIsInitialized = false; ++ } ++ sInstance = newSysCall; ++ if (newSysCall != nullptr) sIsInitialized = true; ++} ++ ++SysCall::SysCall() { ++ sCreatedCount++; ++ ALOGI("Syscall was created %d time", sCreatedCount); ++} ++ ++SysCall::~SysCall() { ++ sCreatedCount--; ++ ALOGI("Syscall was destructed %d time", sCreatedCount); ++} ++ ++int SysCall::open(const char* pathname, int flags) { ++ return ::open(pathname, flags); ++} ++ ++int SysCall::close(int fd) { ++ return ::close(fd); ++} ++ ++void* SysCall::mmap(void* addr, size_t len, int prot, int flag, int filedes, off_t off) { ++ return ::mmap(addr, len, prot, flag, filedes, off); ++} ++ ++int SysCall::munmap(void* addr, size_t len) { ++ return ::munmap(addr, len); ++} ++ ++int SysCall::ioctl(int fd, int request, struct media_device_info* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_link_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_links_enum* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_links_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_entity_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_capability* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, v4l2_fmtdesc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, enum v4l2_buf_type* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_format* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_requestbuffers* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_buffers* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_buffer* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_format* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_stream* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_streamon_info* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_ext_controls* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_control* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_queryctrl* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_selection* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_routing* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_querymenu* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_event_subscription* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_event* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_exportbuffer* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, void* arg) { ++ int ret = 0; ++ do { ++ ret = ::ioctl(fd, request, arg); ++ } while (-1 == ret && EINTR == errno); ++ ++ return ret; ++} ++ ++int SysCall::poll(struct pollfd* pfd, nfds_t nfds, int timeout) { ++ int ret = 0; ++ do { ++ ret = ::poll(pfd, nfds, timeout); ++ } while (-1 == ret && EINTR == errno); ++ ++ return ret; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp b/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp +index d0e9009be..b2c869428 100644 +--- a/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp ++++ b/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp +@@ -15,6 +15,8 @@ + */ + + #include "VideoCapture.h" ++#include ++#include + + #include + +@@ -37,8 +39,10 @@ + // the file descriptor. This must be fixed before using this code for anything but + // experimentation. + bool VideoCapture::open(const char* deviceName, const int32_t width, const int32_t height) { ++ ++ LOG(INFO) <<"App requested resolution "<= 0) { ++ struct v4l2_frmivalenum frmival; ++ memset(&frmival, 0, sizeof(frmival)); ++ frmival.pixel_format = formatDescriptions.pixelformat; ++ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { ++ frmival.width = frmsize.discrete.width; ++ frmival.height = frmsize.discrete.height; ++ while (ioctl(mDeviceFd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == 0) { ++ if ((frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) && ++ (1.0 * frmival.discrete.denominator / frmival.discrete.numerator > ++ 29.0) && ++ (requestWidth * requestHeight) < ++ frmsize.discrete.width * frmsize.discrete.height) { ++ if(frmsize.discrete.width == (uint32_t)width && frmsize.discrete.height == (uint32_t)height) { ++ LOG(INFO) <<"Driver support this resolution "; ++ requestWidth = frmsize.discrete.width; ++ requestHeight = frmsize.discrete.height; ++ break; ++ } ++ } ++ frmival.index++; ++ } ++ } else { ++ LOG(INFO) << "Stepwise: step_width=" << frmsize.stepwise.step_width<< " step_height=" << frmsize.stepwise.step_height; ++ LOG(INFO) << "min_width = " << frmsize.stepwise.min_width << " min_height=" << frmsize.stepwise.min_height; ++ LOG(INFO) << "max_width = " << frmsize.stepwise.max_width << " max_height=" << frmsize.stepwise.max_height; ++ requestWidth = frmsize.stepwise.min_width; ++ requestHeight = frmsize.stepwise.min_height; ++ ++ } ++ frmsize.index++; ++ } + } else { + // No more formats available + break; + } + } +- +- // Verify we can use this device for video capture +- if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) || +- !(caps.capabilities & V4L2_CAP_STREAMING)) { +- // Can't do streaming capture. +- LOG(ERROR) << "Streaming capture not supported by " << deviceName; +- return false; +- } +- + // Set our desired output format + v4l2_format format; +- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +- format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; +- format.fmt.pix.width = width; +- format.fmt.pix.height = height; +- LOG(INFO) << "Requesting format: " << ((char*)&format.fmt.pix.pixelformat)[0] +- << ((char*)&format.fmt.pix.pixelformat)[1] << ((char*)&format.fmt.pix.pixelformat)[2] +- << ((char*)&format.fmt.pix.pixelformat)[3] << "(" << std::hex << std::setw(8) +- << format.fmt.pix.pixelformat << ")"; ++ format.type = mBufferType; ++ if (format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_UYVY; ++ format.fmt.pix_mp.width = width; ++ format.fmt.pix_mp.height = height; ++ format.fmt.pix_mp.num_planes = 1; ++ format.fmt.pix_mp.plane_fmt[0].bytesperline = width * 2; ++ format.fmt.pix_mp.plane_fmt[0].sizeimage = width * height * 2; ++ } else if (strcmp((char*)caps.driver, "virtio-camera") == 0) { ++ LOG(INFO) << "Virtio-camera"< 0 ? requestWidth : 1280; ++ format.fmt.pix.height = requestHeight > 0 ? requestHeight : 960; ++ } else { ++ format.type = V4L2_CAP_VIDEO_CAPTURE; ++ format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; ++ format.fmt.pix.width = requestWidth > 0 ? requestWidth : width; ++ format.fmt.pix.height = requestHeight > 0 ? requestHeight : height; ++ } + + if (ioctl(mDeviceFd, VIDIOC_S_FMT, &format) < 0) { + PLOG(ERROR) << "VIDIOC_S_FMT failed"; + } + + // Report the current output format +- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(mDeviceFd, VIDIOC_G_FMT, &format) == 0) { +- mFormat = format.fmt.pix.pixelformat; +- mWidth = format.fmt.pix.width; +- mHeight = format.fmt.pix.height; +- mStride = format.fmt.pix.bytesperline; +- +- LOG(INFO) << "Current output format: " << "fmt=0x" << std::hex +- << format.fmt.pix.pixelformat << ", " << std::dec << format.fmt.pix.width << " x " +- << format.fmt.pix.height << ", pitch=" << format.fmt.pix.bytesperline; ++ if (format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ mFormat = format.fmt.pix_mp.pixelformat; ++ mWidth = format.fmt.pix_mp.width; ++ mHeight = format.fmt.pix_mp.height; ++ mStride = format.fmt.pix_mp.plane_fmt[0].bytesperline; ++ } else { ++ mFormat = format.fmt.pix.pixelformat; ++ mWidth = format.fmt.pix.width; ++ mHeight = format.fmt.pix.height; ++ mStride = format.fmt.pix.bytesperline; ++ } ++ ++ LOG(INFO) << "Current output format: " ++ << "fmt=0x" << std::hex << mFormat << ", " << std::dec << mWidth << " x " ++ << mHeight << ", pitch=" << mStride; + } else { + PLOG(ERROR) << "VIDIOC_G_FMT failed"; + return false; +@@ -148,45 +212,64 @@ bool VideoCapture::startStream(std::function(mNumBuffers); + mPixelBuffers = std::make_unique(mNumBuffers); + + for (int i = 0; i < mNumBuffers; ++i) { + // Get the information on the buffer that was created for us + memset(&mBufferInfos[i], 0, sizeof(v4l2_buffer)); +- mBufferInfos[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ mBufferInfos[i].type = mBufferType; + mBufferInfos[i].memory = V4L2_MEMORY_MMAP; + mBufferInfos[i].index = i; + ++ if (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ std::vector planes; ++ planes.resize(VIDEO_PLANES); ++ mBufferInfos[i].m.planes = planes.data(); ++ mBufferInfos[i].length = planes.size(); ++ } ++ + if (ioctl(mDeviceFd, VIDIOC_QUERYBUF, &mBufferInfos[i]) < 0) { + PLOG(ERROR) << "VIDIOC_QUERYBUF failed"; + return false; + } + ++ uint32_t memOffset = mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? ++ mBufferInfos[i].m.planes[0].m.mem_offset : ++ mBufferInfos[i].m.offset; + LOG(DEBUG) << "Buffer description:"; +- LOG(DEBUG) << " offset: " << mBufferInfos[i].m.offset; ++ LOG(INFO) << " offset: " << memOffset; + LOG(DEBUG) << " length: " << mBufferInfos[i].length; + LOG(DEBUG) << " flags : " << std::hex << mBufferInfos[i].flags; +- +- // Get a pointer to the buffer contents by mapping into our address space +- mPixelBuffers[i] = mmap(NULL, mBufferInfos[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, +- mDeviceFd, mBufferInfos[i].m.offset); +- +- if (mPixelBuffers[i] == MAP_FAILED) { +- PLOG(ERROR) << "mmap() failed"; +- return false; ++ if (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ LOG(INFO) << " size : " << std::hex << mBufferInfos[i].m.planes[0].length; ++ ++ mBufferSize = (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ? ++ mBufferInfos[i].m.planes[0].length : ++ mBufferInfos[i].length; ++ std::vector mappedBuffer; ++ mappedBuffer.resize(VIDEO_PLANES); ++ for (uint32_t plane = 0; plane < VIDEO_PLANES; plane++) { ++ mappedBuffer[plane] = ++ mmap(NULL, mBufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, mDeviceFd, memOffset); ++ ++ if (mappedBuffer[plane] == MAP_FAILED) { ++ PLOG(ERROR) << "mmap() failed"; ++ return false; ++ } ++ ++ memset(mappedBuffer[plane], 0, mBufferSize); + } +- +- memset(mPixelBuffers[i], 0, mBufferInfos[i].length); ++ mPixelBuffers[i] = mappedBuffer[0]; + LOG(INFO) << "Buffer mapped at " << mPixelBuffers[i]; + + // Queue the first capture buffer +@@ -197,10 +280,10 @@ bool VideoCapture::startStream(std::functionwidth, pDesc->height); ++ if (result) { ++ LOG(ERROR) << "Failed to convert BGRA to RGBA."; ++ } ++} ++ + void fillYUYVFromYUYV(const BufferDesc& tgtBuff, uint8_t* tgt, void* imgData, unsigned imgStride) { + const AHardwareBuffer_Desc* pDesc = + reinterpret_cast(&tgtBuff.buffer.description); +-- +2.17.1 + diff --git a/aosp_diff/base_aaos/build/make/0001-Fix-for-missing-vendor-lib-modules-folder.patch b/aosp_diff/base_aaos/build/make/0001-Fix-for-missing-vendor-lib-modules-folder.patch new file mode 100644 index 0000000000..7fe152a220 --- /dev/null +++ b/aosp_diff/base_aaos/build/make/0001-Fix-for-missing-vendor-lib-modules-folder.patch @@ -0,0 +1,68 @@ +From d32fd4baedc854115341ae1670cc0a5733971913 Mon Sep 17 00:00:00 2001 +From: Ankit Agrawal +Date: Mon, 26 Aug 2024 12:47:02 +0530 +Subject: [PATCH] Fix for missing vendor/lib/modules folder. + +It was looking file_list.txt file to get all the binaries list which +should be part of vendor.img image. this list is not having lib/modules +folder. + +Removing file_list.txt file lookup and creating vendor.img using all the +binaries in vendor folder. + +Tests: EB is successful and able to see vendor/lib/modules folder in +adb shell. + +Tracked-On: OAM-123896 +Signed-off-by: Ankit Agrawal +--- + core/Makefile | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +diff --git a/core/Makefile b/core/Makefile +index 6797a1d157..01b74d66de 100644 +--- a/core/Makefile ++++ b/core/Makefile +@@ -3854,16 +3854,15 @@ define build-vendorimage-target + $(call generate-image-prop-dictionary, $(vendorimage_intermediates)/vendor_image_info.txt,vendor,skip_fsck=true) + PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$PATH \ + $(BUILD_IMAGE) \ +- $(if $(BUILD_BROKEN_INCORRECT_PARTITION_IMAGES),,--input-directory-filter-file $(vendorimage_intermediates)/file_list.txt) \ + $(TARGET_OUT_VENDOR) $(vendorimage_intermediates)/vendor_image_info.txt \ + $(INSTALLED_VENDORIMAGE_TARGET) $(TARGET_OUT) + $(call assert-max-image-size,$(INSTALLED_VENDORIMAGE_TARGET) $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_VENDORIMAGE_PARTITION_SIZE)) + endef + +-$(eval $(call write-partition-file-list,$(vendorimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR),$(INTERNAL_VENDORIMAGE_FILES))) ++#$(eval $(call write-partition-file-list,$(vendorimage_intermediates)/file_list.txt,$(TARGET_OUT_VENDOR),$(INTERNAL_VENDORIMAGE_FILES))) + # Used by soong sandwich to request the staging dir be built +-$(vendorimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES)) +- touch $@ ++#$(vendorimage_intermediates)/staging_dir.stamp: $(filter $(TARGET_OUT_VENDOR)/%,$(INTERNAL_VENDORIMAGE_FILES)) ++# touch $@ + + # We just build this directly to the install location. + INSTALLED_VENDORIMAGE_TARGET := $(BUILT_VENDORIMAGE_TARGET) +@@ -3871,8 +3870,8 @@ $(INSTALLED_VENDORIMAGE_TARGET): \ + $(INTERNAL_USERIMAGES_DEPS) \ + $(INTERNAL_VENDORIMAGE_FILES) \ + $(INSTALLED_FILES_FILE_VENDOR) \ +- $(RECOVERY_FROM_BOOT_PATCH) \ +- $(vendorimage_intermediates)/file_list.txt ++ $(RECOVERY_FROM_BOOT_PATCH) ++ # $(vendorimage_intermediates)/file_list.txt + $(build-vendorimage-target) + + VENDOR_NOTICE_DEPS += $(INSTALLED_VENDORIMAGE_TARGET) +@@ -3881,7 +3880,7 @@ $(call declare-container-license-metadata,$(INSTALLED_VENDORIMAGE_TARGET),legacy + $(call declare-container-license-deps,$(INSTALLED_VENDORIMAGE_TARGET),$(INTERNAL_USERIMAGES_DEPS) $(INTERNAL_VENDORIMAGE_FILES) $(RECOVERY_FROM_BOOT_PATH),$(PRODUCT_OUT)/:/) + + .PHONY: vendorimage-nodeps vnod +-vendorimage-nodeps vnod: | $(INTERNAL_USERIMAGES_DEPS) $(vendorimage_intermediates)/file_list.txt ++vendorimage-nodeps vnod: | $(INTERNAL_USERIMAGES_DEPS) + $(build-vendorimage-target) + + .PHONY: sync_vendor +-- +2.34.1 + diff --git a/aosp_diff/base_aaos/build/make/0002-WA-Replaced-python-files-from-A14.patch b/aosp_diff/base_aaos/build/make/0002-WA-Replaced-python-files-from-A14.patch new file mode 100644 index 0000000000..5185a6cb2e --- /dev/null +++ b/aosp_diff/base_aaos/build/make/0002-WA-Replaced-python-files-from-A14.patch @@ -0,0 +1,2066 @@ +From 80b4c03fca9560dfd38abe957f00aa1eab4cc0f5 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Thu, 20 Jun 2024 10:38:57 +0530 +Subject: [PATCH] [WA] Replaced python files from A14. + +Facing some build issues due to python. +So replacing files from A14 for now. + +Tests: Prepared EB and it is successfull. + +Tracked-On: NA +Signed-off-by: Ankit Agarwal +--- + tools/releasetools/add_img_to_target_files.py | 137 +++-- + tools/releasetools/common.py | 557 ++++++++---------- + .../releasetools/merge/merge_target_files.py | 51 +- + tools/releasetools/test_common.py | 261 ++++---- + tools/releasetools/validate_target_files.py | 24 +- + 5 files changed, 486 insertions(+), 544 deletions(-) + +diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py +index b39a82cf45..3b6fd08412 100644 +--- a/tools/releasetools/add_img_to_target_files.py ++++ b/tools/releasetools/add_img_to_target_files.py +@@ -42,10 +42,6 @@ Usage: add_img_to_target_files [flag] target_files + --is_signing + Skip building & adding the images for "userdata" and "cache" if we + are signing the target files. +- +- --avb-resolve-rollback-index-location-conflict +- If provided, resolve the conflict AVB rollback index location when +- necessary. + """ + + from __future__ import print_function +@@ -69,10 +65,9 @@ import verity_utils + import ota_metadata_pb2 + import rangelib + import sparse_img +-from concurrent.futures import ThreadPoolExecutor ++ + from apex_utils import GetApexInfoFromTargetFiles + from common import ZipDelete, PARTITIONS_WITH_CARE_MAP, ExternalError, RunAndCheckOutput, IsSparseImage, MakeTempFile, ZipWrite +-from build_image import FIXED_FILE_TIMESTAMP + + if sys.hexversion < 0x02070000: + print("Python 2.7 or newer is required.", file=sys.stderr) +@@ -85,7 +80,12 @@ OPTIONS.add_missing = False + OPTIONS.rebuild_recovery = False + OPTIONS.replace_updated_files_list = [] + OPTIONS.is_signing = False +-OPTIONS.avb_resolve_rollback_index_location_conflict = False ++ ++# Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging ++# images. (b/24377993, b/80600931) ++FIXED_FILE_TIMESTAMP = int(( ++ datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None) - ++ datetime.datetime.utcfromtimestamp(0)).total_seconds()) + + + def ParseAvbFooter(img_path) -> avbtool.AvbFooter: +@@ -522,14 +522,12 @@ def AddPvmfw(output_zip): + return img.name + + +-def AddCustomImages(output_zip, partition_name, image_list): +- """Adds and signs avb custom images as needed in IMAGES/. ++def AddCustomImages(output_zip, partition_name): ++ """Adds and signs custom images in IMAGES/. + + Args: + output_zip: The output zip file (needs to be already open), or None to + write images to OPTIONS.input_tmp/. +- partition_name: The custom image partition name. +- image_list: The image list of the custom image partition. + + Uses the image under IMAGES/ if it already exists. Otherwise looks for the + image under PREBUILT_IMAGES/, signs it as needed, and returns the image name. +@@ -538,20 +536,19 @@ def AddCustomImages(output_zip, partition_name, image_list): + AssertionError: If image can't be found. + """ + +- builder = None + key_path = OPTIONS.info_dict.get("avb_{}_key_path".format(partition_name)) +- if key_path is not None: +- algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name)) +- extra_args = OPTIONS.info_dict.get( +- "avb_{}_add_hashtree_footer_args".format(partition_name)) +- partition_size = OPTIONS.info_dict.get( +- "avb_{}_partition_size".format(partition_name)) +- +- builder = verity_utils.CreateCustomImageBuilder( +- OPTIONS.info_dict, partition_name, partition_size, +- key_path, algorithm, extra_args) +- +- for img_name in image_list: ++ algorithm = OPTIONS.info_dict.get("avb_{}_algorithm".format(partition_name)) ++ extra_args = OPTIONS.info_dict.get( ++ "avb_{}_add_hashtree_footer_args".format(partition_name)) ++ partition_size = OPTIONS.info_dict.get( ++ "avb_{}_partition_size".format(partition_name)) ++ ++ builder = verity_utils.CreateCustomImageBuilder( ++ OPTIONS.info_dict, partition_name, partition_size, ++ key_path, algorithm, extra_args) ++ ++ for img_name in OPTIONS.info_dict.get( ++ "avb_{}_image_list".format(partition_name)).split(): + custom_image = OutputFile( + output_zip, OPTIONS.input_tmp, "IMAGES", img_name) + if os.path.exists(custom_image.name): +@@ -597,6 +594,15 @@ def CreateImage(input_dir, info_dict, what, output_file, block_list=None): + if block_list: + image_props["block_list"] = block_list.name + ++ # Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and ++ # build fingerprint). Also use the legacy build id, because the vbmeta digest ++ # isn't available at this point. ++ build_info = common.BuildInfo(info_dict, use_legacy_id=True) ++ uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what) ++ image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed)) ++ hash_seed = "hash_seed-" + uuid_seed ++ image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed)) ++ + build_image.BuildImage( + os.path.join(input_dir, what.upper()), image_props, output_file.name) + +@@ -687,12 +693,39 @@ def AddVBMeta(output_zip, partitions, name, needed_partitions): + logger.info("%s.img already exists; not rebuilding...", name) + return img.name + +- common.BuildVBMeta(img.name, partitions, name, needed_partitions, +- OPTIONS.avb_resolve_rollback_index_location_conflict) ++ common.BuildVBMeta(img.name, partitions, name, needed_partitions) + img.Write() + return img.name + + ++def AddPartitionTable(output_zip): ++ """Create a partition table image and store it in output_zip.""" ++ ++ img = OutputFile( ++ output_zip, OPTIONS.input_tmp, "IMAGES", "partition-table.img") ++ bpt = OutputFile( ++ output_zip, OPTIONS.input_tmp, "META", "partition-table.bpt") ++ ++ # use BPTTOOL from environ, or "bpttool" if empty or not set. ++ bpttool = os.getenv("BPTTOOL") or "bpttool" ++ cmd = [bpttool, "make_table", "--output_json", bpt.name, ++ "--output_gpt", img.name] ++ input_files_str = OPTIONS.info_dict["board_bpt_input_files"] ++ input_files = input_files_str.split() ++ for i in input_files: ++ cmd.extend(["--input", i]) ++ disk_size = OPTIONS.info_dict.get("board_bpt_disk_size") ++ if disk_size: ++ cmd.extend(["--disk_size", disk_size]) ++ args = OPTIONS.info_dict.get("board_bpt_make_table_args") ++ if args: ++ cmd.extend(shlex.split(args)) ++ common.RunAndCheckOutput(cmd) ++ ++ img.Write() ++ bpt.Write() ++ ++ + def AddCache(output_zip): + """Create an empty cache image and store it in output_zip.""" + +@@ -1049,15 +1082,8 @@ def AddImagesToTargetFiles(filename): + ("system_dlkm", has_system_dlkm, AddSystemDlkm, []), + ("system_other", has_system_other, AddSystemOther, []), + ) +- # If output_zip exists, each add_partition_calls writes bytes to the same output_zip, +- # which is not thread-safe. So, run them in serial if output_zip exists. +- if output_zip: +- for call in add_partition_calls: +- add_partition(*call) +- else: +- with ThreadPoolExecutor(max_workers=len(add_partition_calls)) as executor: +- for future in [executor.submit(add_partition, *call) for call in add_partition_calls]: +- future.result() ++ for call in add_partition_calls: ++ add_partition(*call) + + AddApexInfo(output_zip) + +@@ -1067,6 +1093,10 @@ def AddImagesToTargetFiles(filename): + banner("cache") + AddCache(output_zip) + ++ if OPTIONS.info_dict.get("board_bpt_enable") == "true": ++ banner("partition-table") ++ AddPartitionTable(output_zip) ++ + add_partition("dtbo", + OPTIONS.info_dict.get("has_dtbo") == "true", AddDtbo, []) + add_partition("pvmfw", +@@ -1074,29 +1104,18 @@ def AddImagesToTargetFiles(filename): + + # Custom images. + custom_partitions = OPTIONS.info_dict.get( +- "custom_images_partition_list", "").strip().split() ++ "avb_custom_images_partition_list", "").strip().split() + for partition_name in custom_partitions: + partition_name = partition_name.strip() + banner("custom images for " + partition_name) +- image_list = OPTIONS.info_dict.get( +- "{}_image_list".format(partition_name)).split() +- partitions[partition_name] = AddCustomImages(output_zip, partition_name, image_list) +- +- avb_custom_partitions = OPTIONS.info_dict.get( +- "avb_custom_images_partition_list", "").strip().split() +- for partition_name in avb_custom_partitions: +- partition_name = partition_name.strip() +- banner("avb custom images for " + partition_name) +- image_list = OPTIONS.info_dict.get( +- "avb_{}_image_list".format(partition_name)).split() +- partitions[partition_name] = AddCustomImages(output_zip, partition_name, image_list) ++ partitions[partition_name] = AddCustomImages(output_zip, partition_name) + + if OPTIONS.info_dict.get("avb_enable") == "true": + # vbmeta_partitions includes the partitions that should be included into + # top-level vbmeta.img, which are the ones that are not included in any + # chained VBMeta image plus the chained VBMeta images themselves. +- # Currently avb_custom_partitions are all chained to VBMeta image. +- vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(avb_custom_partitions) ++ # Currently custom_partitions are all chained to VBMeta image. ++ vbmeta_partitions = common.AVB_PARTITIONS[:] + tuple(custom_partitions) + + vbmeta_system = OPTIONS.info_dict.get("avb_vbmeta_system", "").strip() + if vbmeta_system: +@@ -1117,18 +1136,14 @@ def AddImagesToTargetFiles(filename): + item for item in vbmeta_partitions + if item not in vbmeta_vendor.split()] + vbmeta_partitions.append("vbmeta_vendor") +- custom_avb_partitions = OPTIONS.info_dict.get( +- "avb_custom_vbmeta_images_partition_list", "").strip().split() ++ custom_avb_partitions = OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split() + if custom_avb_partitions: + for avb_part in custom_avb_partitions: + partition_name = "vbmeta_" + avb_part +- included_partitions = OPTIONS.info_dict.get( +- "avb_vbmeta_{}".format(avb_part), "").strip().split() +- assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format( +- avb_part) ++ included_partitions = OPTIONS.info_dict.get("avb_vbmeta_{}".format(avb_part), "").strip().split() ++ assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format(avb_part) + banner(partition_name) +- logger.info("VBMeta partition {} needs {}".format( +- partition_name, included_partitions)) ++ logger.info("VBMeta partition {} needs {}".format(partition_name, included_partitions)) + partitions[partition_name] = AddVBMeta( + output_zip, partitions, partition_name, included_partitions) + vbmeta_partitions = [ +@@ -1136,6 +1151,7 @@ def AddImagesToTargetFiles(filename): + if item not in included_partitions] + vbmeta_partitions.append(partition_name) + ++ + if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true": + banner("vbmeta") + AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions) +@@ -1229,8 +1245,6 @@ def main(argv): + " please switch to AVB") + elif o == "--is_signing": + OPTIONS.is_signing = True +- elif o == "--avb_resolve_rollback_index_location_conflict": +- OPTIONS.avb_resolve_rollback_index_location_conflict = True + else: + return False + return True +@@ -1240,8 +1254,7 @@ def main(argv): + extra_long_opts=["add_missing", "rebuild_recovery", + "replace_verity_public_key=", + "replace_verity_private_key=", +- "is_signing", +- "avb_resolve_rollback_index_location_conflict"], ++ "is_signing"], + extra_option_handler=option_handler) + + if len(args) != 1: +diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py +index 0317cff897..a7b39c9684 100644 +--- a/tools/releasetools/common.py ++++ b/tools/releasetools/common.py +@@ -20,6 +20,7 @@ import copy + import datetime + import errno + import fnmatch ++from genericpath import isdir + import getopt + import getpass + import gzip +@@ -33,29 +34,21 @@ import re + import shlex + import shutil + import subprocess +-import stat + import sys + import tempfile + import threading + import time + import zipfile +- +-from typing import Iterable, Callable +-from dataclasses import dataclass + from hashlib import sha1, sha256 + + import images ++import rangelib + import sparse_img + from blockimgdiff import BlockImageDiff + + logger = logging.getLogger(__name__) + + +-@dataclass +-class OptionHandler: +- extra_long_opts: Iterable[str] +- handler: Callable +- + class Options(object): + + def __init__(self): +@@ -80,7 +73,9 @@ class Options(object): + if "ANDROID_HOST_OUT" in os.environ: + self.search_path = os.environ["ANDROID_HOST_OUT"] + self.signapk_shared_library_path = "lib64" # Relative to search_path ++ self.sign_sepolicy_path = None + self.extra_signapk_args = [] ++ self.extra_sign_sepolicy_args = [] + self.aapt2_path = "aapt2" + self.java_path = "java" # Use the one on the path by default. + self.java_args = ["-Xmx4096m"] # The default JVM args. +@@ -100,6 +95,8 @@ class Options(object): + self.cache_size = None + self.stash_threshold = 0.8 + self.logfile = None ++ self.host_tools = {} ++ self.sepolicy_name = 'sepolicy.apex' + + + OPTIONS = Options() +@@ -115,18 +112,13 @@ SPECIAL_CERT_STRINGS = ("PRESIGNED", "EXTERNAL") + # descriptor into vbmeta.img. When adding a new entry here, the + # AVB_FOOTER_ARGS_BY_PARTITION in sign_target_files_apks need to be updated + # accordingly. +-AVB_PARTITIONS = ('boot', 'init_boot', 'dtbo', 'odm', 'product', 'pvmfw', +- 'recovery', 'system', 'system_ext', 'vendor', 'vendor_boot', +- 'vendor_kernel_boot', 'vendor_dlkm', 'odm_dlkm', +- 'system_dlkm') ++AVB_PARTITIONS = ('boot', 'init_boot', 'dtbo', 'odm', 'product', 'pvmfw', 'recovery', ++ 'system', 'system_ext', 'vendor', 'vendor_boot', 'vendor_kernel_boot', ++ 'vendor_dlkm', 'odm_dlkm', 'system_dlkm') + + # Chained VBMeta partitions. + AVB_VBMETA_PARTITIONS = ('vbmeta_system', 'vbmeta_vendor') + +-# avbtool arguments name +-AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG = '--include_descriptors_from_image' +-AVB_ARG_NAME_CHAIN_PARTITION = '--chain_partition' +- + # Partitions that should have their care_map added to META/care_map.pb + PARTITIONS_WITH_CARE_MAP = [ + 'system', +@@ -147,19 +139,6 @@ PARTITIONS_WITH_BUILD_PROP = PARTITIONS_WITH_CARE_MAP + ['boot', 'init_boot'] + RAMDISK_BUILD_PROP_REL_PATHS = ['system/etc/ramdisk/build.prop'] + + +-@dataclass +-class AvbChainedPartitionArg: +- """The required arguments for avbtool --chain_partition.""" +- partition: str +- rollback_index_location: int +- pubkey_path: str +- +- def to_string(self): +- """Convert to string command arguments.""" +- return '{}:{}:{}'.format( +- self.partition, self.rollback_index_location, self.pubkey_path) +- +- + class ErrorCode(object): + """Define error_codes for failures that happen during the actual + update package installation. +@@ -215,7 +194,7 @@ def InitLogging(): + '': { + 'handlers': ['default'], + 'propagate': True, +- 'level': 'NOTSET', ++ 'level': 'INFO', + } + } + } +@@ -245,15 +224,23 @@ def InitLogging(): + logging.config.dictConfig(config) + + ++def SetHostToolLocation(tool_name, location): ++ OPTIONS.host_tools[tool_name] = location ++ ++ + def FindHostToolPath(tool_name): + """Finds the path to the host tool. + + Args: + tool_name: name of the tool to find + Returns: +- path to the tool if found under the same directory as this binary is located at. If not found, +- tool_name is returned. ++ path to the tool if found under either one of the host_tools map or under ++ the same directory as this binary is located at. If not found, tool_name ++ is returned. + """ ++ if tool_name in OPTIONS.host_tools: ++ return OPTIONS.host_tools[tool_name] ++ + my_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + tool_path = os.path.join(my_dir, tool_name) + if os.path.exists(tool_path): +@@ -463,26 +450,20 @@ class BuildInfo(object): + + @property + def is_vabc(self): +- return self.info_dict.get("virtual_ab_compression") == "true" ++ vendor_prop = self.info_dict.get("vendor.build.prop") ++ vabc_enabled = vendor_prop and \ ++ vendor_prop.GetProp("ro.virtual_ab.compression.enabled") == "true" ++ return vabc_enabled + + @property + def is_android_r(self): + system_prop = self.info_dict.get("system.build.prop") + return system_prop and system_prop.GetProp("ro.build.version.release") == "11" + +- @property +- def is_release_key(self): +- system_prop = self.info_dict.get("build.prop") +- return system_prop and system_prop.GetProp("ro.build.tags") == "release-key" +- + @property + def vabc_compression_param(self): + return self.get("virtual_ab_compression_method", "") + +- @property +- def vabc_cow_version(self): +- return self.get("virtual_ab_cow_version", "") +- + @property + def vendor_api_level(self): + vendor_prop = self.info_dict.get("vendor.build.prop") +@@ -490,15 +471,16 @@ class BuildInfo(object): + return -1 + + props = [ ++ "ro.board.api_level", + "ro.board.first_api_level", + "ro.product.first_api_level", + ] + for prop in props: + value = vendor_prop.GetProp(prop) + try: +- return int(value) ++ return int(value) + except: +- pass ++ pass + return -1 + + @property +@@ -779,33 +761,6 @@ def ReadFromInputFile(input_file, fn): + return ReadBytesFromInputFile(input_file, fn).decode() + + +-def WriteBytesToInputFile(input_file, fn, data): +- """Write bytes |data| contents to fn of input zipfile or directory.""" +- if isinstance(input_file, zipfile.ZipFile): +- with input_file.open(fn, "w") as entry_fp: +- return entry_fp.write(data) +- elif zipfile.is_zipfile(input_file): +- with zipfile.ZipFile(input_file, "r", allowZip64=True) as zfp: +- with zfp.open(fn, "w") as entry_fp: +- return entry_fp.write(data) +- else: +- if not os.path.isdir(input_file): +- raise ValueError( +- "Invalid input_file, accepted inputs are ZipFile object, path to .zip file on disk, or path to extracted directory. Actual: " + input_file) +- path = os.path.join(input_file, *fn.split("/")) +- try: +- with open(path, "wb") as f: +- return f.write(data) +- except IOError as e: +- if e.errno == errno.ENOENT: +- raise KeyError(fn) +- +- +-def WriteToInputFile(input_file, fn, str: str): +- """Write str content to fn of input file or directory""" +- return WriteBytesToInputFile(input_file, fn, str.encode()) +- +- + def ExtractFromInputFile(input_file, fn): + """Extracts the contents of fn from input zipfile or directory into a file.""" + if isinstance(input_file, zipfile.ZipFile): +@@ -953,14 +908,20 @@ def LoadInfoDict(input_file, repacking=False): + input_file, partition, ramdisk_format=ramdisk_format) + d["build.prop"] = d["system.build.prop"] + ++ # Set up the salt (based on fingerprint) that will be used when adding AVB ++ # hash / hashtree footers. + if d.get("avb_enable") == "true": + build_info = BuildInfo(d, use_legacy_id=True) ++ for partition in PARTITIONS_WITH_BUILD_PROP: ++ fingerprint = build_info.GetPartitionFingerprint(partition) ++ if fingerprint: ++ d["avb_{}_salt".format(partition)] = sha256( ++ fingerprint.encode()).hexdigest() ++ + # Set up the salt for partitions without build.prop + if build_info.fingerprint: +- if "fingerprint" not in d: +- d["fingerprint"] = build_info.fingerprint +- if "avb_salt" not in d: +- d["avb_salt"] = sha256(build_info.fingerprint.encode()).hexdigest() ++ d["avb_salt"] = sha256(build_info.fingerprint.encode()).hexdigest() ++ + # Set the vbmeta digest if exists + try: + d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip() +@@ -1166,7 +1127,8 @@ class PartitionBuildProps(object): + return self.build_props.get(prop) + + +-def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path): ++def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path, ++ system_root_image=False): + class Partition(object): + def __init__(self, mount_point, fs_type, device, length, context, slotselect): + self.mount_point = mount_point +@@ -1225,6 +1187,12 @@ def LoadRecoveryFSTab(read_helper, fstab_version, recovery_fstab_path): + device=pieces[0], length=length, context=context, + slotselect=slotselect) + ++ # / is used for the system mount point when the root directory is included in ++ # system. Other areas assume system is always at "/system" so point /system ++ # at /. ++ if system_root_image: ++ assert '/system' not in d and '/' in d ++ d["/system"] = d["/"] + return d + + +@@ -1240,19 +1208,32 @@ def _FindAndLoadRecoveryFstab(info_dict, input_file, read_helper): + # ../RAMDISK/system/etc/recovery.fstab. This function has to handle both + # cases, since it may load the info_dict from an old build (e.g. when + # generating incremental OTAs from that build). ++ system_root_image = info_dict.get('system_root_image') == 'true' + if info_dict.get('no_recovery') != 'true': + recovery_fstab_path = 'RECOVERY/RAMDISK/system/etc/recovery.fstab' +- if not DoesInputFileContain(input_file, recovery_fstab_path): +- recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab' ++ if isinstance(input_file, zipfile.ZipFile): ++ if recovery_fstab_path not in input_file.namelist(): ++ recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab' ++ else: ++ path = os.path.join(input_file, *recovery_fstab_path.split('/')) ++ if not os.path.exists(path): ++ recovery_fstab_path = 'RECOVERY/RAMDISK/etc/recovery.fstab' + return LoadRecoveryFSTab( +- read_helper, info_dict['fstab_version'], recovery_fstab_path) ++ read_helper, info_dict['fstab_version'], recovery_fstab_path, ++ system_root_image) + + if info_dict.get('recovery_as_boot') == 'true': + recovery_fstab_path = 'BOOT/RAMDISK/system/etc/recovery.fstab' +- if not DoesInputFileContain(input_file, recovery_fstab_path): +- recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab' ++ if isinstance(input_file, zipfile.ZipFile): ++ if recovery_fstab_path not in input_file.namelist(): ++ recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab' ++ else: ++ path = os.path.join(input_file, *recovery_fstab_path.split('/')) ++ if not os.path.exists(path): ++ recovery_fstab_path = 'BOOT/RAMDISK/etc/recovery.fstab' + return LoadRecoveryFSTab( +- read_helper, info_dict['fstab_version'], recovery_fstab_path) ++ read_helper, info_dict['fstab_version'], recovery_fstab_path, ++ system_root_image) + + return None + +@@ -1319,11 +1300,7 @@ def MergeDynamicPartitionInfoDicts(framework_dict, vendor_dict): + key = "super_%s_partition_list" % partition_group + merged_dict[key] = uniq_concat( + framework_dict.get(key, ""), vendor_dict.get(key, "")) +- # in the case that vendor is on s build, but is taking a v3 -> v3 vabc ota, we want to fallback to v2 +- if "vabc_cow_version" not in vendor_dict or "vabc_cow_version" not in framework_dict: +- merged_dict["vabc_cow_version"] = '2' +- else: +- merged_dict["vabc_cow_version"] = min(vendor_dict["vabc_cow_version"], framework_dict["vabc_cow_version"]) ++ + # Various other flags should be copied from the vendor dict, if defined. + for key in ("virtual_ab", "virtual_ab_retrofit", "lpmake", + "super_metadata_device", "super_partition_error_limit", +@@ -1420,16 +1397,14 @@ def RunHostInitVerifier(product_out, partition_map): + return RunAndCheckOutput(cmd) + + +-def AppendAVBSigningArgs(cmd, partition, avb_salt=None): ++def AppendAVBSigningArgs(cmd, partition): + """Append signing arguments for avbtool.""" + # e.g., "--key path/to/signing_key --algorithm SHA256_RSA4096" +- key_path = ResolveAVBSigningPathArgs( +- OPTIONS.info_dict.get("avb_" + partition + "_key_path")) ++ key_path = ResolveAVBSigningPathArgs(OPTIONS.info_dict.get("avb_" + partition + "_key_path")) + algorithm = OPTIONS.info_dict.get("avb_" + partition + "_algorithm") + if key_path and algorithm: + cmd.extend(["--key", key_path, "--algorithm", algorithm]) +- if avb_salt is None: +- avb_salt = OPTIONS.info_dict.get("avb_salt") ++ avb_salt = OPTIONS.info_dict.get("avb_salt") + # make_vbmeta_image doesn't like "--salt" (and it's not needed). + if avb_salt and not partition.startswith("vbmeta"): + cmd.extend(["--salt", avb_salt]) +@@ -1440,12 +1415,11 @@ def ResolveAVBSigningPathArgs(split_args): + def ResolveBinaryPath(path): + if os.path.exists(path): + return path +- if OPTIONS.search_path: +- new_path = os.path.join(OPTIONS.search_path, path) +- if os.path.exists(new_path): +- return new_path ++ new_path = os.path.join(OPTIONS.search_path, path) ++ if os.path.exists(new_path): ++ return new_path + raise ExternalError( +- "Failed to find {}".format(path)) ++ "Failed to find {}".format(new_path)) + + if not split_args: + return split_args +@@ -1463,7 +1437,7 @@ def ResolveAVBSigningPathArgs(split_args): + + + def GetAvbPartitionArg(partition, image, info_dict=None): +- """Returns the VBMeta arguments for one partition. ++ """Returns the VBMeta arguments for partition. + + It sets up the VBMeta argument by including the partition descriptor from the + given 'image', or by configuring the partition as a chained partition. +@@ -1475,7 +1449,7 @@ def GetAvbPartitionArg(partition, image, info_dict=None): + OPTIONS.info_dict if None has been given. + + Returns: +- A list of VBMeta arguments for one partition. ++ A list of VBMeta arguments. + """ + if info_dict is None: + info_dict = OPTIONS.info_dict +@@ -1483,7 +1457,7 @@ def GetAvbPartitionArg(partition, image, info_dict=None): + # Check if chain partition is used. + key_path = info_dict.get("avb_" + partition + "_key_path") + if not key_path: +- return [AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG, image] ++ return ["--include_descriptors_from_image", image] + + # For a non-A/B device, we don't chain /recovery nor include its descriptor + # into vbmeta.img. The recovery image will be configured on an independent +@@ -1495,62 +1469,7 @@ def GetAvbPartitionArg(partition, image, info_dict=None): + + # Otherwise chain the partition into vbmeta. + chained_partition_arg = GetAvbChainedPartitionArg(partition, info_dict) +- return [AVB_ARG_NAME_CHAIN_PARTITION, chained_partition_arg] +- +- +-def GetAvbPartitionsArg(partitions, +- resolve_rollback_index_location_conflict=False, +- info_dict=None): +- """Returns the VBMeta arguments for all AVB partitions. +- +- It sets up the VBMeta argument by calling GetAvbPartitionArg of all +- partitions. +- +- Args: +- partitions: A dict of all AVB partitions. +- resolve_rollback_index_location_conflict: If true, resolve conflicting avb +- rollback index locations by assigning the smallest unused value. +- info_dict: A dict returned by common.LoadInfoDict(). +- +- Returns: +- A list of VBMeta arguments for all partitions. +- """ +- # An AVB partition will be linked into a vbmeta partition by either +- # AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG or AVB_ARG_NAME_CHAIN_PARTITION, there +- # should be no other cases. +- valid_args = { +- AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG: [], +- AVB_ARG_NAME_CHAIN_PARTITION: [] +- } +- +- for partition, path in sorted(partitions.items()): +- avb_partition_arg = GetAvbPartitionArg(partition, path, info_dict) +- if not avb_partition_arg: +- continue +- arg_name, arg_value = avb_partition_arg +- assert arg_name in valid_args +- valid_args[arg_name].append(arg_value) +- +- # Copy the arguments for non-chained AVB partitions directly without +- # intervention. +- avb_args = [] +- for image in valid_args[AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG]: +- avb_args.extend([AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG, image]) +- +- # Handle chained AVB partitions. The rollback index location might be +- # adjusted if two partitions use the same value. This may happen when mixing +- # a shared system image with other vendor images. +- used_index_loc = set() +- for chained_partition_arg in valid_args[AVB_ARG_NAME_CHAIN_PARTITION]: +- if resolve_rollback_index_location_conflict: +- while chained_partition_arg.rollback_index_location in used_index_loc: +- chained_partition_arg.rollback_index_location += 1 +- +- used_index_loc.add(chained_partition_arg.rollback_index_location) +- avb_args.extend([AVB_ARG_NAME_CHAIN_PARTITION, +- chained_partition_arg.to_string()]) +- +- return avb_args ++ return ["--chain_partition", chained_partition_arg] + + + def GetAvbChainedPartitionArg(partition, info_dict, key=None): +@@ -1564,8 +1483,8 @@ def GetAvbChainedPartitionArg(partition, info_dict, key=None): + the key listed in info_dict. + + Returns: +- An AvbChainedPartitionArg object with rollback_index_location and +- pubkey_path that can be used to build or verify vbmeta image. ++ A string of form "partition:rollback_index_location:key" that can be used to ++ build or verify vbmeta image. + """ + if key is None: + key = info_dict["avb_" + partition + "_key_path"] +@@ -1573,14 +1492,54 @@ def GetAvbChainedPartitionArg(partition, info_dict, key=None): + pubkey_path = ExtractAvbPublicKey(info_dict["avb_avbtool"], key) + rollback_index_location = info_dict[ + "avb_" + partition + "_rollback_index_location"] +- return AvbChainedPartitionArg( +- partition=partition, +- rollback_index_location=int(rollback_index_location), +- pubkey_path=pubkey_path) ++ return "{}:{}:{}".format(partition, rollback_index_location, pubkey_path) ++ ++ ++def _HasGkiCertificationArgs(): ++ return ("gki_signing_key_path" in OPTIONS.info_dict and ++ "gki_signing_algorithm" in OPTIONS.info_dict) ++ ++ ++def _GenerateGkiCertificate(image, image_name): ++ key_path = OPTIONS.info_dict.get("gki_signing_key_path") ++ algorithm = OPTIONS.info_dict.get("gki_signing_algorithm") ++ ++ key_path = ResolveAVBSigningPathArgs(key_path) ++ ++ # Checks key_path exists, before processing --gki_signing_* args. ++ if not os.path.exists(key_path): ++ raise ExternalError( ++ 'gki_signing_key_path: "{}" not found'.format(key_path)) ++ ++ output_certificate = tempfile.NamedTemporaryFile() ++ cmd = [ ++ "generate_gki_certificate", ++ "--name", image_name, ++ "--algorithm", algorithm, ++ "--key", key_path, ++ "--output", output_certificate.name, ++ image, ++ ] ++ ++ signature_args = OPTIONS.info_dict.get("gki_signing_signature_args", "") ++ signature_args = signature_args.strip() ++ if signature_args: ++ cmd.extend(["--additional_avb_args", signature_args]) ++ ++ args = OPTIONS.info_dict.get("avb_boot_add_hash_footer_args", "") ++ args = args.strip() ++ if args: ++ cmd.extend(["--additional_avb_args", args]) ++ ++ RunAndCheckOutput(cmd) ++ ++ output_certificate.seek(os.SEEK_SET, 0) ++ data = output_certificate.read() ++ output_certificate.close() ++ return data + + +-def BuildVBMeta(image_path, partitions, name, needed_partitions, +- resolve_rollback_index_location_conflict=False): ++def BuildVBMeta(image_path, partitions, name, needed_partitions): + """Creates a VBMeta image. + + It generates the requested VBMeta image. The requested image could be for +@@ -1595,8 +1554,6 @@ def BuildVBMeta(image_path, partitions, name, needed_partitions, + name: Name of the VBMeta partition, e.g. 'vbmeta', 'vbmeta_system'. + needed_partitions: Partitions whose descriptors should be included into the + generated VBMeta image. +- resolve_rollback_index_location_conflict: If true, resolve conflicting avb +- rollback index locations by assigning the smallest unused value. + + Raises: + AssertionError: On invalid input args. +@@ -1610,8 +1567,7 @@ def BuildVBMeta(image_path, partitions, name, needed_partitions, + custom_avb_partitions = ["vbmeta_" + part for part in OPTIONS.info_dict.get( + "avb_custom_vbmeta_images_partition_list", "").strip().split()] + +- avb_partitions = {} +- for partition, path in sorted(partitions.items()): ++ for partition, path in partitions.items(): + if partition not in needed_partitions: + continue + assert (partition in AVB_PARTITIONS or +@@ -1621,9 +1577,7 @@ def BuildVBMeta(image_path, partitions, name, needed_partitions, + 'Unknown partition: {}'.format(partition) + assert os.path.exists(path), \ + 'Failed to find {} for {}'.format(path, partition) +- avb_partitions[partition] = path +- cmd.extend(GetAvbPartitionsArg(avb_partitions, +- resolve_rollback_index_location_conflict)) ++ cmd.extend(GetAvbPartitionArg(partition, path)) + + args = OPTIONS.info_dict.get("avb_{}_args".format(name)) + if args and args.strip(): +@@ -1634,7 +1588,7 @@ def BuildVBMeta(image_path, partitions, name, needed_partitions, + # same location when running this script (we have the input target_files + # zip only). For such cases, we additionally scan other locations (e.g. + # IMAGES/, RADIO/, etc) before bailing out. +- if arg == AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG: ++ if arg == '--include_descriptors_from_image': + chained_image = split_args[index + 1] + if os.path.exists(chained_image): + continue +@@ -1801,6 +1755,28 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file, + + RunAndCheckOutput(cmd) + ++ if _HasGkiCertificationArgs(): ++ if not os.path.exists(img.name): ++ raise ValueError("Cannot find GKI boot.img") ++ if kernel_path is None or not os.path.exists(kernel_path): ++ raise ValueError("Cannot find GKI kernel.img") ++ ++ # Certify GKI images. ++ boot_signature_bytes = b'' ++ boot_signature_bytes += _GenerateGkiCertificate(img.name, "boot") ++ boot_signature_bytes += _GenerateGkiCertificate( ++ kernel_path, "generic_kernel") ++ ++ BOOT_SIGNATURE_SIZE = 16 * 1024 ++ if len(boot_signature_bytes) > BOOT_SIGNATURE_SIZE: ++ raise ValueError('GKI boot_signature size must be <= {}'.format(BOOT_SIGNATURE_SIZE)) ++ boot_signature_bytes += ( ++ b'\0' * (BOOT_SIGNATURE_SIZE - len(boot_signature_bytes))) ++ assert len(boot_signature_bytes) == BOOT_SIGNATURE_SIZE ++ ++ with open(img.name, 'ab') as f: ++ f.write(boot_signature_bytes) ++ + # Sign the image if vboot is non-empty. + if info_dict.get("vboot"): + path = "/" + partition_name +@@ -1833,11 +1809,7 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file, + cmd = [avbtool, "add_hash_footer", "--image", img.name, + "--partition_size", str(part_size), "--partition_name", + partition_name] +- salt = None +- if kernel_path is not None: +- with open(kernel_path, "rb") as fp: +- salt = sha256(fp.read()).hexdigest() +- AppendAVBSigningArgs(cmd, partition_name, salt) ++ AppendAVBSigningArgs(cmd, partition_name) + args = info_dict.get("avb_" + partition_name + "_add_hash_footer_args") + if args and args.strip(): + split_args = ResolveAVBSigningPathArgs(shlex.split(args)) +@@ -1879,18 +1851,7 @@ def _SignBootableImage(image_path, prebuilt_name, partition_name, + cmd = [avbtool, "add_hash_footer", "--image", image_path, + "--partition_size", str(part_size), "--partition_name", + partition_name] +- # Use sha256 of the kernel as salt for reproducible builds +- with tempfile.TemporaryDirectory() as tmpdir: +- RunAndCheckOutput(["unpack_bootimg", "--boot_img", image_path, "--out", tmpdir]) +- for filename in ["kernel", "ramdisk", "vendor_ramdisk00"]: +- path = os.path.join(tmpdir, filename) +- if os.path.exists(path) and os.path.getsize(path): +- print("Using {} as salt for avb footer of {}".format( +- filename, partition_name)) +- with open(path, "rb") as fp: +- salt = sha256(fp.read()).hexdigest() +- break +- AppendAVBSigningArgs(cmd, partition_name, salt) ++ AppendAVBSigningArgs(cmd, partition_name) + args = info_dict.get("avb_" + partition_name + "_add_hash_footer_args") + if args and args.strip(): + split_args = ResolveAVBSigningPathArgs(shlex.split(args)) +@@ -1917,6 +1878,11 @@ def HasRamdisk(partition_name, info_dict=None): + if info_dict.get("gki_boot_image_without_ramdisk") == "true": + return False # A GKI boot.img has no ramdisk since Android-13. + ++ if info_dict.get("system_root_image") == "true": ++ # The ramdisk content is merged into the system.img, so there is NO ++ # ramdisk in the boot.img or boot-.img. ++ return False ++ + if info_dict.get("init_boot") == "true": + # The ramdisk is moved to the init_boot.img, so there is NO + # ramdisk in the boot.img or boot-.img. +@@ -1971,7 +1937,7 @@ def GetBootableImage(name, prebuilt_name, unpack_dir, tree_subdir, + return None + + +-def _BuildVendorBootImage(sourcedir, fs_config_file, partition_name, info_dict=None): ++def _BuildVendorBootImage(sourcedir, partition_name, info_dict=None): + """Build a vendor boot image from the specified sourcedir. + + Take a ramdisk, dtb, and vendor_cmdline from the input (in 'sourcedir'), and +@@ -1987,7 +1953,7 @@ def _BuildVendorBootImage(sourcedir, fs_config_file, partition_name, info_dict=N + img = tempfile.NamedTemporaryFile() + + ramdisk_format = GetRamdiskFormat(info_dict) +- ramdisk_img = _MakeRamdisk(sourcedir, fs_config_file=fs_config_file, ramdisk_format=ramdisk_format) ++ ramdisk_img = _MakeRamdisk(sourcedir, ramdisk_format=ramdisk_format) + + # use MKBOOTIMG from environ, or "mkbootimg" if empty or not set + mkbootimg = os.getenv('MKBOOTIMG') or "mkbootimg" +@@ -2063,11 +2029,11 @@ def _BuildVendorBootImage(sourcedir, fs_config_file, partition_name, info_dict=N + # AVB: if enabled, calculate and add hash. + if info_dict.get("avb_enable") == "true": + avbtool = info_dict["avb_avbtool"] +- part_size = info_dict[f'{partition_name}_size'] ++ part_size = info_dict['{}_size'.format(partition_name)] + cmd = [avbtool, "add_hash_footer", "--image", img.name, + "--partition_size", str(part_size), "--partition_name", partition_name] + AppendAVBSigningArgs(cmd, partition_name) +- args = info_dict.get(f'avb_{partition_name}_add_hash_footer_args') ++ args = info_dict.get('avb_{}_add_hash_footer_args'.format(partition_name)) + if args and args.strip(): + split_args = ResolveAVBSigningPathArgs(shlex.split(args)) + cmd.extend(split_args) +@@ -2101,9 +2067,8 @@ def GetVendorBootImage(name, prebuilt_name, unpack_dir, tree_subdir, + if info_dict is None: + info_dict = OPTIONS.info_dict + +- fs_config = "META/" + tree_subdir.lower() + "_filesystem_config.txt" + data = _BuildVendorBootImage( +- os.path.join(unpack_dir, tree_subdir), os.path.join(unpack_dir, fs_config), "vendor_boot", info_dict) ++ os.path.join(unpack_dir, tree_subdir), "vendor_boot", info_dict) + if data: + return File(name, data) + return None +@@ -2127,7 +2092,7 @@ def GetVendorKernelBootImage(name, prebuilt_name, unpack_dir, tree_subdir, + info_dict = OPTIONS.info_dict + + data = _BuildVendorBootImage( +- os.path.join(unpack_dir, tree_subdir), None, "vendor_kernel_boot", info_dict) ++ os.path.join(unpack_dir, tree_subdir), "vendor_kernel_boot", info_dict) + if data: + return File(name, data) + return None +@@ -2140,39 +2105,6 @@ def Gunzip(in_filename, out_filename): + shutil.copyfileobj(in_file, out_file) + + +-def UnzipSingleFile(input_zip: zipfile.ZipFile, info: zipfile.ZipInfo, dirname: str): +- # According to https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/6297838#6297838 +- # higher bits of |external_attr| are unix file permission and types +- unix_filetype = info.external_attr >> 16 +- file_perm = unix_filetype & 0o777 +- +- def CheckMask(a, mask): +- return (a & mask) == mask +- +- def IsSymlink(a): +- return CheckMask(a, stat.S_IFLNK) +- +- def IsDir(a): +- return CheckMask(a, stat.S_IFDIR) +- # python3.11 zipfile implementation doesn't handle symlink correctly +- if not IsSymlink(unix_filetype): +- target = input_zip.extract(info, dirname) +- # We want to ensure that the file is at least read/writable by owner and readable by all users +- if IsDir(unix_filetype): +- os.chmod(target, file_perm | 0o755) +- else: +- os.chmod(target, file_perm | 0o644) +- return target +- if dirname is None: +- dirname = os.getcwd() +- target = os.path.join(dirname, info.filename) +- os.makedirs(os.path.dirname(target), exist_ok=True) +- if os.path.exists(target): +- os.unlink(target) +- os.symlink(input_zip.read(info).decode(), target) +- return target +- +- + def UnzipToDir(filename, dirname, patterns=None): + """Unzips the archive to the given directory. + +@@ -2183,32 +2115,20 @@ def UnzipToDir(filename, dirname, patterns=None): + archvie. Non-matching patterns will be filtered out. If there's no match + after the filtering, no file will be unzipped. + """ +- with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip: ++ cmd = ["unzip", "-o", "-q", filename, "-d", dirname] ++ if patterns is not None: + # Filter out non-matching patterns. unzip will complain otherwise. +- entries = input_zip.infolist() +- # b/283033491 +- # Per https://en.wikipedia.org/wiki/ZIP_(file_format)#Central_directory_file_header +- # In zip64 mode, central directory record's header_offset field might be +- # set to 0xFFFFFFFF if header offset is > 2^32. In this case, the extra +- # fields will contain an 8 byte little endian integer at offset 20 +- # to indicate the actual local header offset. +- # As of python3.11, python does not handle zip64 central directories +- # correctly, so we will manually do the parsing here. +- for entry in entries: +- if entry.header_offset == 0xFFFFFFFF and len(entry.extra) >= 28: +- entry.header_offset = int.from_bytes(entry.extra[20:28], "little") +- if patterns is not None: +- filtered = [info for info in entries if any( +- [fnmatch.fnmatch(info.filename, p) for p in patterns])] +- +- # There isn't any matching files. Don't unzip anything. +- if not filtered: +- return +- for info in filtered: +- UnzipSingleFile(input_zip, info, dirname) +- else: +- for info in entries: +- UnzipSingleFile(input_zip, info, dirname) ++ with zipfile.ZipFile(filename, allowZip64=True) as input_zip: ++ names = input_zip.namelist() ++ filtered = [ ++ pattern for pattern in patterns if fnmatch.filter(names, pattern)] ++ ++ # There isn't any matching files. Don't unzip anything. ++ if not filtered: ++ return ++ cmd.extend(filtered) ++ ++ RunAndCheckOutput(cmd) + + + def UnzipTemp(filename, patterns=None): +@@ -2448,12 +2368,11 @@ def GetMinSdkVersion(apk_name): + apk_name, proc.returncode, stdoutdata, stderrdata)) + + for line in stdoutdata.split("\n"): +- # Due to ag/24161708, looking for lines such as minSdkVersion:'23',minSdkVersion:'M' +- # or sdkVersion:'23', sdkVersion:'M'. +- m = re.match(r'(?:minSdkVersion|sdkVersion):\'([^\']*)\'', line) ++ # Looking for lines such as sdkVersion:'23' or sdkVersion:'M'. ++ m = re.match(r'sdkVersion:\'([^\']*)\'', line) + if m: + return m.group(1) +- raise ExternalError("No minSdkVersion returned by aapt2 for apk: {}".format(apk_name)) ++ raise ExternalError("No minSdkVersion returned by aapt2") + + + def GetMinSdkVersionInt(apk_name, codename_to_api_level_map): +@@ -2551,6 +2470,38 @@ def SignFile(input_name, output_name, key, password, min_api_level=None, + proc.returncode, stdoutdata)) + + ++def SignSePolicy(sepolicy, key, password): ++ """Sign the sepolicy zip, producing an fsverity .fsv_sig and ++ an RSA .sig signature files. ++ """ ++ ++ if OPTIONS.sign_sepolicy_path is None: ++ logger.info("No sign_sepolicy_path specified, %s was not signed", sepolicy) ++ return False ++ ++ java_library_path = os.path.join( ++ OPTIONS.search_path, OPTIONS.signapk_shared_library_path) ++ ++ cmd = ([OPTIONS.java_path] + OPTIONS.java_args + ++ ["-Djava.library.path=" + java_library_path, ++ "-jar", os.path.join(OPTIONS.search_path, OPTIONS.sign_sepolicy_path)] + ++ OPTIONS.extra_sign_sepolicy_args) ++ ++ cmd.extend([key + OPTIONS.public_key_suffix, ++ key + OPTIONS.private_key_suffix, ++ sepolicy, os.path.dirname(sepolicy)]) ++ ++ proc = Run(cmd, stdin=subprocess.PIPE) ++ if password is not None: ++ password += "\n" ++ stdoutdata, _ = proc.communicate(password) ++ if proc.returncode != 0: ++ raise ExternalError( ++ "Failed to run sign sepolicy: return code {}:\n{}".format( ++ proc.returncode, stdoutdata)) ++ return True ++ ++ + def CheckSize(data, target, info_dict): + """Checks the data string passed against the max size limit. + +@@ -2578,9 +2529,7 @@ def CheckSize(data, target, info_dict): + device = p.device + if "/" in device: + device = device[device.rfind("/")+1:] +- limit = info_dict.get(device + "_size", 0) +- if isinstance(limit, str): +- limit = int(limit, 0) ++ limit = info_dict.get(device + "_size") + if not fs_type or not limit: + return + +@@ -2717,25 +2666,19 @@ def Usage(docstring): + def ParseOptions(argv, + docstring, + extra_opts="", extra_long_opts=(), +- extra_option_handler: Iterable[OptionHandler] = None): ++ extra_option_handler=None): + """Parse the options in argv and return any arguments that aren't + flags. docstring is the calling module's docstring, to be displayed + for errors and -h. extra_opts and extra_long_opts are for flags + defined by the caller, which are processed by passing them to + extra_option_handler.""" +- extra_long_opts = list(extra_long_opts) +- if not isinstance(extra_option_handler, Iterable): +- extra_option_handler = [extra_option_handler] +- +- for handler in extra_option_handler: +- if isinstance(handler, OptionHandler): +- extra_long_opts.extend(handler.extra_long_opts) + + try: + opts, args = getopt.getopt( + argv, "hvp:s:x:" + extra_opts, + ["help", "verbose", "path=", "signapk_path=", +- "signapk_shared_library_path=", "extra_signapk_args=", "aapt2_path=", ++ "signapk_shared_library_path=", "extra_signapk_args=", ++ "sign_sepolicy_path=", "extra_sign_sepolicy_args=", "aapt2_path=", + "java_path=", "java_args=", "android_jar_path=", "public_key_suffix=", + "private_key_suffix=", "boot_signer_path=", "boot_signer_args=", + "verity_signer_path=", "verity_signer_args=", "device_specific=", +@@ -2759,6 +2702,10 @@ def ParseOptions(argv, + OPTIONS.signapk_shared_library_path = a + elif o in ("--extra_signapk_args",): + OPTIONS.extra_signapk_args = shlex.split(a) ++ elif o in ("--sign_sepolicy_path",): ++ OPTIONS.sign_sepolicy_path = a ++ elif o in ("--extra_sign_sepolicy_args",): ++ OPTIONS.extra_sign_sepolicy_args = shlex.split(a) + elif o in ("--aapt2_path",): + OPTIONS.aapt2_path = a + elif o in ("--java_path",): +@@ -2791,19 +2738,8 @@ def ParseOptions(argv, + elif o in ("--logfile",): + OPTIONS.logfile = a + else: +- if extra_option_handler is None: +- raise ValueError("unknown option \"%s\"" % (o,)) +- success = False +- for handler in extra_option_handler: +- if isinstance(handler, OptionHandler): +- if handler.handler(o, a): +- success = True +- break +- elif handler(o, a): +- success = True +- if not success: +- raise ValueError("unknown option \"%s\"" % (o,)) +- ++ if extra_option_handler is None or not extra_option_handler(o, a): ++ assert False, "unknown option \"%s\"" % (o,) + + if OPTIONS.search_path: + os.environ["PATH"] = (os.path.join(OPTIONS.search_path, "bin") + +@@ -2834,8 +2770,6 @@ def MakeTempDir(prefix='tmp', suffix=''): + + def Cleanup(): + for i in OPTIONS.tempfiles: +- if not os.path.exists(i): +- continue + if os.path.isdir(i): + shutil.rmtree(i, ignore_errors=True) + else: +@@ -3039,7 +2973,8 @@ def ZipWriteStr(zip_file, zinfo_or_arcname, data, perms=None, + zip_file.writestr(zinfo, data) + zipfile.ZIP64_LIMIT = saved_zip64_limit + +-def ZipExclude(input_zip, output_zip, entries, force=False): ++ ++def ZipDelete(zip_filename, entries, force=False): + """Deletes entries from a ZIP file. + + Args: +@@ -3050,38 +2985,22 @@ def ZipExclude(input_zip, output_zip, entries, force=False): + entries = [entries] + # If list is empty, nothing to do + if not entries: +- shutil.copy(input_zip, output_zip) + return + +- with zipfile.ZipFile(input_zip, 'r') as zin: ++ with zipfile.ZipFile(zip_filename, 'r') as zin: + if not force and len(set(zin.namelist()).intersection(entries)) == 0: + raise ExternalError( + "Failed to delete zip entries, name not matched: %s" % entries) + +- fd, new_zipfile = tempfile.mkstemp(dir=os.path.dirname(input_zip)) ++ fd, new_zipfile = tempfile.mkstemp(dir=os.path.dirname(zip_filename)) + os.close(fd) +- cmd = ["zip2zip", "-i", input_zip, "-o", new_zipfile] ++ cmd = ["zip2zip", "-i", zip_filename, "-o", new_zipfile] + for entry in entries: + cmd.append("-x") + cmd.append(entry) + RunAndCheckOutput(cmd) +- os.replace(new_zipfile, output_zip) + +- +-def ZipDelete(zip_filename, entries, force=False): +- """Deletes entries from a ZIP file. +- +- Args: +- zip_filename: The name of the ZIP file. +- entries: The name of the entry, or the list of names to be deleted. +- """ +- if isinstance(entries, str): +- entries = [entries] +- # If list is empty, nothing to do +- if not entries: +- return +- +- ZipExclude(zip_filename, zip_filename, entries, force) ++ os.replace(new_zipfile, zip_filename) + + + def ZipClose(zip_file): +@@ -3787,11 +3706,14 @@ def MakeRecoveryPatch(input_dir, output_sink, recovery_img, boot_img, + output_sink(recovery_img_path, recovery_img.data) + + else: ++ system_root_image = info_dict.get("system_root_image") == "true" + include_recovery_dtbo = info_dict.get("include_recovery_dtbo") == "true" + include_recovery_acpio = info_dict.get("include_recovery_acpio") == "true" + path = os.path.join(input_dir, recovery_resource_dat_path) +- # Use bsdiff to handle mismatching entries (Bug: 72731506) +- if include_recovery_dtbo or include_recovery_acpio: ++ # With system-root-image, boot and recovery images will have mismatching ++ # entries (only recovery has the ramdisk entry) (Bug: 72731506). Use bsdiff ++ # to handle such a case. ++ if system_root_image or include_recovery_dtbo or include_recovery_acpio: + diff_program = ["bsdiff"] + bonus_args = "" + assert not os.path.exists(path) +@@ -4183,18 +4105,7 @@ def IsSparseImage(filepath): + return fp.read(4) == b'\x3A\xFF\x26\xED' + + +-def UnsparseImage(filepath, target_path=None): +- if not IsSparseImage(filepath): +- return +- if target_path is None: +- tmp_img = MakeTempFile(suffix=".img") +- RunAndCheckOutput(["simg2img", filepath, tmp_img]) +- os.rename(tmp_img, filepath) +- else: +- RunAndCheckOutput(["simg2img", filepath, target_path]) +- +- +-def ParseUpdateEngineConfig(path: str): ++def ParseUpdateEngineConfig(path): + """Parse the update_engine config stored in file `path` + Args + path: Path to update_engine_config.txt file in target_files +@@ -4210,9 +4121,9 @@ def ParseUpdateEngineConfig(path: str): + major = re.search(r"PAYLOAD_MAJOR_VERSION=(\d+)", data) + if not major: + raise ValueError( +- f"{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}") ++ "{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}" + path) + minor = re.search(r"PAYLOAD_MINOR_VERSION=(\d+)", data) + if not minor: + raise ValueError( +- f"{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}") ++ "{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}" + path) + return (int(major.group(1)), int(minor.group(1))) +diff --git a/tools/releasetools/merge/merge_target_files.py b/tools/releasetools/merge/merge_target_files.py +index fdba927db9..ba2b14f014 100755 +--- a/tools/releasetools/merge/merge_target_files.py ++++ b/tools/releasetools/merge/merge_target_files.py +@@ -46,10 +46,6 @@ Usage: merge_target_files [args] + The optional path to a newline-separated config file of items that + are extracted as-is from the vendor target files package. + +- --boot-image-dir-path +- The input boot image directory path. This path contains IMAGES/boot.img +- file. +- + --output-target-files output-target-files-package + If provided, the output merged target files package. Also a zip archive. + +@@ -94,14 +90,6 @@ Usage: merge_target_files [args] + --keep-tmp + Keep tempoary files for debugging purposes. + +- --avb-resolve-rollback-index-location-conflict +- If provided, resolve the conflict AVB rollback index location when +- necessary. +- +- --allow-partial-ab +- If provided, allow merging non-AB framework target files with AB vendor +- target files, which means that only the vendor has AB partitions. +- + The following only apply when using the VSDK to perform dexopt on vendor apps: + + --framework-dexpreopt-config +@@ -144,7 +132,6 @@ OPTIONS.framework_item_list = [] + OPTIONS.framework_misc_info_keys = [] + OPTIONS.vendor_target_files = None + OPTIONS.vendor_item_list = [] +-OPTIONS.boot_image_dir_path = None + OPTIONS.output_target_files = None + OPTIONS.output_dir = None + OPTIONS.output_item_list = [] +@@ -157,8 +144,6 @@ OPTIONS.allow_duplicate_apkapex_keys = False + OPTIONS.vendor_otatools = None + OPTIONS.rebuild_sepolicy = False + OPTIONS.keep_tmp = False +-OPTIONS.avb_resolve_rollback_index_location_conflict = False +-OPTIONS.allow_partial_ab = False + OPTIONS.framework_dexpreopt_config = None + OPTIONS.framework_dexpreopt_tools = None + OPTIONS.vendor_dexpreopt_config = None +@@ -180,24 +165,17 @@ def remove_file_if_exists(file_name): + pass + + +-def include_extra_in_list(item_list): +- """ +- 1. Include all `META/*` files in the item list. ++def include_meta_in_list(item_list): ++ """Include all `META/*` files in the item list. + + To ensure that `AddImagesToTargetFiles` can still be used with vendor item + list that do not specify all of the required META/ files, those files should + be included by default. This preserves the backward compatibility of + `rebuild_image_with_sepolicy`. +- +- 2. Include `SYSTEM/build.prop` file in the item list. +- +- To ensure that `AddImagesToTargetFiles` for GRF vendor images, can still +- access SYSTEM/build.prop to pass GetPartitionFingerprint check in BuildInfo +- constructor. + """ + if not item_list: + return None +- return list(item_list) + ['META/*'] + ['SYSTEM/build.prop'] ++ return list(item_list) + ['META/*'] + + + def create_merged_package(temp_dir): +@@ -220,19 +198,11 @@ def create_merged_package(temp_dir): + output_dir=output_target_files_temp_dir, + item_list=OPTIONS.vendor_item_list) + +- if OPTIONS.boot_image_dir_path: +- merge_utils.CollectTargetFiles( +- input_zipfile_or_dir=OPTIONS.boot_image_dir_path, +- output_dir=output_target_files_temp_dir, +- item_list=['IMAGES/boot.img']) +- + # Perform special case processing on META/* items. + # After this function completes successfully, all the files we need to create + # the output target files package are in place. + merge_meta.MergeMetaFiles( +- temp_dir=temp_dir, +- merged_dir=output_target_files_temp_dir, +- framework_partitions=OPTIONS.framework_partition_set) ++ temp_dir=temp_dir, merged_dir=output_target_files_temp_dir) + + merge_dexopt.MergeDexopt( + temp_dir=temp_dir, output_target_files_dir=output_target_files_temp_dir) +@@ -251,8 +221,6 @@ def generate_missing_images(target_files_dir): + ] + if OPTIONS.rebuild_recovery: + add_img_args.append('--rebuild_recovery') +- if OPTIONS.avb_resolve_rollback_index_location_conflict: +- add_img_args.append('--avb_resolve_rollback_index_location_conflict') + add_img_args.append(target_files_dir) + + add_img_to_target_files.main(add_img_args) +@@ -321,7 +289,7 @@ def rebuild_image_with_sepolicy(target_files_dir): + merge_utils.CollectTargetFiles( + input_zipfile_or_dir=OPTIONS.vendor_target_files, + output_dir=vendor_target_files_dir, +- item_list=include_extra_in_list(OPTIONS.vendor_item_list)) ++ item_list=include_meta_in_list(OPTIONS.vendor_item_list)) + + # Copy the partition contents from the merged target-files archive to the + # vendor target-files archive. +@@ -555,8 +523,6 @@ def main(): + OPTIONS.vendor_item_list = a + elif o == '--vendor-item-list': + OPTIONS.vendor_item_list = a +- elif o == '--boot-image-dir-path': +- OPTIONS.boot_image_dir_path = a + elif o == '--output-target-files': + OPTIONS.output_target_files = a + elif o == '--output-dir': +@@ -579,10 +545,6 @@ def main(): + OPTIONS.rebuild_sepolicy = True + elif o == '--keep-tmp': + OPTIONS.keep_tmp = True +- elif o == '--avb-resolve-rollback-index-location-conflict': +- OPTIONS.avb_resolve_rollback_index_location_conflict = True +- elif o == '--allow-partial-ab': +- OPTIONS.allow_partial_ab = True + elif o == '--framework-dexpreopt-config': + OPTIONS.framework_dexpreopt_config = a + elif o == '--framework-dexpreopt-tools': +@@ -607,7 +569,6 @@ def main(): + 'vendor-target-files=', + 'other-item-list=', + 'vendor-item-list=', +- 'boot-image-dir-path=', + 'output-target-files=', + 'output-dir=', + 'output-item-list=', +@@ -623,8 +584,6 @@ def main(): + 'vendor-otatools=', + 'rebuild-sepolicy', + 'keep-tmp', +- 'avb-resolve-rollback-index-location-conflict', +- 'allow-partial-ab', + ], + extra_option_handler=option_handler) + +diff --git a/tools/releasetools/test_common.py b/tools/releasetools/test_common.py +index 89933a00fc..2dfd8c714a 100644 +--- a/tools/releasetools/test_common.py ++++ b/tools/releasetools/test_common.py +@@ -15,13 +15,14 @@ + # + + import copy ++import json + import os + import subprocess + import tempfile ++import time + import unittest + import zipfile + from hashlib import sha1 +-from typing import BinaryIO + + import common + import test_utils +@@ -35,24 +36,14 @@ MiB = 1024 * KiB + GiB = 1024 * MiB + + +-def get_2gb_file(): ++def get_2gb_string(): + size = int(2 * GiB + 1) + block_size = 4 * KiB + step_size = 4 * MiB +- tmpfile = tempfile.NamedTemporaryFile() +- tmpfile.truncate(size) ++ # Generate a long string with holes, e.g. 'xyz\x00abc\x00...'. + for _ in range(0, size, step_size): +- tmpfile.write(os.urandom(block_size)) +- tmpfile.seek(step_size - block_size, os.SEEK_CUR) +- return tmpfile +- +- +-def hash_file(filename): +- sha1_hash = sha1() +- with open(filename, "rb") as fp: +- for data in iter(lambda: fp.read(4*MiB), b''): +- sha1_hash.update(data) +- return sha1_hash ++ yield os.urandom(block_size) ++ yield b'\0' * (step_size - block_size) + + + class BuildInfoTest(test_utils.ReleaseToolsTestCase): +@@ -231,17 +222,17 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): + info_dict = copy.deepcopy(self.TEST_INFO_FINGERPRINT_DICT) + build_info = common.BuildInfo(info_dict) + self.assertEqual( +- 'product-brand/product-name/product-device:version-release/build-id/' +- 'version-incremental:build-type/build-tags', build_info.fingerprint) ++ 'product-brand/product-name/product-device:version-release/build-id/' ++ 'version-incremental:build-type/build-tags', build_info.fingerprint) + + build_props = info_dict['build.prop'].build_props + del build_props['ro.build.id'] + build_props['ro.build.legacy.id'] = 'legacy-build-id' + build_info = common.BuildInfo(info_dict, use_legacy_id=True) + self.assertEqual( +- 'product-brand/product-name/product-device:version-release/' +- 'legacy-build-id/version-incremental:build-type/build-tags', +- build_info.fingerprint) ++ 'product-brand/product-name/product-device:version-release/' ++ 'legacy-build-id/version-incremental:build-type/build-tags', ++ build_info.fingerprint) + + self.assertRaises(common.ExternalError, common.BuildInfo, info_dict, None, + False) +@@ -250,9 +241,9 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): + info_dict['vbmeta_digest'] = 'abcde12345' + build_info = common.BuildInfo(info_dict, use_legacy_id=False) + self.assertEqual( +- 'product-brand/product-name/product-device:version-release/' +- 'legacy-build-id.abcde123/version-incremental:build-type/build-tags', +- build_info.fingerprint) ++ 'product-brand/product-name/product-device:version-release/' ++ 'legacy-build-id.abcde123/version-incremental:build-type/build-tags', ++ build_info.fingerprint) + + def test___getitem__(self): + target_info = common.BuildInfo(self.TEST_INFO_DICT, None) +@@ -385,7 +376,7 @@ class BuildInfoTest(test_utils.ReleaseToolsTestCase): + info_dict['build.prop'].build_props[ + 'ro.product.property_source_order'] = 'bad-source' + with self.assertRaisesRegexp(common.ExternalError, +- 'Invalid ro.product.property_source_order'): ++ 'Invalid ro.product.property_source_order'): + info = common.BuildInfo(info_dict, None) + info.GetBuildProp('ro.product.device') + +@@ -438,13 +429,6 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + self.assertIsNone(zip_file.testzip()) + + def _test_ZipWrite(self, contents, extra_zipwrite_args=None): +- with tempfile.NamedTemporaryFile() as test_file: +- test_file_name = test_file.name +- for data in contents: +- test_file.write(bytes(data)) +- return self._test_ZipWriteFile(test_file_name, extra_zipwrite_args) +- +- def _test_ZipWriteFile(self, test_file_name, extra_zipwrite_args=None): + extra_zipwrite_args = dict(extra_zipwrite_args or {}) + + test_file = tempfile.NamedTemporaryFile(delete=False) +@@ -457,12 +441,17 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + arcname = extra_zipwrite_args.get("arcname", test_file_name) + if arcname[0] == "/": + arcname = arcname[1:] +- sha1_hash = hash_file(test_file_name) + + zip_file.close() + zip_file = zipfile.ZipFile(zip_file_name, "w", allowZip64=True) + + try: ++ sha1_hash = sha1() ++ for data in contents: ++ sha1_hash.update(bytes(data)) ++ test_file.write(bytes(data)) ++ test_file.close() ++ + expected_mode = extra_zipwrite_args.get("perms", 0o644) + expected_compress_type = extra_zipwrite_args.get("compress_type", + zipfile.ZIP_STORED) +@@ -478,6 +467,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + test_file_name, expected_stat, expected_mode, + expected_compress_type) + finally: ++ os.remove(test_file_name) + os.remove(zip_file_name) + + def _test_ZipWriteStr(self, zinfo_or_arcname, contents, extra_args=None): +@@ -512,13 +502,14 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + finally: + os.remove(zip_file_name) + +- def _test_ZipWriteStr_large_file(self, large_file: BinaryIO, small, extra_args=None): ++ def _test_ZipWriteStr_large_file(self, large, small, extra_args=None): + extra_args = dict(extra_args or {}) + + zip_file = tempfile.NamedTemporaryFile(delete=False) + zip_file_name = zip_file.name + +- test_file_name = large_file.name ++ test_file = tempfile.NamedTemporaryFile(delete=False) ++ test_file_name = test_file.name + + arcname_large = test_file_name + arcname_small = "bar" +@@ -531,7 +522,11 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + zip_file = zipfile.ZipFile(zip_file_name, "w", allowZip64=True) + + try: +- sha1_hash = hash_file(test_file_name) ++ sha1_hash = sha1() ++ for data in large: ++ sha1_hash.update(data) ++ test_file.write(data) ++ test_file.close() + + # Arbitrary timestamp, just to make sure common.ZipWrite() restores + # the timestamp after writing. +@@ -556,6 +551,7 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + expected_compress_type=expected_compress_type) + finally: + os.remove(zip_file_name) ++ os.remove(test_file_name) + + def _test_reset_ZIP64_LIMIT(self, func, *args): + default_limit = (1 << 31) - 1 +@@ -581,10 +577,10 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + }) + + def test_ZipWrite_large_file(self): +- with get_2gb_file() as tmpfile: +- self._test_ZipWriteFile(tmpfile.name, { +- "compress_type": zipfile.ZIP_DEFLATED, +- }) ++ file_contents = get_2gb_string() ++ self._test_ZipWrite(file_contents, { ++ "compress_type": zipfile.ZIP_DEFLATED, ++ }) + + def test_ZipWrite_resets_ZIP64_LIMIT(self): + self._test_reset_ZIP64_LIMIT(self._test_ZipWrite, "") +@@ -631,11 +627,11 @@ class CommonZipTest(test_utils.ReleaseToolsTestCase): + # zipfile.writestr() doesn't work when the str size is over 2GiB even with + # the workaround. We will only test the case of writing a string into a + # large archive. ++ long_string = get_2gb_string() + short_string = os.urandom(1024) +- with get_2gb_file() as large_file: +- self._test_ZipWriteStr_large_file(large_file, short_string, { +- "compress_type": zipfile.ZIP_DEFLATED, +- }) ++ self._test_ZipWriteStr_large_file(long_string, short_string, { ++ "compress_type": zipfile.ZIP_DEFLATED, ++ }) + + def test_ZipWriteStr_resets_ZIP64_LIMIT(self): + self._test_reset_ZIP64_LIMIT(self._test_ZipWriteStr, 'foo', b'') +@@ -825,9 +821,9 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): + ) + + APKCERTS_CERTMAP1 = { +- 'RecoveryLocalizer.apk': 'certs/devkey', +- 'Settings.apk': 'build/make/target/product/security/platform', +- 'TV.apk': 'PRESIGNED', ++ 'RecoveryLocalizer.apk' : 'certs/devkey', ++ 'Settings.apk' : 'build/make/target/product/security/platform', ++ 'TV.apk' : 'PRESIGNED', + } + + APKCERTS_TXT2 = ( +@@ -842,10 +838,10 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): + ) + + APKCERTS_CERTMAP2 = { +- 'Compressed1.apk': 'certs/compressed1', +- 'Compressed2a.apk': 'certs/compressed2', +- 'Compressed2b.apk': 'certs/compressed2', +- 'Compressed3.apk': 'certs/compressed3', ++ 'Compressed1.apk' : 'certs/compressed1', ++ 'Compressed2a.apk' : 'certs/compressed2', ++ 'Compressed2b.apk' : 'certs/compressed2', ++ 'Compressed3.apk' : 'certs/compressed3', + } + + APKCERTS_TXT3 = ( +@@ -854,7 +850,7 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): + ) + + APKCERTS_CERTMAP3 = { +- 'Compressed4.apk': 'certs/compressed4', ++ 'Compressed4.apk' : 'certs/compressed4', + } + + # Test parsing with no optional fields, both optional fields, and only the +@@ -871,9 +867,9 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): + ) + + APKCERTS_CERTMAP4 = { +- 'RecoveryLocalizer.apk': 'certs/devkey', +- 'Settings.apk': 'build/make/target/product/security/platform', +- 'TV.apk': 'PRESIGNED', ++ 'RecoveryLocalizer.apk' : 'certs/devkey', ++ 'Settings.apk' : 'build/make/target/product/security/platform', ++ 'TV.apk' : 'PRESIGNED', + } + + def setUp(self): +@@ -977,7 +973,7 @@ class CommonApkUtilsTest(test_utils.ReleaseToolsTestCase): + extracted_from_privkey = common.ExtractAvbPublicKey('avbtool', privkey) + extracted_from_pubkey = common.ExtractAvbPublicKey('avbtool', pubkey) + with open(extracted_from_privkey, 'rb') as privkey_fp, \ +- open(extracted_from_pubkey, 'rb') as pubkey_fp: ++ open(extracted_from_pubkey, 'rb') as pubkey_fp: + self.assertEqual(privkey_fp.read(), pubkey_fp.read()) + + def test_ParseCertificate(self): +@@ -1241,8 +1237,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + self.assertEqual( + '1-5 9-10', + sparse_image.file_map['//system/file1'].extra['text_str']) +- self.assertTrue( +- sparse_image.file_map['//system/file2'].extra['incomplete']) ++ self.assertTrue(sparse_image.file_map['//system/file2'].extra['incomplete']) + self.assertTrue( + sparse_image.file_map['/system/app/file3'].extra['incomplete']) + +@@ -1299,11 +1294,11 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'avb_system_key_path': pubkey, + 'avb_system_rollback_index_location': 2, + } +- chained_partition_args = common.GetAvbChainedPartitionArg( +- 'system', info_dict) +- self.assertEqual('system', chained_partition_args.partition) +- self.assertEqual(2, chained_partition_args.rollback_index_location) +- self.assertTrue(os.path.exists(chained_partition_args.pubkey_path)) ++ args = common.GetAvbChainedPartitionArg('system', info_dict).split(':') ++ self.assertEqual(3, len(args)) ++ self.assertEqual('system', args[0]) ++ self.assertEqual('2', args[1]) ++ self.assertTrue(os.path.exists(args[2])) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_GetAvbChainedPartitionArg_withPrivateKey(self): +@@ -1313,11 +1308,11 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'avb_product_key_path': key, + 'avb_product_rollback_index_location': 2, + } +- chained_partition_args = common.GetAvbChainedPartitionArg( +- 'product', info_dict) +- self.assertEqual('product', chained_partition_args.partition) +- self.assertEqual(2, chained_partition_args.rollback_index_location) +- self.assertTrue(os.path.exists(chained_partition_args.pubkey_path)) ++ args = common.GetAvbChainedPartitionArg('product', info_dict).split(':') ++ self.assertEqual(3, len(args)) ++ self.assertEqual('product', args[0]) ++ self.assertEqual('2', args[1]) ++ self.assertTrue(os.path.exists(args[2])) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_GetAvbChainedPartitionArg_withSpecifiedKey(self): +@@ -1327,11 +1322,12 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'avb_system_rollback_index_location': 2, + } + pubkey = os.path.join(self.testdata_dir, 'testkey.pubkey.pem') +- chained_partition_args = common.GetAvbChainedPartitionArg( +- 'system', info_dict, pubkey) +- self.assertEqual('system', chained_partition_args.partition) +- self.assertEqual(2, chained_partition_args.rollback_index_location) +- self.assertTrue(os.path.exists(chained_partition_args.pubkey_path)) ++ args = common.GetAvbChainedPartitionArg( ++ 'system', info_dict, pubkey).split(':') ++ self.assertEqual(3, len(args)) ++ self.assertEqual('system', args[0]) ++ self.assertEqual('2', args[1]) ++ self.assertTrue(os.path.exists(args[2])) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_GetAvbChainedPartitionArg_invalidKey(self): +@@ -1348,7 +1344,8 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + INFO_DICT_DEFAULT = { + 'recovery_api_version': 3, + 'fstab_version': 2, +- 'no_recovery': 'true', ++ 'system_root_image': 'true', ++ 'no_recovery' : 'true', + 'recovery_as_boot': 'true', + } + +@@ -1376,8 +1373,14 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + info_values = ''.join( + ['{}={}\n'.format(k, v) for k, v in sorted(info_dict.items())]) + common.ZipWriteStr(target_files_zip, 'META/misc_info.txt', info_values) +- common.ZipWriteStr(target_files_zip, fstab_path, +- "/dev/block/system /system ext4 ro,barrier=1 defaults") ++ ++ FSTAB_TEMPLATE = "/dev/block/system {} ext4 ro,barrier=1 defaults" ++ if info_dict.get('system_root_image') == 'true': ++ fstab_values = FSTAB_TEMPLATE.format('/') ++ else: ++ fstab_values = FSTAB_TEMPLATE.format('/system') ++ common.ZipWriteStr(target_files_zip, fstab_path, fstab_values) ++ + common.ZipWriteStr( + target_files_zip, 'META/file_contexts', 'file-contexts') + return target_files +@@ -1390,6 +1393,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + loaded_dict = common.LoadInfoDict(target_files_zip) + self.assertEqual(3, loaded_dict['recovery_api_version']) + self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + + def test_LoadInfoDict_legacyRecoveryFstabPath(self): +@@ -1400,6 +1404,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + loaded_dict = common.LoadInfoDict(target_files_zip) + self.assertEqual(3, loaded_dict['recovery_api_version']) + self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + + @test_utils.SkipIfExternalToolsUnavailable() +@@ -1411,6 +1416,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + loaded_dict = common.LoadInfoDict(unzipped) + self.assertEqual(3, loaded_dict['recovery_api_version']) + self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + + @test_utils.SkipIfExternalToolsUnavailable() +@@ -1422,11 +1428,15 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + loaded_dict = common.LoadInfoDict(unzipped) + self.assertEqual(3, loaded_dict['recovery_api_version']) + self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + +- def test_LoadInfoDict_recoveryAsBootFalse(self): ++ def test_LoadInfoDict_systemRootImageFalse(self): ++ # Devices not using system-as-root nor recovery-as-boot. Non-A/B devices ++ # launched prior to P will likely have this config. + info_dict = copy.copy(self.INFO_DICT_DEFAULT) + del info_dict['no_recovery'] ++ del info_dict['system_root_image'] + del info_dict['recovery_as_boot'] + target_files = self._test_LoadInfoDict_createTargetFiles( + info_dict, +@@ -1438,6 +1448,22 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + self.assertNotIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + ++ def test_LoadInfoDict_recoveryAsBootFalse(self): ++ # Devices using system-as-root, but with standalone recovery image. Non-A/B ++ # devices launched since P will likely have this config. ++ info_dict = copy.copy(self.INFO_DICT_DEFAULT) ++ del info_dict['no_recovery'] ++ del info_dict['recovery_as_boot'] ++ target_files = self._test_LoadInfoDict_createTargetFiles( ++ info_dict, ++ 'RECOVERY/RAMDISK/system/etc/recovery.fstab') ++ with zipfile.ZipFile(target_files, 'r', allowZip64=True) as target_files_zip: ++ loaded_dict = common.LoadInfoDict(target_files_zip) ++ self.assertEqual(3, loaded_dict['recovery_api_version']) ++ self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) ++ self.assertIn('/system', loaded_dict['fstab']) ++ + def test_LoadInfoDict_noRecoveryTrue(self): + # Device doesn't have a recovery partition at all. + info_dict = copy.copy(self.INFO_DICT_DEFAULT) +@@ -1469,6 +1495,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + loaded_dict = common.LoadInfoDict(unzipped, True) + self.assertEqual(3, loaded_dict['recovery_api_version']) + self.assertEqual(2, loaded_dict['fstab_version']) ++ self.assertIn('/', loaded_dict['fstab']) + self.assertIn('/system', loaded_dict['fstab']) + self.assertEqual( + os.path.join(unzipped, 'ROOT'), loaded_dict['root_dir']) +@@ -1515,7 +1542,6 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'super_group_a_group_size': '1000', + 'super_group_b_partition_list': 'product', + 'super_group_b_group_size': '2000', +- 'vabc_cow_version': '2', + } + self.assertEqual(merged_dict, expected_merged_dict) + +@@ -1526,7 +1552,6 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'dynamic_partition_list': 'system', + 'super_group_a_partition_list': 'system', + 'super_group_a_group_size': '5000', +- 'vabc_cow_version': '3', + } + vendor_dict = { + 'use_dynamic_partitions': 'true', +@@ -1548,7 +1573,6 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + 'super_group_a_group_size': '1000', + 'super_group_b_partition_list': 'product', + 'super_group_b_group_size': '2000', +- 'vabc_cow_version': '2', + } + self.assertEqual(merged_dict, expected_merged_dict) + +@@ -1556,8 +1580,7 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + info_dict = {} + cmd = common.GetAvbPartitionArg('system', '/path/to/system.img', info_dict) + self.assertEqual( +- [common.AVB_ARG_NAME_INCLUDE_DESC_FROM_IMG, '/path/to/system.img'], +- cmd) ++ ['--include_descriptors_from_image', '/path/to/system.img'], cmd) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendVBMetaArgsForPartition_vendorAsChainedPartition(self): +@@ -1570,11 +1593,12 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + } + cmd = common.GetAvbPartitionArg('vendor', '/path/to/vendor.img', info_dict) + self.assertEqual(2, len(cmd)) +- self.assertEqual(common.AVB_ARG_NAME_CHAIN_PARTITION, cmd[0]) +- chained_partition_args = cmd[1] +- self.assertEqual('vendor', chained_partition_args.partition) +- self.assertEqual(5, chained_partition_args.rollback_index_location) +- self.assertTrue(os.path.exists(chained_partition_args.pubkey_path)) ++ self.assertEqual('--chain_partition', cmd[0]) ++ chained_partition_args = cmd[1].split(':') ++ self.assertEqual(3, len(chained_partition_args)) ++ self.assertEqual('vendor', chained_partition_args[0]) ++ self.assertEqual('5', chained_partition_args[1]) ++ self.assertTrue(os.path.exists(chained_partition_args[2])) + + @test_utils.SkipIfExternalToolsUnavailable() + def test_AppendVBMetaArgsForPartition_recoveryAsChainedPartition_nonAb(self): +@@ -1602,12 +1626,45 @@ class CommonUtilsTest(test_utils.ReleaseToolsTestCase): + cmd = common.GetAvbPartitionArg( + 'recovery', '/path/to/recovery.img', info_dict) + self.assertEqual(2, len(cmd)) +- self.assertEqual(common.AVB_ARG_NAME_CHAIN_PARTITION, cmd[0]) +- chained_partition_args = cmd[1] +- self.assertEqual('recovery', chained_partition_args.partition) +- self.assertEqual(3, chained_partition_args.rollback_index_location) +- self.assertTrue(os.path.exists(chained_partition_args.pubkey_path)) +- ++ self.assertEqual('--chain_partition', cmd[0]) ++ chained_partition_args = cmd[1].split(':') ++ self.assertEqual(3, len(chained_partition_args)) ++ self.assertEqual('recovery', chained_partition_args[0]) ++ self.assertEqual('3', chained_partition_args[1]) ++ self.assertTrue(os.path.exists(chained_partition_args[2])) ++ ++ def test_GenerateGkiCertificate_KeyPathNotFound(self): ++ pubkey = os.path.join(self.testdata_dir, 'no_testkey_gki.pem') ++ self.assertFalse(os.path.exists(pubkey)) ++ ++ common.OPTIONS.info_dict = { ++ 'gki_signing_key_path': pubkey, ++ 'gki_signing_algorithm': 'SHA256_RSA4096', ++ 'gki_signing_signature_args': '--prop foo:bar', ++ } ++ test_file = tempfile.NamedTemporaryFile() ++ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate, ++ test_file.name, 'generic_kernel') ++ ++ def test_GenerateGkiCertificate_SearchKeyPathNotFound(self): ++ pubkey = 'no_testkey_gki.pem' ++ self.assertFalse(os.path.exists(pubkey)) ++ ++ # Tests it should raise ExternalError if no key found under ++ # OPTIONS.search_path. ++ search_path_dir = common.MakeTempDir() ++ search_pubkey = os.path.join(search_path_dir, pubkey) ++ self.assertFalse(os.path.exists(search_pubkey)) ++ ++ common.OPTIONS.search_path = search_path_dir ++ common.OPTIONS.info_dict = { ++ 'gki_signing_key_path': pubkey, ++ 'gki_signing_algorithm': 'SHA256_RSA4096', ++ 'gki_signing_signature_args': '--prop foo:bar', ++ } ++ test_file = tempfile.NamedTemporaryFile() ++ self.assertRaises(common.ExternalError, common._GenerateGkiCertificate, ++ test_file.name, 'generic_kernel') + + class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase): + """Checks the format of install-recovery.sh. +@@ -1618,7 +1675,7 @@ class InstallRecoveryScriptFormatTest(test_utils.ReleaseToolsTestCase): + def setUp(self): + self._tempdir = common.MakeTempDir() + # Create a fake dict that contains the fstab info for boot&recovery. +- self._info = {"fstab": {}} ++ self._info = {"fstab" : {}} + fake_fstab = [ + "/dev/soc.0/by-name/boot /boot emmc defaults defaults", + "/dev/soc.0/by-name/recovery /recovery emmc defaults defaults"] +@@ -1965,11 +2022,11 @@ class PartitionBuildPropsTest(test_utils.ReleaseToolsTestCase): + input_zip, 'odm', placeholder_values) + + self.assertEqual({ +- 'ro.odm.build.date.utc': '1578430045', +- 'ro.odm.build.fingerprint': +- 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', +- 'ro.product.odm.device': 'coral', +- 'ro.product.odm.name': 'product1', ++ 'ro.odm.build.date.utc': '1578430045', ++ 'ro.odm.build.fingerprint': ++ 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', ++ 'ro.product.odm.device': 'coral', ++ 'ro.product.odm.name': 'product1', + }, partition_props.build_props) + + with zipfile.ZipFile(input_file, 'r', allowZip64=True) as input_zip: +@@ -2152,8 +2209,8 @@ class PartitionBuildPropsTest(test_utils.ReleaseToolsTestCase): + + copied_props = copy.deepcopy(partition_props) + self.assertEqual({ +- 'ro.odm.build.date.utc': '1578430045', +- 'ro.odm.build.fingerprint': +- 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', +- 'ro.product.odm.device': 'coral', ++ 'ro.odm.build.date.utc': '1578430045', ++ 'ro.odm.build.fingerprint': ++ 'google/coral/coral:10/RP1A.200325.001/6337676:user/dev-keys', ++ 'ro.product.odm.device': 'coral', + }, copied_props.build_props) +diff --git a/tools/releasetools/validate_target_files.py b/tools/releasetools/validate_target_files.py +index 88fd8929e5..beb9e75dfd 100755 +--- a/tools/releasetools/validate_target_files.py ++++ b/tools/releasetools/validate_target_files.py +@@ -132,7 +132,7 @@ def ValidateFileConsistency(input_zip, input_tmp, info_dict): + return + + # Verify IMAGES/system.img if applicable. +- # Some targets are system.img-less. ++ # Some targets, e.g., gki_arm64, gki_x86_64, etc., are system.img-less. + if 'IMAGES/system.img' in input_zip.namelist(): + CheckAllFiles('system') + +@@ -361,15 +361,18 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options): + "Mismatching mincrypt verity key files" + logging.info('Verified the content of /verity_key') + +- verity_key_ramdisk = os.path.join( +- input_tmp, 'BOOT', 'RAMDISK', 'verity_key') +- assert os.path.exists( +- verity_key_ramdisk), 'Missing verity_key in ramdisk' ++ # For devices with a separate ramdisk (i.e. non-system-as-root), there must ++ # be a copy in ramdisk. ++ if info_dict.get("system_root_image") != "true": ++ verity_key_ramdisk = os.path.join( ++ input_tmp, 'BOOT', 'RAMDISK', 'verity_key') ++ assert os.path.exists( ++ verity_key_ramdisk), 'Missing verity_key in ramdisk' + +- assert filecmp.cmp( +- verity_key_mincrypt, verity_key_ramdisk, shallow=False), \ +- 'Mismatching verity_key files in root and ramdisk' +- logging.info('Verified the content of /verity_key in ramdisk') ++ assert filecmp.cmp( ++ verity_key_mincrypt, verity_key_ramdisk, shallow=False), \ ++ 'Mismatching verity_key files in root and ramdisk' ++ logging.info('Verified the content of /verity_key in ramdisk') + + # Then verify the verity signed system/vendor/product images, against the + # verity pubkey in mincrypt format. +@@ -427,8 +430,7 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options): + key_file = options.get(key_name, info_dict[key_name]) + chained_partition_arg = common.GetAvbChainedPartitionArg( + partition, info_dict, key_file) +- cmd.extend(['--expected_chain_partition', +- chained_partition_arg.to_string()]) ++ cmd.extend(['--expected_chain_partition', chained_partition_arg]) + + # Handle the boot image with a non-default name, e.g. boot-5.4.img + boot_images = info_dict.get("boot_images") +-- +2.34.1 + diff --git a/aosp_diff/base_aaos/frameworks/base/99_0258-Enable-AX210-and-AX201-Bluetooth-for-Android-Automot.patch b/aosp_diff/base_aaos/frameworks/base/0001-Enable-BT-for-ivi.patch similarity index 74% rename from aosp_diff/base_aaos/frameworks/base/99_0258-Enable-AX210-and-AX201-Bluetooth-for-Android-Automot.patch rename to aosp_diff/base_aaos/frameworks/base/0001-Enable-BT-for-ivi.patch index 151a1c1933..760143633e 100644 --- a/aosp_diff/base_aaos/frameworks/base/99_0258-Enable-AX210-and-AX201-Bluetooth-for-Android-Automot.patch +++ b/aosp_diff/base_aaos/frameworks/base/0001-Enable-BT-for-ivi.patch @@ -1,35 +1,35 @@ -From be118bb56d62f2478748d7cb642de7510aa7d844 Mon Sep 17 00:00:00 2001 -From: "Ye, Zhao" -Date: Sun, 28 Apr 2024 02:32:34 +0000 -Subject: [PATCH] Enable AX210 and AX201 Bluetooth for Android Automotive +From 5ac39430d557f370282e71022f9bdc1fadb58b92 Mon Sep 17 00:00:00 2001 +From: Gowtham Anandha Babu +Date: Tue, 6 Aug 2024 06:39:38 +0000 +Subject: [PATCH] Enable BT for ivi - The BT chip is loaded as USB interface as hci0, the UsbHostManager - is taking control of hci0 interface and doing initialization. - Because of which Bluetooth-HAL is not able to send HCI cmds via - hci0 interface, causing the hci_timeout_abort() crash. - So BT is not enabled. +The BT chip is loaded as USB interface as hci0, the UsbHostManager +is taking control of hci0 interface and doing initialization. +Because of which Bluetooth-HAL is not able to send HCI cmds via +hci0 interface, causing the hci_timeout_abort() crash. +So BT is not enabled. - Add BT chip vendor id and product id in config deny list, so that - UsbHostManager skips the USB interface intialization for hci0. -Tests: -Open bluetooth in Settings app, -bluetooth device can be found. +Add BT chip vendor id and product id in config deny list, so that +UsbHostManager skips the USB interface intialization for hci0. +Added support for AX201, AX210, AX211 cards. -Tracked-On:OAM-118006 +Tests: +1. Bluetooth on/off success +2. Bluetooth scan success -Signed-off-by: Ye, Zhao +Tracked-On: OAM-121975 Signed-off-by: Gowtham Anandha Babu Signed-off-by: Bharat B Panda --- core/res/res/values/config.xml | 3 + - .../android/server/usb/UsbHostManager.java | 57 +++++++++++++++---- - 2 files changed, 49 insertions(+), 11 deletions(-) + .../android/server/usb/UsbHostManager.java | 61 +++++++++++++++---- + 2 files changed, 53 insertions(+), 11 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml -index 5b0f0befcf16..9dcb76040883 100644 +index 4e133de7c483..955cea896e3e 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml -@@ -1245,6 +1245,9 @@ +@@ -1332,6 +1332,9 @@ to this list. If this is empty, no parts of the host USB bus will be excluded. --> @@ -40,10 +40,10 @@ index 5b0f0befcf16..9dcb76040883 100644 %s", __func__, link.srcEntityName.c_str(), ++ link.sinkEntityName.c_str()); ++ ret = -1; ++ int srcEntity = getEntityIdByName(link.srcEntityName.c_str()); ++ int sinkEntity = getEntityIdByName(link.sinkEntityName.c_str()); ++ if (srcEntity >= 0 && sinkEntity >= 0) { ++ ret = setupLink(srcEntity, link.srcPad, sinkEntity, link.sinkPad, true); ++ } ++ if (ret < 0) { ++ ALOGE("@%s, Fail set link : %s --> %s", __func__, link.srcEntityName.c_str(), ++ link.sinkEntityName.c_str()); ++ } ++ } ++ return ret; ++} ++ ++void MediaControl::getDeviceName(const char* entityName, string& deviceNodeName, bool isSubDev) { ++ const char* filePrefix = "video"; ++ const char* dirPath = "/sys/class/video4linux/"; ++ if (isSubDev) filePrefix = "v4l-subdev"; ++ ++ DIR* dp = opendir(dirPath); ++ if (dp == nullptr) { ++ ALOGE("@%s, Fail open : %s", __func__, dirPath); ++ } ++ ++ struct dirent* dirp = nullptr; ++ while ((dirp = readdir(dp)) != nullptr) { ++ if ((dirp->d_type == DT_LNK) && ++ (strncmp(dirp->d_name, filePrefix, strlen(filePrefix)) == 0)) { ++ string subDeviceName = dirPath; ++ subDeviceName += dirp->d_name; ++ subDeviceName += "/name"; ++ int fd = open(subDeviceName.c_str(), O_RDONLY); ++ if (fd < 0) { ++ ALOGE("@%s, Fail open : %s", __func__, subDeviceName.c_str()); ++ } ++ ++ char buf[128] = {'\0'}; ++ int len = read(fd, buf, sizeof(buf)); ++ close(fd); ++ len--; // remove "\n" ++ if (len == (int)strlen(entityName) && memcmp(buf, entityName, len) == 0) { ++ deviceNodeName = "/dev/"; ++ deviceNodeName += dirp->d_name; ++ break; ++ } ++ } ++ } ++ closedir(dp); ++} ++ ++MediaControl* MediaControl::getMediaControlInstance() { ++ MediaControl* mediaControlInstance = nullptr; ++ ++ for (int i = 0; i < MEDIA_DEVICE_MAX_NUM; i++) { ++ std::string fileName = MEDIA_CTL_DEV_NAME; ++ fileName.append(std::to_string(i)); ++ ++ struct stat fileStat = {}; ++ int ret = stat(fileName.c_str(), &fileStat); ++ if (ret != 0) { ++ ALOGE("%s: There is no file %s", __func__, fileName.c_str()); ++ continue; ++ } ++ ++ SysCall* sc = SysCall::getInstance(); ++ int fd = sc->open(fileName.c_str(), O_RDWR); ++ if (fd < 0) { ++ ALOGE("%s, Open media device(%s) failed: %s", __func__, fileName.c_str(), ++ strerror(errno)); ++ break; ++ } ++ ++ media_device_info info; ++ ret = sc->ioctl(fd, MEDIA_IOC_DEVICE_INFO, &info); ++ if ((ret != -1) && ++ (0 == strncmp(info.driver, MEDIA_DRIVER_NAME, strlen(MEDIA_DRIVER_NAME)))) { ++ mediaControlInstance = new MediaControl(fileName.c_str()); ++ } ++ ++ if (sc->close(fd) < 0) { ++ ALOGE("Failed to close media device %s:%s", fileName.c_str(), strerror(errno)); ++ } ++ ++ if (mediaControlInstance) { ++ ALOGE("%s: media device name:%s", __func__, fileName.c_str()); ++ break; ++ } ++ } ++ ++ return mediaControlInstance; ++} ++ ++MediaControl* MediaControl::getInstance() { ++ std::unique_lock lock(sLock); ++ if (!sInstance) { ++ sInstance = getMediaControlInstance(); ++ } ++ return sInstance; ++} ++ ++void MediaControl::releaseInstance() { ++ std::unique_lock lock(sLock); ++ ++ if (sInstance) { ++ delete sInstance; ++ sInstance = nullptr; ++ } ++} ++ ++MediaControl::MediaControl(const char* devName) : mDevName(devName) {} ++ ++MediaControl::~MediaControl() {} ++ ++int MediaControl::initEntities() { ++ mEntities.reserve(100); ++ ++ int ret = enumInfo(); ++ if (ret != 0) { ++ ALOGE("Enum Info failed.\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++void MediaControl::clearEntities() { ++ auto entity = mEntities.begin(); ++ while (entity != mEntities.end()) { ++ delete[] entity->pads; ++ entity->pads = nullptr; ++ delete[] entity->links; ++ entity->links = nullptr; ++ entity = mEntities.erase(entity); ++ } ++} ++ ++MediaEntity* MediaControl::getEntityByName(const char* name) { ++ for (auto& entity : mEntities) { ++ if (strcmp(name, entity.info.name) == 0) { ++ return &entity; ++ } ++ } ++ ++ return nullptr; ++} ++ ++int MediaControl::getEntityIdByName(const char* name) { ++ MediaEntity* entity = getEntityByName(name); ++ if (!entity) { ++ return -1; ++ } ++ ++ return entity->info.id; ++} ++ ++int MediaControl::resetAllLinks() { ++ for (auto& entity : mEntities) { ++ for (uint32_t j = 0; j < entity.numLinks; j++) { ++ MediaLink* link = &entity.links[j]; ++ ++ if (link->flags & MEDIA_LNK_FL_IMMUTABLE || ++ link->source->entity->info.id != entity.info.id) { ++ continue; ++ } ++ int ret = setupLink(link->source, link->sink, link->flags & ~MEDIA_LNK_FL_ENABLED); ++ ++ if (ret < 0) return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++int MediaControl::SetRouting(int fd, v4l2_subdev_route* routes, uint32_t numRoutes) { ++ if (!routes) { ++ ALOGE("%s: Device node %d routes is nullptr", __func__, fd); ++ return -EINVAL; ++ } ++ ++ v4l2_subdev_routing r = {routes, numRoutes, {0}}; ++ ++ int ret = ::ioctl(fd, VIDIOC_SUBDEV_S_ROUTING, &r); ++ if (ret < 0) { ++ ALOGE("%s: Device node %d IOCTL VIDIOC_SUBDEV_S_ROUTING error: %s", __func__, fd, ++ strerror(errno)); ++ return ret; ++ } ++ ++ return ret; ++} ++ ++int MediaControl::GetRouting(int fd, v4l2_subdev_route* routes, uint32_t* numRoutes) { ++ if (!routes || !numRoutes) { ++ ALOGE("%s: Device node %d routes or numRoutes is nullptr", __func__, fd); ++ return -EINVAL; ++ } ++ ++ v4l2_subdev_routing r = {routes, *numRoutes, {0}}; ++ ++ int ret = ::ioctl(fd, VIDIOC_SUBDEV_G_ROUTING, &r); ++ if (ret < 0) { ++ ALOGE("%s: Device node %d IOCTL VIDIOC_SUBDEV_G_ROUTING error: %s", __func__, fd, ++ strerror(errno)); ++ return ret; ++ } ++ ++ *numRoutes = r.num_routes; ++ ++ return ret; ++} ++ ++int MediaControl::resetAllRoutes() { ++ for (MediaEntity& entity : mEntities) { ++ struct v4l2_subdev_route routes[entity.info.pads]; ++ uint32_t numRoutes = entity.info.pads; ++ ++ string subDeviceNodeName; ++ subDeviceNodeName.clear(); ++ getDeviceName(entity.info.name, subDeviceNodeName, true); ++ if (subDeviceNodeName.find("/dev/") == std::string::npos) { ++ continue; ++ } ++ ++ int fd = ::open(subDeviceNodeName.c_str(), O_RDWR); ++ int ret = GetRouting(fd, routes, &numRoutes); ++ if (ret != 0) { ++ close(fd); ++ continue; ++ } ++ ++ for (uint32_t j = 0; j < numRoutes; j++) { ++ routes[j].flags &= ~V4L2_SUBDEV_ROUTE_FL_ACTIVE; ++ } ++ ++ ret = SetRouting(fd, routes, numRoutes); ++ if (ret < 0) { ++ ALOGW("@%s, setRouting ret:%d", __func__, ret); ++ } ++ close(fd); ++ } ++ ++ return 0; ++} ++ ++int MediaControl::setupLink(MediaPad* source, MediaPad* sink, uint32_t flags) { ++ MediaLink* link = nullptr; ++ media_link_desc ulink; ++ uint32_t i; ++ int ret = 0; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ int fd = openDevice(); ++ if (fd < 0) goto done; ++ ++ for (i = 0; i < source->entity->numLinks; i++) { ++ link = &source->entity->links[i]; ++ ++ if (link->source->entity == source->entity && link->source->index == source->index && ++ link->sink->entity == sink->entity && link->sink->index == sink->index) ++ break; ++ } ++ ++ if (i == source->entity->numLinks) { ++ ALOGE("%s: Link not found", __func__); ++ ret = -ENOENT; ++ goto done; ++ } ++ ++ /* source pad */ ++ memset(&ulink, 0, sizeof(media_link_desc)); ++ ulink.source.entity = source->entity->info.id; ++ ulink.source.index = source->index; ++ ulink.source.flags = MEDIA_PAD_FL_SOURCE; ++ ++ /* sink pad */ ++ ulink.sink.entity = sink->entity->info.id; ++ ulink.sink.index = sink->index; ++ ulink.sink.flags = MEDIA_PAD_FL_SINK; ++ ++ if (link) ulink.flags = flags | (link->flags & MEDIA_LNK_FL_IMMUTABLE); ++ ++ ret = sc->ioctl(fd, MEDIA_IOC_SETUP_LINK, &ulink); ++ if (ret == -1) { ++ ret = -errno; ++ ALOGE("Unable to setup link (%s)", strerror(errno)); ++ goto done; ++ } ++ ++ if (link) { ++ link->flags = ulink.flags; ++ link->twin->flags = ulink.flags; ++ } ++ ++ ret = 0; ++ ++done: ++ closeDevice(fd); ++ return ret; ++} ++ ++int MediaControl::setupLink(uint32_t srcEntity, uint32_t srcPad, uint32_t sinkEntity, ++ uint32_t sinkPad, bool enable) { ++ ALOGD("@%s srcEntity %d srcPad %d sinkEntity %d sinkPad %d enable %d", __func__, srcEntity, ++ srcPad, sinkEntity, sinkPad, enable); ++ ++ for (auto& entity : mEntities) { ++ for (uint32_t j = 0; j < entity.numLinks; j++) { ++ MediaLink* link = &entity.links[j]; ++ ++ if ((link->source->entity->info.id == srcEntity) && (link->source->index == srcPad) && ++ (link->sink->entity->info.id == sinkEntity) && (link->sink->index == sinkPad)) { ++ if (enable) ++ link->flags |= MEDIA_LNK_FL_ENABLED; ++ else ++ link->flags &= ~MEDIA_LNK_FL_ENABLED; ++ ++ return setupLink(link->source, link->sink, link->flags); ++ } ++ } ++ } ++ ++ return -1; ++} ++ ++int MediaControl::openDevice() { ++ int fd; ++ SysCall* sc = SysCall::getInstance(); ++ ++ fd = sc->open(mDevName.c_str(), O_RDWR); ++ if (fd < 0) { ++ ALOGE("Failed to open media device %s: %s", mDevName.c_str(), strerror(errno)); ++ return -1; ++ } ++ ++ return fd; ++} ++ ++void MediaControl::closeDevice(int fd) { ++ if (fd < 0) return; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ if (sc->close(fd) < 0) { ++ ALOGE("Failed to close media device %s: %s", mDevName.c_str(), strerror(errno)); ++ } ++} ++ ++int MediaControl::enumInfo() { ++ SysCall* sc = SysCall::getInstance(); ++ ++ if (mEntities.size() > 0) return 0; ++ ++ int fd = openDevice(); ++ if (fd < 0) { ++ ALOGE("Open device failed."); ++ return fd; ++ } ++ ++ media_device_info info; ++ int ret = sc->ioctl(fd, MEDIA_IOC_DEVICE_INFO, &info); ++ if (ret < 0) { ++ ALOGE("Unable to retrieve media device information for device %s (%s)", mDevName.c_str(), ++ strerror(errno)); ++ goto done; ++ } ++ ++ ret = enumEntities(fd); ++ if (ret < 0) { ++ ALOGE("Unable to enumerate entities for device %s", mDevName.c_str()); ++ goto done; ++ } ++ ++ ALOGD("Found %lu entities, enumerating pads and links", mEntities.size()); ++ ++ ret = enumLinks(fd); ++ if (ret < 0) { ++ ALOGE("Unable to enumerate pads and linksfor device %s", mDevName.c_str()); ++ goto done; ++ } ++ ++ ret = 0; ++ ++done: ++ closeDevice(fd); ++ return ret; ++} ++ ++int MediaControl::enumEntities(int fd) { ++ MediaEntity entity; ++ uint32_t id; ++ int ret; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ for (id = 0, ret = 0;; id = entity.info.id) { ++ memset(&entity, 0, sizeof(MediaEntity)); ++ entity.info.id = id | MEDIA_ENT_ID_FLAG_NEXT; ++ ++ ret = sc->ioctl(fd, MEDIA_IOC_ENUM_ENTITIES, &entity.info); ++ if (ret < 0) { ++ ret = errno != EINVAL ? -errno : 0; ++ break; ++ } ++ ++ /* Number of links (for outbound links) plus number of pads (for ++ * inbound links) is a good safe initial estimate of the total ++ * number of links. ++ */ ++ entity.maxLinks = entity.info.pads + entity.info.links; ++ ++ entity.pads = new MediaPad[entity.info.pads]; ++ entity.links = new MediaLink[entity.maxLinks]; ++ getDevnameFromSysfs(&entity); ++ mEntities.push_back(entity); ++ ++ /* Note: carefully to move the follow setting. It must be behind of ++ * push_back to mEntities: ++ * 1. if entity is not pushed back to mEntities, getEntityById will ++ * return NULL. ++ * 2. we can't set entity.pads[i].entity to &entity direct. Because, ++ * entity is stack variable, its scope is just this function. ++ */ ++ for (uint32_t i = 0; i < entity.info.pads; ++i) { ++ entity.pads[i].entity = getEntityById(entity.info.id); ++ } ++ } ++ ++ return ret; ++} ++ ++int MediaControl::getDevnameFromSysfs(MediaEntity* entity) { ++ char sysName[MAX_SYS_NAME] = {'\0'}; ++ char target[MAX_TARGET_NAME] = {'\0'}; ++ int ret; ++ ++ if (!entity) { ++ ALOGE("entity is null."); ++ return -EINVAL; ++ } ++ ++ ret = snprintf(sysName, MAX_SYS_NAME, "/sys/dev/char/%u:%u", entity->info.v4l.major, ++ entity->info.v4l.minor); ++ if (ret <= 0) { ++ ALOGE("create sysName failed ret %d.", ret); ++ return -EINVAL; ++ } ++ ++ ret = readlink(sysName, target, MAX_TARGET_NAME); ++ if (ret <= 0) { ++ ALOGE("readlink sysName %s failed ret %d.", sysName, ret); ++ return -EINVAL; ++ } ++ ++ char* d = strrchr(target, '/'); ++ if (!d) { ++ ALOGE("target is invalid %s.", target); ++ return -EINVAL; ++ } ++ d++; /* skip '/' */ ++ ++ char* t = strstr(d, "dvb"); ++ if (t && t == d) { ++ t = strchr(t, '.'); ++ if (!t) { ++ ALOGE("target is invalid %s.", target); ++ return -EINVAL; ++ } ++ *t = '/'; ++ d += 3; /* skip "dvb" */ ++ snprintf(entity->devname, sizeof(entity->devname), "/dev/dvb/adapter%s", d); ++ } else { ++ snprintf(entity->devname, sizeof(entity->devname), "/dev/%s", d); ++ } ++ ++ return 0; ++} ++ ++int MediaControl::enumLinks(int fd) { ++ int ret = 0; ++ ++ SysCall* sc = SysCall::getInstance(); ++ ++ for (auto& entity : mEntities) { ++ media_links_enum links; ++ uint32_t i; ++ ++ links.entity = entity.info.id; ++ links.pads = new media_pad_desc[entity.info.pads]; ++ links.links = new media_link_desc[entity.info.links]; ++ ++ if (sc->ioctl(fd, MEDIA_IOC_ENUM_LINKS, &links) < 0) { ++ ret = -errno; ++ ALOGE("Unable to enumerate pads and links (%s).", strerror(errno)); ++ delete[] links.pads; ++ delete[] links.links; ++ return ret; ++ } ++ ++ for (i = 0; i < entity.info.pads; ++i) { ++ entity.pads[i].entity = getEntityById(entity.info.id); ++ entity.pads[i].index = links.pads[i].index; ++ entity.pads[i].flags = links.pads[i].flags; ++ } ++ ++ for (i = 0; i < entity.info.links; ++i) { ++ media_link_desc* link = &links.links[i]; ++ MediaLink* fwdlink; ++ MediaLink* backlink; ++ MediaEntity* source; ++ MediaEntity* sink; ++ ++ source = getEntityById(link->source.entity); ++ sink = getEntityById(link->sink.entity); ++ ++ if (source == nullptr || sink == nullptr) { ++ ALOGE("WARNING entity %u link %u src %u/%u to %u/%u is invalid!", entity.info.id, i, ++ link->source.entity, link->source.index, link->sink.entity, link->sink.index); ++ ret = -EINVAL; ++ } else if (link->source.index < 0 || link->source.index >= source->info.pads) { ++ ALOGE("WARNING entity %u link %u src %u/%u index out of range!", entity.info.id, i, ++ link->source.entity, link->source.index); ++ ret = -EINVAL; ++ } else if (link->sink.index < 0 || link->sink.index >= sink->info.pads) { ++ ALOGE("WARNING entity %u link %u to %u/%u index out of range!", entity.info.id, i, ++ link->sink.entity, link->sink.index); ++ ret = -EINVAL; ++ } else { ++ fwdlink = entityAddLink(source); ++ if (fwdlink) { ++ fwdlink->source = &source->pads[link->source.index]; ++ fwdlink->sink = &sink->pads[link->sink.index]; ++ fwdlink->flags = link->flags; ++ } ++ ++ backlink = entityAddLink(sink); ++ if (backlink) { ++ backlink->source = &source->pads[link->source.index]; ++ backlink->sink = &sink->pads[link->sink.index]; ++ backlink->flags = link->flags; ++ } ++ ++ if (fwdlink) fwdlink->twin = backlink; ++ if (backlink) backlink->twin = fwdlink; ++ } ++ } ++ ++ delete[] links.pads; ++ delete[] links.links; ++ } ++ ++ return ret; ++} ++ ++MediaLink* MediaControl::entityAddLink(MediaEntity* entity) { ++ if (entity->numLinks >= entity->maxLinks) { ++ uint32_t maxLinks = entity->maxLinks * 2; ++ MediaLink* links = new MediaLink[maxLinks]; ++ ++ memcpy(links, entity->links, sizeof(MediaLink) * entity->maxLinks); ++ delete[] entity->links; ++ ++ for (uint32_t i = 0; i < entity->numLinks; ++i) { ++ links[i].twin->twin = &links[i]; ++ } ++ ++ entity->maxLinks = maxLinks; ++ entity->links = links; ++ } ++ ++ return &entity->links[entity->numLinks++]; ++} ++ ++MediaEntity* MediaControl::getEntityById(uint32_t id) { ++ bool next = id & MEDIA_ENT_ID_FLAG_NEXT; ++ ++ id &= ~MEDIA_ENT_ID_FLAG_NEXT; ++ ++ for (uint32_t i = 0; i < mEntities.size(); i++) { ++ if ((mEntities[i].info.id == id && !next) || (mEntities[0].info.id > id && next)) { ++ return &mEntities[i]; ++ } ++ } ++ ++ return nullptr; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp b/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp +new file mode 100644 +index 000000000..bc5a61842 +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/src/NodeInfo.cpp +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (C) 2020 Intel Corporation ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include "NodeInfo.h" ++#include ++ ++#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) ++ ++const VideoNodeInfo gVideoNodeInfos[] = { ++ {VIDEO_GENERIC, "VIDEO_GENERIC", "Generic"}, ++ {VIDEO_GENERIC_MEDIUM_EXPO, "VIDEO_GENERIC_MEDIUM_EXPO", "GenericMediumExpo"}, ++ {VIDEO_GENERIC_SHORT_EXPO, "VIDEO_GENERIC_SHORT_EXPO", "GenericShortExpo"}, ++ // CSI_META_S ++ {VIDEO_CSI_META, "VIDEO_CSI_META", "CsiMeta"}, ++ // CSI_META_E ++ ++ {VIDEO_PIXEL_ARRAY, "VIDEO_PIXEL_ARRAY", "PixelArray"}, ++ {VIDEO_PIXEL_BINNER, "VIDEO_PIXEL_BINNER", "PixelBinner"}, ++ {VIDEO_PIXEL_SCALER, "VIDEO_PIXEL_SCALER", "PixelScaler"}, ++ ++ {VIDEO_ISYS_RECEIVER, "VIDEO_ISYS_RECEIVER", "ISysReceiver"}, ++ {VIDEO_ISYS_RECEIVER_BACKEND, "VIDEO_ISYS_RECEIVER_BACKEND", "CsiBE"}, ++}; ++ ++const char* GetNodeName(VideoNodeType nodeType) { ++ int size = ARRAY_SIZE(gVideoNodeInfos); ++ for (int i = 0; i < size; i++) { ++ if (gVideoNodeInfos[i].type == nodeType) { ++ return gVideoNodeInfos[i].shortName; ++ } ++ } ++ return "InvalidNode"; ++} ++ ++VideoNodeType GetNodeType(const char* nodeName) { ++ int size = ARRAY_SIZE(gVideoNodeInfos); ++ for (int i = 0; i < size; i++) { ++ if (strcmp(gVideoNodeInfos[i].fullName, nodeName) == 0) { ++ return gVideoNodeInfos[i].type; ++ } ++ } ++ ++ return VIDEO_GENERIC; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/SysCall.cpp b/cpp/evs/sampleDriver/aidl/src/SysCall.cpp +new file mode 100644 +index 000000000..b66e0e60b +--- /dev/null ++++ b/cpp/evs/sampleDriver/aidl/src/SysCall.cpp +@@ -0,0 +1,171 @@ ++/* ++ * Copyright (C) 2015-2021 Intel Corporation. ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++ ++#include "SysCall.h" ++#include ++#include ++ ++static int sCreatedCount = 0; ++bool SysCall::sIsInitialized = false; ++SysCall* SysCall::sInstance = nullptr; ++// Guard for singleton instance creation ++std::mutex SysCall::sLock; ++ ++/*static*/ SysCall* SysCall::getInstance() { ++ std::unique_lock lock(sLock); ++ if (!sIsInitialized) { ++ // Use real sys call as default ++ sInstance = new SysCall(); ++ sIsInitialized = true; ++ } ++ return sInstance; ++} ++ ++void SysCall::updateInstance(SysCall* newSysCall) { ++ ALOGI("%s", __func__); ++ std::unique_lock lock(sLock); ++ if (sIsInitialized) { ++ sIsInitialized = false; ++ } ++ sInstance = newSysCall; ++ if (newSysCall != nullptr) sIsInitialized = true; ++} ++ ++SysCall::SysCall() { ++ sCreatedCount++; ++ ALOGI("Syscall was created %d time", sCreatedCount); ++} ++ ++SysCall::~SysCall() { ++ sCreatedCount--; ++ ALOGI("Syscall was destructed %d time", sCreatedCount); ++} ++ ++int SysCall::open(const char* pathname, int flags) { ++ return ::open(pathname, flags); ++} ++ ++int SysCall::close(int fd) { ++ return ::close(fd); ++} ++ ++void* SysCall::mmap(void* addr, size_t len, int prot, int flag, int filedes, off_t off) { ++ return ::mmap(addr, len, prot, flag, filedes, off); ++} ++ ++int SysCall::munmap(void* addr, size_t len) { ++ return ::munmap(addr, len); ++} ++ ++int SysCall::ioctl(int fd, int request, struct media_device_info* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_link_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_links_enum* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_links_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct media_entity_desc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_capability* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, v4l2_fmtdesc* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, enum v4l2_buf_type* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_format* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_requestbuffers* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_buffers* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_buffer* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_format* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_stream* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++int SysCall::ioctl(int fd, int request, struct v4l2_streamon_info* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_ext_controls* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_control* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_queryctrl* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_selection* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_subdev_routing* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_querymenu* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_event_subscription* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_event* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, struct v4l2_exportbuffer* arg) { ++ return ioctl(fd, request, reinterpret_cast(arg)); ++} ++ ++int SysCall::ioctl(int fd, int request, void* arg) { ++ int ret = 0; ++ do { ++ ret = ::ioctl(fd, request, arg); ++ } while (-1 == ret && EINTR == errno); ++ ++ return ret; ++} ++ ++int SysCall::poll(struct pollfd* pfd, nfds_t nfds, int timeout) { ++ int ret = 0; ++ do { ++ ret = ::poll(pfd, nfds, timeout); ++ } while (-1 == ret && EINTR == errno); ++ ++ return ret; ++} +diff --git a/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp b/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp +index d0e9009be..b2c869428 100644 +--- a/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp ++++ b/cpp/evs/sampleDriver/aidl/src/VideoCapture.cpp +@@ -15,6 +15,8 @@ + */ + + #include "VideoCapture.h" ++#include ++#include + + #include + +@@ -37,8 +39,10 @@ + // the file descriptor. This must be fixed before using this code for anything but + // experimentation. + bool VideoCapture::open(const char* deviceName, const int32_t width, const int32_t height) { ++ ++ LOG(INFO) <<"App requested resolution "<= 0) { ++ struct v4l2_frmivalenum frmival; ++ memset(&frmival, 0, sizeof(frmival)); ++ frmival.pixel_format = formatDescriptions.pixelformat; ++ if (frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) { ++ frmival.width = frmsize.discrete.width; ++ frmival.height = frmsize.discrete.height; ++ while (ioctl(mDeviceFd, VIDIOC_ENUM_FRAMEINTERVALS, &frmival) == 0) { ++ if ((frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) && ++ (1.0 * frmival.discrete.denominator / frmival.discrete.numerator > ++ 29.0) && ++ (requestWidth * requestHeight) < ++ frmsize.discrete.width * frmsize.discrete.height) { ++ if(frmsize.discrete.width == (uint32_t)width && frmsize.discrete.height == (uint32_t)height) { ++ LOG(INFO) <<"Driver support this resolution "; ++ requestWidth = frmsize.discrete.width; ++ requestHeight = frmsize.discrete.height; ++ break; ++ } ++ } ++ frmival.index++; ++ } ++ } else { ++ LOG(INFO) << "Stepwise: step_width=" << frmsize.stepwise.step_width<< " step_height=" << frmsize.stepwise.step_height; ++ LOG(INFO) << "min_width = " << frmsize.stepwise.min_width << " min_height=" << frmsize.stepwise.min_height; ++ LOG(INFO) << "max_width = " << frmsize.stepwise.max_width << " max_height=" << frmsize.stepwise.max_height; ++ requestWidth = frmsize.stepwise.min_width; ++ requestHeight = frmsize.stepwise.min_height; ++ ++ } ++ frmsize.index++; ++ } + } else { + // No more formats available + break; + } + } +- +- // Verify we can use this device for video capture +- if (!(caps.capabilities & V4L2_CAP_VIDEO_CAPTURE) || +- !(caps.capabilities & V4L2_CAP_STREAMING)) { +- // Can't do streaming capture. +- LOG(ERROR) << "Streaming capture not supported by " << deviceName; +- return false; +- } +- + // Set our desired output format + v4l2_format format; +- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +- format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; +- format.fmt.pix.width = width; +- format.fmt.pix.height = height; +- LOG(INFO) << "Requesting format: " << ((char*)&format.fmt.pix.pixelformat)[0] +- << ((char*)&format.fmt.pix.pixelformat)[1] << ((char*)&format.fmt.pix.pixelformat)[2] +- << ((char*)&format.fmt.pix.pixelformat)[3] << "(" << std::hex << std::setw(8) +- << format.fmt.pix.pixelformat << ")"; ++ format.type = mBufferType; ++ if (format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ format.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_UYVY; ++ format.fmt.pix_mp.width = width; ++ format.fmt.pix_mp.height = height; ++ format.fmt.pix_mp.num_planes = 1; ++ format.fmt.pix_mp.plane_fmt[0].bytesperline = width * 2; ++ format.fmt.pix_mp.plane_fmt[0].sizeimage = width * height * 2; ++ } else if (strcmp((char*)caps.driver, "virtio-camera") == 0) { ++ LOG(INFO) << "Virtio-camera"< 0 ? requestWidth : 1280; ++ format.fmt.pix.height = requestHeight > 0 ? requestHeight : 960; ++ } else { ++ format.type = V4L2_CAP_VIDEO_CAPTURE; ++ format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; ++ format.fmt.pix.width = requestWidth > 0 ? requestWidth : width; ++ format.fmt.pix.height = requestHeight > 0 ? requestHeight : height; ++ } + + if (ioctl(mDeviceFd, VIDIOC_S_FMT, &format) < 0) { + PLOG(ERROR) << "VIDIOC_S_FMT failed"; + } + + // Report the current output format +- format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(mDeviceFd, VIDIOC_G_FMT, &format) == 0) { +- mFormat = format.fmt.pix.pixelformat; +- mWidth = format.fmt.pix.width; +- mHeight = format.fmt.pix.height; +- mStride = format.fmt.pix.bytesperline; +- +- LOG(INFO) << "Current output format: " << "fmt=0x" << std::hex +- << format.fmt.pix.pixelformat << ", " << std::dec << format.fmt.pix.width << " x " +- << format.fmt.pix.height << ", pitch=" << format.fmt.pix.bytesperline; ++ if (format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ mFormat = format.fmt.pix_mp.pixelformat; ++ mWidth = format.fmt.pix_mp.width; ++ mHeight = format.fmt.pix_mp.height; ++ mStride = format.fmt.pix_mp.plane_fmt[0].bytesperline; ++ } else { ++ mFormat = format.fmt.pix.pixelformat; ++ mWidth = format.fmt.pix.width; ++ mHeight = format.fmt.pix.height; ++ mStride = format.fmt.pix.bytesperline; ++ } ++ ++ LOG(INFO) << "Current output format: " ++ << "fmt=0x" << std::hex << mFormat << ", " << std::dec << mWidth << " x " ++ << mHeight << ", pitch=" << mStride; + } else { + PLOG(ERROR) << "VIDIOC_G_FMT failed"; + return false; +@@ -148,45 +212,64 @@ bool VideoCapture::startStream(std::function(mNumBuffers); + mPixelBuffers = std::make_unique(mNumBuffers); + + for (int i = 0; i < mNumBuffers; ++i) { + // Get the information on the buffer that was created for us + memset(&mBufferInfos[i], 0, sizeof(v4l2_buffer)); +- mBufferInfos[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; ++ mBufferInfos[i].type = mBufferType; + mBufferInfos[i].memory = V4L2_MEMORY_MMAP; + mBufferInfos[i].index = i; + ++ if (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ std::vector planes; ++ planes.resize(VIDEO_PLANES); ++ mBufferInfos[i].m.planes = planes.data(); ++ mBufferInfos[i].length = planes.size(); ++ } ++ + if (ioctl(mDeviceFd, VIDIOC_QUERYBUF, &mBufferInfos[i]) < 0) { + PLOG(ERROR) << "VIDIOC_QUERYBUF failed"; + return false; + } + ++ uint32_t memOffset = mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? ++ mBufferInfos[i].m.planes[0].m.mem_offset : ++ mBufferInfos[i].m.offset; + LOG(DEBUG) << "Buffer description:"; +- LOG(DEBUG) << " offset: " << mBufferInfos[i].m.offset; ++ LOG(INFO) << " offset: " << memOffset; + LOG(DEBUG) << " length: " << mBufferInfos[i].length; + LOG(DEBUG) << " flags : " << std::hex << mBufferInfos[i].flags; +- +- // Get a pointer to the buffer contents by mapping into our address space +- mPixelBuffers[i] = mmap(NULL, mBufferInfos[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, +- mDeviceFd, mBufferInfos[i].m.offset); +- +- if (mPixelBuffers[i] == MAP_FAILED) { +- PLOG(ERROR) << "mmap() failed"; +- return false; ++ if (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ LOG(INFO) << " size : " << std::hex << mBufferInfos[i].m.planes[0].length; ++ ++ mBufferSize = (mBufferInfos[i].type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ? ++ mBufferInfos[i].m.planes[0].length : ++ mBufferInfos[i].length; ++ std::vector mappedBuffer; ++ mappedBuffer.resize(VIDEO_PLANES); ++ for (uint32_t plane = 0; plane < VIDEO_PLANES; plane++) { ++ mappedBuffer[plane] = ++ mmap(NULL, mBufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, mDeviceFd, memOffset); ++ ++ if (mappedBuffer[plane] == MAP_FAILED) { ++ PLOG(ERROR) << "mmap() failed"; ++ return false; ++ } ++ ++ memset(mappedBuffer[plane], 0, mBufferSize); + } +- +- memset(mPixelBuffers[i], 0, mBufferInfos[i].length); ++ mPixelBuffers[i] = mappedBuffer[0]; + LOG(INFO) << "Buffer mapped at " << mPixelBuffers[i]; + + // Queue the first capture buffer +@@ -197,10 +280,10 @@ bool VideoCapture::startStream(std::functionwidth, pDesc->height); ++ if (result) { ++ LOG(ERROR) << "Failed to convert BGRA to RGBA."; ++ } ++} ++ + void fillYUYVFromYUYV(const BufferDesc& tgtBuff, uint8_t* tgt, void* imgData, unsigned imgStride) { + const AHardwareBuffer_Desc* pDesc = + reinterpret_cast(&tgtBuff.buffer.description); +-- +2.17.1 + diff --git a/aosp_diff/preliminary/prebuilts/build-tools/01_0001-WA-Fixed-Build-Error-For-Python.patch b/aosp_diff/base_aaos/prebuilts/build-tools/01_0001-WA-Fixed-Build-Error-For-Python.patch similarity index 100% rename from aosp_diff/preliminary/prebuilts/build-tools/01_0001-WA-Fixed-Build-Error-For-Python.patch rename to aosp_diff/base_aaos/prebuilts/build-tools/01_0001-WA-Fixed-Build-Error-For-Python.patch diff --git a/aosp_diff/caas/frameworks/av/0001-Enable-AIDL-as-first-option-in-audio-rc-file.patch b/aosp_diff/caas/frameworks/av/0001-Enable-AIDL-as-first-option-in-audio-rc-file.patch new file mode 100644 index 0000000000..3d5e66bbbc --- /dev/null +++ b/aosp_diff/caas/frameworks/av/0001-Enable-AIDL-as-first-option-in-audio-rc-file.patch @@ -0,0 +1,83 @@ +From e0567832c916949801fe91d26347f82dd2de86ee Mon Sep 17 00:00:00 2001 +From: padmashree mandri +Date: Fri, 2 Aug 2024 05:21:02 +0000 +Subject: [PATCH] Enable AIDL as first option in audio rc file + +When AIDL is enabled, audioserver crashes as it tries to connect +to HIDL as per the entry in .rc file. Changing the order to pick +aidl by audioserver, to avoid crash and pick aidl. + +Test Done: Android boots fine and no audioserver crash found. + +Tracked-on: OAM-122993 +Signed-off-by: padmashree mandri +--- + media/audioserver/audioserver.rc | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc +index 3445703760..0584c24cc8 100644 +--- a/media/audioserver/audioserver.rc ++++ b/media/audioserver/audioserver.rc +@@ -8,11 +8,11 @@ service audioserver /system/bin/audioserver + rlimit rtprio 10 10 + ioprio rt 4 + task_profiles ProcessCapacityHigh HighPerformance +- onrestart restart vendor.audio-hal + onrestart restart vendor.audio-hal-aidl + onrestart restart vendor.audio-effect-hal-aidl + onrestart restart vendor.audio-hal-4-0-msd + onrestart restart audio_proxy_service ++ onrestart restart vendor.audio-hal + + on property:vts.native_server.on=1 + stop audioserver +@@ -20,40 +20,40 @@ on property:vts.native_server.on=0 + start audioserver + + on property:init.svc.audioserver=stopped +- stop vendor.audio-hal + stop vendor.audio-hal-aidl + stop vendor.audio-effect-hal-aidl + stop vendor.audio-hal-4-0-msd + stop audio_proxy_service ++ stop vendor.audio-hal + # See b/155364397. Need to have HAL service running for VTS. + # Can't use 'restart' because then HAL service would restart + # audioserver bringing it back into running state. +- start vendor.audio-hal + start vendor.audio-hal-aidl + start vendor.audio-effect-hal-aidl + start vendor.audio-hal-4-0-msd + start audio_proxy_service ++ start vendor.audio-hal + + on property:init.svc.audioserver=running +- start vendor.audio-hal + start vendor.audio-hal-aidl + start vendor.audio-effect-hal-aidl + start vendor.audio-hal-4-0-msd + start audio_proxy_service ++ start vendor.audio-hal + + on property:sys.audio.restart.hal=1 + # See b/159966243. Avoid restart loop between audioserver and HAL. + # Keep the original service names for backward compatibility +- stop vendor.audio-hal + stop vendor.audio-hal-aidl + stop vendor.audio-effect-hal-aidl + stop vendor.audio-hal-4-0-msd + stop audio_proxy_service +- start vendor.audio-hal ++ stop vendor.audio-hal + start vendor.audio-hal-aidl + start vendor.audio-effect-hal-aidl + start vendor.audio-hal-4-0-msd + start audio_proxy_service ++ start vendor.audio-hal + # reset the property + setprop sys.audio.restart.hal 0 + +-- +2.34.1 + diff --git a/aosp_diff/caas/packages/apps/Camera2/0001-WA-ignore-internal-storage-error-for-capture-record.patch_bkup b/aosp_diff/caas/packages/apps/Camera2/0001-WA-ignore-internal-storage-error-for-capture-record.patch_bkup new file mode 100644 index 0000000000..9a3043c1e1 --- /dev/null +++ b/aosp_diff/caas/packages/apps/Camera2/0001-WA-ignore-internal-storage-error-for-capture-record.patch_bkup @@ -0,0 +1,66 @@ +From fc7ad7b5cd51d8180a092a51348926e1204749ef Mon Sep 17 00:00:00 2001 +From: shivasku82 +Date: Thu, 17 Aug 2023 12:25:06 +0530 +Subject: [PATCH] [WA] ignore internal storage error for capture\record. + +Camera2 app is disabling all the user interaction as storage +access to data/app write permission is not allowed. + +Ignoring the storage write access failure and continue the camera +app to take picture and record video. + +Tracked-On: OAM-111650 +Change-Id: I6ecf0b51ef758f0c03829965ca1225b2356ea3e5 +Signed-off-by: shivasku82 +--- + src/com/android/camera/CameraActivity.java | 5 +++-- + src/com/android/camera/VideoModule.java | 6 +++--- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java +index 3093b2584..547e24700 100644 +--- a/src/com/android/camera/CameraActivity.java ++++ b/src/com/android/camera/CameraActivity.java +@@ -2381,11 +2381,12 @@ public class CameraActivity extends QuickActivity + } else { + mStorageHint.setText(message); + } +- mStorageHint.show(); ++ /*mStorageHint.show(); + UsageStatistics.instance().storageWarning(storageSpace); + + // Disable all user interactions, +- mCameraAppUI.setDisableAllUserInteractions(true); ++ mCameraAppUI.setDisableAllUserInteractions(true);*/ ++ mCameraAppUI.setDisableAllUserInteractions(false); + } else if (mStorageHint != null) { + mStorageHint.cancel(); + mStorageHint = null; +diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java +index f63c962f3..65c1979e4 100644 +--- a/src/com/android/camera/VideoModule.java ++++ b/src/com/android/camera/VideoModule.java +@@ -1363,9 +1363,9 @@ public class VideoModule extends CameraModule + mActivity.updateStorageSpaceAndHint(new CameraActivity.OnStorageUpdateDoneListener() { + @Override + public void onStorageUpdateDone(long bytes) { +- if (bytes <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { ++/* if (bytes <= Storage.LOW_STORAGE_THRESHOLD_BYTES) { + Log.w(TAG, "Storage issue, ignore the start request"); +- } else { ++ } else {*/ + if (mCameraDevice == null) { + Log.v(TAG, "in storage callback after camera closed"); + return; +@@ -1436,7 +1436,7 @@ public class VideoModule extends CameraModule + + updateRecordingTime(); + mActivity.enableKeepScreenOn(true); +- } ++ // } + } + }); + } +-- +2.17.1 + diff --git a/aosp_diff/caas/system/sepolicy/0003-Fix-for-Fuzzer-error-with-lunch-caas-ap3a-user.patch b/aosp_diff/caas/system/sepolicy/0003-Fix-for-Fuzzer-error-with-lunch-caas-ap3a-user.patch new file mode 100644 index 0000000000..d95aa36a96 --- /dev/null +++ b/aosp_diff/caas/system/sepolicy/0003-Fix-for-Fuzzer-error-with-lunch-caas-ap3a-user.patch @@ -0,0 +1,36 @@ +From 55e47fbbf039387825e89b013729b69f294a3e78 Mon Sep 17 00:00:00 2001 +From: "Bhadouria, Aman" +Date: Fri, 16 Aug 2024 10:29:43 +0000 +Subject: [PATCH] Fix for Fuzzer error with 'lunch caas-ap3a-user' + +When giving full build with lunch caas-ap3a-user +we get error that the newly added SharedSecret +service has no fuzzer entry + +Added the required fuzzer entry + +Tests Done: +1. Flash the image Bare metal or CiV +2. Image is booting and service is running + +Tracked-On: OAM-123515 +Signed-off-by: Bhadouria, Aman +--- + build/soong/service_fuzzer_bindings.go | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/build/soong/service_fuzzer_bindings.go b/build/soong/service_fuzzer_bindings.go +index 6ea767907..96438ab0a 100644 +--- a/build/soong/service_fuzzer_bindings.go ++++ b/build/soong/service_fuzzer_bindings.go +@@ -128,6 +128,7 @@ var ( + "android.hardware.security.secretkeeper.ISecretkeeper/nonsecure": []string{"android.hardware.security.secretkeeper-service.nonsecure_fuzzer"}, + "android.hardware.security.secureclock.ISecureClock/default": EXCEPTION_NO_FUZZER, + "android.hardware.security.sharedsecret.ISharedSecret/default": EXCEPTION_NO_FUZZER, ++ "android.hardware.security.sharedsecret.ISharedSecret/gatekeeper": EXCEPTION_NO_FUZZER, + "android.hardware.sensors.ISensors/default": EXCEPTION_NO_FUZZER, + "android.hardware.soundtrigger3.ISoundTriggerHw/default": EXCEPTION_NO_FUZZER, + "android.hardware.tetheroffload.IOffload/default": EXCEPTION_NO_FUZZER, +-- +2.34.1 + diff --git a/aosp_diff/caas_cfc/frameworks/av/0001-Using-RGB565-in-case-YV12-is-not-supported.patch b/aosp_diff/caas_cfc/frameworks/av/0001-Using-RGB565-in-case-YV12-is-not-supported.patch deleted file mode 100644 index 0893db48cc..0000000000 --- a/aosp_diff/caas_cfc/frameworks/av/0001-Using-RGB565-in-case-YV12-is-not-supported.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 85326d6bce0834976d5f9a73800b08ec06cbbab6 Mon Sep 17 00:00:00 2001 -From: renchenglei -Date: Thu, 12 Nov 2020 01:45:25 +0800 -Subject: [PATCH] Using RGB565 in case YV12 is not supported - -Tracked-On: OAM-98107 ---- - .../colorconversion/SoftwareRenderer.cpp | 18 +++++++++++++++++- - media/ndk/NdkImageReader.cpp | 4 ++++ - 2 files changed, 21 insertions(+), 1 deletion(-) - -diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp -index 471131561531..756c94353de0 100644 ---- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp -+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp -@@ -98,6 +98,15 @@ void SoftwareRenderer::resetFormatIfChanged( - dataSpaceChangedForPlanar16 = true; - } - -+ char szVendorIntelVideoCodec[PROPERTY_VALUE_MAX] = {'\0'}; -+ bool noYUV = false; -+ -+ if(property_get("vendor.intel.video.codec", szVendorIntelVideoCodec, NULL) > 0 ) { -+ if (strncmp(szVendorIntelVideoCodec, "hardware", PROPERTY_VALUE_MAX) != 0 ) { -+ noYUV = true; -+ } -+ } -+ - if (static_cast(mColorFormat) == colorFormatNew && - mWidth == widthNew && - mHeight == heightNew && -@@ -105,7 +114,8 @@ void SoftwareRenderer::resetFormatIfChanged( - mCropTop == cropTopNew && - mCropRight == cropRightNew && - mCropBottom == cropBottomNew && -- !dataSpaceChangedForPlanar16) { -+ !dataSpaceChangedForPlanar16 && -+ !noYUV) { - // Nothing changed, no need to reset renderer. - return; - } -@@ -134,6 +144,9 @@ void SoftwareRenderer::resetFormatIfChanged( - case OMX_COLOR_FormatYUV420SemiPlanar: - case OMX_TI_COLOR_FormatYUV420PackedSemiPlanar: - { -+ if (noYUV) { -+ break; -+ } - halFormat = HAL_PIXEL_FORMAT_YV12; - bufWidth = (mCropWidth + 1) & ~1; - bufHeight = (mCropHeight + 1) & ~1; -@@ -164,6 +177,9 @@ void SoftwareRenderer::resetFormatIfChanged( - // use render engine to convert it to RGB if needed. - halFormat = HAL_PIXEL_FORMAT_RGBA_1010102; - } else { -+ if (noYUV) { -+ break; -+ } - halFormat = HAL_PIXEL_FORMAT_YV12; - } - bufWidth = (mCropWidth + 1) & ~1; -diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp -index c0ceb3d70b84..4192fc4b1331 100644 ---- a/media/ndk/NdkImageReader.cpp -+++ b/media/ndk/NdkImageReader.cpp -@@ -469,6 +469,10 @@ AImageReader::acquireImageLocked(/*out*/AImage** image, /*out*/int* acquireFence - // YUV. - mHalFormat = bufferFmt; - ALOGD("%s: Overriding buffer format YUV_420_888 to 0x%x.", __FUNCTION__, bufferFmt); -+ } else if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && bufferFmt == HAL_PIXEL_FORMAT_RGB_565) { -+ //YUV format is not supported on virtio gpu, fall back to RGB565 -+ mHalFormat = bufferFmt; -+ ALOGD("%s: Overriding buffer format YUV_420_888 to 0x%x.", __FUNCTION__, bufferFmt); - } else { - // Return the buffer to the queue. No need to provide fence, as this buffer wasn't - // used anywhere yet. --- -2.17.1 - diff --git a/aosp_diff/caas_cfc/include_preliminary b/aosp_diff/caas_cfc/include_preliminary deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aosp_diff/caas_dev/include_preliminary b/aosp_diff/caas_dev/include_preliminary deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aosp_diff/preliminary/art/0001-Modify-install-hook-check-in-art.patch b/aosp_diff/preliminary/art/0001-Modify-install-hook-check-in-art.patch deleted file mode 100644 index bd14ce3fce..0000000000 --- a/aosp_diff/preliminary/art/0001-Modify-install-hook-check-in-art.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 68f3495e243c55144240de53ae06d929edff8adb Mon Sep 17 00:00:00 2001 -From: Priyanka Bose -Date: Thu, 14 Jul 2022 11:30:14 +0530 -Subject: [PATCH] The install hook can be called for more than one module - variant for the same library (for host). This patch modifies path len check - so as to avoid conflict for avx2 version of libs for x86 and x86_64 - -Tracked-On: -Signed-off-by: Priyanka Bose -Change-Id: I23a485bf7d072b1ab5bd3c8aee0f58ecffa7bd43 ---- - build/art.go | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/build/art.go b/build/art.go -index 79149503c510..586cb6addc71 100644 ---- a/build/art.go -+++ b/build/art.go -@@ -317,7 +317,9 @@ func addTestcasesFile(ctx android.InstallHookContext) { - src := ctx.SrcPath().String() - path := strings.Split(ctx.Path().String(), "/") - // Keep last two parts of the install path (e.g. bin/dex2oat). -- dst := strings.Join(path[len(path)-2:], "/") -+ //dst := strings.Join(path[len(path)-2:], "/") -+ // Keep last four parts of the install path (e.g. bin/dex2oat). -+ dst := strings.Join(path[len(path)-4:], "/") - if oldSrc, ok := testcasesContent[dst]; ok { - ctx.ModuleErrorf("Conflicting sources for %s: %s and %s", dst, oldSrc, src) - } --- -2.25.1 - diff --git a/aosp_diff/preliminary/art/0002-Auto-Fast-JNI-Optimization.patch b/aosp_diff/preliminary/art/0002-Auto-Fast-JNI-Optimization.patch deleted file mode 100644 index 64f73129a8..0000000000 --- a/aosp_diff/preliminary/art/0002-Auto-Fast-JNI-Optimization.patch +++ /dev/null @@ -1,2136 +0,0 @@ -From 0a72289ebb2c312ae8d9a25e1980b6329ba17e70 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 15 Sep 2023 19:17:55 +0530 -Subject: [PATCH] Auto Fast JNI Optimization - -Change-Id: I87c210b0ee40370ad4884be7c5baafe7a995c331 -Signed-off-by: Priyanka Bose ---- - disassembler/disassembler_x86.cc | 40 +- - disassembler/disassembler_x86.h | 12 +- - runtime/Android.bp | 5 + - runtime/art_method.cc | 1 + - runtime/binary_analyzer/BinaryDisassembler.cc | 54 ++ - runtime/binary_analyzer/BinaryDisassembler.h | 106 +++ - runtime/binary_analyzer/binary_analyzer.h | 67 ++ - .../binary_analyzer/binary_analyzer_x86.cc | 731 ++++++++++++++++++ - runtime/binary_analyzer/binary_analyzer_x86.h | 700 +++++++++++++++++ - runtime/class_linker.cc | 43 ++ - runtime/entrypoints/jni/jni_entrypoints.cc | 47 +- - runtime/jit/jit.cc | 8 + - runtime/jit/jit.h | 6 +- - runtime/parsed_options.cc | 7 +- - runtime/runtime.cc | 4 +- - runtime/runtime.h | 13 + - runtime/runtime_options.def | 1 + - 17 files changed, 1830 insertions(+), 15 deletions(-) - create mode 100644 runtime/binary_analyzer/BinaryDisassembler.cc - create mode 100644 runtime/binary_analyzer/BinaryDisassembler.h - create mode 100644 runtime/binary_analyzer/binary_analyzer.h - create mode 100644 runtime/binary_analyzer/binary_analyzer_x86.cc - create mode 100644 runtime/binary_analyzer/binary_analyzer_x86.h - -diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc -index 98201f9a27..c4955c9cb3 100644 ---- a/disassembler/disassembler_x86.cc -+++ b/disassembler/disassembler_x86.cc -@@ -17,7 +17,6 @@ - #include "disassembler_x86.h" - - #include -- - #include - #include - -@@ -280,12 +279,21 @@ static constexpr uint8_t kNops[][10] = { - return 0; - } - --size_t DisassemblerX86::DumpInstruction(std::ostream& os, const uint8_t* instr) { -- size_t nop_size = DumpNops(os, instr); -- if (nop_size != 0u) { -- return nop_size; -+void DisassemblerX86::GetInstructionDetails(const uint8_t* instr, x86_instr *insn) { -+ std::ostream out(nullptr);; -+ size_t sz = DumpInstruction(out,instr,insn); -+ if (sz == 0) { -+ insn->opcode = 0x0; - } -+} - -+size_t DisassemblerX86::DumpInstruction(std::ostream& os, const uint8_t* instr,x86_instr *insn_x86) { -+ if (os) { -+ size_t nop_size = DumpNops(os, instr); -+ if (nop_size != 0u) { -+ return nop_size; -+ } -+ } - const uint8_t* begin_instr = instr; - bool have_prefixes = true; - uint8_t prefix[4] = {0, 0, 0, 0}; -@@ -1608,12 +1616,26 @@ DISASSEMBLER_ENTRY(cmp, - case 0: prefix_str = ""; break; - default: LOG(FATAL) << "Unreachable"; UNREACHABLE(); - } -- os << FormatInstructionPointer(begin_instr) -- << StringPrintf(": %22s \t%-7s%s%s%s%s%s ", DumpCodeHex(begin_instr, instr).c_str(), -+ if (os) { -+ os << FormatInstructionPointer(begin_instr) -+ << StringPrintf(": %22s \t%-7s%s%s%s%s%s ", DumpCodeHex(begin_instr, instr).c_str(), - prefix_str, opcode0, opcode1, opcode2, opcode3, opcode4) -- << args.str() << '\n'; -- return instr - begin_instr; -+ << args.str() << '\n'; -+ } -+ if (insn_x86 != nullptr) { -+ std::string tmp = StringPrintf("%s%s%s%s%s",opcode0,opcode1,opcode2,opcode3,opcode4); -+ strcpy(insn_x86->instr_str,tmp.c_str()); -+ /*LOG(INFO) << "op str:" << insn_x86->instr_str;*/ -+ insn_x86->size = instr - begin_instr; -+ insn_x86->prefix[0] = prefix[0]; -+ insn_x86->prefix[1] = prefix[1]; -+ insn_x86->prefix[2] = prefix[2]; -+ insn_x86->prefix[3] = prefix[3]; -+ insn_x86->opcode = instr; -+ } -+ return instr - begin_instr; - } // NOLINT(readability/fn_size) - -+ - } // namespace x86 - } // namespace art -diff --git a/disassembler/disassembler_x86.h b/disassembler/disassembler_x86.h -index a329280b70..009643e052 100644 ---- a/disassembler/disassembler_x86.h -+++ b/disassembler/disassembler_x86.h -@@ -22,6 +22,15 @@ - namespace art { - namespace x86 { - -+/// Maximum size of an instruction mnemonic string. -+#define INSTR_MNEMONIC_SIZE 32 -+struct x86_instr { -+ char instr_str[INSTR_MNEMONIC_SIZE]; -+ uint16_t size; -+ uint8_t prefix[4] = {0, 0, 0, 0}; -+ const uint8_t* opcode; /* Opcode byte */ -+}; -+ - enum RegFile { GPR, MMX, SSE }; - - class DisassemblerX86 final : public Disassembler { -@@ -30,11 +39,12 @@ class DisassemblerX86 final : public Disassembler { - : Disassembler(options), supports_rex_(supports_rex) {} - - size_t Dump(std::ostream& os, const uint8_t* begin) override; -+ void GetInstructionDetails(const uint8_t* instr, x86_instr *insn); - void Dump(std::ostream& os, const uint8_t* begin, const uint8_t* end) override; - - private: - size_t DumpNops(std::ostream& os, const uint8_t* instr); -- size_t DumpInstruction(std::ostream& os, const uint8_t* instr); -+ size_t DumpInstruction(std::ostream& os, const uint8_t* instr, x86_instr *ins = nullptr); - - std::string DumpAddress(uint8_t mod, uint8_t rm, uint8_t rex64, uint8_t rex_w, bool no_ops, - bool byte_operand, bool byte_second_operand, uint8_t* prefix, bool load, -diff --git a/runtime/Android.bp b/runtime/Android.bp -index 1c4b8714e1..8e5fa67327 100644 ---- a/runtime/Android.bp -+++ b/runtime/Android.bp -@@ -398,6 +398,8 @@ libart_cc_defaults { - "arch/x86/quick_entrypoints_x86.S", - "arch/x86/thread_x86.cc", - "arch/x86/fault_handler_x86.cc", -+ "binary_analyzer/binary_analyzer_x86.cc", -+ "binary_analyzer/BinaryDisassembler.cc", - ], - avx: { - asflags: ["-DMTERP_USE_AVX"], -@@ -421,6 +423,8 @@ libart_cc_defaults { - "arch/x86_64/thread_x86_64.cc", - "monitor_pool.cc", - "arch/x86/fault_handler_x86.cc", -+ "binary_analyzer/binary_analyzer_x86.cc", -+ "binary_analyzer/BinaryDisassembler.cc", - ], - avx: { - asflags: ["-DMTERP_USE_AVX"], -@@ -517,6 +521,7 @@ libart_cc_defaults { - "libnativebridge", - "libnativeloader", - "libsigchain", -+ "libart-disassembler", - "libunwindstack", - ], - static_libs: ["libodrstatslog"], -diff --git a/runtime/art_method.cc b/runtime/art_method.cc -index b500d9b592..6688d0027c 100644 ---- a/runtime/art_method.cc -+++ b/runtime/art_method.cc -@@ -53,6 +53,7 @@ - #include "runtime_callbacks.h" - #include "scoped_thread_state_change-inl.h" - #include "vdex_file.h" -+//#include "binary_analyzer/binary_analyzer.h" - - namespace art { - -diff --git a/runtime/binary_analyzer/BinaryDisassembler.cc b/runtime/binary_analyzer/BinaryDisassembler.cc -new file mode 100644 -index 0000000000..88aa324f91 ---- /dev/null -+++ b/runtime/binary_analyzer/BinaryDisassembler.cc -@@ -0,0 +1,54 @@ -+/* -+ * Copyright (C) 2019 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 agreLOGed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#include "arch/instruction_set.h" -+#include "base/logging.h" -+#include -+#include -+#include "BinaryDisassembler.h" -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+namespace art { -+ -+BinaryDisassembler::BinaryDisassembler(InstructionSet insn_set) { -+ if (disassembler_ == nullptr) { -+ const uint8_t* base_address = nullptr; -+ const uint8_t* end_address = nullptr; -+ disassembler_ = std::unique_ptr((*create_disassembler)( -+ insn_set, -+ new DisassemblerOptions(/* absolute_addresses */ false, -+ base_address, -+ end_address, -+ /* can_read_literals */ true, -+ Is64BitInstructionSet(insn_set) -+ ? &Thread::DumpThreadOffset : -+ &Thread::DumpThreadOffset))); -+ } -+ -+} -+ -+BinaryDisassembler::~BinaryDisassembler() { -+ disassembler_.reset(); -+} -+ -+} // namespace art -diff --git a/runtime/binary_analyzer/BinaryDisassembler.h b/runtime/binary_analyzer/BinaryDisassembler.h -new file mode 100644 -index 0000000000..4e0992ffad ---- /dev/null -+++ b/runtime/binary_analyzer/BinaryDisassembler.h -@@ -0,0 +1,106 @@ -+/* -+ * Copyright (C) 2019 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef ART_RUNTIME_BINARY_ANALYZER_BINARYDISASSEMBLER_H_ -+#define ART_RUNTIME_BINARY_ANALYZER_BINARYDISASSEMBLER_H_ -+ -+#include "arch/instruction_set.h" -+#include -+#include -+#include -+ -+ -+namespace art { -+ -+ -+/** -+ * @brief The Disassembler class is a wrapper around the ART disassembly library. -+ * The Disassembler vaidates each x86 instruction and returns required fields -+ * of instruction mnemonic, instruction size , instruction prefixes & opcode. -+ */ -+class BinaryDisassembler { -+ public: -+ explicit BinaryDisassembler(InstructionSet insn_set); -+ ~BinaryDisassembler(); -+ -+ /** -+ * @brief Returns the address of the head of the stream (that is, the address of the -+ * stream that the user indicated when the last Seek operation was performed). -+ * -+ * @return Address of the head of the stream. -+ */ -+ uint64_t GetAddress() const { -+ return address_; -+ } -+ -+ /** -+ * @brief Returns a pointer corresponding to the head of the binary stream. -+ * -+ * @return Pointer to the head of the strema. -+ */ -+ const uint8_t* GetPtr() const { -+ return ptr_; -+ } -+ -+ /** -+ * @brief Checks if the Disassembler was constructed successfully. The constructor -+ * will fail if the library was not configured for the requested architecture. -+ * -+ * @return true if the Disassembler is ready for use; false otherwise. -+ */ -+ bool IsDisassemblerValid() const { -+ if (disassembler_ == nullptr) { -+ LOG(ERROR) << "Invalid Disassembler !" ; -+ return false; -+ } -+ return true; -+ } -+ -+ /** -+ * @brief Positions the iterator head at ptr and sets the user-specified address to ptr. -+ */ -+ void Seek(const uint8_t* ptr) { -+ Seek(ptr, reinterpret_cast(ptr)); -+ } -+ -+ /** -+ * @brief Positions the iterator head at ptr and sets the user-specified address. -+ */ -+ void Seek(const uint8_t* ptr, uint64_t address) { -+ ptr_ = ptr; -+ address_ = address; -+ } -+ -+ art::x86::x86_instr GetInstructionDetails(const uint8_t* instr) { -+ art::x86::x86_instr insn_x86 = {}; -+ art::x86::DisassemblerX86* disasm = static_cast(disassembler_.get()); -+ (disasm)->GetInstructionDetails(instr, &insn_x86); -+ return insn_x86; -+ } -+ -+ size_t DumpInstruction(std::ostream& os, const uint8_t* instr); -+ -+ private: -+ uint64_t address_; -+ const uint8_t* ptr_; -+ std::unique_ptr disassembler_ = nullptr; -+ private: -+ DISALLOW_COPY_AND_ASSIGN(BinaryDisassembler); -+}; -+ -+} // namespace art -+ -+#endif // ART_RUNTIME_BINARY_ANALYZER_BINARYDISASSEMBLER_H_ -diff --git a/runtime/binary_analyzer/binary_analyzer.h b/runtime/binary_analyzer/binary_analyzer.h -new file mode 100644 -index 0000000000..de7a4ba2d8 ---- /dev/null -+++ b/runtime/binary_analyzer/binary_analyzer.h -@@ -0,0 +1,67 @@ -+/* -+ * Copyright (C) 2019 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_H_ -+#define ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_H_ -+ -+#include -+ -+#include "binary_analyzer_x86.h" -+#include "dex/dex_file.h" -+#include "runtime.h" -+ -+ -+ -+namespace art { -+#if defined(__i386__) || defined(__x86_64__) -+static bool IsFastJNI(uint32_t method_idx, const DexFile& dex_file, const void* fn_ptr) { -+ bool is_fast = false; -+ InstructionSet instruction_set = Runtime::Current()->GetInstructionSet(); -+ switch (instruction_set) { -+ case InstructionSet::kX86: -+ case InstructionSet::kX86_64: { -+ x86::AnalysisResult result = x86::AnalyzeMethod(method_idx, dex_file, fn_ptr); -+ if (result == x86::AnalysisResult::kFast) { -+ is_fast = true; -+ VLOG(jni) << dex_file.PrettyMethod(method_idx) << " is a fast JNI Method"; -+ } else { -+ VLOG(jni) << dex_file.PrettyMethod(method_idx) << " is not a fast JNI Method: " -+ << x86::AnalysisResultToStr(result); -+ } -+ break; -+ } -+ case InstructionSet::kArm: -+ case InstructionSet::kArm64: -+ break; -+ default: -+ LOG(ERROR) << "Unsupported ISA!"; -+ break; -+ } -+ return is_fast; -+} -+#else -+// Todo:FastJni is currently enabled on Arm instruction set -+static bool IsFastJNI(uint32_t method_idx, const DexFile& dex_file, const void* fn_ptr) { -+ UNUSED(method_idx); -+ UNUSED(dex_file); -+ UNUSED(fn_ptr); -+ return false; -+} -+#endif -+ -+} // namespace art -+ -+#endif // ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_H_ -diff --git a/runtime/binary_analyzer/binary_analyzer_x86.cc b/runtime/binary_analyzer/binary_analyzer_x86.cc -new file mode 100644 -index 0000000000..198e187808 ---- /dev/null -+++ b/runtime/binary_analyzer/binary_analyzer_x86.cc -@@ -0,0 +1,731 @@ -+/* -+ * Copyright (C) 2019 Intel Corporation. -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#include "binary_analyzer_x86.h" -+ -+#include -+#include -+#include -+#include -+#include "android-base/stringprintf.h" -+#include "base/logging.h" -+#include "thread.h" -+ -+ -+namespace art { -+namespace x86 { -+ -+using android::base::StringPrintf; -+ -+// Budgetary constraints for classifying a native method as fast. -+static constexpr size_t kCallDepthLimit = 3; -+static constexpr size_t kBasicBlockLimit = 20; -+static constexpr size_t kInstructionLimit = 100; -+ -+enum ControlTransferType { -+ kNone, // Instructions with no control flow transfer. -+ kConditionalBranch, // Conditional branch. -+ kUnconditionalBranch, // Unconditional branch. -+ kInterrupt, // Software Interrupt. -+ kCall, // Direct call. -+ kUnknown, // Unsupported instruction. -+ kIndirectCall, // Indirect call. -+ kIndirectJump, // Indirect jump. -+ kReturn, // Return instruction. -+ kLock, // Lock prefix. -+ kCycle, // Cycling prefix/instruction. -+}; -+ -+/** -+ * @brief Analyze how instruction affects control flow (see ControlTransferType) -+ * @param instr - The instruction pointer. -+ * @param curr_bb - Pointer to the Current Basic Block. -+ * @param is_bb_end - Does the instruction mark the end of Basic Block. -+ * @param target - Adress for direct jump/call. -+ * @param disassembler - Disassembler to be used for instruction decoding. -+ * @return Size of analyzed instruction in bytes. -1 in case of error. -+ */ -+ptrdiff_t AnalyzeInstruction(const uint8_t* instr, -+ MachineBlock* curr_bb, -+ int32_t* is_bb_end, -+ const uint8_t** target, -+ BinaryDisassembler* disassemblerArt) { -+ *is_bb_end = kNone; -+ if (!disassemblerArt->IsDisassemblerValid()) { -+ return -1; -+ } -+ disassemblerArt->Seek(instr); -+ const uint8_t* begin_instr = instr; -+ x86_instr insn_x86 = disassemblerArt->GetInstructionDetails(instr); -+ *target = begin_instr + insn_x86.size; -+ -+ switch (insn_x86.prefix[0]) { -+ case 0xF3: //rep -+ case 0xF2: //repne -+ *is_bb_end = kCycle ; -+ break; -+ case 0xF0: *is_bb_end = kLock ; break; //lock -+ case 0: break; -+ } -+ -+ switch (*instr) { -+ case 0xE2: //Loop -+ case 0xE1: //Loope -+ case 0xE0: //Loopne -+ *is_bb_end = kCycle; -+ break; -+ case 0x0: -+ *is_bb_end = kUnknown; -+ break; -+ case 0xCD: //INT -+ case 0xF1: //INT1 -+ case 0xCC: //INT3 -+ *is_bb_end = kInterrupt; -+ break; -+ case 0xEB:case 0xE9:case 0xEA: //Jump -+ *is_bb_end = kIndirectJump; -+ break; -+ case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: //JCC -+ case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F: -+ case 0xE3: -+ *is_bb_end = kIndirectJump; -+ break; -+ case 0xC3: case 0xCB: case 0xC2: case 0xCA: //Return -+ *is_bb_end = kReturn; -+ break; -+ case 0xE8:case 0x9A: //Call -+ *is_bb_end = kIndirectCall; -+ break; -+ case 0xFF: -+ const uint8_t opcode_digit = (instr[1] >> 3) & 7; -+ // 'call', 'jmp' and 'push' are target specific instructions -+ if (opcode_digit == 2) { -+ *is_bb_end = kIndirectCall; -+ } -+ if (opcode_digit == 4) { -+ *is_bb_end = kIndirectJump; -+ } -+ break; -+ } -+ MachineInstruction* ir = new MachineInstruction(std::string(insn_x86.instr_str), -+ static_cast(insn_x86.size), -+ reinterpret_cast(begin_instr)); -+ MachineInstruction* prev_ir = curr_bb->GetLastInstruction(); -+ ir->SetPrevInstruction(prev_ir); -+ if (prev_ir != nullptr) { -+ prev_ir->SetNextInstruction(ir); -+ } -+ curr_bb->AddInstruction(ir); -+ return insn_x86.size; -+} -+ -+MachineBlock* CFGraph::GetCorrectBB(MachineBlock* bblock) { -+ if (bblock->IsDummy()) { -+ if (!bblock->GetPredBBlockList().empty()) { -+ return bblock->GetPredBBlockList().front(); -+ } else { -+ return nullptr; -+ } -+ } else { -+ return bblock; -+ } -+} -+ -+bool CFGraph::IsVisited(const uint8_t* addr, -+ MachineBlock* prev_bblock, -+ MachineBlock* succ_bblock, -+ std::vector* backlog, -+ const bool is_function_start) { -+ for (const auto current_bb : visited_bblock_list_) { -+ if (!current_bb->IsDummy()) { -+ const uint8_t* start = current_bb->GetStartAddr(); -+ const uint8_t* end = current_bb->GetEndAddr(); -+ // Recognize it as a cycle only if a back-branch found and it was a jmp, not call. -+ if (addr <= prev_bblock->GetEndAddr() && !is_function_start) { -+ this->SetHasCycles(); -+ } -+ -+ // In case we are branching to the beginning of an existing Basic Block, -+ // it is already visited. -+ if (addr == start) { -+ MachineBlock* bb_existing = current_bb; -+ if (prev_bblock->IsDummy()) { -+ prev_bblock->AddSuccBBlock(bb_existing); -+ bb_existing->AddPredBBlock(prev_bblock); -+ succ_bblock->AddPredBBlock(bb_existing); -+ bb_existing->AddSuccBBlock(succ_bblock); -+ } else { -+ prev_bblock->AddSuccBBlock(bb_existing); -+ bb_existing->AddPredBBlock(prev_bblock); -+ } -+ return true; -+ } -+ -+ // In case we are branching to some address in the middle of an existing Basic Block, -+ // then that Basic Block needs to be split. -+ if ((addr > start) && (addr < end)) { -+ MachineBlock* bb_to_be_split = current_bb; -+ -+ const uint8_t* prev_instr = nullptr; -+ const uint8_t* curr_instr = start; -+ -+ // Scan the bblock that is being split to identify the end instruction. -+ const auto& instructions = bb_to_be_split->GetInstructions(); -+ -+ for (auto it_instr : instructions) { -+ prev_instr = curr_instr; -+ curr_instr = reinterpret_cast(curr_instr + it_instr->GetLength()); -+ -+ // The previous instruction is the last instruction of the Basic Block being split. -+ if (curr_instr == addr) { -+ // Change the last instruction. -+ bb_to_be_split->SetEndAddr(prev_instr); -+ MachineBlock* new_bb = CreateBBlock(nullptr, nullptr); -+ const auto& succ_list = bb_to_be_split->GetSuccBBlockList(); -+ bb_to_be_split->ClearSuccBBlockList(); -+ bb_to_be_split->AddSuccBBlock(new_bb); -+ new_bb->AddPredBBlock(bb_to_be_split); -+ new_bb->CopySuccBBlockList(succ_list); -+ if (prev_bblock->IsDummy()) { -+ prev_bblock->AddSuccBBlock(new_bb); -+ new_bb->AddPredBBlock(prev_bblock); -+ succ_bblock->AddPredBBlock(new_bb); -+ new_bb->AddSuccBBlock(succ_bblock); -+ } else { -+ prev_bblock->AddSuccBBlock(new_bb); -+ new_bb->AddPredBBlock(prev_bblock); -+ } -+ AddTuple(new_bb, reinterpret_cast(addr), end); -+ new_bb->CopyInstruction(bb_to_be_split, addr); -+ ChangePredForBacklog(bb_to_be_split, new_bb, backlog); -+ ChangePredecessors(succ_list, bb_to_be_split, new_bb); -+ if (prev_bblock == bb_to_be_split) { -+ new_bb->AddPredBBlock(new_bb); -+ new_bb->AddSuccBBlock(new_bb); -+ } -+ return true; -+ } else if (curr_instr > addr) { -+ return false; -+ } -+ } -+ } -+ } -+ } -+ // Else, we have not visited this earlier. -+ return false; -+} -+ -+void CFGraph::ChangePredecessors(const std::vector& bblock_list, -+ MachineBlock* bblock_to_be_deleted, -+ MachineBlock* bblock_to_be_added) { -+ for (const auto it : bblock_list) { -+ it->DeletePredBBlock(bblock_to_be_deleted); -+ it->AddPredBBlock(bblock_to_be_added); -+ } -+} -+ -+void CFGraph::ChangePredForBacklog(MachineBlock* old_pred, -+ MachineBlock* new_pred, -+ std::vector* backlog) { -+ for (const auto bb : *backlog) { -+ if (bb->pred_bb->GetId() == old_pred->GetId()) { -+ bb->pred_bb = new_pred; -+ return; -+ } -+ } -+} -+ -+void MachineBlock::CopyInstruction(MachineBlock* from_bblock, const uint8_t* start) { -+ const uint8_t* ptr = from_bblock->GetStartAddr(); -+ std::list::iterator it_bb = from_bblock->instrs_.begin(); -+ while (it_bb != from_bblock->instrs_.end()) { -+ if (ptr >= start) { -+ AddInstruction((*it_bb)); -+ ptr += (*it_bb)->GetLength(); -+ from_bblock->DeleteInstruction(it_bb++); -+ } else { -+ ptr += (*it_bb)->GetLength(); -+ it_bb++; -+ } -+ } -+} -+ -+void MachineBlock::DeleteInstruction(std::list::iterator it) { -+ instrs_.erase(it); -+ --num_of_instrs_; -+} -+ -+bool CFGraph::IsVisitedForBacklog(BackLogDs* entry, std::vector* backlog) { -+ if (entry != nullptr) { -+ MachineBlock* prev_bb = entry->pred_bb; -+ const uint8_t* addr = entry->ptr; -+ const bool is_function_start = entry->is_function_start; -+ -+ if (prev_bb != nullptr) { -+ return IsVisited(addr, prev_bb, entry->succ_bb, backlog, is_function_start); -+ } -+ } -+ return false; -+} -+ -+MachineBlock* GetTailBB(MachineBlock* bblock) { -+ MachineBlock* first_succ_bb = bblock->GetSuccBBlockList().front(); -+ if (first_succ_bb == nullptr) { -+ return bblock; -+ } else { -+ return first_succ_bb; -+ } -+} -+ -+/** -+ * @brief The Helper function to build CFG for the given method. -+ * @param cfg - The CFG. -+ * @param ptr - Instruction Pointer. -+ * @param curr_bb - Current Basic Block. -+ * @param backlog - Backlog array. -+ * @param depth - Call depth/levels of call nesting. -+ * @param dummy_end - Dummy basic block. -+ * @param disasm - Disassembler to be used for instructions decoding. -+ */ -+void CFGHelper(CFGraph* cfg, -+ const uint8_t* instr_ptr, -+ MachineBlock* curr_bblock, -+ std::vector* backlog, -+ uint32_t depth, -+ MachineBlock* dummy_end, -+ BinaryDisassembler* disasmArt, -+ CallGraph* call_graph) { -+ ptrdiff_t len = 0; -+ int32_t is_bb_end = kNone; -+ const uint8_t* target = nullptr; -+ const uint8_t* ptr = reinterpret_cast(instr_ptr); -+ const uint8_t* start_ptr = reinterpret_cast(ptr); -+ while ((len = AnalyzeInstruction(ptr, curr_bblock, &is_bb_end, &target, disasmArt)) > 0) { -+ switch (is_bb_end) { -+ case kUnconditionalBranch: { -+ // Push the jmp target to backlog. -+ BackLogDs* uncond_jmp = new BackLogDs(); -+ uncond_jmp->function_start = curr_bblock->GetFunctionStartAddr(); -+ uncond_jmp->pred_bb = curr_bblock; -+ if (depth > 0) { -+ uncond_jmp->succ_bb = dummy_end; -+ } else { -+ uncond_jmp->succ_bb = nullptr; -+ } -+ uncond_jmp->ptr = target; -+ uncond_jmp->is_function_start = false; -+ uncond_jmp->call_depth = 0; -+ backlog->push_back(uncond_jmp); -+ // Add the current BB to CFG. -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kConditionalBranch: { -+ // Push the conditional (if) jmp target to backlog. -+ BackLogDs* cond_if_jmp = new BackLogDs(); -+ cond_if_jmp->pred_bb = curr_bblock; -+ cond_if_jmp->function_start = curr_bblock->GetFunctionStartAddr(); -+ if (depth > 0) { -+ cond_if_jmp->succ_bb = dummy_end; -+ } else { -+ cond_if_jmp->succ_bb = nullptr; -+ } -+ cond_if_jmp->ptr = target; -+ cond_if_jmp->call_depth = 0; -+ cond_if_jmp->is_function_start = false; -+ backlog->push_back(cond_if_jmp); -+ // Push the else (subsequent instruction) to the backlog. -+ BackLogDs* cond_else_jmp = new BackLogDs(); -+ cond_else_jmp->is_function_start = false; -+ cond_else_jmp->pred_bb = curr_bblock; -+ cond_else_jmp->function_start = curr_bblock->GetFunctionStartAddr(); -+ if (depth > 0) { -+ cond_else_jmp->succ_bb = dummy_end; -+ } else { -+ cond_else_jmp->succ_bb = nullptr; -+ } -+ cond_else_jmp->ptr = reinterpret_cast(ptr + len); -+ cond_else_jmp->call_depth = 0; -+ backlog->push_back(cond_else_jmp); -+ // Add the current Basic Block to the CFG. -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kCall: { -+ // Add the current Basic Block to the CFG. -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ MachineBlock* start_bb = cfg->CreateBBlock(curr_bblock, curr_bblock->GetFunctionStartAddr()); -+ MachineBlock* end_bb = cfg->CreateBBlock(nullptr, curr_bblock->GetFunctionStartAddr()); -+ start_bb->SetDummy(); -+ end_bb->SetDummy(); -+ BackLogDs* call_entry = new BackLogDs(); -+ call_entry->pred_bb = start_bb; -+ call_entry->ptr = target; -+ call_entry->function_start = target; -+ call_entry->succ_bb = end_bb; -+ call_entry->is_function_start = true; -+ call_entry->call_depth = depth + 1; -+ if (call_entry->call_depth > cfg->GetCallDepth()) { -+ cfg->SetCallDepth(call_entry->call_depth); -+ } -+ backlog->push_back(call_entry); -+ MachineBlock* bb_after_call = cfg->CreateBBlock(end_bb, curr_bblock->GetFunctionStartAddr()); -+ curr_bblock = bb_after_call; -+ is_bb_end = kNone; -+ start_ptr = ptr + len; -+ cfg->AddTuple(start_bb, nullptr, nullptr); -+ cfg->AddTuple(end_bb, nullptr, nullptr); -+ -+ call_graph->AddCall(curr_bblock->GetFunctionStartAddr(), target); -+ break; -+ } -+ case kReturn: { -+ if (dummy_end != nullptr) { -+ dummy_end->AddPredBBlock(curr_bblock); -+ curr_bblock->AddSuccBBlock(dummy_end); -+ } -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kInterrupt: { -+ cfg->SetHasInterrupts(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kIndirectCall: { -+ cfg->SetHasIndirectCalls(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kIndirectJump: { -+ cfg->SetHasIndirectJumps(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kUnknown: { -+ cfg->SetHasUnknownInstructions(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kLock: { -+ cfg->SetHasLocks(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ case kCycle: { -+ cfg->SetHasCycles(); -+ cfg->AddTuple(curr_bblock, start_ptr, reinterpret_cast(ptr)); -+ break; -+ } -+ } -+ -+ ptr += len; -+ if (is_bb_end != kNone && is_bb_end != kCall) { -+ break; -+ } -+ } -+} -+ -+/** -+ * @brief Constructs the CFG for the method by binary analysis. -+ * @param ptr - the method function pointer. -+ * @param method_name - Pretty Name of method. -+ * @return the CFG for the analyzed method. -+ */ -+AnalysisResult AnalyzeCFG(const uint8_t* ptr, const std::string& method_name) { -+ CFGraph cfg(method_name); -+ -+ auto call_graph = CallGraph::CreateNew(); -+ BinaryDisassembler disassemblerArt(Runtime::Current()->GetInstructionSet()); -+ MachineBlock* predecessor_bb = nullptr; -+ MachineBlock* start_bb = cfg.CreateBBlock(predecessor_bb, nullptr); -+ MachineBlock* curr_bb = start_bb; -+ cfg.AddStartBBlock(start_bb); -+ MachineBlock* dummy_end = nullptr; -+ uint32_t depth = 0; -+ std::vector backlog; -+ CFGHelper(&cfg, ptr, curr_bb, &backlog, depth, dummy_end, &disassemblerArt,call_graph.get()); -+ -+ if (!cfg.IsStillFast()) { -+ for (auto& e : backlog) { -+ delete e; -+ } -+ return cfg.GetAnalysisState(); -+ } -+ -+ do { -+ BackLogDs* entry = nullptr; -+ if (!backlog.empty()) { -+ entry = backlog.back(); -+ backlog.pop_back(); -+ if (!cfg.IsVisitedForBacklog(entry, &backlog)) { -+ ptr = entry->ptr; -+ predecessor_bb = entry->pred_bb; -+ curr_bb = cfg.CreateBBlock(predecessor_bb, entry->function_start); -+ dummy_end = entry->succ_bb; -+ depth = entry->call_depth; -+ CFGHelper(&cfg, ptr, curr_bb, &backlog, depth, dummy_end, &disassemblerArt, call_graph.get()); -+ } -+ } -+ delete entry; -+ if (!cfg.IsStillFast()) { -+ for (auto& e : backlog) { -+ delete e; -+ } -+ return cfg.GetAnalysisState(); -+ } -+ } while ((!backlog.empty())); -+ if (CallGraph::HasCycles(std::move(call_graph))) { -+ return AnalysisResult::kHasCycles; -+ } -+ -+ return cfg.GetAnalysisState(); -+} -+ -+bool CFGraph::IsStillFast() const { -+ return state_ == AnalysisResult::kFast; -+} -+ -+void MachineInstruction::Print(std::ostream& os, bool is_dot) { -+ os << Print(is_dot).str(); -+} -+ -+void ReplaceString(std::string& subject, -+ const std::string& search, -+ const std::string& replace) { -+ size_t pos = 0; -+ while ((pos = subject.find(search, pos)) != std::string::npos) { -+ subject.replace(pos, search.length(), replace); -+ pos += replace.length(); -+ } -+} -+ -+std::ostringstream MachineInstruction::Print(bool is_dot) { -+ std::ostringstream os; -+ if (is_dot) { -+ ReplaceString(instr_, "0x", ""); -+ os << instr_ << "\\l"; -+ } else { -+ os << "\t\t" << instr_ << std::endl; -+ } -+ return os; -+} -+ -+void MachineBlock::Print(std::ostream& os, bool is_dot) { -+ os << Print(is_dot).str(); -+} -+ -+std::ostringstream MachineBlock::Print(bool is_dot) { -+ std::ostringstream os; -+ if (is_dot) { -+ std::string label = StringPrintf("BB#%d\\n", id_); -+ if (!is_dummy_) { -+ std::ostringstream o_instr; -+ for (auto it : instrs_) { -+ it->Print(o_instr, true); -+ } -+ label = label + o_instr.str(); -+ } else { -+ label = label + " (Dummy)"; -+ } -+ os << StringPrintf("\nB_%d [shape=rectangle, label=\"%s\"];", id_, label.c_str()); -+ for (MachineBlock* bb : succ_bblock_) { -+ os << StringPrintf("\nB_%d -> B_%d;", id_, bb->GetId()); -+ } -+ } else { -+ os << " Basic Block Id : " << id_ -+ << "\n Call entry: 0x" << std::hex << size_t(function_start_addr_) -+ << "\n BB -No. of instructions " << GetInstrCnt() -+ << "\n List of predecessor BBs : "; -+ for (auto it : pred_bblock_) { -+ os << it->GetId() << " "; -+ } -+ os << "\n List of successor BBs : "; -+ for (auto it : succ_bblock_) { -+ os << it->GetId() << " "; -+ } -+ if (!is_dummy_) { -+ os << "\n Instructions begin at : " << StringPrintf("%p", start_addr_) << "\n"; -+ for (auto it : instrs_) { -+ it->Print(os, false); -+ } -+ os << " Instructions end at : " << StringPrintf("%p", end_addr_) << "\n"; -+ } else { -+ os << "\n Dummy BB \n"; -+ } -+ } -+ return os; -+} -+ -+void CFGraph::Print(std::ostringstream& os, bool is_dot) const { -+ if (is_dot) { -+ std::string method_name = GetMethodName(); -+ ReplaceString(method_name, ".", "_"); -+ ReplaceString(method_name, " ", "_"); -+ ReplaceString(method_name, ",", "_"); -+ ReplaceString(method_name, ")", "_"); -+ ReplaceString(method_name, "(", "_"); -+ os << "\ndigraph G_" << method_name <<" {"; -+ } else { -+ os << "--- CFG begins ---\nCFG -No. of instructions " << GetInstructionCnt(); -+ } -+ for (auto bb : visited_bblock_list_) { -+ bb->Print(os, is_dot); -+ } -+ if (is_dot) { -+ os << std::endl << "}"; -+ } else { -+ os << "--- CFG ends ---\n"; -+ } -+} -+ -+MachineBlock::~MachineBlock() { -+ for (auto it : instrs_) { -+ delete it; -+ } -+} -+ -+AnalysisResult AnalyzeMethod(uint32_t method_idx, const DexFile& dex_file, const void* fn_ptr) { -+ return AnalyzeCFG((unsigned char*) fn_ptr, dex_file.PrettyMethod(method_idx)); -+} -+ -+void MachineBlock::AddPredBBlock(MachineBlock* bblock) { -+ auto it = std::find(pred_bblock_.begin(), pred_bblock_.end(), bblock); -+ if (it == pred_bblock_.end()) { -+ pred_bblock_.push_back(bblock); -+ } -+ if (function_start_addr_ == nullptr && bblock != nullptr) { -+ function_start_addr_ = bblock->GetFunctionStartAddr(); -+ } -+} -+ -+void MachineBlock::AddSuccBBlock(MachineBlock* bblock) { -+ auto it = std::find(succ_bblock_.begin(), succ_bblock_.end(), bblock); -+ if (it == succ_bblock_.end()) { -+ succ_bblock_.push_back(bblock); -+ } -+} -+ -+void MachineBlock::DeletePredBBlock(MachineBlock* bblock) { -+ for (auto it = pred_bblock_.begin(); -+ it != pred_bblock_.end();) { -+ if ((*it) == bblock) { -+ it = pred_bblock_.erase(it); -+ } else { -+ it++; -+ } -+ } -+} -+ -+void MachineBlock::CopyPredBBlockList(const std::vector& to_copy) { -+ for (auto it : to_copy) { -+ pred_bblock_.push_back(it); -+ } -+} -+ -+void MachineBlock::CopySuccBBlockList(const std::vector& to_copy) { -+ for (auto it : to_copy) { -+ succ_bblock_.push_back(it); -+ } -+} -+ -+void CFGraph::SetCallDepth(uint32_t depth) { -+ call_depth_ = depth; -+ if (call_depth_ >= kCallDepthLimit) { -+ state_ = AnalysisResult::kCallDepthLimitExceeded; -+ } -+} -+ -+void CFGraph::IncBBlockCnt() { -+ ++num_of_bblocks_; -+ if (num_of_bblocks_ > kBasicBlockLimit) { -+ state_ = AnalysisResult::kBasicBlockLimitExceeded; -+ } -+} -+ -+void CFGraph::IncreaseInstructionCnt(uint32_t amount) { -+ num_of_instrs_ += amount; -+ if (num_of_instrs_ > kInstructionLimit) { -+ state_ = AnalysisResult::kInstructionLimitExceeded; -+ } -+} -+ -+MachineBlock* CFGraph::CreateBBlock(MachineBlock* predecessor_bb, const uint8_t* function_start) { -+ MachineBlock* new_bb = new MachineBlock(predecessor_bb, function_start); -+ new_bb->SetId(GetBBlockCnt()); -+ new_bb->SetStartAddr(nullptr); -+ new_bb->SetEndAddr(nullptr); -+ IncBBlockCnt(); -+ cfg_bblock_list_.push_back(new_bb); -+ return new_bb; -+} -+ -+void CFGraph::AddTuple(MachineBlock* bblock, const uint8_t* start, const uint8_t* end) { -+ bblock->SetStartAddr(start); -+ bblock->SetEndAddr(end); -+ visited_bblock_list_.push_back(bblock); -+ IncreaseInstructionCnt(bblock->GetInstrCnt()); -+} -+ -+bool CallGraph::HasCycles(std::unique_ptr graph) { -+ if (graph->root == nullptr) { -+ return false; -+ } -+ return graph->SubgraphCheckCycles(graph->root); -+} -+ -+void CallGraph::AddCall(const uint8_t* caller, const uint8_t* callee) { -+ auto caller_entry = GetOrAddCallEntry(caller); -+ auto callee_entry = GetOrAddCallEntry(callee); -+ if (root == nullptr) { -+ root = caller_entry; -+ } -+ caller_entry->AddCallee(callee_entry); -+} -+ -+bool CallGraph::SubgraphCheckCycles(CallEntry* node) { -+ // The classic algorithm for checking a directed graph for the presence of cycles in it. -+ if (node->state == NodeState::kAlreadyChecked) { -+ return false; -+ } -+ if (node->state == NodeState::kInCurrentPath) { -+ return true; -+ } -+ -+ node->state = NodeState::kInCurrentPath; -+ for (auto& child : node->callees) { -+ if (SubgraphCheckCycles(child)) { -+ return true; -+ } -+ } -+ -+ node->state = NodeState::kAlreadyChecked; -+ return false; -+} -+ -+CallGraph::CallEntry* CallGraph::GetOrAddCallEntry(const uint8_t* entry_start_address) { -+ auto it = entries.find(entry_start_address); -+ if (it != entries.end()) { -+ return it->second.get(); -+ } -+ auto new_entry = std::unique_ptr(new CallEntry(entry_start_address)); -+ auto new_entry_ptr = new_entry.get(); -+ entries[entry_start_address] = std::move(new_entry); -+ return new_entry_ptr; -+} -+ -+} // namespace x86 -+} // namespace art -diff --git a/runtime/binary_analyzer/binary_analyzer_x86.h b/runtime/binary_analyzer/binary_analyzer_x86.h -new file mode 100644 -index 0000000000..1553f6d843 ---- /dev/null -+++ b/runtime/binary_analyzer/binary_analyzer_x86.h -@@ -0,0 +1,700 @@ -+/* -+ * Copyright (C) 2019 The Android Open Source Project -+ * -+ * Licensed under the Apache License, Version 2.0 (the "License"); -+ * you may not use this file except in compliance with the License. -+ * You may obtain a copy of the License at -+ * -+ * http://www.apache.org/licenses/LICENSE-2.0 -+ * -+ * Unless required by applicable law or agreed to in writing, software -+ * distributed under the License is distributed on an "AS IS" BASIS, -+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -+ * See the License for the specific language governing permissions and -+ * limitations under the License. -+ */ -+ -+#ifndef ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_X86_H_ -+#define ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_X86_H_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "art_field-inl.h" -+#include "art_method-inl.h" -+ -+#include "base/logging.h" -+#include "BinaryDisassembler.h" -+#include "mirror/class-inl.h" -+#include "mirror/class_loader.h" -+#include "mirror/object-inl.h" -+#include "mirror/object_array-inl.h" -+#include "mirror/string-inl.h" -+#include "mirror/throwable.h" -+/*#include "utils/assembler.h"*/ -+ -+namespace art { -+namespace x86 { -+ -+/** -+ * @brief The instruction class stores information about -+ * the decoded/analyzed binary instruction. -+ */ -+class MachineInstruction { -+ public: -+ MachineInstruction(std::string instruction_str, uint8_t length, const uint8_t* ptr) -+ : instr_(instruction_str), instr_ptr_(ptr), length_(length) { -+ } -+ -+ ~MachineInstruction() {} -+ -+ /** -+ * @brief prints the decoded x86 instruction in human readable/dot format to logcat. -+ * @param output - output stream. -+ * @param is_dot - whether the output must be in dot format. -+ */ -+ void Print(std::ostream& output, bool is_dot); -+ -+ /** -+ * @brief prints the decoded x86 instruction in human readable/dot format. -+ * @param is_dot - whether the output must be in dot format. -+ * @return the output stream. -+ */ -+ std::ostringstream Print(bool is_dot); -+ -+ /** -+ * @brief returns the human readable x86 instruction. -+ * @return the decoded x86 instruction. -+ */ -+ const std::string& GetInstruction() const { -+ return instr_; -+ } -+ -+ /** -+ * @brief Get the number of bytes of assembly instruction. -+ * @return the number of bytes the instruction consumes. -+ */ -+ uint8_t GetLength() const { -+ return length_; -+ } -+ -+ /** -+ * @brief Get the pointer to the instruction. -+ * @return the byte pointer to the x86 assembly code. -+ */ -+ const uint8_t* GetInstructionPtr() const { -+ return instr_ptr_; -+ } -+ -+ /** -+ * @brief Get the previous Instruction pointer. -+ * @return the previous instruction's pointer. -+ */ -+ const MachineInstruction* GetPrevInstruction() { -+ return prev_instr_; -+ } -+ -+ /** -+ * @brief Get the next Instruction pointer. -+ * @return the next instruction's pointer. -+ */ -+ MachineInstruction* GetNextInstruction() { -+ return next_instr_; -+ } -+ -+ /** -+ * @brief Set the previous instruction pointer for the current Instruction. -+ * @param prev the previous instruction pointer. -+ */ -+ void SetPrevInstruction(MachineInstruction* prev) { -+ prev_instr_ = prev; -+ } -+ -+ /** -+ * @brief Set the next instruction pointer for the current Instruction. -+ * @param next the next instruction pointer. -+ */ -+ void SetNextInstruction(MachineInstruction* next) { -+ next_instr_ = next; -+ } -+ -+ private: -+ std::string instr_; -+ const uint8_t* instr_ptr_; -+ uint8_t length_; -+ MachineInstruction* prev_instr_; -+ MachineInstruction* next_instr_; -+}; -+ -+/** -+ * @brief BBlock class contains information about a Basic Block. -+ * Note : A dummy basic block is the one that connects a basic block -+ * that ends with a call instruction to the starting of the call site -+ * Basic Block. A dummy basic block does not contain any instructions. -+ * It merely serves as a link. -+ */ -+class MachineBlock { -+ public: -+ explicit MachineBlock(MachineBlock* pred_bb, const uint8_t* function_start_addr) -+ : num_of_instrs_(0), -+ is_dummy_(false) { -+ function_start_addr_ = function_start_addr; -+ if (pred_bb != nullptr) { -+ AddPredBBlock(pred_bb); -+ pred_bb->AddSuccBBlock(this); -+ } -+ id_ = -1; -+ start_addr_ = nullptr; -+ end_addr_ = nullptr; -+ } -+ -+ ~MachineBlock(); -+ -+ /** -+ * @brief Get the last Instruction class pointer for the Basic Block. -+ * @return the pointer to the last Instruction of the Basic Block. -+ */ -+ MachineInstruction* GetLastInstruction() const { -+ if (!instrs_.empty()) { -+ return instrs_.back(); -+ } -+ return nullptr; -+ } -+ -+ /** -+ * @brief Set the starting address of the Basic Block. -+ * @param start - Starting address of the Basic Block. -+ */ -+ void SetStartAddr(const uint8_t* start) { -+ start_addr_ = start; -+ if (function_start_addr_ == nullptr) { -+ function_start_addr_ = start; // Probably we are the first in CFG. -+ } -+ } -+ -+ /** -+ * @brief Get the starting address of the Basic Block. -+ * @return Starting address of the Basic Block. -+ */ -+ const uint8_t* GetStartAddr() const { -+ return start_addr_; -+ } -+ -+ /** -+ * @brief Set the ending address of the Basic Block. -+ * @param end - Ending address of the Basic Block. -+ */ -+ void SetEndAddr(const uint8_t* end) { -+ end_addr_ = end; -+ } -+ -+ /** -+ * @brief Get the ending address of the Basic Block. -+ * @return Ending address of the Basic Block. -+ */ -+ const uint8_t* GetEndAddr() const { -+ return end_addr_; -+ } -+ -+ /** -+ * @param start - address of the first instruction of the function which this Basic Block belongs. -+ * @brief Set start of the function which this Basic Block belongs. -+ */ -+ void SetFunctionStartAddr(const uint8_t* start) { -+ function_start_addr_ = start; -+ } -+ -+ /* -+ * @brief Get start of the function which this Basic Block belongs. -+ * @return Address of the first instruction of this function. -+ */ -+ const uint8_t* GetFunctionStartAddr() const { -+ return function_start_addr_; -+ } -+ -+ /** -+ * @brief Set this Basic Block as Dummy. -+ */ -+ void SetDummy() { -+ is_dummy_ = true; -+ } -+ -+ /** -+ * @brief Is this Basic Block a dummy. -+ * @return whether the basic block is a dummy or not. -+ */ -+ bool IsDummy() const { -+ return is_dummy_; -+ } -+ -+ /** -+ * @brief Get the number of Instructions. -+ * @return number of Instructions in the Basic Block. -+ */ -+ uint32_t GetInstrCnt() const { -+ return num_of_instrs_; -+ } -+ -+ /** -+ * @brief Get The Id of this Basic Block. -+ * @return the Basic Block's id. -+ */ -+ uint32_t GetId() const { -+ return id_; -+ } -+ -+ /** -+ * @brief Set the Basic Block's Id. -+ * @param - the Id for the Basic Block. -+ */ -+ void SetId(uint32_t id) { -+ id_ = id; -+ } -+ -+ /** -+ * @brief Add the Instruction to the Basic Block. -+ * @param instruction - The instruction to be added to the Basic Block. -+ */ -+ void AddInstruction(MachineInstruction* instruction) { -+ instrs_.push_back(instruction); -+ ++num_of_instrs_; -+ } -+ -+ /** -+ * @brief Add a Basic Block to list of predecessor Basic Blocks. -+ * @param bblock - the predecessor Basic Block. -+ */ -+ void AddPredBBlock(MachineBlock* bblock); -+ -+ /** -+ * @brief Add a Basic Block to list of successor Basic Blocks. -+ * @param bblock - the successor Basic Block. -+ */ -+ void AddSuccBBlock(MachineBlock* bblock); -+ -+ /** -+ * @brief Delete a certain Basic Block from the list of predecessor Basic Blocks. -+ * @param bblock - the Basic Block to be deleted. -+ */ -+ void DeletePredBBlock(MachineBlock* bblock); -+ -+ /** -+ * Get the list of predecessor Basic Blocks. -+ * @return the predecessor Basic Block List. -+ */ -+ const std::vector& GetPredBBlockList() const { -+ return pred_bblock_; -+ } -+ -+ /** -+ * Get the list of successor Basic Blocks. -+ * @return the successor Basic Block List. -+ */ -+ const std::vector& GetSuccBBlockList() const { -+ return succ_bblock_; -+ } -+ -+ /** -+ * @brief Make a copy of the array of predecessor Basic Blocks. -+ * @param to_copy - The vector that contain predecessor Basic Blocks to be copied. -+ */ -+ void CopyPredBBlockList(const std::vector& to_copy); -+ -+ /** -+ * @brief Make a copy of the array of successor Basic Blocks. -+ * @param to_copy - The vector that contain successor Basic Blocks to be copied. -+ */ -+ void CopySuccBBlockList(const std::vector& to_copy); -+ -+ /** -+ * @brief Clear the array of predecessor Basic Blocks. -+ */ -+ void ClearPredBBlockList() { -+ pred_bblock_.clear(); -+ } -+ -+ /** -+ * @brief Clear the array of successor Basic Blocks. -+ */ -+ void ClearSuccBBlockList() { -+ succ_bblock_.clear(); -+ } -+ -+ /** -+ * @brief Get the Instruction Class Pointer List for the Basic Block. -+ * @return The Instruction class pointer list. -+ */ -+ const std::list& GetInstructions() const { -+ return instrs_; -+ } -+ -+ /** -+ * @brief prints the info on Basic Block in human readable/dot format to logcat. -+ * @param output - output stream. -+ * @param is_dot - whether the output must be in dot format. -+ */ -+ void Print(std::ostream& output, bool is_dot); -+ -+ /** -+ * @brief prints the info on Basic Block in human readable/dot format. -+ * @param is_dot - whether the output must be in dot format. -+ * @return the output stream. -+ */ -+ std::ostringstream Print(bool is_dot); -+ -+ /** -+ * @brief Copies the Instructions Starting from a certain Address to the Basic Block. -+ * @param from_bblock - the Basic Block from which Instructions have to be copied. -+ * @param start - The starting pointer to the Instruction Class. -+ */ -+ void CopyInstruction(MachineBlock* from_bblock, const uint8_t* start); -+ -+ /** -+ * @brief Deletes a certain Instruction from the Basic Block. -+ * @param it - iterator for the Instruction List. -+ */ -+ void DeleteInstruction(std::list::iterator it); -+ -+ private: -+ uint32_t id_; -+ const uint8_t* function_start_addr_; -+ const uint8_t* start_addr_; -+ const uint8_t* end_addr_; -+ uint32_t num_of_instrs_; -+ std::vector pred_bblock_; -+ std::vector succ_bblock_; -+ std::list instrs_; -+ bool is_dummy_; -+}; -+ -+/** -+ * The BackLogDs Data Structure stores the code paths that have not yet been -+ * analyzed. This could be due to call, jump (conditional/unconditional) etc. -+ */ -+struct BackLogDs { -+ MachineBlock* pred_bb; -+ const uint8_t* ptr; -+ MachineBlock* succ_bb; -+ const uint8_t* function_start; -+ bool is_function_start; -+ uint32_t call_depth; -+}; -+ -+/** -+ * Call graph used to detect recursion since we disabled detection of cycles -+ * on CFG level (it was replaced with heuristic which cannot detect recursion). -+ */ -+class CallGraph { -+ struct CallEntry; -+ public: -+ CallGraph(CallGraph&& other) = default; -+ CallGraph& operator=(CallGraph&& other) = default; -+ -+ static std::unique_ptr CreateNew() { -+ return std::unique_ptr(new CallGraph); -+ } -+ -+ static bool HasCycles(std::unique_ptr graph); -+ -+ void AddCall(const uint8_t* caller, const uint8_t* callee); -+ -+ private: -+ enum class NodeState { -+ kNotVisited, // Not visited node. -+ kInCurrentPath, // Already visited during current sub-path. -+ kAlreadyChecked, // Node from checked subgraph. -+ }; -+ -+ struct CallEntry { -+ explicit CallEntry(const uint8_t* call_entry_address) -+ : call_entry_addr(call_entry_address) {} -+ -+ void AddCallee(CallEntry* callee) { -+ callees.insert(callee); -+ } -+ -+ const uint8_t* const call_entry_addr; -+ std::unordered_set callees; -+ NodeState state = NodeState::kNotVisited; -+ }; -+ -+ CallGraph() = default; -+ -+ bool SubgraphCheckCycles(CallEntry* node); -+ CallEntry* GetOrAddCallEntry(const uint8_t* entry_start_address); -+ -+ CallEntry* root = nullptr; -+ std::unordered_map> entries; -+ DISALLOW_COPY_AND_ASSIGN(CallGraph); -+}; -+ -+enum class AnalysisResult { -+ kFast, -+ kHasLocks, -+ kHasCycles, -+ kHasInterrupts, -+ kHasIndirectCalls, -+ kHasIndirectJumps, -+ kHasUnknownInstructions, -+ kCallDepthLimitExceeded, -+ kBasicBlockLimitExceeded, -+ kInstructionLimitExceeded, -+}; -+ -+inline const char* AnalysisResultToStr(AnalysisResult res) { -+ switch (res) { -+ case AnalysisResult::kFast: -+ return "fast"; -+ case AnalysisResult::kHasLocks: -+ return "has locks"; -+ case AnalysisResult::kHasCycles: -+ return "has cycles"; -+ case AnalysisResult::kHasInterrupts: -+ return "has interrupts"; -+ case AnalysisResult::kHasIndirectCalls: -+ return "has indirect calls"; -+ case AnalysisResult::kHasIndirectJumps: -+ return "has indirect jumps"; -+ case AnalysisResult::kHasUnknownInstructions: -+ return "has unknown instructions"; -+ case AnalysisResult::kCallDepthLimitExceeded: -+ return "exceeds call depth limit"; -+ case AnalysisResult::kBasicBlockLimitExceeded: -+ return "exceeds basic block limit"; -+ case AnalysisResult::kInstructionLimitExceeded: -+ return "exceeds instruction limit"; -+ default: -+ LOG(ERROR) << "Unknown auto fast JNI analysis result!"; -+ return ""; -+ } -+} -+ -+/** -+ * CFGraph Class has information about the Control Flow Graph. -+ */ -+class CFGraph { -+ public: -+ explicit CFGraph(std::string method_name) -+ : method_name_(method_name) {} -+ -+ ~CFGraph() { -+ for (auto it : cfg_bblock_list_) { -+ delete it; -+ } -+ } -+ -+ /** -+ * @brief Delete a certain Basic Block & Add a certain Basic Block from & to a -+ * list of Basic Blocks respectively. -+ * @param bblock_list - the list from which a Basic Block has to deleted & -+ * to which a Basic Block has to be added. -+ * @param bblock_to_be_deleted - the Basic Block to be deleted. -+ * @param bblock_to_be_added - the Basic Block to de added. -+ */ -+ void ChangePredecessors(const std::vector &bblock_list, -+ MachineBlock* bblock_to_be_deleted, -+ MachineBlock* bblock_to_be_added); -+ -+ /** -+ * In case a Basic Block is a dummy, returns it's predecessor. -+ * @param bblock - the Basic Block which is being tested. -+ * @return bblock itself if not dummy; else returns it's predecessor. -+ */ -+ MachineBlock* GetCorrectBB(MachineBlock* bblock); -+ -+ /** -+ * @brief Get the name of the method being analyzed. -+ * @return the method's PrettyName. -+ */ -+ const std::string& GetMethodName() const { -+ return method_name_; -+ } -+ -+ void SetHasUnknownInstructions() { -+ state_ = AnalysisResult::kHasUnknownInstructions; -+ } -+ -+ void SetHasCycles() { -+ state_ = AnalysisResult::kHasCycles; -+ } -+ -+ void SetHasLocks() { -+ state_ = AnalysisResult::kHasLocks; -+ } -+ -+ void SetHasIndirectJumps() { -+ state_ = AnalysisResult::kHasIndirectJumps; -+ } -+ -+ void SetHasInterrupts() { -+ state_ = AnalysisResult::kHasInterrupts; -+ } -+ -+ void SetHasIndirectCalls() { -+ state_ = AnalysisResult::kHasIndirectCalls; -+ } -+ -+ /** -+ * @brief Get the levels of call nesting. -+ * @return the levels of call nesting. -+ */ -+ uint32_t GetCallDepth() const { -+ return call_depth_; -+ } -+ -+ /** -+ * @brief Sets the call nesting level (and checks if we are still in budget) -+ * @param depth - the level of call nesting. -+ */ -+ void SetCallDepth(uint32_t depth); -+ -+ /** -+ * @brief Get the Number of Instructions in the CFG. -+ * @return the number of Instructions. -+ */ -+ uint32_t GetInstructionCnt() const { -+ return num_of_instrs_; -+ } -+ -+ /** -+ * @brief Increase instruction count by the given amount (and check if we are still in budget). -+ * @param amount - amount of added instructions. -+ */ -+ void IncreaseInstructionCnt(uint32_t amount); -+ -+ /** -+ * @brief Get the Number of Basic Blocks in the CFG. -+ * @return the number of Basic Blocks. -+ */ -+ uint32_t GetBBlockCnt() const { -+ return num_of_bblocks_; -+ } -+ -+ /** -+ * @brief Increment basic block count (and check if we are still in budget) -+ */ -+ void IncBBlockCnt(); -+ -+ /** -+ * @brief Add a Basic Block as the Starting Basic Block for CFG. -+ * @param start_bblock - the starting Basic Block. -+ */ -+ void AddStartBBlock(MachineBlock* start_bblock) { -+ start_bblock_ = start_bblock; -+ } -+ -+ /** -+ * @brief Creates a Basic Block in the CFG & updates the predecessor. -+ * @param predecessor_bblock - Predecessor Basic Block. -+ * @return the created Basic Block. -+ */ -+ MachineBlock* CreateBBlock(MachineBlock* predecessor_bblock, const uint8_t* function_start); -+ -+ /** -+ * @brief Update the Predecessors & successors caused by backlog due -+ * to calls/jumps in the CFG. -+ * @param old_pred - The old predecessor to be updated. -+ * @param new_pred - The new predecessor. -+ * @param backlog - List of backlog Data Structure. -+ */ -+ void ChangePredForBacklog(MachineBlock* old_pred, -+ MachineBlock* new_pred, -+ std::vector* backlog); -+ -+ /** -+ * @brief Get the First Basic Block of the CFG. -+ * @return The first Basic Block. -+ */ -+ MachineBlock* GetStartBBlock() { -+ return start_bblock_; -+ } -+ -+ /** -+ * @brief Keeps track of visited Basic Blocks. -+ * @param bblock - the Basic Block that was visited. -+ * @param start - Starting instruction pointer. -+ * @param end - ending instruction pointer. -+ */ -+ void AddTuple(MachineBlock* bblock, const uint8_t* start, const uint8_t* end); -+ -+ /** -+ * @brief Check whether the Basic Block was already visited. -+ * @param addr - the pointer to a certain location that has to be tested. -+ * @param prev_bblock - Predecessor Basic Block. -+ * @return true if visited. False otherwise. -+ */ -+ bool IsVisitedForCall(uint8_t* addr, MachineBlock* prev_bblock) const; -+ -+ /** -+ * @brief Check if an entry in the backlog was analyzed already. -+ * @param entry - the backlog entry. -+ * @param backlog - list of backlog entries. -+ * @return true of visited; false otherwise. -+ */ -+ bool IsVisitedForBacklog(BackLogDs* entry, std::vector* backlog); -+ -+ /** -+ * @brief Check if a certain location(instruction) was already analyzed or not. -+ * @param addr - The address that is being checked. -+ * @param prev_bblock - Predecessor Basic Block. -+ * @param succ_bblock - Successor Basic Block. -+ * @param backlog - List of backlog entries. -+ * @param is_function_start - True if it is the first instruction in function otherwise false. -+ * @return true if analyzed already; false otherwise. -+ */ -+ bool IsVisited(const uint8_t* addr, -+ MachineBlock* prev_bblock, -+ MachineBlock* succ_bblock, -+ std::vector* backlog, -+ const bool is_function_start); -+ -+ /** -+ * @brief prints the CFG in human readable/dot format to logcat. -+ * @param output - output stream. -+ * @param is_dot - whether the output must be in dot format. -+ */ -+ void Print(std::ostringstream &output, bool is_dot) const; -+ -+ /** -+ * @brief Determine if the CFG falls within the budget to call it Fast or not. -+ * @return true if method's CFG satisfies budget; false otherwise. -+ */ -+ bool IsStillFast() const; -+ -+ /** -+ * @brief Get the current state of CFG analysis. -+ * @return Current state of analysis. -+ */ -+ AnalysisResult GetAnalysisState() const { -+ return state_; -+ } -+ -+ private: -+ MachineBlock* start_bblock_; -+ uint32_t num_of_bblocks_ = 0u; -+ uint32_t num_of_instrs_ = 0u; -+ uint32_t call_depth_ = 0u; -+ AnalysisResult state_ = AnalysisResult::kFast; -+ std::vector cfg_bblock_list_; -+ std::vector visited_bblock_list_; -+ std::string method_name_; -+}; -+ -+/** -+ * @brief Analyze a method and determine whether it can be marked fast or not. -+ * @param method_idx - dex method Index. -+ * @param dex_file - dex File. -+ * @param fn_ptr - Function pointer of method to be analyzed. -+ * @return true if fast; false otherwise. -+ */ -+AnalysisResult AnalyzeMethod(uint32_t method_idx, const DexFile& dex_file, const void* fn_ptr); -+ -+} // namespace x86 -+} // namespace art -+ -+#endif // ART_RUNTIME_BINARY_ANALYZER_BINARY_ANALYZER_X86_H_ -diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc -index ecb2fcf472..e227b765f7 100644 ---- a/runtime/class_linker.cc -+++ b/runtime/class_linker.cc -@@ -59,6 +59,7 @@ - #include "base/unix_file/fd_file.h" - #include "base/utils.h" - #include "base/value_object.h" -+#include "binary_analyzer/binary_analyzer.h" - #include "cha.h" - #include "class_linker-inl.h" - #include "class_loader_utils.h" -@@ -426,12 +427,54 @@ ClassLinker::VisiblyInitializedCallback* ClassLinker::MarkClassInitialized( - return nullptr; - } - } -+class AutoFastJniDetectTask final : public jit::JniTask { -+ public: -+ AutoFastJniDetectTask(ArtMethod* method, const void* native_method) -+ : method_(method), native_method_(native_method) { } -+ -+ ~AutoFastJniDetectTask() { } -+ -+ void Run(Thread* self) override { -+ ScopedObjectAccess soa(self); -+ bool is_fast = IsFastJNI(method_->GetDexMethodIndex(), *method_->GetDexFile(), native_method_); -+ if (is_fast) { -+ method_->SetAccessFlags(method_->GetAccessFlags() | kAccFastNative); -+ } -+ } -+ -+ void Finalize() override { -+ delete this; -+ } -+ -+ private: -+ ArtMethod* const method_; -+ const void* native_method_; -+ -+ DISALLOW_IMPLICIT_CONSTRUCTORS(AutoFastJniDetectTask); -+}; -+ - - const void* ClassLinker::RegisterNative( - Thread* self, ArtMethod* method, const void* native_method) { - CHECK(method->IsNative()) << method->PrettyMethod(); - CHECK(native_method != nullptr) << method->PrettyMethod(); - void* new_native_method = nullptr; -+ if (Runtime::Current()->IsAutoFastDetect()) { -+ // FastJni analysis will be triggered only for native methods during the time of -+ // registration -+ const bool not_going_to_unregister = (native_method != GetJniDlsymLookupStub()); -+ if (Runtime::Current()->IsAutoFastDetect() && not_going_to_unregister) { -+ jit::Jit* jit = Runtime::Current()->GetJit(); -+ if (jit != nullptr) { -+ jit->AddJniTask(Thread::Current(), new AutoFastJniDetectTask(method, native_method)); -+ } else { -+ // auto fastJNI detection doesn't work in AOT at all. -+ // In JIT mode it works too but only between -+ // process startup and JIT creation. -+ } -+ } -+ } -+ - Runtime* runtime = Runtime::Current(); - runtime->GetRuntimeCallbacks()->RegisterNativeMethod(method, - native_method, -diff --git a/runtime/entrypoints/jni/jni_entrypoints.cc b/runtime/entrypoints/jni/jni_entrypoints.cc -index e606c2173a..e35baf2764 100644 ---- a/runtime/entrypoints/jni/jni_entrypoints.cc -+++ b/runtime/entrypoints/jni/jni_entrypoints.cc -@@ -46,6 +46,47 @@ static inline uint32_t GetInvokeStaticMethodIndex(ArtMethod* caller, uint32_t de - return method_idx; - } - -+ -+// To ensure mutator lock could be held throughout the code path as a part of compiler error, -+// added the NO_THREAD_SAFETY_ANALYSIS flag */ -+const void* artFindNativeMethodFastJni(Thread* self, -+ ScopedObjectAccess& soa) -+ NO_THREAD_SAFETY_ANALYSIS { // We continue as Native. -+ bool was_slow = false; -+ bool is_fast = false; -+ const void* return_val = nullptr; -+ { -+ ArtMethod* method = self->GetCurrentMethod(nullptr); -+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); -+ -+ DCHECK(method != nullptr); -+ std::string error_msg; -+ -+ // Lookup symbol address for method, on failure we'll return null with an exception set, -+ // otherwise we return the address of the method we found -+ void* native_code = soa.Vm()->FindCodeForNativeMethod(method, &error_msg, /*can_suspend=*/ true); -+ if (native_code == nullptr) { -+ LOG(ERROR) << error_msg; -+ self->ThrowNewException("Ljava/lang/UnsatisfiedLinkError;", error_msg.c_str()); -+ return nullptr; -+ } else { -+ // Register so that future calls don't come here -+ was_slow = !method->IsFastNative(); -+ const void* final_function_ptr = class_linker->RegisterNative(self, method, native_code); -+ is_fast = method->IsFastNative(); -+ return_val = final_function_ptr; -+ } -+ } -+ -+ // The thread does not have to do costly transition from kRunnable to kNative,reducing the -+ // JNI overhead once a method is marked as Fast native. -+ if (was_slow && is_fast) { -+ self->TransitionFromSuspendedToRunnable(); -+ } -+ return return_val; -+} -+ -+ - // Used by the JNI dlsym stub to find the native method to invoke if none is registered. - extern "C" const void* artFindNativeMethodRunnable(Thread* self) - REQUIRES_SHARED(Locks::mutator_lock_) { -@@ -129,7 +170,11 @@ extern "C" const void* artFindNativeMethod(Thread* self) { - DCHECK_EQ(self, Thread::Current()); - Locks::mutator_lock_->AssertNotHeld(self); // We come here as Native. - ScopedObjectAccess soa(self); -- return artFindNativeMethodRunnable(self); -+ if (Runtime::Current()->IsAutoFastDetect()) { -+ return artFindNativeMethodFastJni(self, soa); -+ } else { -+ return artFindNativeMethodRunnable(self); -+ } - } - - extern "C" size_t artCriticalNativeFrameSize(ArtMethod* method, uintptr_t caller_pc) -diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc -index b231cce0bc..3b37472f64 100644 ---- a/runtime/jit/jit.cc -+++ b/runtime/jit/jit.cc -@@ -1569,6 +1569,14 @@ void Jit::MethodEntered(Thread* self, ArtMethod* method) { - AddSamples(self, method); - } - -+bool Jit::AddJniTask(Thread* self, JniTask* task) { -+ if (thread_pool_ == nullptr) { -+ return false; -+ } -+ thread_pool_->AddTask(self, task); -+ return true; -+} -+ - void Jit::WaitForCompilationToFinish(Thread* self) { - if (thread_pool_ != nullptr) { - thread_pool_->Wait(self, false, false); -diff --git a/runtime/jit/jit.h b/runtime/jit/jit.h -index c95fd9d934..9e63eff667 100644 ---- a/runtime/jit/jit.h -+++ b/runtime/jit/jit.h -@@ -56,6 +56,7 @@ class JitCodeCache; - class JitCompileTask; - class JitMemoryRegion; - class JitOptions; -+class JniTask : public Task { }; - - static constexpr int16_t kJitCheckForOSR = -1; - static constexpr int16_t kJitHotnessDisabled = -2; -@@ -370,7 +371,10 @@ class Jit { - ThreadPool* GetThreadPool() const { - return thread_pool_.get(); - } -- -+ -+ -+ bool AddJniTask(Thread* self, JniTask* task); -+ - // Stop the JIT by waiting for all current compilations and enqueued compilations to finish. - void Stop(); - -diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc -index 7df765fe29..6e9a5836fe 100644 ---- a/runtime/parsed_options.cc -+++ b/runtime/parsed_options.cc -@@ -437,6 +437,10 @@ std::unique_ptr ParsedOptions::MakeParser(bool ignore_unrecognize - .IntoKey(M::UseStderrLogger) - .Define("-Xonly-use-system-oat-files") - .IntoKey(M::OnlyUseTrustedOatFiles) -+ .Define("-XAutoFastJni:_") -+ .WithType() -+ .WithValueMap({{"false", false}, {"true", true}}) -+ .IntoKey(M::AutoFastJni) - .Define("-Xdeny-art-apex-data-files") - .IntoKey(M::DenyArtApexDataFiles) - .Define("-Xverifier-logging-threshold=_") -@@ -513,7 +517,8 @@ std::unique_ptr ParsedOptions::MakeParser(bool ignore_unrecognize - "-Xjitprofile", - "-Xjitdisableopt", - "-Xjitsuspendpoll", -- "-XX:mainThreadStackSize=_"}) -+ "-XX:mainThreadStackSize=_", -+ "-XAutoFastJni"}) - .IgnoreUnrecognized(ignore_unrecognized) - .OrderCategories({"standard", "extended", "Dalvik", "ART"}); - -diff --git a/runtime/runtime.cc b/runtime/runtime.cc -index 36d7d7ed7a..43e2a2fcc6 100644 ---- a/runtime/runtime.cc -+++ b/runtime/runtime.cc -@@ -311,6 +311,7 @@ Runtime::Runtime() - // Initially assume we perceive jank in case the process state is never updated. - process_state_(kProcessStateJankPerceptible), - zygote_no_threads_(false), -+ auto_fast_detect_(false), - verifier_logging_threshold_ms_(100), - verifier_missing_kthrow_fatal_(false), - perfetto_hprof_enabled_(false), -@@ -1507,11 +1508,10 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { - image_dex2oat_enabled_ = runtime_options.GetOrDefault(Opt::ImageDex2Oat); - dump_native_stack_on_sig_quit_ = runtime_options.GetOrDefault(Opt::DumpNativeStackOnSigQuit); - allow_in_memory_compilation_ = runtime_options.Exists(Opt::AllowInMemoryCompilation); -- - if (is_zygote_ || runtime_options.Exists(Opt::OnlyUseTrustedOatFiles)) { - oat_file_manager_->SetOnlyUseTrustedOatFiles(); - } -- -+ auto_fast_detect_ = runtime_options.GetOrDefault(Opt::AutoFastJni); - vfprintf_ = runtime_options.GetOrDefault(Opt::HookVfprintf); - exit_ = runtime_options.GetOrDefault(Opt::HookExit); - abort_ = runtime_options.GetOrDefault(Opt::HookAbort); -diff --git a/runtime/runtime.h b/runtime/runtime.h -index fc8c050cf1..d112f31d2b 100644 ---- a/runtime/runtime.h -+++ b/runtime/runtime.h -@@ -961,6 +961,16 @@ class Runtime { - char** GetEnvSnapshot() const { - return env_snapshot_.GetSnapshot(); - } -+ -+ // Should Auto fast Detection be done. -+ bool IsAutoFastDetect() const { -+ return auto_fast_detect_; -+ } -+ -+ // Set Auto Fast Detection. -+ void SetAutoFastDetect(bool value) { -+ auto_fast_detect_ = value; -+ } - - void AddSystemWeakHolder(gc::AbstractSystemWeakHolder* holder); - void RemoveSystemWeakHolder(gc::AbstractSystemWeakHolder* holder); -@@ -1564,6 +1574,9 @@ class Runtime { - static_cast(DeoptimizationKind::kLast) + 1]; - - MemMap protected_fault_page_; -+ -+ // Auto Fast JNI detection gate. -+ bool auto_fast_detect_; - - uint32_t verifier_logging_threshold_ms_; - -diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def -index b2fcf7df13..2cf9db77f9 100644 ---- a/runtime/runtime_options.def -+++ b/runtime/runtime_options.def -@@ -176,6 +176,7 @@ RUNTIME_OPTIONS_KEY (unsigned int, GlobalRefAllocStackTraceLimit, 0) // - RUNTIME_OPTIONS_KEY (Unit, UseStderrLogger) - - RUNTIME_OPTIONS_KEY (Unit, OnlyUseTrustedOatFiles) -+RUNTIME_OPTIONS_KEY (bool, AutoFastJni, false) - RUNTIME_OPTIONS_KEY (Unit, DenyArtApexDataFiles) - RUNTIME_OPTIONS_KEY (unsigned int, VerifierLoggingThreshold, 100) - --- -2.17.1 - diff --git a/aosp_diff/preliminary/art/0003-Coverity-Fixes.patch b/aosp_diff/preliminary/art/0003-Coverity-Fixes.patch deleted file mode 100644 index 2644af7cd4..0000000000 --- a/aosp_diff/preliminary/art/0003-Coverity-Fixes.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 596415038b14c0065b91fd2d8bddd46455c299ac Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 15 Sep 2023 19:25:48 +0530 -Subject: [PATCH] Coverity Fixes - -Change-Id: Ic1e5b77db643f10fbc1f4254ee2e98829435bee3 -Signed-off-by: Priyanka Bose ---- - disassembler/disassembler_x86.cc | 4 +++- - runtime/binary_analyzer/BinaryDisassembler.cc | 2 +- - runtime/binary_analyzer/binary_analyzer_x86.h | 14 +++++++------- - 3 files changed, 11 insertions(+), 9 deletions(-) - -diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc -index c4955c9cb3..bf8af72c3e 100644 ---- a/disassembler/disassembler_x86.cc -+++ b/disassembler/disassembler_x86.cc -@@ -1624,7 +1624,9 @@ DISASSEMBLER_ENTRY(cmp, - } - if (insn_x86 != nullptr) { - std::string tmp = StringPrintf("%s%s%s%s%s",opcode0,opcode1,opcode2,opcode3,opcode4); -- strcpy(insn_x86->instr_str,tmp.c_str()); -+ memset(insn_x86->instr_str,0,INSTR_MNEMONIC_SIZE); -+ strncpy(insn_x86->instr_str,tmp.c_str(),INSTR_MNEMONIC_SIZE); -+ insn_x86->instr_str[INSTR_MNEMONIC_SIZE-1] = '\0'; - /*LOG(INFO) << "op str:" << insn_x86->instr_str;*/ - insn_x86->size = instr - begin_instr; - insn_x86->prefix[0] = prefix[0]; -diff --git a/runtime/binary_analyzer/BinaryDisassembler.cc b/runtime/binary_analyzer/BinaryDisassembler.cc -index 88aa324f91..5ca393995c 100644 ---- a/runtime/binary_analyzer/BinaryDisassembler.cc -+++ b/runtime/binary_analyzer/BinaryDisassembler.cc -@@ -34,7 +34,7 @@ BinaryDisassembler::BinaryDisassembler(InstructionSet insn_set) { - if (disassembler_ == nullptr) { - const uint8_t* base_address = nullptr; - const uint8_t* end_address = nullptr; -- disassembler_ = std::unique_ptr((*create_disassembler)( -+ disassembler_ = std::unique_ptr(create_disassembler( - insn_set, - new DisassemblerOptions(/* absolute_addresses */ false, - base_address, -diff --git a/runtime/binary_analyzer/binary_analyzer_x86.h b/runtime/binary_analyzer/binary_analyzer_x86.h -index 1553f6d843..38a13c6ebb 100644 ---- a/runtime/binary_analyzer/binary_analyzer_x86.h -+++ b/runtime/binary_analyzer/binary_analyzer_x86.h -@@ -124,11 +124,11 @@ class MachineInstruction { - } - - private: -- std::string instr_; -- const uint8_t* instr_ptr_; -- uint8_t length_; -- MachineInstruction* prev_instr_; -- MachineInstruction* next_instr_; -+ std::string instr_ {}; -+ const uint8_t* instr_ptr_ = nullptr; -+ uint8_t length_ = 0; -+ MachineInstruction* prev_instr_ = nullptr; -+ MachineInstruction* next_instr_ = nullptr; - }; - - /** -@@ -675,14 +675,14 @@ class CFGraph { - } - - private: -- MachineBlock* start_bblock_; -+ MachineBlock* start_bblock_ = nullptr; - uint32_t num_of_bblocks_ = 0u; - uint32_t num_of_instrs_ = 0u; - uint32_t call_depth_ = 0u; - AnalysisResult state_ = AnalysisResult::kFast; - std::vector cfg_bblock_list_; - std::vector visited_bblock_list_; -- std::string method_name_; -+ std::string method_name_ {}; - }; - - /** --- -2.17.1 - diff --git a/aosp_diff/preliminary/art/0004-Fixed-static-analysis-issue.patch b/aosp_diff/preliminary/art/0004-Fixed-static-analysis-issue.patch deleted file mode 100644 index 6bfdaced52..0000000000 --- a/aosp_diff/preliminary/art/0004-Fixed-static-analysis-issue.patch +++ /dev/null @@ -1,32 +0,0 @@ -From ff51c22e1d19862aebee1a5e9a50e039544725b8 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 15 Sep 2023 19:28:08 +0530 -Subject: [PATCH] Fixed static analysis issue - -Following issue is fixed: -Uninitialized members - -Change-Id: I5d8e567570237483bf9a28e70a21dbc49445b6ba -Signed-off-by: Priyanka Bose ---- - runtime/binary_analyzer/BinaryDisassembler.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/runtime/binary_analyzer/BinaryDisassembler.h b/runtime/binary_analyzer/BinaryDisassembler.h -index 4e0992ffad..ea8fa03aa5 100644 ---- a/runtime/binary_analyzer/BinaryDisassembler.h -+++ b/runtime/binary_analyzer/BinaryDisassembler.h -@@ -94,8 +94,8 @@ class BinaryDisassembler { - size_t DumpInstruction(std::ostream& os, const uint8_t* instr); - - private: -- uint64_t address_; -- const uint8_t* ptr_; -+ uint64_t address_ = 0; -+ const uint8_t* ptr_ = nullptr; - std::unique_ptr disassembler_ = nullptr; - private: - DISALLOW_COPY_AND_ASSIGN(BinaryDisassembler); --- -2.17.1 - diff --git a/aosp_diff/preliminary/art/0005-Improve-linear-loop-optimization-overflow-checks.patch b/aosp_diff/preliminary/art/0005-Improve-linear-loop-optimization-overflow-checks.patch deleted file mode 100644 index b9a48d1996..0000000000 --- a/aosp_diff/preliminary/art/0005-Improve-linear-loop-optimization-overflow-checks.patch +++ /dev/null @@ -1,350 +0,0 @@ -From e56eb3c93937a69af79470c1065d928ea016df84 Mon Sep 17 00:00:00 2001 -From: Santiago Aboy Solanes -Date: Tue, 24 Oct 2023 14:09:47 +0100 -Subject: [PATCH] Improve linear loop optimization overflow checks - -We can move the logic from GenerateLastValueLinear to GenerateCode, -where we can: - * be more granular, and - * reuse that code for other methods. - -To do so we add an allow_potential_overflow variable. This is done -because BCE does perform operations that might overflow, but it -uses HDeoptimize instructions to guard against that. Loop -optimization doesn't add HDeoptimize instructions so we must be -more careful. - -Bug: 231415860 -Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b -Change-Id: I1d689e5ddd87d96707673b6065ab0cc48b288617 ---- - compiler/optimizing/induction_var_range.cc | 197 ++++++++++++++++-- - compiler/optimizing/induction_var_range.h | 19 +- - .../optimizing/induction_var_range_test.cc | 6 +- - 3 files changed, 205 insertions(+), 17 deletions(-) - -diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc -index 9b78699ead..764b1459f4 100644 ---- a/compiler/optimizing/induction_var_range.cc -+++ b/compiler/optimizing/induction_var_range.cc -@@ -1132,18 +1132,27 @@ bool InductionVarRange::GenerateLastValueLinear(const HBasicBlock* context, - return false; - } - -- // Stride value must be a known constant that fits into int32. -+ // Stride value must be a known constant that fits into int32. The stride will be the `i` in `a * -+ // i + b`. - int64_t stride_value = 0; - if (!IsConstant(context, loop, info->op_a, kExact, &stride_value) || - !CanLongValueFitIntoInt(stride_value)) { - return false; - } - -- // We require `a` to be a constant value that didn't overflow. -+ // We require the calculation of `a` to not overflow. - const bool is_min_a = stride_value >= 0 ? is_min : !is_min; -- Value val_a = GetVal(context, loop, trip, trip, is_min_a); -+ HInstruction* opa; - HInstruction* opb; -- if (!IsConstantValue(val_a) || -+ if (!GenerateCode(context, -+ loop, -+ trip, -+ trip, -+ graph, -+ block, -+ is_min_a, -+ &opa, -+ /*allow_potential_overflow=*/false) || - !GenerateCode(context, loop, info->op_b, trip, graph, block, is_min, &opb)) { - return false; - } -@@ -1151,7 +1160,8 @@ bool InductionVarRange::GenerateLastValueLinear(const HBasicBlock* context, - if (graph != nullptr) { - ArenaAllocator* allocator = graph->GetAllocator(); - HInstruction* oper; -- HInstruction* opa = graph->GetConstant(type, val_a.b_constant); -+ // Emit instructions for `a * i + b`. These are fine to overflow as they would have overflown -+ // also if we had kept the loop. - if (stride_value == 1) { - oper = new (allocator) HAdd(type, opa, opb); - } else if (stride_value == -1) { -@@ -1406,7 +1416,8 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - HGraph* graph, // when set, code is generated - HBasicBlock* block, - bool is_min, -- /*out*/HInstruction** result) const { -+ /*out*/ HInstruction** result, -+ bool allow_potential_overflow) const { - if (info != nullptr) { - // If during codegen, the result is not needed (nullptr), simply return success. - if (graph != nullptr && result == nullptr) { -@@ -1431,8 +1442,41 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - case HInductionVarAnalysis::kLE: - case HInductionVarAnalysis::kGT: - case HInductionVarAnalysis::kGE: -- if (GenerateCode(context, loop, info->op_a, trip, graph, block, is_min, &opa) && -- GenerateCode(context, loop, info->op_b, trip, graph, block, is_min, &opb)) { -+ if (GenerateCode(context, -+ loop, -+ info->op_a, -+ trip, -+ graph, -+ block, -+ is_min, -+ &opa, -+ allow_potential_overflow) && -+ GenerateCode(context, -+ loop, -+ info->op_b, -+ trip, -+ graph, -+ block, -+ is_min, -+ &opb, -+ allow_potential_overflow)) { -+ // Check for potentially invalid operations. -+ if (!allow_potential_overflow) { -+ switch (info->operation) { -+ case HInductionVarAnalysis::kAdd: -+ return TryGenerateAddWithoutOverflow( -+ context, loop, info, graph, opa, opb, result); -+ case HInductionVarAnalysis::kSub: -+ return TryGenerateSubWithoutOverflow(context, loop, info, graph, opa, result); -+ default: -+ // The rest of the operations are not relevant in the cases where -+ // `allow_potential_overflow` is false. Fall through to the allowed overflow -+ // case. -+ break; -+ } -+ } -+ -+ // Overflows here are accepted. - if (graph != nullptr) { - HInstruction* operation = nullptr; - switch (info->operation) { -@@ -1465,7 +1509,15 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - } - break; - case HInductionVarAnalysis::kNeg: -- if (GenerateCode(context, loop, info->op_b, trip, graph, block, !is_min, &opb)) { -+ if (GenerateCode(context, -+ loop, -+ info->op_b, -+ trip, -+ graph, -+ block, -+ !is_min, -+ &opb, -+ allow_potential_overflow)) { - if (graph != nullptr) { - *result = Insert(block, new (graph->GetAllocator()) HNeg(type, opb)); - } -@@ -1481,8 +1533,15 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - case HInductionVarAnalysis::kTripCountInLoopUnsafe: - if (UseFullTripCount(context, loop, is_min)) { - // Generate the full trip count (do not subtract 1 as we do in loop body). -- return GenerateCode( -- context, loop, info->op_a, trip, graph, block, /*is_min=*/ false, result); -+ return GenerateCode(context, -+ loop, -+ info->op_a, -+ trip, -+ graph, -+ block, -+ /*is_min=*/false, -+ result, -+ allow_potential_overflow); - } - FALLTHROUGH_INTENDED; - case HInductionVarAnalysis::kTripCountInBody: -@@ -1493,7 +1552,15 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - } - return true; - } else if (IsContextInBody(context, loop)) { -- if (GenerateCode(context, loop, info->op_a, trip, graph, block, is_min, &opb)) { -+ if (GenerateCode(context, -+ loop, -+ info->op_a, -+ trip, -+ graph, -+ block, -+ is_min, -+ &opb, -+ allow_potential_overflow)) { - if (graph != nullptr) { - ArenaAllocator* allocator = graph->GetAllocator(); - *result = -@@ -1519,8 +1586,24 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - if (IsConstant(context, loop, info->op_a, kExact, &stride_value) && - CanLongValueFitIntoInt(stride_value)) { - const bool is_min_a = stride_value >= 0 ? is_min : !is_min; -- if (GenerateCode(context, loop, trip, trip, graph, block, is_min_a, &opa) && -- GenerateCode(context, loop, info->op_b, trip, graph, block, is_min, &opb)) { -+ if (GenerateCode(context, -+ loop, -+ trip, -+ trip, -+ graph, -+ block, -+ is_min_a, -+ &opa, -+ allow_potential_overflow) && -+ GenerateCode(context, -+ loop, -+ info->op_b, -+ trip, -+ graph, -+ block, -+ is_min, -+ &opb, -+ allow_potential_overflow)) { - if (graph != nullptr) { - ArenaAllocator* allocator = graph->GetAllocator(); - HInstruction* oper; -@@ -1562,6 +1645,92 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - return false; - } - -+bool InductionVarRange::TryGenerateAddWithoutOverflow(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ /*in*/ HInstruction* opa, -+ /*in*/ HInstruction* opb, -+ /*out*/ HInstruction** result) const { -+ // Calculate `a + b` making sure we can't overflow. -+ int64_t val_a; -+ const bool a_is_const = IsConstant(context, loop, info->op_a, kExact, &val_a); -+ int64_t val_b; -+ const bool b_is_const = IsConstant(context, loop, info->op_b, kExact, &val_b); -+ if (a_is_const && b_is_const) { -+ // Calculate `a + b` and use that. Note that even when the values are known, -+ // their addition can still overflow. -+ Value add_val = AddValue(Value(val_a), Value(val_b)); -+ if (add_val.is_known) { -+ DCHECK(IsConstantValue(add_val)); -+ // Known value not overflowing. -+ if (graph != nullptr) { -+ *result = graph->GetConstant(info->type, add_val.b_constant); -+ } -+ return true; -+ } -+ } -+ -+ // When `a` is `0`, we can just use `b`. -+ if (a_is_const && val_a == 0) { -+ if (graph != nullptr) { -+ *result = opb; -+ } -+ return true; -+ } -+ -+ if (b_is_const && val_b == 0) { -+ if (graph != nullptr) { -+ *result = opa; -+ } -+ return true; -+ } -+ -+ // Couldn't safely calculate the addition. -+ return false; -+} -+ -+bool InductionVarRange::TryGenerateSubWithoutOverflow(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ /*in*/ HInstruction* opa, -+ /*out*/ HInstruction** result) const { -+ // Calculate `a - b` making sure we can't overflow. -+ int64_t val_b; -+ if (!IsConstant(context, loop, info->op_b, kExact, &val_b)) { -+ // If b is unknown, a - b can potentially overflow for any value of a since b -+ // can be Integer.MIN_VALUE. -+ return false; -+ } -+ -+ int64_t val_a; -+ if (IsConstant(context, loop, info->op_a, kExact, &val_a)) { -+ // Calculate `a - b` and use that. Note that even when the values are known, -+ // their subtraction can still overflow. -+ Value sub_val = SubValue(Value(val_a), Value(val_b)); -+ if (sub_val.is_known) { -+ DCHECK(IsConstantValue(sub_val)); -+ // Known value not overflowing. -+ if (graph != nullptr) { -+ *result = graph->GetConstant(info->type, sub_val.b_constant); -+ } -+ return true; -+ } -+ } -+ -+ // When `b` is `0`, we can just use `a`. -+ if (val_b == 0) { -+ if (graph != nullptr) { -+ *result = opa; -+ } -+ return true; -+ } -+ -+ // Couldn't safely calculate the subtraction. -+ return false; -+} -+ - void InductionVarRange::ReplaceInduction(HInductionVarAnalysis::InductionInfo* info, - HInstruction* fetch, - HInstruction* replacement) { -diff --git a/compiler/optimizing/induction_var_range.h b/compiler/optimizing/induction_var_range.h -index 3e1212bec8..f908b92282 100644 ---- a/compiler/optimizing/induction_var_range.h -+++ b/compiler/optimizing/induction_var_range.h -@@ -367,7 +367,24 @@ class InductionVarRange { - HGraph* graph, - HBasicBlock* block, - bool is_min, -- /*out*/ HInstruction** result) const; -+ /*out*/ HInstruction** result, -+ // TODO(solanes): Remove default value when all cases have been assessed. -+ bool allow_potential_overflow = true) const; -+ -+ bool TryGenerateAddWithoutOverflow(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ /*in*/ HInstruction* opa, -+ /*in*/ HInstruction* opb, -+ /*out*/ HInstruction** result) const; -+ -+ bool TryGenerateSubWithoutOverflow(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ /*in*/ HInstruction* opa, -+ /*out*/ HInstruction** result) const; - - void ReplaceInduction(HInductionVarAnalysis::InductionInfo* info, - HInstruction* fetch, -diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc -index d879897959..40fb0d6092 100644 ---- a/compiler/optimizing/induction_var_range_test.cc -+++ b/compiler/optimizing/induction_var_range_test.cc -@@ -1061,11 +1061,13 @@ TEST_F(InductionVarRangeTest, ConstantTripCountDown) { - range_.CanGenerateRange(exit->GetBlock(), exit, &needs_finite_test, &needs_taken_test)); - EXPECT_FALSE(range_.CanGenerateLastValue(exit)); - -- // Last value (unsimplified). -+ // Last value (unsimplified). We expect Sub(1000, Neg(-1000)) which is equivalent to Sub(1000, -+ // 1000) aka 0. - HInstruction* last = range_.GenerateLastValue(phi, graph_, loop_preheader_); - ASSERT_TRUE(last->IsSub()); - ExpectInt(1000, last->InputAt(0)); -- ExpectInt(1000, last->InputAt(1)); -+ ASSERT_TRUE(last->InputAt(1)->IsNeg()); -+ ExpectInt(-1000, last->InputAt(1)->AsNeg()->InputAt(0)); - - // Loop logic. - int64_t tc = 0; --- -2.42.0 - diff --git a/aosp_diff/preliminary/art/0006-Improve-linear-induction-var-range-creation.patch b/aosp_diff/preliminary/art/0006-Improve-linear-induction-var-range-creation.patch deleted file mode 100644 index 7c5ce7e4d7..0000000000 --- a/aosp_diff/preliminary/art/0006-Improve-linear-induction-var-range-creation.patch +++ /dev/null @@ -1,575 +0,0 @@ -From fdb807737f56d8de64a827a2e858066d793366f2 Mon Sep 17 00:00:00 2001 -From: Santiago Aboy Solanes -Date: Wed, 25 Oct 2023 14:10:13 +0100 -Subject: [PATCH] Improve linear induction var range creation - -We can now detect and remove loops that require an is_taken test e.g. - -int a = 0; -for (int i = 0; i < n; i++) { - a += 1; -} - -can be turned into `if (n < 0) then 0 else n`. - -Part of this logic can be reused in the future to help eliminate -BoundsCheck instructions. - -Bug: 304967775 -Fixes: 304967775 -Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing -Change-Id: I944f3408e623a0652977d4c3f72d29caf9c1f908 ---- - compiler/optimizing/induction_var_range.cc | 82 +++++++--- - compiler/optimizing/induction_var_range.h | 17 +- - test/449-checker-bce/src/Main.java | 87 ++++++++++- - test/618-checker-induction/src/Main.java | 173 +++++++++++++++++++-- - 4 files changed, 323 insertions(+), 36 deletions(-) - -diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc -index 764b1459f4..b1f33abdf8 100644 ---- a/compiler/optimizing/induction_var_range.cc -+++ b/compiler/optimizing/induction_var_range.cc -@@ -1066,11 +1066,11 @@ bool InductionVarRange::GenerateRangeOrLastValue(const HBasicBlock* context, - if (*stride_value > 0) { - lower = nullptr; - return GenerateLastValueLinear( -- context, loop, info, trip, graph, block, /*is_min=*/false, upper); -+ context, loop, info, trip, graph, block, /*is_min=*/false, upper, needs_taken_test); - } else { - upper = nullptr; - return GenerateLastValueLinear( -- context, loop, info, trip, graph, block, /*is_min=*/true, lower); -+ context, loop, info, trip, graph, block, /*is_min=*/true, lower, needs_taken_test); - } - case HInductionVarAnalysis::kPolynomial: - return GenerateLastValuePolynomial(context, loop, info, trip, graph, block, lower); -@@ -1124,7 +1124,8 @@ bool InductionVarRange::GenerateLastValueLinear(const HBasicBlock* context, - HGraph* graph, - HBasicBlock* block, - bool is_min, -- /*out*/ HInstruction** result) const { -+ /*out*/ HInstruction** result, -+ /*inout*/ bool* needs_taken_test) const { - DataType::Type type = info->type; - // Avoid any narrowing linear induction or any type mismatch between the linear induction and the - // trip count expression. -@@ -1172,6 +1173,15 @@ bool InductionVarRange::GenerateLastValueLinear(const HBasicBlock* context, - } - *result = Insert(block, oper); - } -+ -+ if (*needs_taken_test) { -+ if (TryGenerateTakenTest(context, loop, trip->op_b, graph, block, result, opb)) { -+ *needs_taken_test = false; // taken care of -+ } else { -+ return false; -+ } -+ } -+ - return true; - } - -@@ -1308,8 +1318,8 @@ bool InductionVarRange::GenerateLastValuePeriodic(const HBasicBlock* context, - HInductionVarAnalysis::InductionInfo* trip, - HGraph* graph, - HBasicBlock* block, -- /*out*/HInstruction** result, -- /*out*/bool* needs_taken_test) const { -+ /*out*/ HInstruction** result, -+ /*inout*/ bool* needs_taken_test) const { - DCHECK(info != nullptr); - DCHECK_EQ(info->induction_class, HInductionVarAnalysis::kPeriodic); - // Count period and detect all-invariants. -@@ -1384,21 +1394,9 @@ bool InductionVarRange::GenerateLastValuePeriodic(const HBasicBlock* context, - Insert(block, new (allocator) HEqual(msk, graph->GetConstant(type, 0), kNoDexPc)); - *result = Insert(block, new (graph->GetAllocator()) HSelect(is_even, x, y, kNoDexPc)); - } -- // Guard select with taken test if needed. -+ - if (*needs_taken_test) { -- HInstruction* is_taken = nullptr; -- if (GenerateCode(context, -- loop, -- trip->op_b, -- /*trip=*/ nullptr, -- graph, -- block, -- /*is_min=*/ false, -- graph ? &is_taken : nullptr)) { -- if (graph != nullptr) { -- ArenaAllocator* allocator = graph->GetAllocator(); -- *result = Insert(block, new (allocator) HSelect(is_taken, *result, x, kNoDexPc)); -- } -+ if (TryGenerateTakenTest(context, loop, trip->op_b, graph, block, result, x)) { - *needs_taken_test = false; // taken care of - } else { - return false; -@@ -1551,7 +1549,8 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - *result = graph->GetConstant(type, 0); - } - return true; -- } else if (IsContextInBody(context, loop)) { -+ } else if (IsContextInBody(context, loop) || -+ (context == loop->GetHeader() && !allow_potential_overflow)) { - if (GenerateCode(context, - loop, - info->op_a, -@@ -1562,9 +1561,19 @@ bool InductionVarRange::GenerateCode(const HBasicBlock* context, - &opb, - allow_potential_overflow)) { - if (graph != nullptr) { -- ArenaAllocator* allocator = graph->GetAllocator(); -- *result = -- Insert(block, new (allocator) HSub(type, opb, graph->GetConstant(type, 1))); -+ if (IsContextInBody(context, loop)) { -+ ArenaAllocator* allocator = graph->GetAllocator(); -+ *result = -+ Insert(block, new (allocator) HSub(type, opb, graph->GetConstant(type, 1))); -+ } else { -+ // We want to generate the full trip count since we want the last value. This -+ // will be combined with an `is_taken` test so we don't want to subtract one. -+ DCHECK(context == loop->GetHeader()); -+ // TODO(solanes): Remove the !allow_potential_overflow restriction and allow -+ // other parts e.g. BCE to take advantage of this. -+ DCHECK(!allow_potential_overflow); -+ *result = opb; -+ } - } - return true; - } -@@ -1731,6 +1740,33 @@ bool InductionVarRange::TryGenerateSubWithoutOverflow(const HBasicBlock* context - return false; - } - -+bool InductionVarRange::TryGenerateTakenTest(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ HBasicBlock* block, -+ /*inout*/ HInstruction** result, -+ /*inout*/ HInstruction* not_taken_result) const { -+ HInstruction* is_taken = nullptr; -+ if (GenerateCode(context, -+ loop, -+ info, -+ /*trip=*/nullptr, -+ graph, -+ block, -+ /*is_min=*/false, -+ graph != nullptr ? &is_taken : nullptr)) { -+ if (graph != nullptr) { -+ ArenaAllocator* allocator = graph->GetAllocator(); -+ *result = -+ Insert(block, new (allocator) HSelect(is_taken, *result, not_taken_result, kNoDexPc)); -+ } -+ return true; -+ } else { -+ return false; -+ } -+} -+ - void InductionVarRange::ReplaceInduction(HInductionVarAnalysis::InductionInfo* info, - HInstruction* fetch, - HInstruction* replacement) { -diff --git a/compiler/optimizing/induction_var_range.h b/compiler/optimizing/induction_var_range.h -index f908b92282..a81227b41b 100644 ---- a/compiler/optimizing/induction_var_range.h -+++ b/compiler/optimizing/induction_var_range.h -@@ -325,7 +325,8 @@ class InductionVarRange { - HGraph* graph, - HBasicBlock* block, - bool is_min, -- /*out*/ HInstruction** result) const; -+ /*out*/ HInstruction** result, -+ /*inout*/ bool* needs_taken_test) const; - - bool GenerateLastValuePolynomial(const HBasicBlock* context, - const HLoopInformation* loop, -@@ -357,8 +358,8 @@ class InductionVarRange { - HInductionVarAnalysis::InductionInfo* trip, - HGraph* graph, - HBasicBlock* block, -- /*out*/HInstruction** result, -- /*out*/ bool* needs_taken_test) const; -+ /*out*/ HInstruction** result, -+ /*inout*/ bool* needs_taken_test) const; - - bool GenerateCode(const HBasicBlock* context, - const HLoopInformation* loop, -@@ -386,6 +387,16 @@ class InductionVarRange { - /*in*/ HInstruction* opa, - /*out*/ HInstruction** result) const; - -+ // Try to guard the taken test with an HSelect instruction. Returns true if it can generate the -+ // code, or false otherwise. The caller is responsible of updating `needs_taken_test`. -+ bool TryGenerateTakenTest(const HBasicBlock* context, -+ const HLoopInformation* loop, -+ HInductionVarAnalysis::InductionInfo* info, -+ HGraph* graph, -+ HBasicBlock* block, -+ /*inout*/ HInstruction** result, -+ /*inout*/ HInstruction* not_taken_result) const; -+ - void ReplaceInduction(HInductionVarAnalysis::InductionInfo* info, - HInstruction* fetch, - HInstruction* replacement); -diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java -index 3e414103ba..f23896728e 100644 ---- a/test/449-checker-bce/src/Main.java -+++ b/test/449-checker-bce/src/Main.java -@@ -14,6 +14,8 @@ - * limitations under the License. - */ - -+import java.util.Arrays; -+ - public class Main { - - /// CHECK-START: int Main.sieve(int) BCE (before) -@@ -1773,6 +1775,87 @@ public class Main { - } - } - -+ // Tests `setZeroToRange` with a range of values. Checks for exceptions as well as the correctness -+ // of setting the right values to zero. -+ static void $noinline$testSetZeroToRange() { -+ for (int start = -2; start < 7; ++start) { -+ for (int len = -2; len < 7; ++len) { -+ int[] array = {1, 2, 3, 4, 5}; -+ final int lower = start; -+ final int upper = start + len - 1; -+ // We expect an exception if: -+ // * The first value is out of range, or -+ // * The last value is more than the length of the array. -+ // Note that if `upper < 0` it means that we will only do one iteration of the do while in -+ // `setZeroToRange` so we have the exception covered with the `lower` checks. -+ final boolean expected_exception = -+ (lower < 0) || (lower >= array.length) || (upper >= array.length); -+ try { -+ $noinline$setZeroToRange(array, start, len); -+ if (expected_exception) { -+ System.out.println("Missing ArrayIndexOutOfBoundsException for start " + start -+ + " and len " + len); -+ } -+ $noinline$checkZerosForSetZeroToRange(array, start, len); -+ } catch (ArrayIndexOutOfBoundsException e) { -+ if (!expected_exception) { -+ System.out.println("Unexpected ArrayIndexOutOfBoundsException for start " + start -+ + " and len " + len); -+ } -+ } -+ } -+ } -+ } -+ -+ // TODO(solanes): Improve the code to replace the following BoundsCheck with HDeoptimize -+ // instructions. See b/304967775 and aosp/2804075. -+ -+ /// CHECK-START: void Main.$noinline$setZeroToRange(int[], int, int) BCE (before) -+ /// CHECK: BoundsCheck -+ -+ /// CHECK-START: void Main.$noinline$setZeroToRange(int[], int, int) BCE (after) -+ /// CHECK: BoundsCheck -+ -+ // Sets to `0` the values of `arr` in the range `[start, len)`. -+ static void $noinline$setZeroToRange(int[] arr, int start, int len) { -+ int charPos = start; -+ do { -+ arr[charPos++] = 0; -+ } while (charPos < start + len); -+ } -+ -+ static void $noinline$checkZerosForSetZeroToRange(int[] arr, int start, int len) { -+ // Non-zeroes before zeroes. -+ int i = 0; -+ for (; i < Math.min(start, arr.length); ++i) { -+ if (arr[i] == 0) { -+ System.out.println("Expected non-zero for arr " + Arrays.toString(arr) + " before zeroes i " -+ + i + " start " + start + " and len " + len); -+ } -+ } -+ -+ int bound = start + len; -+ if (bound < 1 || len < 1) { -+ // We always set one zero since it is a do-while. -+ bound = i + 1; -+ } -+ -+ for (; i < Math.min(bound, arr.length); ++i) { -+ if (arr[i] != 0) { -+ System.out.println("Expected zero for arr " + Arrays.toString(arr) + " i " + i + " start " -+ + start + " and len " + len); -+ } -+ } -+ -+ // Then zeroes until the end. -+ for (; i < arr.length; ++i) { -+ if (arr[i] == 0) { -+ System.out.println("Expected non-zero after zeroes for arr " + Arrays.toString(arr) + " i " -+ + i + " start " + start + " and len " + len); -+ } -+ } -+ } -+ - // Make sure this method is compiled with optimizing. - /// CHECK-START: void Main.main(java.lang.String[]) register (after) - /// CHECK: ParallelMove -@@ -1909,10 +1992,12 @@ public class Main { - int i = 1; - if (foo() + i != 100) { - System.out.println("foo failed!"); -- }; -+ } - - testUnknownBounds(); - new Main().testExceptionMessage(); -+ -+ $noinline$testSetZeroToRange(); - } - - public static native boolean compiledWithOptimizing(); -diff --git a/test/618-checker-induction/src/Main.java b/test/618-checker-induction/src/Main.java -index 5dc8e9884a..21cca22dd3 100644 ---- a/test/618-checker-induction/src/Main.java -+++ b/test/618-checker-induction/src/Main.java -@@ -331,7 +331,26 @@ public class Main { - return closed; // only needs last-value - } - -- // TODO: taken test around closed form? -+ // closedFormInductionUpN turns into `if n < 0 then 12345 else 12345 + n * 5`. -+ -+ /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormInductionUpN(int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant 5 -+ /// CHECK-DAG: <> IntConstant 12345 -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Mul [<>,<>] -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] -+ /// CHECK-DAG: Return [<>] - static int closedFormInductionUpN(int n) { - int closed = 12345; - for (int i = 0; i < n; i++) { -@@ -340,7 +359,26 @@ public class Main { - return closed; // only needs last value - } - -- // TODO: taken test around closed form? -+ // closedFormInductionInAndDownN turns into `if n < 0 then closed else closed - n * 5`. -+ -+ /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormInductionInAndDownN(int, int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant -5 -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Mul [<>,<>] -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] -+ /// CHECK-DAG: Return [<>] - static int closedFormInductionInAndDownN(int closed, int n) { - for (int i = 0; i < n; i++) { - closed -= 5; -@@ -348,7 +386,27 @@ public class Main { - return closed; // only needs last value - } - -- // TODO: move closed form even further out? -+ // closedFormNestedN turns into `if (n < 0) then 0 else n * 10` -+ -+ /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedN(int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant 10 -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Mul [<>,<>] -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] -+ /// CHECK-DAG: Return [<>] - static int closedFormNestedN(int n) { - int closed = 0; - for (int i = 0; i < n; i++) { -@@ -359,7 +417,28 @@ public class Main { - return closed; // only needs last-value - } - -- // TODO: move closed form even further out? -+ // closedFormNestedNAlt turns into `if (n < 0) then 12345 else 12345 + n * 161` -+ -+ /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedNAlt(int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant 161 -+ /// CHECK-DAG: <> IntConstant 12345 -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Mul [<>,<>] -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] -+ /// CHECK-DAG: Return [<>] - static int closedFormNestedNAlt(int n) { - int closed = 12345; - for (int i = 0; i < n; i++) { -@@ -370,7 +449,30 @@ public class Main { - return closed; // only needs last-value - } - -- // TODO: move closed form even further out? -+ // We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n`. -+ // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) -+ // then 0 else m * n`. -+ /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ // Inner loop optimization -+ /// CHECK-START: int Main.closedFormNestedMN(int, int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Phi -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] - static int closedFormNestedMN(int m, int n) { - int closed = 0; - for (int i = 0; i < m; i++) { -@@ -381,10 +483,36 @@ public class Main { - return closed; // only needs last-value - } - -- // TODO: move closed form even further out? -+ // We optimize only the inner loop. It turns into `if (n < 0) then closed else closed + n * 7`. -+ // Potentially we can also update the outer loop turning into if (m < 0) then 0 else if (n < 0) -+ // then 1245 else 12345 + m * n * 7`. -+ /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) -+ /// CHECK: Phi -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ // Inner loop optimization -+ /// CHECK-START: int Main.closedFormNestedMNAlt(int, int) loop_optimization (after) -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> ParameterValue -+ /// CHECK-DAG: <> IntConstant 7 -+ /// CHECK-DAG: <> IntConstant 0 -+ /// CHECK-DAG: <> Phi -+ /// CHECK-DAG: <> Mul [<>,<>] -+ /// CHECK-DAG: <> Add [<>,<>] -+ /// CHECK-DAG: <> LessThan [<>,<>] -+ /// CHECK-DAG: <> Select [<>,<>,<>] - static int closedFormNestedMNAlt(int m, int n) { - int closed = 12345; - for (int i = 0; i < m; i++) { -+ // if n < 0 then closed else closed + n * 7 - for (int j = 0; j < n; j++) { - closed += 7; - } -@@ -481,21 +609,48 @@ public class Main { - return sum; - } - -- // TODO: handle as closed/empty eventually? -+ // We can generate a select, which then DCE detects it is redundant. Therefore, we eliminate -+ // these loops. -+ -+ /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexReturnedN(int) loop_optimization (after) -+ /// CHECK: Select - static int mainIndexReturnedN(int n) { - int i; - for (i = 0; i < n; i++); - return i; - } - -- // TODO: handle as closed/empty eventually? -+ /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexShort1(short) loop_optimization (after) -+ /// CHECK: Select - static int mainIndexShort1(short s) { - int i = 0; - for (i = 0; i < s; i++) { } - return i; - } - -- // TODO: handle as closed/empty eventually? -+ /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (before) -+ /// CHECK: Phi -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) -+ /// CHECK-NOT: Phi -+ // -+ /// CHECK-START: int Main.mainIndexShort2(short) loop_optimization (after) -+ /// CHECK: Select - static int mainIndexShort2(short s) { - int i = 0; - for (i = 0; s > i; i++) { } --- -2.17.1 - diff --git a/aosp_diff/preliminary/art/0007-Align-induction-var-range-checks-and-uses.patch b/aosp_diff/preliminary/art/0007-Align-induction-var-range-checks-and-uses.patch deleted file mode 100644 index f8bafa610b..0000000000 --- a/aosp_diff/preliminary/art/0007-Align-induction-var-range-checks-and-uses.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 97e5d89ca1cfe5f84d100a9546cf391d76c9f0be Mon Sep 17 00:00:00 2001 -From: Santiago Aboy Solanes -Date: Wed, 25 Oct 2023 14:34:25 +0100 -Subject: [PATCH] Align induction var range checks and uses - -We were requiring some conditions but we weren't checking all of them. - -Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing -Change-Id: I7442db52492d3de2e4593152e22f4c4e2fed65b5 ---- - compiler/optimizing/induction_var_range.cc | 23 +++++++++++++++------- - 1 file changed, 16 insertions(+), 7 deletions(-) - -diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc -index b54507a03c..8568062933 100644 ---- a/compiler/optimizing/induction_var_range.cc -+++ b/compiler/optimizing/induction_var_range.cc -@@ -255,8 +255,8 @@ bool InductionVarRange::CanGenerateRange(const HBasicBlock* context, - nullptr, // nothing generated yet - &stride_value, - needs_finite_test, -- needs_taken_test) -- && (stride_value == -1 || -+ needs_taken_test) && -+ (stride_value == -1 || - stride_value == 0 || - stride_value == 1); // avoid arithmetic wrap-around anomalies. - } -@@ -280,7 +280,10 @@ void InductionVarRange::GenerateRange(const HBasicBlock* context, - nullptr, - &stride_value, - &b1, -- &b2)) { -+ &b2) || -+ (stride_value != -1 && -+ stride_value != 0 && -+ stride_value != 1)) { - LOG(FATAL) << "Failed precondition: CanGenerateRange()"; - } - } -@@ -303,7 +306,10 @@ HInstruction* InductionVarRange::GenerateTakenTest(HInstruction* loop_control, - &taken_test, - &stride_value, - &b1, -- &b2)) { -+ &b2) || -+ (stride_value != -1 && -+ stride_value != 0 && -+ stride_value != 1)) { - LOG(FATAL) << "Failed precondition: CanGenerateRange()"; - } - return taken_test; -@@ -336,7 +342,8 @@ HInstruction* InductionVarRange::GenerateLastValue(HInstruction* instruction, - HInstruction* last_value = nullptr; - bool is_last_value = true; - int64_t stride_value = 0; -- bool b1, b2; // unused -+ bool needs_finite_test = false; -+ bool needs_taken_test = false; - if (!GenerateRangeOrLastValue(context, - instruction, - is_last_value, -@@ -346,8 +353,10 @@ HInstruction* InductionVarRange::GenerateLastValue(HInstruction* instruction, - &last_value, - nullptr, - &stride_value, -- &b1, -- &b2)) { -+ &needs_finite_test, -+ &needs_taken_test) || -+ needs_finite_test || -+ needs_taken_test) { - LOG(FATAL) << "Failed precondition: CanGenerateLastValue()"; - } - return last_value; --- -2.17.1 - diff --git a/aosp_diff/preliminary/bionic/0001-Optimize-bionic-memory-functions-with-avx2-instructi.patch b/aosp_diff/preliminary/bionic/0001-Optimize-bionic-memory-functions-with-avx2-instructi.patch deleted file mode 100644 index 63d6bd3c46..0000000000 --- a/aosp_diff/preliminary/bionic/0001-Optimize-bionic-memory-functions-with-avx2-instructi.patch +++ /dev/null @@ -1,3785 +0,0 @@ -From 217a53b3b38a70862810372d147acf7e48b62b1c Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Wed, 13 Sep 2023 18:36:21 +0530 -Subject: [PATCH] Optimize bionic memory functions with avx2 instructions - -Following memory related functions are optimized with -avx2 implementation ported from glibc 2.20 -(only for 64-bit) - - memchr - - memcmp - - memrchr - -Change-Id: I956773c79b9bcebee69726820eaa74c709df7081 -Signed-off-by: ahs ---- - libc/Android.bp | 46 +- - .../kabylake/string/avx2-memcpy-kbl.S | 2052 +++++++++++++++++ - .../arch-x86_64/dynamic_function_dispatch.cpp | 38 + - libc/arch-x86_64/generic/string/memchr.c | 19 + - libc/arch-x86_64/generic/string/memrchr.c | 19 + - libc/arch-x86_64/generic/string/wmemset.c | 19 + - libc/arch-x86_64/{string => include}/cache.h | 0 - .../kabylake/string/avx2-memchr-kbl.S | 371 +++ - .../kabylake/string/avx2-memcmp-kbl.S | 428 ++++ - .../kabylake/string/avx2-memrchr-kbl.S | 408 ++++ - .../kabylake/string/avx2-wmemset-kbl.S | 140 ++ - .../string/sse2-memmove-slm.S | 4 +- - .../{ => silvermont}/string/sse2-memset-slm.S | 0 - .../{ => silvermont}/string/sse2-stpcpy-slm.S | 0 - .../string/sse2-stpncpy-slm.S | 0 - .../{ => silvermont}/string/sse2-strcat-slm.S | 0 - .../{ => silvermont}/string/sse2-strcpy-slm.S | 0 - .../{ => silvermont}/string/sse2-strlen-slm.S | 0 - .../string/sse2-strncat-slm.S | 0 - .../string/sse2-strncpy-slm.S | 0 - .../{ => silvermont}/string/sse4-memcmp-slm.S | 2 +- - .../string/ssse3-strcmp-slm.S | 0 - .../string/ssse3-strncmp-slm.S | 0 - libc/arch-x86_64/static_function_dispatch.S | 6 + - 24 files changed, 3537 insertions(+), 15 deletions(-) - create mode 100644 libc/arch-x86/kabylake/string/avx2-memcpy-kbl.S - create mode 100644 libc/arch-x86_64/generic/string/memchr.c - create mode 100644 libc/arch-x86_64/generic/string/memrchr.c - create mode 100644 libc/arch-x86_64/generic/string/wmemset.c - rename libc/arch-x86_64/{string => include}/cache.h (100%) - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-memchr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-memcmp-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-memrchr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wmemset-kbl.S - rename libc/arch-x86_64/{ => silvermont}/string/sse2-memmove-slm.S (99%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-memset-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-stpcpy-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-stpncpy-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-strcat-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-strcpy-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-strlen-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-strncat-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse2-strncpy-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/sse4-memcmp-slm.S (99%) - rename libc/arch-x86_64/{ => silvermont}/string/ssse3-strcmp-slm.S (100%) - rename libc/arch-x86_64/{ => silvermont}/string/ssse3-strncmp-slm.S (100%) - -diff --git a/libc/Android.bp b/libc/Android.bp -index f5f5f7cee..cb803a193 100644 ---- a/libc/Android.bp -+++ b/libc/Android.bp -@@ -381,6 +381,11 @@ cc_library_static { - "upstream-freebsd/lib/libc/string/wmemcmp.c", - ], - }, -+ //x86_64: { -+ // exclude_srcs: [ -+ // "upstream-freebsd/lib/libc/string/wmemset.c", -+ // ], -+ //}, - }, - - cflags: [ -@@ -698,6 +703,8 @@ cc_library_static { - - x86_64: { - exclude_srcs: [ -+ "upstream-openbsd/lib/libc/string/memchr.c", -+ "upstream-openbsd/lib/libc/string/memrchr.c", - "upstream-openbsd/lib/libc/string/stpcpy.c", - "upstream-openbsd/lib/libc/string/stpncpy.c", - "upstream-openbsd/lib/libc/string/strcat.c", -@@ -1002,20 +1009,35 @@ cc_library_static { - ], - }, - x86_64: { -+ cflags: ["-include openbsd-compat.h"], -+ include_dirs: ["bionic/libc/arch-x86_64/include"], -+ local_include_dirs: [ -+ // "private", -+ "upstream-openbsd/android/include", -+ ], - srcs: [ - "arch-x86_64/string/avx2-memset-kbl.S", -- "arch-x86_64/string/sse2-memmove-slm.S", -- "arch-x86_64/string/sse2-memset-slm.S", -- "arch-x86_64/string/sse2-stpcpy-slm.S", -- "arch-x86_64/string/sse2-stpncpy-slm.S", -- "arch-x86_64/string/sse2-strcat-slm.S", -- "arch-x86_64/string/sse2-strcpy-slm.S", -- "arch-x86_64/string/sse2-strlen-slm.S", -- "arch-x86_64/string/sse2-strncat-slm.S", -- "arch-x86_64/string/sse2-strncpy-slm.S", -- "arch-x86_64/string/sse4-memcmp-slm.S", -- "arch-x86_64/string/ssse3-strcmp-slm.S", -- "arch-x86_64/string/ssse3-strncmp-slm.S", -+ "arch-x86_64/silvermont/string/sse2-memmove-slm.S", -+ "arch-x86_64/silvermont/string/sse2-memset-slm.S", -+ "arch-x86_64/silvermont/string/sse2-stpcpy-slm.S", -+ "arch-x86_64/silvermont/string/sse2-stpncpy-slm.S", -+ "arch-x86_64/silvermont/string/sse2-strcat-slm.S", -+ "arch-x86_64/silvermont/string/sse2-strcpy-slm.S", -+ "arch-x86_64/silvermont/string/sse2-strlen-slm.S", -+ "arch-x86_64/silvermont/string/sse2-strncat-slm.S", -+ "arch-x86_64/silvermont/string/sse2-strncpy-slm.S", -+ "arch-x86_64/silvermont/string/sse4-memcmp-slm.S", -+ "arch-x86_64/silvermont/string/ssse3-strcmp-slm.S", -+ "arch-x86_64/silvermont/string/ssse3-strncmp-slm.S", -+ -+ //"arch-x86_64/generic/string/wmemset.c" -+ "arch-x86_64/generic/string/memchr.c", -+ "arch-x86_64/generic/string/memrchr.c", -+ -+ //"arch-x86_64/kabylake/string/avx2-wmemset-kbl.S" -+ "arch-x86_64/kabylake/string/avx2-memcmp-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-memchr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-memrchr-kbl.S", - - "arch-x86_64/bionic/__bionic_clone.S", - "arch-x86_64/bionic/_exit_with_stack_teardown.S", -diff --git a/libc/arch-x86/kabylake/string/avx2-memcpy-kbl.S b/libc/arch-x86/kabylake/string/avx2-memcpy-kbl.S -new file mode 100644 -index 000000000..69fca7cf1 ---- /dev/null -+++ b/libc/arch-x86/kabylake/string/avx2-memcpy-kbl.S -@@ -0,0 +1,2052 @@ -+#define ENTRY(f) \ -+ .text; \ -+ .globl f; \ -+ .p2align 4, 0x90; \ -+ .type f,@function; \ -+ f: \ -+ -+#define END(f) -+ .size f, .-f; \ -+ .section .rodata,"a",@progbits; \ -+ .p2align 2 \ -+ -+ENTRY(memcpy_avx2) -+# %bb.0: -+ pushl %ebp -+ pushl %ebx -+ pushl %edi -+ pushl %esi -+ movl 28(%esp), %ebx -+ movl 24(%esp), %ecx -+ movl 20(%esp), %eax -+ calll .L0$pb -+.L0$pb: -+ popl %esi -+.Ltmp0: -+ addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %esi -+ cmpl $256, %ebx # imm = 0x100 -+ ja .LBB0_251 -+# %bb.1: -+ leal -1(%ebx), %edi -+ cmpl $255, %edi -+ ja .LBB0_270 -+# %bb.2: -+ addl .LJTI0_1@GOTOFF(%esi,%edi,4), %esi -+ leal (%eax,%ebx), %edx -+ addl %ebx, %ecx -+ jmpl *%esi -+.LBB0_251: -+ movl %eax, %ebp -+ vmovups (%ecx), %ymm0 -+ movl %ebx, %edi -+ negl %ebp -+ andl $31, %ebp -+ subl %ebp, %edi -+ addl %ebp, %ecx -+ leal (%eax,%ebp), %edx -+ cmpl $2097152, %edi # imm = 0x200000 -+ vmovups %ymm0, (%eax) -+ ja .LBB0_256 -+# %bb.252: -+ cmpl $256, %edi # imm = 0x100 -+ jb .LBB0_260 -+# %bb.253: -+ subl %ebp, %ebx -+ .p2align 4, 0x90 -+.LBB0_254: # =>This Inner Loop Header: Depth=1 -+ vmovups (%ecx), %ymm0 -+ vmovups 32(%ecx), %ymm1 -+ vmovups 64(%ecx), %ymm2 -+ vmovups 96(%ecx), %ymm3 -+ vmovups 128(%ecx), %ymm4 -+ vmovups 160(%ecx), %ymm5 -+ vmovups 192(%ecx), %ymm6 -+ vmovups 224(%ecx), %ymm7 -+ prefetchnta 512(%ecx) -+ addl $-256, %edi -+ addl $256, %ecx # imm = 0x100 -+ vmovups %ymm0, (%edx) -+ vmovups %ymm1, 32(%edx) -+ vmovups %ymm2, 64(%edx) -+ vmovups %ymm3, 96(%edx) -+ vmovups %ymm4, 128(%edx) -+ vmovups %ymm5, 160(%edx) -+ vmovups %ymm6, 192(%edx) -+ vmovups %ymm7, 224(%edx) -+ addl $256, %edx # imm = 0x100 -+ cmpl $255, %edi -+ ja .LBB0_254 -+# %bb.255: -+ movzbl %bl, %edi -+ leal -1(%edi), %ebx -+ cmpl $255, %ebx -+ jbe .LBB0_261 -+ jmp .LBB0_270 -+.LBB0_256: -+ prefetchnta (%ecx) -+ subl %ebp, %ebx -+ testb $31, %cl -+ je .LBB0_257 -+ .p2align 4, 0x90 -+.LBB0_258: # =>This Inner Loop Header: Depth=1 -+ vmovups (%ecx), %ymm0 -+ vmovups 32(%ecx), %ymm1 -+ vmovups 64(%ecx), %ymm2 -+ vmovups 96(%ecx), %ymm3 -+ vmovups 128(%ecx), %ymm4 -+ vmovups 160(%ecx), %ymm5 -+ vmovups 192(%ecx), %ymm6 -+ vmovups 224(%ecx), %ymm7 -+ prefetchnta 512(%ecx) -+ addl $-256, %edi -+ addl $256, %ecx # imm = 0x100 -+ vmovntps %ymm0, (%edx) -+ vmovntps %ymm1, 32(%edx) -+ vmovntps %ymm2, 64(%edx) -+ vmovntps %ymm3, 96(%edx) -+ vmovntps %ymm4, 128(%edx) -+ vmovntps %ymm5, 160(%edx) -+ vmovntps %ymm6, 192(%edx) -+ vmovntps %ymm7, 224(%edx) -+ addl $256, %edx # imm = 0x100 -+ cmpl $255, %edi -+ ja .LBB0_258 -+ jmp .LBB0_259 -+ .p2align 4, 0x90 -+.LBB0_257: # =>This Inner Loop Header: Depth=1 -+ vmovaps (%ecx), %ymm0 -+ vmovaps 32(%ecx), %ymm1 -+ vmovaps 64(%ecx), %ymm2 -+ vmovaps 96(%ecx), %ymm3 -+ vmovaps 128(%ecx), %ymm4 -+ vmovaps 160(%ecx), %ymm5 -+ vmovaps 192(%ecx), %ymm6 -+ vmovaps 224(%ecx), %ymm7 -+ prefetchnta 512(%ecx) -+ addl $-256, %edi -+ addl $256, %ecx # imm = 0x100 -+ vmovntps %ymm0, (%edx) -+ vmovntps %ymm1, 32(%edx) -+ vmovntps %ymm2, 64(%edx) -+ vmovntps %ymm3, 96(%edx) -+ vmovntps %ymm4, 128(%edx) -+ vmovntps %ymm5, 160(%edx) -+ vmovntps %ymm6, 192(%edx) -+ vmovntps %ymm7, 224(%edx) -+ addl $256, %edx # imm = 0x100 -+ cmpl $255, %edi -+ ja .LBB0_257 -+.LBB0_259: -+ sfence -+ movzbl %bl, %edi -+.LBB0_260: -+ leal -1(%edi), %ebx -+ cmpl $255, %ebx -+ ja .LBB0_270 -+.LBB0_261: -+ addl .LJTI0_0@GOTOFF(%esi,%ebx,4), %esi -+ addl %edi, %edx -+ addl %edi, %ecx -+ jmpl *%esi -+.LBB0_11: -+ vmovups -131(%ecx), %ymm0 -+ vmovups %ymm0, -131(%edx) -+ vmovups -99(%ecx), %ymm0 -+ vmovups %ymm0, -99(%edx) -+ vmovups -67(%ecx), %ymm0 -+ vmovups %ymm0, -67(%edx) -+ vmovups -35(%ecx), %ymm0 -+ vmovups %ymm0, -35(%edx) -+.LBB0_12: -+ movzwl -3(%ecx), %esi -+ movw %si, -3(%edx) -+ jmp .LBB0_6 -+.LBB0_17: -+ vmovups -133(%ecx), %ymm0 -+ vmovups %ymm0, -133(%edx) -+ vmovups -101(%ecx), %ymm0 -+ vmovups %ymm0, -101(%edx) -+ vmovups -69(%ecx), %ymm0 -+ vmovups %ymm0, -69(%edx) -+ vmovups -37(%ecx), %ymm0 -+ vmovups %ymm0, -37(%edx) -+.LBB0_18: -+ movl -5(%ecx), %esi -+ movl %esi, -5(%edx) -+ jmp .LBB0_6 -+.LBB0_19: -+ vmovups -134(%ecx), %ymm0 -+ vmovups %ymm0, -134(%edx) -+ vmovups -102(%ecx), %ymm0 -+ vmovups %ymm0, -102(%edx) -+ vmovups -70(%ecx), %ymm0 -+ vmovups %ymm0, -70(%edx) -+ vmovups -38(%ecx), %ymm0 -+ vmovups %ymm0, -38(%edx) -+.LBB0_20: -+ movl -6(%ecx), %esi -+ movl %esi, -6(%edx) -+ jmp .LBB0_10 -+.LBB0_21: -+ vmovups -135(%ecx), %ymm0 -+ vmovups %ymm0, -135(%edx) -+ vmovups -103(%ecx), %ymm0 -+ vmovups %ymm0, -103(%edx) -+ vmovups -71(%ecx), %ymm0 -+ vmovups %ymm0, -71(%edx) -+ vmovups -39(%ecx), %ymm0 -+ vmovups %ymm0, -39(%edx) -+.LBB0_22: -+ movl -7(%ecx), %esi -+ movl %esi, -7(%edx) -+ jmp .LBB0_16 -+.LBB0_27: -+ vmovups -137(%ecx), %ymm0 -+ vmovups %ymm0, -137(%edx) -+ vmovups -105(%ecx), %ymm0 -+ vmovups %ymm0, -105(%edx) -+ vmovups -73(%ecx), %ymm0 -+ vmovups %ymm0, -73(%edx) -+ vmovups -41(%ecx), %ymm0 -+ vmovups %ymm0, -41(%edx) -+.LBB0_28: -+ vmovsd -9(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -9(%edx) -+ jmp .LBB0_6 -+.LBB0_29: -+ vmovups -138(%ecx), %ymm0 -+ vmovups %ymm0, -138(%edx) -+ vmovups -106(%ecx), %ymm0 -+ vmovups %ymm0, -106(%edx) -+ vmovups -74(%ecx), %ymm0 -+ vmovups %ymm0, -74(%edx) -+ vmovups -42(%ecx), %ymm0 -+ vmovups %ymm0, -42(%edx) -+.LBB0_30: -+ vmovsd -10(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -10(%edx) -+ jmp .LBB0_10 -+.LBB0_31: -+ vmovups -139(%ecx), %ymm0 -+ vmovups %ymm0, -139(%edx) -+ vmovups -107(%ecx), %ymm0 -+ vmovups %ymm0, -107(%edx) -+ vmovups -75(%ecx), %ymm0 -+ vmovups %ymm0, -75(%edx) -+ vmovups -43(%ecx), %ymm0 -+ vmovups %ymm0, -43(%edx) -+.LBB0_32: -+ vmovsd -11(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -11(%edx) -+ jmp .LBB0_16 -+.LBB0_33: -+ vmovups -140(%ecx), %ymm0 -+ vmovups %ymm0, -140(%edx) -+ vmovups -108(%ecx), %ymm0 -+ vmovups %ymm0, -108(%edx) -+ vmovups -76(%ecx), %ymm0 -+ vmovups %ymm0, -76(%edx) -+ vmovups -44(%ecx), %ymm0 -+ vmovups %ymm0, -44(%edx) -+.LBB0_34: -+ vmovsd -12(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -12(%edx) -+ jmp .LBB0_16 -+.LBB0_35: -+ vmovups -141(%ecx), %ymm0 -+ vmovups %ymm0, -141(%edx) -+ vmovups -109(%ecx), %ymm0 -+ vmovups %ymm0, -109(%edx) -+ vmovups -77(%ecx), %ymm0 -+ vmovups %ymm0, -77(%edx) -+ vmovups -45(%ecx), %ymm0 -+ vmovups %ymm0, -45(%edx) -+.LBB0_36: -+ vmovsd -13(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -13(%edx) -+ jmp .LBB0_26 -+.LBB0_37: -+ vmovups -142(%ecx), %ymm0 -+ vmovups %ymm0, -142(%edx) -+ vmovups -110(%ecx), %ymm0 -+ vmovups %ymm0, -110(%edx) -+ vmovups -78(%ecx), %ymm0 -+ vmovups %ymm0, -78(%edx) -+ vmovups -46(%ecx), %ymm0 -+ vmovups %ymm0, -46(%edx) -+.LBB0_38: -+ vmovsd -14(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -14(%edx) -+ jmp .LBB0_26 -+.LBB0_39: -+ vmovups -143(%ecx), %ymm0 -+ vmovups %ymm0, -143(%edx) -+ vmovups -111(%ecx), %ymm0 -+ vmovups %ymm0, -111(%edx) -+ vmovups -79(%ecx), %ymm0 -+ vmovups %ymm0, -79(%edx) -+ vmovups -47(%ecx), %ymm0 -+ vmovups %ymm0, -47(%edx) -+.LBB0_40: -+ vmovsd -15(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -15(%edx) -+ jmp .LBB0_26 -+.LBB0_45: -+ vmovups -145(%ecx), %ymm0 -+ vmovups %ymm0, -145(%edx) -+ vmovups -113(%ecx), %ymm0 -+ vmovups %ymm0, -113(%edx) -+ vmovups -81(%ecx), %ymm0 -+ vmovups %ymm0, -81(%edx) -+ vmovups -49(%ecx), %ymm0 -+ vmovups %ymm0, -49(%edx) -+.LBB0_46: -+ vmovups -17(%ecx), %xmm0 -+ vmovups %xmm0, -17(%edx) -+ jmp .LBB0_6 -+.LBB0_47: -+ vmovups -146(%ecx), %ymm0 -+ vmovups %ymm0, -146(%edx) -+ vmovups -114(%ecx), %ymm0 -+ vmovups %ymm0, -114(%edx) -+ vmovups -82(%ecx), %ymm0 -+ vmovups %ymm0, -82(%edx) -+ vmovups -50(%ecx), %ymm0 -+ vmovups %ymm0, -50(%edx) -+.LBB0_48: -+ vmovups -18(%ecx), %xmm0 -+ vmovups %xmm0, -18(%edx) -+ jmp .LBB0_10 -+.LBB0_49: -+ vmovups -147(%ecx), %ymm0 -+ vmovups %ymm0, -147(%edx) -+ vmovups -115(%ecx), %ymm0 -+ vmovups %ymm0, -115(%edx) -+ vmovups -83(%ecx), %ymm0 -+ vmovups %ymm0, -83(%edx) -+ vmovups -51(%ecx), %ymm0 -+ vmovups %ymm0, -51(%edx) -+.LBB0_50: -+ vmovups -19(%ecx), %xmm0 -+ vmovups %xmm0, -19(%edx) -+ jmp .LBB0_16 -+.LBB0_51: -+ vmovups -148(%ecx), %ymm0 -+ vmovups %ymm0, -148(%edx) -+ vmovups -116(%ecx), %ymm0 -+ vmovups %ymm0, -116(%edx) -+ vmovups -84(%ecx), %ymm0 -+ vmovups %ymm0, -84(%edx) -+ vmovups -52(%ecx), %ymm0 -+ vmovups %ymm0, -52(%edx) -+.LBB0_52: -+ vmovups -20(%ecx), %xmm0 -+ vmovups %xmm0, -20(%edx) -+ jmp .LBB0_16 -+.LBB0_53: -+ vmovups -149(%ecx), %ymm0 -+ vmovups %ymm0, -149(%edx) -+ vmovups -117(%ecx), %ymm0 -+ vmovups %ymm0, -117(%edx) -+ vmovups -85(%ecx), %ymm0 -+ vmovups %ymm0, -85(%edx) -+ vmovups -53(%ecx), %ymm0 -+ vmovups %ymm0, -53(%edx) -+.LBB0_54: -+ vmovups -21(%ecx), %xmm0 -+ vmovups %xmm0, -21(%edx) -+ jmp .LBB0_26 -+.LBB0_55: -+ vmovups -150(%ecx), %ymm0 -+ vmovups %ymm0, -150(%edx) -+ vmovups -118(%ecx), %ymm0 -+ vmovups %ymm0, -118(%edx) -+ vmovups -86(%ecx), %ymm0 -+ vmovups %ymm0, -86(%edx) -+ vmovups -54(%ecx), %ymm0 -+ vmovups %ymm0, -54(%edx) -+.LBB0_56: -+ vmovups -22(%ecx), %xmm0 -+ vmovups %xmm0, -22(%edx) -+ jmp .LBB0_26 -+.LBB0_57: -+ vmovups -151(%ecx), %ymm0 -+ vmovups %ymm0, -151(%edx) -+ vmovups -119(%ecx), %ymm0 -+ vmovups %ymm0, -119(%edx) -+ vmovups -87(%ecx), %ymm0 -+ vmovups %ymm0, -87(%edx) -+ vmovups -55(%ecx), %ymm0 -+ vmovups %ymm0, -55(%edx) -+.LBB0_58: -+ vmovups -23(%ecx), %xmm0 -+ vmovups %xmm0, -23(%edx) -+ jmp .LBB0_26 -+.LBB0_59: -+ vmovups -152(%ecx), %ymm0 -+ vmovups %ymm0, -152(%edx) -+ vmovups -120(%ecx), %ymm0 -+ vmovups %ymm0, -120(%edx) -+ vmovups -88(%ecx), %ymm0 -+ vmovups %ymm0, -88(%edx) -+ vmovups -56(%ecx), %ymm0 -+ vmovups %ymm0, -56(%edx) -+.LBB0_60: -+ vmovups -24(%ecx), %xmm0 -+ vmovups %xmm0, -24(%edx) -+ jmp .LBB0_26 -+.LBB0_61: -+ vmovups -153(%ecx), %ymm0 -+ vmovups %ymm0, -153(%edx) -+ vmovups -121(%ecx), %ymm0 -+ vmovups %ymm0, -121(%edx) -+ vmovups -89(%ecx), %ymm0 -+ vmovups %ymm0, -89(%edx) -+ vmovups -57(%ecx), %ymm0 -+ vmovups %ymm0, -57(%edx) -+.LBB0_62: -+ vmovups -25(%ecx), %xmm0 -+ vmovups %xmm0, -25(%edx) -+ jmp .LBB0_44 -+.LBB0_63: -+ vmovups -154(%ecx), %ymm0 -+ vmovups %ymm0, -154(%edx) -+ vmovups -122(%ecx), %ymm0 -+ vmovups %ymm0, -122(%edx) -+ vmovups -90(%ecx), %ymm0 -+ vmovups %ymm0, -90(%edx) -+ vmovups -58(%ecx), %ymm0 -+ vmovups %ymm0, -58(%edx) -+.LBB0_64: -+ vmovups -26(%ecx), %xmm0 -+ vmovups %xmm0, -26(%edx) -+ jmp .LBB0_44 -+.LBB0_65: -+ vmovups -155(%ecx), %ymm0 -+ vmovups %ymm0, -155(%edx) -+ vmovups -123(%ecx), %ymm0 -+ vmovups %ymm0, -123(%edx) -+ vmovups -91(%ecx), %ymm0 -+ vmovups %ymm0, -91(%edx) -+ vmovups -59(%ecx), %ymm0 -+ vmovups %ymm0, -59(%edx) -+.LBB0_66: -+ vmovups -27(%ecx), %xmm0 -+ vmovups %xmm0, -27(%edx) -+ jmp .LBB0_44 -+.LBB0_67: -+ vmovups -156(%ecx), %ymm0 -+ vmovups %ymm0, -156(%edx) -+ vmovups -124(%ecx), %ymm0 -+ vmovups %ymm0, -124(%edx) -+ vmovups -92(%ecx), %ymm0 -+ vmovups %ymm0, -92(%edx) -+ vmovups -60(%ecx), %ymm0 -+ vmovups %ymm0, -60(%edx) -+.LBB0_68: -+ vmovups -28(%ecx), %xmm0 -+ vmovups %xmm0, -28(%edx) -+ jmp .LBB0_44 -+.LBB0_69: -+ vmovups -157(%ecx), %ymm0 -+ vmovups %ymm0, -157(%edx) -+ vmovups -125(%ecx), %ymm0 -+ vmovups %ymm0, -125(%edx) -+ vmovups -93(%ecx), %ymm0 -+ vmovups %ymm0, -93(%edx) -+ vmovups -61(%ecx), %ymm0 -+ vmovups %ymm0, -61(%edx) -+.LBB0_70: -+ vmovups -29(%ecx), %xmm0 -+ vmovups %xmm0, -29(%edx) -+ jmp .LBB0_44 -+.LBB0_71: -+ vmovups -158(%ecx), %ymm0 -+ vmovups %ymm0, -158(%edx) -+ vmovups -126(%ecx), %ymm0 -+ vmovups %ymm0, -126(%edx) -+ vmovups -94(%ecx), %ymm0 -+ vmovups %ymm0, -94(%edx) -+ vmovups -62(%ecx), %ymm0 -+ vmovups %ymm0, -62(%edx) -+.LBB0_72: -+ vmovups -30(%ecx), %xmm0 -+ vmovups %xmm0, -30(%edx) -+ jmp .LBB0_44 -+.LBB0_73: -+ vmovups -159(%ecx), %ymm0 -+ vmovups %ymm0, -159(%edx) -+ vmovups -127(%ecx), %ymm0 -+ vmovups %ymm0, -127(%edx) -+ vmovups -95(%ecx), %ymm0 -+ vmovups %ymm0, -95(%edx) -+ vmovups -63(%ecx), %ymm0 -+ vmovups %ymm0, -63(%edx) -+.LBB0_74: -+ vmovups -31(%ecx), %xmm0 -+ vmovups %xmm0, -31(%edx) -+ jmp .LBB0_44 -+.LBB0_75: -+ vmovups -193(%ecx), %ymm0 -+ vmovups %ymm0, -193(%edx) -+.LBB0_76: -+ vmovups -161(%ecx), %ymm0 -+ vmovups %ymm0, -161(%edx) -+.LBB0_3: -+ vmovups -129(%ecx), %ymm0 -+ vmovups %ymm0, -129(%edx) -+ vmovups -97(%ecx), %ymm0 -+ vmovups %ymm0, -97(%edx) -+.LBB0_4: -+ vmovups -65(%ecx), %ymm0 -+ vmovups %ymm0, -65(%edx) -+.LBB0_5: -+ vmovups -33(%ecx), %ymm0 -+ vmovups %ymm0, -33(%edx) -+.LBB0_6: -+ movb -1(%ecx), %cl -+ movb %cl, -1(%edx) -+ jmp .LBB0_270 -+.LBB0_77: -+ vmovups -194(%ecx), %ymm0 -+ vmovups %ymm0, -194(%edx) -+.LBB0_78: -+ vmovups -162(%ecx), %ymm0 -+ vmovups %ymm0, -162(%edx) -+.LBB0_7: -+ vmovups -130(%ecx), %ymm0 -+ vmovups %ymm0, -130(%edx) -+ vmovups -98(%ecx), %ymm0 -+ vmovups %ymm0, -98(%edx) -+.LBB0_8: -+ vmovups -66(%ecx), %ymm0 -+ vmovups %ymm0, -66(%edx) -+.LBB0_9: -+ vmovups -34(%ecx), %ymm0 -+ vmovups %ymm0, -34(%edx) -+.LBB0_10: -+ movzwl -2(%ecx), %ecx -+ movw %cx, -2(%edx) -+ jmp .LBB0_270 -+.LBB0_79: -+ vmovups -195(%ecx), %ymm0 -+ vmovups %ymm0, -195(%edx) -+.LBB0_80: -+ vmovups -163(%ecx), %ymm0 -+ vmovups %ymm0, -163(%edx) -+ vmovups -131(%ecx), %ymm0 -+ vmovups %ymm0, -131(%edx) -+ vmovups -99(%ecx), %ymm0 -+ vmovups %ymm0, -99(%edx) -+.LBB0_81: -+ vmovups -67(%ecx), %ymm0 -+ vmovups %ymm0, -67(%edx) -+.LBB0_82: -+ vmovups -35(%ecx), %ymm0 -+ vmovups %ymm0, -35(%edx) -+ jmp .LBB0_16 -+.LBB0_83: -+ vmovups -196(%ecx), %ymm0 -+ vmovups %ymm0, -196(%edx) -+.LBB0_84: -+ vmovups -164(%ecx), %ymm0 -+ vmovups %ymm0, -164(%edx) -+.LBB0_13: -+ vmovups -132(%ecx), %ymm0 -+ vmovups %ymm0, -132(%edx) -+ vmovups -100(%ecx), %ymm0 -+ vmovups %ymm0, -100(%edx) -+.LBB0_14: -+ vmovups -68(%ecx), %ymm0 -+ vmovups %ymm0, -68(%edx) -+.LBB0_15: -+ vmovups -36(%ecx), %ymm0 -+ vmovups %ymm0, -36(%edx) -+.LBB0_16: -+ movl -4(%ecx), %ecx -+ movl %ecx, -4(%edx) -+ jmp .LBB0_270 -+.LBB0_85: -+ vmovups -197(%ecx), %ymm0 -+ vmovups %ymm0, -197(%edx) -+.LBB0_86: -+ vmovups -165(%ecx), %ymm0 -+ vmovups %ymm0, -165(%edx) -+ vmovups -133(%ecx), %ymm0 -+ vmovups %ymm0, -133(%edx) -+ vmovups -101(%ecx), %ymm0 -+ vmovups %ymm0, -101(%edx) -+.LBB0_87: -+ vmovups -69(%ecx), %ymm0 -+ vmovups %ymm0, -69(%edx) -+.LBB0_88: -+ vmovups -37(%ecx), %ymm0 -+ vmovups %ymm0, -37(%edx) -+ jmp .LBB0_26 -+.LBB0_89: -+ vmovups -198(%ecx), %ymm0 -+ vmovups %ymm0, -198(%edx) -+.LBB0_90: -+ vmovups -166(%ecx), %ymm0 -+ vmovups %ymm0, -166(%edx) -+ vmovups -134(%ecx), %ymm0 -+ vmovups %ymm0, -134(%edx) -+ vmovups -102(%ecx), %ymm0 -+ vmovups %ymm0, -102(%edx) -+.LBB0_91: -+ vmovups -70(%ecx), %ymm0 -+ vmovups %ymm0, -70(%edx) -+.LBB0_92: -+ vmovups -38(%ecx), %ymm0 -+ vmovups %ymm0, -38(%edx) -+ jmp .LBB0_26 -+.LBB0_93: -+ vmovups -199(%ecx), %ymm0 -+ vmovups %ymm0, -199(%edx) -+.LBB0_94: -+ vmovups -167(%ecx), %ymm0 -+ vmovups %ymm0, -167(%edx) -+ vmovups -135(%ecx), %ymm0 -+ vmovups %ymm0, -135(%edx) -+ vmovups -103(%ecx), %ymm0 -+ vmovups %ymm0, -103(%edx) -+.LBB0_95: -+ vmovups -71(%ecx), %ymm0 -+ vmovups %ymm0, -71(%edx) -+.LBB0_96: -+ vmovups -39(%ecx), %ymm0 -+ vmovups %ymm0, -39(%edx) -+ jmp .LBB0_26 -+.LBB0_97: -+ vmovups -200(%ecx), %ymm0 -+ vmovups %ymm0, -200(%edx) -+.LBB0_98: -+ vmovups -168(%ecx), %ymm0 -+ vmovups %ymm0, -168(%edx) -+.LBB0_23: -+ vmovups -136(%ecx), %ymm0 -+ vmovups %ymm0, -136(%edx) -+ vmovups -104(%ecx), %ymm0 -+ vmovups %ymm0, -104(%edx) -+.LBB0_24: -+ vmovups -72(%ecx), %ymm0 -+ vmovups %ymm0, -72(%edx) -+.LBB0_25: -+ vmovups -40(%ecx), %ymm0 -+ vmovups %ymm0, -40(%edx) -+.LBB0_26: -+ vmovsd -8(%ecx), %xmm0 # xmm0 = mem[0],zero -+ vmovsd %xmm0, -8(%edx) -+ jmp .LBB0_270 -+.LBB0_99: -+ vmovups -201(%ecx), %ymm0 -+ vmovups %ymm0, -201(%edx) -+.LBB0_100: -+ vmovups -169(%ecx), %ymm0 -+ vmovups %ymm0, -169(%edx) -+ vmovups -137(%ecx), %ymm0 -+ vmovups %ymm0, -137(%edx) -+ vmovups -105(%ecx), %ymm0 -+ vmovups %ymm0, -105(%edx) -+.LBB0_101: -+ vmovups -73(%ecx), %ymm0 -+ vmovups %ymm0, -73(%edx) -+.LBB0_102: -+ vmovups -41(%ecx), %ymm0 -+ vmovups %ymm0, -41(%edx) -+ jmp .LBB0_44 -+.LBB0_103: -+ vmovups -202(%ecx), %ymm0 -+ vmovups %ymm0, -202(%edx) -+.LBB0_104: -+ vmovups -170(%ecx), %ymm0 -+ vmovups %ymm0, -170(%edx) -+ vmovups -138(%ecx), %ymm0 -+ vmovups %ymm0, -138(%edx) -+ vmovups -106(%ecx), %ymm0 -+ vmovups %ymm0, -106(%edx) -+.LBB0_105: -+ vmovups -74(%ecx), %ymm0 -+ vmovups %ymm0, -74(%edx) -+.LBB0_106: -+ vmovups -42(%ecx), %ymm0 -+ vmovups %ymm0, -42(%edx) -+ jmp .LBB0_44 -+.LBB0_107: -+ vmovups -203(%ecx), %ymm0 -+ vmovups %ymm0, -203(%edx) -+.LBB0_108: -+ vmovups -171(%ecx), %ymm0 -+ vmovups %ymm0, -171(%edx) -+ vmovups -139(%ecx), %ymm0 -+ vmovups %ymm0, -139(%edx) -+ vmovups -107(%ecx), %ymm0 -+ vmovups %ymm0, -107(%edx) -+.LBB0_109: -+ vmovups -75(%ecx), %ymm0 -+ vmovups %ymm0, -75(%edx) -+.LBB0_110: -+ vmovups -43(%ecx), %ymm0 -+ vmovups %ymm0, -43(%edx) -+ jmp .LBB0_44 -+.LBB0_111: -+ vmovups -204(%ecx), %ymm0 -+ vmovups %ymm0, -204(%edx) -+.LBB0_112: -+ vmovups -172(%ecx), %ymm0 -+ vmovups %ymm0, -172(%edx) -+ vmovups -140(%ecx), %ymm0 -+ vmovups %ymm0, -140(%edx) -+ vmovups -108(%ecx), %ymm0 -+ vmovups %ymm0, -108(%edx) -+.LBB0_113: -+ vmovups -76(%ecx), %ymm0 -+ vmovups %ymm0, -76(%edx) -+.LBB0_114: -+ vmovups -44(%ecx), %ymm0 -+ vmovups %ymm0, -44(%edx) -+ jmp .LBB0_44 -+.LBB0_115: -+ vmovups -205(%ecx), %ymm0 -+ vmovups %ymm0, -205(%edx) -+.LBB0_116: -+ vmovups -173(%ecx), %ymm0 -+ vmovups %ymm0, -173(%edx) -+ vmovups -141(%ecx), %ymm0 -+ vmovups %ymm0, -141(%edx) -+ vmovups -109(%ecx), %ymm0 -+ vmovups %ymm0, -109(%edx) -+.LBB0_117: -+ vmovups -77(%ecx), %ymm0 -+ vmovups %ymm0, -77(%edx) -+.LBB0_118: -+ vmovups -45(%ecx), %ymm0 -+ vmovups %ymm0, -45(%edx) -+ jmp .LBB0_44 -+.LBB0_119: -+ vmovups -206(%ecx), %ymm0 -+ vmovups %ymm0, -206(%edx) -+.LBB0_120: -+ vmovups -174(%ecx), %ymm0 -+ vmovups %ymm0, -174(%edx) -+ vmovups -142(%ecx), %ymm0 -+ vmovups %ymm0, -142(%edx) -+ vmovups -110(%ecx), %ymm0 -+ vmovups %ymm0, -110(%edx) -+.LBB0_121: -+ vmovups -78(%ecx), %ymm0 -+ vmovups %ymm0, -78(%edx) -+.LBB0_122: -+ vmovups -46(%ecx), %ymm0 -+ vmovups %ymm0, -46(%edx) -+ jmp .LBB0_44 -+.LBB0_123: -+ vmovups -207(%ecx), %ymm0 -+ vmovups %ymm0, -207(%edx) -+.LBB0_124: -+ vmovups -175(%ecx), %ymm0 -+ vmovups %ymm0, -175(%edx) -+ vmovups -143(%ecx), %ymm0 -+ vmovups %ymm0, -143(%edx) -+ vmovups -111(%ecx), %ymm0 -+ vmovups %ymm0, -111(%edx) -+.LBB0_125: -+ vmovups -79(%ecx), %ymm0 -+ vmovups %ymm0, -79(%edx) -+.LBB0_126: -+ vmovups -47(%ecx), %ymm0 -+ vmovups %ymm0, -47(%edx) -+ jmp .LBB0_44 -+.LBB0_127: -+ vmovups -208(%ecx), %ymm0 -+ vmovups %ymm0, -208(%edx) -+.LBB0_128: -+ vmovups -176(%ecx), %ymm0 -+ vmovups %ymm0, -176(%edx) -+.LBB0_41: -+ vmovups -144(%ecx), %ymm0 -+ vmovups %ymm0, -144(%edx) -+ vmovups -112(%ecx), %ymm0 -+ vmovups %ymm0, -112(%edx) -+.LBB0_42: -+ vmovups -80(%ecx), %ymm0 -+ vmovups %ymm0, -80(%edx) -+.LBB0_43: -+ vmovups -48(%ecx), %ymm0 -+ vmovups %ymm0, -48(%edx) -+.LBB0_44: -+ vmovups -16(%ecx), %xmm0 -+ vmovups %xmm0, -16(%edx) -+ jmp .LBB0_270 -+.LBB0_129: -+ vmovups -209(%ecx), %ymm0 -+ vmovups %ymm0, -209(%edx) -+.LBB0_130: -+ vmovups -177(%ecx), %ymm0 -+ vmovups %ymm0, -177(%edx) -+ vmovups -145(%ecx), %ymm0 -+ vmovups %ymm0, -145(%edx) -+ vmovups -113(%ecx), %ymm0 -+ vmovups %ymm0, -113(%edx) -+.LBB0_131: -+ vmovups -81(%ecx), %ymm0 -+ vmovups %ymm0, -81(%edx) -+.LBB0_132: -+ vmovups -49(%ecx), %ymm0 -+ vmovups %ymm0, -49(%edx) -+ jmp .LBB0_269 -+.LBB0_133: -+ vmovups -210(%ecx), %ymm0 -+ vmovups %ymm0, -210(%edx) -+.LBB0_134: -+ vmovups -178(%ecx), %ymm0 -+ vmovups %ymm0, -178(%edx) -+ vmovups -146(%ecx), %ymm0 -+ vmovups %ymm0, -146(%edx) -+ vmovups -114(%ecx), %ymm0 -+ vmovups %ymm0, -114(%edx) -+.LBB0_135: -+ vmovups -82(%ecx), %ymm0 -+ vmovups %ymm0, -82(%edx) -+.LBB0_136: -+ vmovups -50(%ecx), %ymm0 -+ vmovups %ymm0, -50(%edx) -+ jmp .LBB0_269 -+.LBB0_137: -+ vmovups -211(%ecx), %ymm0 -+ vmovups %ymm0, -211(%edx) -+.LBB0_138: -+ vmovups -179(%ecx), %ymm0 -+ vmovups %ymm0, -179(%edx) -+ vmovups -147(%ecx), %ymm0 -+ vmovups %ymm0, -147(%edx) -+ vmovups -115(%ecx), %ymm0 -+ vmovups %ymm0, -115(%edx) -+.LBB0_139: -+ vmovups -83(%ecx), %ymm0 -+ vmovups %ymm0, -83(%edx) -+.LBB0_140: -+ vmovups -51(%ecx), %ymm0 -+ vmovups %ymm0, -51(%edx) -+ jmp .LBB0_269 -+.LBB0_141: -+ vmovups -212(%ecx), %ymm0 -+ vmovups %ymm0, -212(%edx) -+.LBB0_142: -+ vmovups -180(%ecx), %ymm0 -+ vmovups %ymm0, -180(%edx) -+ vmovups -148(%ecx), %ymm0 -+ vmovups %ymm0, -148(%edx) -+ vmovups -116(%ecx), %ymm0 -+ vmovups %ymm0, -116(%edx) -+.LBB0_143: -+ vmovups -84(%ecx), %ymm0 -+ vmovups %ymm0, -84(%edx) -+.LBB0_144: -+ vmovups -52(%ecx), %ymm0 -+ vmovups %ymm0, -52(%edx) -+ jmp .LBB0_269 -+.LBB0_145: -+ vmovups -213(%ecx), %ymm0 -+ vmovups %ymm0, -213(%edx) -+.LBB0_146: -+ vmovups -181(%ecx), %ymm0 -+ vmovups %ymm0, -181(%edx) -+ vmovups -149(%ecx), %ymm0 -+ vmovups %ymm0, -149(%edx) -+ vmovups -117(%ecx), %ymm0 -+ vmovups %ymm0, -117(%edx) -+.LBB0_147: -+ vmovups -85(%ecx), %ymm0 -+ vmovups %ymm0, -85(%edx) -+.LBB0_148: -+ vmovups -53(%ecx), %ymm0 -+ vmovups %ymm0, -53(%edx) -+ jmp .LBB0_269 -+.LBB0_149: -+ vmovups -214(%ecx), %ymm0 -+ vmovups %ymm0, -214(%edx) -+.LBB0_150: -+ vmovups -182(%ecx), %ymm0 -+ vmovups %ymm0, -182(%edx) -+ vmovups -150(%ecx), %ymm0 -+ vmovups %ymm0, -150(%edx) -+ vmovups -118(%ecx), %ymm0 -+ vmovups %ymm0, -118(%edx) -+.LBB0_151: -+ vmovups -86(%ecx), %ymm0 -+ vmovups %ymm0, -86(%edx) -+.LBB0_152: -+ vmovups -54(%ecx), %ymm0 -+ vmovups %ymm0, -54(%edx) -+ jmp .LBB0_269 -+.LBB0_153: -+ vmovups -215(%ecx), %ymm0 -+ vmovups %ymm0, -215(%edx) -+.LBB0_154: -+ vmovups -183(%ecx), %ymm0 -+ vmovups %ymm0, -183(%edx) -+ vmovups -151(%ecx), %ymm0 -+ vmovups %ymm0, -151(%edx) -+ vmovups -119(%ecx), %ymm0 -+ vmovups %ymm0, -119(%edx) -+.LBB0_155: -+ vmovups -87(%ecx), %ymm0 -+ vmovups %ymm0, -87(%edx) -+.LBB0_156: -+ vmovups -55(%ecx), %ymm0 -+ vmovups %ymm0, -55(%edx) -+ jmp .LBB0_269 -+.LBB0_157: -+ vmovups -216(%ecx), %ymm0 -+ vmovups %ymm0, -216(%edx) -+.LBB0_158: -+ vmovups -184(%ecx), %ymm0 -+ vmovups %ymm0, -184(%edx) -+ vmovups -152(%ecx), %ymm0 -+ vmovups %ymm0, -152(%edx) -+ vmovups -120(%ecx), %ymm0 -+ vmovups %ymm0, -120(%edx) -+.LBB0_159: -+ vmovups -88(%ecx), %ymm0 -+ vmovups %ymm0, -88(%edx) -+.LBB0_160: -+ vmovups -56(%ecx), %ymm0 -+ vmovups %ymm0, -56(%edx) -+ jmp .LBB0_269 -+.LBB0_161: -+ vmovups -217(%ecx), %ymm0 -+ vmovups %ymm0, -217(%edx) -+.LBB0_162: -+ vmovups -185(%ecx), %ymm0 -+ vmovups %ymm0, -185(%edx) -+ vmovups -153(%ecx), %ymm0 -+ vmovups %ymm0, -153(%edx) -+ vmovups -121(%ecx), %ymm0 -+ vmovups %ymm0, -121(%edx) -+.LBB0_163: -+ vmovups -89(%ecx), %ymm0 -+ vmovups %ymm0, -89(%edx) -+.LBB0_164: -+ vmovups -57(%ecx), %ymm0 -+ vmovups %ymm0, -57(%edx) -+ jmp .LBB0_269 -+.LBB0_165: -+ vmovups -218(%ecx), %ymm0 -+ vmovups %ymm0, -218(%edx) -+.LBB0_166: -+ vmovups -186(%ecx), %ymm0 -+ vmovups %ymm0, -186(%edx) -+ vmovups -154(%ecx), %ymm0 -+ vmovups %ymm0, -154(%edx) -+ vmovups -122(%ecx), %ymm0 -+ vmovups %ymm0, -122(%edx) -+.LBB0_167: -+ vmovups -90(%ecx), %ymm0 -+ vmovups %ymm0, -90(%edx) -+.LBB0_168: -+ vmovups -58(%ecx), %ymm0 -+ vmovups %ymm0, -58(%edx) -+ jmp .LBB0_269 -+.LBB0_169: -+ vmovups -219(%ecx), %ymm0 -+ vmovups %ymm0, -219(%edx) -+.LBB0_170: -+ vmovups -187(%ecx), %ymm0 -+ vmovups %ymm0, -187(%edx) -+ vmovups -155(%ecx), %ymm0 -+ vmovups %ymm0, -155(%edx) -+ vmovups -123(%ecx), %ymm0 -+ vmovups %ymm0, -123(%edx) -+.LBB0_171: -+ vmovups -91(%ecx), %ymm0 -+ vmovups %ymm0, -91(%edx) -+.LBB0_172: -+ vmovups -59(%ecx), %ymm0 -+ vmovups %ymm0, -59(%edx) -+ jmp .LBB0_269 -+.LBB0_173: -+ vmovups -220(%ecx), %ymm0 -+ vmovups %ymm0, -220(%edx) -+.LBB0_174: -+ vmovups -188(%ecx), %ymm0 -+ vmovups %ymm0, -188(%edx) -+ vmovups -156(%ecx), %ymm0 -+ vmovups %ymm0, -156(%edx) -+ vmovups -124(%ecx), %ymm0 -+ vmovups %ymm0, -124(%edx) -+.LBB0_175: -+ vmovups -92(%ecx), %ymm0 -+ vmovups %ymm0, -92(%edx) -+.LBB0_176: -+ vmovups -60(%ecx), %ymm0 -+ vmovups %ymm0, -60(%edx) -+ jmp .LBB0_269 -+.LBB0_177: -+ vmovups -221(%ecx), %ymm0 -+ vmovups %ymm0, -221(%edx) -+.LBB0_178: -+ vmovups -189(%ecx), %ymm0 -+ vmovups %ymm0, -189(%edx) -+ vmovups -157(%ecx), %ymm0 -+ vmovups %ymm0, -157(%edx) -+ vmovups -125(%ecx), %ymm0 -+ vmovups %ymm0, -125(%edx) -+.LBB0_179: -+ vmovups -93(%ecx), %ymm0 -+ vmovups %ymm0, -93(%edx) -+.LBB0_180: -+ vmovups -61(%ecx), %ymm0 -+ vmovups %ymm0, -61(%edx) -+ jmp .LBB0_269 -+.LBB0_181: -+ vmovups -222(%ecx), %ymm0 -+ vmovups %ymm0, -222(%edx) -+.LBB0_182: -+ vmovups -190(%ecx), %ymm0 -+ vmovups %ymm0, -190(%edx) -+ vmovups -158(%ecx), %ymm0 -+ vmovups %ymm0, -158(%edx) -+ vmovups -126(%ecx), %ymm0 -+ vmovups %ymm0, -126(%edx) -+.LBB0_183: -+ vmovups -94(%ecx), %ymm0 -+ vmovups %ymm0, -94(%edx) -+.LBB0_184: -+ vmovups -62(%ecx), %ymm0 -+ vmovups %ymm0, -62(%edx) -+ jmp .LBB0_269 -+.LBB0_185: -+ vmovups -223(%ecx), %ymm0 -+ vmovups %ymm0, -223(%edx) -+.LBB0_186: -+ vmovups -191(%ecx), %ymm0 -+ vmovups %ymm0, -191(%edx) -+ vmovups -159(%ecx), %ymm0 -+ vmovups %ymm0, -159(%edx) -+ vmovups -127(%ecx), %ymm0 -+ vmovups %ymm0, -127(%edx) -+.LBB0_187: -+ vmovups -95(%ecx), %ymm0 -+ vmovups %ymm0, -95(%edx) -+.LBB0_188: -+ vmovups -63(%ecx), %ymm0 -+ vmovups %ymm0, -63(%edx) -+ jmp .LBB0_269 -+.LBB0_189: -+ vmovups -225(%ecx), %ymm0 -+ vmovups %ymm0, -225(%edx) -+ vmovups -193(%ecx), %ymm0 -+ vmovups %ymm0, -193(%edx) -+ vmovups -161(%ecx), %ymm0 -+ vmovups %ymm0, -161(%edx) -+ vmovups -129(%ecx), %ymm0 -+ vmovups %ymm0, -129(%edx) -+.LBB0_190: -+ vmovups -97(%ecx), %ymm0 -+ vmovups %ymm0, -97(%edx) -+ vmovups -65(%ecx), %ymm0 -+ vmovups %ymm0, -65(%edx) -+ jmp .LBB0_268 -+.LBB0_191: -+ vmovups -226(%ecx), %ymm0 -+ vmovups %ymm0, -226(%edx) -+ vmovups -194(%ecx), %ymm0 -+ vmovups %ymm0, -194(%edx) -+ vmovups -162(%ecx), %ymm0 -+ vmovups %ymm0, -162(%edx) -+ vmovups -130(%ecx), %ymm0 -+ vmovups %ymm0, -130(%edx) -+.LBB0_192: -+ vmovups -98(%ecx), %ymm0 -+ vmovups %ymm0, -98(%edx) -+ vmovups -66(%ecx), %ymm0 -+ vmovups %ymm0, -66(%edx) -+ jmp .LBB0_268 -+.LBB0_193: -+ vmovups -227(%ecx), %ymm0 -+ vmovups %ymm0, -227(%edx) -+ vmovups -195(%ecx), %ymm0 -+ vmovups %ymm0, -195(%edx) -+ vmovups -163(%ecx), %ymm0 -+ vmovups %ymm0, -163(%edx) -+ vmovups -131(%ecx), %ymm0 -+ vmovups %ymm0, -131(%edx) -+.LBB0_194: -+ vmovups -99(%ecx), %ymm0 -+ vmovups %ymm0, -99(%edx) -+ vmovups -67(%ecx), %ymm0 -+ vmovups %ymm0, -67(%edx) -+ jmp .LBB0_268 -+.LBB0_195: -+ vmovups -228(%ecx), %ymm0 -+ vmovups %ymm0, -228(%edx) -+ vmovups -196(%ecx), %ymm0 -+ vmovups %ymm0, -196(%edx) -+ vmovups -164(%ecx), %ymm0 -+ vmovups %ymm0, -164(%edx) -+ vmovups -132(%ecx), %ymm0 -+ vmovups %ymm0, -132(%edx) -+.LBB0_196: -+ vmovups -100(%ecx), %ymm0 -+ vmovups %ymm0, -100(%edx) -+ vmovups -68(%ecx), %ymm0 -+ vmovups %ymm0, -68(%edx) -+ jmp .LBB0_268 -+.LBB0_197: -+ vmovups -229(%ecx), %ymm0 -+ vmovups %ymm0, -229(%edx) -+ vmovups -197(%ecx), %ymm0 -+ vmovups %ymm0, -197(%edx) -+ vmovups -165(%ecx), %ymm0 -+ vmovups %ymm0, -165(%edx) -+ vmovups -133(%ecx), %ymm0 -+ vmovups %ymm0, -133(%edx) -+.LBB0_198: -+ vmovups -101(%ecx), %ymm0 -+ vmovups %ymm0, -101(%edx) -+ vmovups -69(%ecx), %ymm0 -+ vmovups %ymm0, -69(%edx) -+ jmp .LBB0_268 -+.LBB0_199: -+ vmovups -230(%ecx), %ymm0 -+ vmovups %ymm0, -230(%edx) -+ vmovups -198(%ecx), %ymm0 -+ vmovups %ymm0, -198(%edx) -+ vmovups -166(%ecx), %ymm0 -+ vmovups %ymm0, -166(%edx) -+ vmovups -134(%ecx), %ymm0 -+ vmovups %ymm0, -134(%edx) -+.LBB0_200: -+ vmovups -102(%ecx), %ymm0 -+ vmovups %ymm0, -102(%edx) -+ vmovups -70(%ecx), %ymm0 -+ vmovups %ymm0, -70(%edx) -+ jmp .LBB0_268 -+.LBB0_201: -+ vmovups -231(%ecx), %ymm0 -+ vmovups %ymm0, -231(%edx) -+ vmovups -199(%ecx), %ymm0 -+ vmovups %ymm0, -199(%edx) -+ vmovups -167(%ecx), %ymm0 -+ vmovups %ymm0, -167(%edx) -+ vmovups -135(%ecx), %ymm0 -+ vmovups %ymm0, -135(%edx) -+.LBB0_202: -+ vmovups -103(%ecx), %ymm0 -+ vmovups %ymm0, -103(%edx) -+ vmovups -71(%ecx), %ymm0 -+ vmovups %ymm0, -71(%edx) -+ jmp .LBB0_268 -+.LBB0_203: -+ vmovups -232(%ecx), %ymm0 -+ vmovups %ymm0, -232(%edx) -+ vmovups -200(%ecx), %ymm0 -+ vmovups %ymm0, -200(%edx) -+ vmovups -168(%ecx), %ymm0 -+ vmovups %ymm0, -168(%edx) -+ vmovups -136(%ecx), %ymm0 -+ vmovups %ymm0, -136(%edx) -+.LBB0_204: -+ vmovups -104(%ecx), %ymm0 -+ vmovups %ymm0, -104(%edx) -+ vmovups -72(%ecx), %ymm0 -+ vmovups %ymm0, -72(%edx) -+ jmp .LBB0_268 -+.LBB0_205: -+ vmovups -233(%ecx), %ymm0 -+ vmovups %ymm0, -233(%edx) -+ vmovups -201(%ecx), %ymm0 -+ vmovups %ymm0, -201(%edx) -+ vmovups -169(%ecx), %ymm0 -+ vmovups %ymm0, -169(%edx) -+ vmovups -137(%ecx), %ymm0 -+ vmovups %ymm0, -137(%edx) -+.LBB0_206: -+ vmovups -105(%ecx), %ymm0 -+ vmovups %ymm0, -105(%edx) -+ vmovups -73(%ecx), %ymm0 -+ vmovups %ymm0, -73(%edx) -+ jmp .LBB0_268 -+.LBB0_207: -+ vmovups -234(%ecx), %ymm0 -+ vmovups %ymm0, -234(%edx) -+ vmovups -202(%ecx), %ymm0 -+ vmovups %ymm0, -202(%edx) -+ vmovups -170(%ecx), %ymm0 -+ vmovups %ymm0, -170(%edx) -+ vmovups -138(%ecx), %ymm0 -+ vmovups %ymm0, -138(%edx) -+.LBB0_208: -+ vmovups -106(%ecx), %ymm0 -+ vmovups %ymm0, -106(%edx) -+ vmovups -74(%ecx), %ymm0 -+ vmovups %ymm0, -74(%edx) -+ jmp .LBB0_268 -+.LBB0_209: -+ vmovups -235(%ecx), %ymm0 -+ vmovups %ymm0, -235(%edx) -+ vmovups -203(%ecx), %ymm0 -+ vmovups %ymm0, -203(%edx) -+ vmovups -171(%ecx), %ymm0 -+ vmovups %ymm0, -171(%edx) -+ vmovups -139(%ecx), %ymm0 -+ vmovups %ymm0, -139(%edx) -+.LBB0_210: -+ vmovups -107(%ecx), %ymm0 -+ vmovups %ymm0, -107(%edx) -+ vmovups -75(%ecx), %ymm0 -+ vmovups %ymm0, -75(%edx) -+ jmp .LBB0_268 -+.LBB0_211: -+ vmovups -236(%ecx), %ymm0 -+ vmovups %ymm0, -236(%edx) -+ vmovups -204(%ecx), %ymm0 -+ vmovups %ymm0, -204(%edx) -+ vmovups -172(%ecx), %ymm0 -+ vmovups %ymm0, -172(%edx) -+ vmovups -140(%ecx), %ymm0 -+ vmovups %ymm0, -140(%edx) -+.LBB0_212: -+ vmovups -108(%ecx), %ymm0 -+ vmovups %ymm0, -108(%edx) -+ vmovups -76(%ecx), %ymm0 -+ vmovups %ymm0, -76(%edx) -+ jmp .LBB0_268 -+.LBB0_213: -+ vmovups -237(%ecx), %ymm0 -+ vmovups %ymm0, -237(%edx) -+ vmovups -205(%ecx), %ymm0 -+ vmovups %ymm0, -205(%edx) -+ vmovups -173(%ecx), %ymm0 -+ vmovups %ymm0, -173(%edx) -+ vmovups -141(%ecx), %ymm0 -+ vmovups %ymm0, -141(%edx) -+.LBB0_214: -+ vmovups -109(%ecx), %ymm0 -+ vmovups %ymm0, -109(%edx) -+ vmovups -77(%ecx), %ymm0 -+ vmovups %ymm0, -77(%edx) -+ jmp .LBB0_268 -+.LBB0_215: -+ vmovups -238(%ecx), %ymm0 -+ vmovups %ymm0, -238(%edx) -+ vmovups -206(%ecx), %ymm0 -+ vmovups %ymm0, -206(%edx) -+ vmovups -174(%ecx), %ymm0 -+ vmovups %ymm0, -174(%edx) -+ vmovups -142(%ecx), %ymm0 -+ vmovups %ymm0, -142(%edx) -+.LBB0_216: -+ vmovups -110(%ecx), %ymm0 -+ vmovups %ymm0, -110(%edx) -+ vmovups -78(%ecx), %ymm0 -+ vmovups %ymm0, -78(%edx) -+ jmp .LBB0_268 -+.LBB0_217: -+ vmovups -239(%ecx), %ymm0 -+ vmovups %ymm0, -239(%edx) -+ vmovups -207(%ecx), %ymm0 -+ vmovups %ymm0, -207(%edx) -+ vmovups -175(%ecx), %ymm0 -+ vmovups %ymm0, -175(%edx) -+ vmovups -143(%ecx), %ymm0 -+ vmovups %ymm0, -143(%edx) -+.LBB0_218: -+ vmovups -111(%ecx), %ymm0 -+ vmovups %ymm0, -111(%edx) -+ vmovups -79(%ecx), %ymm0 -+ vmovups %ymm0, -79(%edx) -+ jmp .LBB0_268 -+.LBB0_219: -+ vmovups -240(%ecx), %ymm0 -+ vmovups %ymm0, -240(%edx) -+ vmovups -208(%ecx), %ymm0 -+ vmovups %ymm0, -208(%edx) -+ vmovups -176(%ecx), %ymm0 -+ vmovups %ymm0, -176(%edx) -+ vmovups -144(%ecx), %ymm0 -+ vmovups %ymm0, -144(%edx) -+.LBB0_220: -+ vmovups -112(%ecx), %ymm0 -+ vmovups %ymm0, -112(%edx) -+ vmovups -80(%ecx), %ymm0 -+ vmovups %ymm0, -80(%edx) -+ jmp .LBB0_268 -+.LBB0_221: -+ vmovups -241(%ecx), %ymm0 -+ vmovups %ymm0, -241(%edx) -+ vmovups -209(%ecx), %ymm0 -+ vmovups %ymm0, -209(%edx) -+ vmovups -177(%ecx), %ymm0 -+ vmovups %ymm0, -177(%edx) -+ vmovups -145(%ecx), %ymm0 -+ vmovups %ymm0, -145(%edx) -+.LBB0_222: -+ vmovups -113(%ecx), %ymm0 -+ vmovups %ymm0, -113(%edx) -+ vmovups -81(%ecx), %ymm0 -+ vmovups %ymm0, -81(%edx) -+ jmp .LBB0_268 -+.LBB0_223: -+ vmovups -242(%ecx), %ymm0 -+ vmovups %ymm0, -242(%edx) -+ vmovups -210(%ecx), %ymm0 -+ vmovups %ymm0, -210(%edx) -+ vmovups -178(%ecx), %ymm0 -+ vmovups %ymm0, -178(%edx) -+ vmovups -146(%ecx), %ymm0 -+ vmovups %ymm0, -146(%edx) -+.LBB0_224: -+ vmovups -114(%ecx), %ymm0 -+ vmovups %ymm0, -114(%edx) -+ vmovups -82(%ecx), %ymm0 -+ vmovups %ymm0, -82(%edx) -+ jmp .LBB0_268 -+.LBB0_225: -+ vmovups -243(%ecx), %ymm0 -+ vmovups %ymm0, -243(%edx) -+ vmovups -211(%ecx), %ymm0 -+ vmovups %ymm0, -211(%edx) -+ vmovups -179(%ecx), %ymm0 -+ vmovups %ymm0, -179(%edx) -+ vmovups -147(%ecx), %ymm0 -+ vmovups %ymm0, -147(%edx) -+.LBB0_226: -+ vmovups -115(%ecx), %ymm0 -+ vmovups %ymm0, -115(%edx) -+ vmovups -83(%ecx), %ymm0 -+ vmovups %ymm0, -83(%edx) -+ jmp .LBB0_268 -+.LBB0_227: -+ vmovups -244(%ecx), %ymm0 -+ vmovups %ymm0, -244(%edx) -+ vmovups -212(%ecx), %ymm0 -+ vmovups %ymm0, -212(%edx) -+ vmovups -180(%ecx), %ymm0 -+ vmovups %ymm0, -180(%edx) -+ vmovups -148(%ecx), %ymm0 -+ vmovups %ymm0, -148(%edx) -+.LBB0_228: -+ vmovups -116(%ecx), %ymm0 -+ vmovups %ymm0, -116(%edx) -+ vmovups -84(%ecx), %ymm0 -+ vmovups %ymm0, -84(%edx) -+ jmp .LBB0_268 -+.LBB0_229: -+ vmovups -245(%ecx), %ymm0 -+ vmovups %ymm0, -245(%edx) -+ vmovups -213(%ecx), %ymm0 -+ vmovups %ymm0, -213(%edx) -+ vmovups -181(%ecx), %ymm0 -+ vmovups %ymm0, -181(%edx) -+ vmovups -149(%ecx), %ymm0 -+ vmovups %ymm0, -149(%edx) -+.LBB0_230: -+ vmovups -117(%ecx), %ymm0 -+ vmovups %ymm0, -117(%edx) -+ vmovups -85(%ecx), %ymm0 -+ vmovups %ymm0, -85(%edx) -+ jmp .LBB0_268 -+.LBB0_231: -+ vmovups -246(%ecx), %ymm0 -+ vmovups %ymm0, -246(%edx) -+ vmovups -214(%ecx), %ymm0 -+ vmovups %ymm0, -214(%edx) -+ vmovups -182(%ecx), %ymm0 -+ vmovups %ymm0, -182(%edx) -+ vmovups -150(%ecx), %ymm0 -+ vmovups %ymm0, -150(%edx) -+.LBB0_232: -+ vmovups -118(%ecx), %ymm0 -+ vmovups %ymm0, -118(%edx) -+ vmovups -86(%ecx), %ymm0 -+ vmovups %ymm0, -86(%edx) -+ jmp .LBB0_268 -+.LBB0_233: -+ vmovups -247(%ecx), %ymm0 -+ vmovups %ymm0, -247(%edx) -+ vmovups -215(%ecx), %ymm0 -+ vmovups %ymm0, -215(%edx) -+ vmovups -183(%ecx), %ymm0 -+ vmovups %ymm0, -183(%edx) -+ vmovups -151(%ecx), %ymm0 -+ vmovups %ymm0, -151(%edx) -+.LBB0_234: -+ vmovups -119(%ecx), %ymm0 -+ vmovups %ymm0, -119(%edx) -+ vmovups -87(%ecx), %ymm0 -+ vmovups %ymm0, -87(%edx) -+ jmp .LBB0_268 -+.LBB0_235: -+ vmovups -248(%ecx), %ymm0 -+ vmovups %ymm0, -248(%edx) -+ vmovups -216(%ecx), %ymm0 -+ vmovups %ymm0, -216(%edx) -+ vmovups -184(%ecx), %ymm0 -+ vmovups %ymm0, -184(%edx) -+ vmovups -152(%ecx), %ymm0 -+ vmovups %ymm0, -152(%edx) -+.LBB0_236: -+ vmovups -120(%ecx), %ymm0 -+ vmovups %ymm0, -120(%edx) -+ vmovups -88(%ecx), %ymm0 -+ vmovups %ymm0, -88(%edx) -+ jmp .LBB0_268 -+.LBB0_237: -+ vmovups -249(%ecx), %ymm0 -+ vmovups %ymm0, -249(%edx) -+ vmovups -217(%ecx), %ymm0 -+ vmovups %ymm0, -217(%edx) -+ vmovups -185(%ecx), %ymm0 -+ vmovups %ymm0, -185(%edx) -+ vmovups -153(%ecx), %ymm0 -+ vmovups %ymm0, -153(%edx) -+.LBB0_238: -+ vmovups -121(%ecx), %ymm0 -+ vmovups %ymm0, -121(%edx) -+ vmovups -89(%ecx), %ymm0 -+ vmovups %ymm0, -89(%edx) -+ jmp .LBB0_268 -+.LBB0_239: -+ vmovups -250(%ecx), %ymm0 -+ vmovups %ymm0, -250(%edx) -+ vmovups -218(%ecx), %ymm0 -+ vmovups %ymm0, -218(%edx) -+ vmovups -186(%ecx), %ymm0 -+ vmovups %ymm0, -186(%edx) -+ vmovups -154(%ecx), %ymm0 -+ vmovups %ymm0, -154(%edx) -+.LBB0_240: -+ vmovups -122(%ecx), %ymm0 -+ vmovups %ymm0, -122(%edx) -+ vmovups -90(%ecx), %ymm0 -+ vmovups %ymm0, -90(%edx) -+ jmp .LBB0_268 -+.LBB0_241: -+ vmovups -251(%ecx), %ymm0 -+ vmovups %ymm0, -251(%edx) -+ vmovups -219(%ecx), %ymm0 -+ vmovups %ymm0, -219(%edx) -+ vmovups -187(%ecx), %ymm0 -+ vmovups %ymm0, -187(%edx) -+ vmovups -155(%ecx), %ymm0 -+ vmovups %ymm0, -155(%edx) -+.LBB0_242: -+ vmovups -123(%ecx), %ymm0 -+ vmovups %ymm0, -123(%edx) -+ vmovups -91(%ecx), %ymm0 -+ vmovups %ymm0, -91(%edx) -+ jmp .LBB0_268 -+.LBB0_243: -+ vmovups -252(%ecx), %ymm0 -+ vmovups %ymm0, -252(%edx) -+ vmovups -220(%ecx), %ymm0 -+ vmovups %ymm0, -220(%edx) -+ vmovups -188(%ecx), %ymm0 -+ vmovups %ymm0, -188(%edx) -+ vmovups -156(%ecx), %ymm0 -+ vmovups %ymm0, -156(%edx) -+.LBB0_244: -+ vmovups -124(%ecx), %ymm0 -+ vmovups %ymm0, -124(%edx) -+ vmovups -92(%ecx), %ymm0 -+ vmovups %ymm0, -92(%edx) -+ jmp .LBB0_268 -+.LBB0_245: -+ vmovups -253(%ecx), %ymm0 -+ vmovups %ymm0, -253(%edx) -+ vmovups -221(%ecx), %ymm0 -+ vmovups %ymm0, -221(%edx) -+ vmovups -189(%ecx), %ymm0 -+ vmovups %ymm0, -189(%edx) -+ vmovups -157(%ecx), %ymm0 -+ vmovups %ymm0, -157(%edx) -+.LBB0_246: -+ vmovups -125(%ecx), %ymm0 -+ vmovups %ymm0, -125(%edx) -+ vmovups -93(%ecx), %ymm0 -+ vmovups %ymm0, -93(%edx) -+ jmp .LBB0_268 -+.LBB0_247: -+ vmovups -254(%ecx), %ymm0 -+ vmovups %ymm0, -254(%edx) -+ vmovups -222(%ecx), %ymm0 -+ vmovups %ymm0, -222(%edx) -+ vmovups -190(%ecx), %ymm0 -+ vmovups %ymm0, -190(%edx) -+ vmovups -158(%ecx), %ymm0 -+ vmovups %ymm0, -158(%edx) -+.LBB0_248: -+ vmovups -126(%ecx), %ymm0 -+ vmovups %ymm0, -126(%edx) -+ vmovups -94(%ecx), %ymm0 -+ vmovups %ymm0, -94(%edx) -+ jmp .LBB0_268 -+.LBB0_249: -+ vmovups -255(%ecx), %ymm0 -+ vmovups %ymm0, -255(%edx) -+ vmovups -223(%ecx), %ymm0 -+ vmovups %ymm0, -223(%edx) -+ vmovups -191(%ecx), %ymm0 -+ vmovups %ymm0, -191(%edx) -+ vmovups -159(%ecx), %ymm0 -+ vmovups %ymm0, -159(%edx) -+.LBB0_250: -+ vmovups -127(%ecx), %ymm0 -+ vmovups %ymm0, -127(%edx) -+ vmovups -95(%ecx), %ymm0 -+ vmovups %ymm0, -95(%edx) -+ jmp .LBB0_268 -+.LBB0_262: -+ vmovups -256(%ecx), %ymm0 -+ vmovups %ymm0, -256(%edx) -+.LBB0_263: -+ vmovups -224(%ecx), %ymm0 -+ vmovups %ymm0, -224(%edx) -+.LBB0_264: -+ vmovups -192(%ecx), %ymm0 -+ vmovups %ymm0, -192(%edx) -+.LBB0_265: -+ vmovups -160(%ecx), %ymm0 -+ vmovups %ymm0, -160(%edx) -+.LBB0_266: -+ vmovups -128(%ecx), %ymm0 -+ vmovups %ymm0, -128(%edx) -+.LBB0_267: -+ vmovups -96(%ecx), %ymm0 -+ vmovups %ymm0, -96(%edx) -+.LBB0_268: -+ vmovups -64(%ecx), %ymm0 -+ vmovups %ymm0, -64(%edx) -+.LBB0_269: -+ vmovups -32(%ecx), %ymm0 -+ vmovups %ymm0, -32(%edx) -+.LBB0_270: -+ vzeroupper -+ popl %esi -+ popl %edi -+ popl %ebx -+ popl %ebp -+ retl -+END(memcpy_avx2) -+ -+/*.Lfunc_end0: -+ .size memcpy_avx2, .Lfunc_end0-memcpy_avx2 -+ .section .rodata,"a",@progbits -+ .p2align 2*/ -+.LJTI0_0: -+ .long .LBB0_6@GOTOFF -+ .long .LBB0_10@GOTOFF -+ .long .LBB0_12@GOTOFF -+ .long .LBB0_16@GOTOFF -+ .long .LBB0_18@GOTOFF -+ .long .LBB0_20@GOTOFF -+ .long .LBB0_22@GOTOFF -+ .long .LBB0_26@GOTOFF -+ .long .LBB0_28@GOTOFF -+ .long .LBB0_30@GOTOFF -+ .long .LBB0_32@GOTOFF -+ .long .LBB0_34@GOTOFF -+ .long .LBB0_36@GOTOFF -+ .long .LBB0_38@GOTOFF -+ .long .LBB0_40@GOTOFF -+ .long .LBB0_44@GOTOFF -+ .long .LBB0_46@GOTOFF -+ .long .LBB0_48@GOTOFF -+ .long .LBB0_50@GOTOFF -+ .long .LBB0_52@GOTOFF -+ .long .LBB0_54@GOTOFF -+ .long .LBB0_56@GOTOFF -+ .long .LBB0_58@GOTOFF -+ .long .LBB0_60@GOTOFF -+ .long .LBB0_62@GOTOFF -+ .long .LBB0_64@GOTOFF -+ .long .LBB0_66@GOTOFF -+ .long .LBB0_68@GOTOFF -+ .long .LBB0_70@GOTOFF -+ .long .LBB0_72@GOTOFF -+ .long .LBB0_74@GOTOFF -+ .long .LBB0_269@GOTOFF -+ .long .LBB0_5@GOTOFF -+ .long .LBB0_9@GOTOFF -+ .long .LBB0_82@GOTOFF -+ .long .LBB0_15@GOTOFF -+ .long .LBB0_88@GOTOFF -+ .long .LBB0_92@GOTOFF -+ .long .LBB0_96@GOTOFF -+ .long .LBB0_25@GOTOFF -+ .long .LBB0_102@GOTOFF -+ .long .LBB0_106@GOTOFF -+ .long .LBB0_110@GOTOFF -+ .long .LBB0_114@GOTOFF -+ .long .LBB0_118@GOTOFF -+ .long .LBB0_122@GOTOFF -+ .long .LBB0_126@GOTOFF -+ .long .LBB0_43@GOTOFF -+ .long .LBB0_132@GOTOFF -+ .long .LBB0_136@GOTOFF -+ .long .LBB0_140@GOTOFF -+ .long .LBB0_144@GOTOFF -+ .long .LBB0_148@GOTOFF -+ .long .LBB0_152@GOTOFF -+ .long .LBB0_156@GOTOFF -+ .long .LBB0_160@GOTOFF -+ .long .LBB0_164@GOTOFF -+ .long .LBB0_168@GOTOFF -+ .long .LBB0_172@GOTOFF -+ .long .LBB0_176@GOTOFF -+ .long .LBB0_180@GOTOFF -+ .long .LBB0_184@GOTOFF -+ .long .LBB0_188@GOTOFF -+ .long .LBB0_268@GOTOFF -+ .long .LBB0_4@GOTOFF -+ .long .LBB0_8@GOTOFF -+ .long .LBB0_81@GOTOFF -+ .long .LBB0_14@GOTOFF -+ .long .LBB0_87@GOTOFF -+ .long .LBB0_91@GOTOFF -+ .long .LBB0_95@GOTOFF -+ .long .LBB0_24@GOTOFF -+ .long .LBB0_101@GOTOFF -+ .long .LBB0_105@GOTOFF -+ .long .LBB0_109@GOTOFF -+ .long .LBB0_113@GOTOFF -+ .long .LBB0_117@GOTOFF -+ .long .LBB0_121@GOTOFF -+ .long .LBB0_125@GOTOFF -+ .long .LBB0_42@GOTOFF -+ .long .LBB0_131@GOTOFF -+ .long .LBB0_135@GOTOFF -+ .long .LBB0_139@GOTOFF -+ .long .LBB0_143@GOTOFF -+ .long .LBB0_147@GOTOFF -+ .long .LBB0_151@GOTOFF -+ .long .LBB0_155@GOTOFF -+ .long .LBB0_159@GOTOFF -+ .long .LBB0_163@GOTOFF -+ .long .LBB0_167@GOTOFF -+ .long .LBB0_171@GOTOFF -+ .long .LBB0_175@GOTOFF -+ .long .LBB0_179@GOTOFF -+ .long .LBB0_183@GOTOFF -+ .long .LBB0_187@GOTOFF -+ .long .LBB0_267@GOTOFF -+ .long .LBB0_190@GOTOFF -+ .long .LBB0_192@GOTOFF -+ .long .LBB0_194@GOTOFF -+ .long .LBB0_196@GOTOFF -+ .long .LBB0_198@GOTOFF -+ .long .LBB0_200@GOTOFF -+ .long .LBB0_202@GOTOFF -+ .long .LBB0_204@GOTOFF -+ .long .LBB0_206@GOTOFF -+ .long .LBB0_208@GOTOFF -+ .long .LBB0_210@GOTOFF -+ .long .LBB0_212@GOTOFF -+ .long .LBB0_214@GOTOFF -+ .long .LBB0_216@GOTOFF -+ .long .LBB0_218@GOTOFF -+ .long .LBB0_220@GOTOFF -+ .long .LBB0_222@GOTOFF -+ .long .LBB0_224@GOTOFF -+ .long .LBB0_226@GOTOFF -+ .long .LBB0_228@GOTOFF -+ .long .LBB0_230@GOTOFF -+ .long .LBB0_232@GOTOFF -+ .long .LBB0_234@GOTOFF -+ .long .LBB0_236@GOTOFF -+ .long .LBB0_238@GOTOFF -+ .long .LBB0_240@GOTOFF -+ .long .LBB0_242@GOTOFF -+ .long .LBB0_244@GOTOFF -+ .long .LBB0_246@GOTOFF -+ .long .LBB0_248@GOTOFF -+ .long .LBB0_250@GOTOFF -+ .long .LBB0_266@GOTOFF -+ .long .LBB0_3@GOTOFF -+ .long .LBB0_7@GOTOFF -+ .long .LBB0_11@GOTOFF -+ .long .LBB0_13@GOTOFF -+ .long .LBB0_17@GOTOFF -+ .long .LBB0_19@GOTOFF -+ .long .LBB0_21@GOTOFF -+ .long .LBB0_23@GOTOFF -+ .long .LBB0_27@GOTOFF -+ .long .LBB0_29@GOTOFF -+ .long .LBB0_31@GOTOFF -+ .long .LBB0_33@GOTOFF -+ .long .LBB0_35@GOTOFF -+ .long .LBB0_37@GOTOFF -+ .long .LBB0_39@GOTOFF -+ .long .LBB0_41@GOTOFF -+ .long .LBB0_45@GOTOFF -+ .long .LBB0_47@GOTOFF -+ .long .LBB0_49@GOTOFF -+ .long .LBB0_51@GOTOFF -+ .long .LBB0_53@GOTOFF -+ .long .LBB0_55@GOTOFF -+ .long .LBB0_57@GOTOFF -+ .long .LBB0_59@GOTOFF -+ .long .LBB0_61@GOTOFF -+ .long .LBB0_63@GOTOFF -+ .long .LBB0_65@GOTOFF -+ .long .LBB0_67@GOTOFF -+ .long .LBB0_69@GOTOFF -+ .long .LBB0_71@GOTOFF -+ .long .LBB0_73@GOTOFF -+ .long .LBB0_265@GOTOFF -+ .long .LBB0_76@GOTOFF -+ .long .LBB0_78@GOTOFF -+ .long .LBB0_80@GOTOFF -+ .long .LBB0_84@GOTOFF -+ .long .LBB0_86@GOTOFF -+ .long .LBB0_90@GOTOFF -+ .long .LBB0_94@GOTOFF -+ .long .LBB0_98@GOTOFF -+ .long .LBB0_100@GOTOFF -+ .long .LBB0_104@GOTOFF -+ .long .LBB0_108@GOTOFF -+ .long .LBB0_112@GOTOFF -+ .long .LBB0_116@GOTOFF -+ .long .LBB0_120@GOTOFF -+ .long .LBB0_124@GOTOFF -+ .long .LBB0_128@GOTOFF -+ .long .LBB0_130@GOTOFF -+ .long .LBB0_134@GOTOFF -+ .long .LBB0_138@GOTOFF -+ .long .LBB0_142@GOTOFF -+ .long .LBB0_146@GOTOFF -+ .long .LBB0_150@GOTOFF -+ .long .LBB0_154@GOTOFF -+ .long .LBB0_158@GOTOFF -+ .long .LBB0_162@GOTOFF -+ .long .LBB0_166@GOTOFF -+ .long .LBB0_170@GOTOFF -+ .long .LBB0_174@GOTOFF -+ .long .LBB0_178@GOTOFF -+ .long .LBB0_182@GOTOFF -+ .long .LBB0_186@GOTOFF -+ .long .LBB0_264@GOTOFF -+ .long .LBB0_75@GOTOFF -+ .long .LBB0_77@GOTOFF -+ .long .LBB0_79@GOTOFF -+ .long .LBB0_83@GOTOFF -+ .long .LBB0_85@GOTOFF -+ .long .LBB0_89@GOTOFF -+ .long .LBB0_93@GOTOFF -+ .long .LBB0_97@GOTOFF -+ .long .LBB0_99@GOTOFF -+ .long .LBB0_103@GOTOFF -+ .long .LBB0_107@GOTOFF -+ .long .LBB0_111@GOTOFF -+ .long .LBB0_115@GOTOFF -+ .long .LBB0_119@GOTOFF -+ .long .LBB0_123@GOTOFF -+ .long .LBB0_127@GOTOFF -+ .long .LBB0_129@GOTOFF -+ .long .LBB0_133@GOTOFF -+ .long .LBB0_137@GOTOFF -+ .long .LBB0_141@GOTOFF -+ .long .LBB0_145@GOTOFF -+ .long .LBB0_149@GOTOFF -+ .long .LBB0_153@GOTOFF -+ .long .LBB0_157@GOTOFF -+ .long .LBB0_161@GOTOFF -+ .long .LBB0_165@GOTOFF -+ .long .LBB0_169@GOTOFF -+ .long .LBB0_173@GOTOFF -+ .long .LBB0_177@GOTOFF -+ .long .LBB0_181@GOTOFF -+ .long .LBB0_185@GOTOFF -+ .long .LBB0_263@GOTOFF -+ .long .LBB0_189@GOTOFF -+ .long .LBB0_191@GOTOFF -+ .long .LBB0_193@GOTOFF -+ .long .LBB0_195@GOTOFF -+ .long .LBB0_197@GOTOFF -+ .long .LBB0_199@GOTOFF -+ .long .LBB0_201@GOTOFF -+ .long .LBB0_203@GOTOFF -+ .long .LBB0_205@GOTOFF -+ .long .LBB0_207@GOTOFF -+ .long .LBB0_209@GOTOFF -+ .long .LBB0_211@GOTOFF -+ .long .LBB0_213@GOTOFF -+ .long .LBB0_215@GOTOFF -+ .long .LBB0_217@GOTOFF -+ .long .LBB0_219@GOTOFF -+ .long .LBB0_221@GOTOFF -+ .long .LBB0_223@GOTOFF -+ .long .LBB0_225@GOTOFF -+ .long .LBB0_227@GOTOFF -+ .long .LBB0_229@GOTOFF -+ .long .LBB0_231@GOTOFF -+ .long .LBB0_233@GOTOFF -+ .long .LBB0_235@GOTOFF -+ .long .LBB0_237@GOTOFF -+ .long .LBB0_239@GOTOFF -+ .long .LBB0_241@GOTOFF -+ .long .LBB0_243@GOTOFF -+ .long .LBB0_245@GOTOFF -+ .long .LBB0_247@GOTOFF -+ .long .LBB0_249@GOTOFF -+ .long .LBB0_262@GOTOFF -+.LJTI0_1: -+ .long .LBB0_6@GOTOFF -+ .long .LBB0_10@GOTOFF -+ .long .LBB0_12@GOTOFF -+ .long .LBB0_16@GOTOFF -+ .long .LBB0_18@GOTOFF -+ .long .LBB0_20@GOTOFF -+ .long .LBB0_22@GOTOFF -+ .long .LBB0_26@GOTOFF -+ .long .LBB0_28@GOTOFF -+ .long .LBB0_30@GOTOFF -+ .long .LBB0_32@GOTOFF -+ .long .LBB0_34@GOTOFF -+ .long .LBB0_36@GOTOFF -+ .long .LBB0_38@GOTOFF -+ .long .LBB0_40@GOTOFF -+ .long .LBB0_44@GOTOFF -+ .long .LBB0_46@GOTOFF -+ .long .LBB0_48@GOTOFF -+ .long .LBB0_50@GOTOFF -+ .long .LBB0_52@GOTOFF -+ .long .LBB0_54@GOTOFF -+ .long .LBB0_56@GOTOFF -+ .long .LBB0_58@GOTOFF -+ .long .LBB0_60@GOTOFF -+ .long .LBB0_62@GOTOFF -+ .long .LBB0_64@GOTOFF -+ .long .LBB0_66@GOTOFF -+ .long .LBB0_68@GOTOFF -+ .long .LBB0_70@GOTOFF -+ .long .LBB0_72@GOTOFF -+ .long .LBB0_74@GOTOFF -+ .long .LBB0_269@GOTOFF -+ .long .LBB0_5@GOTOFF -+ .long .LBB0_9@GOTOFF -+ .long .LBB0_82@GOTOFF -+ .long .LBB0_15@GOTOFF -+ .long .LBB0_88@GOTOFF -+ .long .LBB0_92@GOTOFF -+ .long .LBB0_96@GOTOFF -+ .long .LBB0_25@GOTOFF -+ .long .LBB0_102@GOTOFF -+ .long .LBB0_106@GOTOFF -+ .long .LBB0_110@GOTOFF -+ .long .LBB0_114@GOTOFF -+ .long .LBB0_118@GOTOFF -+ .long .LBB0_122@GOTOFF -+ .long .LBB0_126@GOTOFF -+ .long .LBB0_43@GOTOFF -+ .long .LBB0_132@GOTOFF -+ .long .LBB0_136@GOTOFF -+ .long .LBB0_140@GOTOFF -+ .long .LBB0_144@GOTOFF -+ .long .LBB0_148@GOTOFF -+ .long .LBB0_152@GOTOFF -+ .long .LBB0_156@GOTOFF -+ .long .LBB0_160@GOTOFF -+ .long .LBB0_164@GOTOFF -+ .long .LBB0_168@GOTOFF -+ .long .LBB0_172@GOTOFF -+ .long .LBB0_176@GOTOFF -+ .long .LBB0_180@GOTOFF -+ .long .LBB0_184@GOTOFF -+ .long .LBB0_188@GOTOFF -+ .long .LBB0_268@GOTOFF -+ .long .LBB0_4@GOTOFF -+ .long .LBB0_8@GOTOFF -+ .long .LBB0_81@GOTOFF -+ .long .LBB0_14@GOTOFF -+ .long .LBB0_87@GOTOFF -+ .long .LBB0_91@GOTOFF -+ .long .LBB0_95@GOTOFF -+ .long .LBB0_24@GOTOFF -+ .long .LBB0_101@GOTOFF -+ .long .LBB0_105@GOTOFF -+ .long .LBB0_109@GOTOFF -+ .long .LBB0_113@GOTOFF -+ .long .LBB0_117@GOTOFF -+ .long .LBB0_121@GOTOFF -+ .long .LBB0_125@GOTOFF -+ .long .LBB0_42@GOTOFF -+ .long .LBB0_131@GOTOFF -+ .long .LBB0_135@GOTOFF -+ .long .LBB0_139@GOTOFF -+ .long .LBB0_143@GOTOFF -+ .long .LBB0_147@GOTOFF -+ .long .LBB0_151@GOTOFF -+ .long .LBB0_155@GOTOFF -+ .long .LBB0_159@GOTOFF -+ .long .LBB0_163@GOTOFF -+ .long .LBB0_167@GOTOFF -+ .long .LBB0_171@GOTOFF -+ .long .LBB0_175@GOTOFF -+ .long .LBB0_179@GOTOFF -+ .long .LBB0_183@GOTOFF -+ .long .LBB0_187@GOTOFF -+ .long .LBB0_267@GOTOFF -+ .long .LBB0_190@GOTOFF -+ .long .LBB0_192@GOTOFF -+ .long .LBB0_194@GOTOFF -+ .long .LBB0_196@GOTOFF -+ .long .LBB0_198@GOTOFF -+ .long .LBB0_200@GOTOFF -+ .long .LBB0_202@GOTOFF -+ .long .LBB0_204@GOTOFF -+ .long .LBB0_206@GOTOFF -+ .long .LBB0_208@GOTOFF -+ .long .LBB0_210@GOTOFF -+ .long .LBB0_212@GOTOFF -+ .long .LBB0_214@GOTOFF -+ .long .LBB0_216@GOTOFF -+ .long .LBB0_218@GOTOFF -+ .long .LBB0_220@GOTOFF -+ .long .LBB0_222@GOTOFF -+ .long .LBB0_224@GOTOFF -+ .long .LBB0_226@GOTOFF -+ .long .LBB0_228@GOTOFF -+ .long .LBB0_230@GOTOFF -+ .long .LBB0_232@GOTOFF -+ .long .LBB0_234@GOTOFF -+ .long .LBB0_236@GOTOFF -+ .long .LBB0_238@GOTOFF -+ .long .LBB0_240@GOTOFF -+ .long .LBB0_242@GOTOFF -+ .long .LBB0_244@GOTOFF -+ .long .LBB0_246@GOTOFF -+ .long .LBB0_248@GOTOFF -+ .long .LBB0_250@GOTOFF -+ .long .LBB0_266@GOTOFF -+ .long .LBB0_3@GOTOFF -+ .long .LBB0_7@GOTOFF -+ .long .LBB0_11@GOTOFF -+ .long .LBB0_13@GOTOFF -+ .long .LBB0_17@GOTOFF -+ .long .LBB0_19@GOTOFF -+ .long .LBB0_21@GOTOFF -+ .long .LBB0_23@GOTOFF -+ .long .LBB0_27@GOTOFF -+ .long .LBB0_29@GOTOFF -+ .long .LBB0_31@GOTOFF -+ .long .LBB0_33@GOTOFF -+ .long .LBB0_35@GOTOFF -+ .long .LBB0_37@GOTOFF -+ .long .LBB0_39@GOTOFF -+ .long .LBB0_41@GOTOFF -+ .long .LBB0_45@GOTOFF -+ .long .LBB0_47@GOTOFF -+ .long .LBB0_49@GOTOFF -+ .long .LBB0_51@GOTOFF -+ .long .LBB0_53@GOTOFF -+ .long .LBB0_55@GOTOFF -+ .long .LBB0_57@GOTOFF -+ .long .LBB0_59@GOTOFF -+ .long .LBB0_61@GOTOFF -+ .long .LBB0_63@GOTOFF -+ .long .LBB0_65@GOTOFF -+ .long .LBB0_67@GOTOFF -+ .long .LBB0_69@GOTOFF -+ .long .LBB0_71@GOTOFF -+ .long .LBB0_73@GOTOFF -+ .long .LBB0_265@GOTOFF -+ .long .LBB0_76@GOTOFF -+ .long .LBB0_78@GOTOFF -+ .long .LBB0_80@GOTOFF -+ .long .LBB0_84@GOTOFF -+ .long .LBB0_86@GOTOFF -+ .long .LBB0_90@GOTOFF -+ .long .LBB0_94@GOTOFF -+ .long .LBB0_98@GOTOFF -+ .long .LBB0_100@GOTOFF -+ .long .LBB0_104@GOTOFF -+ .long .LBB0_108@GOTOFF -+ .long .LBB0_112@GOTOFF -+ .long .LBB0_116@GOTOFF -+ .long .LBB0_120@GOTOFF -+ .long .LBB0_124@GOTOFF -+ .long .LBB0_128@GOTOFF -+ .long .LBB0_130@GOTOFF -+ .long .LBB0_134@GOTOFF -+ .long .LBB0_138@GOTOFF -+ .long .LBB0_142@GOTOFF -+ .long .LBB0_146@GOTOFF -+ .long .LBB0_150@GOTOFF -+ .long .LBB0_154@GOTOFF -+ .long .LBB0_158@GOTOFF -+ .long .LBB0_162@GOTOFF -+ .long .LBB0_166@GOTOFF -+ .long .LBB0_170@GOTOFF -+ .long .LBB0_174@GOTOFF -+ .long .LBB0_178@GOTOFF -+ .long .LBB0_182@GOTOFF -+ .long .LBB0_186@GOTOFF -+ .long .LBB0_264@GOTOFF -+ .long .LBB0_75@GOTOFF -+ .long .LBB0_77@GOTOFF -+ .long .LBB0_79@GOTOFF -+ .long .LBB0_83@GOTOFF -+ .long .LBB0_85@GOTOFF -+ .long .LBB0_89@GOTOFF -+ .long .LBB0_93@GOTOFF -+ .long .LBB0_97@GOTOFF -+ .long .LBB0_99@GOTOFF -+ .long .LBB0_103@GOTOFF -+ .long .LBB0_107@GOTOFF -+ .long .LBB0_111@GOTOFF -+ .long .LBB0_115@GOTOFF -+ .long .LBB0_119@GOTOFF -+ .long .LBB0_123@GOTOFF -+ .long .LBB0_127@GOTOFF -+ .long .LBB0_129@GOTOFF -+ .long .LBB0_133@GOTOFF -+ .long .LBB0_137@GOTOFF -+ .long .LBB0_141@GOTOFF -+ .long .LBB0_145@GOTOFF -+ .long .LBB0_149@GOTOFF -+ .long .LBB0_153@GOTOFF -+ .long .LBB0_157@GOTOFF -+ .long .LBB0_161@GOTOFF -+ .long .LBB0_165@GOTOFF -+ .long .LBB0_169@GOTOFF -+ .long .LBB0_173@GOTOFF -+ .long .LBB0_177@GOTOFF -+ .long .LBB0_181@GOTOFF -+ .long .LBB0_185@GOTOFF -+ .long .LBB0_263@GOTOFF -+ .long .LBB0_189@GOTOFF -+ .long .LBB0_191@GOTOFF -+ .long .LBB0_193@GOTOFF -+ .long .LBB0_195@GOTOFF -+ .long .LBB0_197@GOTOFF -+ .long .LBB0_199@GOTOFF -+ .long .LBB0_201@GOTOFF -+ .long .LBB0_203@GOTOFF -+ .long .LBB0_205@GOTOFF -+ .long .LBB0_207@GOTOFF -+ .long .LBB0_209@GOTOFF -+ .long .LBB0_211@GOTOFF -+ .long .LBB0_213@GOTOFF -+ .long .LBB0_215@GOTOFF -+ .long .LBB0_217@GOTOFF -+ .long .LBB0_219@GOTOFF -+ .long .LBB0_221@GOTOFF -+ .long .LBB0_223@GOTOFF -+ .long .LBB0_225@GOTOFF -+ .long .LBB0_227@GOTOFF -+ .long .LBB0_229@GOTOFF -+ .long .LBB0_231@GOTOFF -+ .long .LBB0_233@GOTOFF -+ .long .LBB0_235@GOTOFF -+ .long .LBB0_237@GOTOFF -+ .long .LBB0_239@GOTOFF -+ .long .LBB0_241@GOTOFF -+ .long .LBB0_243@GOTOFF -+ .long .LBB0_245@GOTOFF -+ .long .LBB0_247@GOTOFF -+ .long .LBB0_249@GOTOFF -+ .long .LBB0_262@GOTOFF -+ # -- End function -diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp b/libc/arch-x86_64/dynamic_function_dispatch.cpp -index c846ded45..43aaebb54 100644 ---- a/libc/arch-x86_64/dynamic_function_dispatch.cpp -+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp -@@ -46,4 +46,42 @@ DEFINE_IFUNC_FOR(__memset_chk) { - RETURN_FUNC(__memset_chk_func, __memset_chk_generic); - } - -+typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n); -+DEFINE_IFUNC_FOR(memcmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memcmp_func, memcmp_avx2) -+ RETURN_FUNC(memcmp_func, memcmp_generic); -+} -+ -+typedef void* memmove_func(void* __dst, const void* __src, size_t __n); -+DEFINE_IFUNC_FOR(memmove) { -+ RETURN_FUNC(memmove_func, memmove_generic); -+} -+ -+typedef void* memcpy_func(void* __dst, const void* __src, size_t __n); -+DEFINE_IFUNC_FOR(memcpy) { -+ return memmove_resolver(); -+} -+ -+typedef void* memchr_func(const void* __s, int __ch, size_t __n); -+DEFINE_IFUNC_FOR(memchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memchr_func, memchr_avx2); -+ RETURN_FUNC(memchr_func, memchr_openbsd); -+} -+ -+typedef void* memrchr_func(const void* __s, int __ch, size_t __n); -+DEFINE_IFUNC_FOR(memrchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memrchr_func, memrchr_avx2); -+ RETURN_FUNC(memrchr_func, memrchr_openbsd); -+} -+ -+// typedef int wmemset_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n); -+// DEFINE_IFUNC_FOR(wmemset) { -+// __builtin_cpu_init(); -+// if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wmemset_func, wmemset_avx2); -+// RETURN_FUNC(wmemset_func, wmemset_freebsd); -+// } -+ - } // extern "C" -diff --git a/libc/arch-x86_64/generic/string/memchr.c b/libc/arch-x86_64/generic/string/memchr.c -new file mode 100644 -index 000000000..f530eaca8 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/memchr.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define memchr memchr_openbsd -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/memrchr.c b/libc/arch-x86_64/generic/string/memrchr.c -new file mode 100644 -index 000000000..44262f2d1 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/memrchr.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define memrchr memrchr_openbsd -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wmemset.c b/libc/arch-x86_64/generic/string/wmemset.c -new file mode 100644 -index 000000000..35d489f44 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wmemset.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wmemset wmemset_freebsd -+ -+#include -diff --git a/libc/arch-x86_64/string/cache.h b/libc/arch-x86_64/include/cache.h -similarity index 100% -rename from libc/arch-x86_64/string/cache.h -rename to libc/arch-x86_64/include/cache.h -diff --git a/libc/arch-x86_64/kabylake/string/avx2-memchr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-memchr-kbl.S -new file mode 100644 -index 000000000..da667c9b3 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-memchr-kbl.S -@@ -0,0 +1,371 @@ -+#ifndef L -+# define L(label) .L##label -+#endif -+ -+#ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+#endif -+ -+#ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+#endif -+ -+#ifndef cfi_rel_offset -+# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off -+#endif -+ -+#ifndef cfi_restore -+# define cfi_restore(reg) .cfi_restore reg -+#endif -+ -+#ifndef cfi_adjust_cfa_offset -+# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off -+#endif -+ -+#ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+#endif -+ -+#ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+#endif -+ -+#define CFI_PUSH(REG) \ -+ cfi_adjust_cfa_offset (4); \ -+ cfi_rel_offset (REG, 0) -+ -+#define CFI_POP(REG) \ -+ cfi_adjust_cfa_offset (-4); \ -+ cfi_restore (REG) -+ -+#define PUSH(REG) push REG; -+#define POP(REG) pop REG; -+ -+#define ENTRANCE PUSH (%rbx); -+#define RETURN_END POP (%rbx); ret -+#define RETURN RETURN_END; -+ -+# ifndef MEMCHR -+# define MEMCHR memchr_avx2 -+# endif -+ -+# ifdef USE_AS_WMEMCHR -+# define VPCMPEQ vpcmpeqd -+# else -+# define VPCMPEQ vpcmpeqb -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (MEMCHR) -+# ifndef USE_AS_RAWMEMCHR -+ /* Check for zero length. */ -+ testq %rdx, %rdx -+ jz L(null) -+# endif -+ movl %edi, %ecx -+ /* Broadcast CHAR to YMM0. */ -+ vmovd %esi, %xmm0 -+# ifdef USE_AS_WMEMCHR -+ shl $2, %rdx -+ vpbroadcastd %xmm0, %ymm0 -+# else -+ vpbroadcastb %xmm0, %ymm0 -+# endif -+ /* Check if we may cross page boundary with one vector load. */ -+ andl $(2 * VEC_SIZE - 1), %ecx -+ cmpl $VEC_SIZE, %ecx -+ ja L(cros_page_boundary) -+ -+ /* Check the first VEC_SIZE bytes. */ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+# ifndef USE_AS_RAWMEMCHR -+ jnz L(first_vec_x0_check) -+ /* Adjust length and check the end of data. */ -+ subq $VEC_SIZE, %rdx -+ jbe L(zero) -+# else -+ jnz L(first_vec_x0) -+# endif -+ -+ /* Align data for aligned loads in the loop. */ -+ addq $VEC_SIZE, %rdi -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ -+# ifndef USE_AS_RAWMEMCHR -+ /* Adjust length. */ -+ addq %rcx, %rdx -+ -+ subq $(VEC_SIZE * 4), %rdx -+ jbe L(last_4x_vec_or_less) -+# endif -+ jmp L(more_4x_vec) -+ -+ .p2align 4 -+L(cros_page_boundary): -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ /* Remove the leading bytes. */ -+ sarl %cl, %eax -+ testl %eax, %eax -+ jz L(aligned_more) -+ tzcntl %eax, %eax -+# ifndef USE_AS_RAWMEMCHR -+ /* Check the end of data. */ -+ cmpq %rax, %rdx -+ jbe L(zero) -+# endif -+ addq %rdi, %rax -+ addq %rcx, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(aligned_more): -+# ifndef USE_AS_RAWMEMCHR -+ /* Calculate "rdx + rcx - VEC_SIZE" with "rdx - (VEC_SIZE - rcx)" -+ instead of "(rdx + rcx) - VEC_SIZE" to void possible addition -+ overflow. */ -+ negq %rcx -+ addq $VEC_SIZE, %rcx -+ -+ /* Check the end of data. */ -+ subq %rcx, %rdx -+ jbe L(zero) -+# endif -+ -+ addq $VEC_SIZE, %rdi -+ -+# ifndef USE_AS_RAWMEMCHR -+ subq $(VEC_SIZE * 4), %rdx -+ jbe L(last_4x_vec_or_less) -+# endif -+ -+L(more_4x_vec): -+ /* Check the first 4 * VEC_SIZE. Only one VEC_SIZE at a time -+ since data is only aligned to VEC_SIZE. */ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x3) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+# ifndef USE_AS_RAWMEMCHR -+ subq $(VEC_SIZE * 4), %rdx -+ jbe L(last_4x_vec_or_less) -+# endif -+ -+ /* Align data to 4 * VEC_SIZE. */ -+ movq %rdi, %rcx -+ andl $(4 * VEC_SIZE - 1), %ecx -+ andq $-(4 * VEC_SIZE), %rdi -+ -+# ifndef USE_AS_RAWMEMCHR -+ /* Adjust length. */ -+ addq %rcx, %rdx -+# endif -+ -+ .p2align 4 -+L(loop_4x_vec): -+ /* Compare 4 * VEC at a time forward. */ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm2 -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm0, %ymm3 -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm0, %ymm4 -+ -+ vpor %ymm1, %ymm2, %ymm5 -+ vpor %ymm3, %ymm4, %ymm6 -+ vpor %ymm5, %ymm6, %ymm5 -+ -+ vpmovmskb %ymm5, %eax -+ testl %eax, %eax -+ jnz L(4x_vec_end) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+# ifdef USE_AS_RAWMEMCHR -+ jmp L(loop_4x_vec) -+# else -+ subq $(VEC_SIZE * 4), %rdx -+ ja L(loop_4x_vec) -+ -+L(last_4x_vec_or_less): -+ /* Less than 4 * VEC and aligned to VEC_SIZE. */ -+ addl $(VEC_SIZE * 2), %edx -+ jle L(last_2x_vec) -+ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x2_check) -+ subl $VEC_SIZE, %edx -+ jle L(zero) -+ -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x3_check) -+ xorl %eax, %eax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_2x_vec): -+ addl $(VEC_SIZE * 2), %edx -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x0_check) -+ subl $VEC_SIZE, %edx -+ jle L(zero) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1_check) -+ xorl %eax, %eax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x0_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rdx -+ jbe L(zero) -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x1_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rdx -+ jbe L(zero) -+ addq $VEC_SIZE, %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x2_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rdx -+ jbe L(zero) -+ addq $(VEC_SIZE * 2), %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x3_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rdx -+ jbe L(zero) -+ addq $(VEC_SIZE * 3), %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(zero): -+ VZEROUPPER -+L(null): -+ xorl %eax, %eax -+ ret -+# endif -+ -+ .p2align 4 -+L(first_vec_x0): -+ tzcntl %eax, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x1): -+ tzcntl %eax, %eax -+ addq $VEC_SIZE, %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x2): -+ tzcntl %eax, %eax -+ addq $(VEC_SIZE * 2), %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(4x_vec_end): -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ vpmovmskb %ymm4, %eax -+ testl %eax, %eax -+L(first_vec_x3): -+ tzcntl %eax, %eax -+ addq $(VEC_SIZE * 3), %rax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+END (MEMCHR) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-memcmp-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-memcmp-kbl.S -new file mode 100644 -index 000000000..e9778ca5a ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-memcmp-kbl.S -@@ -0,0 +1,428 @@ -+/* Copyright (C) 2017-2019 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+/* memcmp/wmemcmp is implemented as: -+ 1. For size from 2 to 7 bytes, load as big endian with movbe and bswap -+ to avoid branches. -+ 2. Use overlapping compare to avoid branch. -+ 3. Use vector compare when size >= 4 bytes for memcmp or size >= 8 -+ bytes for wmemcmp. -+ 4. If size is 8 * VEC_SIZE or less, unroll the loop. -+ 5. Compare 4 * VEC_SIZE at a time with the aligned first memory -+ area. -+ 6. Use 2 vector compares when size is 2 * VEC_SIZE or less. -+ 7. Use 4 vector compares when size is 4 * VEC_SIZE or less. -+ 8. Use 8 vector compares when size is 8 * VEC_SIZE or less. */ -+ -+ -+#ifndef MEMCMP -+# define MEMCMP memcmp_avx2 -+#endif -+ -+#ifndef L -+# define L(label) .L##label -+#endif -+ -+#ifndef ALIGN -+# define ALIGN(n) .p2align n -+#endif -+ -+#ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+#endif -+ -+#ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+#endif -+ -+#ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+#endif -+ -+#ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+#endif -+ -+#ifndef ALIGN -+# define ALIGN(n) .p2align n -+#endif -+ -+# ifdef USE_AS_WMEMCMP -+# define VPCMPEQ vpcmpeqd -+# else -+# define VPCMPEQ vpcmpeqb -+# endif -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+# define VEC_SIZE 32 -+# define VEC_MASK ((1 << VEC_SIZE) - 1) -+ .section .text.avx,"ax",@progbits -+ENTRY (MEMCMP) -+# ifdef USE_AS_WMEMCMP -+ shl $2, %RDX_LP -+# elif defined __ILP32__ -+ /* Clear the upper 32 bits. */ -+ movl %edx, %edx -+# endif -+ cmp $VEC_SIZE, %rdx -+ jb L(less_vec) -+ /* From VEC to 2 * VEC. No branch when size == VEC_SIZE. */ -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ cmpq $(VEC_SIZE * 2), %rdx -+ jbe L(last_vec) -+ VPCMPEQ %ymm0, %ymm0, %ymm0 -+ /* More than 2 * VEC. */ -+ cmpq $(VEC_SIZE * 8), %rdx -+ ja L(more_8x_vec) -+ cmpq $(VEC_SIZE * 4), %rdx -+ jb L(last_4x_vec) -+ /* From 4 * VEC to 8 * VEC, inclusively. */ -+ vmovdqu (%rsi), %ymm1 -+ VPCMPEQ (%rdi), %ymm1, %ymm1 -+ vmovdqu VEC_SIZE(%rsi), %ymm2 -+ VPCMPEQ VEC_SIZE(%rdi), %ymm2, %ymm2 -+ vmovdqu (VEC_SIZE * 2)(%rsi), %ymm3 -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm3, %ymm3 -+ vmovdqu (VEC_SIZE * 3)(%rsi), %ymm4 -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm4, %ymm4 -+ vpand %ymm1, %ymm2, %ymm5 -+ vpand %ymm3, %ymm4, %ymm6 -+ vpand %ymm5, %ymm6, %ymm5 -+ vptest %ymm0, %ymm5 -+ jnc L(4x_vec_end) -+ leaq -(4 * VEC_SIZE)(%rdi, %rdx), %rdi -+ leaq -(4 * VEC_SIZE)(%rsi, %rdx), %rsi -+ vmovdqu (%rsi), %ymm1 -+ VPCMPEQ (%rdi), %ymm1, %ymm1 -+ vmovdqu VEC_SIZE(%rsi), %ymm2 -+ VPCMPEQ VEC_SIZE(%rdi), %ymm2, %ymm2 -+ vpand %ymm2, %ymm1, %ymm5 -+ vmovdqu (VEC_SIZE * 2)(%rsi), %ymm3 -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm3, %ymm3 -+ vpand %ymm3, %ymm5, %ymm5 -+ vmovdqu (VEC_SIZE * 3)(%rsi), %ymm4 -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm4, %ymm4 -+ vpand %ymm4, %ymm5, %ymm5 -+ vptest %ymm0, %ymm5 -+ jnc L(4x_vec_end) -+ xorl %eax, %eax -+ VZEROUPPER -+ ret -+ .p2align 4 -+L(last_2x_vec): -+ /* From VEC to 2 * VEC. No branch when size == VEC_SIZE. */ -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+L(last_vec): -+ /* Use overlapping loads to avoid branches. */ -+ leaq -VEC_SIZE(%rdi, %rdx), %rdi -+ leaq -VEC_SIZE(%rsi, %rdx), %rsi -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ VZEROUPPER -+ ret -+ .p2align 4 -+L(first_vec): -+ /* A byte or int32 is different within 16 or 32 bytes. */ -+ tzcntl %eax, %ecx -+# ifdef USE_AS_WMEMCMP -+ xorl %eax, %eax -+ movl (%rdi, %rcx), %edx -+ cmpl (%rsi, %rcx), %edx -+L(wmemcmp_return): -+ setl %al -+ negl %eax -+ orl $1, %eax -+# else -+ movzbl (%rdi, %rcx), %eax -+ movzbl (%rsi, %rcx), %edx -+ sub %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+# ifdef USE_AS_WMEMCMP -+ .p2align 4 -+L(4): -+ xorl %eax, %eax -+ movl (%rdi), %edx -+ cmpl (%rsi), %edx -+ jne L(wmemcmp_return) -+ ret -+# else -+ -+L(between_4_7): -+ /* Load as big endian with overlapping movbe to avoid branches. */ -+ movbe (%rdi), %eax -+ movbe (%rsi), %ecx -+ shlq $32, %rax -+ shlq $32, %rcx -+ movbe -4(%rdi, %rdx), %edi -+ movbe -4(%rsi, %rdx), %esi -+ orq %rdi, %rax -+ orq %rsi, %rcx -+ subq %rcx, %rax -+ je L(exit) -+ sbbl %eax, %eax -+ orl $1, %eax -+ ret -+ .p2align 4 -+/*L(8): -+ giving two failures -+ movl (%rdi), %eax -+ subl (%rsi), %eax -+ je L(between_4_7) -+ retq */ -+ -+L(exit): -+ ret -+ .p2align 4 -+L(between_2_3): -+ /* Load as big endian to avoid branches. */ -+ movzwl (%rdi), %eax -+ movzwl (%rsi), %ecx -+ shll $8, %eax -+ shll $8, %ecx -+ bswap %eax -+ bswap %ecx -+ movb -1(%rdi, %rdx), %al -+ movb -1(%rsi, %rdx), %cl -+ /* Subtraction is okay because the upper 8 bits are zero. */ -+ subl %ecx, %eax -+ ret -+ .p2align 4 -+L(1): -+ movzbl (%rdi), %eax -+ movzbl (%rsi), %ecx -+ sub %ecx, %eax -+ ret -+# endif -+ .p2align 4 -+L(zero): -+ xorl %eax, %eax -+ ret -+ .p2align 4 -+L(less_vec): -+# ifdef USE_AS_WMEMCMP -+ /* It can only be 0, 4, 8, 12, 16, 20, 24, 28 bytes. */ -+ cmpb $4, %dl -+ je L(4) -+ jb L(zero) -+# else -+/* cmpb $8, %dl -+ jne L(tmp) -+ movl (%rdi), %eax -+ subl (%rsi), %eax -+ jne L(exit) -+L(temp): -+ movl %edx, %edx -+ //jmp L(tmp) -+L(tmp):*/ -+ -+ cmpb $1, %dl -+ je L(1) -+ jb L(zero) -+ -+ cmpb $4, %dl -+ jb L(between_2_3) -+ cmpb $8, %dl -+ //je L(8) -+ jb L(between_4_7) -+# endif -+ cmpb $16, %dl -+ jae L(between_16_31) -+ /* It is between 8 and 15 bytes. */ -+ vmovq (%rdi), %xmm1 -+ vmovq (%rsi), %xmm2 -+ VPCMPEQ %xmm1, %xmm2, %xmm2 -+ vpmovmskb %xmm2, %eax -+ subl $0xffff, %eax -+ jnz L(first_vec) -+ /* Use overlapping loads to avoid branches. */ -+ leaq -8(%rdi, %rdx), %rdi -+ leaq -8(%rsi, %rdx), %rsi -+ vmovq (%rdi), %xmm1 -+ vmovq (%rsi), %xmm2 -+ VPCMPEQ %xmm1, %xmm2, %xmm2 -+ vpmovmskb %xmm2, %eax -+ subl $0xffff, %eax -+ jnz L(first_vec) -+ ret -+ .p2align 4 -+L(between_16_31): -+ /* From 16 to 31 bytes. No branch when size == 16. */ -+ vmovdqu (%rsi), %xmm2 -+ VPCMPEQ (%rdi), %xmm2, %xmm2 -+ vpmovmskb %xmm2, %eax -+ subl $0xffff, %eax -+ jnz L(first_vec) -+ /* Use overlapping loads to avoid branches. */ -+ leaq -16(%rdi, %rdx), %rdi -+ leaq -16(%rsi, %rdx), %rsi -+ vmovdqu (%rsi), %xmm2 -+ VPCMPEQ (%rdi), %xmm2, %xmm2 -+ vpmovmskb %xmm2, %eax -+ subl $0xffff, %eax -+ jnz L(first_vec) -+ ret -+ .p2align 4 -+L(more_8x_vec): -+ /* More than 8 * VEC. Check the first VEC. */ -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ /* Align the first memory area for aligned loads in the loop. -+ Compute how much the first memory area is misaligned. */ -+ movq %rdi, %rcx -+ andl $(VEC_SIZE - 1), %ecx -+ /* Get the negative of offset for alignment. */ -+ subq $VEC_SIZE, %rcx -+ /* Adjust the second memory area. */ -+ subq %rcx, %rsi -+ /* Adjust the first memory area which should be aligned now. */ -+ subq %rcx, %rdi -+ /* Adjust length. */ -+ addq %rcx, %rdx -+L(loop_4x_vec): -+ /* Compare 4 * VEC at a time forward. */ -+ vmovdqu (%rsi), %ymm1 -+ VPCMPEQ (%rdi), %ymm1, %ymm1 -+ vmovdqu VEC_SIZE(%rsi), %ymm2 -+ VPCMPEQ VEC_SIZE(%rdi), %ymm2, %ymm2 -+ vpand %ymm2, %ymm1, %ymm5 -+ vmovdqu (VEC_SIZE * 2)(%rsi), %ymm3 -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm3, %ymm3 -+ vpand %ymm3, %ymm5, %ymm5 -+ vmovdqu (VEC_SIZE * 3)(%rsi), %ymm4 -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm4, %ymm4 -+ vpand %ymm4, %ymm5, %ymm5 -+ vptest %ymm0, %ymm5 -+ jnc L(4x_vec_end) -+ addq $(VEC_SIZE * 4), %rdi -+ addq $(VEC_SIZE * 4), %rsi -+ subq $(VEC_SIZE * 4), %rdx -+ cmpq $(VEC_SIZE * 4), %rdx -+ jae L(loop_4x_vec) -+ /* Less than 4 * VEC. */ -+ cmpq $VEC_SIZE, %rdx -+ jbe L(last_vec) -+ cmpq $(VEC_SIZE * 2), %rdx -+ jbe L(last_2x_vec) -+L(last_4x_vec): -+ /* From 2 * VEC to 4 * VEC. */ -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ addq $VEC_SIZE, %rdi -+ addq $VEC_SIZE, %rsi -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ /* Use overlapping loads to avoid branches. */ -+ leaq -(3 * VEC_SIZE)(%rdi, %rdx), %rdi -+ leaq -(3 * VEC_SIZE)(%rsi, %rdx), %rsi -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ addq $VEC_SIZE, %rdi -+ addq $VEC_SIZE, %rsi -+ vmovdqu (%rsi), %ymm2 -+ VPCMPEQ (%rdi), %ymm2, %ymm2 -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ VZEROUPPER -+ ret -+ .p2align 4 -+L(4x_vec_end): -+ vpmovmskb %ymm1, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec) -+ vpmovmskb %ymm2, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec_x1) -+ vpmovmskb %ymm3, %eax -+ subl $VEC_MASK, %eax -+ jnz L(first_vec_x2) -+ vpmovmskb %ymm4, %eax -+ subl $VEC_MASK, %eax -+ tzcntl %eax, %ecx -+# ifdef USE_AS_WMEMCMP -+ xorl %eax, %eax -+ movl (VEC_SIZE * 3)(%rdi, %rcx), %edx -+ cmpl (VEC_SIZE * 3)(%rsi, %rcx), %edx -+ jmp L(wmemcmp_return) -+# else -+ movzbl (VEC_SIZE * 3)(%rdi, %rcx), %eax -+ movzbl (VEC_SIZE * 3)(%rsi, %rcx), %edx -+ sub %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+ .p2align 4 -+L(first_vec_x1): -+ tzcntl %eax, %ecx -+# ifdef USE_AS_WMEMCMP -+ xorl %eax, %eax -+ movl VEC_SIZE(%rdi, %rcx), %edx -+ cmpl VEC_SIZE(%rsi, %rcx), %edx -+ jmp L(wmemcmp_return) -+# else -+ movzbl VEC_SIZE(%rdi, %rcx), %eax -+ movzbl VEC_SIZE(%rsi, %rcx), %edx -+ sub %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+ .p2align 4 -+L(first_vec_x2): -+ tzcntl %eax, %ecx -+# ifdef USE_AS_WMEMCMP -+ xorl %eax, %eax -+ movl (VEC_SIZE * 2)(%rdi, %rcx), %edx -+ cmpl (VEC_SIZE * 2)(%rsi, %rcx), %edx -+ jmp L(wmemcmp_return) -+# else -+ movzbl (VEC_SIZE * 2)(%rdi, %rcx), %eax -+ movzbl (VEC_SIZE * 2)(%rsi, %rcx), %edx -+ sub %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+END (MEMCMP) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-memrchr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-memrchr-kbl.S -new file mode 100644 -index 000000000..a958fb56d ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-memrchr-kbl.S -@@ -0,0 +1,408 @@ -+/* memrchr optimized with AVX2. -+ Copyright (C) 2017-2019 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef L -+# define L(label) .L##label -+#endif -+ -+#ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+#endif -+ -+#ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+#endif -+ -+#ifndef cfi_rel_offset -+# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off -+#endif -+ -+#ifndef cfi_restore -+# define cfi_restore(reg) .cfi_restore reg -+#endif -+ -+#ifndef cfi_adjust_cfa_offset -+# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off -+#endif -+ -+#ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+#endif -+ -+#ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+#endif -+ -+#define CFI_PUSH(REG) \ -+ cfi_adjust_cfa_offset (4); \ -+ cfi_rel_offset (REG, 0) -+ -+#define CFI_POP(REG) \ -+ cfi_adjust_cfa_offset (-4); \ -+ cfi_restore (REG) -+ -+#define PUSH(REG) pushl REG; CFI_PUSH (REG) -+#define POP(REG) popl REG; CFI_POP (REG) -+ -+# ifndef MEMRCHR -+# define MEMRCHR memrchr_avx2 -+# endif -+ -+#ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (MEMRCHR) -+ /* Broadcast CHAR to YMM0. */ -+ vmovd %esi, %xmm0 -+ vpbroadcastb %xmm0, %ymm0 -+ -+ sub $VEC_SIZE, %rdx -+ jbe L(last_vec_or_less) -+ -+ add %rdx, %rdi -+ -+ /* Check the last VEC_SIZE bytes. */ -+ vpcmpeqb (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x0) -+ -+ subq $(VEC_SIZE * 4), %rdi -+ movl %edi, %ecx -+ andl $(VEC_SIZE - 1), %ecx -+ jz L(aligned_more) -+ -+ /* Align data for aligned loads in the loop. */ -+ addq $VEC_SIZE, %rdi -+ addq $VEC_SIZE, %rdx -+ andq $-VEC_SIZE, %rdi -+ subq %rcx, %rdx -+ -+ .p2align 4 -+L(aligned_more): -+ subq $(VEC_SIZE * 4), %rdx -+ jbe L(last_4x_vec_or_less) -+ -+ /* Check the last 4 * VEC_SIZE. Only one VEC_SIZE at a time -+ since data is only aligned to VEC_SIZE. */ -+ vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x3) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm2 -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x2) -+ -+ vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm3 -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x1) -+ -+ vpcmpeqb (%rdi), %ymm0, %ymm4 -+ vpmovmskb %ymm4, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x0) -+ -+ /* Align data to 4 * VEC_SIZE for loop with fewer branches. -+ There are some overlaps with above if data isn't aligned -+ to 4 * VEC_SIZE. */ -+ movl %edi, %ecx -+ andl $(VEC_SIZE * 4 - 1), %ecx -+ jz L(loop_4x_vec) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ addq $(VEC_SIZE * 4), %rdx -+ andq $-(VEC_SIZE * 4), %rdi -+ subq %rcx, %rdx -+ -+ .p2align 4 -+L(loop_4x_vec): -+ /* Compare 4 * VEC at a time forward. */ -+ subq $(VEC_SIZE * 4), %rdi -+ subq $(VEC_SIZE * 4), %rdx -+ jbe L(last_4x_vec_or_less) -+ -+ vmovdqa (%rdi), %ymm1 -+ vmovdqa VEC_SIZE(%rdi), %ymm2 -+ vmovdqa (VEC_SIZE * 2)(%rdi), %ymm3 -+ vmovdqa (VEC_SIZE * 3)(%rdi), %ymm4 -+ -+ vpcmpeqb %ymm1, %ymm0, %ymm1 -+ vpcmpeqb %ymm2, %ymm0, %ymm2 -+ vpcmpeqb %ymm3, %ymm0, %ymm3 -+ vpcmpeqb %ymm4, %ymm0, %ymm4 -+ -+ vpor %ymm1, %ymm2, %ymm5 -+ vpor %ymm3, %ymm4, %ymm6 -+ vpor %ymm5, %ymm6, %ymm5 -+ -+ vpmovmskb %ymm5, %eax -+ testl %eax, %eax -+ jz L(loop_4x_vec) -+ -+ /* There is a match. */ -+ vpmovmskb %ymm4, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x3) -+ -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x2) -+ -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x1) -+ -+ vpmovmskb %ymm1, %eax -+ bsrl %eax, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_4x_vec_or_less): -+ addl $(VEC_SIZE * 4), %edx -+ cmpl $(VEC_SIZE * 2), %edx -+ jbe L(last_2x_vec) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x3) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm2 -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x2) -+ -+ vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm3 -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x1_check) -+ cmpl $(VEC_SIZE * 3), %edx -+ jbe L(zero) -+ -+ vpcmpeqb (%rdi), %ymm0, %ymm4 -+ vpmovmskb %ymm4, %eax -+ testl %eax, %eax -+ jz L(zero) -+ bsrl %eax, %eax -+ subq $(VEC_SIZE * 4), %rdx -+ addq %rax, %rdx -+ jl L(zero) -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_2x_vec): -+ vpcmpeqb (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(last_vec_x3_check) -+ cmpl $VEC_SIZE, %edx -+ jbe L(zero) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jz L(zero) -+ bsrl %eax, %eax -+ subq $(VEC_SIZE * 2), %rdx -+ addq %rax, %rdx -+ jl L(zero) -+ addl $(VEC_SIZE * 2), %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_x0): -+ bsrl %eax, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_x1): -+ bsrl %eax, %eax -+ addl $VEC_SIZE, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_x2): -+ bsrl %eax, %eax -+ addl $(VEC_SIZE * 2), %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_x3): -+ bsrl %eax, %eax -+ addl $(VEC_SIZE * 3), %eax -+ addq %rdi, %rax -+ ret -+ -+ .p2align 4 -+L(last_vec_x1_check): -+ bsrl %eax, %eax -+ subq $(VEC_SIZE * 3), %rdx -+ addq %rax, %rdx -+ jl L(zero) -+ addl $VEC_SIZE, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_x3_check): -+ bsrl %eax, %eax -+ subq $VEC_SIZE, %rdx -+ addq %rax, %rdx -+ jl L(zero) -+ addl $(VEC_SIZE * 3), %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(zero): -+ VZEROUPPER -+L(null): -+ xorl %eax, %eax -+ ret -+ -+ .p2align 4 -+L(last_vec_or_less_aligned): -+ movl %edx, %ecx -+ -+ vpcmpeqb (%rdi), %ymm0, %ymm1 -+ -+ movl $1, %edx -+ /* Support rdx << 32. */ -+ salq %cl, %rdx -+ subq $1, %rdx -+ -+ vpmovmskb %ymm1, %eax -+ -+ /* Remove the trailing bytes. */ -+ andl %edx, %eax -+ testl %eax, %eax -+ jz L(zero) -+ -+ bsrl %eax, %eax -+ addq %rdi, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_or_less): -+ addl $VEC_SIZE, %edx -+ -+ /* Check for zero length. */ -+ testl %edx, %edx -+ jz L(null) -+ -+ movl %edi, %ecx -+ andl $(VEC_SIZE - 1), %ecx -+ jz L(last_vec_or_less_aligned) -+ -+ movl %ecx, %esi -+ movl %ecx, %r8d -+ addl %edx, %esi -+ andq $-VEC_SIZE, %rdi -+ -+ subl $VEC_SIZE, %esi -+ ja L(last_vec_2x_aligned) -+ -+ /* Check the last VEC. */ -+ vpcmpeqb (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ -+ /* Remove the leading and trailing bytes. */ -+ sarl %cl, %eax -+ movl %edx, %ecx -+ -+ movl $1, %edx -+ sall %cl, %edx -+ subl $1, %edx -+ -+ andl %edx, %eax -+ testl %eax, %eax -+ jz L(zero) -+ -+ bsrl %eax, %eax -+ addq %rdi, %rax -+ addq %r8, %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_vec_2x_aligned): -+ movl %esi, %ecx -+ -+ /* Check the last VEC. */ -+ vpcmpeqb VEC_SIZE(%rdi), %ymm0, %ymm1 -+ -+ movl $1, %edx -+ sall %cl, %edx -+ subl $1, %edx -+ -+ vpmovmskb %ymm1, %eax -+ -+ /* Remove the trailing bytes. */ -+ andl %edx, %eax -+ -+ testl %eax, %eax -+ jnz L(last_vec_x1) -+ -+ /* Check the second last VEC. */ -+ vpcmpeqb (%rdi), %ymm0, %ymm1 -+ -+ movl %r8d, %ecx -+ -+ vpmovmskb %ymm1, %eax -+ -+ /* Remove the leading bytes. Must use unsigned right shift for -+ bsrl below. */ -+ shrl %cl, %eax -+ testl %eax, %eax -+ jz L(zero) -+ -+ bsrl %eax, %eax -+ addq %rdi, %rax -+ addq %r8, %rax -+ VZEROUPPER -+ ret -+END (MEMRCHR) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wmemset-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wmemset-kbl.S -new file mode 100644 -index 000000000..7c485cf70 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wmemset-kbl.S -@@ -0,0 +1,140 @@ -+/* -+Copyright (C) 2019 The Android Open Source Project -+All rights reserved. -+ -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions -+are met: -+ * Redistributions of source code must retain the above copyright -+ notice, this list of conditions and the following disclaimer. -+ * Redistributions in binary form must reproduce the above copyright -+ notice, this list of conditions and the following disclaimer in -+ the documentation and/or other materials provided with the -+ distribution. -+ -+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+SUCH DAMAGE. -+*/ -+ -+#include -+ -+#ifndef WMEMSET -+ #define WMEMSET wmemset_avx2 -+#endif -+ -+ .section .text.avx2,"ax",@progbits -+ -+ENTRY (WMEMSET) -+# BB#0: -+ testq %rdx, %rdx -+ je .LBB0_14 -+# BB#1: -+ cmpq $32, %rdx -+ jae .LBB0_3 -+# BB#2: -+ xorl %r8d, %r8d -+ movq %rdi, %rax -+ jmp .LBB0_12 -+.LBB0_3: -+ movq %rdx, %r8 -+ andq $-32, %r8 -+ vmovd %esi, %xmm0 -+ vpbroadcastd %xmm0, %ymm0 -+ leaq -32(%r8), %rcx -+ movq %rcx, %rax -+ shrq $5, %rax -+ leal 1(%rax), %r9d -+ andl $7, %r9d -+ cmpq $224, %rcx -+ jae .LBB0_5 -+# BB#4: -+ xorl %eax, %eax -+ testq %r9, %r9 -+ jne .LBB0_8 -+ jmp .LBB0_10 -+.LBB0_5: -+ leaq 992(%rdi), %rcx -+ leaq -1(%r9), %r10 -+ subq %rax, %r10 -+ xorl %eax, %eax -+ .p2align 4, 0x90 -+.LBB0_6: # =>This Inner Loop Header: Depth=1 -+ vmovdqu %ymm0, -992(%rcx,%rax,4) -+ vmovdqu %ymm0, -960(%rcx,%rax,4) -+ vmovdqu %ymm0, -928(%rcx,%rax,4) -+ vmovdqu %ymm0, -896(%rcx,%rax,4) -+ vmovdqu %ymm0, -864(%rcx,%rax,4) -+ vmovdqu %ymm0, -832(%rcx,%rax,4) -+ vmovdqu %ymm0, -800(%rcx,%rax,4) -+ vmovdqu %ymm0, -768(%rcx,%rax,4) -+ vmovdqu %ymm0, -736(%rcx,%rax,4) -+ vmovdqu %ymm0, -704(%rcx,%rax,4) -+ vmovdqu %ymm0, -672(%rcx,%rax,4) -+ vmovdqu %ymm0, -640(%rcx,%rax,4) -+ vmovdqu %ymm0, -608(%rcx,%rax,4) -+ vmovdqu %ymm0, -576(%rcx,%rax,4) -+ vmovdqu %ymm0, -544(%rcx,%rax,4) -+ vmovdqu %ymm0, -512(%rcx,%rax,4) -+ vmovdqu %ymm0, -480(%rcx,%rax,4) -+ vmovdqu %ymm0, -448(%rcx,%rax,4) -+ vmovdqu %ymm0, -416(%rcx,%rax,4) -+ vmovdqu %ymm0, -384(%rcx,%rax,4) -+ vmovdqu %ymm0, -352(%rcx,%rax,4) -+ vmovdqu %ymm0, -320(%rcx,%rax,4) -+ vmovdqu %ymm0, -288(%rcx,%rax,4) -+ vmovdqu %ymm0, -256(%rcx,%rax,4) -+ vmovdqu %ymm0, -224(%rcx,%rax,4) -+ vmovdqu %ymm0, -192(%rcx,%rax,4) -+ vmovdqu %ymm0, -160(%rcx,%rax,4) -+ vmovdqu %ymm0, -128(%rcx,%rax,4) -+ vmovdqu %ymm0, -96(%rcx,%rax,4) -+ vmovdqu %ymm0, -64(%rcx,%rax,4) -+ vmovdqu %ymm0, -32(%rcx,%rax,4) -+ vmovdqu %ymm0, (%rcx,%rax,4) -+ addq $256, %rax # imm = 0x100 -+ addq $8, %r10 -+ jne .LBB0_6 -+# BB#7: -+ testq %r9, %r9 -+ je .LBB0_10 -+.LBB0_8: -+ leaq (%rdi,%rax,4), %rax -+ addq $96, %rax -+ negq %r9 -+ .p2align 4, 0x90 -+.LBB0_9: # =>This Inner Loop Header: Depth=1 -+ vmovdqu %ymm0, -96(%rax) -+ vmovdqu %ymm0, -64(%rax) -+ vmovdqu %ymm0, -32(%rax) -+ vmovdqu %ymm0, (%rax) -+ subq $-128, %rax -+ addq $1, %r9 -+ jne .LBB0_9 -+.LBB0_10: -+ cmpq %rdx, %r8 -+ je .LBB0_14 -+# BB#11: -+ leaq (%rdi,%r8,4), %rax -+.LBB0_12: -+ subq %r8, %rdx -+ .p2align 4, 0x90 -+.LBB0_13: # =>This Inner Loop Header: Depth=1 -+ movl %esi, (%rax) -+ addq $4, %rax -+ addq $-1, %rdx -+ jne .LBB0_13 -+.LBB0_14: -+ movq %rdi, %rax -+ vzeroupper -+ retq -+END(WMEMSET) -diff --git a/libc/arch-x86_64/string/sse2-memmove-slm.S b/libc/arch-x86_64/silvermont/string/sse2-memmove-slm.S -similarity index 99% -rename from libc/arch-x86_64/string/sse2-memmove-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-memmove-slm.S -index 739502888..7024f4950 100644 ---- a/libc/arch-x86_64/string/sse2-memmove-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-memmove-slm.S -@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #include "cache.h" - - #ifndef MEMMOVE --# define MEMMOVE memmove -+# define MEMMOVE memmove_generic - #endif - - #ifndef L -@@ -515,4 +515,4 @@ L(mm_large_page_loop_backward): - - END (MEMMOVE) - --ALIAS_SYMBOL(memcpy, MEMMOVE) -+//ALIAS_SYMBOL(memcpy, MEMMOVE) -diff --git a/libc/arch-x86_64/string/sse2-memset-slm.S b/libc/arch-x86_64/silvermont/string/sse2-memset-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-memset-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-memset-slm.S -diff --git a/libc/arch-x86_64/string/sse2-stpcpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-stpcpy-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S -diff --git a/libc/arch-x86_64/string/sse2-stpncpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-stpncpy-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S -diff --git a/libc/arch-x86_64/string/sse2-strcat-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-strcat-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S -diff --git a/libc/arch-x86_64/string/sse2-strcpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-strcpy-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S -diff --git a/libc/arch-x86_64/string/sse2-strlen-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-strlen-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S -diff --git a/libc/arch-x86_64/string/sse2-strncat-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-strncat-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S -diff --git a/libc/arch-x86_64/string/sse2-strncpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/sse2-strncpy-slm.S -rename to libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S -diff --git a/libc/arch-x86_64/string/sse4-memcmp-slm.S b/libc/arch-x86_64/silvermont/string/sse4-memcmp-slm.S -similarity index 99% -rename from libc/arch-x86_64/string/sse4-memcmp-slm.S -rename to libc/arch-x86_64/silvermont/string/sse4-memcmp-slm.S -index 8a8b180a2..6cfcd767f 100644 ---- a/libc/arch-x86_64/string/sse4-memcmp-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse4-memcmp-slm.S -@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #include "cache.h" - - #ifndef MEMCMP --# define MEMCMP memcmp -+# define MEMCMP memcmp_generic - #endif - - #ifndef L -diff --git a/libc/arch-x86_64/string/ssse3-strcmp-slm.S b/libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/ssse3-strcmp-slm.S -rename to libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S -diff --git a/libc/arch-x86_64/string/ssse3-strncmp-slm.S b/libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S -similarity index 100% -rename from libc/arch-x86_64/string/ssse3-strncmp-slm.S -rename to libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S -diff --git a/libc/arch-x86_64/static_function_dispatch.S b/libc/arch-x86_64/static_function_dispatch.S -index 93ff5f2fc..979ce4f18 100644 ---- a/libc/arch-x86_64/static_function_dispatch.S -+++ b/libc/arch-x86_64/static_function_dispatch.S -@@ -35,3 +35,9 @@ END(name) - - FUNCTION_DELEGATE(memset, memset_generic) - FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic) -+FUNCTION_DELEGATE(memcmp, memcmp_generic) -+FUNCTION_DELEGATE(memcpy, memmove_generic) -+FUNCTION_DELEGATE(memmove, memmove_generic) -+FUNCTION_DELEGATE(memchr, memchr_openbsd) -+FUNCTION_DELEGATE(memrchr, memrchr_openbsd) -+//FUNCTION_DELEGATE(wmemset, wmemset_freebsd) --- -2.17.1 - diff --git a/aosp_diff/preliminary/bionic/0001-Update-libdl-bionic-library.patch b/aosp_diff/preliminary/bionic/0001-Update-libdl-bionic-library.patch new file mode 100644 index 0000000000..19c4f1c32c --- /dev/null +++ b/aosp_diff/preliminary/bionic/0001-Update-libdl-bionic-library.patch @@ -0,0 +1,32 @@ +From 6457265356586871249a2a946dc575662cbb6b76 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Tue, 18 Jun 2024 09:37:00 +0530 +Subject: [PATCH] Update libdl bionic library. + +Snapuserd module is dependent on libdl bionic library. Since snapuserd +should be apex platform avaiable, then dependent libdl library should +also be make apex platform avaiable. + +Tests: Build the EB, there was no issue in these two modules. + +Tracked-On: NA +Signed-off-by: Ankit Agarwal +--- + libdl/Android.bp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libdl/Android.bp b/libdl/Android.bp +index 95b412b96..533d39f29 100644 +--- a/libdl/Android.bp ++++ b/libdl/Android.bp +@@ -48,6 +48,7 @@ cc_library_static { + never: true, + }, + apex_available: [ ++ "//apex_available:platform", + "com.android.runtime", + ], + } +-- +2.34.1 + diff --git a/aosp_diff/preliminary/bionic/0002-Optimize-bionic-string-functions-with-avx-implementa.patch b/aosp_diff/preliminary/bionic/0002-Optimize-bionic-string-functions-with-avx-implementa.patch deleted file mode 100644 index d54f8636d5..0000000000 --- a/aosp_diff/preliminary/bionic/0002-Optimize-bionic-string-functions-with-avx-implementa.patch +++ /dev/null @@ -1,4271 +0,0 @@ -From d4be5441a2e787541ac5cba6ded7b281950bff12 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Thu, 14 Sep 2023 18:38:22 +0530 -Subject: [PATCH] Optimize bionic string functions with avx implementation - -Following are the string functions that has been -optimized with avx2 implementation from glibc 2.32 version. - - strcmp, strncmp - - strlen, strnlen - - strchr, strrchr - - strcpy, strncpy - - stpcpy, stpncpy - - strcat, strncat - - wcscmp, wcsncmp - - wcslen, wcsnlen - - wcschr, wcsrchr - -Change-Id: I7f08a7507d25447ce886e9fde0482527c3f7a178 -Signed-off-by: ahs ---- - libc/Android.bp | 54 +- - .../arch-x86_64/dynamic_function_dispatch.cpp | 133 ++- - .../dynamic_function_dispatch.cpp.orig | 87 ++ - libc/arch-x86_64/generic/string/memchr.c | 2 +- - libc/arch-x86_64/generic/string/memrchr.c | 2 +- - libc/arch-x86_64/generic/string/strchr.cpp | 19 + - libc/arch-x86_64/generic/string/strnlen.c | 19 + - libc/arch-x86_64/generic/string/strrchr.cpp | 19 + - libc/arch-x86_64/generic/string/wcschr.c | 19 + - libc/arch-x86_64/generic/string/wcscmp.c | 19 + - libc/arch-x86_64/generic/string/wcslen.c | 19 + - libc/arch-x86_64/generic/string/wcsncmp.c | 19 + - libc/arch-x86_64/generic/string/wcsnlen.c | 19 + - libc/arch-x86_64/generic/string/wcsrchr.c | 19 + - libc/arch-x86_64/generic/string/wmemset.c | 2 +- - .../{ => kabylake}/string/avx2-memset-kbl.S | 0 - .../kabylake/string/avx2-stpcpy-kbl.S | 3 + - .../kabylake/string/avx2-stpncpy-kbl.S | 5 + - .../kabylake/string/avx2-strcat-kbl.S | 299 +++++ - .../kabylake/string/avx2-strchr-kbl.S | 277 +++++ - .../kabylake/string/avx2-strcmp-kbl.S | 885 ++++++++++++++ - .../kabylake/string/avx2-strcpy-kbl.S | 1046 +++++++++++++++++ - .../kabylake/string/avx2-strlen-kbl.S | 418 +++++++ - .../kabylake/string/avx2-strncat-kbl.S | 3 + - .../kabylake/string/avx2-strncmp-kbl.S | 4 + - .../kabylake/string/avx2-strncpy-kbl.S | 4 + - .../kabylake/string/avx2-strnlen-kbl.S | 4 + - .../kabylake/string/avx2-strrchr-kbl.S | 258 ++++ - .../kabylake/string/avx2-wcschr-kbl.S | 3 + - .../kabylake/string/avx2-wcscmp-kbl.S | 4 + - .../kabylake/string/avx2-wcslen-kbl.S | 4 + - .../kabylake/string/avx2-wcsncmp-kbl.S | 6 + - .../kabylake/string/avx2-wcsnlen-kbl.S | 6 + - .../kabylake/string/avx2-wcsrchr-kbl.S | 3 + - libc/arch-x86_64/kabylake/string/avx_regs.h | 26 + - .../{include => kabylake/string}/cache.h | 0 - libc/arch-x86_64/silvermont/string/cache.h | 36 + - .../silvermont/string/sse2-stpcpy-slm.S | 2 +- - .../silvermont/string/sse2-stpncpy-slm.S | 2 +- - .../silvermont/string/sse2-strcat-slm.S | 2 +- - .../silvermont/string/sse2-strcpy-slm.S | 2 +- - .../silvermont/string/sse2-strlen-slm.S | 2 +- - .../silvermont/string/sse2-strncat-slm.S | 2 +- - .../silvermont/string/sse2-strncpy-slm.S | 2 +- - .../silvermont/string/ssse3-strcmp-slm.S | 2 +- - .../silvermont/string/ssse3-strncmp-slm.S | 2 +- - libc/arch-x86_64/static_function_dispatch.S | 25 +- - 47 files changed, 3762 insertions(+), 26 deletions(-) - create mode 100644 libc/arch-x86_64/dynamic_function_dispatch.cpp.orig - create mode 100644 libc/arch-x86_64/generic/string/strchr.cpp - create mode 100644 libc/arch-x86_64/generic/string/strnlen.c - create mode 100644 libc/arch-x86_64/generic/string/strrchr.cpp - create mode 100644 libc/arch-x86_64/generic/string/wcschr.c - create mode 100644 libc/arch-x86_64/generic/string/wcscmp.c - create mode 100644 libc/arch-x86_64/generic/string/wcslen.c - create mode 100644 libc/arch-x86_64/generic/string/wcsncmp.c - create mode 100644 libc/arch-x86_64/generic/string/wcsnlen.c - create mode 100644 libc/arch-x86_64/generic/string/wcsrchr.c - rename libc/arch-x86_64/{ => kabylake}/string/avx2-memset-kbl.S (100%) - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-stpcpy-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-stpncpy-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strcat-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strchr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strcmp-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strcpy-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strlen-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strncat-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strncmp-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strncpy-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strnlen-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-strrchr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcschr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcscmp-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcslen-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcsncmp-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcsnlen-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-wcsrchr-kbl.S - create mode 100644 libc/arch-x86_64/kabylake/string/avx_regs.h - rename libc/arch-x86_64/{include => kabylake/string}/cache.h (100%) - create mode 100644 libc/arch-x86_64/silvermont/string/cache.h - -diff --git a/libc/Android.bp b/libc/Android.bp -index cb803a193..4a4aac198 100644 ---- a/libc/Android.bp -+++ b/libc/Android.bp -@@ -381,11 +381,18 @@ cc_library_static { - "upstream-freebsd/lib/libc/string/wmemcmp.c", - ], - }, -- //x86_64: { -- // exclude_srcs: [ -- // "upstream-freebsd/lib/libc/string/wmemset.c", -- // ], -- //}, -+ x86_64: { -+ exclude_srcs: [ -+ //"upstream-freebsd/lib/libc/string/wmemset.c", -+ "upstream-freebsd/lib/libc/string/wcscmp.c", -+ "upstream-freebsd/lib/libc/string/wcsncmp.c", -+ "upstream-freebsd/lib/libc/string/wcslen.c", -+ "upstream-freebsd/lib/libc/string/wcsnlen.c", -+ "upstream-freebsd/lib/libc/string/wcschr.c", -+ "upstream-freebsd/lib/libc/string/wcsrchr.c", -+ -+ ], -+ }, - }, - - cflags: [ -@@ -1010,13 +1017,11 @@ cc_library_static { - }, - x86_64: { - cflags: ["-include openbsd-compat.h"], -- include_dirs: ["bionic/libc/arch-x86_64/include"], - local_include_dirs: [ -- // "private", - "upstream-openbsd/android/include", - ], - srcs: [ -- "arch-x86_64/string/avx2-memset-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-memset-kbl.S", - "arch-x86_64/silvermont/string/sse2-memmove-slm.S", - "arch-x86_64/silvermont/string/sse2-memset-slm.S", - "arch-x86_64/silvermont/string/sse2-stpcpy-slm.S", -@@ -1033,11 +1038,38 @@ cc_library_static { - //"arch-x86_64/generic/string/wmemset.c" - "arch-x86_64/generic/string/memchr.c", - "arch-x86_64/generic/string/memrchr.c", -+ "arch-x86_64/generic/string/strchr.cpp", -+ "arch-x86_64/generic/string/strrchr.cpp", -+ "arch-x86_64/generic/string/strnlen.c", -+ "arch-x86_64/generic/string/wcscmp.c", -+ "arch-x86_64/generic/string/wcsncmp.c", -+ "arch-x86_64/generic/string/wcslen.c", -+ "arch-x86_64/generic/string/wcsnlen.c", -+ "arch-x86_64/generic/string/wcschr.c", -+ "arch-x86_64/generic/string/wcsrchr.c", - - //"arch-x86_64/kabylake/string/avx2-wmemset-kbl.S" - "arch-x86_64/kabylake/string/avx2-memcmp-kbl.S", - "arch-x86_64/kabylake/string/avx2-memchr-kbl.S", - "arch-x86_64/kabylake/string/avx2-memrchr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strcmp-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strncmp-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strlen-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strnlen-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strchr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strrchr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strcpy-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strncpy-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-stpcpy-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-stpncpy-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strcat-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-strncat-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcscmp-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcsncmp-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcslen-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcsnlen-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcschr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-wcsrchr-kbl.S", - - "arch-x86_64/bionic/__bionic_clone.S", - "arch-x86_64/bionic/_exit_with_stack_teardown.S", -@@ -1046,6 +1078,12 @@ cc_library_static { - "arch-x86_64/bionic/syscall.S", - "arch-x86_64/bionic/vfork.S", - ], -+ exclude_srcs: [ -+ "bionic/strchr.cpp", -+ "bionic/strnlen.c", -+ "bionic/strrchr.cpp", -+ ], -+ - }, - }, - -diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp b/libc/arch-x86_64/dynamic_function_dispatch.cpp -index 43aaebb54..182eb4200 100644 ---- a/libc/arch-x86_64/dynamic_function_dispatch.cpp -+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp -@@ -67,21 +67,148 @@ typedef void* memchr_func(const void* __s, int __ch, size_t __n); - DEFINE_IFUNC_FOR(memchr) { - __builtin_cpu_init(); - if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memchr_func, memchr_avx2); -- RETURN_FUNC(memchr_func, memchr_openbsd); -+ RETURN_FUNC(memchr_func, memchr_generic); - } - - typedef void* memrchr_func(const void* __s, int __ch, size_t __n); - DEFINE_IFUNC_FOR(memrchr) { - __builtin_cpu_init(); - if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memrchr_func, memrchr_avx2); -- RETURN_FUNC(memrchr_func, memrchr_openbsd); -+ RETURN_FUNC(memrchr_func, memrchr_generic); - } - - // typedef int wmemset_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n); - // DEFINE_IFUNC_FOR(wmemset) { - // __builtin_cpu_init(); - // if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wmemset_func, wmemset_avx2); --// RETURN_FUNC(wmemset_func, wmemset_freebsd); -+// RETURN_FUNC(wmemset_func, wmemset_generic); - // } - -+typedef int strcmp_func(const char* __lhs, const char* __rhs); -+DEFINE_IFUNC_FOR(strcmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strcmp_func, strcmp_avx2); -+ RETURN_FUNC(strcmp_func, strcmp_generic); -+} -+ -+typedef int strncmp_func(const char* __lhs, const char* __rhs, size_t __n); -+DEFINE_IFUNC_FOR(strncmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strncmp_func, strncmp_avx2); -+ RETURN_FUNC(strncmp_func, strncmp_generic); -+} -+ -+typedef char* strcpy_func(char* __dst, const char* __src); -+DEFINE_IFUNC_FOR(strcpy) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strcpy_func, strcpy_avx2); -+ RETURN_FUNC(strcpy_func, strcpy_generic); -+} -+ -+typedef char* strncpy_func(char* __dst, const char* __src, size_t __n); -+DEFINE_IFUNC_FOR(strncpy) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strncpy_func, strncpy_avx2); -+ RETURN_FUNC(strncpy_func, strncpy_generic); -+} -+ -+typedef char* stpcpy_func(char* __dst, const char* __src); -+DEFINE_IFUNC_FOR(stpcpy) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(stpcpy_func, stpcpy_avx2); -+ RETURN_FUNC(stpcpy_func, stpcpy_generic); -+} -+ -+typedef char* stpncpy_func(char* __dst, const char* __src, size_t __n); -+DEFINE_IFUNC_FOR(stpncpy) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(stpncpy_func, stpncpy_avx2); -+ RETURN_FUNC(stpncpy_func, stpncpy_generic); -+} -+ -+typedef size_t strlen_func(const char* __s); -+DEFINE_IFUNC_FOR(strlen) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strlen_func, strlen_avx2); -+ RETURN_FUNC(strlen_func, strlen_generic); -+} -+ -+ -+typedef size_t strnlen_func(const char* __s, size_t __n); -+DEFINE_IFUNC_FOR(strnlen) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strnlen_func, strnlen_avx2); -+ RETURN_FUNC(strnlen_func, strnlen_generic); -+} -+ -+typedef char* strchr_func(const char* __s, int __ch); -+DEFINE_IFUNC_FOR(strchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strchr_func, strchr_avx2); -+ RETURN_FUNC(strchr_func, strchr_generic); -+} -+ -+typedef char* strrchr_func(const char* __s, int __ch); -+DEFINE_IFUNC_FOR(strrchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strrchr_func, strrchr_avx2); -+ RETURN_FUNC(strrchr_func, strrchr_generic); -+} -+ -+typedef char* strcat_func(char* __dst, const char* __src); -+DEFINE_IFUNC_FOR(strcat) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strcat_func, strcat_avx2); -+ RETURN_FUNC(strcat_func, strcat_generic); -+} -+ -+typedef char* strncat_func(char* __dst, const char* __src, size_t __n); -+DEFINE_IFUNC_FOR(strncat) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(strncat_func, strncat_avx2); -+ RETURN_FUNC(strncat_func, strncat_generic); -+} -+ -+typedef int wcscmp_func(const wchar_t* __lhs, const wchar_t* __rhs); -+DEFINE_IFUNC_FOR(wcscmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcscmp_func, wcscmp_avx2); -+ RETURN_FUNC(wcscmp_func, wcscmp_generic); -+} -+ -+typedef int wcsncmp_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n); -+DEFINE_IFUNC_FOR(wcsncmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcsncmp_func, wcsncmp_avx2); -+ RETURN_FUNC(wcsncmp_func, wcsncmp_generic); -+} -+ -+typedef size_t wcslen_func(const wchar_t* __s); -+DEFINE_IFUNC_FOR(wcslen) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcslen_func, wcslen_avx2); -+ RETURN_FUNC(wcslen_func, wcslen_generic); -+} -+ -+typedef size_t wcsnlen_func(const wchar_t* __s, size_t __n); -+DEFINE_IFUNC_FOR(wcsnlen) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcsnlen_func, wcsnlen_avx2); -+ RETURN_FUNC(wcsnlen_func, wcsnlen_generic); -+} -+ -+typedef wchar_t* wcschr_func(const wchar_t* __s, wchar_t __wc); -+DEFINE_IFUNC_FOR(wcschr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcschr_func, wcschr_avx2); -+ RETURN_FUNC(wcschr_func, wcschr_generic); -+} -+ -+typedef wchar_t* wcsrchr_func(const wchar_t* __s, wchar_t __wc); -+DEFINE_IFUNC_FOR(wcsrchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wcsrchr_func, wcsrchr_avx2); -+ RETURN_FUNC(wcsrchr_func, wcsrchr_generic); -+} -+ - } // extern "C" -diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp.orig b/libc/arch-x86_64/dynamic_function_dispatch.cpp.orig -new file mode 100644 -index 000000000..43aaebb54 ---- /dev/null -+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp.orig -@@ -0,0 +1,87 @@ -+/* -+ * Copyright (C) 2022 The Android Open Source Project -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * * Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * * Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED -+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+#include -+ -+#include -+ -+extern "C" { -+ -+typedef int memset_func(void* __dst, int __ch, size_t __n); -+DEFINE_IFUNC_FOR(memset) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memset_func, memset_avx2); -+ RETURN_FUNC(memset_func, memset_generic); -+} -+ -+typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2); -+DEFINE_IFUNC_FOR(__memset_chk) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(__memset_chk_func, __memset_chk_avx2); -+ RETURN_FUNC(__memset_chk_func, __memset_chk_generic); -+} -+ -+typedef int memcmp_func(const void* __lhs, const void* __rhs, size_t __n); -+DEFINE_IFUNC_FOR(memcmp) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memcmp_func, memcmp_avx2) -+ RETURN_FUNC(memcmp_func, memcmp_generic); -+} -+ -+typedef void* memmove_func(void* __dst, const void* __src, size_t __n); -+DEFINE_IFUNC_FOR(memmove) { -+ RETURN_FUNC(memmove_func, memmove_generic); -+} -+ -+typedef void* memcpy_func(void* __dst, const void* __src, size_t __n); -+DEFINE_IFUNC_FOR(memcpy) { -+ return memmove_resolver(); -+} -+ -+typedef void* memchr_func(const void* __s, int __ch, size_t __n); -+DEFINE_IFUNC_FOR(memchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memchr_func, memchr_avx2); -+ RETURN_FUNC(memchr_func, memchr_openbsd); -+} -+ -+typedef void* memrchr_func(const void* __s, int __ch, size_t __n); -+DEFINE_IFUNC_FOR(memrchr) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memrchr_func, memrchr_avx2); -+ RETURN_FUNC(memrchr_func, memrchr_openbsd); -+} -+ -+// typedef int wmemset_func(const wchar_t* __lhs, const wchar_t* __rhs, size_t __n); -+// DEFINE_IFUNC_FOR(wmemset) { -+// __builtin_cpu_init(); -+// if (__builtin_cpu_supports("avx2")) RETURN_FUNC(wmemset_func, wmemset_avx2); -+// RETURN_FUNC(wmemset_func, wmemset_freebsd); -+// } -+ -+} // extern "C" -diff --git a/libc/arch-x86_64/generic/string/memchr.c b/libc/arch-x86_64/generic/string/memchr.c -index f530eaca8..fccf0296d 100644 ---- a/libc/arch-x86_64/generic/string/memchr.c -+++ b/libc/arch-x86_64/generic/string/memchr.c -@@ -14,6 +14,6 @@ - * limitations under the License. - */ - --#define memchr memchr_openbsd -+#define memchr memchr_generic - - #include -diff --git a/libc/arch-x86_64/generic/string/memrchr.c b/libc/arch-x86_64/generic/string/memrchr.c -index 44262f2d1..7525474b2 100644 ---- a/libc/arch-x86_64/generic/string/memrchr.c -+++ b/libc/arch-x86_64/generic/string/memrchr.c -@@ -14,6 +14,6 @@ - * limitations under the License. - */ - --#define memrchr memrchr_openbsd -+#define memrchr memrchr_generic - - #include -diff --git a/libc/arch-x86_64/generic/string/strchr.cpp b/libc/arch-x86_64/generic/string/strchr.cpp -new file mode 100644 -index 000000000..8a3d6d619 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/strchr.cpp -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define strchr strchr_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/strnlen.c b/libc/arch-x86_64/generic/string/strnlen.c -new file mode 100644 -index 000000000..f47adbdab ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/strnlen.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define strnlen strnlen_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/strrchr.cpp b/libc/arch-x86_64/generic/string/strrchr.cpp -new file mode 100644 -index 000000000..9f0f33fd2 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/strrchr.cpp -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define strrchr strrchr_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcschr.c b/libc/arch-x86_64/generic/string/wcschr.c -new file mode 100644 -index 000000000..d45e45d20 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcschr.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcschr wcschr_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcscmp.c b/libc/arch-x86_64/generic/string/wcscmp.c -new file mode 100644 -index 000000000..e55bab549 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcscmp.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcscmp wcscmp_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcslen.c b/libc/arch-x86_64/generic/string/wcslen.c -new file mode 100644 -index 000000000..5b873fc30 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcslen.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcslen wcslen_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcsncmp.c b/libc/arch-x86_64/generic/string/wcsncmp.c -new file mode 100644 -index 000000000..40b2ca2f3 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcsncmp.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcsncmp wcsncmp_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcsnlen.c b/libc/arch-x86_64/generic/string/wcsnlen.c -new file mode 100644 -index 000000000..91051cea7 ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcsnlen.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcsnlen wcsnlen_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wcsrchr.c b/libc/arch-x86_64/generic/string/wcsrchr.c -new file mode 100644 -index 000000000..73e8c25bc ---- /dev/null -+++ b/libc/arch-x86_64/generic/string/wcsrchr.c -@@ -0,0 +1,19 @@ -+/* -+ * Copyright (C) 2019 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. -+*/ -+ -+#define wcsrchr wcsrchr_generic -+ -+#include -diff --git a/libc/arch-x86_64/generic/string/wmemset.c b/libc/arch-x86_64/generic/string/wmemset.c -index 35d489f44..42de09a1a 100644 ---- a/libc/arch-x86_64/generic/string/wmemset.c -+++ b/libc/arch-x86_64/generic/string/wmemset.c -@@ -14,6 +14,6 @@ - * limitations under the License. - */ - --#define wmemset wmemset_freebsd -+#define wmemset wmemset_generic - - #include -diff --git a/libc/arch-x86_64/string/avx2-memset-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-memset-kbl.S -similarity index 100% -rename from libc/arch-x86_64/string/avx2-memset-kbl.S -rename to libc/arch-x86_64/kabylake/string/avx2-memset-kbl.S -diff --git a/libc/arch-x86_64/kabylake/string/avx2-stpcpy-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-stpcpy-kbl.S -new file mode 100644 -index 000000000..63f9ba25b ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-stpcpy-kbl.S -@@ -0,0 +1,3 @@ -+#define USE_AS_STPCPY -+#define STRCPY stpcpy_avx2 -+#include "avx2-strcpy-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-stpncpy-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-stpncpy-kbl.S -new file mode 100644 -index 000000000..c1bbdb29e ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-stpncpy-kbl.S -@@ -0,0 +1,5 @@ -+#define USE_AS_STPCPY -+#define USE_AS_STRNCPY -+#define STRCPY stpncpy_avx2 -+#include "avx_regs.h" -+#include "avx2-strcpy-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strcat-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strcat-kbl.S -new file mode 100644 -index 000000000..d1e9b4b38 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strcat-kbl.S -@@ -0,0 +1,299 @@ -+/* strcat with AVX2 -+ Copyright (C) 2011-2020 Free Software Foundation, Inc. -+ Contributed by Intel Corporation. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+ -+ -+# ifndef STRCAT -+# define STRCAT strcat_avx2 -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+# define USE_AS_STRCAT -+ -+/* Number of bytes in a vector register */ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRCAT) -+ mov %rdi, %r9 -+# ifdef USE_AS_STRNCAT -+ mov %rdx, %r8 -+# endif -+ -+ xor %eax, %eax -+ mov %edi, %ecx -+ and $((VEC_SIZE * 4) - 1), %ecx -+ vpxor %xmm6, %xmm6, %xmm6 -+ cmp $(VEC_SIZE * 3), %ecx -+ ja L(fourth_vector_boundary) -+ vpcmpeqb (%rdi), %ymm6, %ymm0 -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_first_vector) -+ mov %rdi, %rax -+ and $-VEC_SIZE, %rax -+ jmp L(align_vec_size_start) -+L(fourth_vector_boundary): -+ mov %rdi, %rax -+ and $-VEC_SIZE, %rax -+ vpcmpeqb (%rax), %ymm6, %ymm0 -+ mov $-1, %r10d -+ sub %rax, %rcx -+ shl %cl, %r10d -+ vpmovmskb %ymm0, %edx -+ and %r10d, %edx -+ jnz L(exit) -+ -+L(align_vec_size_start): -+ vpcmpeqb VEC_SIZE(%rax), %ymm6, %ymm0 -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_second_vector) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rax), %ymm6, %ymm1 -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_third_vector) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rax), %ymm6, %ymm2 -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fourth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 4)(%rax), %ymm6, %ymm3 -+ vpmovmskb %ymm3, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fifth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 5)(%rax), %ymm6, %ymm0 -+ add $(VEC_SIZE * 4), %rax -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_second_vector) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rax), %ymm6, %ymm1 -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_third_vector) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rax), %ymm6, %ymm2 -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fourth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 4)(%rax), %ymm6, %ymm3 -+ vpmovmskb %ymm3, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fifth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 5)(%rax), %ymm6, %ymm0 -+ add $(VEC_SIZE * 4), %rax -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_second_vector) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rax), %ymm6, %ymm1 -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_third_vector) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rax), %ymm6, %ymm2 -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fourth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 4)(%rax), %ymm6, %ymm3 -+ vpmovmskb %ymm3, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fifth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 5)(%rax), %ymm6, %ymm0 -+ add $(VEC_SIZE * 4), %rax -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_second_vector) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rax), %ymm6, %ymm1 -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_third_vector) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rax), %ymm6, %ymm2 -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fourth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 4)(%rax), %ymm6, %ymm3 -+ vpmovmskb %ymm3, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fifth_vector) -+ -+ test $((VEC_SIZE * 4) - 1), %rax -+ jz L(align_four_vec_loop) -+ -+ vpcmpeqb (VEC_SIZE * 5)(%rax), %ymm6, %ymm0 -+ add $(VEC_SIZE * 5), %rax -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit) -+ -+ test $((VEC_SIZE * 4) - 1), %rax -+ jz L(align_four_vec_loop) -+ -+ vpcmpeqb VEC_SIZE(%rax), %ymm6, %ymm1 -+ add $VEC_SIZE, %rax -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit) -+ -+ test $((VEC_SIZE * 4) - 1), %rax -+ jz L(align_four_vec_loop) -+ -+ vpcmpeqb VEC_SIZE(%rax), %ymm6, %ymm2 -+ add $VEC_SIZE, %rax -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit) -+ -+ test $((VEC_SIZE * 4) - 1), %rax -+ jz L(align_four_vec_loop) -+ -+ vpcmpeqb VEC_SIZE(%rax), %ymm6, %ymm3 -+ add $VEC_SIZE, %rax -+ vpmovmskb %ymm3, %edx -+ test %edx, %edx -+ jnz L(exit) -+ -+ add $VEC_SIZE, %rax -+ -+ .p2align 4 -+L(align_four_vec_loop): -+ vmovaps (%rax), %ymm4 -+ vpminub VEC_SIZE(%rax), %ymm4, %ymm4 -+ vmovaps (VEC_SIZE * 2)(%rax), %ymm5 -+ vpminub (VEC_SIZE * 3)(%rax), %ymm5, %ymm5 -+ add $(VEC_SIZE * 4), %rax -+ vpminub %ymm4, %ymm5, %ymm5 -+ vpcmpeqb %ymm5, %ymm6, %ymm5 -+ vpmovmskb %ymm5, %edx -+ test %edx, %edx -+ jz L(align_four_vec_loop) -+ -+ vpcmpeqb -(VEC_SIZE * 4)(%rax), %ymm6, %ymm0 -+ sub $(VEC_SIZE * 5), %rax -+ vpmovmskb %ymm0, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_second_vector) -+ -+ vpcmpeqb (VEC_SIZE * 2)(%rax), %ymm6, %ymm1 -+ vpmovmskb %ymm1, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_third_vector) -+ -+ vpcmpeqb (VEC_SIZE * 3)(%rax), %ymm6, %ymm2 -+ vpmovmskb %ymm2, %edx -+ test %edx, %edx -+ jnz L(exit_null_on_fourth_vector) -+ -+ vpcmpeqb (VEC_SIZE * 4)(%rax), %ymm6, %ymm3 -+ vpmovmskb %ymm3, %edx -+ sub %rdi, %rax -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ add $(VEC_SIZE * 4), %rax -+ jmp L(StartStrcpyPart) -+ -+ .p2align 4 -+L(exit): -+ sub %rdi, %rax -+L(exit_null_on_first_vector): -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ jmp L(StartStrcpyPart) -+ -+ .p2align 4 -+L(exit_null_on_second_vector): -+ sub %rdi, %rax -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ add $VEC_SIZE, %rax -+ jmp L(StartStrcpyPart) -+ -+ .p2align 4 -+L(exit_null_on_third_vector): -+ sub %rdi, %rax -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ add $(VEC_SIZE * 2), %rax -+ jmp L(StartStrcpyPart) -+ -+ .p2align 4 -+L(exit_null_on_fourth_vector): -+ sub %rdi, %rax -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ add $(VEC_SIZE * 3), %rax -+ jmp L(StartStrcpyPart) -+ -+ .p2align 4 -+L(exit_null_on_fifth_vector): -+ sub %rdi, %rax -+ bsf %rdx, %rdx -+ add %rdx, %rax -+ add $(VEC_SIZE * 4), %rax -+ -+ .p2align 4 -+L(StartStrcpyPart): -+ lea (%r9, %rax), %rdi -+ mov %rsi, %rcx -+ mov %r9, %rax /* save result */ -+ -+# ifdef USE_AS_STRNCAT -+ test %r8, %r8 -+ jz L(ExitZero) -+# define USE_AS_STRNCPY -+# endif -+ -+# include "avx2-strcpy-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strchr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strchr-kbl.S -new file mode 100644 -index 000000000..7d8a44c81 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strchr-kbl.S -@@ -0,0 +1,277 @@ -+/* strchr/strchrnul optimized with AVX2. -+ Copyright (C) 2017-2020 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+ -+# ifndef STRCHR -+# define STRCHR strchr_avx2 -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+# ifdef USE_AS_WCSCHR -+# define VPBROADCAST vpbroadcastd -+# define VPCMPEQ vpcmpeqd -+# define CHAR_REG esi -+# else -+# define VPBROADCAST vpbroadcastb -+# define VPCMPEQ vpcmpeqb -+# define CHAR_REG sil -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRCHR) -+ movl %edi, %ecx -+ /* Broadcast CHAR to YMM0. */ -+ vmovd %esi, %xmm0 -+ vpxor %xmm9, %xmm9, %xmm9 -+ VPBROADCAST %xmm0, %ymm0 -+ /* Check if we may cross page boundary with one vector load. */ -+ andl $(2 * VEC_SIZE - 1), %ecx -+ cmpl $VEC_SIZE, %ecx -+ ja L(cros_page_boundary) -+ -+ /* Check the first VEC_SIZE bytes. Search for both CHAR and the -+ null byte. */ -+ vmovdqu (%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ /* Align data for aligned loads in the loop. */ -+ addq $VEC_SIZE, %rdi -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ -+ jmp L(more_4x_vec) -+ -+ .p2align 4 -+L(cros_page_boundary): -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ vmovdqu (%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ /* Remove the leading bytes. */ -+ sarl %cl, %eax -+ testl %eax, %eax -+ jz L(aligned_more) -+ /* Found CHAR or the null byte. */ -+ tzcntl %eax, %eax -+ addq %rcx, %rax -+# ifdef USE_AS_STRCHRNUL -+ addq %rdi, %rax -+# else -+ xorl %edx, %edx -+ leaq (%rdi, %rax), %rax -+ cmp (%rax), %CHAR_REG -+ cmovne %rdx, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(aligned_more): -+ addq $VEC_SIZE, %rdi -+ -+L(more_4x_vec): -+ /* Check the first 4 * VEC_SIZE. Only one VEC_SIZE at a time -+ since data is only aligned to VEC_SIZE. */ -+ vmovdqa (%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ vmovdqa VEC_SIZE(%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ -+ vmovdqa (VEC_SIZE * 2)(%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ -+ vmovdqa (VEC_SIZE * 3)(%rdi), %ymm8 -+ VPCMPEQ %ymm8, %ymm0, %ymm1 -+ VPCMPEQ %ymm8, %ymm9, %ymm2 -+ vpor %ymm1, %ymm2, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x3) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+ /* Align data to 4 * VEC_SIZE. */ -+ movq %rdi, %rcx -+ andl $(4 * VEC_SIZE - 1), %ecx -+ andq $-(4 * VEC_SIZE), %rdi -+ -+ .p2align 4 -+L(loop_4x_vec): -+ /* Compare 4 * VEC at a time forward. */ -+ vmovdqa (%rdi), %ymm5 -+ vmovdqa VEC_SIZE(%rdi), %ymm6 -+ vmovdqa (VEC_SIZE * 2)(%rdi), %ymm7 -+ vmovdqa (VEC_SIZE * 3)(%rdi), %ymm8 -+ -+ VPCMPEQ %ymm5, %ymm0, %ymm1 -+ VPCMPEQ %ymm6, %ymm0, %ymm2 -+ VPCMPEQ %ymm7, %ymm0, %ymm3 -+ VPCMPEQ %ymm8, %ymm0, %ymm4 -+ -+ VPCMPEQ %ymm5, %ymm9, %ymm5 -+ VPCMPEQ %ymm6, %ymm9, %ymm6 -+ VPCMPEQ %ymm7, %ymm9, %ymm7 -+ VPCMPEQ %ymm8, %ymm9, %ymm8 -+ -+ vpor %ymm1, %ymm5, %ymm1 -+ vpor %ymm2, %ymm6, %ymm2 -+ vpor %ymm3, %ymm7, %ymm3 -+ vpor %ymm4, %ymm8, %ymm4 -+ -+ vpor %ymm1, %ymm2, %ymm5 -+ vpor %ymm3, %ymm4, %ymm6 -+ -+ vpor %ymm5, %ymm6, %ymm5 -+ -+ vpmovmskb %ymm5, %eax -+ testl %eax, %eax -+ jnz L(4x_vec_end) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+ jmp L(loop_4x_vec) -+ -+ .p2align 4 -+L(first_vec_x0): -+ /* Found CHAR or the null byte. */ -+ tzcntl %eax, %eax -+# ifdef USE_AS_STRCHRNUL -+ addq %rdi, %rax -+# else -+ xorl %edx, %edx -+ leaq (%rdi, %rax), %rax -+ cmp (%rax), %CHAR_REG -+ cmovne %rdx, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x1): -+ tzcntl %eax, %eax -+# ifdef USE_AS_STRCHRNUL -+ addq $VEC_SIZE, %rax -+ addq %rdi, %rax -+# else -+ xorl %edx, %edx -+ leaq VEC_SIZE(%rdi, %rax), %rax -+ cmp (%rax), %CHAR_REG -+ cmovne %rdx, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x2): -+ tzcntl %eax, %eax -+# ifdef USE_AS_STRCHRNUL -+ addq $(VEC_SIZE * 2), %rax -+ addq %rdi, %rax -+# else -+ xorl %edx, %edx -+ leaq (VEC_SIZE * 2)(%rdi, %rax), %rax -+ cmp (%rax), %CHAR_REG -+ cmovne %rdx, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(4x_vec_end): -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ vpmovmskb %ymm4, %eax -+ testl %eax, %eax -+L(first_vec_x3): -+ tzcntl %eax, %eax -+# ifdef USE_AS_STRCHRNUL -+ addq $(VEC_SIZE * 3), %rax -+ addq %rdi, %rax -+# else -+ xorl %edx, %edx -+ leaq (VEC_SIZE * 3)(%rdi, %rax), %rax -+ cmp (%rax), %CHAR_REG -+ cmovne %rdx, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+END (STRCHR) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strcmp-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strcmp-kbl.S -new file mode 100644 -index 000000000..b241812d8 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strcmp-kbl.S -@@ -0,0 +1,885 @@ -+/* strcmp/wcscmp/strncmp/wcsncmp optimized with AVX2. -+ Copyright (C) 2018-2020 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+ -+# ifndef STRCMP -+# define STRCMP strcmp_avx2 -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+# define PAGE_SIZE 4096 -+ -+/* VEC_SIZE = Number of bytes in a ymm register */ -+# define VEC_SIZE 32 -+ -+/* Shift for dividing by (VEC_SIZE * 4). */ -+# define DIVIDE_BY_VEC_4_SHIFT 7 -+# if (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) -+# error (VEC_SIZE * 4) != (1 << DIVIDE_BY_VEC_4_SHIFT) -+# endif -+ -+# ifdef USE_AS_WCSCMP -+/* Compare packed dwords. */ -+# define VPCMPEQ vpcmpeqd -+/* Compare packed dwords and store minimum. */ -+# define VPMINU vpminud -+/* 1 dword char == 4 bytes. */ -+# define SIZE_OF_CHAR 4 -+# else -+/* Compare packed bytes. */ -+# define VPCMPEQ vpcmpeqb -+/* Compare packed bytes and store minimum. */ -+# define VPMINU vpminub -+/* 1 byte char == 1 byte. */ -+# define SIZE_OF_CHAR 1 -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+/* Warning! -+ wcscmp/wcsncmp have to use SIGNED comparison for elements. -+ strcmp/strncmp have to use UNSIGNED comparison for elements. -+*/ -+ -+/* The main idea of the string comparison (byte or dword) using AVX2 -+ consists of comparing (VPCMPEQ) two ymm vectors. The latter can be on -+ either packed bytes or dwords depending on USE_AS_WCSCMP. In order -+ to check the null char, algorithm keeps the matched bytes/dwords, -+ requiring two more AVX2 instructions (VPMINU and VPCMPEQ). In general, -+ the costs of comparing VEC_SIZE bytes (32-bytes) are two VPCMPEQ and -+ one VPMINU instructions, together with movdqu and testl instructions. -+ Main loop (away from from page boundary) compares 4 vectors are a time, -+ effectively comparing 4 x VEC_SIZE bytes (128 bytes) on each loop. -+ -+ The routine strncmp/wcsncmp (enabled by defining USE_AS_STRNCMP) logic -+ is the same as strcmp, except that an a maximum offset is tracked. If -+ the maximum offset is reached before a difference is found, zero is -+ returned. */ -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRCMP) -+# ifdef USE_AS_STRNCMP -+ /* Check for simple cases (0 or 1) in offset. */ -+ cmp $1, %RDX_LP -+ je L(char0) -+ jb L(zero) -+# ifdef USE_AS_WCSCMP -+ /* Convert units: from wide to byte char. */ -+ shl $2, %RDX_LP -+# endif -+ /* Register %r11 tracks the maximum offset. */ -+ mov %RDX_LP, %R11_LP -+# endif -+ movl %edi, %eax -+ xorl %edx, %edx -+ /* Make %xmm7 (%ymm7) all zeros in this function. */ -+ vpxor %xmm7, %xmm7, %xmm7 -+ orl %esi, %eax -+ andl $(PAGE_SIZE - 1), %eax -+ cmpl $(PAGE_SIZE - (VEC_SIZE * 4)), %eax -+ jg L(cross_page) -+ /* Start comparing 4 vectors. */ -+ vmovdqu (%rdi), %ymm1 -+ VPCMPEQ (%rsi), %ymm1, %ymm0 -+ VPMINU %ymm1, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm0, %ymm0 -+ vpmovmskb %ymm0, %ecx -+ testl %ecx, %ecx -+ je L(next_3_vectors) -+ tzcntl %ecx, %edx -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the mismatched index (%rdx) is after the maximum -+ offset (%r11). */ -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi, %rdx), %ecx -+ cmpl (%rsi, %rdx), %ecx -+ je L(return) -+L(wcscmp_return): -+ setl %al -+ negl %eax -+ orl $1, %eax -+L(return): -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(return_vec_size): -+ tzcntl %ecx, %edx -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the mismatched index (%rdx + VEC_SIZE) is after -+ the maximum offset (%r11). */ -+ addq $VEC_SIZE, %rdx -+ cmpq %r11, %rdx -+ jae L(zero) -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi, %rdx), %ecx -+ cmpl (%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl VEC_SIZE(%rdi, %rdx), %ecx -+ cmpl VEC_SIZE(%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl VEC_SIZE(%rdi, %rdx), %eax -+ movzbl VEC_SIZE(%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(return_2_vec_size): -+ tzcntl %ecx, %edx -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the mismatched index (%rdx + 2 * VEC_SIZE) is -+ after the maximum offset (%r11). */ -+ addq $(VEC_SIZE * 2), %rdx -+ cmpq %r11, %rdx -+ jae L(zero) -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi, %rdx), %ecx -+ cmpl (%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (VEC_SIZE * 2)(%rdi, %rdx), %ecx -+ cmpl (VEC_SIZE * 2)(%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (VEC_SIZE * 2)(%rdi, %rdx), %eax -+ movzbl (VEC_SIZE * 2)(%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(return_3_vec_size): -+ tzcntl %ecx, %edx -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the mismatched index (%rdx + 3 * VEC_SIZE) is -+ after the maximum offset (%r11). */ -+ addq $(VEC_SIZE * 3), %rdx -+ cmpq %r11, %rdx -+ jae L(zero) -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi, %rdx), %ecx -+ cmpl (%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (VEC_SIZE * 3)(%rdi, %rdx), %ecx -+ cmpl (VEC_SIZE * 3)(%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (VEC_SIZE * 3)(%rdi, %rdx), %eax -+ movzbl (VEC_SIZE * 3)(%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(next_3_vectors): -+ vmovdqu VEC_SIZE(%rdi), %ymm6 -+ VPCMPEQ VEC_SIZE(%rsi), %ymm6, %ymm3 -+ VPMINU %ymm6, %ymm3, %ymm3 -+ VPCMPEQ %ymm7, %ymm3, %ymm3 -+ vpmovmskb %ymm3, %ecx -+ testl %ecx, %ecx -+ jne L(return_vec_size) -+ vmovdqu (VEC_SIZE * 2)(%rdi), %ymm5 -+ vmovdqu (VEC_SIZE * 3)(%rdi), %ymm4 -+ vmovdqu (VEC_SIZE * 3)(%rsi), %ymm0 -+ VPCMPEQ (VEC_SIZE * 2)(%rsi), %ymm5, %ymm2 -+ VPMINU %ymm5, %ymm2, %ymm2 -+ VPCMPEQ %ymm4, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm2, %ymm2 -+ vpmovmskb %ymm2, %ecx -+ testl %ecx, %ecx -+ jne L(return_2_vec_size) -+ VPMINU %ymm4, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm0, %ymm0 -+ vpmovmskb %ymm0, %ecx -+ testl %ecx, %ecx -+ jne L(return_3_vec_size) -+L(main_loop_header): -+ leaq (VEC_SIZE * 4)(%rdi), %rdx -+ movl $PAGE_SIZE, %ecx -+ /* Align load via RAX. */ -+ andq $-(VEC_SIZE * 4), %rdx -+ subq %rdi, %rdx -+ leaq (%rdi, %rdx), %rax -+# ifdef USE_AS_STRNCMP -+ /* Starting from this point, the maximum offset, or simply the -+ 'offset', DECREASES by the same amount when base pointers are -+ moved forward. Return 0 when: -+ 1) On match: offset <= the matched vector index. -+ 2) On mistmach, offset is before the mistmatched index. -+ */ -+ subq %rdx, %r11 -+ jbe L(zero) -+# endif -+ addq %rsi, %rdx -+ movq %rdx, %rsi -+ andl $(PAGE_SIZE - 1), %esi -+ /* Number of bytes before page crossing. */ -+ subq %rsi, %rcx -+ /* Number of VEC_SIZE * 4 blocks before page crossing. */ -+ shrq $DIVIDE_BY_VEC_4_SHIFT, %rcx -+ /* ESI: Number of VEC_SIZE * 4 blocks before page crossing. */ -+ movl %ecx, %esi -+ jmp L(loop_start) -+ -+ .p2align 4 -+L(loop): -+# ifdef USE_AS_STRNCMP -+ /* Base pointers are moved forward by 4 * VEC_SIZE. Decrease -+ the maximum offset (%r11) by the same amount. */ -+ subq $(VEC_SIZE * 4), %r11 -+ jbe L(zero) -+# endif -+ addq $(VEC_SIZE * 4), %rax -+ addq $(VEC_SIZE * 4), %rdx -+L(loop_start): -+ testl %esi, %esi -+ leal -1(%esi), %esi -+ je L(loop_cross_page) -+L(back_to_loop): -+ /* Main loop, comparing 4 vectors are a time. */ -+ vmovdqa (%rax), %ymm0 -+ vmovdqa VEC_SIZE(%rax), %ymm3 -+ VPCMPEQ (%rdx), %ymm0, %ymm4 -+ VPCMPEQ VEC_SIZE(%rdx), %ymm3, %ymm1 -+ VPMINU %ymm0, %ymm4, %ymm4 -+ VPMINU %ymm3, %ymm1, %ymm1 -+ vmovdqa (VEC_SIZE * 2)(%rax), %ymm2 -+ VPMINU %ymm1, %ymm4, %ymm0 -+ vmovdqa (VEC_SIZE * 3)(%rax), %ymm3 -+ VPCMPEQ (VEC_SIZE * 2)(%rdx), %ymm2, %ymm5 -+ VPCMPEQ (VEC_SIZE * 3)(%rdx), %ymm3, %ymm6 -+ VPMINU %ymm2, %ymm5, %ymm5 -+ VPMINU %ymm3, %ymm6, %ymm6 -+ VPMINU %ymm5, %ymm0, %ymm0 -+ VPMINU %ymm6, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm0, %ymm0 -+ -+ /* Test each mask (32 bits) individually because for VEC_SIZE -+ == 32 is not possible to OR the four masks and keep all bits -+ in a 64-bit integer register, differing from SSE2 strcmp -+ where ORing is possible. */ -+ vpmovmskb %ymm0, %ecx -+ testl %ecx, %ecx -+ je L(loop) -+ VPCMPEQ %ymm7, %ymm4, %ymm0 -+ vpmovmskb %ymm0, %edi -+ testl %edi, %edi -+ je L(test_vec) -+ tzcntl %edi, %ecx -+# ifdef USE_AS_STRNCMP -+ cmpq %rcx, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %edi -+ cmpl (%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %edi -+ cmpl (%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(test_vec): -+# ifdef USE_AS_STRNCMP -+ /* The first vector matched. Return 0 if the maximum offset -+ (%r11) <= VEC_SIZE. */ -+ cmpq $VEC_SIZE, %r11 -+ jbe L(zero) -+# endif -+ VPCMPEQ %ymm7, %ymm1, %ymm1 -+ vpmovmskb %ymm1, %ecx -+ testl %ecx, %ecx -+ je L(test_2_vec) -+ tzcntl %ecx, %edi -+# ifdef USE_AS_STRNCMP -+ addq $VEC_SIZE, %rdi -+ cmpq %rdi, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rdi), %ecx -+ cmpl (%rdx, %rdi), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rdi), %eax -+ movzbl (%rdx, %rdi), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl VEC_SIZE(%rsi, %rdi), %ecx -+ cmpl VEC_SIZE(%rdx, %rdi), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl VEC_SIZE(%rax, %rdi), %eax -+ movzbl VEC_SIZE(%rdx, %rdi), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(test_2_vec): -+# ifdef USE_AS_STRNCMP -+ /* The first 2 vectors matched. Return 0 if the maximum offset -+ (%r11) <= 2 * VEC_SIZE. */ -+ cmpq $(VEC_SIZE * 2), %r11 -+ jbe L(zero) -+# endif -+ VPCMPEQ %ymm7, %ymm5, %ymm5 -+ vpmovmskb %ymm5, %ecx -+ testl %ecx, %ecx -+ je L(test_3_vec) -+ tzcntl %ecx, %edi -+# ifdef USE_AS_STRNCMP -+ addq $(VEC_SIZE * 2), %rdi -+ cmpq %rdi, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rdi), %ecx -+ cmpl (%rdx, %rdi), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rdi), %eax -+ movzbl (%rdx, %rdi), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (VEC_SIZE * 2)(%rsi, %rdi), %ecx -+ cmpl (VEC_SIZE * 2)(%rdx, %rdi), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (VEC_SIZE * 2)(%rax, %rdi), %eax -+ movzbl (VEC_SIZE * 2)(%rdx, %rdi), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(test_3_vec): -+# ifdef USE_AS_STRNCMP -+ /* The first 3 vectors matched. Return 0 if the maximum offset -+ (%r11) <= 3 * VEC_SIZE. */ -+ cmpq $(VEC_SIZE * 3), %r11 -+ jbe L(zero) -+# endif -+ VPCMPEQ %ymm7, %ymm6, %ymm6 -+ vpmovmskb %ymm6, %esi -+ tzcntl %esi, %ecx -+# ifdef USE_AS_STRNCMP -+ addq $(VEC_SIZE * 3), %rcx -+ cmpq %rcx, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %esi -+ cmpl (%rdx, %rcx), %esi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (VEC_SIZE * 3)(%rsi, %rcx), %esi -+ cmpl (VEC_SIZE * 3)(%rdx, %rcx), %esi -+ jne L(wcscmp_return) -+# else -+ movzbl (VEC_SIZE * 3)(%rax, %rcx), %eax -+ movzbl (VEC_SIZE * 3)(%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(loop_cross_page): -+ xorl %r10d, %r10d -+ movq %rdx, %rcx -+ /* Align load via RDX. We load the extra ECX bytes which should -+ be ignored. */ -+ andl $((VEC_SIZE * 4) - 1), %ecx -+ /* R10 is -RCX. */ -+ subq %rcx, %r10 -+ -+ /* This works only if VEC_SIZE * 2 == 64. */ -+# if (VEC_SIZE * 2) != 64 -+# error (VEC_SIZE * 2) != 64 -+# endif -+ -+ /* Check if the first VEC_SIZE * 2 bytes should be ignored. */ -+ cmpl $(VEC_SIZE * 2), %ecx -+ jge L(loop_cross_page_2_vec) -+ -+ vmovdqu (%rax, %r10), %ymm2 -+ vmovdqu VEC_SIZE(%rax, %r10), %ymm3 -+ VPCMPEQ (%rdx, %r10), %ymm2, %ymm0 -+ VPCMPEQ VEC_SIZE(%rdx, %r10), %ymm3, %ymm1 -+ VPMINU %ymm2, %ymm0, %ymm0 -+ VPMINU %ymm3, %ymm1, %ymm1 -+ VPCMPEQ %ymm7, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm1, %ymm1 -+ -+ vpmovmskb %ymm0, %edi -+ vpmovmskb %ymm1, %esi -+ -+ salq $32, %rsi -+ xorq %rsi, %rdi -+ -+ /* Since ECX < VEC_SIZE * 2, simply skip the first ECX bytes. */ -+ shrq %cl, %rdi -+ -+ testq %rdi, %rdi -+ je L(loop_cross_page_2_vec) -+ tzcntq %rdi, %rcx -+# ifdef USE_AS_STRNCMP -+ cmpq %rcx, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %edi -+ cmpl (%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %edi -+ cmpl (%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(loop_cross_page_2_vec): -+ /* The first VEC_SIZE * 2 bytes match or are ignored. */ -+ vmovdqu (VEC_SIZE * 2)(%rax, %r10), %ymm2 -+ vmovdqu (VEC_SIZE * 3)(%rax, %r10), %ymm3 -+ VPCMPEQ (VEC_SIZE * 2)(%rdx, %r10), %ymm2, %ymm5 -+ VPMINU %ymm2, %ymm5, %ymm5 -+ VPCMPEQ (VEC_SIZE * 3)(%rdx, %r10), %ymm3, %ymm6 -+ VPCMPEQ %ymm7, %ymm5, %ymm5 -+ VPMINU %ymm3, %ymm6, %ymm6 -+ VPCMPEQ %ymm7, %ymm6, %ymm6 -+ -+ vpmovmskb %ymm5, %edi -+ vpmovmskb %ymm6, %esi -+ -+ salq $32, %rsi -+ xorq %rsi, %rdi -+ -+ xorl %r8d, %r8d -+ /* If ECX > VEC_SIZE * 2, skip ECX - (VEC_SIZE * 2) bytes. */ -+ subl $(VEC_SIZE * 2), %ecx -+ jle 1f -+ /* Skip ECX bytes. */ -+ shrq %cl, %rdi -+ /* R8 has number of bytes skipped. */ -+ movl %ecx, %r8d -+1: -+ /* Before jumping back to the loop, set ESI to the number of -+ VEC_SIZE * 4 blocks before page crossing. */ -+ movl $(PAGE_SIZE / (VEC_SIZE * 4) - 1), %esi -+ -+ testq %rdi, %rdi -+# ifdef USE_AS_STRNCMP -+ /* At this point, if %rdi value is 0, it already tested -+ VEC_SIZE*4+%r10 byte starting from %rax. This label -+ checks whether strncmp maximum offset reached or not. */ -+ je L(string_nbyte_offset_check) -+# else -+ je L(back_to_loop) -+# endif -+ tzcntq %rdi, %rcx -+ addq %r10, %rcx -+ /* Adjust for number of bytes skipped. */ -+ addq %r8, %rcx -+# ifdef USE_AS_STRNCMP -+ addq $(VEC_SIZE * 2), %rcx -+ subq %rcx, %r11 -+ jbe L(zero) -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (%rsi, %rcx), %edi -+ cmpl (%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (%rax, %rcx), %eax -+ movzbl (%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# else -+# ifdef USE_AS_WCSCMP -+ movq %rax, %rsi -+ xorl %eax, %eax -+ movl (VEC_SIZE * 2)(%rsi, %rcx), %edi -+ cmpl (VEC_SIZE * 2)(%rdx, %rcx), %edi -+ jne L(wcscmp_return) -+# else -+ movzbl (VEC_SIZE * 2)(%rax, %rcx), %eax -+ movzbl (VEC_SIZE * 2)(%rdx, %rcx), %edx -+ subl %edx, %eax -+# endif -+# endif -+ VZEROUPPER -+ ret -+ -+# ifdef USE_AS_STRNCMP -+L(string_nbyte_offset_check): -+ leaq (VEC_SIZE * 4)(%r10), %r10 -+ cmpq %r10, %r11 -+ jbe L(zero) -+ jmp L(back_to_loop) -+# endif -+ -+ .p2align 4 -+L(cross_page_loop): -+ /* Check one byte/dword at a time. */ -+# ifdef USE_AS_WCSCMP -+ cmpl %ecx, %eax -+# else -+ subl %ecx, %eax -+# endif -+ jne L(different) -+ addl $SIZE_OF_CHAR, %edx -+ cmpl $(VEC_SIZE * 4), %edx -+ je L(main_loop_header) -+# ifdef USE_AS_STRNCMP -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+# ifdef USE_AS_WCSCMP -+ movl (%rdi, %rdx), %eax -+ movl (%rsi, %rdx), %ecx -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %ecx -+# endif -+ /* Check null char. */ -+ testl %eax, %eax -+ jne L(cross_page_loop) -+ /* Since %eax == 0, subtract is OK for both SIGNED and UNSIGNED -+ comparisons. */ -+ subl %ecx, %eax -+# ifndef USE_AS_WCSCMP -+L(different): -+# endif -+ VZEROUPPER -+ ret -+ -+# ifdef USE_AS_WCSCMP -+ .p2align 4 -+L(different): -+ /* Use movl to avoid modifying EFLAGS. */ -+ movl $0, %eax -+ setl %al -+ negl %eax -+ orl $1, %eax -+ VZEROUPPER -+ ret -+# endif -+ -+# ifdef USE_AS_STRNCMP -+ .p2align 4 -+L(zero): -+ xorl %eax, %eax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(char0): -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi), %ecx -+ cmpl (%rsi), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rsi), %ecx -+ movzbl (%rdi), %eax -+ subl %ecx, %eax -+# endif -+ VZEROUPPER -+ ret -+# endif -+ -+ .p2align 4 -+L(last_vector): -+ addq %rdx, %rdi -+ addq %rdx, %rsi -+# ifdef USE_AS_STRNCMP -+ subq %rdx, %r11 -+# endif -+ tzcntl %ecx, %edx -+# ifdef USE_AS_STRNCMP -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+# ifdef USE_AS_WCSCMP -+ xorl %eax, %eax -+ movl (%rdi, %rdx), %ecx -+ cmpl (%rsi, %rdx), %ecx -+ jne L(wcscmp_return) -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %edx -+ subl %edx, %eax -+# endif -+ VZEROUPPER -+ ret -+ -+ /* Comparing on page boundary region requires special treatment: -+ It must done one vector at the time, starting with the wider -+ ymm vector if possible, if not, with xmm. If fetching 16 bytes -+ (xmm) still passes the boundary, byte comparison must be done. -+ */ -+ .p2align 4 -+L(cross_page): -+ /* Try one ymm vector at a time. */ -+ cmpl $(PAGE_SIZE - VEC_SIZE), %eax -+ jg L(cross_page_1_vector) -+L(loop_1_vector): -+ vmovdqu (%rdi, %rdx), %ymm1 -+ VPCMPEQ (%rsi, %rdx), %ymm1, %ymm0 -+ VPMINU %ymm1, %ymm0, %ymm0 -+ VPCMPEQ %ymm7, %ymm0, %ymm0 -+ vpmovmskb %ymm0, %ecx -+ testl %ecx, %ecx -+ jne L(last_vector) -+ -+ addl $VEC_SIZE, %edx -+ -+ addl $VEC_SIZE, %eax -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the current offset (%rdx) >= the maximum offset -+ (%r11). */ -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+ cmpl $(PAGE_SIZE - VEC_SIZE), %eax -+ jle L(loop_1_vector) -+L(cross_page_1_vector): -+ /* Less than 32 bytes to check, try one xmm vector. */ -+ cmpl $(PAGE_SIZE - 16), %eax -+ jg L(cross_page_1_xmm) -+ vmovdqu (%rdi, %rdx), %xmm1 -+ VPCMPEQ (%rsi, %rdx), %xmm1, %xmm0 -+ VPMINU %xmm1, %xmm0, %xmm0 -+ VPCMPEQ %xmm7, %xmm0, %xmm0 -+ vpmovmskb %xmm0, %ecx -+ testl %ecx, %ecx -+ jne L(last_vector) -+ -+ addl $16, %edx -+# ifndef USE_AS_WCSCMP -+ addl $16, %eax -+# endif -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the current offset (%rdx) >= the maximum offset -+ (%r11). */ -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+ -+L(cross_page_1_xmm): -+# ifndef USE_AS_WCSCMP -+ /* Less than 16 bytes to check, try 8 byte vector. NB: No need -+ for wcscmp nor wcsncmp since wide char is 4 bytes. */ -+ cmpl $(PAGE_SIZE - 8), %eax -+ jg L(cross_page_8bytes) -+ vmovq (%rdi, %rdx), %xmm1 -+ vmovq (%rsi, %rdx), %xmm0 -+ VPCMPEQ %xmm0, %xmm1, %xmm0 -+ VPMINU %xmm1, %xmm0, %xmm0 -+ VPCMPEQ %xmm7, %xmm0, %xmm0 -+ vpmovmskb %xmm0, %ecx -+ /* Only last 8 bits are valid. */ -+ andl $0xff, %ecx -+ testl %ecx, %ecx -+ jne L(last_vector) -+ -+ addl $8, %edx -+ addl $8, %eax -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the current offset (%rdx) >= the maximum offset -+ (%r11). */ -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+ -+L(cross_page_8bytes): -+ /* Less than 8 bytes to check, try 4 byte vector. */ -+ cmpl $(PAGE_SIZE - 4), %eax -+ jg L(cross_page_4bytes) -+ vmovd (%rdi, %rdx), %xmm1 -+ vmovd (%rsi, %rdx), %xmm0 -+ VPCMPEQ %xmm0, %xmm1, %xmm0 -+ VPMINU %xmm1, %xmm0, %xmm0 -+ VPCMPEQ %xmm7, %xmm0, %xmm0 -+ vpmovmskb %xmm0, %ecx -+ /* Only last 4 bits are valid. */ -+ andl $0xf, %ecx -+ testl %ecx, %ecx -+ jne L(last_vector) -+ -+ addl $4, %edx -+# ifdef USE_AS_STRNCMP -+ /* Return 0 if the current offset (%rdx) >= the maximum offset -+ (%r11). */ -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+ -+L(cross_page_4bytes): -+# endif -+ /* Less than 4 bytes to check, try one byte/dword at a time. */ -+# ifdef USE_AS_STRNCMP -+ cmpq %r11, %rdx -+ jae L(zero) -+# endif -+# ifdef USE_AS_WCSCMP -+ movl (%rdi, %rdx), %eax -+ movl (%rsi, %rdx), %ecx -+# else -+ movzbl (%rdi, %rdx), %eax -+ movzbl (%rsi, %rdx), %ecx -+# endif -+ testl %eax, %eax -+ jne L(cross_page_loop) -+ subl %ecx, %eax -+ VZEROUPPER -+ ret -+END (STRCMP) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strcpy-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strcpy-kbl.S -new file mode 100644 -index 000000000..809a9ac00 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strcpy-kbl.S -@@ -0,0 +1,1046 @@ -+/* strcpy with AVX2 -+ Copyright (C) 2011-2020 Free Software Foundation, Inc. -+ Contributed by Intel Corporation. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+ -+# ifndef USE_AS_STRCAT -+ -+# ifndef STRCPY -+# define STRCPY strcpy_avx2 -+# endif -+ -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+/* Number of bytes in a vector register */ -+# ifndef VEC_SIZE -+# define VEC_SIZE 32 -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+/* zero register */ -+#define xmmZ xmm0 -+#define ymmZ ymm0 -+ -+/* mask register */ -+#define ymmM ymm1 -+ -+# ifndef USE_AS_STRCAT -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRCPY) -+# ifdef USE_AS_STRNCPY -+ mov %RDX_LP, %R8_LP -+ test %R8_LP, %R8_LP -+ jz L(ExitZero) -+# endif -+ mov %rsi, %rcx -+# ifndef USE_AS_STPCPY -+ mov %rdi, %rax /* save result */ -+# endif -+ -+# endif -+ -+ vpxor %xmmZ, %xmmZ, %xmmZ -+ -+ and $((VEC_SIZE * 4) - 1), %ecx -+ cmp $(VEC_SIZE * 2), %ecx -+ jbe L(SourceStringAlignmentLessTwoVecSize) -+ -+ and $-VEC_SIZE, %rsi -+ and $(VEC_SIZE - 1), %ecx -+ -+ vpcmpeqb (%rsi), %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ shr %cl, %rdx -+ -+# ifdef USE_AS_STRNCPY -+# if defined USE_AS_STPCPY || defined USE_AS_STRCAT -+ mov $VEC_SIZE, %r10 -+ sub %rcx, %r10 -+ cmp %r10, %r8 -+# else -+ mov $(VEC_SIZE + 1), %r10 -+ sub %rcx, %r10 -+ cmp %r10, %r8 -+# endif -+ jbe L(CopyVecSizeTailCase2OrCase3) -+# endif -+ test %edx, %edx -+ jnz L(CopyVecSizeTail) -+ -+ vpcmpeqb VEC_SIZE(%rsi), %ymmZ, %ymm2 -+ vpmovmskb %ymm2, %edx -+ -+# ifdef USE_AS_STRNCPY -+ add $VEC_SIZE, %r10 -+ cmp %r10, %r8 -+ jbe L(CopyTwoVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+ jnz L(CopyTwoVecSize) -+ -+ vmovdqu (%rsi, %rcx), %ymm2 /* copy VEC_SIZE bytes */ -+ vmovdqu %ymm2, (%rdi) -+ -+/* If source address alignment != destination address alignment */ -+ .p2align 4 -+L(UnalignVecSizeBoth): -+ sub %rcx, %rdi -+# ifdef USE_AS_STRNCPY -+ add %rcx, %r8 -+ sbb %rcx, %rcx -+ or %rcx, %r8 -+# endif -+ mov $VEC_SIZE, %rcx -+ vmovdqa (%rsi, %rcx), %ymm2 -+ vmovdqu %ymm2, (%rdi, %rcx) -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm2 -+ vpcmpeqb %ymm2, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $(VEC_SIZE * 3), %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec2) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqu %ymm2, (%rdi, %rcx) -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm3 -+ vpcmpeqb %ymm3, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec3) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqu %ymm3, (%rdi, %rcx) -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm4 -+ vpcmpeqb %ymm4, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec4) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqu %ymm4, (%rdi, %rcx) -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm2 -+ vpcmpeqb %ymm2, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec2) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqu %ymm2, (%rdi, %rcx) -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm2 -+ vpcmpeqb %ymm2, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec2) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqa VEC_SIZE(%rsi, %rcx), %ymm3 -+ vmovdqu %ymm2, (%rdi, %rcx) -+ vpcmpeqb %ymm3, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $VEC_SIZE, %rcx -+# ifdef USE_AS_STRNCPY -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+# endif -+ test %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec3) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vmovdqu %ymm3, (%rdi, %rcx) -+ mov %rsi, %rdx -+ lea VEC_SIZE(%rsi, %rcx), %rsi -+ and $-(VEC_SIZE * 4), %rsi -+ sub %rsi, %rdx -+ sub %rdx, %rdi -+# ifdef USE_AS_STRNCPY -+ lea (VEC_SIZE * 8)(%r8, %rdx), %r8 -+# endif -+L(UnalignedFourVecSizeLoop): -+ vmovdqa (%rsi), %ymm4 -+ vmovdqa VEC_SIZE(%rsi), %ymm5 -+ vmovdqa (VEC_SIZE * 2)(%rsi), %ymm6 -+ vmovdqa (VEC_SIZE * 3)(%rsi), %ymm7 -+ vpminub %ymm5, %ymm4, %ymm2 -+ vpminub %ymm7, %ymm6, %ymm3 -+ vpminub %ymm2, %ymm3, %ymm3 -+ vpcmpeqb %ymmM, %ymm3, %ymm3 -+ vpmovmskb %ymm3, %edx -+# ifdef USE_AS_STRNCPY -+ sub $(VEC_SIZE * 4), %r8 -+ jbe L(UnalignedLeaveCase2OrCase3) -+# endif -+ test %edx, %edx -+ jnz L(UnalignedFourVecSizeLeave) -+ -+L(UnalignedFourVecSizeLoop_start): -+ add $(VEC_SIZE * 4), %rdi -+ add $(VEC_SIZE * 4), %rsi -+ vmovdqu %ymm4, -(VEC_SIZE * 4)(%rdi) -+ vmovdqa (%rsi), %ymm4 -+ vmovdqu %ymm5, -(VEC_SIZE * 3)(%rdi) -+ vmovdqa VEC_SIZE(%rsi), %ymm5 -+ vpminub %ymm5, %ymm4, %ymm2 -+ vmovdqu %ymm6, -(VEC_SIZE * 2)(%rdi) -+ vmovdqa (VEC_SIZE * 2)(%rsi), %ymm6 -+ vmovdqu %ymm7, -VEC_SIZE(%rdi) -+ vmovdqa (VEC_SIZE * 3)(%rsi), %ymm7 -+ vpminub %ymm7, %ymm6, %ymm3 -+ vpminub %ymm2, %ymm3, %ymm3 -+ vpcmpeqb %ymmM, %ymm3, %ymm3 -+ vpmovmskb %ymm3, %edx -+# ifdef USE_AS_STRNCPY -+ sub $(VEC_SIZE * 4), %r8 -+ jbe L(UnalignedLeaveCase2OrCase3) -+# endif -+ test %edx, %edx -+ jz L(UnalignedFourVecSizeLoop_start) -+ -+L(UnalignedFourVecSizeLeave): -+ vpcmpeqb %ymm4, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ test %edx, %edx -+ jnz L(CopyVecSizeUnaligned_0) -+ -+ vpcmpeqb %ymm5, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %ecx -+ test %ecx, %ecx -+ jnz L(CopyVecSizeUnaligned_16) -+ -+ vpcmpeqb %ymm6, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ test %edx, %edx -+ jnz L(CopyVecSizeUnaligned_32) -+ -+ vpcmpeqb %ymm7, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %ecx -+ bsf %ecx, %edx -+ vmovdqu %ymm4, (%rdi) -+ vmovdqu %ymm5, VEC_SIZE(%rdi) -+ vmovdqu %ymm6, (VEC_SIZE * 2)(%rdi) -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+# ifdef USE_AS_STPCPY -+ lea (VEC_SIZE * 3)(%rdi, %rdx), %rax -+# endif -+ vmovdqu %ymm7, (VEC_SIZE * 3)(%rdi) -+ add $(VEC_SIZE - 1), %r8 -+ sub %rdx, %r8 -+ lea ((VEC_SIZE * 3) + 1)(%rdi, %rdx), %rdi -+ jmp L(StrncpyFillTailWithZero) -+# else -+ add $(VEC_SIZE * 3), %rsi -+ add $(VEC_SIZE * 3), %rdi -+ jmp L(CopyVecSizeExit) -+# endif -+ -+/* If source address alignment == destination address alignment */ -+ -+L(SourceStringAlignmentLessTwoVecSize): -+ vmovdqu (%rsi), %ymm3 -+ vmovdqu VEC_SIZE(%rsi), %ymm2 -+ vpcmpeqb %ymm3, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ -+# ifdef USE_AS_STRNCPY -+# if defined USE_AS_STPCPY || defined USE_AS_STRCAT -+ cmp $VEC_SIZE, %r8 -+# else -+ cmp $(VEC_SIZE + 1), %r8 -+# endif -+ jbe L(CopyVecSizeTail1Case2OrCase3) -+# endif -+ test %edx, %edx -+ jnz L(CopyVecSizeTail1) -+ -+ vmovdqu %ymm3, (%rdi) -+ vpcmpeqb %ymm2, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ -+# ifdef USE_AS_STRNCPY -+# if defined USE_AS_STPCPY || defined USE_AS_STRCAT -+ cmp $(VEC_SIZE * 2), %r8 -+# else -+ cmp $((VEC_SIZE * 2) + 1), %r8 -+# endif -+ jbe L(CopyTwoVecSize1Case2OrCase3) -+# endif -+ test %edx, %edx -+ jnz L(CopyTwoVecSize1) -+ -+ and $-VEC_SIZE, %rsi -+ and $(VEC_SIZE - 1), %ecx -+ jmp L(UnalignVecSizeBoth) -+ -+/*------End of main part with loops---------------------*/ -+ -+/* Case1 */ -+ -+# if (!defined USE_AS_STRNCPY) || (defined USE_AS_STRCAT) -+ .p2align 4 -+L(CopyVecSize): -+ add %rcx, %rdi -+# endif -+L(CopyVecSizeTail): -+ add %rcx, %rsi -+L(CopyVecSizeTail1): -+ bsf %edx, %edx -+L(CopyVecSizeExit): -+ cmp $32, %edx -+ jae L(Exit32_63) -+ cmp $16, %edx -+ jae L(Exit16_31) -+ cmp $8, %edx -+ jae L(Exit8_15) -+ cmp $4, %edx -+ jae L(Exit4_7) -+ cmp $3, %edx -+ je L(Exit3) -+ cmp $1, %edx -+ ja L(Exit2) -+ je L(Exit1) -+ movb $0, (%rdi) -+# ifdef USE_AS_STPCPY -+ lea (%rdi), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub $1, %r8 -+ lea 1(%rdi), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(CopyTwoVecSize1): -+ add $VEC_SIZE, %rsi -+ add $VEC_SIZE, %rdi -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub $VEC_SIZE, %r8 -+# endif -+ jmp L(CopyVecSizeTail1) -+ -+ .p2align 4 -+L(CopyTwoVecSize): -+ bsf %edx, %edx -+ add %rcx, %rsi -+ add $VEC_SIZE, %edx -+ sub %ecx, %edx -+ jmp L(CopyVecSizeExit) -+ -+ .p2align 4 -+L(CopyVecSizeUnaligned_0): -+ bsf %edx, %edx -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+ vmovdqu %ymm4, (%rdi) -+ add $((VEC_SIZE * 4) - 1), %r8 -+ sub %rdx, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ jmp L(StrncpyFillTailWithZero) -+# else -+ jmp L(CopyVecSizeExit) -+# endif -+ -+ .p2align 4 -+L(CopyVecSizeUnaligned_16): -+ bsf %ecx, %edx -+ vmovdqu %ymm4, (%rdi) -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+# ifdef USE_AS_STPCPY -+ lea VEC_SIZE(%rdi, %rdx), %rax -+# endif -+ vmovdqu %ymm5, VEC_SIZE(%rdi) -+ add $((VEC_SIZE * 3) - 1), %r8 -+ sub %rdx, %r8 -+ lea (VEC_SIZE + 1)(%rdi, %rdx), %rdi -+ jmp L(StrncpyFillTailWithZero) -+# else -+ add $VEC_SIZE, %rsi -+ add $VEC_SIZE, %rdi -+ jmp L(CopyVecSizeExit) -+# endif -+ -+ .p2align 4 -+L(CopyVecSizeUnaligned_32): -+ bsf %edx, %edx -+ vmovdqu %ymm4, (%rdi) -+ vmovdqu %ymm5, VEC_SIZE(%rdi) -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+# ifdef USE_AS_STPCPY -+ lea (VEC_SIZE * 2)(%rdi, %rdx), %rax -+# endif -+ vmovdqu %ymm6, (VEC_SIZE * 2)(%rdi) -+ add $((VEC_SIZE * 2) - 1), %r8 -+ sub %rdx, %r8 -+ lea ((VEC_SIZE * 2) + 1)(%rdi, %rdx), %rdi -+ jmp L(StrncpyFillTailWithZero) -+# else -+ add $(VEC_SIZE * 2), %rsi -+ add $(VEC_SIZE * 2), %rdi -+ jmp L(CopyVecSizeExit) -+# endif -+ -+# ifdef USE_AS_STRNCPY -+# ifndef USE_AS_STRCAT -+ .p2align 4 -+L(CopyVecSizeUnalignedVec6): -+ vmovdqu %ymm6, (%rdi, %rcx) -+ jmp L(CopyVecSizeVecExit) -+ -+ .p2align 4 -+L(CopyVecSizeUnalignedVec5): -+ vmovdqu %ymm5, (%rdi, %rcx) -+ jmp L(CopyVecSizeVecExit) -+ -+ .p2align 4 -+L(CopyVecSizeUnalignedVec4): -+ vmovdqu %ymm4, (%rdi, %rcx) -+ jmp L(CopyVecSizeVecExit) -+ -+ .p2align 4 -+L(CopyVecSizeUnalignedVec3): -+ vmovdqu %ymm3, (%rdi, %rcx) -+ jmp L(CopyVecSizeVecExit) -+# endif -+ -+/* Case2 */ -+ -+ .p2align 4 -+L(CopyVecSizeCase2): -+ add $VEC_SIZE, %r8 -+ add %rcx, %rdi -+ add %rcx, %rsi -+ bsf %edx, %edx -+ cmp %r8d, %edx -+ jb L(CopyVecSizeExit) -+ jmp L(StrncpyExit) -+ -+ .p2align 4 -+L(CopyTwoVecSizeCase2): -+ add %rcx, %rsi -+ bsf %edx, %edx -+ add $VEC_SIZE, %edx -+ sub %ecx, %edx -+ cmp %r8d, %edx -+ jb L(CopyVecSizeExit) -+ jmp L(StrncpyExit) -+ -+L(CopyVecSizeTailCase2): -+ add %rcx, %rsi -+ bsf %edx, %edx -+ cmp %r8d, %edx -+ jb L(CopyVecSizeExit) -+ jmp L(StrncpyExit) -+ -+L(CopyVecSizeTail1Case2): -+ bsf %edx, %edx -+ cmp %r8d, %edx -+ jb L(CopyVecSizeExit) -+ jmp L(StrncpyExit) -+ -+/* Case2 or Case3, Case3 */ -+ -+ .p2align 4 -+L(CopyVecSizeCase2OrCase3): -+ test %rdx, %rdx -+ jnz L(CopyVecSizeCase2) -+L(CopyVecSizeCase3): -+ add $VEC_SIZE, %r8 -+ add %rcx, %rdi -+ add %rcx, %rsi -+ jmp L(StrncpyExit) -+ -+ .p2align 4 -+L(CopyTwoVecSizeCase2OrCase3): -+ test %rdx, %rdx -+ jnz L(CopyTwoVecSizeCase2) -+ add %rcx, %rsi -+ jmp L(StrncpyExit) -+ -+ .p2align 4 -+L(CopyVecSizeTailCase2OrCase3): -+ test %rdx, %rdx -+ jnz L(CopyVecSizeTailCase2) -+ add %rcx, %rsi -+ jmp L(StrncpyExit) -+ -+ .p2align 4 -+L(CopyTwoVecSize1Case2OrCase3): -+ add $VEC_SIZE, %rdi -+ add $VEC_SIZE, %rsi -+ sub $VEC_SIZE, %r8 -+L(CopyVecSizeTail1Case2OrCase3): -+ test %rdx, %rdx -+ jnz L(CopyVecSizeTail1Case2) -+ jmp L(StrncpyExit) -+# endif -+ -+/*------------End labels regarding with copying 1-VEC_SIZE bytes--and 1-(VEC_SIZE*2) bytes----*/ -+ -+ .p2align 4 -+L(Exit1): -+ movzwl (%rsi), %edx -+ mov %dx, (%rdi) -+# ifdef USE_AS_STPCPY -+ lea 1(%rdi), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub $2, %r8 -+ lea 2(%rdi), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit2): -+ movzwl (%rsi), %ecx -+ mov %cx, (%rdi) -+ movb $0, 2(%rdi) -+# ifdef USE_AS_STPCPY -+ lea 2(%rdi), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub $3, %r8 -+ lea 3(%rdi), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit3): -+ mov (%rsi), %edx -+ mov %edx, (%rdi) -+# ifdef USE_AS_STPCPY -+ lea 3(%rdi), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub $4, %r8 -+ lea 4(%rdi), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit4_7): -+ mov (%rsi), %ecx -+ mov %ecx, (%rdi) -+ mov -3(%rsi, %rdx), %ecx -+ mov %ecx, -3(%rdi, %rdx) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub %rdx, %r8 -+ sub $1, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit8_15): -+ mov (%rsi), %rcx -+ mov -7(%rsi, %rdx), %r9 -+ mov %rcx, (%rdi) -+ mov %r9, -7(%rdi, %rdx) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub %rdx, %r8 -+ sub $1, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit16_31): -+ vmovdqu (%rsi), %xmm2 -+ vmovdqu -15(%rsi, %rdx), %xmm3 -+ vmovdqu %xmm2, (%rdi) -+ vmovdqu %xmm3, -15(%rdi, %rdx) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub %rdx, %r8 -+ sub $1, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Exit32_63): -+ vmovdqu (%rsi), %ymm2 -+ vmovdqu -31(%rsi, %rdx), %ymm3 -+ vmovdqu %ymm2, (%rdi) -+ vmovdqu %ymm3, -31(%rdi, %rdx) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+# if defined USE_AS_STRNCPY && !defined USE_AS_STRCAT -+ sub %rdx, %r8 -+ sub $1, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ jnz L(StrncpyFillTailWithZero) -+# endif -+ VZEROUPPER -+ ret -+ -+# ifdef USE_AS_STRNCPY -+ -+ .p2align 4 -+L(StrncpyExit1): -+ movzbl (%rsi), %edx -+ mov %dl, (%rdi) -+# ifdef USE_AS_STPCPY -+ lea 1(%rdi), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, 1(%rdi) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit2): -+ movzwl (%rsi), %edx -+ mov %dx, (%rdi) -+# ifdef USE_AS_STPCPY -+ lea 2(%rdi), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, 2(%rdi) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit3_4): -+ movzwl (%rsi), %ecx -+ movzwl -2(%rsi, %r8), %edx -+ mov %cx, (%rdi) -+ mov %dx, -2(%rdi, %r8) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %r8), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi, %r8) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit5_8): -+ mov (%rsi), %ecx -+ mov -4(%rsi, %r8), %edx -+ mov %ecx, (%rdi) -+ mov %edx, -4(%rdi, %r8) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %r8), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi, %r8) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit9_16): -+ mov (%rsi), %rcx -+ mov -8(%rsi, %r8), %rdx -+ mov %rcx, (%rdi) -+ mov %rdx, -8(%rdi, %r8) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %r8), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi, %r8) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit17_32): -+ vmovdqu (%rsi), %xmm2 -+ vmovdqu -16(%rsi, %r8), %xmm3 -+ vmovdqu %xmm2, (%rdi) -+ vmovdqu %xmm3, -16(%rdi, %r8) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %r8), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi, %r8) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit33_64): -+ /* 0/32, 31/16 */ -+ vmovdqu (%rsi), %ymm2 -+ vmovdqu -VEC_SIZE(%rsi, %r8), %ymm3 -+ vmovdqu %ymm2, (%rdi) -+ vmovdqu %ymm3, -VEC_SIZE(%rdi, %r8) -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %r8), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi, %r8) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(StrncpyExit65): -+ /* 0/32, 32/32, 64/1 */ -+ vmovdqu (%rsi), %ymm2 -+ vmovdqu 32(%rsi), %ymm3 -+ mov 64(%rsi), %cl -+ vmovdqu %ymm2, (%rdi) -+ vmovdqu %ymm3, 32(%rdi) -+ mov %cl, 64(%rdi) -+# ifdef USE_AS_STPCPY -+ lea 65(%rdi), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, 65(%rdi) -+# endif -+ VZEROUPPER -+ ret -+ -+# ifndef USE_AS_STRCAT -+ -+ .p2align 4 -+L(Fill1): -+ mov %dl, (%rdi) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Fill2): -+ mov %dx, (%rdi) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Fill3_4): -+ mov %dx, (%rdi) -+ mov %dx, -2(%rdi, %r8) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Fill5_8): -+ mov %edx, (%rdi) -+ mov %edx, -4(%rdi, %r8) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Fill9_16): -+ mov %rdx, (%rdi) -+ mov %rdx, -8(%rdi, %r8) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(Fill17_32): -+ vmovdqu %xmmZ, (%rdi) -+ vmovdqu %xmmZ, -16(%rdi, %r8) -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(CopyVecSizeUnalignedVec2): -+ vmovdqu %ymm2, (%rdi, %rcx) -+ -+ .p2align 4 -+L(CopyVecSizeVecExit): -+ bsf %edx, %edx -+ add $(VEC_SIZE - 1), %r8 -+ add %rcx, %rdi -+# ifdef USE_AS_STPCPY -+ lea (%rdi, %rdx), %rax -+# endif -+ sub %rdx, %r8 -+ lea 1(%rdi, %rdx), %rdi -+ -+ .p2align 4 -+L(StrncpyFillTailWithZero): -+ xor %edx, %edx -+ sub $VEC_SIZE, %r8 -+ jbe L(StrncpyFillExit) -+ -+ vmovdqu %ymmZ, (%rdi) -+ add $VEC_SIZE, %rdi -+ -+ mov %rdi, %rsi -+ and $(VEC_SIZE - 1), %esi -+ sub %rsi, %rdi -+ add %rsi, %r8 -+ sub $(VEC_SIZE * 4), %r8 -+ jb L(StrncpyFillLessFourVecSize) -+ -+L(StrncpyFillLoopVmovdqa): -+ vmovdqa %ymmZ, (%rdi) -+ vmovdqa %ymmZ, VEC_SIZE(%rdi) -+ vmovdqa %ymmZ, (VEC_SIZE * 2)(%rdi) -+ vmovdqa %ymmZ, (VEC_SIZE * 3)(%rdi) -+ add $(VEC_SIZE * 4), %rdi -+ sub $(VEC_SIZE * 4), %r8 -+ jae L(StrncpyFillLoopVmovdqa) -+ -+L(StrncpyFillLessFourVecSize): -+ add $(VEC_SIZE * 2), %r8 -+ jl L(StrncpyFillLessTwoVecSize) -+ vmovdqa %ymmZ, (%rdi) -+ vmovdqa %ymmZ, VEC_SIZE(%rdi) -+ add $(VEC_SIZE * 2), %rdi -+ sub $VEC_SIZE, %r8 -+ jl L(StrncpyFillExit) -+ vmovdqa %ymmZ, (%rdi) -+ add $VEC_SIZE, %rdi -+ jmp L(Fill) -+ -+ .p2align 4 -+L(StrncpyFillLessTwoVecSize): -+ add $VEC_SIZE, %r8 -+ jl L(StrncpyFillExit) -+ vmovdqa %ymmZ, (%rdi) -+ add $VEC_SIZE, %rdi -+ jmp L(Fill) -+ -+ .p2align 4 -+L(StrncpyFillExit): -+ add $VEC_SIZE, %r8 -+L(Fill): -+ cmp $17, %r8d -+ jae L(Fill17_32) -+ cmp $9, %r8d -+ jae L(Fill9_16) -+ cmp $5, %r8d -+ jae L(Fill5_8) -+ cmp $3, %r8d -+ jae L(Fill3_4) -+ cmp $1, %r8d -+ ja L(Fill2) -+ je L(Fill1) -+ VZEROUPPER -+ ret -+ -+/* end of ifndef USE_AS_STRCAT */ -+# endif -+ -+ .p2align 4 -+L(UnalignedLeaveCase2OrCase3): -+ test %rdx, %rdx -+ jnz L(UnalignedFourVecSizeLeaveCase2) -+L(UnalignedFourVecSizeLeaveCase3): -+ lea (VEC_SIZE * 4)(%r8), %rcx -+ and $-VEC_SIZE, %rcx -+ add $(VEC_SIZE * 3), %r8 -+ jl L(CopyVecSizeCase3) -+ vmovdqu %ymm4, (%rdi) -+ sub $VEC_SIZE, %r8 -+ jb L(CopyVecSizeCase3) -+ vmovdqu %ymm5, VEC_SIZE(%rdi) -+ sub $VEC_SIZE, %r8 -+ jb L(CopyVecSizeCase3) -+ vmovdqu %ymm6, (VEC_SIZE * 2)(%rdi) -+ sub $VEC_SIZE, %r8 -+ jb L(CopyVecSizeCase3) -+ vmovdqu %ymm7, (VEC_SIZE * 3)(%rdi) -+# ifdef USE_AS_STPCPY -+ lea (VEC_SIZE * 4)(%rdi), %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (VEC_SIZE * 4)(%rdi) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(UnalignedFourVecSizeLeaveCase2): -+ xor %ecx, %ecx -+ vpcmpeqb %ymm4, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ add $(VEC_SIZE * 3), %r8 -+ jle L(CopyVecSizeCase2OrCase3) -+ test %edx, %edx -+# ifndef USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec4) -+# else -+ jnz L(CopyVecSize) -+# endif -+ vpcmpeqb %ymm5, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ vmovdqu %ymm4, (%rdi) -+ add $VEC_SIZE, %rcx -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+ test %edx, %edx -+# ifndef USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec5) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vpcmpeqb %ymm6, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ vmovdqu %ymm5, VEC_SIZE(%rdi) -+ add $VEC_SIZE, %rcx -+ sub $VEC_SIZE, %r8 -+ jbe L(CopyVecSizeCase2OrCase3) -+ test %edx, %edx -+# ifndef USE_AS_STRCAT -+ jnz L(CopyVecSizeUnalignedVec6) -+# else -+ jnz L(CopyVecSize) -+# endif -+ -+ vpcmpeqb %ymm7, %ymmZ, %ymmM -+ vpmovmskb %ymmM, %edx -+ vmovdqu %ymm6, (VEC_SIZE * 2)(%rdi) -+ lea VEC_SIZE(%rdi, %rcx), %rdi -+ lea VEC_SIZE(%rsi, %rcx), %rsi -+ bsf %edx, %edx -+ cmp %r8d, %edx -+ jb L(CopyVecSizeExit) -+L(StrncpyExit): -+ cmp $65, %r8d -+ je L(StrncpyExit65) -+ cmp $33, %r8d -+ jae L(StrncpyExit33_64) -+ cmp $17, %r8d -+ jae L(StrncpyExit17_32) -+ cmp $9, %r8d -+ jae L(StrncpyExit9_16) -+ cmp $5, %r8d -+ jae L(StrncpyExit5_8) -+ cmp $3, %r8d -+ jae L(StrncpyExit3_4) -+ cmp $1, %r8d -+ ja L(StrncpyExit2) -+ je L(StrncpyExit1) -+# ifdef USE_AS_STPCPY -+ mov %rdi, %rax -+# endif -+# ifdef USE_AS_STRCAT -+ movb $0, (%rdi) -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(ExitZero): -+# ifndef USE_AS_STRCAT -+ mov %rdi, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+# endif -+ -+# ifndef USE_AS_STRCAT -+END (STRCPY) -+# else -+END (STRCAT) -+# endif -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strlen-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strlen-kbl.S -new file mode 100644 -index 000000000..912d771b4 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strlen-kbl.S -@@ -0,0 +1,418 @@ -+/* strlen/strnlen/wcslen/wcsnlen optimized with AVX2. -+ Copyright (C) 2017-2020 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+# ifndef STRLEN -+# define STRLEN strlen_avx2 -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+# ifdef USE_AS_WCSLEN -+# define VPCMPEQ vpcmpeqd -+# define VPMINU vpminud -+# else -+# define VPCMPEQ vpcmpeqb -+# define VPMINU vpminub -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRLEN) -+# ifdef USE_AS_STRNLEN -+ /* Check for zero length. */ -+ test %RSI_LP, %RSI_LP -+ jz L(zero) -+# ifdef USE_AS_WCSLEN -+ shl $2, %RSI_LP -+# elif defined __ILP32__ -+ /* Clear the upper 32 bits. */ -+ movl %esi, %esi -+# endif -+ mov %RSI_LP, %R8_LP -+# endif -+ movl %edi, %ecx -+ movq %rdi, %rdx -+ vpxor %xmm0, %xmm0, %xmm0 -+ -+ /* Check if we may cross page boundary with one vector load. */ -+ andl $(2 * VEC_SIZE - 1), %ecx -+ cmpl $VEC_SIZE, %ecx -+ ja L(cros_page_boundary) -+ -+ /* Check the first VEC_SIZE bytes. */ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+# ifdef USE_AS_STRNLEN -+ jnz L(first_vec_x0_check) -+ /* Adjust length and check the end of data. */ -+ subq $VEC_SIZE, %rsi -+ jbe L(max) -+# else -+ jnz L(first_vec_x0) -+# endif -+ -+ /* Align data for aligned loads in the loop. */ -+ addq $VEC_SIZE, %rdi -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ -+# ifdef USE_AS_STRNLEN -+ /* Adjust length. */ -+ addq %rcx, %rsi -+ -+ subq $(VEC_SIZE * 4), %rsi -+ jbe L(last_4x_vec_or_less) -+# endif -+ jmp L(more_4x_vec) -+ -+ .p2align 4 -+L(cros_page_boundary): -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ /* Remove the leading bytes. */ -+ sarl %cl, %eax -+ testl %eax, %eax -+ jz L(aligned_more) -+ tzcntl %eax, %eax -+# ifdef USE_AS_STRNLEN -+ /* Check the end of data. */ -+ cmpq %rax, %rsi -+ jbe L(max) -+# endif -+ addq %rdi, %rax -+ addq %rcx, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(aligned_more): -+# ifdef USE_AS_STRNLEN -+ /* "rcx" is less than VEC_SIZE. Calculate "rdx + rcx - VEC_SIZE" -+ with "rdx - (VEC_SIZE - rcx)" instead of "(rdx + rcx) - VEC_SIZE" -+ to void possible addition overflow. */ -+ negq %rcx -+ addq $VEC_SIZE, %rcx -+ -+ /* Check the end of data. */ -+ subq %rcx, %rsi -+ jbe L(max) -+# endif -+ -+ addq $VEC_SIZE, %rdi -+ -+# ifdef USE_AS_STRNLEN -+ subq $(VEC_SIZE * 4), %rsi -+ jbe L(last_4x_vec_or_less) -+# endif -+ -+L(more_4x_vec): -+ /* Check the first 4 * VEC_SIZE. Only one VEC_SIZE at a time -+ since data is only aligned to VEC_SIZE. */ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x3) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+# ifdef USE_AS_STRNLEN -+ subq $(VEC_SIZE * 4), %rsi -+ jbe L(last_4x_vec_or_less) -+# endif -+ -+ /* Align data to 4 * VEC_SIZE. */ -+ movq %rdi, %rcx -+ andl $(4 * VEC_SIZE - 1), %ecx -+ andq $-(4 * VEC_SIZE), %rdi -+ -+# ifdef USE_AS_STRNLEN -+ /* Adjust length. */ -+ addq %rcx, %rsi -+# endif -+ -+ .p2align 4 -+L(loop_4x_vec): -+ /* Compare 4 * VEC at a time forward. */ -+ vmovdqa (%rdi), %ymm1 -+ vmovdqa VEC_SIZE(%rdi), %ymm2 -+ vmovdqa (VEC_SIZE * 2)(%rdi), %ymm3 -+ vmovdqa (VEC_SIZE * 3)(%rdi), %ymm4 -+ VPMINU %ymm1, %ymm2, %ymm5 -+ VPMINU %ymm3, %ymm4, %ymm6 -+ VPMINU %ymm5, %ymm6, %ymm5 -+ -+ VPCMPEQ %ymm5, %ymm0, %ymm5 -+ vpmovmskb %ymm5, %eax -+ testl %eax, %eax -+ jnz L(4x_vec_end) -+ -+ addq $(VEC_SIZE * 4), %rdi -+ -+# ifndef USE_AS_STRNLEN -+ jmp L(loop_4x_vec) -+# else -+ subq $(VEC_SIZE * 4), %rsi -+ ja L(loop_4x_vec) -+ -+L(last_4x_vec_or_less): -+ /* Less than 4 * VEC and aligned to VEC_SIZE. */ -+ addl $(VEC_SIZE * 2), %esi -+ jle L(last_2x_vec) -+ -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ -+ VPCMPEQ (VEC_SIZE * 2)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x2_check) -+ subl $VEC_SIZE, %esi -+ jle L(max) -+ -+ VPCMPEQ (VEC_SIZE * 3)(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x3_check) -+ movq %r8, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(last_2x_vec): -+ addl $(VEC_SIZE * 2), %esi -+ VPCMPEQ (%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ -+ jnz L(first_vec_x0_check) -+ subl $VEC_SIZE, %esi -+ jle L(max) -+ -+ VPCMPEQ VEC_SIZE(%rdi), %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1_check) -+ movq %r8, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x0_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rsi -+ jbe L(max) -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x1_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rsi -+ jbe L(max) -+ addq $VEC_SIZE, %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x2_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rsi -+ jbe L(max) -+ addq $(VEC_SIZE * 2), %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x3_check): -+ tzcntl %eax, %eax -+ /* Check the end of data. */ -+ cmpq %rax, %rsi -+ jbe L(max) -+ addq $(VEC_SIZE * 3), %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(max): -+ movq %r8, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(zero): -+ xorl %eax, %eax -+ ret -+# endif -+ -+ .p2align 4 -+L(first_vec_x0): -+ tzcntl %eax, %eax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x1): -+ tzcntl %eax, %eax -+ addq $VEC_SIZE, %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(first_vec_x2): -+ tzcntl %eax, %eax -+ addq $(VEC_SIZE * 2), %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(4x_vec_end): -+ VPCMPEQ %ymm1, %ymm0, %ymm1 -+ vpmovmskb %ymm1, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x0) -+ VPCMPEQ %ymm2, %ymm0, %ymm2 -+ vpmovmskb %ymm2, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x1) -+ VPCMPEQ %ymm3, %ymm0, %ymm3 -+ vpmovmskb %ymm3, %eax -+ testl %eax, %eax -+ jnz L(first_vec_x2) -+ VPCMPEQ %ymm4, %ymm0, %ymm4 -+ vpmovmskb %ymm4, %eax -+L(first_vec_x3): -+ tzcntl %eax, %eax -+ addq $(VEC_SIZE * 3), %rax -+ addq %rdi, %rax -+ subq %rdx, %rax -+# ifdef USE_AS_WCSLEN -+ shrq $2, %rax -+# endif -+ VZEROUPPER -+ ret -+ -+END (STRLEN) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strncat-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strncat-kbl.S -new file mode 100644 -index 000000000..71e1a46c2 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strncat-kbl.S -@@ -0,0 +1,3 @@ -+#define USE_AS_STRNCAT -+#define STRCAT strncat_avx2 -+#include "avx2-strcat-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strncmp-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strncmp-kbl.S -new file mode 100644 -index 000000000..b21a19134 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strncmp-kbl.S -@@ -0,0 +1,4 @@ -+#define STRCMP strncmp_avx2 -+#define USE_AS_STRNCMP 1 -+#include "avx_regs.h" -+#include "avx2-strcmp-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strncpy-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strncpy-kbl.S -new file mode 100644 -index 000000000..7ad840667 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strncpy-kbl.S -@@ -0,0 +1,4 @@ -+#define USE_AS_STRNCPY -+#define STRCPY strncpy_avx2 -+#include "avx_regs.h" -+#include "avx2-strcpy-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strnlen-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strnlen-kbl.S -new file mode 100644 -index 000000000..22cc5c527 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strnlen-kbl.S -@@ -0,0 +1,4 @@ -+#define STRLEN strnlen_avx2 -+#define USE_AS_STRNLEN 1 -+#include "avx_regs.h" -+#include "avx2-strlen-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-strrchr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-strrchr-kbl.S -new file mode 100644 -index 000000000..b3a65fbc6 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-strrchr-kbl.S -@@ -0,0 +1,258 @@ -+/* strrchr/wcsrchr optimized with AVX2. -+ Copyright (C) 2017-2020 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+ -+# ifndef STRRCHR -+# define STRRCHR strrchr_avx2 -+# endif -+ -+# ifndef L -+# define L(label) .L##label -+# endif -+ -+# ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+# endif -+ -+# ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+# endif -+ -+# ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+# endif -+ -+# ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+# endif -+ -+# ifdef USE_AS_WCSRCHR -+# define VPBROADCAST vpbroadcastd -+# define VPCMPEQ vpcmpeqd -+# else -+# define VPBROADCAST vpbroadcastb -+# define VPCMPEQ vpcmpeqb -+# endif -+ -+# ifndef VZEROUPPER -+# define VZEROUPPER vzeroupper -+# endif -+ -+# define VEC_SIZE 32 -+ -+ .section .text.avx,"ax",@progbits -+ENTRY (STRRCHR) -+ movd %esi, %xmm4 -+ movl %edi, %ecx -+ /* Broadcast CHAR to YMM4. */ -+ VPBROADCAST %xmm4, %ymm4 -+ vpxor %xmm0, %xmm0, %xmm0 -+ -+ /* Check if we may cross page boundary with one vector load. */ -+ andl $(2 * VEC_SIZE - 1), %ecx -+ cmpl $VEC_SIZE, %ecx -+ ja L(cros_page_boundary) -+ -+ vmovdqu (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %ecx -+ vpmovmskb %ymm3, %eax -+ addq $VEC_SIZE, %rdi -+ -+ testl %eax, %eax -+ jnz L(first_vec) -+ -+ testl %ecx, %ecx -+ jnz L(return_null) -+ -+ andq $-VEC_SIZE, %rdi -+ xorl %edx, %edx -+ jmp L(aligned_loop) -+ -+ .p2align 4 -+L(first_vec): -+ /* Check if there is a nul CHAR. */ -+ testl %ecx, %ecx -+ jnz L(char_and_nul_in_first_vec) -+ -+ /* Remember the match and keep searching. */ -+ movl %eax, %edx -+ movq %rdi, %rsi -+ andq $-VEC_SIZE, %rdi -+ jmp L(aligned_loop) -+ -+ .p2align 4 -+L(cros_page_boundary): -+ andl $(VEC_SIZE - 1), %ecx -+ andq $-VEC_SIZE, %rdi -+ vmovdqa (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %edx -+ vpmovmskb %ymm3, %eax -+ shrl %cl, %edx -+ shrl %cl, %eax -+ addq $VEC_SIZE, %rdi -+ -+ /* Check if there is a CHAR. */ -+ testl %eax, %eax -+ jnz L(found_char) -+ -+ testl %edx, %edx -+ jnz L(return_null) -+ -+ jmp L(aligned_loop) -+ -+ .p2align 4 -+L(found_char): -+ testl %edx, %edx -+ jnz L(char_and_nul) -+ -+ /* Remember the match and keep searching. */ -+ movl %eax, %edx -+ leaq (%rdi, %rcx), %rsi -+ -+ .p2align 4 -+L(aligned_loop): -+ vmovdqa (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ addq $VEC_SIZE, %rdi -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %ecx -+ vpmovmskb %ymm3, %eax -+ orl %eax, %ecx -+ jnz L(char_nor_null) -+ -+ vmovdqa (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ add $VEC_SIZE, %rdi -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %ecx -+ vpmovmskb %ymm3, %eax -+ orl %eax, %ecx -+ jnz L(char_nor_null) -+ -+ vmovdqa (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ addq $VEC_SIZE, %rdi -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %ecx -+ vpmovmskb %ymm3, %eax -+ orl %eax, %ecx -+ jnz L(char_nor_null) -+ -+ vmovdqa (%rdi), %ymm1 -+ VPCMPEQ %ymm1, %ymm0, %ymm2 -+ addq $VEC_SIZE, %rdi -+ VPCMPEQ %ymm1, %ymm4, %ymm3 -+ vpmovmskb %ymm2, %ecx -+ vpmovmskb %ymm3, %eax -+ orl %eax, %ecx -+ jz L(aligned_loop) -+ -+ .p2align 4 -+L(char_nor_null): -+ /* Find a CHAR or a nul CHAR in a loop. */ -+ testl %eax, %eax -+ jnz L(match) -+L(return_value): -+ testl %edx, %edx -+ jz L(return_null) -+ movl %edx, %eax -+ movq %rsi, %rdi -+ -+# ifdef USE_AS_WCSRCHR -+ /* Keep the first bit for each matching CHAR for bsr. */ -+ andl $0x11111111, %eax -+# endif -+ bsrl %eax, %eax -+ leaq -VEC_SIZE(%rdi, %rax), %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(match): -+ /* Find a CHAR. Check if there is a nul CHAR. */ -+ vpmovmskb %ymm2, %ecx -+ testl %ecx, %ecx -+ jnz L(find_nul) -+ -+ /* Remember the match and keep searching. */ -+ movl %eax, %edx -+ movq %rdi, %rsi -+ jmp L(aligned_loop) -+ -+ .p2align 4 -+L(find_nul): -+# ifdef USE_AS_WCSRCHR -+ /* Keep the first bit for each matching CHAR for bsr. */ -+ andl $0x11111111, %ecx -+ andl $0x11111111, %eax -+# endif -+ /* Mask out any matching bits after the nul CHAR. */ -+ movl %ecx, %r8d -+ subl $1, %r8d -+ xorl %ecx, %r8d -+ andl %r8d, %eax -+ testl %eax, %eax -+ /* If there is no CHAR here, return the remembered one. */ -+ jz L(return_value) -+ bsrl %eax, %eax -+ leaq -VEC_SIZE(%rdi, %rax), %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(char_and_nul): -+ /* Find both a CHAR and a nul CHAR. */ -+ addq %rcx, %rdi -+ movl %edx, %ecx -+L(char_and_nul_in_first_vec): -+# ifdef USE_AS_WCSRCHR -+ /* Keep the first bit for each matching CHAR for bsr. */ -+ andl $0x11111111, %ecx -+ andl $0x11111111, %eax -+# endif -+ /* Mask out any matching bits after the nul CHAR. */ -+ movl %ecx, %r8d -+ subl $1, %r8d -+ xorl %ecx, %r8d -+ andl %r8d, %eax -+ testl %eax, %eax -+ /* Return null pointer if the nul CHAR comes first. */ -+ jz L(return_null) -+ bsrl %eax, %eax -+ leaq -VEC_SIZE(%rdi, %rax), %rax -+ VZEROUPPER -+ ret -+ -+ .p2align 4 -+L(return_null): -+ xorl %eax, %eax -+ VZEROUPPER -+ ret -+ -+END (STRRCHR) -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcschr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcschr-kbl.S -new file mode 100644 -index 000000000..b03124767 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcschr-kbl.S -@@ -0,0 +1,3 @@ -+#define STRCHR wcschr_avx2 -+#define USE_AS_WCSCHR 1 -+#include "avx2-strchr-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcscmp-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcscmp-kbl.S -new file mode 100644 -index 000000000..bcbcd4ce7 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcscmp-kbl.S -@@ -0,0 +1,4 @@ -+#define STRCMP wcscmp_avx2 -+#define USE_AS_WCSCMP 1 -+ -+#include "avx2-strcmp-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcslen-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcslen-kbl.S -new file mode 100644 -index 000000000..f1b973572 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcslen-kbl.S -@@ -0,0 +1,4 @@ -+#define STRLEN wcslen_avx2 -+#define USE_AS_WCSLEN 1 -+ -+#include "avx2-strlen-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcsncmp-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcsncmp-kbl.S -new file mode 100644 -index 000000000..7603169c1 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcsncmp-kbl.S -@@ -0,0 +1,6 @@ -+#define STRCMP wcsncmp_avx2 -+#define USE_AS_STRNCMP 1 -+#define USE_AS_WCSCMP 1 -+ -+#include "avx_regs.h" -+#include "avx2-strcmp-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcsnlen-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcsnlen-kbl.S -new file mode 100644 -index 000000000..2095cd8e0 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcsnlen-kbl.S -@@ -0,0 +1,6 @@ -+#define STRLEN wcsnlen_avx2 -+#define USE_AS_WCSLEN 1 -+#define USE_AS_STRNLEN 1 -+ -+#include "avx_regs.h" -+#include "avx2-strlen-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx2-wcsrchr-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-wcsrchr-kbl.S -new file mode 100644 -index 000000000..fbec1286c ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-wcsrchr-kbl.S -@@ -0,0 +1,3 @@ -+#define STRRCHR wcsrchr_avx2 -+#define USE_AS_WCSRCHR 1 -+#include "avx2-strrchr-kbl.S" -diff --git a/libc/arch-x86_64/kabylake/string/avx_regs.h b/libc/arch-x86_64/kabylake/string/avx_regs.h -new file mode 100644 -index 000000000..223d97e3e ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx_regs.h -@@ -0,0 +1,26 @@ -+/* Long and pointer size in bytes. */ -+#define LP_SIZE 8 -+ -+/* Instruction to operate on long and pointer. */ -+#define LP_OP(insn) insn##q -+ -+/* Assembler address directive. */ -+#define ASM_ADDR .quad -+ -+/* Registers to hold long and pointer. */ -+#define RAX_LP rax -+#define RBP_LP rbp -+#define RBX_LP rbx -+#define RCX_LP rcx -+#define RDI_LP rdi -+#define RDX_LP rdx -+#define RSI_LP rsi -+#define RSP_LP rsp -+#define R8_LP r8 -+#define R9_LP r9 -+#define R10_LP r10 -+#define R11_LP r11 -+#define R12_LP r12 -+#define R13_LP r13 -+#define R14_LP r14 -+#define R15_LP r15 -diff --git a/libc/arch-x86_64/include/cache.h b/libc/arch-x86_64/kabylake/string/cache.h -similarity index 100% -rename from libc/arch-x86_64/include/cache.h -rename to libc/arch-x86_64/kabylake/string/cache.h -diff --git a/libc/arch-x86_64/silvermont/string/cache.h b/libc/arch-x86_64/silvermont/string/cache.h -new file mode 100644 -index 000000000..3606d2a1a ---- /dev/null -+++ b/libc/arch-x86_64/silvermont/string/cache.h -@@ -0,0 +1,36 @@ -+/* -+Copyright (c) 2014, Intel Corporation -+All rights reserved. -+ -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions are met: -+ -+ * Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ -+ * Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ -+ * Neither the name of Intel Corporation nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ -+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+/* Values are optimized for Silvermont */ -+#define SHARED_CACHE_SIZE (1024*1024) /* Silvermont L2 Cache */ -+#define DATA_CACHE_SIZE (24*1024) /* Silvermont L1 Data Cache */ -+ -+#define SHARED_CACHE_SIZE_HALF (SHARED_CACHE_SIZE / 2) -+#define DATA_CACHE_SIZE_HALF (DATA_CACHE_SIZE / 2) -diff --git a/libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S -index 0ad2d44cf..ce15cdf1c 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-stpcpy-slm.S -@@ -29,5 +29,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #define USE_AS_STPCPY --#define STRCPY stpcpy -+#define STRCPY stpcpy_generic - #include "sse2-strcpy-slm.S" -diff --git a/libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S -index 30666850b..02b4df02d 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-stpncpy-slm.S -@@ -30,5 +30,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - #define USE_AS_STRNCPY - #define USE_AS_STPCPY --#define STRCPY stpncpy -+#define STRCPY stpncpy_generic - #include "sse2-strcpy-slm.S" -diff --git a/libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S -index dd8207ff5..007adfe95 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-strcat-slm.S -@@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #ifndef STRCAT --# define STRCAT strcat -+# define STRCAT strcat_generic - #endif - - #ifndef L -diff --git a/libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S -index 3e146bfbc..ade9eac4f 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-strcpy-slm.S -@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #ifndef USE_AS_STRCAT - - # ifndef STRCPY --# define STRCPY strcpy -+# define STRCPY strcpy_generic - # endif - - # ifndef L -diff --git a/libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S -index 3772fe770..df24f9de2 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-strlen-slm.S -@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #ifndef USE_AS_STRCAT - - #ifndef STRLEN --# define STRLEN strlen -+# define STRLEN strlen_generic - #endif - - #ifndef L -diff --git a/libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S -index 6b4a43084..c5394f9d5 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-strncat-slm.S -@@ -29,5 +29,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #define USE_AS_STRNCAT --#define STRCAT strncat -+#define STRCAT strncat_generic - #include "sse2-strcat-slm.S" -diff --git a/libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S b/libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S -index 594e78f74..2e8d68d12 100644 ---- a/libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S -+++ b/libc/arch-x86_64/silvermont/string/sse2-strncpy-slm.S -@@ -29,5 +29,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #define USE_AS_STRNCPY --#define STRCPY strncpy -+#define STRCPY strncpy_generic - #include "sse2-strcpy-slm.S" -diff --git a/libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S b/libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S -index e8acd5ba4..fa2542f00 100644 ---- a/libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S -+++ b/libc/arch-x86_64/silvermont/string/ssse3-strcmp-slm.S -@@ -43,7 +43,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #else - #define UPDATE_STRNCMP_COUNTER - #ifndef STRCMP --#define STRCMP strcmp -+#define STRCMP strcmp_generic - #endif - #endif - -diff --git a/libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S b/libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S -index 0e4077517..5d20a483f 100644 ---- a/libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S -+++ b/libc/arch-x86_64/silvermont/string/ssse3-strncmp-slm.S -@@ -29,5 +29,5 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - #define USE_AS_STRNCMP --#define STRCMP strncmp -+#define STRCMP strncmp_generic - #include "ssse3-strcmp-slm.S" -diff --git a/libc/arch-x86_64/static_function_dispatch.S b/libc/arch-x86_64/static_function_dispatch.S -index 979ce4f18..5c0f1f2ba 100644 ---- a/libc/arch-x86_64/static_function_dispatch.S -+++ b/libc/arch-x86_64/static_function_dispatch.S -@@ -38,6 +38,25 @@ FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic) - FUNCTION_DELEGATE(memcmp, memcmp_generic) - FUNCTION_DELEGATE(memcpy, memmove_generic) - FUNCTION_DELEGATE(memmove, memmove_generic) --FUNCTION_DELEGATE(memchr, memchr_openbsd) --FUNCTION_DELEGATE(memrchr, memrchr_openbsd) --//FUNCTION_DELEGATE(wmemset, wmemset_freebsd) -+FUNCTION_DELEGATE(memchr, memchr_generic) -+FUNCTION_DELEGATE(memrchr, memrchr_generic) -+//FUNCTION_DELEGATE(wmemset, wmemset_generic) -+FUNCTION_DELEGATE(strcmp, strcmp_generic) -+FUNCTION_DELEGATE(strncmp, strncmp_generic) -+FUNCTION_DELEGATE(strcpy, strcpy_generic) -+FUNCTION_DELEGATE(strncpy, strncpy_generic) -+FUNCTION_DELEGATE(stpcpy, stpcpy_generic) -+FUNCTION_DELEGATE(stpncpy, stpncpy_generic) -+FUNCTION_DELEGATE(strlen, strlen_generic) -+FUNCTION_DELEGATE(strnlen, strnlen_generic) -+FUNCTION_DELEGATE(strchr, strchr_generic) -+FUNCTION_DELEGATE(strrchr, strrchr_generic) -+FUNCTION_DELEGATE(strcat, strcat_generic) -+FUNCTION_DELEGATE(strncat, strncat_generic) -+FUNCTION_DELEGATE(wcscmp, wcscmp_generic) -+FUNCTION_DELEGATE(wcsncmp, wcsncmp_generic) -+FUNCTION_DELEGATE(wcslen, wcslen_generic) -+FUNCTION_DELEGATE(wcsnlen, wcsnlen_generic) -+FUNCTION_DELEGATE(wcschr, wcschr_generic) -+FUNCTION_DELEGATE(wcsrchr, wcsrchr_generic) -+ --- -2.17.1 - diff --git a/aosp_diff/preliminary/bionic/0002-WA-Fixed-build-error-in-bionic.patch b/aosp_diff/preliminary/bionic/0002-WA-Fixed-build-error-in-bionic.patch new file mode 100644 index 0000000000..2da63b3c88 --- /dev/null +++ b/aosp_diff/preliminary/bionic/0002-WA-Fixed-build-error-in-bionic.patch @@ -0,0 +1,32 @@ +From a745837e936b0c996a348329db1a985b2543bf87 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Tue, 18 Jun 2024 09:42:41 +0530 +Subject: [PATCH] [WA] Fixed build error in bionic. + +Observed build issue due to unavaiable reference of __sF[]. +For now removing flag to make it avaiable. + +Tests: Build the EB. there was no issue due to this change. + +Tracked-On: NA +Signed-off-by: Ankit Agarwal +--- + libc/include/stdio.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libc/include/stdio.h b/libc/include/stdio.h +index 279c6584a..50a016b33 100644 +--- a/libc/include/stdio.h ++++ b/libc/include/stdio.h +@@ -69,7 +69,7 @@ extern FILE* _Nonnull stderr __INTRODUCED_IN(23); + #define stderr stderr + #else + /* Before M the actual symbols for stdin and friends had different names. */ +-extern FILE __sF[] __REMOVED_IN(23, "Use stdin/stdout/stderr"); ++extern FILE __sF[];// __REMOVED_IN(23, "Use stdin/stdout/stderr"); + + #define stdin (&__sF[0]) + #define stdout (&__sF[1]) +-- +2.34.1 + diff --git a/aosp_diff/preliminary/bionic/0003-avx2-implementation-for-memmove-api.patch b/aosp_diff/preliminary/bionic/0003-avx2-implementation-for-memmove-api.patch deleted file mode 100644 index ca393c23d4..0000000000 --- a/aosp_diff/preliminary/bionic/0003-avx2-implementation-for-memmove-api.patch +++ /dev/null @@ -1,643 +0,0 @@ -From eb8e947b7d28d6bb297a9fdb4a790bdbe74473d9 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Wed, 1 Nov 2023 18:43:18 +0530 -Subject: [PATCH] avx2 implementation for memmove api - -This patch includes handwritten avx2 assembly -implementation for memmove 64-bit. - -Signed-off-by: ahs ---- - libc/Android.bp | 1 + - .../arch-x86_64/dynamic_function_dispatch.cpp | 2 + - .../kabylake/string/avx2-memmove-kbl.S | 593 ++++++++++++++++++ - 3 files changed, 596 insertions(+) - create mode 100644 libc/arch-x86_64/kabylake/string/avx2-memmove-kbl.S - -diff --git a/libc/Android.bp b/libc/Android.bp -index 4a4aac198..6d1b65b86 100644 ---- a/libc/Android.bp -+++ b/libc/Android.bp -@@ -1052,6 +1052,7 @@ cc_library_static { - "arch-x86_64/kabylake/string/avx2-memcmp-kbl.S", - "arch-x86_64/kabylake/string/avx2-memchr-kbl.S", - "arch-x86_64/kabylake/string/avx2-memrchr-kbl.S", -+ "arch-x86_64/kabylake/string/avx2-memmove-kbl.S", - "arch-x86_64/kabylake/string/avx2-strcmp-kbl.S", - "arch-x86_64/kabylake/string/avx2-strncmp-kbl.S", - "arch-x86_64/kabylake/string/avx2-strlen-kbl.S", -diff --git a/libc/arch-x86_64/dynamic_function_dispatch.cpp b/libc/arch-x86_64/dynamic_function_dispatch.cpp -index 182eb4200..5bcf63e4c 100644 ---- a/libc/arch-x86_64/dynamic_function_dispatch.cpp -+++ b/libc/arch-x86_64/dynamic_function_dispatch.cpp -@@ -55,6 +55,8 @@ DEFINE_IFUNC_FOR(memcmp) { - - typedef void* memmove_func(void* __dst, const void* __src, size_t __n); - DEFINE_IFUNC_FOR(memmove) { -+ __builtin_cpu_init(); -+ if (__builtin_cpu_supports("avx2")) RETURN_FUNC(memmove_func, memmove_avx2); - RETURN_FUNC(memmove_func, memmove_generic); - } - -diff --git a/libc/arch-x86_64/kabylake/string/avx2-memmove-kbl.S b/libc/arch-x86_64/kabylake/string/avx2-memmove-kbl.S -new file mode 100644 -index 000000000..02e9ec1d2 ---- /dev/null -+++ b/libc/arch-x86_64/kabylake/string/avx2-memmove-kbl.S -@@ -0,0 +1,593 @@ -+/* -+Copyright (c) 2014, Intel Corporation -+All rights reserved. -+ -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions are met: -+ -+ * Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ -+ * Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ -+ * Neither the name of Intel Corporation nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ -+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+#include "cache.h" -+ -+#ifndef MEMMOVE -+# define MEMMOVE memmove_avx2 -+#endif -+ -+#ifndef L -+# define L(label) .L##label -+#endif -+ -+#ifndef cfi_startproc -+# define cfi_startproc .cfi_startproc -+#endif -+ -+#ifndef cfi_endproc -+# define cfi_endproc .cfi_endproc -+#endif -+ -+#ifndef cfi_rel_offset -+# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off -+#endif -+ -+#ifndef cfi_restore -+# define cfi_restore(reg) .cfi_restore reg -+#endif -+ -+#ifndef cfi_adjust_cfa_offset -+# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off -+#endif -+ -+#ifndef ENTRY -+# define ENTRY(name) \ -+ .type name, @function; \ -+ .globl name; \ -+ .p2align 4; \ -+name: \ -+ cfi_startproc -+#endif -+ -+#ifndef ALIAS_SYMBOL -+# define ALIAS_SYMBOL(alias, original) \ -+ .globl alias; \ -+ .equ alias, original -+#endif -+ -+#ifndef END -+# define END(name) \ -+ cfi_endproc; \ -+ .size name, .-name -+#endif -+ -+#define CFI_PUSH(REG) \ -+ cfi_adjust_cfa_offset (4); \ -+ cfi_rel_offset (REG, 0) -+ -+#define CFI_POP(REG) \ -+ cfi_adjust_cfa_offset (-4); \ -+ cfi_restore (REG) -+ -+#define PUSH(REG) push REG; -+#define POP(REG) pop REG; -+ -+#define ENTRANCE PUSH (%rbx); -+#define RETURN_END POP (%rbx); ret -+#define RETURN RETURN_END; -+ -+ .section .text.avx2,"ax",@progbits -+ENTRY (MEMMOVE) -+ ENTRANCE -+ mov %rdi, %rax -+ -+/* Check whether we should copy backward or forward. */ -+ cmp %rsi, %rdi -+ je L(mm_return) -+ jg L(mm_len_0_or_more_backward) -+ -+/* Now do checks for lengths. We do [0..16], [0..32], [0..64], [0..128] -+ separately. */ -+ cmp $16, %rdx -+ jbe L(mm_len_0_16_bytes_forward) -+ -+ cmp $32, %rdx -+ ja L(mm_len_32_or_more_forward) -+ -+/* Copy [0..32] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu -16(%rsi, %rdx), %xmm1 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_32_or_more_forward): -+ cmp $64, %rdx -+ ja L(mm_len_64_or_more_forward) -+ -+/* Copy [0..64] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu -16(%rsi, %rdx), %xmm2 -+ movdqu -32(%rsi, %rdx), %xmm3 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, -16(%rdi, %rdx) -+ movdqu %xmm3, -32(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_64_or_more_forward): -+ cmp $128, %rdx -+ ja L(mm_len_128_or_more_forward) -+ -+/* Copy [0..128] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu 32(%rsi), %xmm2 -+ movdqu 48(%rsi), %xmm3 -+ movdqu -64(%rsi, %rdx), %xmm4 -+ movdqu -48(%rsi, %rdx), %xmm5 -+ movdqu -32(%rsi, %rdx), %xmm6 -+ movdqu -16(%rsi, %rdx), %xmm7 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, 32(%rdi) -+ movdqu %xmm3, 48(%rdi) -+ movdqu %xmm4, -64(%rdi, %rdx) -+ movdqu %xmm5, -48(%rdi, %rdx) -+ movdqu %xmm6, -32(%rdi, %rdx) -+ movdqu %xmm7, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_128_or_more_forward): -+ cmp $256, %rdx -+ ja L(mm_len_256_or_more_forward) -+ -+/* Copy [0..256] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu 32(%rsi), %xmm2 -+ movdqu 48(%rsi), %xmm3 -+ movdqu 64(%rsi), %xmm4 -+ movdqu 80(%rsi), %xmm5 -+ movdqu 96(%rsi), %xmm6 -+ movdqu 112(%rsi), %xmm7 -+ movdqu -128(%rsi, %rdx), %xmm8 -+ movdqu -112(%rsi, %rdx), %xmm9 -+ movdqu -96(%rsi, %rdx), %xmm10 -+ movdqu -80(%rsi, %rdx), %xmm11 -+ movdqu -64(%rsi, %rdx), %xmm12 -+ movdqu -48(%rsi, %rdx), %xmm13 -+ movdqu -32(%rsi, %rdx), %xmm14 -+ movdqu -16(%rsi, %rdx), %xmm15 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, 32(%rdi) -+ movdqu %xmm3, 48(%rdi) -+ movdqu %xmm4, 64(%rdi) -+ movdqu %xmm5, 80(%rdi) -+ movdqu %xmm6, 96(%rdi) -+ movdqu %xmm7, 112(%rdi) -+ movdqu %xmm8, -128(%rdi, %rdx) -+ movdqu %xmm9, -112(%rdi, %rdx) -+ movdqu %xmm10, -96(%rdi, %rdx) -+ movdqu %xmm11, -80(%rdi, %rdx) -+ movdqu %xmm12, -64(%rdi, %rdx) -+ movdqu %xmm13, -48(%rdi, %rdx) -+ movdqu %xmm14, -32(%rdi, %rdx) -+ movdqu %xmm15, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_256_or_more_forward): -+/* Aligning the address of destination. */ -+/* save first unaligned 128 bytes */ -+ vmovdqu (%rsi), %ymm0 -+ vmovdqu 32(%rsi), %ymm1 -+ vmovdqu 64(%rsi), %ymm2 -+ vmovdqu 96(%rsi), %ymm3 -+ -+ lea 128(%rdi), %r8 -+ and $-128, %r8 /* r8 now aligned to next 128 byte boundary */ -+ sub %rdi, %rsi /* rsi = src - dst = diff */ -+ -+ vmovdqu (%r8, %rsi), %ymm4 -+ vmovdqu 32(%r8, %rsi), %ymm5 -+ vmovdqu 64(%r8, %rsi), %ymm6 -+ vmovdqu 96(%r8, %rsi), %ymm7 -+ -+ vmovdqu %ymm0, (%rdi) -+ vmovdqu %ymm1, 32(%rdi) -+ vmovdqu %ymm2, 64(%rdi) -+ vmovdqu %ymm3, 96(%rdi) -+ vmovdqa %ymm4, (%r8) -+ vmovaps %ymm5, 32(%r8) -+ vmovaps %ymm6, 64(%r8) -+ vmovaps %ymm7, 96(%r8) -+ add $128, %r8 -+ -+ lea (%rdi, %rdx), %rbx -+ and $-128, %rbx -+ cmp %r8, %rbx -+ jbe L(mm_copy_remaining_forward) -+ -+ cmp $SHARED_CACHE_SIZE_HALF, %rdx -+ jae L(mm_large_page_loop_forward) -+ -+ .p2align 4 -+L(mm_main_loop_forward): -+ prefetcht0 128(%r8, %rsi) -+ vmovdqu (%r8, %rsi), %ymm0 -+ vmovdqu 32(%r8, %rsi), %ymm1 -+ vmovdqa %ymm0, (%r8) -+ vmovaps %ymm1, 32(%r8) -+ lea 64(%r8), %r8 -+ cmp %r8, %rbx -+ ja L(mm_main_loop_forward) -+ -+L(mm_copy_remaining_forward): -+ add %rdi, %rdx -+ sub %r8, %rdx -+/* We copied all up till %rdi position in the dst. -+ In %rdx now is how many bytes are left to copy. -+ Now we need to advance %r8. */ -+ lea (%r8, %rsi), %r9 -+ -+L(mm_remaining_0_128_bytes_forward): -+ cmp $64, %rdx -+ ja L(mm_remaining_65_128_bytes_forward) -+ cmp $32, %rdx -+ ja L(mm_remaining_33_64_bytes_forward) -+ vzeroupper -+ cmp $16, %rdx -+ ja L(mm_remaining_17_32_bytes_forward) -+ test %rdx, %rdx -+ .p2align 4,,2 -+ je L(mm_return) -+ -+ cmpb $8, %dl -+ ja L(mm_remaining_9_16_bytes_forward) -+ cmpb $4, %dl -+ .p2align 4,,5 -+ ja L(mm_remaining_5_8_bytes_forward) -+ cmpb $2, %dl -+ .p2align 4,,1 -+ ja L(mm_remaining_3_4_bytes_forward) -+ movzbl -1(%r9,%rdx), %esi -+ movzbl (%r9), %ebx -+ movb %sil, -1(%r8,%rdx) -+ movb %bl, (%r8) -+ jmp L(mm_return) -+ -+L(mm_remaining_65_128_bytes_forward): -+ vmovdqu (%r9), %ymm0 -+ vmovdqu 32(%r9), %ymm1 -+ vmovdqu -64(%r9, %rdx), %ymm2 -+ vmovdqu -32(%r9, %rdx), %ymm3 -+ vmovdqu %ymm0, (%r8) -+ vmovdqu %ymm1, 32(%r8) -+ vmovdqu %ymm2, -64(%r8, %rdx) -+ vmovdqu %ymm3, -32(%r8, %rdx) -+ jmp L(mm_return) -+ -+L(mm_remaining_33_64_bytes_forward): -+ vmovdqu (%r9), %ymm0 -+ vmovdqu -32(%r9, %rdx), %ymm1 -+ vmovdqu %ymm0, (%r8) -+ vmovdqu %ymm1, -32(%r8, %rdx) -+ jmp L(mm_return) -+ -+L(mm_remaining_17_32_bytes_forward): -+ movdqu (%r9), %xmm0 -+ movdqu -16(%r9, %rdx), %xmm1 -+ movdqu %xmm0, (%r8) -+ movdqu %xmm1, -16(%r8, %rdx) -+ jmp L(mm_return) -+ -+L(mm_remaining_5_8_bytes_forward): -+ movl (%r9), %esi -+ movl -4(%r9,%rdx), %ebx -+ movl %esi, (%r8) -+ movl %ebx, -4(%r8,%rdx) -+ jmp L(mm_return) -+ -+L(mm_remaining_9_16_bytes_forward): -+ mov (%r9), %rsi -+ mov -8(%r9, %rdx), %rbx -+ mov %rsi, (%r8) -+ mov %rbx, -8(%r8, %rdx) -+ jmp L(mm_return) -+ -+L(mm_remaining_3_4_bytes_forward): -+ movzwl -2(%r9,%rdx), %esi -+ movzwl (%r9), %ebx -+ movw %si, -2(%r8,%rdx) -+ movw %bx, (%r8) -+ jmp L(mm_return) -+ -+L(mm_len_0_16_bytes_forward): -+ testb $24, %dl -+ jne L(mm_len_9_16_bytes_forward) -+ testb $4, %dl -+ .p2align 4,,5 -+ jne L(mm_len_5_8_bytes_forward) -+ test %rdx, %rdx -+ .p2align 4,,2 -+ je L(mm_return) -+ testb $2, %dl -+ .p2align 4,,1 -+ jne L(mm_len_2_4_bytes_forward) -+ movzbl -1(%rsi,%rdx), %ebx -+ movzbl (%rsi), %esi -+ movb %bl, -1(%rdi,%rdx) -+ movb %sil, (%rdi) -+ jmp L(mm_return) -+ -+L(mm_len_2_4_bytes_forward): -+ movzwl -2(%rsi,%rdx), %ebx -+ movzwl (%rsi), %esi -+ movw %bx, -2(%rdi,%rdx) -+ movw %si, (%rdi) -+ jmp L(mm_return) -+ -+L(mm_len_5_8_bytes_forward): -+ movl (%rsi), %ebx -+ movl -4(%rsi,%rdx), %esi -+ movl %ebx, (%rdi) -+ movl %esi, -4(%rdi,%rdx) -+ jmp L(mm_return) -+ -+L(mm_len_9_16_bytes_forward): -+ mov (%rsi), %rbx -+ mov -8(%rsi, %rdx), %rsi -+ mov %rbx, (%rdi) -+ mov %rsi, -8(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_recalc_len): -+/* Compute in %rdx how many bytes are left to copy after -+ the main loop stops. */ -+ vzeroupper -+ mov %rbx, %rdx -+ sub %rdi, %rdx -+/* The code for copying backwards. */ -+L(mm_len_0_or_more_backward): -+ -+/* Now do checks for lengths. We do [0..16], [16..32], [32..64], [64..128] -+ separately. */ -+ cmp $16, %rdx -+ jbe L(mm_len_0_16_bytes_backward) -+ -+ cmp $32, %rdx -+ ja L(mm_len_32_or_more_backward) -+ -+/* Copy [0..32] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu -16(%rsi, %rdx), %xmm1 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_32_or_more_backward): -+ cmp $64, %rdx -+ ja L(mm_len_64_or_more_backward) -+ -+/* Copy [0..64] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu -16(%rsi, %rdx), %xmm2 -+ movdqu -32(%rsi, %rdx), %xmm3 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, -16(%rdi, %rdx) -+ movdqu %xmm3, -32(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_64_or_more_backward): -+ cmp $128, %rdx -+ ja L(mm_len_128_or_more_backward) -+ -+/* Copy [0..128] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu 32(%rsi), %xmm2 -+ movdqu 48(%rsi), %xmm3 -+ movdqu -64(%rsi, %rdx), %xmm4 -+ movdqu -48(%rsi, %rdx), %xmm5 -+ movdqu -32(%rsi, %rdx), %xmm6 -+ movdqu -16(%rsi, %rdx), %xmm7 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, 32(%rdi) -+ movdqu %xmm3, 48(%rdi) -+ movdqu %xmm4, -64(%rdi, %rdx) -+ movdqu %xmm5, -48(%rdi, %rdx) -+ movdqu %xmm6, -32(%rdi, %rdx) -+ movdqu %xmm7, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_128_or_more_backward): -+ cmp $256, %rdx -+ ja L(mm_len_256_or_more_backward) -+ -+/* Copy [0..256] and return. */ -+ movdqu (%rsi), %xmm0 -+ movdqu 16(%rsi), %xmm1 -+ movdqu 32(%rsi), %xmm2 -+ movdqu 48(%rsi), %xmm3 -+ movdqu 64(%rsi), %xmm4 -+ movdqu 80(%rsi), %xmm5 -+ movdqu 96(%rsi), %xmm6 -+ movdqu 112(%rsi), %xmm7 -+ movdqu -128(%rsi, %rdx), %xmm8 -+ movdqu -112(%rsi, %rdx), %xmm9 -+ movdqu -96(%rsi, %rdx), %xmm10 -+ movdqu -80(%rsi, %rdx), %xmm11 -+ movdqu -64(%rsi, %rdx), %xmm12 -+ movdqu -48(%rsi, %rdx), %xmm13 -+ movdqu -32(%rsi, %rdx), %xmm14 -+ movdqu -16(%rsi, %rdx), %xmm15 -+ movdqu %xmm0, (%rdi) -+ movdqu %xmm1, 16(%rdi) -+ movdqu %xmm2, 32(%rdi) -+ movdqu %xmm3, 48(%rdi) -+ movdqu %xmm4, 64(%rdi) -+ movdqu %xmm5, 80(%rdi) -+ movdqu %xmm6, 96(%rdi) -+ movdqu %xmm7, 112(%rdi) -+ movdqu %xmm8, -128(%rdi, %rdx) -+ movdqu %xmm9, -112(%rdi, %rdx) -+ movdqu %xmm10, -96(%rdi, %rdx) -+ movdqu %xmm11, -80(%rdi, %rdx) -+ movdqu %xmm12, -64(%rdi, %rdx) -+ movdqu %xmm13, -48(%rdi, %rdx) -+ movdqu %xmm14, -32(%rdi, %rdx) -+ movdqu %xmm15, -16(%rdi, %rdx) -+ jmp L(mm_return) -+ -+L(mm_len_256_or_more_backward): -+/* Aligning the address of destination. We need to save -+ 128 bytes from the source in order not to overwrite them. */ -+ vmovdqu -32(%rsi, %rdx), %ymm0 -+ vmovdqu -64(%rsi, %rdx), %ymm1 -+ vmovdqu -96(%rsi, %rdx), %ymm2 -+ vmovdqu -128(%rsi, %rdx), %ymm3 -+ -+ lea (%rdi, %rdx), %r9 -+ and $-128, %r9 /* r9 = aligned dst */ -+ -+ mov %rsi, %r8 -+ sub %rdi, %r8 /* r8 = src - dst, diff */ -+ -+ vmovdqu -32(%r9, %r8), %ymm4 -+ vmovdqu -64(%r9, %r8), %ymm5 -+ vmovdqu -96(%r9, %r8), %ymm6 -+ vmovdqu -128(%r9, %r8), %ymm7 -+ -+ vmovdqu %ymm0, -32(%rdi, %rdx) -+ vmovdqu %ymm1, -64(%rdi, %rdx) -+ vmovdqu %ymm2, -96(%rdi, %rdx) -+ vmovdqu %ymm3, -128(%rdi, %rdx) -+ vmovdqa %ymm4, -32(%r9) -+ vmovdqa %ymm5, -64(%r9) -+ vmovdqa %ymm6, -96(%r9) -+ vmovdqa %ymm7, -128(%r9) -+ lea -128(%r9), %r9 -+ -+ lea 128(%rdi), %rbx -+ and $-128, %rbx -+ -+ cmp %r9, %rbx -+ jae L(mm_recalc_len) -+ -+ cmp $SHARED_CACHE_SIZE_HALF, %rdx -+ jae L(mm_large_page_loop_backward) -+ -+ .p2align 4 -+L(mm_main_loop_backward): -+ prefetcht0 -128(%r9, %r8) -+ -+ vmovdqu -64(%r9, %r8), %ymm0 -+ vmovdqu -32(%r9, %r8), %ymm1 -+ vmovdqa %ymm0, -64(%r9) -+ vmovaps %ymm1, -32(%r9) -+ lea -64(%r9), %r9 -+ cmp %r9, %rbx -+ jb L(mm_main_loop_backward) -+ jmp L(mm_recalc_len) -+ -+/* Copy [0..16] and return. */ -+L(mm_len_0_16_bytes_backward): -+ testb $24, %dl -+ jnz L(mm_len_9_16_bytes_backward) -+ testb $4, %dl -+ .p2align 4,,5 -+ jnz L(mm_len_5_8_bytes_backward) -+ test %rdx, %rdx -+ .p2align 4,,2 -+ je L(mm_return) -+ testb $2, %dl -+ .p2align 4,,1 -+ jne L(mm_len_3_4_bytes_backward) -+ movzbl -1(%rsi,%rdx), %ebx -+ movzbl (%rsi), %ecx -+ movb %bl, -1(%rdi,%rdx) -+ movb %cl, (%rdi) -+ jmp L(mm_return) -+ -+L(mm_len_3_4_bytes_backward): -+ movzwl -2(%rsi,%rdx), %ebx -+ movzwl (%rsi), %ecx -+ movw %bx, -2(%rdi,%rdx) -+ movw %cx, (%rdi) -+ jmp L(mm_return) -+ -+L(mm_len_9_16_bytes_backward): -+ movl -4(%rsi,%rdx), %ebx -+ movl -8(%rsi,%rdx), %ecx -+ movl %ebx, -4(%rdi,%rdx) -+ movl %ecx, -8(%rdi,%rdx) -+ sub $8, %rdx -+ jmp L(mm_len_0_16_bytes_backward) -+ -+L(mm_len_5_8_bytes_backward): -+ movl (%rsi), %ebx -+ movl -4(%rsi,%rdx), %ecx -+ movl %ebx, (%rdi) -+ movl %ecx, -4(%rdi,%rdx) -+ -+L(mm_return): -+ vzeroupper -+ RETURN -+ -+/* Big length copy forward part. */ -+ -+ .p2align 4 -+L(mm_large_page_loop_forward): -+ vmovdqu (%r8, %rsi), %ymm0 -+ vmovdqu 32(%r8, %rsi), %ymm1 -+ vmovdqu 64(%r8, %rsi), %ymm2 -+ vmovdqu 96(%r8, %rsi), %ymm3 -+ vmovntdq %ymm0, (%r8) -+ vmovntdq %ymm1, 32(%r8) -+ vmovntdq %ymm2, 64(%r8) -+ vmovntdq %ymm3, 96(%r8) -+ lea 128(%r8), %r8 -+ cmp %r8, %rbx -+ ja L(mm_large_page_loop_forward) -+ sfence -+ jmp L(mm_copy_remaining_forward) -+ -+/* Big length copy backward part. */ -+ .p2align 4 -+L(mm_large_page_loop_backward): -+ vmovdqu -64(%r9, %r8), %ymm0 -+ vmovdqu -32(%r9, %r8), %ymm1 -+ vmovntdq %ymm0, -64(%r9) -+ vmovntdq %ymm1, -32(%r9) -+ lea -64(%r9), %r9 -+ cmp %r9, %rbx -+ jb L(mm_large_page_loop_backward) -+ sfence -+ jmp L(mm_recalc_len) -+ -+END (MEMMOVE) -+ -+//ALIAS_SYMBOL(memcpy, MEMMOVE) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/make/0004-Remove-usage-of-F-string.patch b/aosp_diff/preliminary/build/make/0004-Remove-usage-of-F-string.patch deleted file mode 100644 index ef7717dabd..0000000000 --- a/aosp_diff/preliminary/build/make/0004-Remove-usage-of-F-string.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 4725c8c7cec68a56f24460091f6b925acdd853ca Mon Sep 17 00:00:00 2001 -From: svenate -Date: Wed, 30 Mar 2022 07:13:54 +0530 -Subject: [PATCH] Remove usage of F-string - -The usage of F-string is supported only from python 3.6 and -was giving build error: -"SyntaxError: invalid syntax" - -Change-Id: I3b5e9dcc4dbf12dfd1459eb7d312517058f6e228 -Signed-off-by: svenate ---- - tools/releasetools/common.py | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index eb7886209a..68eb36f678 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -1765,8 +1765,7 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file, - - BOOT_SIGNATURE_SIZE = 16 * 1024 - if len(boot_signature_bytes) > BOOT_SIGNATURE_SIZE: -- raise ValueError( -- f"GKI boot_signature size must be <= {BOOT_SIGNATURE_SIZE}") -+ raise ValueError('GKI boot_signature size must be <= {}'.format(BOOT_SIGNATURE_SIZE)) - boot_signature_bytes += ( - b'\0' * (BOOT_SIGNATURE_SIZE - len(boot_signature_bytes))) - assert len(boot_signature_bytes) == BOOT_SIGNATURE_SIZE -@@ -2026,11 +2025,11 @@ def _BuildVendorBootImage(sourcedir, partition_name, info_dict=None): - # AVB: if enabled, calculate and add hash. - if info_dict.get("avb_enable") == "true": - avbtool = info_dict["avb_avbtool"] -- part_size = info_dict[f'{partition_name}_size'] -+ part_size = info_dict['{}_size'.format(partition_name)] - cmd = [avbtool, "add_hash_footer", "--image", img.name, - "--partition_size", str(part_size), "--partition_name", partition_name] - AppendAVBSigningArgs(cmd, partition_name) -- args = info_dict.get(f'avb_{partition_name}_add_hash_footer_args') -+ args = info_dict.get('avb_{}_add_hash_footer_args'.format(partition_name)) - if args and args.strip(): - split_args = ResolveAVBSigningPathArgs(shlex.split(args)) - cmd.extend(split_args) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/make/0006-WA-Revert-Handle-zip64-extra-fields-better.patch b/aosp_diff/preliminary/build/make/0004-WA-Revert-Handle-zip64-extra-fields-better.patch similarity index 100% rename from aosp_diff/preliminary/build/make/0006-WA-Revert-Handle-zip64-extra-fields-better.patch rename to aosp_diff/preliminary/build/make/0004-WA-Revert-Handle-zip64-extra-fields-better.patch diff --git a/aosp_diff/preliminary/build/make/0005-WA-Revert-Handle-symlinks-when-extracting-zipfiles.patch b/aosp_diff/preliminary/build/make/0005-WA-Revert-Handle-symlinks-when-extracting-zipfiles.patch deleted file mode 100644 index b5d198e4c1..0000000000 --- a/aosp_diff/preliminary/build/make/0005-WA-Revert-Handle-symlinks-when-extracting-zipfiles.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 18072c7708f7a50ed7c226802400282bda0aa3f7 Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Tue, 29 Aug 2023 08:33:46 +0000 -Subject: [PATCH] WA - Revert "Handle symlinks when extracting zipfiles" - -This reverts commit 0e7644ff0674fd5fb86502b6a8f9c05332634041. -Since Android build is failing because of this patch. -This will be removed and fix will be merged. - -Tracked-On: NA -Change-Id: I6d0bbdb9e1753d57867e5688afc3c4b66176edfb -Signed-off-by: Tanuj Tekriwal ---- - tools/releasetools/common.py | 27 ++------------------------- - 1 file changed, 2 insertions(+), 25 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index 3d55b2e000..160f976553 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -35,7 +35,6 @@ import shlex - import shutil - import subprocess - import sys --import stat - import tempfile - import threading - import time -@@ -2102,26 +2101,6 @@ def Gunzip(in_filename, out_filename): - shutil.copyfileobj(in_file, out_file) - - --def UnzipSingleFile(input_zip: zipfile.ZipFile, info: zipfile.ZipInfo, dirname: str): -- # According to https://stackoverflow.com/questions/434641/how-do-i-set-permissions-attributes-on-a-file-in-a-zip-file-using-pythons-zip/6297838#6297838 -- # higher bits of |external_attr| are unix file permission and types -- unix_filetype = info.external_attr >> 16 -- -- def CheckMask(a, mask): -- return (a & mask) == mask -- -- def IsSymlink(a): -- return CheckMask(a, stat.S_IFLNK) -- # python3.11 zipfile implementation doesn't handle symlink correctly -- if not IsSymlink(unix_filetype): -- return input_zip.extract(info, dirname) -- if dirname is None: -- dirname = os.getcwd() -- target = os.path.join(dirname, info.filename) -- os.makedirs(os.path.dirname(target), exist_ok=True) -- os.symlink(input_zip.read(info).decode(), target) -- -- - def UnzipToDir(filename, dirname, patterns=None): - """Unzips the archive to the given directory. - -@@ -2167,11 +2146,9 @@ def UnzipToDir(filename, dirname, patterns=None): - # There isn't any matching files. Don't unzip anything. - if not filtered: - return -- for info in filtered: -- UnzipSingleFile(input_zip, info, dirname) -+ input_zip.extractall(dirname, filtered) - else: -- for info in entries: -- UnzipSingleFile(input_zip, info, dirname) -+ input_zip.extractall(dirname, entries) - - - def UnzipTemp(filename, patterns=None): --- -2.39.2 - diff --git a/aosp_diff/preliminary/build/make/0006-Revert-Add-an-execution-check-for-BOARD_KERNEL_VERSI.patch b/aosp_diff/preliminary/build/make/0006-Revert-Add-an-execution-check-for-BOARD_KERNEL_VERSI.patch new file mode 100644 index 0000000000..44f5a23f80 --- /dev/null +++ b/aosp_diff/preliminary/build/make/0006-Revert-Add-an-execution-check-for-BOARD_KERNEL_VERSI.patch @@ -0,0 +1,89 @@ +From e8a00f1260995b884bd8edc94f9608a5603bca00 Mon Sep 17 00:00:00 2001 +From: Jeevaka Prabu Badrappan +Date: Wed, 14 Aug 2024 09:48:49 +0530 +Subject: [PATCH] Revert "Add an execution check for BOARD_KERNEL_VERSION" + +This reverts commit 4a4bbda6e7fa0856facdfe05e500c969c9f1e2ec as it is +not working when kernel is built from source. Commit checks the +BOARD_KERNEL_VERSION with the kernel version extracted from the built +kernel. Check fails as the build kernel has kernel version with hash +suffix whereas the BOARD_KERNEL_VERSION only has the kernel version. + +Tests done: +- Android builds with kernel vintf check enabled + +Tracked-On: OAM-123601 +Signed-off-by: Jeevaka Prabu Badrappan +--- + core/Makefile | 34 +++++++++++++--------------------- + 1 file changed, 13 insertions(+), 21 deletions(-) + +diff --git a/core/Makefile b/core/Makefile +index cdb8423a9d..6797a1d157 100644 +--- a/core/Makefile ++++ b/core/Makefile +@@ -5240,48 +5240,40 @@ BUILT_KERNEL_VERSION_FILE := $(intermediates)/kernel_version.txt + + my_board_extracted_kernel := + +-# Tools for decompression that is not in PATH. +-# Check $(EXTRACT_KERNEL) for decompression algorithms supported by the script. +-# Algorithms that are in the script but not in this list will be found in PATH. +-my_decompress_tools := \ +- lz4:$(HOST_OUT_EXECUTABLES)/lz4 \ +- +- + # BOARD_KERNEL_CONFIG_FILE and BOARD_KERNEL_VERSION can be used to override the values extracted + # from INSTALLED_KERNEL_TARGET. +-ifdef BOARD_KERNEL_VERSION +-$(BUILT_KERNEL_VERSION_FILE): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools) +-$(BUILT_KERNEL_VERSION_FILE): $(foreach pair,$(my_decompress_tools),$(call word-colon,2,$(pair))) +-$(BUILT_KERNEL_VERSION_FILE): $(EXTRACT_KERNEL) $(firstword $(INSTALLED_KERNEL_TARGET)) +- KERNEL_RELEASE=`$(EXTRACT_KERNEL) --tools $(PRIVATE_DECOMPRESS_TOOLS) --input $(firstword $(INSTALLED_KERNEL_TARGET)) \ +- --output-release` ;\ +- if [ "$$KERNEL_RELEASE" != '$(BOARD_KERNEL_VERSION)' ]; then \ +- echo "Specified kernel version '$(BOARD_KERNEL_VERSION)' does not match actual kernel version '$$KERNEL_RELEASE' " ; exit 1; fi; +- echo '$(BOARD_KERNEL_VERSION)' > $@ +- + ifdef BOARD_KERNEL_CONFIG_FILE ++ifdef BOARD_KERNEL_VERSION + $(BUILT_KERNEL_CONFIGS_FILE): $(BOARD_KERNEL_CONFIG_FILE) + cp $< $@ ++$(BUILT_KERNEL_VERSION_FILE): ++ echo $(BOARD_KERNEL_VERSION) > $@ + + $(call declare-license-metadata,$(BUILT_KERNEL_CONFIGS_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel) + $(call declare-license-metadata,$(BUILT_KERNEL_VERSION_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel) + + my_board_extracted_kernel := true +-endif # BOARD_KERNEL_CONFIG_FILE + endif # BOARD_KERNEL_VERSION ++endif # BOARD_KERNEL_CONFIG_FILE + ++ifneq ($(my_board_extracted_kernel),true) ++# Tools for decompression that is not in PATH. ++# Check $(EXTRACT_KERNEL) for decompression algorithms supported by the script. ++# Algorithms that are in the script but not in this list will be found in PATH. ++my_decompress_tools := \ ++ lz4:$(HOST_OUT_EXECUTABLES)/lz4 \ ++ ++endif # my_board_extracted_kernel + + ifneq ($(my_board_extracted_kernel),true) + ifdef INSTALLED_KERNEL_TARGET +-ifndef BOARD_KERNEL_VERSION + $(BUILT_KERNEL_CONFIGS_FILE): .KATI_IMPLICIT_OUTPUTS := $(BUILT_KERNEL_VERSION_FILE) +-endif + $(BUILT_KERNEL_CONFIGS_FILE): PRIVATE_DECOMPRESS_TOOLS := $(my_decompress_tools) + $(BUILT_KERNEL_CONFIGS_FILE): $(foreach pair,$(my_decompress_tools),$(call word-colon,2,$(pair))) + $(BUILT_KERNEL_CONFIGS_FILE): $(EXTRACT_KERNEL) $(firstword $(INSTALLED_KERNEL_TARGET)) + $< --tools $(PRIVATE_DECOMPRESS_TOOLS) --input $(firstword $(INSTALLED_KERNEL_TARGET)) \ + --output-configs $@ \ +- $(if $(BOARD_KERNEL_VERSION),,--output-release $(BUILT_KERNEL_VERSION_FILE)) ++ --output-release $(BUILT_KERNEL_VERSION_FILE) + + $(call declare-license-metadata,$(BUILT_KERNEL_CONFIGS_FILE),SPDX-license-identifier-GPL-2.0-only,restricted,$(BUILD_SYSTEM)/LINUX_KERNEL_COPYING,"Kernel",kernel) + +-- +2.45.2 + diff --git a/aosp_diff/preliminary/build/make/0007-WA-Revert-Fix-python3.11-s-support-for-zip64.patch b/aosp_diff/preliminary/build/make/0007-WA-Revert-Fix-python3.11-s-support-for-zip64.patch deleted file mode 100644 index 7c282e806a..0000000000 --- a/aosp_diff/preliminary/build/make/0007-WA-Revert-Fix-python3.11-s-support-for-zip64.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 8c665cc2fd45b6a82f0d8e4867bd10fcd0947c60 Mon Sep 17 00:00:00 2001 -From: celadon -Date: Fri, 1 Sep 2023 08:57:06 +0000 -Subject: [PATCH] WA - Revert "Fix python3.11's support for zip64" - -This reverts commit 9021cb5ae1440d20686d1b8929fcb0959f56d7fc. ---- - tools/releasetools/common.py | 19 ++++--------------- - 1 file changed, 4 insertions(+), 15 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index 1c8914565f..018efba531 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -2113,28 +2113,17 @@ def UnzipToDir(filename, dirname, patterns=None): - """ - with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip: - # Filter out non-matching patterns. unzip will complain otherwise. -- entries = input_zip.infolist() -- # b/283033491 -- # Per https://en.wikipedia.org/wiki/ZIP_(file_format)#Central_directory_file_header -- # In zip64 mode, central directory record's header_offset field might be -- # set to 0xFFFFFFFF if header offset is > 2^32. In this case, the extra -- # fields will contain an 8 byte little endian integer at offset 20 -- # to indicate the actual local header offset. -- # As of python3.11, python does not handle zip64 central directories -- # correctly, so we will manually do the parsing here. -- for entry in entries: -- if entry.header_offset == 0xFFFFFFFF and len(entry.extra) >= 28: -- entry.header_offset = int.from_bytes(entry.extra[20:28], "little") - if patterns is not None: -- filtered = [info for info in entries if any( -- [fnmatch.fnmatch(info.filename, p) for p in patterns])] -+ names = input_zip.namelist() -+ filtered = [name for name in names if any( -+ [fnmatch.fnmatch(name, p) for p in patterns])] - - # There isn't any matching files. Don't unzip anything. - if not filtered: - return - input_zip.extractall(dirname, filtered) - else: -- input_zip.extractall(dirname, entries) -+ input_zip.extractall(dirname) - - - def UnzipTemp(filename, patterns=None): --- -2.39.2 - diff --git a/aosp_diff/preliminary/build/make/0008-WA-Revert-Use-python-based-unzip-function-for-portabili.patch b/aosp_diff/preliminary/build/make/0008-WA-Revert-Use-python-based-unzip-function-for-portabili.patch deleted file mode 100644 index a8c65d08bc..0000000000 --- a/aosp_diff/preliminary/build/make/0008-WA-Revert-Use-python-based-unzip-function-for-portabili.patch +++ /dev/null @@ -1,48 +0,0 @@ -From fce0e68b4ab3606be782f5f70d462075e0be7a2a Mon Sep 17 00:00:00 2001 -From: celadon -Date: Fri, 1 Sep 2023 08:57:37 +0000 -Subject: [PATCH] WA - Revert "Use python based unzip function for portability" - -This reverts commit 512a1f5f2d13f4b28db3f2f7d89151f31345db95. ---- - tools/releasetools/common.py | 21 +++++++++++---------- - 1 file changed, 11 insertions(+), 10 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index 018efba531..6db1d14782 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -2111,19 +2111,20 @@ def UnzipToDir(filename, dirname, patterns=None): - archvie. Non-matching patterns will be filtered out. If there's no match - after the filtering, no file will be unzipped. - """ -- with zipfile.ZipFile(filename, allowZip64=True, mode="r") as input_zip: -+ cmd = ["unzip", "-o", "-q", filename, "-d", dirname] -+ if patterns is not None: - # Filter out non-matching patterns. unzip will complain otherwise. -- if patterns is not None: -+ with zipfile.ZipFile(filename, allowZip64=True) as input_zip: - names = input_zip.namelist() -- filtered = [name for name in names if any( -- [fnmatch.fnmatch(name, p) for p in patterns])] -+ filtered = [ -+ pattern for pattern in patterns if fnmatch.filter(names, pattern)] - -- # There isn't any matching files. Don't unzip anything. -- if not filtered: -- return -- input_zip.extractall(dirname, filtered) -- else: -- input_zip.extractall(dirname) -+ # There isn't any matching files. Don't unzip anything. -+ if not filtered: -+ return -+ cmd.extend(filtered) -+ -+ RunAndCheckOutput(cmd) - - - def UnzipTemp(filename, patterns=None): --- -2.39.2 - diff --git a/aosp_diff/preliminary/build/make/0009-Update-security_patch_level-string.patch b/aosp_diff/preliminary/build/make/0009-Update-security_patch_level-string.patch deleted file mode 100644 index 66951b9022..0000000000 --- a/aosp_diff/preliminary/build/make/0009-Update-security_patch_level-string.patch +++ /dev/null @@ -1,30 +0,0 @@ -From ae4f3aec1e1b29afad9e596684abd0fbccc71f11 Mon Sep 17 00:00:00 2001 -From: "Alam, SahibeX" -Date: Wed, 21 Feb 2024 17:36:52 +0530 -Subject: [PATCH] Update security_patch_level string - -Security_patch_level needs to be updated -When ASB Security patches are integrated. - -Tracked-On: OAM-115659 -Signed-off-by: Alam, SahibeX ---- - core/version_defaults.mk | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/core/version_defaults.mk b/core/version_defaults.mk -index dba897a9c3..a2dae42533 100644 ---- a/core/version_defaults.mk -+++ b/core/version_defaults.mk -@@ -104,7 +104,7 @@ ifndef PLATFORM_SECURITY_PATCH - # It must be of the form "YYYY-MM-DD" on production devices. - # It must match one of the Android Security Patch Level strings of the Public Security Bulletins. - # If there is no $PLATFORM_SECURITY_PATCH set, keep it empty. -- PLATFORM_SECURITY_PATCH := 2024-02-05 -+ PLATFORM_SECURITY_PATCH := 2024-08-01 - endif - - include $(BUILD_SYSTEM)/version_util.mk --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/soong/0001-Add-support-for-overide_lib_name-for-IA-perf-variant.patch b/aosp_diff/preliminary/build/soong/0001-Add-support-for-overide_lib_name-for-IA-perf-variant.patch new file mode 100644 index 0000000000..45f42e0a8e --- /dev/null +++ b/aosp_diff/preliminary/build/soong/0001-Add-support-for-overide_lib_name-for-IA-perf-variant.patch @@ -0,0 +1,79 @@ +From 0e4c60a532ab3d4761cac733a2dfd8885274d2ea Mon Sep 17 00:00:00 2001 +From: bodapati +Date: Mon, 10 Jun 2024 13:46:24 +0530 +Subject: [PATCH] Add support for overide_lib_name for IA perf variants of a + library + +Signed-off-by: bodapati +--- + android/module.go | 5 +++++ + cc/cc.go | 5 +++++ + cc/library.go | 6 ++++++ + 3 files changed, 16 insertions(+) + +diff --git a/android/module.go b/android/module.go +index dc585d295..7306af0a9 100644 +--- a/android/module.go ++++ b/android/module.go +@@ -277,6 +277,7 @@ func (c *soongConfigTrace) hash() string { + type nameProperties struct { + // The name of the module. Must be unique across all modules. + Name *string ++ Override_lib_name *string + } + + type commonProperties struct { +@@ -1205,6 +1206,10 @@ func (m *ModuleBase) BaseModuleName() string { + return String(m.nameProperties.Name) + } + ++func (m *ModuleBase) OverrideLibraryName() string { ++ return String(m.nameProperties.Override_lib_name) ++} ++ + func (m *ModuleBase) base() *ModuleBase { + return m + } +diff --git a/cc/cc.go b/cc/cc.go +index df0aa6d68..f8aaf2c4b 100644 +--- a/cc/cc.go ++++ b/cc/cc.go +@@ -515,6 +515,7 @@ type ModuleContextIntf interface { + InVendorOrProduct() bool + selectedStl() string + baseModuleName() string ++ overrideLibraryName() string + isAfdoCompile(ctx ModuleContext) bool + isOrderfileCompile() bool + isCfi() bool +@@ -1678,6 +1679,10 @@ func (ctx *moduleContextImpl) baseModuleName() string { + return ctx.mod.BaseModuleName() + } + ++func (ctx *moduleContextImpl) overrideLibraryName() string { ++ return ctx.mod.ModuleBase.OverrideLibraryName() ++} ++ + func (ctx *moduleContextImpl) isForPlatform() bool { + apexInfo, _ := android.ModuleProvider(ctx.ctx, android.ApexInfoProvider) + return apexInfo.IsForPlatform() +diff --git a/cc/library.go b/cc/library.go +index e49f50cc0..79b951a8a 100644 +--- a/cc/library.go ++++ b/cc/library.go +@@ -749,6 +749,12 @@ func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendo + // getLibName returns the actual canonical name of the library (the name which + // should be passed to the linker via linker flags). + func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string { ++ ++ // If an overrideLibraryName exists => this is a proxy library ++ // We must use the overrideLibraryName ++ if ctx.overrideLibraryName() != "" { ++ library.libName = ctx.overrideLibraryName() ++ } + name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct()) + + if ctx.Host() && Bool(library.Properties.Unique_host_soname) { +-- +2.34.1 + diff --git a/aosp_diff/preliminary/build/soong/0001-REVERTME-Disable-kati-checks-and-compiler-warning.patch b/aosp_diff/preliminary/build/soong/0001-REVERTME-Disable-kati-checks-and-compiler-warning.patch deleted file mode 100644 index 5f183725be..0000000000 --- a/aosp_diff/preliminary/build/soong/0001-REVERTME-Disable-kati-checks-and-compiler-warning.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 32fb789e61f893290d88c2bdf052bec76e0e5aea Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Mon, 15 Mar 2021 11:51:06 +0530 -Subject: [PATCH] REVERTME-Disable-kati-checks-and-compiler-warning - - I735f0c2c6fab153e9991e27fb08677723764afe5 - Suppress compiler warnings - -Wno-tautological-bitwise-compare - -Werror=pragma-pack - -Werror=pragma-pack-suspicious-include - Disable below kati checks - --werror_overriding_commands - --werror_real_to_phony - --werror_phony_looks_real - --werror_writable - -Tracked-On: None -Signed-off-by: ahs -Change-Id: I88455004f124e290e66cf727cde11f019676cdf9 ---- - cc/config/global.go | 2 -- - ui/build/kati.go | 8 ++++---- - 2 files changed, 4 insertions(+), 6 deletions(-) - -diff --git a/cc/config/global.go b/cc/config/global.go -index 48a8b4805..733bde3eb 100644 ---- a/cc/config/global.go -+++ b/cc/config/global.go -@@ -51,8 +51,6 @@ var ( - "-fno-strict-aliasing", - - "-Werror=date-time", -- "-Werror=pragma-pack", -- "-Werror=pragma-pack-suspicious-include", - "-Werror=string-plus-int", - "-Werror=unreachable-code-loop-increment", - -diff --git a/ui/build/kati.go b/ui/build/kati.go -index fb62df549..9ab97b288 100644 ---- a/ui/build/kati.go -+++ b/ui/build/kati.go -@@ -111,14 +111,14 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF - // Fail when suffix rules are used. - "--werror_suffix_rules", - // Fail when a real target depends on a phony target. -- "--werror_real_to_phony", -+// "--werror_real_to_phony", - // Makes real_to_phony checks assume that any top-level or leaf - // dependencies that does *not* have a '/' in it is a phony target. - "--top_level_phony", - // Fail when a phony target contains slashes. -- "--werror_phony_looks_real", -+// "--werror_phony_looks_real", - // Fail when writing to a read-only directory. -- "--werror_writable", -+// "--werror_writable", - // Print Kati's internal statistics, such as the number of variables, - // implicit/explicit/suffix rules, and so on. - "--kati_stats", -@@ -204,7 +204,7 @@ func runKatiBuild(ctx Context, config Config) { - - if !config.BuildBrokenDupRules() { - // Fail when redefining / duplicating a target. -- args = append(args, "--werror_overriding_commands") -+// args = append(args, "--werror_overriding_commands") - } - - args = append(args, config.KatiArgs()...) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/soong/0002-WA-Build-soong-errors.patch b/aosp_diff/preliminary/build/soong/0002-WA-Build-soong-errors.patch new file mode 100644 index 0000000000..ab4218c579 --- /dev/null +++ b/aosp_diff/preliminary/build/soong/0002-WA-Build-soong-errors.patch @@ -0,0 +1,119 @@ +From 6407f5f295e729665a78c17a2523ec9c11a1c8b4 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Mon, 10 Jun 2024 13:29:25 +0530 +Subject: [PATCH] [WA] Build-soong errors. + +Signed-off-by: Ankit Agarwal +--- + cc/config/global.go | 4 ++-- + ui/build/build.go | 1 + + ui/build/kati.go | 10 +++++----- + ui/build/ninja.go | 2 +- + ui/build/soong.go | 8 ++++---- + 5 files changed, 13 insertions(+), 12 deletions(-) + +diff --git a/cc/config/global.go b/cc/config/global.go +index 290a27dfb..f18f38b55 100644 +--- a/cc/config/global.go ++++ b/cc/config/global.go +@@ -50,10 +50,10 @@ var ( + "-Werror=int-conversion", + // Detects unterminated alignment modification pragmas, which often lead + // to ABI mismatch between modules and hard-to-debug crashes. +- "-Werror=pragma-pack", ++ //"-Werror=pragma-pack", + // Same as above, but detects alignment pragmas around a header + // inclusion. +- "-Werror=pragma-pack-suspicious-include", ++ //"-Werror=pragma-pack-suspicious-include", + // Detects dividing an array size by itself, which is a common typo that + // leads to bugs. + "-Werror=sizeof-array-div", +diff --git a/ui/build/build.go b/ui/build/build.go +index 9a9eccd7d..5acbeed1a 100644 +--- a/ui/build/build.go ++++ b/ui/build/build.go +@@ -93,6 +93,7 @@ builddir = {{.OutDir}} + {{end -}} + pool highmem_pool + depth = {{.HighmemParallel}} ++build _kati_always_build_: phony + {{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}} + subninja {{.KatiPackageNinjaFile}} + {{end -}} +diff --git a/ui/build/kati.go b/ui/build/kati.go +index d599c99a7..91c5ad29f 100644 +--- a/ui/build/kati.go ++++ b/ui/build/kati.go +@@ -99,7 +99,7 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF + // using 'include'. + "--no_ninja_prelude", + // Support declaring phony outputs in AOSP Ninja. +- "--use_ninja_phony_output", ++ //"--use_ninja_phony_output", + // Regenerate the Ninja file if environment inputs have changed. e.g. + // CLI flags, .mk file timestamps, env vars, $(wildcard ..) and some + // $(shell ..) results. +@@ -123,14 +123,14 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF + // Fail when suffix rules are used. + "--werror_suffix_rules", + // Fail when a real target depends on a phony target. +- "--werror_real_to_phony", ++ //"--werror_real_to_phony", + // Makes real_to_phony checks assume that any top-level or leaf + // dependencies that does *not* have a '/' in it is a phony target. + "--top_level_phony", + // Fail when a phony target contains slashes. +- "--werror_phony_looks_real", ++ //"--werror_phony_looks_real", + // Fail when writing to a read-only directory. +- "--werror_writable", ++ //"--werror_writable", + // Print Kati's internal statistics, such as the number of variables, + // implicit/explicit/suffix rules, and so on. + "--kati_stats", +@@ -230,7 +230,7 @@ func runKatiBuild(ctx Context, config Config) { + + if !config.BuildBrokenDupRules() { + // Fail when redefining / duplicating a target. +- args = append(args, "--werror_overriding_commands") ++ //args = append(args, "--werror_overriding_commands") + } + + args = append(args, config.KatiArgs()...) +diff --git a/ui/build/ninja.go b/ui/build/ninja.go +index 551b8ab41..b4d579314 100644 +--- a/ui/build/ninja.go ++++ b/ui/build/ninja.go +@@ -73,7 +73,7 @@ func runNinjaForBuild(ctx Context, config Config) { + args = append(args, "-f", config.CombinedNinjaFile()) + + args = append(args, +- "-o", "usesphonyoutputs=yes", ++ // "-o", "usesphonyoutputs=yes", + "-w", "dupbuild=err", + "-w", "missingdepfile=err") + +diff --git a/ui/build/soong.go b/ui/build/soong.go +index 9955b1fdc..a5539f8b6 100644 +--- a/ui/build/soong.go ++++ b/ui/build/soong.go +@@ -632,11 +632,11 @@ func runSoong(ctx Context, config Config) { + ninjaArgs := []string{ + "-d", "keepdepfile", + "-d", "stats", +- "-o", "usesphonyoutputs=yes", +- "-o", "preremoveoutputs=yes", ++ //"-o", "usesphonyoutputs=yes", ++ //"-o", "preremoveoutputs=yes", + "-w", "dupbuild=err", +- "-w", "outputdir=err", +- "-w", "missingoutfile=err", ++ //"-w", "outputdir=err", ++ //"-w", "missingoutfile=err", + "-j", strconv.Itoa(config.Parallel()), + "--frontend_file", fifo, + "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"), +-- +2.34.1 + diff --git a/aosp_diff/preliminary/build/soong/0003-REVERTME-Revert-patch-for-allowing-PHONY-target.patch b/aosp_diff/preliminary/build/soong/0003-REVERTME-Revert-patch-for-allowing-PHONY-target.patch deleted file mode 100644 index 283e0c50fb..0000000000 --- a/aosp_diff/preliminary/build/soong/0003-REVERTME-Revert-patch-for-allowing-PHONY-target.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 17ce45639ac428228be390da0b065b6009f2b73e Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Wed, 11 Aug 2021 21:45:15 +0530 -Subject: [PATCH] [REVERTME] Revert patch for allowing PHONY target - - commit 6587beddfa79ee06db08625a3673f6b97d7a68bd - Author: Dan Willemsen - Date: Sat Apr 18 20:25:59 2020 -0700 - -Turn on ninja phony outputs - -This replaces the _kati_always_build_ hack with a ninja feature so that -ninja can actually understand what's happening. This means that we can -turn on some more options and checks around expected output filenames: - -* Remove the output file(s) before the command executes -* Error if the output file(s) don't exist after the execution -* Error if the output is a directory - -They're turned on immediately during the soong bootstrap runs, as those -run a limited number of rules. The main ninja execution does not remove -the output files, and prints warnings instead of errors for the others. -I'll turn them on as we understand how often those warnings are seen. - -Test: m (check for new warnings) -Test: treehugger (check for new warnings) - Change-Id: I7f5c1a361dd1498eb54a2c07a918f3b0aa086e4c - -Signed-off-by: Tanuj Tekriwal -Change-Id: I48bdf330cfc57e410c0ed0302e0d689fd0b642b2 ---- - ui/build/build.go | 1 + - ui/build/kati.go | 2 +- - ui/build/ninja.go | 2 +- - ui/build/soong.go | 8 ++++---- - 4 files changed, 7 insertions(+), 6 deletions(-) - -diff --git a/ui/build/build.go b/ui/build/build.go -index 8f050d9be..b49f43743 100644 ---- a/ui/build/build.go -+++ b/ui/build/build.go -@@ -60,6 +60,7 @@ builddir = {{.OutDir}} - {{end -}} - pool highmem_pool - depth = {{.HighmemParallel}} -+build _kati_always_build_: phony - {{if and (not .SkipKatiNinja) .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}} - subninja {{.KatiPackageNinjaFile}} - {{end -}} -diff --git a/ui/build/kati.go b/ui/build/kati.go -index fa5f2c5af..9ab97b288 100644 ---- a/ui/build/kati.go -+++ b/ui/build/kati.go -@@ -85,7 +85,7 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF - // using 'include'. - "--no_ninja_prelude", - // Support declaring phony outputs in AOSP Ninja. -- "--use_ninja_phony_output", -+// "--use_ninja_phony_output", - // Support declaring symlink outputs in AOSP Ninja. - "--use_ninja_symlink_outputs", - // Regenerate the Ninja file if environment inputs have changed. e.g. -diff --git a/ui/build/ninja.go b/ui/build/ninja.go -index 5961c4525..e3b59481e 100644 ---- a/ui/build/ninja.go -+++ b/ui/build/ninja.go -@@ -65,7 +65,7 @@ func runNinjaForBuild(ctx Context, config Config) { - args = append(args, "-f", config.CombinedNinjaFile()) - - args = append(args, -- "-o", "usesphonyoutputs=yes", -+// "-o", "usesphonyoutputs=yes", - "-w", "dupbuild=err", - "-w", "missingdepfile=err") - -diff --git a/ui/build/soong.go b/ui/build/soong.go -index 87818e386..51e359400 100644 ---- a/ui/build/soong.go -+++ b/ui/build/soong.go -@@ -272,11 +272,11 @@ func runSoong(ctx Context, config Config) { - config.PrebuiltBuildTool("ninja"), - "-d", "keepdepfile", - "-d", "stats", -- "-o", "usesphonyoutputs=yes", -- "-o", "preremoveoutputs=yes", -+// "-o", "usesphonyoutputs=yes", -+// "-o", "preremoveoutputs=yes", - "-w", "dupbuild=err", -- "-w", "outputdir=err", -- "-w", "missingoutfile=err", -+// "-w", "outputdir=err", -+// "-w", "missingoutfile=err", - "-j", strconv.Itoa(config.Parallel()), - "--frontend_file", fifo, - "-f", filepath.Join(config.SoongOutDir(), file)) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/soong/0007-Add-support-for-overide_lib_name-for-IA-perf-variant.patch b/aosp_diff/preliminary/build/soong/0007-Add-support-for-overide_lib_name-for-IA-perf-variant.patch deleted file mode 100644 index 3aa25bc758..0000000000 --- a/aosp_diff/preliminary/build/soong/0007-Add-support-for-overide_lib_name-for-IA-perf-variant.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 5928b8b0c0bd38c669f2c0abfa21354bea31be72 Mon Sep 17 00:00:00 2001 -From: bodapati -Date: Mon, 26 Apr 2021 14:24:42 +0530 -Subject: [PATCH] Add support for overide_lib_name for IA perf variants of a - library - -Signed-off-by: bodapati ---- - android/module.go | 5 +++++ - cc/cc.go | 5 +++++ - cc/library.go | 5 +++++ - cc/vndk.go | 4 +++- - 4 files changed, 18 insertions(+), 1 deletion(-) - -diff --git a/android/module.go b/android/module.go -index ba474530d..a434baf91 100644 ---- a/android/module.go -+++ b/android/module.go -@@ -713,6 +713,7 @@ func SortedUniqueNamedPaths(l NamedPaths) NamedPaths { - type nameProperties struct { - // The name of the module. Must be unique across all modules. - Name *string -+ Override_lib_name *string - } - - type commonProperties struct { -@@ -1766,6 +1767,10 @@ func (m *ModuleBase) BaseModuleName() string { - return String(m.nameProperties.Name) - } - -+func (m *ModuleBase) OverrideLibraryName() string { -+ return String(m.nameProperties.Override_lib_name) -+} -+ - func (m *ModuleBase) base() *ModuleBase { - return m - } -diff --git a/cc/cc.go b/cc/cc.go -index 0addb60b4..73e3e2fd4 100644 ---- a/cc/cc.go -+++ b/cc/cc.go -@@ -513,6 +513,7 @@ type ModuleContextIntf interface { - inRecovery() bool - selectedStl() string - baseModuleName() string -+ overrideLibraryName() string - getVndkExtendsModuleName() string - isAfdoCompile() bool - isPgoCompile() bool -@@ -1687,6 +1688,10 @@ func (ctx *moduleContextImpl) baseModuleName() string { - return ctx.mod.ModuleBase.BaseModuleName() - } - -+func (ctx *moduleContextImpl) overrideLibraryName() string { -+ return ctx.mod.ModuleBase.OverrideLibraryName() -+} -+ - func (ctx *moduleContextImpl) getVndkExtendsModuleName() string { - return ctx.mod.getVndkExtendsModuleName() - } -diff --git a/cc/library.go b/cc/library.go -index 7051f723c..9981179f8 100644 ---- a/cc/library.go -+++ b/cc/library.go -@@ -1431,6 +1431,11 @@ func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendo - // getLibName returns the actual canonical name of the library (the name which - // should be passed to the linker via linker flags). - func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string { -+ // If an overrideLibraryName exists => this is a proxy library -+ // We must use the overrideLibraryName -+ if ctx.overrideLibraryName() != "" { -+ library.libName = ctx.overrideLibraryName() -+ } - name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct()) - - if ctx.IsVndkExt() { -diff --git a/cc/vndk.go b/cc/vndk.go -index 9b70004c5..a0c8931c1 100644 ---- a/cc/vndk.go -+++ b/cc/vndk.go -@@ -706,7 +706,9 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex - } - - libPath := m.outputFile.Path() -- snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base()) -+ qualifiedLibName := m.RelativeInstallPath() -+ qualifiedLibName = filepath.Join(qualifiedLibName, libPath.Base()) -+ snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, qualifiedLibName) - ret = append(ret, snapshot.CopyFileRule(pctx, ctx, libPath, snapshotLibOut)) - - // json struct to export snapshot information --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/soong/0009-Filterout-isa-perf-libraries-from-vndk-list.patch b/aosp_diff/preliminary/build/soong/0009-Filterout-isa-perf-libraries-from-vndk-list.patch deleted file mode 100644 index ad3aeb83c2..0000000000 --- a/aosp_diff/preliminary/build/soong/0009-Filterout-isa-perf-libraries-from-vndk-list.patch +++ /dev/null @@ -1,49 +0,0 @@ -From cd3b13e0103045310ace4b02d9c4f88e6e14d71c Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 10 Nov 2023 14:49:06 +0530 -Subject: [PATCH] Filterout isa perf libraries from vndk list - -Currently we have added perf libs under vndksp, -filter them out as they are not new libraries, -rather avx2 implementations of existing libraries. -Should have no impact on GSI. - -Signed-off-by: bodapati ---- - cc/vndk.go | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/cc/vndk.go b/cc/vndk.go -index bb96548e2..3e32e8691 100644 ---- a/cc/vndk.go -+++ b/cc/vndk.go -@@ -871,6 +871,15 @@ func getVndkFileName(m *Module) (string, error) { - return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker) - } - -+func filterOutAvxLibs(libList []string) (filtered []string) { -+ for _, lib := range libList { -+ if !strings.Contains(lib, "_avx2.") { -+ filtered = append(filtered, lib) -+ } -+ } -+ return -+ } -+ - func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) { - // Build list of vndk libs as merged & tagged & filter-out(libclang_rt): - // Since each target have different set of libclang_rt.* files, -@@ -882,7 +891,9 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton - _, vndkproduct := vndkModuleListRemover(vndkProductLibraries, "libclang_rt.")(ctx) - var merged []string - merged = append(merged, addPrefix(llndk, "LLNDK: ")...) -- merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...) -+ // Currently we have added perf libs under vndksp, filter them out as they are not new libraries, -+ // rather avx implementations of existing libraries. Should have no impact on GSI -+ merged = append(merged, addPrefix(filterOutAvxLibs(vndksp), "VNDK-SP: ")...) - merged = append(merged, addPrefix(vndkcore, "VNDK-core: ")...) - merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...) - merged = append(merged, addPrefix(vndkproduct, "VNDK-product: ")...) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/tools/01_0001-Remove-usage-of-F-string.patch b/aosp_diff/preliminary/build/tools/01_0001-Remove-usage-of-F-string.patch deleted file mode 100644 index cdd1d3a891..0000000000 --- a/aosp_diff/preliminary/build/tools/01_0001-Remove-usage-of-F-string.patch +++ /dev/null @@ -1,46 +0,0 @@ -From af9a3443822537aa259f85f09563291b394562b3 Mon Sep 17 00:00:00 2001 -From: svenate -Date: Wed, 30 Mar 2022 07:13:54 +0530 -Subject: [PATCH] Remove usage of F-string - -The usage of F-string is supported only from python 3.6 and -was giving build error: -"SyntaxError: invalid syntax" - -Change-Id: I3b5e9dcc4dbf12dfd1459eb7d312517058f6e228 -Signed-off-by: svenate ---- - tools/releasetools/common.py | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index 696215e475..30a324c671 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -1661,8 +1661,7 @@ def _BuildBootableImage(image_name, sourcedir, fs_config_file, info_dict=None, - - BOOT_SIGNATURE_SIZE = 16 * 1024 - if len(boot_signature_bytes) > BOOT_SIGNATURE_SIZE: -- raise ValueError( -- f"GKI boot_signature size must be <= {BOOT_SIGNATURE_SIZE}") -+ raise ValueError('GKI boot_signature size must be <= {}'.format(BOOT_SIGNATURE_SIZE)) - boot_signature_bytes += ( - b'\0' * (BOOT_SIGNATURE_SIZE - len(boot_signature_bytes))) - assert len(boot_signature_bytes) == BOOT_SIGNATURE_SIZE -@@ -1931,11 +1930,11 @@ def _BuildVendorBootImage(sourcedir, partition_name, info_dict=None): - # AVB: if enabled, calculate and add hash. - if info_dict.get("avb_enable") == "true": - avbtool = info_dict["avb_avbtool"] -- part_size = info_dict[f'{partition_name}_size'] -+ part_size = info_dict['{}_size'.format(partition_name)] - cmd = [avbtool, "add_hash_footer", "--image", img.name, - "--partition_size", str(part_size), "--partition_name", partition_name] - AppendAVBSigningArgs(cmd, partition_name) -- args = info_dict.get(f'avb_{partition_name}_add_hash_footer_args') -+ args = info_dict.get('avb_{}_add_hash_footer_args'.format(partition_name)) - if args and args.strip(): - cmd.extend(shlex.split(args)) - RunAndCheckOutput(cmd) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/tools/03_0003-WA-Fixed-Build-Error-Releasetools.patch b/aosp_diff/preliminary/build/tools/03_0003-WA-Fixed-Build-Error-Releasetools.patch deleted file mode 100644 index 252f2e7755..0000000000 --- a/aosp_diff/preliminary/build/tools/03_0003-WA-Fixed-Build-Error-Releasetools.patch +++ /dev/null @@ -1,57 +0,0 @@ -From f8c841e3fd2f8d7f1c5de4ad1a003e9725d37499 Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Thu, 18 May 2023 16:19:38 +0530 -Subject: [PATCH] WA-Fixed Build Error Releasetools. - -Build error-: -File "build/tools/releasetools/common.py", line 4104 - def ParseUpdateEngineConfig(path: str): - ^ -SyntaxError: invalid syntax - -File "build/tools/releasetools/common.py", line 4123 - f"{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}") - ^ -SyntaxError: invalid syntax - -File "build/tools/releasetools/common.py", line 4124 - f"{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}") - ^ -SyntaxError: invalid syntax - -Seems due to python version. Above seems not supported in python2. - -Tracked-On: OAM-106853 -Signed-off-by: Ankit Agrawal ---- - tools/releasetools/common.py | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py -index 68eb36f678..6db1d14782 100644 ---- a/tools/releasetools/common.py -+++ b/tools/releasetools/common.py -@@ -4101,7 +4101,7 @@ def IsSparseImage(filepath): - return fp.read(4) == b'\x3A\xFF\x26\xED' - - --def ParseUpdateEngineConfig(path: str): -+def ParseUpdateEngineConfig(path): - """Parse the update_engine config stored in file `path` - Args - path: Path to update_engine_config.txt file in target_files -@@ -4117,9 +4117,9 @@ def ParseUpdateEngineConfig(path: str): - major = re.search(r"PAYLOAD_MAJOR_VERSION=(\d+)", data) - if not major: - raise ValueError( -- f"{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}") -+ "{path} is an invalid update_engine config, missing PAYLOAD_MAJOR_VERSION {data}" + path) - minor = re.search(r"PAYLOAD_MINOR_VERSION=(\d+)", data) - if not minor: - raise ValueError( -- f"{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}") -+ "{path} is an invalid update_engine config, missing PAYLOAD_MINOR_VERSION {data}" + path) - return (int(major.group(1)), int(minor.group(1))) --- -2.17.1 - diff --git a/aosp_diff/preliminary/build/tools/04_0004-Add-allowZip64-True-for-ZipFile-in-RebuildAndWriteSu.patch b/aosp_diff/preliminary/build/tools/04_0004-Add-allowZip64-True-for-ZipFile-in-RebuildAndWriteSu.patch deleted file mode 100644 index a9f1f110b9..0000000000 --- a/aosp_diff/preliminary/build/tools/04_0004-Add-allowZip64-True-for-ZipFile-in-RebuildAndWriteSu.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 49ed1fc4979e49f7a3c2c1c332f5c6d455403d1a Mon Sep 17 00:00:00 2001 -From: jizhenlo -Date: Mon, 29 May 2023 16:50:52 +0800 -Subject: [PATCH] Add allowZip64=True for ZipFile in RebuildAndWriteSuperImages - -Zip failure will be seen if the size of super image is larger than -4G. So, fix the issue by setting allowZip64 to true. - -Tracked-On: OAM-110514 -Signed-off-by: jizhenlo ---- - tools/releasetools/img_from_target_files.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/tools/releasetools/img_from_target_files.py b/tools/releasetools/img_from_target_files.py -index 76da89c865..f8bdd81ce6 100755 ---- a/tools/releasetools/img_from_target_files.py -+++ b/tools/releasetools/img_from_target_files.py -@@ -173,7 +173,7 @@ def RebuildAndWriteSuperImages(input_file, output_file): - logger.info('Writing super.img to archive...') - with zipfile.ZipFile( - output_file, 'a', compression=zipfile.ZIP_DEFLATED, -- allowZip64=not OPTIONS.sparse_userimages) as output_zip: -+ allowZip64=True) as output_zip: - common.ZipWrite(output_zip, super_file, 'super.img') - - --- -2.25.1 - diff --git a/aosp_diff/preliminary/external/angle/0001-Build-external-angle-by-python3.patch b/aosp_diff/preliminary/external/angle/0001-Build-external-angle-by-python3.patch deleted file mode 100644 index 2a479709c5..0000000000 --- a/aosp_diff/preliminary/external/angle/0001-Build-external-angle-by-python3.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 7f10d411b99d68c7a954030d67f3693e964b51fe Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Tue, 12 Dec 2023 10:38:32 +0000 -Subject: [PATCH] Build external angle by python3 - -This patch will enable to build generate_registry_tables.py -file to use python3 instead of python2 -This patch needs to be reverted when we make python3 -as default. - -Tests-Done: Build and boot the device. - -Tracked-On: OAM-114192 -Signed-off-by: Tanuj Tekriwal ---- - .../spirv-tools/src/utils/generate_registry_tables.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/third_party/vulkan-deps/spirv-tools/src/utils/generate_registry_tables.py b/third_party/vulkan-deps/spirv-tools/src/utils/generate_registry_tables.py -index 14d4909fa6..69628faada 100755 ---- a/third_party/vulkan-deps/spirv-tools/src/utils/generate_registry_tables.py -+++ b/third_party/vulkan-deps/spirv-tools/src/utils/generate_registry_tables.py -@@ -1,4 +1,4 @@ --#!/usr/bin/env python -+#!/usr/bin/env python3 - # Copyright (c) 2016 Google Inc. - - # Licensed under the Apache License, Version 2.0 (the "License"); --- -2.39.2 - diff --git a/aosp_diff/preliminary/external/boringssl/0001-WA-Fixed-build-error-in-boringssl.patch b/aosp_diff/preliminary/external/boringssl/0001-WA-Fixed-build-error-in-boringssl.patch new file mode 100644 index 0000000000..8a85f514e2 --- /dev/null +++ b/aosp_diff/preliminary/external/boringssl/0001-WA-Fixed-build-error-in-boringssl.patch @@ -0,0 +1,120 @@ +From fe81e81d16525b819fae52a6fab3c4ae40b768dd Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Fri, 14 Jun 2024 09:24:49 +0530 +Subject: [PATCH] [WA] Fixed build error in boringssl. + +Observed build error due to undefined dsa flags. +Adding dummy getentropy function for now. + +Tests: Prepared EB, there is no error. + +Tracked-On: NA +Signed-off-by: Ankit Agarwal +--- + src/crypto/internal.h | 24 ++++++++++++++++-------- + src/crypto/rand_extra/getentropy.c | 8 ++++++++ + 2 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/src/crypto/internal.h b/src/crypto/internal.h +index a77102d7..b7d9fddc 100644 +--- a/src/crypto/internal.h ++++ b/src/crypto/internal.h +@@ -312,6 +312,7 @@ static inline int buffers_alias(const void *a, size_t a_bytes, + // power of two, and |ptr| must have at least |alignment - 1| bytes of scratch + // space. + static inline void *align_pointer(void *ptr, size_t alignment) { ++ uintptr_t offset; + // |alignment| must be a power of two. + assert(alignment != 0 && (alignment & (alignment - 1)) == 0); + // Instead of aligning |ptr| as a |uintptr_t| and casting back, compute the +@@ -319,7 +320,7 @@ static inline void *align_pointer(void *ptr, size_t alignment) { + // to |uintptr_t| and back gives the same pointer, but general + // integer-to-pointer conversions are implementation-defined. GCC does define + // it in the useful way, but this makes fewer assumptions. +- uintptr_t offset = (0u - (uintptr_t)ptr) & (alignment - 1); ++ offset = (0u - (uintptr_t)ptr) & (alignment - 1); + ptr = (char *)ptr + offset; + assert(((uintptr_t)ptr & (alignment - 1)) == 0); + return ptr; +@@ -543,9 +544,11 @@ static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { + static inline void constant_time_conditional_memcpy(void *dst, const void *src, + const size_t n, + const crypto_word_t mask) { ++ uint8_t *out; ++ const uint8_t *in; + assert(!buffers_alias(dst, n, src, n)); +- uint8_t *out = (uint8_t *)dst; +- const uint8_t *in = (const uint8_t *)src; ++ out = (uint8_t *)dst; ++ in = (const uint8_t *)src; + for (size_t i = 0; i < n; i++) { + out[i] = constant_time_select_8(mask, in[i], out[i]); + } +@@ -557,9 +560,11 @@ static inline void constant_time_conditional_memcpy(void *dst, const void *src, + static inline void constant_time_conditional_memxor(void *dst, const void *src, + const size_t n, + const crypto_word_t mask) { ++ uint8_t *out; ++ const uint8_t *in; + assert(!buffers_alias(dst, n, src, n)); +- uint8_t *out = (uint8_t *)dst; +- const uint8_t *in = (const uint8_t *)src; ++ out = (uint8_t *)dst; ++ in = (const uint8_t *)src; + for (size_t i = 0; i < n; i++) { + out[i] ^= value_barrier_w(mask) & in[i]; + } +@@ -1124,10 +1129,10 @@ static inline crypto_word_t CRYPTO_load_word_be(const void *in) { + crypto_word_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + #if defined(OPENSSL_64_BIT) +- static_assert(sizeof(v) == 8, "crypto_word_t has unexpected size"); ++ assert(sizeof(v) == 8); + return CRYPTO_bswap8(v); + #else +- static_assert(sizeof(v) == 4, "crypto_word_t has unexpected size"); ++ assert(sizeof(v) == 4); + return CRYPTO_bswap4(v); + #endif + } +@@ -1327,7 +1332,9 @@ int boringssl_self_test_hmac_sha256(void); + #if defined(BORINGSSL_FIPS_COUNTERS) + void boringssl_fips_inc_counter(enum fips_counter_t counter); + #else +-OPENSSL_INLINE void boringssl_fips_inc_counter(enum fips_counter_t counter) {} ++OPENSSL_INLINE void boringssl_fips_inc_counter(enum fips_counter_t counter) { ++ int i = (counter < 0); ++} + #endif + + #if defined(BORINGSSL_FIPS_BREAK_TESTS) +@@ -1337,6 +1344,7 @@ OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { + } + #else + OPENSSL_INLINE int boringssl_fips_break_test(const char *test) { ++ int i = (strcmp("test", test) == 0); + return 0; + } + #endif // BORINGSSL_FIPS_BREAK_TESTS +diff --git a/src/crypto/rand_extra/getentropy.c b/src/crypto/rand_extra/getentropy.c +index 234b9b68..33298826 100644 +--- a/src/crypto/rand_extra/getentropy.c ++++ b/src/crypto/rand_extra/getentropy.c +@@ -30,6 +30,14 @@ + #include + #endif + ++int getentropy(void* buffer, size_t buffer_size) { ++ if (buffer_size > 256) { ++ return -1; ++ } ++ ++ return 0; ++} ++ + // CRYPTO_sysrand puts |requested| random bytes into |out|. + void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { +-- +2.34.1 + diff --git a/aosp_diff/preliminary/external/drm_hwcomposer/0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch b/aosp_diff/preliminary/external/drm_hwcomposer/0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch new file mode 100644 index 0000000000..7fe4b1f1c4 --- /dev/null +++ b/aosp_diff/preliminary/external/drm_hwcomposer/0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch @@ -0,0 +1,174 @@ +From c7a96df0642d37d8b7e7db6896102bd166932274 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Mon, 10 Jun 2024 13:57:49 +0530 +Subject: [PATCH] Use private drm_hwcomposer instead of external + drm_hwcomposer. + +Rename lib names to libxxx_orig, so that we use +vendor/intel/external/drm-hwcomposer instead of external +drm_hwcomposer. + +Signed-off-by: svenate +--- + Android.bp | 36 ++++++++++++++++++------------------ + tests/Android.bp | 20 ++++++++++---------- + 2 files changed, 28 insertions(+), 28 deletions(-) + +diff --git a/Android.bp b/Android.bp +index 62c7e0c..22ebe29 100644 +--- a/Android.bp ++++ b/Android.bp +@@ -30,7 +30,7 @@ license { + } + + cc_library_headers { +- name: "drm_hwcomposer_headers", ++ name: "drm_hwcomposer_headers_orig", + vendor: true, + export_include_dirs: ["."], + } +@@ -39,7 +39,7 @@ cc_library_headers { + // hwcomposer.drm.so + // ===================== + cc_defaults { +- name: "hwcomposer.drm_defaults", ++ name: "hwcomposer.drm_defaults_orig", + + shared_libs: [ + "libcutils", +@@ -52,7 +52,7 @@ cc_defaults { + "libutils", + ], + +- header_libs: ["drm_hwcomposer_headers"], ++ header_libs: ["drm_hwcomposer_headers_orig"], + + cflags: [ + "-Wall", +@@ -70,12 +70,12 @@ cc_defaults { + } + + filegroup { +- name: "drm_hwcomposer_fd", ++ name: "drm_hwcomposer_fd_orig", + srcs: ["utils/fd.cpp"], + } + + filegroup { +- name: "drm_hwcomposer_common", ++ name: "drm_hwcomposer_common_orig", + srcs: [ + "bufferinfo/BufferInfoGetter.cpp", + "bufferinfo/BufferInfoMapperMetadata.cpp", +@@ -113,50 +113,50 @@ filegroup { + + // Kept only for compatibility with older Android version. Please do not use! + cc_library_static { +- name: "drm_hwcomposer", +- defaults: ["hwcomposer.drm_defaults"], +- srcs: [":drm_hwcomposer_common"], ++ name: "drm_hwcomposer_orig", ++ defaults: ["hwcomposer.drm_defaults_orig"], ++ srcs: [":drm_hwcomposer_common_orig"], + } + + cc_library_shared { +- name: "hwcomposer.drm", +- defaults: ["hwcomposer.drm_defaults"], ++ name: "hwcomposer.drm_orig", ++ defaults: ["hwcomposer.drm_defaults_orig"], + srcs: [ +- ":drm_hwcomposer_common", ++ ":drm_hwcomposer_common_orig", + "bufferinfo/legacy/BufferInfoLibdrm.cpp", + ], + cflags: ["-DUSE_IMAPPER4_METADATA_API"], + } + + cc_library_shared { +- name: "hwcomposer.drm_minigbm", +- defaults: ["hwcomposer.drm_defaults"], ++ name: "hwcomposer.drm_minigbm_orig", ++ defaults: ["hwcomposer.drm_defaults_orig"], + srcs: [ +- ":drm_hwcomposer_common", ++ ":drm_hwcomposer_common_orig", + "bufferinfo/legacy/BufferInfoMinigbm.cpp", + ], + } + + // Used by hwcomposer.drm_imagination + filegroup { +- name: "drm_hwcomposer_platformimagination", ++ name: "drm_hwcomposer_platformimagination_orig", + srcs: ["bufferinfo/legacy/BufferInfoImagination.cpp"], + } + + // Used by hwcomposer.drm_hikey and hwcomposer.drm_hikey960 + filegroup { +- name: "drm_hwcomposer_platformhisi", ++ name: "drm_hwcomposer_platformhisi_orig", + srcs: ["bufferinfo/legacy/BufferInfoMaliHisi.cpp"], + } + + // Used by hwcomposer.drm_meson + filegroup { +- name: "drm_hwcomposer_platformmeson", ++ name: "drm_hwcomposer_platformmeson_orig", + srcs: ["bufferinfo/legacy/BufferInfoMaliMeson.cpp"], + } + + // Used by hwcomposer.drm_mediatek + filegroup { +- name: "drm_hwcomposer_platformmediatek", ++ name: "drm_hwcomposer_platformmediatek_orig", + srcs: ["bufferinfo/legacy/BufferInfoMaliMediatek.cpp"], + } +diff --git a/tests/Android.bp b/tests/Android.bp +index 43fd3fa..178838c 100644 +--- a/tests/Android.bp ++++ b/tests/Android.bp +@@ -1,13 +1,13 @@ + cc_library_shared { +- name: "hwcomposer.filegroups_build_test", +- defaults: ["hwcomposer.drm_defaults"], ++ name: "hwcomposer.filegroups_build_test_orig", ++ defaults: ["hwcomposer.drm_defaults_orig"], + + srcs: [ +- ":drm_hwcomposer_common", +- ":drm_hwcomposer_platformhisi", +- ":drm_hwcomposer_platformimagination", +- ":drm_hwcomposer_platformmediatek", +- ":drm_hwcomposer_platformmeson", ++ ":drm_hwcomposer_common_orig", ++ ":drm_hwcomposer_platformhisi_orig", ++ ":drm_hwcomposer_platformimagination_orig", ++ ":drm_hwcomposer_platformmediatek_orig", ++ ":drm_hwcomposer_platformmeson_orig", + ], + + local_include_dirs: [ +@@ -30,16 +30,16 @@ package { + + // Tool for listening and dumping uevents + cc_test { +- name: "hwc-drm-uevent-print", ++ name: "hwc-drm-uevent-print_orig", + + srcs: [ +- ":drm_hwcomposer_fd", ++ ":drm_hwcomposer_fd_orig", + "uevent_print.cpp", + ], + + vendor: true, + header_libs: [ +- "drm_hwcomposer_headers", ++ "drm_hwcomposer_headers_orig", + "libhardware_headers", + ], + shared_libs: ["liblog"], +-- +2.34.1 + diff --git a/aosp_diff/preliminary/external/drm_hwcomposer/01_0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch b/aosp_diff/preliminary/external/drm_hwcomposer/01_0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch deleted file mode 100644 index ccd8e0798c..0000000000 --- a/aosp_diff/preliminary/external/drm_hwcomposer/01_0001-Use-private-drm_hwcomposer-instead-of-external-drm_h.patch +++ /dev/null @@ -1,142 +0,0 @@ -From ffbfd6d5d19a53df45b1190ec3225223178efac1 Mon Sep 17 00:00:00 2001 -From: svenate -Date: Wed, 21 Sep 2022 15:40:38 +0530 -Subject: [PATCH] Use private drm_hwcomposer instead of external drm_hwcomposer - -Rename lib names to libxxx_orig, so that we use -vendor/intel/external/drm-hwcomposer instead of -external drm_hwcomposer. - -Change-Id: I3e2fa1a1cc883c6e3f53907666295db71abb6115 -Signed-off-by: svenate ---- - Android.bp | 22 +++++++++++----------- - tests/Android.bp | 6 +++--- - 2 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/Android.bp b/Android.bp -index c9c94af..5ccb2d0 100644 ---- a/Android.bp -+++ b/Android.bp -@@ -33,7 +33,7 @@ license { - } - - cc_library_static { -- name: "libdrmhwc_utils", -+ name: "libdrmhwc_utils_orig", - - srcs: ["utils/Worker.cpp"], - -@@ -55,7 +55,7 @@ cc_library_static { - // hwcomposer.drm.so - // ===================== - cc_defaults { -- name: "hwcomposer.drm_defaults", -+ name: "hwcomposer.drm_defaults_orig", - - shared_libs: [ - "libcutils", -@@ -73,7 +73,7 @@ cc_defaults { - "external/drm_hwcomposer/include", - ], - -- static_libs: ["libdrmhwc_utils"], -+ static_libs: ["libdrmhwc_utils_orig"], - - cflags: [ - "-Wall", -@@ -97,7 +97,7 @@ cc_defaults { - } - - filegroup { -- name: "drm_hwcomposer_common", -+ name: "drm_hwcomposer_common_orig", - srcs: [ - "bufferinfo/BufferInfoGetter.cpp", - "bufferinfo/BufferInfoMapperMetadata.cpp", -@@ -134,13 +134,13 @@ filegroup { - - // Kept only for compatibility with older Android version. Please do not use! - cc_library_static { -- name: "drm_hwcomposer", -+ name: "drm_hwcomposer_orig", - defaults: ["hwcomposer.drm_defaults"], - srcs: [":drm_hwcomposer_common"], - } - - cc_library_shared { -- name: "hwcomposer.drm", -+ name: "hwcomposer.drm_orig", - defaults: ["hwcomposer.drm_defaults"], - srcs: [ - ":drm_hwcomposer_common", -@@ -150,7 +150,7 @@ cc_library_shared { - } - - cc_library_shared { -- name: "hwcomposer.drm_minigbm", -+ name: "hwcomposer.drm_minigbm_orig", - defaults: ["hwcomposer.drm_defaults"], - srcs: [ - ":drm_hwcomposer_common", -@@ -160,24 +160,24 @@ cc_library_shared { - - // Used by hwcomposer.drm_imagination - filegroup { -- name: "drm_hwcomposer_platformimagination", -+ name: "drm_hwcomposer_platformimagination_orig", - srcs: ["bufferinfo/legacy/BufferInfoImagination.cpp"], - } - - // Used by hwcomposer.drm_hikey and hwcomposer.drm_hikey960 - filegroup { -- name: "drm_hwcomposer_platformhisi", -+ name: "drm_hwcomposer_platformhisi_orig", - srcs: ["bufferinfo/legacy/BufferInfoMaliHisi.cpp"], - } - - // Used by hwcomposer.drm_meson - filegroup { -- name: "drm_hwcomposer_platformmeson", -+ name: "drm_hwcomposer_platformmeson_orig", - srcs: ["bufferinfo/legacy/BufferInfoMaliMeson.cpp"], - } - - // Used by hwcomposer.drm_mediatek - filegroup { -- name: "drm_hwcomposer_platformmediatek", -+ name: "drm_hwcomposer_platformmediatek_orig", - srcs: ["bufferinfo/legacy/BufferInfoMaliMediatek.cpp"], - } -diff --git a/tests/Android.bp b/tests/Android.bp -index b25342e..5f4f119 100644 ---- a/tests/Android.bp -+++ b/tests/Android.bp -@@ -1,5 +1,5 @@ - cc_library_shared { -- name: "hwcomposer.filegroups_build_test", -+ name: "hwcomposer.filegroups_build_test_orig", - defaults: ["hwcomposer.drm_defaults"], - - srcs: [ -@@ -29,7 +29,7 @@ package { - } - - cc_test { -- name: "hwc-drm-tests", -+ name: "hwc-drm-tests_orig", - - srcs: ["worker_test.cpp"], - -@@ -45,7 +45,7 @@ cc_test { - - // Tool for listening and dumping uevents - cc_test { -- name: "hwc-drm-uevent-print", -+ name: "hwc-drm-uevent-print_orig", - - srcs: ["uevent_print.cpp"], - --- -2.33.0 - diff --git a/aosp_diff/preliminary/external/kmod/0001-Add-libkmod-shared-library-build-target.patch b/aosp_diff/preliminary/external/kmod/0001-Add-libkmod-shared-library-build-target.patch deleted file mode 100644 index c992e75952..0000000000 --- a/aosp_diff/preliminary/external/kmod/0001-Add-libkmod-shared-library-build-target.patch +++ /dev/null @@ -1,82 +0,0 @@ -From d15b6343f332e3d6bffc892c01f37119c7eb0624 Mon Sep 17 00:00:00 2001 -From: ahs -Date: Thu, 19 Mar 2020 16:20:01 +0530 -Subject: Add-libkmod-shared-library-build-target - -Change-Id: I8c9d5d7ac3ec69e49b9a32ff0f0f7a0bc0aad338 -Tracked-On: -Signed-off-by: ahs ---- - Android.bp | 43 ++++++++++++++++++++++++++++++++ - android/libkmod-android-compat.h | 8 ++++++ - 2 files changed, 51 insertions(+) - create mode 100644 android/libkmod-android-compat.h - -diff --git a/Android.bp b/Android.bp -index f6edaa0..63623bc 100644 ---- a/Android.bp -+++ b/Android.bp -@@ -65,3 +65,46 @@ cc_binary_host { - ], - static_libs: ["libkmod"], - } -+ -+// ======================================================== -+// libkmod shared library -+// ======================================================== -+cc_library_shared { -+ name: "libkmod-shared", -+ vendor: true, -+ srcs: [ -+ "libkmod/libkmod.c", -+ "libkmod/libkmod-file.c", -+ "libkmod/libkmod-module.c", -+ "libkmod/libkmod-config.c", -+ "libkmod/libkmod-index.c", -+ "libkmod/libkmod-elf.c", -+ "libkmod/libkmod-list.c", -+ "libkmod/libkmod-signature.c", -+ "shared/array.c", -+ "shared/scratchbuf.c", -+ "shared/util.c", -+ "shared/hash.c", -+ "shared/strbuf.c", -+ ], -+ -+ local_include_dirs: [ -+ "port-gnu", -+ "android", -+ ], -+ cflags: [ -+ "-include config.h", -+ "-include libkmod-android-compat.h", -+ "-ffunction-sections", -+ "-fdata-sections", -+ "-Wall", -+ "-Werror", -+ "-Wno-format", -+ "-Wno-unused-parameter", -+ "-Wno-unused-variable", -+ "-Dsecure_getenv=getenv", -+ "-DHAVE_CONFIG_H", -+ "-DANOTHER_BRICK_IN_THE", -+ "-DSYSCONFDIR=\"/etc\"", -+ ], -+} -diff --git a/android/libkmod-android-compat.h b/android/libkmod-android-compat.h -new file mode 100644 -index 0000000..78b73d4 ---- /dev/null -+++ b/android/libkmod-android-compat.h -@@ -0,0 +1,8 @@ -+#pragma once -+ -+#ifdef ANDROID -+ -+//#define strndupa(_s,_l) strdup(_s) -+//char *get_current_dir_name(void); -+ -+#endif /* ANDROID */ --- -2.24.0 - diff --git a/aosp_diff/preliminary/external/libdrm/0001-use-private-libdrm-instead-of-external-libdrm.patch b/aosp_diff/preliminary/external/libdrm/0001-use-private-libdrm-instead-of-external-libdrm.patch index feb08b6e8a..5e842fc5c9 100644 --- a/aosp_diff/preliminary/external/libdrm/0001-use-private-libdrm-instead-of-external-libdrm.patch +++ b/aosp_diff/preliminary/external/libdrm/0001-use-private-libdrm-instead-of-external-libdrm.patch @@ -1,4 +1,4 @@ -From bcd90f1169fa3a41134961e330c77f5aba8d7b7a Mon Sep 17 00:00:00 2001 +From 1c0440fc0c198d28285a373ca0fa2bbeb81fe4b8 Mon Sep 17 00:00:00 2001 From: yifang ma Date: Tue, 3 Dec 2019 15:51:42 +0800 Subject: [PATCH] use private libdrm instead of external libdrm @@ -42,10 +42,10 @@ Signed-off-by: Chenglei Ren 26 files changed, 87 insertions(+), 87 deletions(-) diff --git a/Android.bp b/Android.bp -index dbac5626..cbd98379 100644 +index 2f727d20..b956751f 100644 --- a/Android.bp +++ b/Android.bp -@@ -22,7 +22,7 @@ +@@ -22,11 +22,11 @@ // package { @@ -53,17 +53,13 @@ index dbac5626..cbd98379 100644 + default_applicable_licenses: ["external_libdrm_license_orig"], } - // Added automatically by a large-scale-change that took the approach of -@@ -40,7 +40,7 @@ package { - // used in the current project. - // See: http://go/android-license-faq license { - name: "external_libdrm_license", + name: "external_libdrm_license_orig", visibility: [":__subpackages__"], license_kinds: [ "SPDX-license-identifier-BSD", -@@ -54,7 +54,7 @@ subdirs = ["*"] +@@ -40,7 +40,7 @@ subdirs = ["*"] build = ["Android.sources.bp"] cc_defaults { @@ -72,7 +68,7 @@ index dbac5626..cbd98379 100644 cflags: [ // XXX: Consider moving these to config.h analogous to autoconf. "-DMAJOR_IN_SYSMACROS=1", -@@ -77,7 +77,7 @@ cc_defaults { +@@ -63,7 +63,7 @@ cc_defaults { } cc_library_headers { @@ -81,15 +77,18 @@ index dbac5626..cbd98379 100644 vendor_available: true, host_supported: true, defaults: ["libdrm_defaults"], -@@ -86,13 +86,13 @@ cc_library_headers { +@@ -79,7 +79,7 @@ cc_library_headers { // Library for the device cc_library { - name: "libdrm", + name: "libdrm_orig", recovery_available: true, - vendor_available: true, host_supported: true, + vendor_available: true, +@@ -89,8 +89,8 @@ cc_library { + "//apex_available:anyapex", + ], defaults: [ - "libdrm_defaults", - "libdrm_sources", @@ -97,7 +96,7 @@ index dbac5626..cbd98379 100644 + "libdrm_sources_orig", ], - export_include_dirs: ["include/drm", "android"], + export_include_dirs: [ diff --git a/Android.sources.bp b/Android.sources.bp index 73356dd8..1e4f8013 100644 --- a/Android.sources.bp @@ -644,5 +643,5 @@ index 529e1124..c9a6f1a0 100644 "format.c", "kms.c", -- -2.39.2 +2.34.1 diff --git a/aosp_diff/preliminary/external/minigbm/0001-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch b/aosp_diff/preliminary/external/minigbm/0001-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch new file mode 100644 index 0000000000..8fecbcf557 --- /dev/null +++ b/aosp_diff/preliminary/external/minigbm/0001-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch @@ -0,0 +1,40 @@ +From 3e8e2ac66383d592218c719959f90eae26016676 Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Mon, 10 Jun 2024 14:00:54 +0530 +Subject: [PATCH] Remove aidl, libminigbm_gralloc_* and gralloc.* Android.bp + +Removed Anrdroid.bp files to make sure aidl, libminigbm_gralloc_* and +gralloc.* are not compiled from AOSP tree. + +Tracked-On: OAM-110710 +Signed-off-by: Jeevaka Prabu Badrappan +--- + Android.bp => Android_bp | 0 + cros_gralloc/aidl/{Android.bp => Android_bp} | 0 + cros_gralloc/gralloc4/{Android.bp => Android_bp} | 0 + cros_gralloc/mapper_stablec/{Android.bp => Android_bp} | 0 + 4 files changed, 0 insertions(+), 0 deletions(-) + rename Android.bp => Android_bp (100%) + rename cros_gralloc/aidl/{Android.bp => Android_bp} (100%) + rename cros_gralloc/gralloc4/{Android.bp => Android_bp} (100%) + rename cros_gralloc/mapper_stablec/{Android.bp => Android_bp} (100%) + +diff --git a/Android.bp b/Android_bp +similarity index 100% +rename from Android.bp +rename to Android_bp +diff --git a/cros_gralloc/aidl/Android.bp b/cros_gralloc/aidl/Android_bp +similarity index 100% +rename from cros_gralloc/aidl/Android.bp +rename to cros_gralloc/aidl/Android_bp +diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android_bp +similarity index 100% +rename from cros_gralloc/gralloc4/Android.bp +rename to cros_gralloc/gralloc4/Android_bp +diff --git a/cros_gralloc/mapper_stablec/Android.bp b/cros_gralloc/mapper_stablec/Android_bp +similarity index 100% +rename from cros_gralloc/mapper_stablec/Android.bp +rename to cros_gralloc/mapper_stablec/Android_bp +-- +2.34.1 + diff --git a/aosp_diff/preliminary/external/minigbm/0001-gralloc4-Remove-gralloc4-build-as-it-is-not-needed.patch b/aosp_diff/preliminary/external/minigbm/0001-gralloc4-Remove-gralloc4-build-as-it-is-not-needed.patch deleted file mode 100644 index 7e58170655..0000000000 --- a/aosp_diff/preliminary/external/minigbm/0001-gralloc4-Remove-gralloc4-build-as-it-is-not-needed.patch +++ /dev/null @@ -1,183 +0,0 @@ -From ae0c778131a978eb09e40285c464d52f21d4adaf Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Wed, 11 Aug 2021 21:48:40 +0530 -Subject: [PATCH] gralloc4: Remove gralloc4 build as it is not needed. - -Signed-off-by: Tanuj Tekriwal -Change-Id: I0323fef046689abd33fd74a2f58bed422142c684 ---- - cros_gralloc/gralloc4/Android.bp | 162 ------------------------------- - 1 file changed, 162 deletions(-) - delete mode 100644 cros_gralloc/gralloc4/Android.bp - -diff --git a/cros_gralloc/gralloc4/Android.bp b/cros_gralloc/gralloc4/Android.bp -deleted file mode 100644 -index fb6aca9..0000000 ---- a/cros_gralloc/gralloc4/Android.bp -+++ /dev/null -@@ -1,162 +0,0 @@ --// --// Copyright (C) 2020 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 { -- // See: http://go/android-license-faq -- // A large-scale-change added 'default_applicable_licenses' to import -- // all of the 'license_kinds' from "external_minigbm_license" -- // to get the below license kinds: -- // SPDX-license-identifier-Apache-2.0 -- // SPDX-license-identifier-BSD -- default_applicable_licenses: ["external_minigbm_license"], --} -- --filegroup { -- name: "minigbm_gralloc4_allocator_files", -- srcs: [ -- "CrosGralloc4Allocator.cc", -- "CrosGralloc4AllocatorService.cc", -- "CrosGralloc4Utils.cc", -- ], --} -- --filegroup { -- name: "minigbm_gralloc4_mapper_files", -- srcs: [ -- "CrosGralloc4Mapper.cc", -- "CrosGralloc4Utils.cc", -- ], --} -- --cc_library { -- name: "libminigbm_gralloc4_utils", -- defaults: ["minigbm_cros_gralloc_defaults"], -- vendor: true, -- srcs: [ -- "CrosGralloc4Utils.cc", -- ], -- shared_libs: [ -- "android.hardware.graphics.mapper@4.0", -- "libgralloctypes", -- "libhidlbase", -- "libminigbm_gralloc", -- ], --} -- --cc_defaults { -- name: "minigbm_gralloc4_common_defaults", -- defaults: ["minigbm_cros_gralloc_defaults"], -- -- shared_libs: [ -- "android.hardware.graphics.mapper@4.0", -- "libgralloctypes", -- "libhidlbase", -- "libbase", -- "libutils", -- ], -- -- cflags: ["-Wno-sign-compare"], -- relative_install_path: "hw", --} -- --cc_defaults { -- name: "minigbm_gralloc4_allocator_defaults", -- defaults: ["minigbm_gralloc4_common_defaults"], -- -- shared_libs: ["android.hardware.graphics.allocator@4.0"], -- srcs: [":minigbm_gralloc4_allocator_files"], --} -- --cc_binary { -- name: "android.hardware.graphics.allocator@4.0-service.minigbm", -- defaults: ["minigbm_gralloc4_allocator_defaults"], -- shared_libs: ["libminigbm_gralloc"], -- vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], -- init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm.rc"], --} -- --cc_binary { -- name: "android.hardware.graphics.allocator@4.0-service.minigbm_msm", -- defaults: ["minigbm_gralloc4_allocator_defaults"], -- shared_libs: ["libminigbm_gralloc_msm"], -- vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], -- init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_msm.rc"], --} -- --cc_binary { -- name: "android.hardware.graphics.allocator@4.0-service.minigbm_arcvm", -- defaults: ["minigbm_gralloc4_allocator_defaults"], -- shared_libs: ["libminigbm_gralloc_arcvm"], -- vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], -- init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_arcvm.rc"], --} -- --cc_binary { -- name: "android.hardware.graphics.allocator@4.0-service.minigbm_intel", -- defaults: ["minigbm_gralloc4_allocator_defaults"], -- shared_libs: ["libminigbm_gralloc_intel"], -- vintf_fragments: ["android.hardware.graphics.allocator@4.0.xml"], -- init_rc: ["android.hardware.graphics.allocator@4.0-service.minigbm_intel.rc"], -- enabled: false, -- arch: { -- x86: { -- enabled: true, -- }, -- x86_64: { -- enabled: true, -- }, -- }, --} -- --cc_library_shared { -- name: "android.hardware.graphics.mapper@4.0-impl.minigbm", -- defaults: ["minigbm_gralloc4_common_defaults"], -- shared_libs: ["libminigbm_gralloc"], -- vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], -- srcs: [":minigbm_gralloc4_mapper_files"], --} -- --cc_library_shared { -- name: "android.hardware.graphics.mapper@4.0-impl.minigbm_msm", -- defaults: ["minigbm_gralloc4_common_defaults"], -- shared_libs: ["libminigbm_gralloc_msm"], -- vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], -- srcs: [":minigbm_gralloc4_mapper_files"], --} -- --cc_library_shared { -- name: "android.hardware.graphics.mapper@4.0-impl.minigbm_arcvm", -- defaults: ["minigbm_gralloc4_common_defaults"], -- shared_libs: ["libminigbm_gralloc_arcvm"], -- vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], -- srcs: [":minigbm_gralloc4_mapper_files"], --} -- --cc_library_shared { -- name: "android.hardware.graphics.mapper@4.0-impl.minigbm_intel", -- defaults: ["minigbm_gralloc4_common_defaults"], -- shared_libs: ["libminigbm_gralloc_intel"], -- vintf_fragments: ["android.hardware.graphics.mapper@4.0.xml"], -- srcs: [":minigbm_gralloc4_mapper_files"], -- enabled: false, -- arch: { -- x86: { -- enabled: true, -- }, -- x86_64: { -- enabled: true, -- }, -- }, --} --- -2.17.1 - diff --git a/aosp_diff/preliminary/external/minigbm/0002-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch b/aosp_diff/preliminary/external/minigbm/0002-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch deleted file mode 100644 index 78d28626c8..0000000000 --- a/aosp_diff/preliminary/external/minigbm/0002-Remove-aidl-libminigbm_gralloc_-and-gralloc.-Android.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 809b4acadba552fe1c3afaa9441e29c2f225d174 Mon Sep 17 00:00:00 2001 -From: "Badrappan, Jeevaka" -Date: Fri, 16 Jun 2023 22:55:48 +0530 -Subject: [PATCH] Remove aidl, libminigbm_gralloc_* and gralloc.* Android.bp - files - -Removed Anrdroid.bp files to make sure aidl, libminigbm_gralloc_* and -gralloc.* are not compiled from AOSP tree. - -Tracked-On: OAM-110710 -Change-Id: I7ed204e1200b3174720d655e1514245de91f7774 -Signed-off-by: Jeevaka Prabu Badrappan ---- - Android.bp | 262 ------------------------- - cros_gralloc/aidl/Android.bp | 51 ----- - cros_gralloc/mapper_stablec/Android.bp | 44 ----- - 3 files changed, 357 deletions(-) - delete mode 100644 Android.bp - delete mode 100644 cros_gralloc/aidl/Android.bp - delete mode 100644 cros_gralloc/mapper_stablec/Android.bp - -diff --git a/Android.bp b/Android.bp -deleted file mode 100644 -index e2d74d2..0000000 ---- a/Android.bp -+++ /dev/null -@@ -1,262 +0,0 @@ --// Use of this source code is governed by a BSD-style license that can be --// found in the LICENSE file. -- --package { -- default_applicable_licenses: ["external_minigbm_license"], --} -- --// Added automatically by a large-scale-change that took the approach of --// 'apply every license found to every target'. While this makes sure we respect --// every license restriction, it may not be entirely correct. --// --// e.g. GPL in an MIT project might only apply to the contrib/ directory. --// --// Please consider splitting the single license below into multiple licenses, --// taking care not to lose any license_kind information, and overriding the --// default license using the 'licenses: [...]' property on targets as needed. --// --// For unused files, consider creating a 'fileGroup' with "//visibility:private" --// to attach the license to, and including a comment whether the files may be --// used in the current project. --// See: http://go/android-license-faq --license { -- name: "external_minigbm_license", -- visibility: [":__subpackages__"], -- license_kinds: [ -- "SPDX-license-identifier-Apache-2.0", -- "SPDX-license-identifier-BSD", -- "SPDX-license-identifier-MIT", -- ], -- license_text: [ -- "LICENSE", -- ], --} -- --filegroup { -- name: "minigbm_core_files", -- -- srcs: [ -- "amdgpu.c", -- "drv.c", -- "drv_array_helpers.c", -- "drv_helpers.c", -- "dumb_driver.c", -- "i915.c", -- "mediatek.c", -- "msm.c", -- "rockchip.c", -- "vc4.c", -- "virtgpu.c", -- "virtgpu_cross_domain.c", -- "virtgpu_virgl.c", -- ], --} -- --filegroup { -- name: "minigbm_gralloc_common_files", -- -- srcs: [ -- "cros_gralloc/cros_gralloc_buffer.cc", -- "cros_gralloc/cros_gralloc_helpers.cc", -- "cros_gralloc/cros_gralloc_driver.cc", -- ], --} -- --filegroup { -- name: "minigbm_gralloc0_files", -- srcs: ["cros_gralloc/gralloc0/gralloc0.cc"], --} -- --cc_defaults { -- name: "minigbm_defaults", -- -- cflags: [ -- "-D_GNU_SOURCE=1", -- "-D_FILE_OFFSET_BITS=64", -- "-Wall", -- "-Wsign-compare", -- "-Wpointer-arith", -- "-Wcast-qual", -- "-Wcast-align", -- "-Wno-unused-parameter", -- ], -- -- product_variables: { -- platform_sdk_version: { -- cflags: ["-DANDROID_API_LEVEL=%d"], -- }, -- }, --} -- --cc_library_headers { -- name: "minigbm_headers", -- host_supported: true, -- vendor_available: true, -- export_include_dirs: ["."], --} -- --cc_defaults { -- name: "minigbm_cros_gralloc_defaults", -- -- defaults: ["minigbm_defaults"], -- -- header_libs: [ -- "libhardware_headers", -- "libnativebase_headers", -- "libsystem_headers", -- "minigbm_headers", -- ], -- -- static_libs: ["libarect"], -- -- vendor: true, -- -- shared_libs: [ -- "libcutils", -- "libdmabufheap", -- "libdrm", -- "libnativewindow", -- "libsync", -- "liblog", -- ], --} -- --cc_defaults { -- name: "minigbm_cros_gralloc_library_defaults", -- -- defaults: ["minigbm_cros_gralloc_defaults"], -- srcs: [ -- ":minigbm_core_files", -- ":minigbm_gralloc_common_files", -- ], --} -- --cc_defaults { -- name: "minigbm_cros_gralloc0_defaults", -- -- defaults: ["minigbm_cros_gralloc_defaults"], -- relative_install_path: "hw", -- -- srcs: [":minigbm_gralloc0_files"], --} -- --cc_library { -- name: "libgbm", -- defaults: ["minigbm_defaults"], -- host_supported: true, -- -- srcs: [ -- ":minigbm_core_files", -- "gbm.c", -- "gbm_helpers.c", -- ], -- -- target: { -- host: { -- // Avoid linking to another host copy of libdrm; this library will cause -- // binary GPU drivers to be loaded from the host, which might be linked -- // to a system copy of libdrm, which conflicts with the AOSP one -- allow_undefined_symbols: true, -- header_libs: ["libdrm_headers"], -- }, -- android: { -- shared_libs: [ -- "libdrm", -- "liblog" -- ], -- }, -- }, -- apex_available: [ -- "//apex_available:platform", -- "com.android.virt", -- ], -- -- export_include_dirs: ["."], --} -- --// Generic --cc_library_shared { -- name: "libminigbm_gralloc", -- defaults: ["minigbm_cros_gralloc_library_defaults"], -- cflags: ["-DHAS_DMABUF_SYSTEM_HEAP"], --} -- --cc_library_shared { -- name: "gralloc.minigbm", -- defaults: ["minigbm_cros_gralloc0_defaults"], -- shared_libs: ["libminigbm_gralloc"], --} -- --// Intel --cc_library_shared { -- name: "libminigbm_gralloc_intel", -- defaults: ["minigbm_cros_gralloc_library_defaults"], -- cflags: ["-DDRV_I915"], -- enabled: false, -- arch: { -- x86: { -- enabled: true, -- }, -- x86_64: { -- enabled: true, -- }, -- }, --} -- --cc_library_shared { -- name: "gralloc.minigbm_intel", -- defaults: ["minigbm_cros_gralloc0_defaults"], -- shared_libs: ["libminigbm_gralloc_intel"], -- enabled: false, -- arch: { -- x86: { -- enabled: true, -- }, -- x86_64: { -- enabled: true, -- }, -- }, --} -- --// Meson --cc_library_shared { -- name: "libminigbm_gralloc_meson", -- defaults: ["minigbm_cros_gralloc_library_defaults"], -- cflags: ["-DDRV_MESON"], --} -- --cc_library_shared { -- name: "gralloc.minigbm_meson", -- defaults: ["minigbm_cros_gralloc0_defaults"], -- shared_libs: ["libminigbm_gralloc_meson"], --} -- --// MSM --cc_library_shared { -- name: "libminigbm_gralloc_msm", -- defaults: ["minigbm_cros_gralloc_library_defaults"], -- cflags: [ -- "-DDRV_MSM", -- "-DQCOM_DISABLE_COMPRESSED_NV12", -- "-DHAS_DMABUF_SYSTEM_HEAP", -- ], --} -- --cc_library_shared { -- name: "gralloc.minigbm_msm", -- defaults: ["minigbm_cros_gralloc0_defaults"], -- shared_libs: ["libminigbm_gralloc_msm"], --} -- --// ARCVM --cc_library_shared { -- name: "libminigbm_gralloc_arcvm", -- defaults: ["minigbm_cros_gralloc_library_defaults"], -- cflags: ["-DVIRTIO_GPU_NEXT"], --} -- --cc_library_shared { -- name: "gralloc.minigbm_arcvm", -- defaults: ["minigbm_cros_gralloc0_defaults"], -- shared_libs: ["libminigbm_gralloc_arcvm"], --} -diff --git a/cros_gralloc/aidl/Android.bp b/cros_gralloc/aidl/Android.bp -deleted file mode 100644 -index da8f670..0000000 ---- a/cros_gralloc/aidl/Android.bp -+++ /dev/null -@@ -1,51 +0,0 @@ --// --// Copyright (C) 2022 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 { -- // See: http://go/android-license-faq -- // A large-scale-change added 'default_applicable_licenses' to import -- // all of the 'license_kinds' from "external_minigbm_license" -- // to get the below license kinds: -- // SPDX-license-identifier-Apache-2.0 -- // SPDX-license-identifier-BSD -- default_applicable_licenses: ["external_minigbm_license"], --} -- --cc_binary { -- name: "android.hardware.graphics.allocator-service.minigbm", -- defaults: ["minigbm_cros_gralloc_defaults"], -- relative_install_path: "hw", -- init_rc: ["allocator.rc"], -- vintf_fragments: ["allocator.xml"], -- vendor: true, -- shared_libs: [ -- "android.hardware.graphics.allocator-V2-ndk", -- "android.hardware.graphics.mapper@4.0", -- "libbase", -- "libbinder_ndk", -- "libgralloctypes", -- "libhidlbase", -- "liblog", -- "libminigbm_gralloc", -- "libminigbm_gralloc4_utils", -- ], -- static_libs: [ -- "libaidlcommonsupport", -- ], -- srcs: [ -- "Allocator.cpp", -- "Main.cpp", -- ], --} -diff --git a/cros_gralloc/mapper_stablec/Android.bp b/cros_gralloc/mapper_stablec/Android.bp -deleted file mode 100644 -index b25be17..0000000 ---- a/cros_gralloc/mapper_stablec/Android.bp -+++ /dev/null -@@ -1,44 +0,0 @@ --// --// Copyright (C) 2022 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 { -- // See: http://go/android-license-faq -- // A large-scale-change added 'default_applicable_licenses' to import -- // all of the 'license_kinds' from "external_minigbm_license" -- // to get the below license kinds: -- // SPDX-license-identifier-Apache-2.0 -- // SPDX-license-identifier-BSD -- default_applicable_licenses: ["external_minigbm_license"], --} -- --cc_library_shared { -- name: "mapper.minigbm", -- defaults: ["minigbm_gralloc4_common_defaults"], -- vintf_fragments: ["mapper.minigbm.xml"], -- shared_libs: [ -- "android.hardware.graphics.allocator-V2-ndk", -- "libminigbm_gralloc", -- ], -- header_libs: [ -- "libbase_headers", -- "libimapper_stablec", -- "libimapper_providerutils", -- ], -- srcs: [ -- ":minigbm_gralloc4_mapper_files", -- "Mapper.cpp", -- ], -- cpp_std: "c++20", --} --- -2.40.0 - diff --git a/aosp_diff/preliminary/external/sonivox/0001-fix-buffer-overrun-in-eas_wtengine.bulletin.patch b/aosp_diff/preliminary/external/sonivox/0001-fix-buffer-overrun-in-eas_wtengine.bulletin.patch deleted file mode 100644 index dc78fb0c51..0000000000 --- a/aosp_diff/preliminary/external/sonivox/0001-fix-buffer-overrun-in-eas_wtengine.bulletin.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0205dff2273fd26ab00b4526a96793da79242644 Mon Sep 17 00:00:00 2001 -From: Ray Essick -Date: Wed, 14 Feb 2024 11:10:41 -0600 -Subject: [PATCH] fix buffer overrun in eas_wtengine - -avoid a buffer overrun in eas_wtengine. -Check buffer limits during application of gain -Clip calculated length in eas_wtsynth - -Bug: 317780080 -Test: POC with bug -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6b66e7665dbcd891ff23081c13ab0b1637bb1dda) -backporting fix from main -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d1b0f81a2bb44a924365a11c1a51b27501a9a1ad) -Merged-In: I3609d6a36d89b26ae7eb3ae84cbe7772f6c3bee0 -Change-Id: I3609d6a36d89b26ae7eb3ae84cbe7772f6c3bee0 ---- - arm-wt-22k/lib_src/eas_wtengine.c | 24 ++++++++++++++++++++++++ - arm-wt-22k/lib_src/eas_wtsynth.c | 12 +++++++++++- - 2 files changed, 35 insertions(+), 1 deletion(-) - -diff --git a/arm-wt-22k/lib_src/eas_wtengine.c b/arm-wt-22k/lib_src/eas_wtengine.c -index b1ee749..dc8d864 100644 ---- a/arm-wt-22k/lib_src/eas_wtengine.c -+++ b/arm-wt-22k/lib_src/eas_wtengine.c -@@ -99,6 +99,10 @@ void WT_VoiceGain (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pMixBuffer = pWTIntFrame->pMixBuffer; - pInputBuffer = pWTIntFrame->pAudioBuffer; -@@ -196,6 +200,10 @@ void WT_Interpolate (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pOutputBuffer = pWTIntFrame->pAudioBuffer; - -@@ -297,6 +305,10 @@ void WT_InterpolateNoLoop (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pOutputBuffer = pWTIntFrame->pAudioBuffer; - -@@ -397,6 +409,10 @@ void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pAudioBuffer = pWTIntFrame->pAudioBuffer; - -@@ -465,6 +481,10 @@ void WT_VoiceFilter (S_FILTER_CONTROL *pFilter, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pOutputBuffer = pWTIntFrame->pAudioBuffer; - phaseInc = pWTIntFrame->frame.phaseIncrement; -@@ -613,6 +633,10 @@ void WT_InterpolateMono (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame) - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - return; -+ } else if (numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - pMixBuffer = pWTIntFrame->pMixBuffer; - -diff --git a/arm-wt-22k/lib_src/eas_wtsynth.c b/arm-wt-22k/lib_src/eas_wtsynth.c -index 74f78f5..ea1fe78 100644 ---- a/arm-wt-22k/lib_src/eas_wtsynth.c -+++ b/arm-wt-22k/lib_src/eas_wtsynth.c -@@ -484,7 +484,12 @@ EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, E - /*lint -e{703} use shift for performance */ - numSamples = (numSamples << NUM_PHASE_FRAC_BITS) - (EAS_I32) pWTVoice->phaseFrac; - if (pWTIntFrame->frame.phaseIncrement) { -- pWTIntFrame->numSamples = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement); -+ EAS_I32 oldMethod = 1 + (numSamples / pWTIntFrame->frame.phaseIncrement); -+ pWTIntFrame->numSamples = -+ (numSamples + pWTIntFrame->frame.phaseIncrement - 1) / pWTIntFrame->frame.phaseIncrement; -+ if (oldMethod != pWTIntFrame->numSamples) { -+ ALOGE("b/317780080 old %ld new %ld", oldMethod, pWTIntFrame->numSamples); -+ } - } else { - pWTIntFrame->numSamples = numSamples; - } -@@ -492,6 +497,11 @@ EAS_BOOL WT_CheckSampleEnd (S_WT_VOICE *pWTVoice, S_WT_INT_FRAME *pWTIntFrame, E - ALOGE("b/26366256"); - android_errorWriteLog(0x534e4554, "26366256"); - pWTIntFrame->numSamples = 0; -+ } else if (pWTIntFrame->numSamples > BUFFER_SIZE_IN_MONO_SAMPLES) { -+ ALOGE("b/317780080 clip numSamples %ld -> %d", -+ pWTIntFrame->numSamples, BUFFER_SIZE_IN_MONO_SAMPLES); -+ android_errorWriteLog(0x534e4554, "317780080"); -+ pWTIntFrame->numSamples = BUFFER_SIZE_IN_MONO_SAMPLES; - } - - /* sound will be done this frame */ --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/external/thermal_daemon/0001-Disable-libicuuc-lib-fro-A15.patch b/aosp_diff/preliminary/external/thermal_daemon/0001-Disable-libicuuc-lib-fro-A15.patch new file mode 100644 index 0000000000..2ec9b8010e --- /dev/null +++ b/aosp_diff/preliminary/external/thermal_daemon/0001-Disable-libicuuc-lib-fro-A15.patch @@ -0,0 +1,32 @@ +From 4ec5a1fb8a0ba5b1a52a13c44026f396ca8d82ea Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Tue, 18 Jun 2024 13:59:35 +0000 +Subject: [PATCH] Disable libicuuc lib fro A15 + +This patch will disable libicuuc since it is giving build +errors. + +Tests Done: Build should proceed + +Tracked-On: NA +Signed-off-by: Ankit Agarwal +--- + Android.mk | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Android.mk b/Android.mk +index 54b431f..0e6b670 100644 +--- a/Android.mk ++++ b/Android.mk +@@ -54,7 +54,7 @@ LOCAL_STATIC_LIBRARIES := libxml2 + ifeq ($(BOARD_VNDK_VERSION),current) + LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libc++ libutils + else +-LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libc++ libicuuc libutils ++LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libc++ libutils + endif + LOCAL_PRELINK_MODULE := false + LOCAL_MODULE := thermal-daemon +-- +2.34.1 + diff --git a/aosp_diff/preliminary/external/wpa_supplicant_8/0001-Fix-wifi-connection-failure.patch b/aosp_diff/preliminary/external/wpa_supplicant_8/0001-Fix-wifi-connection-failure.patch new file mode 100644 index 0000000000..a31c6ffebe --- /dev/null +++ b/aosp_diff/preliminary/external/wpa_supplicant_8/0001-Fix-wifi-connection-failure.patch @@ -0,0 +1,35 @@ +From 6a1782fa64511901cfe07d58fc1fc86c43e39a96 Mon Sep 17 00:00:00 2001 +From: Bharat B Panda +Date: Thu, 8 Aug 2024 12:59:33 +0000 +Subject: [PATCH] Fix wifi connection failure + +Changes made to disable PASN (Pre-Association Security Negotiation), +as we do not support respective sub-feature in iwlwifi driver. + +Test Done: +1. Flash the image BM and CiV +2. After boot, connect to an AP +3. Connection Successfull + +Tracked-On: OAM-123250 +Signed-off-by: Bharat B Panda +--- + wpa_supplicant/android.config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config +index 4cc38084..4c8fd230 100644 +--- a/wpa_supplicant/android.config ++++ b/wpa_supplicant/android.config +@@ -542,7 +542,7 @@ CONFIG_DPP2=y + CONFIG_SAE=y + + # PASN +-CONFIG_PASN=y ++#CONFIG_PASN=y + + # WPA3-Enterprise (SuiteB-192) + CONFIG_SUITEB=y +-- +2.34.1 + diff --git a/aosp_diff/preliminary/frameworks/av/0001-fix-audio-crash-issue.patch b/aosp_diff/preliminary/frameworks/av/0001-fixed-audio-crash-issue.patch similarity index 63% rename from aosp_diff/preliminary/frameworks/av/0001-fix-audio-crash-issue.patch rename to aosp_diff/preliminary/frameworks/av/0001-fixed-audio-crash-issue.patch index a1aaac94d1..f7ecf689c4 100644 --- a/aosp_diff/preliminary/frameworks/av/0001-fix-audio-crash-issue.patch +++ b/aosp_diff/preliminary/frameworks/av/0001-fixed-audio-crash-issue.patch @@ -1,9 +1,10 @@ -From ae8a89a16fa029b8968e0184be6613b485043558 Mon Sep 17 00:00:00 2001 -From: Chen Yu Y -Date: Tue, 4 Dec 2018 14:42:09 +0800 -Subject: [PATCH] fix audio crash issue +From 113ab52d9111d555cc90a20a350c2f9f45eda18d Mon Sep 17 00:00:00 2001 +From: Ankit Agarwal +Date: Thu, 20 Jun 2024 18:38:21 +0530 +Subject: [PATCH] fixed audio crash issue. + +Tests: Device is booting successfully. -Change-Id: I08abe891f0692fa58cc4bb3dbda8e63725cda2f8 Tracked-On: Signed-off-by: Chen Yu Y --- @@ -11,7 +12,7 @@ Signed-off-by: Chen Yu Y 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc -index 5484613fab..fde725e981 100644 +index 8bdb86e47d..3445703760 100644 --- a/media/audioserver/audioserver.rc +++ b/media/audioserver/audioserver.rc @@ -3,7 +3,7 @@ service audioserver /system/bin/audioserver @@ -20,9 +21,9 @@ index 5484613fab..fde725e981 100644 group audio camera drmrpc media mediadrm net_bt net_bt_admin net_bw_acct wakelock - capabilities BLOCK_SUSPEND + capabilities SYS_NICE BLOCK_SUSPEND + # match rtprio cur / max with sensor service as we handle AR/VR HID sensor data. + rlimit rtprio 10 10 ioprio rt 4 - writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks - onrestart restart vendor.audio-hal -- -2.24.0 +2.34.1 diff --git a/aosp_diff/preliminary/frameworks/av/0002-camera-fix-crash-while-disconnect-USB-camera.patch b/aosp_diff/preliminary/frameworks/av/0002-camera-fix-crash-while-disconnect-USB-camera.patch deleted file mode 100644 index 104dccc433..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0002-camera-fix-crash-while-disconnect-USB-camera.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8efb896a004d1bfb1d9c4861de6b3b3df0cd0b43 Mon Sep 17 00:00:00 2001 -From: kbillore -Date: Thu, 24 Sep 2020 19:48:50 +0530 -Subject: [PATCH] camera fix crash while disconnect USB camera - ---- - services/camera/libcameraservice/CameraService.cpp | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp -index af1e01d8e1..a5ee26e30a 100644 ---- a/services/camera/libcameraservice/CameraService.cpp -+++ b/services/camera/libcameraservice/CameraService.cpp -@@ -493,9 +493,6 @@ void CameraService::disconnectClient(const String8& id, sp clientTo - ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL", - __FUNCTION__, id.string()); - // Notify the client of disconnection -- clientToDisconnect->notifyError( -- hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED, -- CaptureResultExtras{}); - clientToDisconnect->disconnect(); - } - } --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/av/0003-Apply-the-correct-stride-for-HEVC-codec.patch b/aosp_diff/preliminary/frameworks/av/0003-Apply-the-correct-stride-for-HEVC-codec.patch deleted file mode 100644 index 10f0af82af..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0003-Apply-the-correct-stride-for-HEVC-codec.patch +++ /dev/null @@ -1,35 +0,0 @@ -From fa93ec8245984317c4d183618e297c8e6f626581 Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Tue, 25 May 2021 16:04:00 +0530 -Subject: [PATCH] Apply the correct stride for HEVC codec - -Remember the stride decoded from the header, so that -we can use the correct stride information when decoding -the frame. Currently since we donot remember this, there -is a mismatch with the stride we know and stride applied -during decode frame. - -Tracked-On: OAM-95490 -Signed-off-by: Vinay Kompella -Change-Id: I08ab2064d9d311ab0f5a3899a294ae9725af97d9 ---- - media/codec2/components/hevc/C2SoftHevcDec.cpp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/media/codec2/components/hevc/C2SoftHevcDec.cpp b/media/codec2/components/hevc/C2SoftHevcDec.cpp -index 2a6adcab3b..0afd4c48c3 100644 ---- a/media/codec2/components/hevc/C2SoftHevcDec.cpp -+++ b/media/codec2/components/hevc/C2SoftHevcDec.cpp -@@ -919,7 +919,8 @@ void C2SoftHevcDec::process( - if (0 < ps_decode_op->u4_pic_wd && 0 < ps_decode_op->u4_pic_ht) { - if (mHeaderDecoded == false) { - mHeaderDecoded = true; -- setParams(ALIGN128(ps_decode_op->u4_pic_wd), IVD_DECODE_FRAME); -+ mStride = ALIGN128(ps_decode_op->u4_pic_wd); -+ setParams(mStride, IVD_DECODE_FRAME); - } - if (ps_decode_op->u4_pic_wd != mWidth || ps_decode_op->u4_pic_ht != mHeight) { - mWidth = ps_decode_op->u4_pic_wd; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/av/0004-Generate-avx2-version-of-libaudioprocessing-library.patch b/aosp_diff/preliminary/frameworks/av/0004-Generate-avx2-version-of-libaudioprocessing-library.patch deleted file mode 100644 index 7ff53681c1..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0004-Generate-avx2-version-of-libaudioprocessing-library.patch +++ /dev/null @@ -1,100 +0,0 @@ -From f686fb2429d3bbf05217d8ddfb911e52fa94a643 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 10 Nov 2023 15:41:31 +0530 -Subject: [PATCH] Generate avx2 version of libaudioprocessing library - -Signed-off-by: ahs ---- - media/libaudioprocessing/Android.bp | 54 +++++++++++++++++++---------- - 1 file changed, 36 insertions(+), 18 deletions(-) - -diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp -index 309765aeb8..9a5272db64 100644 ---- a/media/libaudioprocessing/Android.bp -+++ b/media/libaudioprocessing/Android.bp -@@ -28,29 +28,22 @@ cc_defaults { - // uncomment to disable NEON on architectures that actually do support NEON, for benchmarking - // "-DUSE_NEON=false", - ], -+} - -+cc_defaults { -+ name: "libaudioprocessing_defaults_avx2", - arch: { - x86: { -- avx2: { -- cflags: [ -- "-mavx2", -- "-mfma", -- ], -- }, -+ cflags: [ "-mavx2", "-mfma"], - }, - x86_64: { -- avx2: { -- cflags: [ -- "-mavx2", -- "-mfma", -- ], -- }, -+ cflags: [ "-mavx2", "-mfma"], - }, - }, - } - --cc_library_shared { -- name: "libaudioprocessing", -+cc_defaults { -+ name: "libaudioprocessing_generic", - defaults: ["libaudioprocessing_defaults"], - - srcs: [ -@@ -70,12 +63,10 @@ cc_library_shared { - "libsonic", - "libvibrator", - ], -- -- whole_static_libs: ["libaudioprocessing_base"], - } - --cc_library_static { -- name: "libaudioprocessing_base", -+cc_defaults { -+ name: "libaudioprocessing_base_generic", - defaults: ["libaudioprocessing_defaults"], - vendor_available: true, - -@@ -93,3 +84,30 @@ cc_library_static { - }, - }, - } -+ -+cc_library_static { -+ name: "libaudioprocessing_base", -+ defaults: ["libaudioprocessing_base_generic"], -+} -+ -+cc_library_static { -+ name: "libaudioprocessing_base_avx2", -+ defaults: ["libaudioprocessing_base_generic", "libaudioprocessing_defaults_avx2"], -+} -+ -+cc_library_shared { -+ name: "libaudioprocessing", -+ defaults: ["libaudioprocessing_generic"], -+ whole_static_libs: ["libaudioprocessing_base"], -+} -+ -+cc_library_shared { -+ name: "libaudioprocessing_avx2", -+ defaults: ["libaudioprocessing_generic", "libaudioprocessing_defaults_avx2"], -+ target: { -+ android: { -+ relative_install_path: "IA-Perf/avx2", -+ }, -+ }, -+ whole_static_libs: ["libaudioprocessing_base_avx2"], -+} --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/av/0004-Update-mtp-packet-buffer.bulletin.patch b/aosp_diff/preliminary/frameworks/av/0004-Update-mtp-packet-buffer.bulletin.patch deleted file mode 100644 index 57dd4adfcf..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0004-Update-mtp-packet-buffer.bulletin.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 2ca6c27dc0336fd98f47cfb96dc514efa98e8864 Mon Sep 17 00:00:00 2001 -From: Ashish Kumar Gupta -Date: Tue, 21 Nov 2023 08:48:43 +0530 -Subject: [PATCH] Update mtp packet buffer - -Currently, the buffer size is not changed when the packet size is increased. Ideally, the buffer size should be larger than the packet size. In our case, when the packet size is increased, we must reallocate the buffer of MTP packet. - -Bug: 300007708 -Test: build and flash the device. Check MTP works -Test: run fuzzer locally -(cherry picked from commit e1494a2d8e7eee25d7ea5469be43740e97294c99) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5c0f99beb6fa5ff920caf5b0d06aaebc8e9eab24) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:38852806102bb7e9d46f4b0de8a3b4918d625ad4) -Merged-In: I98398a9e15962e6d5f08445ee7b17f5d61a3a528 -Change-Id: I98398a9e15962e6d5f08445ee7b17f5d61a3a528 ---- - media/mtp/MtpPacket.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp -index 5faaac2026..634aa46dd9 100644 ---- a/media/mtp/MtpPacket.cpp -+++ b/media/mtp/MtpPacket.cpp -@@ -168,8 +168,10 @@ void MtpPacket::setParameter(int index, uint32_t value) { - return; - } - int offset = MTP_CONTAINER_PARAMETER_OFFSET + (index - 1) * sizeof(uint32_t); -- if (mPacketSize < offset + sizeof(uint32_t)) -+ if (mPacketSize < offset + sizeof(uint32_t)) { - mPacketSize = offset + sizeof(uint32_t); -+ allocate(mPacketSize); -+ } - putUInt32(offset, value); - } - --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/av/0005-Modify-IA-Perf-variants-of-library-to-have-same-name.patch b/aosp_diff/preliminary/frameworks/av/0005-Modify-IA-Perf-variants-of-library-to-have-same-name.patch deleted file mode 100644 index 5c6d0e0185..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0005-Modify-IA-Perf-variants-of-library-to-have-same-name.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 114bfc94102c558460009f058a22cd9572951425 Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 10 Nov 2023 15:42:55 +0530 -Subject: [PATCH] Modify IA-Perf variants of library to have same name as - original - -Signed-off-by: ahs ---- - media/libaudioprocessing/Android.bp | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp -index 9a5272db64..b5b2177619 100644 ---- a/media/libaudioprocessing/Android.bp -+++ b/media/libaudioprocessing/Android.bp -@@ -103,11 +103,8 @@ cc_library_shared { - - cc_library_shared { - name: "libaudioprocessing_avx2", -+ override_lib_name: "libaudioprocessing", - defaults: ["libaudioprocessing_generic", "libaudioprocessing_defaults_avx2"], -- target: { -- android: { -- relative_install_path: "IA-Perf/avx2", -- }, -- }, -+ relative_install_path: "IA-Perf/avx2", - whole_static_libs: ["libaudioprocessing_base_avx2"], - } --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/av/0005-SoftVideoDecodeOMXComponent-validate-OMX-params-for-dynamic-HDR.bulletin.patch b/aosp_diff/preliminary/frameworks/av/0005-SoftVideoDecodeOMXComponent-validate-OMX-params-for-dynamic-HDR.bulletin.patch deleted file mode 100644 index 16388e1577..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0005-SoftVideoDecodeOMXComponent-validate-OMX-params-for-dynamic-HDR.bulletin.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 23a035af9be9f4ec6fe16a5fb9710d19ef669eec Mon Sep 17 00:00:00 2001 -From: Harish Mahendrakar -Date: Mon, 30 Oct 2023 20:38:56 +0000 -Subject: [PATCH] SoftVideoDecodeOMXComponent: validate OMX params for dynamic - HDR - -Bug: 273935108 -Bug: 281065553 -(cherry picked from https://partner-android-review.googlesource.com/q/commit:b2c67bdcf57149a5e19a04466205266dc543fd86) -(cherry picked from commit a542f2c50700ca6df93e966fe8d4c468e1a15d9a) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:80e0acc096d201e80a1b65af944b1e47c9dd6f7b) -Merged-In: I707745594a9196d8d85d4c4bb498eba3c6198b42 -Change-Id: I707745594a9196d8d85d4c4bb498eba3c6198b42 ---- - media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp -index e853da9763..418302389d 100644 ---- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp -+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp -@@ -616,6 +616,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getConfig( - DescribeHDR10PlusInfoParams* outParams = - (DescribeHDR10PlusInfoParams *)params; - -+ if (!isValidOMXParam(outParams)) { -+ return OMX_ErrorBadParameter; -+ } -+ - outParams->nParamSizeUsed = info->size(); - - // If the buffer provided by the client does not have enough -@@ -694,6 +698,10 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetConfig( - const DescribeHDR10PlusInfoParams* inParams = - (DescribeHDR10PlusInfoParams *)params; - -+ if (!isValidOMXParam(inParams)) { -+ return OMX_ErrorBadParameter; -+ } -+ - if (*frameConfig) { - // This is a request to append to the current frame config set. - // For now, we only support kDescribeHdr10PlusInfoIndex, which --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/av/0006-Fix-out-of-bounds-read-and-write-in-onQueueFilled-in-outQueue.bulletin.patch b/aosp_diff/preliminary/frameworks/av/0006-Fix-out-of-bounds-read-and-write-in-onQueueFilled-in-outQueue.bulletin.patch deleted file mode 100644 index 277ef63bc2..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0006-Fix-out-of-bounds-read-and-write-in-onQueueFilled-in-outQueue.bulletin.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 3bedd18fd3f4465162666592a2850da9f4c0ff48 Mon Sep 17 00:00:00 2001 -From: Haripriya Deshmukh -Date: Tue, 5 Dec 2023 18:32:38 +0000 -Subject: [PATCH] Fix out of bounds read and write in onQueueFilled in outQueue - -Bug: 276442130 -Test: POC in bug descriptions -(cherry picked from https://partner-android-review.googlesource.com/q/commit:7aef41e59412e2f95bab5de7e33f5f04bb808643) -(cherry picked from commit 8f4cfda9fc75f1e9ba3b6dee3fbffda4b6111d64) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:208e430bc6380fafafca8041b239f835263a9d47) -Merged-In: Ic230d10048193a785f185dc6a7de6f455f9318c1 -Change-Id: Ic230d10048193a785f185dc6a7de6f455f9318c1 ---- - media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp -index a4b3e2f434..14c3fa0875 100644 ---- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp -+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp -@@ -312,8 +312,11 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { - outHeader->nFilledLen = frameSize; - - List::iterator it = outQueue.begin(); -- while ((*it)->mHeader != outHeader) { -- ++it; -+ while (it != outQueue.end() && (*it)->mHeader != outHeader) { -+ ++it; -+ } -+ if (it == outQueue.end()) { -+ return; - } - - BufferInfo *outInfo = *it; --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/av/0007-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch b/aosp_diff/preliminary/frameworks/av/0007-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch deleted file mode 100644 index 7b26094c13..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0007-libmediatranscoding-handle-death-recipient-cookie-ownership-dif.bulletin.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 4b68b00993849b6a7f0e6d075bc2c8bb2e184e61 Mon Sep 17 00:00:00 2001 -From: Devin Moore -Date: Fri, 23 Feb 2024 19:19:38 +0000 -Subject: [PATCH] libmediatranscoding: handle death recipient cookie ownership - differently - -The ownership of the death recipient cookie is now limited to the -TranscodingResourcePolicy object and the binderDied callback. -They both must be able to delete the cookie object and they both must be -aware of it already being deleted. - -In all cases, the TranscodingResourcePolicy object that needs to be -unregistered will outlive the cookie and the death recipient. - -Calling unlinkToDeath is unneccessary because the last strong ref to the -binder that was linked to death is removed in the unregisterSelf method -which will unlink the binder and death recipient. - -Test: atest CtsMediaTranscodingTestCases MediaSampleReaderNDKTests -Test: adb shell kill -9 `pid media.resource_observer` -Test: delete mResourcePolicy.get() to force destructor after linkToDeath -Bug: 319210610 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0c674f5ff68daa64b90e1a234061ba9bebe6173c) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3bd045d3543190b1e8d2d26743356ad657f25e33) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:13ed07dee27c3affa4511f02c612701d6cbf603a) -Merged-In: I8e6ba40fe3da30bf8753e7a16ad5c8cd5dfda40b -Change-Id: I8e6ba40fe3da30bf8753e7a16ad5c8cd5dfda40b ---- - .../TranscodingResourcePolicy.cpp | 57 +++++++++++++++++-- - .../include/media/TranscodingResourcePolicy.h | 4 ++ - 2 files changed, 56 insertions(+), 5 deletions(-) - -diff --git a/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp -index af53f64671..6a0c09a20a 100644 ---- a/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp -+++ b/media/module/libmediatranscoding/TranscodingResourcePolicy.cpp -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -66,11 +67,31 @@ struct TranscodingResourcePolicy::ResourceObserver : public BnResourceObserver { - TranscodingResourcePolicy* mOwner; - }; - -+// cookie used for death recipients. The TranscodingResourcePolicy -+// that this cookie is associated with must outlive this cookie. It is -+// either deleted by binderDied, or in unregisterSelf which is also called -+// in the destructor of TranscodingResourcePolicy -+class TranscodingResourcePolicyCookie { -+ public: -+ TranscodingResourcePolicyCookie(TranscodingResourcePolicy* policy) : mPolicy(policy) {} -+ TranscodingResourcePolicyCookie() = delete; -+ TranscodingResourcePolicy* mPolicy; -+}; -+ -+static std::map> sCookies; -+static uintptr_t sCookieKeyCounter; -+static std::mutex sCookiesMutex; -+ - // static - void TranscodingResourcePolicy::BinderDiedCallback(void* cookie) { -- TranscodingResourcePolicy* owner = reinterpret_cast(cookie); -- if (owner != nullptr) { -- owner->unregisterSelf(); -+ std::lock_guard guard(sCookiesMutex); -+ if (auto it = sCookies.find(reinterpret_cast(cookie)); it != sCookies.end()) { -+ ALOGI("BinderDiedCallback unregistering TranscodingResourcePolicy"); -+ auto policy = reinterpret_cast(it->second->mPolicy); -+ if (policy) { -+ policy->unregisterSelf(); -+ } -+ sCookies.erase(it); - } - // TODO(chz): retry to connecting to IResourceObserverService after failure. - // Also need to have back-up logic if IResourceObserverService is offline for -@@ -88,6 +109,24 @@ TranscodingResourcePolicy::TranscodingResourcePolicy() - } - - TranscodingResourcePolicy::~TranscodingResourcePolicy() { -+ { -+ std::lock_guard guard(sCookiesMutex); -+ -+ // delete all of the cookies associated with this TranscodingResourcePolicy -+ // instance since they are holding pointers to this object that will no -+ // longer be valid. -+ for (auto it = sCookies.begin(); it != sCookies.end();) { -+ const uintptr_t key = it->first; -+ std::lock_guard guard(mCookieKeysLock); -+ if (mCookieKeys.find(key) != mCookieKeys.end()) { -+ // No longer need to track this cookie -+ mCookieKeys.erase(key); -+ it = sCookies.erase(it); -+ } else { -+ it++; -+ } -+ } -+ } - unregisterSelf(); - } - -@@ -123,7 +162,16 @@ void TranscodingResourcePolicy::registerSelf() { - return; - } - -- AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(this)); -+ std::unique_ptr cookie = -+ std::make_unique(this); -+ uintptr_t cookieKey = sCookieKeyCounter++; -+ sCookies.emplace(cookieKey, std::move(cookie)); -+ { -+ std::lock_guard guard(mCookieKeysLock); -+ mCookieKeys.insert(cookieKey); -+ } -+ -+ AIBinder_linkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(cookieKey)); - - ALOGD("@@@ registered observer"); - mRegistered = true; -@@ -141,7 +189,6 @@ void TranscodingResourcePolicy::unregisterSelf() { - ::ndk::SpAIBinder binder = mService->asBinder(); - if (binder.get() != nullptr) { - Status status = mService->unregisterObserver(mObserver); -- AIBinder_unlinkToDeath(binder.get(), mDeathRecipient.get(), reinterpret_cast(this)); - } - - mService = nullptr; -diff --git a/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h -index ee232e7551..4d762b5832 100644 ---- a/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h -+++ b/media/module/libmediatranscoding/include/media/TranscodingResourcePolicy.h -@@ -22,6 +22,7 @@ - #include - - #include -+#include - namespace aidl { - namespace android { - namespace media { -@@ -48,6 +49,8 @@ private: - bool mRegistered GUARDED_BY(mRegisteredLock); - std::shared_ptr mService GUARDED_BY(mRegisteredLock); - std::shared_ptr mObserver; -+ mutable std::mutex mCookieKeysLock; -+ std::set mCookieKeys; - - mutable std::mutex mCallbackLock; - std::weak_ptr mResourcePolicyCallback -@@ -59,6 +62,7 @@ private: - static void BinderDiedCallback(void* cookie); - - void registerSelf(); -+ // must delete the associated TranscodingResourcePolicyCookie any time this is called - void unregisterSelf(); - void onResourceAvailable(pid_t pid); - }; // class TranscodingUidPolicy --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/av/0008-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch b/aosp_diff/preliminary/frameworks/av/0008-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch deleted file mode 100644 index f7b4f51471..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0008-StagefrightRecoder-Disabling-B-frame-support.bulletin.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 6cfd048292b2cc706811a22c9078208cfa8e6d24 Mon Sep 17 00:00:00 2001 -From: Rakesh Kumar -Date: Thu, 30 May 2024 11:17:48 +0000 -Subject: [PATCH] StagefrightRecoder: Disabling B-frame support - -Disabling b-frame support from stagefright recorder in case of -audio source as mic and video source is surface use case only -because screen recorder with microphone doesn't play in sync -if b-frame is enabled. -If the audio source selected is INTERNAL (i.e. device) or -MIC_AND_INTERNAL with screen recorder then b frame is supported. - -Bug: 288549440 -Test: manually check screen recording with audio from mic has audio/video in synch -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:af685c66bab17b71fe1624f76b5d55628f79e6fa) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:da3407f7688f35eb2dce79f1405feeb182241a3c) -Merged-In: I4098655eb9687fb633085333bc140634441566e6 -Change-Id: I4098655eb9687fb633085333bc140634441566e6 ---- - media/libmediaplayerservice/StagefrightRecorder.cpp | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp -index 036508507b..e0449ffc0d 100644 ---- a/media/libmediaplayerservice/StagefrightRecorder.cpp -+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp -@@ -2099,6 +2099,11 @@ status_t StagefrightRecorder::setupVideoEncoder( - - if (tsLayers > 1) { - uint32_t bLayers = std::min(2u, tsLayers - 1); // use up-to 2 B-layers -+ // TODO(b/341121900): Remove this once B frames are handled correctly in screen recorder -+ // use case in case of mic only -+ if (mAudioSource == AUDIO_SOURCE_MIC && mVideoSource == VIDEO_SOURCE_SURFACE) { -+ bLayers = 0; -+ } - uint32_t pLayers = tsLayers - bLayers; - format->setString( - "ts-schema", AStringPrintf("android.generic.%u+%u", pLayers, bLayers)); --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/av/0009-By-default-disable-HDR-support-for-VP9-codec.patch b/aosp_diff/preliminary/frameworks/av/0009-By-default-disable-HDR-support-for-VP9-codec.patch deleted file mode 100644 index f209cdcad7..0000000000 --- a/aosp_diff/preliminary/frameworks/av/0009-By-default-disable-HDR-support-for-VP9-codec.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 695fa89a4552a52498e92151440848aa4a968eed Mon Sep 17 00:00:00 2001 -From: Lina Sun -Date: Mon, 29 Jul 2024 08:06:16 +0000 -Subject: [PATCH] By default disable HDR support for VP9 codec - -The change is because current mediasdk_c2 doesn't support HDR for -VP9 codec, but in framework VP9 HDR is supported by default. - -Will need to remove this patch when VP9 is supported in -mediasdk_c2. ---- - media/codec2/sfplugin/Codec2InfoBuilder.cpp | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/media/codec2/sfplugin/Codec2InfoBuilder.cpp b/media/codec2/sfplugin/Codec2InfoBuilder.cpp -index 453a0d2f59..3e00dc5ee5 100644 ---- a/media/codec2/sfplugin/Codec2InfoBuilder.cpp -+++ b/media/codec2/sfplugin/Codec2InfoBuilder.cpp -@@ -154,7 +154,9 @@ bool addSupportedProfileLevels( - // VP9 does not support HDR metadata in the bitstream and static metadata - // can always be carried by the framework. (The framework does not propagate - // dynamic metadata as that needs to be frame accurate.) -- supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9); -+ // TODO: comment out this line for now as VP9 HDR is not supported in SDK yet -+ // will need uncomment it when adding VP9 HDR support in SDK. -+ //supportsHdr |= (mediaType == MIMETYPE_VIDEO_VP9); - - // HDR support implies 10-bit support. AV1 codecs are also required to - // support 10-bit per CDD. --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/0001-catch-IllegalArgumentException-from-getHarmfulAppWar.patch b/aosp_diff/preliminary/frameworks/base/0001-catch-IllegalArgumentException-from-getHarmfulAppWar.patch deleted file mode 100644 index 4f91fb6e5e..0000000000 --- a/aosp_diff/preliminary/frameworks/base/0001-catch-IllegalArgumentException-from-getHarmfulAppWar.patch +++ /dev/null @@ -1,34 +0,0 @@ -From ecce1532361829a59a87cb8f12afa2af45420453 Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Thu, 10 Nov 2022 15:19:44 +0530 -Subject: [PATCH] catch IllegalArgumentException from getHarmfulAppWarning - -A missing package should not cause system_server crash. - -BUG: 253989182 -Test: builds -Merged-In: I55fd685280ea6a3d08b9c838b2245ed6dec0aa56 -Change-Id: I55fd685280ea6a3d08b9c838b2245ed6dec0aa56 -(cherry picked from commit 20e4747134c49501e67a1b0df1fe17f350937787) -Tracked-On: NA -Signed-Off-By: Songchun Fan ---- - .../java/com/android/server/wm/ActivityStartInterceptor.java | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java -index a452013bf42a..34220cc40f10 100644 ---- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java -+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java -@@ -380,7 +380,7 @@ class ActivityStartInterceptor { - try { - harmfulAppWarning = mService.getPackageManager() - .getHarmfulAppWarning(mAInfo.packageName, mUserId); -- } catch (RemoteException ex) { -+ } catch (RemoteException | IllegalArgumentException ex) { - return false; - } - --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/01_0001-adb-dbc-tty-device-offline-issue.patch b/aosp_diff/preliminary/frameworks/base/01_0001-adb-dbc-tty-device-offline-issue.patch deleted file mode 100644 index 012e993dca..0000000000 --- a/aosp_diff/preliminary/frameworks/base/01_0001-adb-dbc-tty-device-offline-issue.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 7010d64a6c9788200afd02660f248a4770d9b415 Mon Sep 17 00:00:00 2001 -From: Prabhat Chand Pandey -Date: Mon, 14 Jun 2021 15:09:40 +0530 -Subject: [PATCH] adb: dbc: tty: device offline issue - -Restarting the adb daemon when DbC device move to the dbc -state configured from dbc state enable. -To do so added DEVPATH variable which match to the DbC TTY -DEVPATH uevent. - -Change-Id: I823e38e862d9b185e9581978058dc17c2c4a42d4 -Tracked-On: -Signed-off-by: Prabhat Chand Pandey -Signed-off-by: Balaji M ---- - .../android/server/usb/UsbDeviceManager.java | 26 ++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - -diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java -index 77b263824b78..fe0f134234d7 100644 ---- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java -+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java -@@ -132,6 +132,8 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - */ - private static final String NORMAL_BOOT = "normal"; - -+ private static final String USB_DBC_STATE_MATCH = -+ "DEVPATH=/devices/virtual/tty/ttyDBC0"; - private static final String USB_STATE_MATCH = - "DEVPATH=/devices/virtual/android_usb/android0"; - private static final String ACCESSORY_START_MATCH = -@@ -254,6 +256,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - } - - String state = event.get("USB_STATE"); -+ -+ if (state == null) -+ state = event.get("ACTION"); -+ - String accessory = event.get("ACCESSORY"); - - if (state != null) { -@@ -402,6 +408,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - mUEventObserver.startObserving(USB_STATE_MATCH); - mUEventObserver.startObserving(ACCESSORY_START_MATCH); - -+ mUEventObserver.startObserving(USB_DBC_STATE_MATCH); - sEventLogger = new EventLogger(DUMPSYS_LOG_BUFFER, "UsbDeviceManager activity"); - } - -@@ -529,6 +536,7 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - abstract static class UsbHandler extends Handler { - - // current USB state -+ private boolean mDbcConnected; - private boolean mHostConnected; - private boolean mUsbAccessoryConnected; - private boolean mInHostModeWithNoAccessoryConnected; -@@ -714,6 +722,9 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - } else if ("CONFIGURED".equals(state)) { - connected = 1; - configured = 1; -+ } else if ("add".equals(state)) { -+ connected = 2; -+ configured = 1; - } else { - Slog.e(TAG, "unknown state " + state); - return; -@@ -985,7 +996,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - - @Override - public void handleMessage(Message msg) { -- switch (msg.what) { -+ final String ADBD = "adbd"; -+ final String CTL_START = "ctl.start"; -+ final String CTL_STOP = "ctl.stop"; -+ -+ switch (msg.what) { - case MSG_UPDATE_STATE: - int operationId = sUsbOperationCount.incrementAndGet(); - mConnected = (msg.arg1 == 1); -@@ -994,6 +1009,10 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - Slog.i(TAG, "handleMessage MSG_UPDATE_STATE " + "mConnected:" + mConnected - + " mConfigured:" + mConfigured); - } -+ if (msg.arg1==2) { -+ mConnected = (msg.arg1 == 2); -+ mDbcConnected = (msg.arg1 == 2); -+ } - updateUsbNotification(false); - updateAdbNotification(false); - if (mBootCompleted) { -@@ -1018,6 +1037,11 @@ public class UsbDeviceManager implements ActivityTaskManagerInternal.ScreenObser - mPendingBootBroadcast = true; - } - updateUsbSpeed(); -+ if (mDbcConnected) { -+ setSystemProperty("sys.usb.controller", "none"); -+ setSystemProperty(CTL_STOP, ADBD); -+ setSystemProperty(CTL_START, ADBD); -+ } - break; - case MSG_UPDATE_PORT_STATE: - SomeArgs args = (SomeArgs) msg.obj; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/02_0002-Handle-simultaneous-HDMI-WiredHeadphone-events.patch b/aosp_diff/preliminary/frameworks/base/02_0002-Handle-simultaneous-HDMI-WiredHeadphone-events.patch deleted file mode 100644 index a559502c36..0000000000 --- a/aosp_diff/preliminary/frameworks/base/02_0002-Handle-simultaneous-HDMI-WiredHeadphone-events.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 573c82ea591b910ccc4b68a0f04f441426a9c2e7 Mon Sep 17 00:00:00 2001 -From: akodanka -Date: Wed, 24 Jun 2020 13:12:52 +0530 -Subject: [PATCH] Handle simultaneous HDMI & WiredHeadphone events - -Wired Headset sets these 2 bits in the device when connected: -SW_HEADPHONE_INSERT_BIT & SW_MICROPHONE_INSERT_BIT -Additionally, if HDMI device is connected, it sets the -SW_LINEOUT_INSERT_BIT event too. -The combination of these 3 bits has to be handled correctly. - -Tracked-On: OAM-91511 -Signed-off-by: akodanka ---- - .../com/android/server/WiredAccessoryManager.java | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - mode change 100644 => 100755 services/core/java/com/android/server/WiredAccessoryManager.java - -diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java -old mode 100644 -new mode 100755 -index 8e5c73bfc02..3a9e4d46d4e ---- a/services/core/java/com/android/server/WiredAccessoryManager.java -+++ b/services/core/java/com/android/server/WiredAccessoryManager.java -@@ -167,6 +167,14 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { - headset = BIT_HEADSET; - break; - -+ case SW_HEADPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT: -+ headset = BIT_HEADSET; -+ break; -+ -+ case SW_HEADPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT | SW_MICROPHONE_INSERT_BIT: -+ headset = BIT_HEADSET; -+ break; -+ - default: - headset = 0; - break; -@@ -404,11 +412,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks { - // - // If the kernel does not have an "hdmi_audio" switch, just fall back on the older - // "hdmi" switch instead. -- uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, 0, 0); -+ uei = new UEventInfo(NAME_HDMI_AUDIO, BIT_HDMI_AUDIO, BIT_LINEOUT, 0); - if (uei.checkSwitchExists()) { - retVal.add(uei); - } else { -- uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, 0, 0); -+ uei = new UEventInfo(NAME_HDMI, BIT_HDMI_AUDIO, BIT_LINEOUT, 0); - if (uei.checkSwitchExists()) { - retVal.add(uei); - } else { --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/03_003-Allow-batteryless-device-for-system-update.patch b/aosp_diff/preliminary/frameworks/base/03_003-Allow-batteryless-device-for-system-update.patch deleted file mode 100644 index 35c0decb64..0000000000 --- a/aosp_diff/preliminary/frameworks/base/03_003-Allow-batteryless-device-for-system-update.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 474379e98aee362dc9029febacaa4f4c5f46cbb4 Mon Sep 17 00:00:00 2001 -From: Jaikrishna Nemallapudi -Date: Fri, 19 Mar 2021 16:24:32 +0530 -Subject: [PATCH] Allow batteryless device for system update. - -SytemUpdate CTS tests will pass only if battery is available. -Fixed it to allow for batteryless device also. - -Tracked-On: OAM-97111 -Signed-off-by: Jaikrishna Nemallapudi ---- - .../server/devicepolicy/UpdateInstaller.java | 22 ++++++++++++++++--- - 1 file changed, 19 insertions(+), 3 deletions(-) - -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/UpdateInstaller.java b/services/devicepolicy/java/com/android/server/devicepolicy/UpdateInstaller.java -index 7148ed4523d..36984c00d33 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/UpdateInstaller.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/UpdateInstaller.java -@@ -90,11 +90,27 @@ abstract class UpdateInstaller { - Intent batteryStatus = mContext.registerReceiver( - /* receiver= */ null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); - float batteryPercentage = calculateBatteryPercentage(batteryStatus); -- boolean isBatteryPluggedIn = -- batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, /* defaultValue= */ -1) > 0; -- return isBatteryPluggedIn -+ int batteryLevel = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -+ /* defaultValue= */ -1); -+ int powerType = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -+ /* defaultValue= */ -1); -+ int batteryHealth = batteryStatus.getIntExtra(BatteryManager.EXTRA_HEALTH, -+ /* defaultValue= */ -1); -+ int batteryStat = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -+ /* defaultValue= */ -1); -+ -+ boolean isBatteryPluggedIn = powerType > 0; -+ -+ /* Condition to allow batteryless deivce */ -+ if (batteryLevel == 0 && powerType == BatteryManager.BATTERY_PLUGGED_AC -+ && batteryHealth == BatteryManager.BATTERY_HEALTH_UNKNOWN -+ && batteryStat == BatteryManager.BATTERY_STATUS_UNKNOWN) { -+ return true; -+ } else { -+ return isBatteryPluggedIn - ? batteryPercentage >= mConstants.BATTERY_THRESHOLD_CHARGING - : batteryPercentage >= mConstants.BATTERY_THRESHOLD_NOT_CHARGING; -+ } - } - - private float calculateBatteryPercentage(Intent batteryStatus) { --- -2.31.1 - diff --git a/aosp_diff/preliminary/frameworks/base/04_0004-Enable-ART-AutoFastJni.patch b/aosp_diff/preliminary/frameworks/base/04_0004-Enable-ART-AutoFastJni.patch deleted file mode 100644 index 098a6e8b49..0000000000 --- a/aosp_diff/preliminary/frameworks/base/04_0004-Enable-ART-AutoFastJni.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 183b76c813cf8f69bd250b4fe45415eb14a7294a Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Mon, 16 Oct 2023 18:46:24 +0530 -Subject: [PATCH] Enable ART AutoFastJni - -Change-Id: I391cac74930c3b8236b4a8c81bf90a31a825e8a2 -Signed-off-by: bodapati ---- - core/jni/AndroidRuntime.cpp | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp -index e5d567607199..89813ac0ac1a 100644 ---- a/core/jni/AndroidRuntime.cpp -+++ b/core/jni/AndroidRuntime.cpp -@@ -642,6 +642,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p - char heapminfreeOptsBuf[sizeof("-XX:HeapMinFree=")-1 + PROPERTY_VALUE_MAX]; - char heapmaxfreeOptsBuf[sizeof("-XX:HeapMaxFree=")-1 + PROPERTY_VALUE_MAX]; - char usejitOptsBuf[sizeof("-Xusejit:")-1 + PROPERTY_VALUE_MAX]; -+ char autofastjniOptsBuf[sizeof("-XAutoFastJni:")-1 + PROPERTY_VALUE_MAX]; - char jitpthreadpriorityOptsBuf[sizeof("-Xjitpthreadpriority:")-1 + PROPERTY_VALUE_MAX]; - char jitmaxsizeOptsBuf[sizeof("-Xjitmaxsize:")-1 + PROPERTY_VALUE_MAX]; - char jitinitialsizeOptsBuf[sizeof("-Xjitinitialsize:")-1 + PROPERTY_VALUE_MAX]; -@@ -852,6 +853,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool p - * JIT related options. - */ - parseRuntimeOption("dalvik.vm.usejit", usejitOptsBuf, "-Xusejit:"); -+ parseRuntimeOption("dalvik.vm.useautofastjni", autofastjniOptsBuf, "-XAutoFastJni:"); - parseRuntimeOption("dalvik.vm.jitmaxsize", jitmaxsizeOptsBuf, "-Xjitmaxsize:"); - parseRuntimeOption("dalvik.vm.jitinitialsize", jitinitialsizeOptsBuf, "-Xjitinitialsize:"); - parseRuntimeOption("dalvik.vm.jitthreshold", jitthresholdOptsBuf, "-Xjitthreshold:"); --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/10_0010-Add-whitelist-permissions-to-clipboardagent-privapp.patch b/aosp_diff/preliminary/frameworks/base/10_0010-Add-whitelist-permissions-to-clipboardagent-privapp.patch deleted file mode 100644 index 3c425b9462..0000000000 --- a/aosp_diff/preliminary/frameworks/base/10_0010-Add-whitelist-permissions-to-clipboardagent-privapp.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 8183bc434f4311980535a6494940cfe19ef8c3b6 Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Tue, 23 May 2023 09:41:53 +0530 -Subject: [PATCH] Add whitelist permissions to clipboardagent privapp - -Tracked-On: OAM-102872 -Change-Id: I195f58dcea3818452ef861a3014c923a0ff84c8e -Signed-off-by: ahs ---- - data/etc/privapp-permissions-platform.xml | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml -index 1f1239e3c310..883d962611d1 100644 ---- a/data/etc/privapp-permissions-platform.xml -+++ b/data/etc/privapp-permissions-platform.xml -@@ -577,4 +577,10 @@ applications that come with the platform - - - -+ -+ -+ -+ -+ -+ - --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/11_0011-Allow-clipboard-access-to-intel-packages.patch b/aosp_diff/preliminary/frameworks/base/11_0011-Allow-clipboard-access-to-intel-packages.patch deleted file mode 100644 index 0b5108fa16..0000000000 --- a/aosp_diff/preliminary/frameworks/base/11_0011-Allow-clipboard-access-to-intel-packages.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 31ea8acb731d616b2fffdcfa3092ef590ab4cf11 Mon Sep 17 00:00:00 2001 -From: Vinay Prasad Kompella -Date: Mon, 12 Jul 2021 11:37:51 +0530 -Subject: [PATCH] Allow clipboard access to intel packages - -Tracked-On: OAM-102872 -Signed-off-by: Vinay Prasad Kompella ---- - .../java/com/android/server/clipboard/ClipboardService.java | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java -index 093ecd57124f..b38201b0b68b 100644 ---- a/services/core/java/com/android/server/clipboard/ClipboardService.java -+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java -@@ -252,6 +252,11 @@ public class ClipboardService extends SystemService { - if (mWm.isUidFocused(Binder.getCallingUid())) { - return true; - } -+ // Allow clipboard access to intel packages marked as system -+ // and have the permissions granted -+ if (callingPackage.startsWith("com.intel.")) { -+ return true; -+ } - } - - return false; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/12_0012-Adds-GET_TASKS-permission-to-ClipboardAgent.patch b/aosp_diff/preliminary/frameworks/base/12_0012-Adds-GET_TASKS-permission-to-ClipboardAgent.patch deleted file mode 100644 index 9cf4de0261..0000000000 --- a/aosp_diff/preliminary/frameworks/base/12_0012-Adds-GET_TASKS-permission-to-ClipboardAgent.patch +++ /dev/null @@ -1,26 +0,0 @@ -From f8fabbe2dcfecc29e04a1c148eda3363b88925fa Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Tue, 23 May 2023 09:45:40 +0530 -Subject: [PATCH] Adds GET_TASKS permission to ClipboardAgent - -Tracked-On: OAM-104815 -Change-Id: Ied2041c2de8425703072bb7e16d928b3781d879f -Signed-off-by: ahs ---- - data/etc/privapp-permissions-platform.xml | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml -index 883d962611d1..c236e39045bf 100644 ---- a/data/etc/privapp-permissions-platform.xml -+++ b/data/etc/privapp-permissions-platform.xml -@@ -582,5 +582,6 @@ applications that come with the platform - - - -+ - - --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/22_0022-Display-is-not-alerted-for-message-in-sleep-mode.patch b/aosp_diff/preliminary/frameworks/base/22_0022-Display-is-not-alerted-for-message-in-sleep-mode.patch deleted file mode 100644 index 870b1c0fd1..0000000000 --- a/aosp_diff/preliminary/frameworks/base/22_0022-Display-is-not-alerted-for-message-in-sleep-mode.patch +++ /dev/null @@ -1,64 +0,0 @@ -From b6baab5f6b921be71fafd88250577095cd14664b Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Tue, 23 May 2023 09:53:44 +0530 -Subject: [PATCH] Display is not alerted for message in sleep mode. - -Wake Screen for notifications feature was not enabled, -So it was not waking up the screen. - -Enabled this feature and can be enable/disble from -Settings->Display->Lock screen option. - -Tracked-On: OAM-104595 -Change-Id: I922096b8a6d2f29baa2a15e43f0c331a0e2a4131 -Signed-off-by: Ankit Agrawal ---- - core/res/res/values/config.xml | 2 +- - packages/SettingsProvider/res/values/defaults.xml | 3 +++ - .../src/com/android/providers/settings/DatabaseHelper.java | 3 +++ - 3 files changed, 7 insertions(+), 1 deletion(-) - -diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml -index 50aec835cc31..b111896a2816 100644 ---- a/core/res/res/values/config.xml -+++ b/core/res/res/values/config.xml -@@ -2582,7 +2582,7 @@ - - Note that doze dreams are not subject to the same start conditions as ordinary dreams. - Doze dreams will run whenever the power manager is in a dozing state. --> -- -+ com.android.systemui/com.android.systemui.doze.DozeService - - -diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml -index a93cd62e6301..159e9ad8a0cf 100644 ---- a/packages/SettingsProvider/res/values/defaults.xml -+++ b/packages/SettingsProvider/res/values/defaults.xml -@@ -184,6 +184,9 @@ - - true - -+ -+ true -+ - - true - -diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java -index ed5654d4f259..61b2a6437fbe 100644 ---- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java -+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java -@@ -2367,6 +2367,9 @@ class DatabaseHelper extends SQLiteOpenHelper { - loadBooleanSetting(stmt, Settings.Secure.WAKE_GESTURE_ENABLED, - R.bool.def_wake_gesture_enabled); - -+ loadBooleanSetting(stmt, Settings.Secure.DOZE_ENABLED, -+ R.bool.def_doze_enabled); -+ - loadIntegerSetting(stmt, Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, - R.integer.def_lock_screen_show_notifications); - --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/24_0024--Hide-Android-data-obb-sanbox-on-shared-storage.bulletin.patch b/aosp_diff/preliminary/frameworks/base/24_0024--Hide-Android-data-obb-sanbox-on-shared-storage.bulletin.patch deleted file mode 100644 index 03893b77b1..0000000000 --- a/aosp_diff/preliminary/frameworks/base/24_0024--Hide-Android-data-obb-sanbox-on-shared-storage.bulletin.patch +++ /dev/null @@ -1,557 +0,0 @@ -From 4af5db76f25348849252e0b8a08f4a517ef842b7 Mon Sep 17 00:00:00 2001 -From: Sergey Nikolaienkov -Date: Sat, 1 Jul 2023 16:03:56 +0200 -Subject: [PATCH] "Hide" /Android/data|obb|sanbox/ on shared storage - -Implement shouldHideDocument() in the ExternalStorageProvider so that it -resitcts access to 'Android/data/', 'Android/obb/' and 'Android/sandbox' -on the integrated shared storage along with all their content and -subdirectories. - -Clean up the abstract FileSystemProvider, specifically all variants of -queryChildDocuments(). - -Bug: 200034476 -Bug: 220066255 -Bug: 283962634 -Test: make & flash systemimage, run manually -Test: atest ExternalStorageProviderTests -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7f5667bfafbd9b1b4d59c2cb15f9a3e07a559318) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:cf28630a3e286629ed7b13badd4fb0412564c0fd) -Merged-In: I48c2ce7ff2d7fc067961ea2af0ea63818316f086 -Change-Id: I48c2ce7ff2d7fc067961ea2af0ea63818316f086 ---- - .../internal/content/FileSystemProvider.java | 168 +++++++++-------- - .../ExternalStorageProvider.java | 173 +++++++++++------- - 2 files changed, 198 insertions(+), 143 deletions(-) - -diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java -index 58376a77c705..0801dd8c0bd8 100644 ---- a/core/java/com/android/internal/content/FileSystemProvider.java -+++ b/core/java/com/android/internal/content/FileSystemProvider.java -@@ -62,16 +62,14 @@ import java.nio.file.FileVisitor; - import java.nio.file.Files; - import java.nio.file.Path; - import java.nio.file.attribute.BasicFileAttributes; -+ import java.util.ArrayDeque; - import java.util.ArrayList; - import java.util.Arrays; --import java.util.Deque; --import java.util.LinkedList; - import java.util.List; - import java.util.Locale; -+import java.util.Queue; - import java.util.Set; - import java.util.concurrent.CopyOnWriteArrayList; --import java.util.function.Predicate; --import java.util.regex.Pattern; - - /** - * A helper class for {@link android.provider.DocumentsProvider} to perform file operations on local -@@ -89,6 +87,8 @@ public abstract class FileSystemProvider extends DocumentsProvider { - DocumentsContract.QUERY_ARG_LAST_MODIFIED_AFTER, - DocumentsContract.QUERY_ARG_MIME_TYPES); - -+ private static final int MAX_RESULTS_NUMBER = 23; -+ - private static String joinNewline(String... args) { - return TextUtils.join("\n", args); - } -@@ -375,62 +375,53 @@ public abstract class FileSystemProvider extends DocumentsProvider { - } - - /** -- * This method is similar to -- * {@link DocumentsProvider#queryChildDocuments(String, String[], String)}. This method returns -- * all children documents including hidden directories/files. -- * -- *

-- * In a scoped storage world, access to "Android/data" style directories are hidden for privacy -- * reasons. This method may show privacy sensitive data, so its usage should only be in -- * restricted modes. -- * -- * @param parentDocumentId the directory to return children for. -- * @param projection list of {@link Document} columns to put into the -- * cursor. If {@code null} all supported columns should be -- * included. -- * @param sortOrder how to order the rows, formatted as an SQL -- * {@code ORDER BY} clause (excluding the ORDER BY itself). -- * Passing {@code null} will use the default sort order, which -- * may be unordered. This ordering is a hint that can be used to -- * prioritize how data is fetched from the network, but UI may -- * always enforce a specific ordering -- * @throws FileNotFoundException when parent document doesn't exist or query fails -+ * WARNING: this method should really be {@code final}, but for the backward compatibility it's -+ * not; new classes that extend {@link FileSystemProvider} should override -+ * {@link #queryChildDocuments(String, String[], String, boolean)}, not this method. - */ -- protected Cursor queryChildDocumentsShowAll( -- String parentDocumentId, String[] projection, String sortOrder) -+ @Override -+ public Cursor queryChildDocuments(String documentId, String[] projection, String sortOrder) - throws FileNotFoundException { -- return queryChildDocuments(parentDocumentId, projection, sortOrder, File -> true); -+ return queryChildDocuments(documentId, projection, sortOrder, /* includeHidden */ false); - } - -+ /** -+ * This method is similar to {@link #queryChildDocuments(String, String[], String)}, however, it -+ * could return all content of the directory, including restricted (hidden) -+ * directories and files. -+ *

-+ * In the scoped storage world, some directories and files (e.g. {@code Android/data/} and -+ * {@code Android/obb/} on the external storage) are hidden for privacy reasons. -+ * Hence, this method may reveal privacy-sensitive data, thus should be used with extra care. -+ */ - @Override -- public Cursor queryChildDocuments( -- String parentDocumentId, String[] projection, String sortOrder) -- throws FileNotFoundException { -- // Access to some directories is hidden for privacy reasons. -- return queryChildDocuments(parentDocumentId, projection, sortOrder, this::shouldShow); -+ public final Cursor queryChildDocumentsForManage(String documentId, String[] projection, -+ String sortOrder) throws FileNotFoundException { -+ return queryChildDocuments(documentId, projection, sortOrder, /* includeHidden */ true); - } - -- private Cursor queryChildDocuments( -- String parentDocumentId, String[] projection, String sortOrder, -- @NonNull Predicate filter) throws FileNotFoundException { -- final File parent = getFileForDocId(parentDocumentId); -+ protected Cursor queryChildDocuments(String documentId, String[] projection, String sortOrder, -+ boolean includeHidden) throws FileNotFoundException { -+ final File parent = getFileForDocId(documentId); - final MatrixCursor result = new DirectoryCursor( -- resolveProjection(projection), parentDocumentId, parent); -+ resolveProjection(projection), documentId, parent); -+ -+ if (!parent.isDirectory()) { -+ Log.w(TAG, '"' + documentId + "\" is not a directory"); -+ return result; -+ } - -- if (!filter.test(parent)) { -- Log.w(TAG, "No permission to access parentDocumentId: " + parentDocumentId); -+ if (!includeHidden && shouldHideDocument(documentId)) { -+ Log.w(TAG, "Queried directory \"" + documentId + "\" is hidden"); - return result; - } - -- if (parent.isDirectory()) { -- for (File file : FileUtils.listFilesOrEmpty(parent)) { -- if (filter.test(file)) { -- includeFile(result, null, file); -- } -- } -- } else { -- Log.w(TAG, "parentDocumentId '" + parentDocumentId + "' is not Directory"); -+ for (File file : FileUtils.listFilesOrEmpty(parent)) { -+ if (!includeHidden && shouldHideDocument(file)) continue; -+ -+ includeFile(result, null, file); - } -+ - return result; - } - -@@ -452,23 +443,29 @@ public abstract class FileSystemProvider extends DocumentsProvider { - * - * @see ContentResolver#EXTRA_HONORED_ARGS - */ -- protected final Cursor querySearchDocuments( -- File folder, String[] projection, Set exclusion, Bundle queryArgs) -- throws FileNotFoundException { -+ protected final Cursor querySearchDocuments(File folder, String[] projection, -+ Set exclusion, Bundle queryArgs) throws FileNotFoundException { - final MatrixCursor result = new MatrixCursor(resolveProjection(projection)); -- final List pending = new ArrayList<>(); -- pending.add(folder); -- while (!pending.isEmpty() && result.getCount() < 24) { -- final File file = pending.remove(0); -- if (shouldHide(file)) continue; -+ -+ // We'll be a running a BFS here. -+ final Queue pending = new ArrayDeque<>(); -+ pending.offer(folder); -+ -+ while (!pending.isEmpty() && result.getCount() < MAX_RESULTS_NUMBER) { -+ final File file = pending.poll(); -+ -+ // Skip hidden documents (both files and directories) -+ if (shouldHideDocument(file)) continue; - - if (file.isDirectory()) { - for (File child : FileUtils.listFilesOrEmpty(file)) { -- pending.add(child); -+ pending.offer(child); - } - } -- if (!exclusion.contains(file.getAbsolutePath()) && matchSearchQueryArguments(file, -- queryArgs)) { -+ -+ if (exclusion.contains(file.getAbsolutePath())) continue; -+ -+ if (matchSearchQueryArguments(file, queryArgs)) { - includeFile(result, null, file); - } - } -@@ -612,26 +609,23 @@ public abstract class FileSystemProvider extends DocumentsProvider { - - final int flagIndex = ArrayUtils.indexOf(columns, Document.COLUMN_FLAGS); - if (flagIndex != -1) { -+ final boolean isDir = mimeType.equals(Document.MIME_TYPE_DIR); - int flags = 0; - if (file.canWrite()) { -- if (mimeType.equals(Document.MIME_TYPE_DIR)) { -+ flags |= Document.FLAG_SUPPORTS_DELETE; -+ flags |= Document.FLAG_SUPPORTS_RENAME; -+ flags |= Document.FLAG_SUPPORTS_MOVE; -+ if (isDir) { - flags |= Document.FLAG_DIR_SUPPORTS_CREATE; -- flags |= Document.FLAG_SUPPORTS_DELETE; -- flags |= Document.FLAG_SUPPORTS_RENAME; -- flags |= Document.FLAG_SUPPORTS_MOVE; -- -- if (shouldBlockFromTree(docId)) { -- flags |= Document.FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE; -- } -- - } else { - flags |= Document.FLAG_SUPPORTS_WRITE; -- flags |= Document.FLAG_SUPPORTS_DELETE; -- flags |= Document.FLAG_SUPPORTS_RENAME; -- flags |= Document.FLAG_SUPPORTS_MOVE; - } - } - -+ if (isDir && shouldBlockDirectoryFromTree(docId)) { -+ flags |= Document.FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE; -+ } -+ - if (mimeType.startsWith("image/")) { - flags |= Document.FLAG_SUPPORTS_THUMBNAIL; - } -@@ -664,22 +658,36 @@ public abstract class FileSystemProvider extends DocumentsProvider { - return row; - } - -- private static final Pattern PATTERN_HIDDEN_PATH = Pattern.compile( -- "(?i)^/storage/[^/]+/(?:[0-9]+/)?Android/(?:data|obb|sandbox)$"); -- - /** -- * In a scoped storage world, access to "Android/data" style directories are -- * hidden for privacy reasons. -+ * Some providers may want to restrict access to certain directories and files, -+ * e.g. "Android/data" and "Android/obb" on the shared storage for -+ * privacy reasons. -+ * Such providers should override this method. - */ -- protected boolean shouldHide(@NonNull File file) { -- return (PATTERN_HIDDEN_PATH.matcher(file.getAbsolutePath()).matches()); -+ protected boolean shouldHideDocument(@NonNull String documentId) -+ throws FileNotFoundException { -+ return false; - } - -- private boolean shouldShow(@NonNull File file) { -- return !shouldHide(file); -+ /** -+ * A variant of the {@link #shouldHideDocument(String)} that takes a {@link File} instead of -+ * a {@link String} {@code documentId}. -+ * -+ * @see #shouldHideDocument(String) -+ */ -+ protected final boolean shouldHideDocument(@NonNull File document) -+ throws FileNotFoundException { -+ return shouldHideDocument(getDocIdForFile(document)); - } - -- protected boolean shouldBlockFromTree(@NonNull String docId) { -+ /** -+ * @return if the directory that should be blocked from being selected when the user launches -+ * an {@link Intent#ACTION_OPEN_DOCUMENT_TREE} intent. -+ * -+ * @see Document#FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE -+ */ -+ protected boolean shouldBlockDirectoryFromTree(@NonNull String documentId) -+ throws FileNotFoundException { - return false; - } - -diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java -index 4c313b22f71e..3409c29d3c2c 100644 ---- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java -+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java -@@ -16,6 +16,8 @@ - - package com.android.externalstorage; - -+import static java.util.regex.Pattern.CASE_INSENSITIVE; -+ - import android.annotation.NonNull; - import android.annotation.Nullable; - import android.app.usage.StorageStatsManager; -@@ -64,7 +66,19 @@ import java.util.List; - import java.util.Locale; - import java.util.Objects; - import java.util.UUID; -- -+import java.util.regex.Pattern; -+ -+/** -+ * Presents content of the shared (a.k.a. "external") storage. -+ *

-+ * Starting with Android 11 (R), restricts access to the certain sections of the shared storage: -+ * {@code Android/data/}, {@code Android/obb/} and {@code Android/sandbox/}, that will be hidden in -+ * the DocumentsUI by default. -+ * See -+ * Storage updates in Android 11. -+ *

-+ * Documents ID format: {@code root:path/to/file}. -+ */ - public class ExternalStorageProvider extends FileSystemProvider { - private static final String TAG = "ExternalStorage"; - -@@ -75,7 +89,12 @@ public class ExternalStorageProvider extends FileSystemProvider { - private static final Uri BASE_URI = - new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY).build(); - -- // docId format: root:path/to/file -+ /** -+ * Regex for detecting {@code /Android/data/}, {@code /Android/obb/} and -+ * {@code /Android/sandbox/} along with all their subdirectories and content. -+ */ -+ private static final Pattern PATTERN_RESTRICTED_ANDROID_SUBTREES = -+ Pattern.compile("^Android/(?:data|obb|sandbox)(?:/.+)?", CASE_INSENSITIVE); - - private static final String[] DEFAULT_ROOT_PROJECTION = new String[] { - Root.COLUMN_ROOT_ID, Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE, -@@ -278,76 +297,91 @@ public class ExternalStorageProvider extends FileSystemProvider { - return projection != null ? projection : DEFAULT_ROOT_PROJECTION; - } - -+ /** -+ * Mark {@code Android/data/}, {@code Android/obb/} and {@code Android/sandbox/} on the -+ * integrated shared ("external") storage along with all their content and subdirectories as -+ * hidden. -+ */ - @Override -- public Cursor queryChildDocumentsForManage( -- String parentDocId, String[] projection, String sortOrder) -- throws FileNotFoundException { -- return queryChildDocumentsShowAll(parentDocId, projection, sortOrder); -+ protected boolean shouldHideDocument(@NonNull String documentId) { -+ // Don't need to hide anything on USB drives. -+ if (isOnRemovableUsbStorage(documentId)) { -+ return false; -+ } -+ -+ final String path = getPathFromDocId(documentId); -+ return PATTERN_RESTRICTED_ANDROID_SUBTREES.matcher(path).matches(); - } - - /** - * Check that the directory is the root of storage or blocked file from tree. -+ *

-+ * Note, that this is different from hidden documents: blocked documents WILL appear -+ * the UI, but the user WILL NOT be able to select them. - * -- * @param docId the docId of the directory to be checked -+ * @param documentId the docId of the directory to be checked - * @return true, should be blocked from tree. Otherwise, false. -+ * -+ * @see Document#FLAG_DIR_BLOCKS_OPEN_DOCUMENT_TREE - */ - @Override -- protected boolean shouldBlockFromTree(@NonNull String docId) { -- try { -- final File dir = getFileForDocId(docId, false /* visible */); -- -- // the file is null or it is not a directory -- if (dir == null || !dir.isDirectory()) { -- return false; -- } -+ protected boolean shouldBlockDirectoryFromTree(@NonNull String documentId) -+ throws FileNotFoundException { -+ final File dir = getFileForDocId(documentId, false); -+ // The file is null or it is not a directory -+ if (dir == null || !dir.isDirectory()) { -+ return false; -+ } - -- // Allow all directories on USB, including the root. -- try { -- RootInfo rootInfo = getRootFromDocId(docId); -- if ((rootInfo.flags & Root.FLAG_REMOVABLE_USB) == Root.FLAG_REMOVABLE_USB) { -- return false; -- } -- } catch (FileNotFoundException e) { -- Log.e(TAG, "Failed to determine rootInfo for docId"); -- } -+ // Allow all directories on USB, including the root. -+ if (isOnRemovableUsbStorage(documentId)) { -+ return false; -+ } - -- final String path = getPathFromDocId(docId); -+ // Get canonical(!) path. Note that this path will have neither leading nor training "/". -+ // This the root's path will be just an empty string. -+ final String path = getPathFromDocId(documentId); - -- // Block the root of the storage -- if (path.isEmpty()) { -- return true; -- } -+ // Block the root of the storage -+ if (path.isEmpty()) { -+ return true; -+ } - -- // Block Download folder from tree -- if (TextUtils.equals(Environment.DIRECTORY_DOWNLOADS.toLowerCase(Locale.ROOT), -- path.toLowerCase(Locale.ROOT))) { -- return true; -- } -+ // Block /Download/ and /Android/ folders from the tree. -+ if (equalIgnoringCase(path, Environment.DIRECTORY_DOWNLOADS) || -+ equalIgnoringCase(path, Environment.DIRECTORY_ANDROID)) { -+ return true; -+ } - -- // Block /Android -- if (TextUtils.equals(Environment.DIRECTORY_ANDROID.toLowerCase(Locale.ROOT), -- path.toLowerCase(Locale.ROOT))) { -- return true; -- } -+ // This shouldn't really make a difference, but just in case - let's block hidden -+ // directories as well. -+ if (shouldHideDocument(documentId)) { -+ return true; -+ } - -- // Block /Android/data, /Android/obb, /Android/sandbox and sub dirs -- if (shouldHide(dir)) { -- return true; -- } -+ return false; -+ } - -+ private boolean isOnRemovableUsbStorage(@NonNull String documentId) { -+ final RootInfo rootInfo; -+ try { -+ rootInfo = getRootFromDocId(documentId); -+ } catch (FileNotFoundException e) { -+ Log.e(TAG, "Failed to determine rootInfo for docId\"" + documentId + '"'); - return false; -- } catch (IOException e) { -- throw new IllegalArgumentException( -- "Failed to determine if " + docId + " should block from tree " + ": " + e); - } -+ -+ return (rootInfo.flags & Root.FLAG_REMOVABLE_USB) != 0; - } - -+ @NonNull - @Override -- protected String getDocIdForFile(File file) throws FileNotFoundException { -+ protected String getDocIdForFile(@NonNull File file) throws FileNotFoundException { - return getDocIdForFileMaybeCreate(file, false); - } - -- private String getDocIdForFileMaybeCreate(File file, boolean createNewDir) -+ @NonNull -+ private String getDocIdForFileMaybeCreate(@NonNull File file, boolean createNewDir) - throws FileNotFoundException { - String path = file.getAbsolutePath(); - -@@ -417,31 +451,33 @@ public class ExternalStorageProvider extends FileSystemProvider { - private File getFileForDocId(String docId, boolean visible, boolean mustExist) - throws FileNotFoundException { - RootInfo root = getRootFromDocId(docId); -- return buildFile(root, docId, visible, mustExist); -+ return buildFile(root, docId, mustExist); - } - -- private Pair resolveDocId(String docId, boolean visible) -- throws FileNotFoundException { -+ private Pair resolveDocId(String docId) throws FileNotFoundException { - RootInfo root = getRootFromDocId(docId); -- return Pair.create(root, buildFile(root, docId, visible, true)); -+ return Pair.create(root, buildFile(root, docId, /* mustExist */ true)); - } - - @VisibleForTesting -- static String getPathFromDocId(String docId) throws IOException { -+ static String getPathFromDocId(String docId) { - final int splitIndex = docId.indexOf(':', 1); - final String docIdPath = docId.substring(splitIndex + 1); -- // Get CanonicalPath and remove the first "/" -- final String canonicalPath = new File(docIdPath).getCanonicalPath().substring(1); - -- if (canonicalPath.isEmpty()) { -- return canonicalPath; -+ // Canonicalize path and strip the leading "/" -+ final String path; -+ try { -+ path = new File(docIdPath).getCanonicalPath().substring(1); -+ } catch (IOException e) { -+ Log.w(TAG, "Could not canonicalize \"" + docIdPath + '"'); -+ return ""; - } - -- // remove trailing "/" -- if (canonicalPath.charAt(canonicalPath.length() - 1) == '/') { -- return canonicalPath.substring(0, canonicalPath.length() - 1); -+ // Remove the trailing "/" as well. -+ if (!path.isEmpty() && path.charAt(path.length() - 1) == '/') { -+ return path.substring(0, path.length() - 1); - } else { -- return canonicalPath; -+ return path; - } - } - -@@ -460,7 +496,7 @@ public class ExternalStorageProvider extends FileSystemProvider { - return root; - } - -- private File buildFile(RootInfo root, String docId, boolean visible, boolean mustExist) -+ private File buildFile(RootInfo root, String docId, boolean mustExist) - throws FileNotFoundException { - final int splitIndex = docId.indexOf(':', 1); - final String path = docId.substring(splitIndex + 1); -@@ -544,7 +580,7 @@ public class ExternalStorageProvider extends FileSystemProvider { - @Override - public Path findDocumentPath(@Nullable String parentDocId, String childDocId) - throws FileNotFoundException { -- final Pair resolvedDocId = resolveDocId(childDocId, false); -+ final Pair resolvedDocId = resolveDocId(childDocId); - final RootInfo root = resolvedDocId.first; - File child = resolvedDocId.second; - -@@ -648,6 +684,13 @@ public class ExternalStorageProvider extends FileSystemProvider { - } - } - -+ /** -+ * Print the state into the given stream. -+ * Gets invoked when you run: -+ *

-+     * adb shell dumpsys activity provider com.android.externalstorage/.ExternalStorageProvider
-+     * 
-+ */ - @Override - public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { - final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ", 160); -@@ -731,4 +774,8 @@ public class ExternalStorageProvider extends FileSystemProvider { - } - return bundle; - } -+ -+ private static boolean equalIgnoringCase(@NonNull String a, @NonNull String b) { -+ return TextUtils.equals(a.toLowerCase(Locale.ROOT), b.toLowerCase(Locale.ROOT)); -+ } - } --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/base/25_0025-Unbind-TileService-onNullBinding.bulletin.patch b/aosp_diff/preliminary/frameworks/base/25_0025-Unbind-TileService-onNullBinding.bulletin.patch deleted file mode 100644 index 835e65c9db..0000000000 --- a/aosp_diff/preliminary/frameworks/base/25_0025-Unbind-TileService-onNullBinding.bulletin.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 7b7fff1eb5014d12200a32ff9047da396c7ab6a4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabi=C3=A1n=20Kozynski?= -Date: Fri, 13 Oct 2023 11:58:10 -0400 -Subject: [PATCH] Unbind TileService onNullBinding - -Test: atest TileLifecycleManagerTest -Test: manual: adb shell dumpsys activity service -Test: sts test -Bug: 300903792 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7cf363d1fe7c474120ae1c4a96c6adc4c8946d9f) -Merged-In: Ia8126ac65432b124683960e3ebf47301ba6172a1 -Change-Id: Ia8126ac65432b124683960e3ebf47301ba6172a1 ---- - .../qs/external/TileLifecycleManager.java | 5 ++++ - .../qs/external/TileLifecycleManagerTest.java | 24 +++++++++++++++++++ - 2 files changed, 29 insertions(+) - -diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java -index 2469a98140e3..3750c44a4923 100644 ---- a/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java -+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileLifecycleManager.java -@@ -280,6 +280,11 @@ public class TileLifecycleManager extends BroadcastReceiver implements - handlePendingMessages(); - } - -+ @Override -+ public void onNullBinding(ComponentName name) { -+ executeSetBindService(false); -+ } -+ - @Override - public void onServiceDisconnected(ComponentName name) { - if (DEBUG) Log.d(TAG, "onServiceDisconnected " + name); -diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java -index 67587e3a8914..37df93e4c809 100644 ---- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java -+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTest.java -@@ -373,6 +373,30 @@ public class TileLifecycleManagerTest extends SysuiTestCase { - verify(falseContext).bindServiceAsUser(any(), any(), eq(flags), any()); - } - -+ @Test -+ public void testNullBindingCallsUnbind() { -+ Context mockContext = mock(Context.class); -+ // Binding has to succeed -+ when(mockContext.bindServiceAsUser(any(), any(), anyInt(), any())).thenReturn(true); -+ TileLifecycleManager manager = new TileLifecycleManager(mHandler, mockContext, -+ mock(IQSService.class), -+ mMockPackageManagerAdapter, -+ mMockBroadcastDispatcher, -+ mTileServiceIntent, -+ mUser, -+ mExecutor); -+ -+ manager.executeSetBindService(true); -+ mExecutor.runAllReady(); -+ -+ ArgumentCaptor captor = ArgumentCaptor.forClass(ServiceConnection.class); -+ verify(mockContext).bindServiceAsUser(any(), captor.capture(), anyInt(), any()); -+ -+ captor.getValue().onNullBinding(mTileServiceComponentName); -+ mExecutor.runAllReady(); -+ verify(mockContext).unbindService(captor.getValue()); -+ } -+ - private void mockChangeEnabled(long changeId, boolean enabled) { - doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(), - any(UserHandle.class))); --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/base/27_0027-Enforce-permission-INJECT_EVENTS-for-injecting-to-input-filter-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/27_0027-Enforce-permission-INJECT_EVENTS-for-injecting-to-input-filter-.bulletin.patch deleted file mode 100644 index fc6b035233..0000000000 --- a/aosp_diff/preliminary/frameworks/base/27_0027-Enforce-permission-INJECT_EVENTS-for-injecting-to-input-filter-.bulletin.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 3e88d987235f5a2acd50a9b6bad78dbbf39cb079 Mon Sep 17 00:00:00 2001 -From: Daniel Norman -Date: Fri, 17 Nov 2023 20:53:05 +0000 -Subject: [PATCH] Enforce permission INJECT_EVENTS for injecting to input - filter. - -Bug: 309426390 -Test: atest CtsAccessibilityTestCases:AccessibilityManagerTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e83d6c801bb4f97b9b4b54280ac9e1486e622313) -Merged-In: I4a63583dcd1c7a7c388fb278ec1c1c53c135e934 -Change-Id: I4a63583dcd1c7a7c388fb278ec1c1c53c135e934 ---- - core/java/android/app/UiAutomationConnection.java | 5 +++++ - .../server/accessibility/AccessibilityManagerService.java | 2 ++ - 2 files changed, 7 insertions(+) - -diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java -index 34f0964cf823..9831885f291d 100644 ---- a/core/java/android/app/UiAutomationConnection.java -+++ b/core/java/android/app/UiAutomationConnection.java -@@ -183,6 +183,11 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { - - @Override - public void injectInputEventToInputFilter(InputEvent event) throws RemoteException { -+ synchronized (mLock) { -+ throwIfCalledByNotTrustedUidLocked(); -+ throwIfShutdownLocked(); -+ throwIfNotConnectedLocked(); -+ } - mAccessibilityManager.injectInputEventToInputFilter(event); - } - -diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -index fdb28ba9103e..531227947ba0 100644 ---- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -@@ -5232,6 +5232,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub - - @Override - public void injectInputEventToInputFilter(InputEvent event) { -+ mSecurityPolicy.enforceCallingPermission(Manifest.permission.INJECT_EVENTS, -+ "injectInputEventToInputFilter"); - synchronized (mLock) { - final long endMillis = - SystemClock.uptimeMillis() + WAIT_INPUT_FILTER_INSTALL_TIMEOUT_MS; --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/base/28_0028--RESTRICT-AUTOMERGE-Check-permission-of-Autofill-icon-URIs.bulletin.patch b/aosp_diff/preliminary/frameworks/base/28_0028--RESTRICT-AUTOMERGE-Check-permission-of-Autofill-icon-URIs.bulletin.patch deleted file mode 100644 index 25fa6e5aa8..0000000000 --- a/aosp_diff/preliminary/frameworks/base/28_0028--RESTRICT-AUTOMERGE-Check-permission-of-Autofill-icon-URIs.bulletin.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 55fc00a0788ea0995fe0851616b9ac21710a2931 Mon Sep 17 00:00:00 2001 -From: Tim Yu -Date: Tue, 12 Sep 2023 21:11:31 +0000 -Subject: [PATCH] [RESTRICT AUTOMERGE] Check permission of Autofill icon URIs - -* SaveUI's template -* Inline Suggestions slices - -Fixes: b/286235483 -Fixes: b/292104015 - -Test: atest CtsAutoFillServiceTestCases -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df893defcf8cc6e1e223111e79ad3daf0ec7cd8b) -Merged-In: I48879174664b70ced90492bb0991dc91cbf89b79 -Change-Id: I48879174664b70ced90492bb0991dc91cbf89b79 ---- - .../com/android/server/autofill/Helper.java | 48 ++++++++++++++++++- - .../RemoteInlineSuggestionViewConnector.java | 30 ++++++------ - .../android/server/autofill/ui/SaveUi.java | 3 +- - 3 files changed, 62 insertions(+), 19 deletions(-) - -diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java -index 7557071d0d4b..b93ee9b96e57 100644 ---- a/services/autofill/java/com/android/server/autofill/Helper.java -+++ b/services/autofill/java/com/android/server/autofill/Helper.java -@@ -25,8 +25,11 @@ import android.app.ActivityManager; - import android.app.assist.AssistStructure; - import android.app.assist.AssistStructure.ViewNode; - import android.app.assist.AssistStructure.WindowNode; -+import android.app.slice.Slice; -+import android.app.slice.SliceItem; - import android.content.ComponentName; - import android.content.Context; -+import android.graphics.drawable.Icon; - import android.hardware.display.DisplayManager; - import android.metrics.LogMaker; - import android.os.UserManager; -@@ -55,7 +58,6 @@ import java.util.ArrayList; - import java.util.Arrays; - import java.util.concurrent.atomic.AtomicBoolean; - -- - public final class Helper { - - private static final String TAG = "AutofillHelper"; -@@ -93,7 +95,7 @@ public final class Helper { - final AtomicBoolean permissionsOk = new AtomicBoolean(true); - - rView.visitUris(uri -> { -- int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri); -+ int uriOwnerId = android.content.ContentProvider.getUserIdFromUri(uri, userId); - boolean allowed = uriOwnerId == userId; - permissionsOk.set(allowed && permissionsOk.get()); - }); -@@ -125,6 +127,48 @@ public final class Helper { - return (ok ? rView : null); - } - -+ /** -+ * Checks the URI permissions of the icon in the slice, to see if the current userId is able to -+ * access it. -+ * -+ *

Returns null if slice contains user inaccessible icons -+ * -+ *

TODO: instead of returning a null Slice when the current userId cannot access an icon, -+ * return a reconstructed Slice without the icons. This is currently non-trivial since there are -+ * no public methods to generically add SliceItems to Slices -+ */ -+ public static @Nullable Slice sanitizeSlice(Slice slice) { -+ if (slice == null) { -+ return null; -+ } -+ -+ int userId = ActivityManager.getCurrentUser(); -+ -+ // Recontruct the Slice, filtering out bad icons -+ for (SliceItem sliceItem : slice.getItems()) { -+ if (!sliceItem.getFormat().equals(SliceItem.FORMAT_IMAGE)) { -+ // Not an image slice -+ continue; -+ } -+ -+ Icon icon = sliceItem.getIcon(); -+ if (icon.getType() != Icon.TYPE_URI -+ && icon.getType() != Icon.TYPE_URI_ADAPTIVE_BITMAP) { -+ // No URIs to sanitize -+ continue; -+ } -+ -+ int iconUriId = android.content.ContentProvider.getUserIdFromUri(icon.getUri(), userId); -+ -+ if (iconUriId != userId) { -+ Slog.w(TAG, "sanitizeSlice() user: " + userId + " cannot access icons in Slice"); -+ return null; -+ } -+ } -+ -+ return slice; -+ } -+ - - @Nullable - static AutofillId[] toArray(@Nullable ArraySet set) { -diff --git a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java -index 70443f9153d1..024de4e825aa 100644 ---- a/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java -+++ b/services/autofill/java/com/android/server/autofill/ui/RemoteInlineSuggestionViewConnector.java -@@ -27,6 +27,7 @@ import android.service.autofill.InlinePresentation; - import android.util.Slog; - - import com.android.server.LocalServices; -+import com.android.server.autofill.Helper; - import com.android.server.autofill.RemoteInlineSuggestionRenderService; - import com.android.server.inputmethod.InputMethodManagerInternal; - -@@ -39,24 +40,17 @@ import java.util.function.Consumer; - final class RemoteInlineSuggestionViewConnector { - private static final String TAG = RemoteInlineSuggestionViewConnector.class.getSimpleName(); - -- @Nullable -- private final RemoteInlineSuggestionRenderService mRemoteRenderService; -- @NonNull -- private final InlinePresentation mInlinePresentation; -- @Nullable -- private final IBinder mHostInputToken; -+ @Nullable private final RemoteInlineSuggestionRenderService mRemoteRenderService; -+ @NonNull private final InlinePresentation mInlinePresentation; -+ @Nullable private final IBinder mHostInputToken; - private final int mDisplayId; - private final int mUserId; - private final int mSessionId; - -- @NonNull -- private final Runnable mOnAutofillCallback; -- @NonNull -- private final Runnable mOnErrorCallback; -- @NonNull -- private final Runnable mOnInflateCallback; -- @NonNull -- private final Consumer mStartIntentSenderFromClientApp; -+ @NonNull private final Runnable mOnAutofillCallback; -+ @NonNull private final Runnable mOnErrorCallback; -+ @NonNull private final Runnable mOnInflateCallback; -+ @NonNull private final Consumer mStartIntentSenderFromClientApp; - - RemoteInlineSuggestionViewConnector( - @NonNull InlineFillUi.InlineFillUiInfo inlineFillUiInfo, -@@ -81,8 +75,12 @@ final class RemoteInlineSuggestionViewConnector { - * - * @return true if the call is made to the remote renderer service, false otherwise. - */ -- public boolean renderSuggestion(int width, int height, -- @NonNull IInlineSuggestionUiCallback callback) { -+ public boolean renderSuggestion( -+ int width, int height, @NonNull IInlineSuggestionUiCallback callback) { -+ if (Helper.sanitizeSlice(mInlinePresentation.getSlice()) == null) { -+ if (sDebug) Slog.d(TAG, "Skipped rendering inline suggestion."); -+ return false; -+ } - if (mRemoteRenderService != null) { - if (sDebug) Slog.d(TAG, "Request to recreate the UI"); - mRemoteRenderService.renderSuggestion(callback, mInlinePresentation, width, height, -diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -index 70382f1d5274..4488d86c60b5 100644 ---- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java -@@ -443,7 +443,8 @@ final class SaveUi { - } - final BatchUpdates batchUpdates = pair.second; - // First apply the updates... -- final RemoteViews templateUpdates = batchUpdates.getUpdates(); -+ final RemoteViews templateUpdates = -+ Helper.sanitizeRemoteView(batchUpdates.getUpdates()); - if (templateUpdates != null) { - if (sDebug) Slog.d(TAG, "Applying template updates for batch update #" + i); - templateUpdates.reapply(context, customSubtitleView); --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/base/29_0029-Always-sync-user-restriction-state-to-UserManager.bulletin.patch b/aosp_diff/preliminary/frameworks/base/29_0029-Always-sync-user-restriction-state-to-UserManager.bulletin.patch deleted file mode 100644 index 511c94ada5..0000000000 --- a/aosp_diff/preliminary/frameworks/base/29_0029-Always-sync-user-restriction-state-to-UserManager.bulletin.patch +++ /dev/null @@ -1,182 +0,0 @@ -From f516739398746fef7e0cf1437d9a40e2ad3c10bb Mon Sep 17 00:00:00 2001 -From: Jonathan Scott -Date: Tue, 21 Nov 2023 16:36:13 +0000 -Subject: [PATCH] Always sync user restriction state to UserManager - -On certain Android 14 builds, global restrictions set by the -DPC can errornously go into UserManager's local restriction -store, resulting in a bad state where they cannot be unset -in future. Fix this by always force syncing user restrictions -from the policy engine to the UserManager when a restriction is -being set or cleared by the DPC. The force sync ensures that both -local and global restriction states of UserManager are consistent -with policy engine, for the restriction that is being updated. - -Ran through the following manual tests: -1. (DO) Start with A14 bad build, set global restrictions - -> OTA to this fix - -> try clearing policy -2. (DO) Start with A14 bad build, set global restrictions - -> reboot device - -> OTA to this fix - -> try clearing policy -3. (DO) A13 with local & global restrictions set - -> OTA to A14 bad build - -> set same restrictions again - -> OTA to this fix - -> try clearing policy -4. (DO) A13 with local & global restrictions set - -> OTA to A14 bad build - -> reboot device - -> set same restrictions again - -> OTA to this fix - -> try clearing policy -5. (DO) A13 with local & global restrictions set - -> OTA to A14 bad build - -> OTA to this fix - -> try clearing policy -6. (DO) A13 with local & global restrictions set - -> OTA to A14 bad build - -> reboot device - -> OTA to this fix - -> try clearing policy -7. (DO) A13 with local & global restrictions set - -> OTA to this fix - -> try clearing policy -8. (BYOD PO) A13 with global restrictions set - -> OTA to A14 bad build - -> reboot device - -> OTA to this fix - -> try clearing policy -Case 1 & 2: fresh A14 setup -Case 3 & 4: OTA'ed devices with workaround applied -Case 5 & 6: OTA'ed devices without workaround applied -Case 7: directly OTA'ed to build with fix -Case 8: same as case 5 & 6 but on a BYOD PO device - -Bug: 311687929 -Bug: 299302474 -Test: btest a.d.c.PolicyEngineTest -Test: atest android.devicepolicy.cts.UserRestrictionsTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5394ddbee5dd88a35e2a9a8508dc260395895ac1) -Merged-In: I4d700bc42ec114d1c0fc86f230f7f7612819195c -Change-Id: I4d700bc42ec114d1c0fc86f230f7f7612819195c ---- - .../devicepolicy/DevicePolicyEngine.java | 66 +++++++++++++++++++ - 1 file changed, 66 insertions(+) - -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java -index 9c1d765fe0f9..9f65a33185b5 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyEngine.java -@@ -30,6 +30,7 @@ import android.annotation.NonNull; - import android.annotation.Nullable; - import android.app.AppGlobals; - import android.app.BroadcastOptions; -+import android.app.admin.BooleanPolicyValue; - import android.app.admin.DevicePolicyIdentifiers; - import android.app.admin.DevicePolicyManager; - import android.app.admin.DevicePolicyState; -@@ -133,6 +134,67 @@ final class DevicePolicyEngine { - mEnforcingAdmins = new SparseArray<>(); - } - -+ private void maybeForceEnforcementRefreshLocked(@NonNull PolicyDefinition policyDefinition) { -+ try { -+ if (shouldForceEnforcementRefresh(policyDefinition)) { -+ // This is okay because it's only true for user restrictions which are all -+ forceEnforcementRefreshLocked((PolicyDefinition) policyDefinition); -+ } -+ } catch (Throwable e) { -+ // Catch any possible exceptions just to be on the safe side -+ Log.e(TAG, "Exception throw during maybeForceEnforcementRefreshLocked", e); -+ } -+ } -+ -+ private boolean shouldForceEnforcementRefresh(@NonNull PolicyDefinition policyDefinition) { -+ // These are all "not nullable" but for the purposes of maximum safety for a lightly tested -+ // change we check here -+ if (policyDefinition == null) { -+ return false; -+ } -+ PolicyKey policyKey = policyDefinition.getPolicyKey(); -+ if (policyKey == null) { -+ return false; -+ } -+ -+ if (policyKey instanceof UserRestrictionPolicyKey) { -+ // b/307481299 We must force all user restrictions to re-sync local -+ // + global on each set/clear -+ return true; -+ } -+ -+ return false; -+ } -+ -+ private void forceEnforcementRefreshLocked(PolicyDefinition policyDefinition) { -+ Binder.withCleanCallingIdentity(() -> { -+ // Sync global state -+ PolicyValue globalValue = new BooleanPolicyValue(false); -+ try { -+ PolicyState policyState = getGlobalPolicyStateLocked(policyDefinition); -+ globalValue = policyState.getCurrentResolvedPolicy(); -+ } catch (IllegalArgumentException e) { -+ // Expected for local-only policies -+ } -+ -+ enforcePolicy(policyDefinition, globalValue, UserHandle.USER_ALL); -+ -+ // Loop through each user and sync that user's state -+ for (UserInfo user : mUserManager.getUsers()) { -+ PolicyValue localValue = new BooleanPolicyValue(false); -+ try { -+ PolicyState localPolicyState = getLocalPolicyStateLocked( -+ policyDefinition, user.id); -+ localValue = localPolicyState.getCurrentResolvedPolicy(); -+ } catch (IllegalArgumentException e) { -+ // Expected for global-only policies -+ } -+ -+ enforcePolicy(policyDefinition, localValue, user.id); -+ } -+ }); -+ } -+ - /** - * Set the policy for the provided {@code policyDefinition} (see {@link PolicyDefinition}) and - * {@code enforcingAdmin} to the provided {@code value}. -@@ -174,6 +236,7 @@ final class DevicePolicyEngine { - // No need to notify admins as no new policy is actually enforced, we're just filling in - // the data structures. - if (!skipEnforcePolicy) { -+ maybeForceEnforcementRefreshLocked(policyDefinition); - if (policyChanged) { - onLocalPolicyChangedLocked(policyDefinition, enforcingAdmin, userId); - } -@@ -262,6 +325,7 @@ final class DevicePolicyEngine { - Objects.requireNonNull(enforcingAdmin); - - synchronized (mLock) { -+ maybeForceEnforcementRefreshLocked(policyDefinition); - if (!hasLocalPolicyLocked(policyDefinition, userId)) { - return; - } -@@ -425,6 +489,7 @@ final class DevicePolicyEngine { - // No need to notify admins as no new policy is actually enforced, we're just filling in - // the data structures. - if (!skipEnforcePolicy) { -+ maybeForceEnforcementRefreshLocked(policyDefinition); - if (policyChanged) { - onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin); - } -@@ -474,6 +539,7 @@ final class DevicePolicyEngine { - PolicyState policyState = getGlobalPolicyStateLocked(policyDefinition); - boolean policyChanged = policyState.removePolicy(enforcingAdmin); - -+ maybeForceEnforcementRefreshLocked(policyDefinition); - if (policyChanged) { - onGlobalPolicyChangedLocked(policyDefinition, enforcingAdmin); - } --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/30_0030-Validate-package-names-passed-to-the-installer-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/30_0030-Validate-package-names-passed-to-the-installer-.bulletin.patch deleted file mode 100644 index 116c418012..0000000000 --- a/aosp_diff/preliminary/frameworks/base/30_0030-Validate-package-names-passed-to-the-installer-.bulletin.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 954b2874b85b6cd0d6bb12cd677cdf22e5dbd77b Mon Sep 17 00:00:00 2001 -From: Alex Buynytskyy -Date: Thu, 2 Nov 2023 15:15:48 -0700 -Subject: [PATCH] Validate package names passed to the installer. - -Bug: 308989388 -Bug: 307532206 -Test: atest android.content.pm.cts.PackageManagerTest -(cherry picked from commit 1f445474cd1b902b2e7292a0d24e58f020fd51e7) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8705e13d7c0f9fd1d73ea66619dc28e966d98666) -Merged-In: I840c9c9af5752b3901d4719a13e7908faa43ab04 -Change-Id: I840c9c9af5752b3901d4719a13e7908faa43ab04 ---- - .../server/pm/PackageInstallerService.java | 29 +++++++++++++++---- - 1 file changed, 24 insertions(+), 5 deletions(-) - -diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java -index a9115371413c..b99e66f68038 100644 ---- a/services/core/java/com/android/server/pm/PackageInstallerService.java -+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java -@@ -55,6 +55,7 @@ import android.content.pm.PackageItemInfo; - import android.content.pm.PackageManager; - import android.content.pm.ParceledListSlice; - import android.content.pm.VersionedPackage; -+import android.content.pm.parsing.FrameworkParsingPackageUtils; - import android.graphics.Bitmap; - import android.net.Uri; - import android.os.Binder; -@@ -665,17 +666,22 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements - - // App package name and label length is restricted so that really long strings aren't - // written to disk. -- if (params.appPackageName != null -- && params.appPackageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) { -+ if (params.appPackageName != null && !isValidPackageName(params.appPackageName)) { - params.appPackageName = null; - } - - params.appLabel = TextUtils.trimToSize(params.appLabel, - PackageItemInfo.MAX_SAFE_LABEL_LENGTH); - -- String requestedInstallerPackageName = (params.installerPackageName != null -- && params.installerPackageName.length() < SessionParams.MAX_PACKAGE_NAME_LENGTH) -- ? params.installerPackageName : installerPackageName; -+ // Validate installer package name. -+ if (params.installerPackageName != null && !isValidPackageName( -+ params.installerPackageName)) { -+ params.installerPackageName = null; -+ } -+ -+ var requestedInstallerPackageName = -+ params.installerPackageName != null ? params.installerPackageName -+ : installerPackageName; - - if (PackageManagerServiceUtils.isRootOrShell(callingUid) - || PackageInstallerSession.isSystemDataLoaderInstallation(params) -@@ -1085,6 +1091,19 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements - return Integer.parseInt(sessionId); - } - -+ private static boolean isValidPackageName(@NonNull String packageName) { -+ if (packageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) { -+ return false; -+ } -+ // "android" is a valid package name -+ var errorMessage = FrameworkParsingPackageUtils.validateName( -+ packageName, /* requireSeparator= */ false, /* requireFilename */ true); -+ if (errorMessage != null) { -+ return false; -+ } -+ return true; -+ } -+ - private File getTmpSessionDir(String volumeUuid) { - return Environment.getDataAppDirectory(volumeUuid); - } --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/31_0031-Disallow-system-apps-to-be-installed-updated-as-instant-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/31_0031-Disallow-system-apps-to-be-installed-updated-as-instant-.bulletin.patch deleted file mode 100644 index 8a3a5043fe..0000000000 --- a/aosp_diff/preliminary/frameworks/base/31_0031-Disallow-system-apps-to-be-installed-updated-as-instant-.bulletin.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 022aff702e6607ca21d2eb6947f126e8d59a61c5 Mon Sep 17 00:00:00 2001 -From: Alex Buynytskyy -Date: Wed, 20 Dec 2023 01:50:36 +0000 -Subject: [PATCH] Disallow system apps to be installed/updated as instant. - -Bug: 299441833 -Test: atest android.content.pm.cts.PackageManagerTest -(cherry picked from commit 496e78a1951f2ed69290f03c5625c0f8382f4d31) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b978fdc30bf3dc8babb60ce88be47cf5b0622e84) -Merged-In: Idd89a6dd72f0e68259095f677185f0494391025c -Change-Id: Idd89a6dd72f0e68259095f677185f0494391025c ---- - .../core/java/com/android/server/pm/InstallPackageHelper.java | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java -index 622cb6609630..d0304b43215e 100644 ---- a/services/core/java/com/android/server/pm/InstallPackageHelper.java -+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java -@@ -668,6 +668,9 @@ final class InstallPackageHelper { - if (pkgSetting == null || pkgSetting.getPkg() == null) { - return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); - } -+ if (instantApp && (pkgSetting.isSystem() || pkgSetting.isUpdatedSystemApp())) { -+ return Pair.create(PackageManager.INSTALL_FAILED_INVALID_URI, intentSender); -+ } - if (!snapshot.canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) { - // only allow the existing package to be used if it's installed as a full - // application for at least one user --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/32_0032-Close-AccountManagerService-session-after-timeout-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/32_0032-Close-AccountManagerService-session-after-timeout-.bulletin.patch deleted file mode 100644 index d8c5484ea9..0000000000 --- a/aosp_diff/preliminary/frameworks/base/32_0032-Close-AccountManagerService-session-after-timeout-.bulletin.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 813900c458e9113e27d8d44a912b1c7ae281381c Mon Sep 17 00:00:00 2001 -From: Dmitry Dementyev -Date: Wed, 3 Jan 2024 09:26:56 -0800 -Subject: [PATCH] Close AccountManagerService.session after timeout. - -Bug: 303905130 -Bug: 316893159 -Test: manual -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bb53f192e0ceaa026a083da156ef0cb0140f0c09) -Merged-In: Ib4cebf1750fc6324dc1c8853e0d716ea5e8ec073 -Change-Id: Ib4cebf1750fc6324dc1c8853e0d716ea5e8ec073 ---- - .../android/server/accounts/AccountManagerService.java | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java -index 8e1e3d86146f..cba28f3a596f 100644 ---- a/services/core/java/com/android/server/accounts/AccountManagerService.java -+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java -@@ -189,6 +189,7 @@ public class AccountManagerService - - final MessageHandler mHandler; - -+ private static final int TIMEOUT_DELAY_MS = 1000 * 60 * 15; - // Messages that can be sent on mHandler - private static final int MESSAGE_TIMED_OUT = 3; - private static final int MESSAGE_COPY_SHARED_ACCOUNT = 4; -@@ -4903,6 +4904,7 @@ public class AccountManagerService - synchronized (mSessions) { - mSessions.put(toString(), this); - } -+ scheduleTimeout(); - if (response != null) { - try { - response.asBinder().linkToDeath(this, 0 /* flags */); -@@ -5070,6 +5072,11 @@ public class AccountManagerService - } - } - -+ private void scheduleTimeout() { -+ mHandler.sendMessageDelayed( -+ mHandler.obtainMessage(MESSAGE_TIMED_OUT, this), TIMEOUT_DELAY_MS); -+ } -+ - public void cancelTimeout() { - mHandler.removeMessages(MESSAGE_TIMED_OUT, this); - } -@@ -5107,6 +5114,9 @@ public class AccountManagerService - - public void onTimedOut() { - IAccountManagerResponse response = getResponseAndClose(); -+ if (Log.isLoggable(TAG, Log.VERBOSE)) { -+ Log.v(TAG, "Session.onTimedOut"); -+ } - if (response != null) { - try { - response.onError(AccountManager.ERROR_CODE_REMOTE_EXCEPTION, --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/33_0033-Revert-On-device-lockdown-always-show-the-keyguard.patch b/aosp_diff/preliminary/frameworks/base/33_0033-Revert-On-device-lockdown-always-show-the-keyguard.patch deleted file mode 100644 index 604bf0effe..0000000000 --- a/aosp_diff/preliminary/frameworks/base/33_0033-Revert-On-device-lockdown-always-show-the-keyguard.patch +++ /dev/null @@ -1,97 +0,0 @@ -From adbc2773a6ead84c1f57ea56c53654cfc2996c70 Mon Sep 17 00:00:00 2001 -From: Beverly Tai -Date: Thu, 14 Sep 2023 20:51:56 +0000 -Subject: [PATCH 1/6] Revert "On device lockdown, always show the keyguard" - -This reverts commit c851ef6d27bf7d3193c85170706a67fb6185981a. - -Reason for revert: b/300463732 regression -Bug: 300463732 -Bug: 218495634 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:eaa129138096bc00b663bca93a5af9786aa47154) -Merged-In: I314e5615b798487d9a965eaa0937905b65aa85fc -Change-Id: I314e5615b798487d9a965eaa0937905b65aa85fc ---- - .../keyguard/KeyguardViewMediator.java | 10 +------- - .../keyguard/KeyguardViewMediatorTest.java | 25 ------------------- - 2 files changed, 1 insertion(+), 34 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -index 1ae5d0a1a39d..becb10a31fc9 100644 ---- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -@@ -763,13 +763,6 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, - } - } - } -- -- @Override -- public void onStrongAuthStateChanged(int userId) { -- if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { -- doKeyguardLocked(null); -- } -- } - }; - - ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { -@@ -2189,8 +2182,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, - */ - private void doKeyguardLocked(Bundle options) { - // if another app is disabling us, don't show -- if (!mExternallyEnabled -- && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { -+ if (!mExternallyEnabled) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); - - mNeedToReshowWhenReenabled = true; -diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java -index fdeed9fddf7a..b1bfd7b73347 100644 ---- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java -+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java -@@ -177,8 +177,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { - private @Mock ShadeWindowLogger mShadeWindowLogger; - private @Captor ArgumentCaptor - mKeyguardStateControllerCallback; -- private @Captor ArgumentCaptor -- mKeyguardUpdateMonitorCallbackCaptor; - private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake(); - private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); - -@@ -238,25 +236,6 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { - KeyguardUpdateMonitor.setCurrentUser(mInitialUserId); - } - -- @Test -- @TestableLooper.RunWithLooper(setAsMainLooper = true) -- public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() { -- // GIVEN keyguard is not enabled and isn't showing -- mViewMediator.onSystemReady(); -- mViewMediator.setKeyguardEnabled(false); -- TestableLooper.get(this).processAllMessages(); -- captureKeyguardUpdateMonitorCallback(); -- assertFalse(mViewMediator.isShowingAndNotOccluded()); -- -- // WHEN lockdown occurs -- when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true); -- mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0); -- -- // THEN keyguard is shown -- TestableLooper.get(this).processAllMessages(); -- assertTrue(mViewMediator.isShowingAndNotOccluded()); -- } -- - @Test - @TestableLooper.RunWithLooper(setAsMainLooper = true) - public void doNotHideKeyguard_whenLockdown_onKeyguardNotEnabledExternally() { -@@ -1023,8 +1002,4 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { - private void captureKeyguardStateControllerCallback() { - verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture()); - } -- -- private void captureKeyguardUpdateMonitorCallback() { -- verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture()); -- } - } --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/34_0034-Updated-always-show-the-keyguard-on-device-lockdown.patch b/aosp_diff/preliminary/frameworks/base/34_0034-Updated-always-show-the-keyguard-on-device-lockdown.patch deleted file mode 100644 index e7043c6bfb..0000000000 --- a/aosp_diff/preliminary/frameworks/base/34_0034-Updated-always-show-the-keyguard-on-device-lockdown.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0939f517df40dc9c35d08f686bfda566e60e6261 Mon Sep 17 00:00:00 2001 -From: Beverly Tai -Date: Tue, 19 Sep 2023 20:54:47 +0000 -Subject: [PATCH 2/6] Updated: always show the keyguard on device lockdown - -Additionally, don't hide keyguard when it's disabled if the user has locked -down the device. - -Manual test steps: - 1. Enable app pinning and disable "Ask for PIN before unpinning" setting - 2. Pin an app (ie: Settings) - 3. Lockdown from the power menu - 4. Observe: user is brought to the keyguard, primary auth is - required to enter the device. - => After entering correct credential, the device is still in - app pinning mode. - => After entering an incorrect credential, the keyguard remains - showing and the user can attempt again up to the limit - -Bug: 300463732 -Bug: 218495634 -Test: atest KeyguardViewMediatorTest -Test: manual -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:d9c7c85c52c007fdedb177b9f5f98821d0a76090) -Merged-In: I70fdae80f717712b3dfc9df54b9649959b4bb8f0 -Change-Id: I70fdae80f717712b3dfc9df54b9649959b4bb8f0 ---- - .../systemui/keyguard/KeyguardViewMediator.java | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -index becb10a31fc9..1f472e3f7e6c 100644 ---- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java -@@ -763,6 +763,13 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, - } - } - } -+ -+ @Override -+ public void onStrongAuthStateChanged(int userId) { -+ if (mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { -+ doKeyguardLocked(null); -+ } -+ } - }; - - ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { -@@ -2181,8 +2188,9 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable, - * Enable the keyguard if the settings are appropriate. - */ - private void doKeyguardLocked(Bundle options) { -- // if another app is disabling us, don't show -- if (!mExternallyEnabled) { -+ // if another app is disabling us, don't show unless we're in lockdown mode -+ if (!mExternallyEnabled -+ && !mLockPatternUtils.isUserInLockdown(KeyguardUpdateMonitor.getCurrentUser())) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); - - mNeedToReshowWhenReenabled = true; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/35_0035-RESTRICT-AUTOMERGE-Added-limitations-for-attribution.patch b/aosp_diff/preliminary/frameworks/base/35_0035-RESTRICT-AUTOMERGE-Added-limitations-for-attribution.patch deleted file mode 100644 index 7faa1084d0..0000000000 --- a/aosp_diff/preliminary/frameworks/base/35_0035-RESTRICT-AUTOMERGE-Added-limitations-for-attribution.patch +++ /dev/null @@ -1,95 +0,0 @@ -From ca0066e89695c867594d329fab33f4dd0c182329 Mon Sep 17 00:00:00 2001 -From: Kiran Ramachandra -Date: Tue, 19 Dec 2023 21:33:56 +0000 -Subject: [PATCH 3/6] RESTRICT AUTOMERGE Added limitations for attributions to - handle invalid cases - -Bug: 304983146 -Test: Modified and introduced new tests to verify change -> atest CtsAppOpsTestCases:AttributionTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2806d263c0b74da36d6d2bcc1583ea641266fd43) -Merged-In: Iee26fdb9cf1ca0fa8905e22732c32ec7d9b80fea -Change-Id: Iee26fdb9cf1ca0fa8905e22732c32ec7d9b80fea ---- - .../android/server/appop/AppOpsService.java | 38 +++++++++++++++++++ - .../pkg/component/ParsedAttributionImpl.java | 2 +- - 2 files changed, 39 insertions(+), 1 deletion(-) - -diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java -index a110169ac8c2..33655f748230 100644 ---- a/services/core/java/com/android/server/appop/AppOpsService.java -+++ b/services/core/java/com/android/server/appop/AppOpsService.java -@@ -2640,6 +2640,10 @@ public class AppOpsService extends IAppOpsService.Stub { - return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, - packageName); - } -+ if (proxyAttributionTag != null -+ && !isAttributionTagDefined(packageName, proxyPackageName, proxyAttributionTag)) { -+ proxyAttributionTag = null; -+ } - - synchronized (this) { - final Ops ops = getOpsLocked(uid, packageName, attributionTag, -@@ -3177,6 +3181,10 @@ public class AppOpsService extends IAppOpsService.Stub { - return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag, - packageName); - } -+ if (proxyAttributionTag != null -+ && !isAttributionTagDefined(packageName, proxyPackageName, proxyAttributionTag)) { -+ proxyAttributionTag = null; -+ } - - boolean isRestricted = false; - int startType = START_TYPE_FAILED; -@@ -3909,6 +3917,36 @@ public class AppOpsService extends IAppOpsService.Stub { - return false; - } - -+ /** -+ * Checks to see if the attribution tag is defined in either package or proxyPackage. -+ * This method is intended for ProxyAttributionTag validation and returns false -+ * if it does not exist in either one of them. -+ * -+ * @param packageName Name of the package -+ * @param proxyPackageName Name of the proxy package -+ * @param attributionTag attribution tag to be checked -+ * -+ * @return boolean specifying if attribution tag is valid or not -+ */ -+ private boolean isAttributionTagDefined(@Nullable String packageName, -+ @Nullable String proxyPackageName, -+ @Nullable String attributionTag) { -+ if (packageName == null) { -+ return false; -+ } else if (attributionTag == null) { -+ return true; -+ } -+ PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); -+ if (proxyPackageName != null) { -+ AndroidPackage proxyPkg = pmInt.getPackage(proxyPackageName); -+ if (proxyPkg != null && isAttributionInPackage(proxyPkg, attributionTag)) { -+ return true; -+ } -+ } -+ AndroidPackage pkg = pmInt.getPackage(packageName); -+ return isAttributionInPackage(pkg, attributionTag); -+ } -+ - /** - * Get (and potentially create) ops. - * -diff --git a/services/core/java/com/android/server/pm/pkg/component/ParsedAttributionImpl.java b/services/core/java/com/android/server/pm/pkg/component/ParsedAttributionImpl.java -index b59f511afa57..0917eb6ee43f 100644 ---- a/services/core/java/com/android/server/pm/pkg/component/ParsedAttributionImpl.java -+++ b/services/core/java/com/android/server/pm/pkg/component/ParsedAttributionImpl.java -@@ -38,7 +38,7 @@ import java.util.List; - public class ParsedAttributionImpl implements ParsedAttribution, Parcelable { - - /** Maximum amount of attributions per package */ -- static final int MAX_NUM_ATTRIBUTIONS = 10000; -+ static final int MAX_NUM_ATTRIBUTIONS = 1000; - - /** Tag of the attribution */ - private @NonNull String tag; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/36_0036-Don-t-store-invalid-pkgs-when-migrating-filters.patch b/aosp_diff/preliminary/frameworks/base/36_0036-Don-t-store-invalid-pkgs-when-migrating-filters.patch deleted file mode 100644 index 6f520ae50c..0000000000 --- a/aosp_diff/preliminary/frameworks/base/36_0036-Don-t-store-invalid-pkgs-when-migrating-filters.patch +++ /dev/null @@ -1,91 +0,0 @@ -From ef71c4ffedec38eb647824d533d13e39bea168c3 Mon Sep 17 00:00:00 2001 -From: Julia Reynolds -Date: Wed, 27 Dec 2023 11:26:49 -0500 -Subject: [PATCH 4/6] Don't store invalid pkgs when migrating filters - -Test: NotificationManagerServiceTest -Test: call method from test app, view policy xml file -Flag: none -Bug: 305926929 -(cherry picked from commit bfa04e208995b05eee2a5336667f4e2dcd19fd30) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:85ccbd33e3766bbd22ced332cb5b9e983c2707db) -Merged-In: Ib7fcb733edd2cf2cbac0a7699763a5fe993b467e -Change-Id: Ib7fcb733edd2cf2cbac0a7699763a5fe993b467e ---- - .../NotificationManagerService.java | 6 ++-- - .../NotificationManagerServiceTest.java | 35 +++++++++++++++++++ - 2 files changed, 39 insertions(+), 2 deletions(-) - -diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index e633ba6886d0..cddc71b621b9 100644 ---- a/services/core/java/com/android/server/notification/NotificationManagerService.java -+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java -@@ -4814,8 +4814,10 @@ public class NotificationManagerService extends SystemService { - for (int userId : mUm.getProfileIds(info.userid, false)) { - try { - int uid = getUidForPackageAndUser(pkg, UserHandle.of(userId)); -- VersionedPackage vp = new VersionedPackage(pkg, uid); -- nlf.addPackage(vp); -+ if (uid != INVALID_UID) { -+ VersionedPackage vp = new VersionedPackage(pkg, uid); -+ nlf.addPackage(vp); -+ } - } catch (Exception e) { - // pkg doesn't exist on that user; skip - } -diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -index 6a6fa3f91a22..e4950a2e947b 100755 ---- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -@@ -105,6 +105,7 @@ import static junit.framework.Assert.assertSame; - import static junit.framework.Assert.assertTrue; - import static junit.framework.Assert.fail; - -+import static org.junit.Assert.assertNotEquals; - import static org.junit.Assert.assertThrows; - import static org.mockito.ArgumentMatchers.isNull; - import static org.mockito.Matchers.anyBoolean; -@@ -10390,6 +10391,40 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { - assertTrue(captor.getValue().isPackageAllowed(new VersionedPackage("apples", 10000))); - } - -+ @Test -+ public void testMigrateNotificationFilter_invalidPackage() throws Exception { -+ int[] userIds = new int[] {mUserId, 1000}; -+ when(mUm.getProfileIds(anyInt(), anyBoolean())).thenReturn(userIds); -+ List disallowedApps = ImmutableList.of("apples", "bananas", "cherries"); -+ for (int userId : userIds) { -+ when(mPackageManager.getPackageUid("apples", 0, userId)).thenThrow( -+ new RemoteException("")); -+ when(mPackageManager.getPackageUid("bananas", 0, userId)).thenReturn(9000); -+ when(mPackageManager.getPackageUid("cherries", 0, userId)).thenReturn(9001); -+ } -+ -+ when(mListeners.getNotificationListenerFilter(any())).thenReturn( -+ new NotificationListenerFilter()); -+ -+ mBinderService.migrateNotificationFilter(null, -+ FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING, -+ disallowedApps); -+ -+ ArgumentCaptor captor = -+ ArgumentCaptor.forClass(NotificationListenerFilter.class); -+ verify(mListeners).setNotificationListenerFilter(any(), captor.capture()); -+ -+ assertEquals(FLAG_FILTER_TYPE_CONVERSATIONS | FLAG_FILTER_TYPE_ONGOING, -+ captor.getValue().getTypes()); -+ // valid values stay -+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("bananas", 9000))); -+ assertFalse(captor.getValue().isPackageAllowed(new VersionedPackage("cherries", 9001))); -+ // don't store invalid values -+ for (VersionedPackage vp : captor.getValue().getDisallowedPackages()) { -+ assertNotEquals("apples", vp.getPackageName()); -+ } -+ } -+ - @Test - public void testMigrateNotificationFilter_noPreexistingFilter() throws Exception { - int[] userIds = new int[] {mUserId}; --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/37_0037-isUserInLockDown-can-be-true-when-there-are-other-st.patch b/aosp_diff/preliminary/frameworks/base/37_0037-isUserInLockDown-can-be-true-when-there-are-other-st.patch deleted file mode 100644 index d0c650aac6..0000000000 --- a/aosp_diff/preliminary/frameworks/base/37_0037-isUserInLockDown-can-be-true-when-there-are-other-st.patch +++ /dev/null @@ -1,119 +0,0 @@ -From 5d06f04b6ccd4d085a96d2b784d17b5e82215d44 Mon Sep 17 00:00:00 2001 -From: Beverly -Date: Thu, 18 Jan 2024 20:13:52 +0000 -Subject: [PATCH 5/6] isUserInLockDown can be true when there are other strong - auth requirements - -Bug: 315206668 -Bug: 218495634 -Flag: None -Test: manual, atest LockPatternUtilsTest -(cherry picked from commit d341f1ecdb011d24b17358f115391b3f997cb179) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:93149616ba8255ec82877e43d4b41c2ebd6abf24) -Merged-In: I5e979a7822dd7254b4579ab28ecf96df1db44179 -Change-Id: I5e979a7822dd7254b4579ab28ecf96df1db44179 ---- - .../internal/widget/LockPatternUtils.java | 4 +- - .../internal/util/LockPatternUtilsTest.java | 39 ++++++++++++++++--- - 2 files changed, 36 insertions(+), 7 deletions(-) - -diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java -index 1b1efeed5ff2..2a7d8c8e5b58 100644 ---- a/core/java/com/android/internal/widget/LockPatternUtils.java -+++ b/core/java/com/android/internal/widget/LockPatternUtils.java -@@ -1402,8 +1402,8 @@ public class LockPatternUtils { - } - - public boolean isUserInLockdown(int userId) { -- return getStrongAuthForUser(userId) -- == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; -+ return (getStrongAuthForUser(userId) -+ & StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN) != 0; - } - - private static class WrappedCallback extends ICheckCredentialProgressCallback.Stub { -diff --git a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java -index 0b7019995acb..b4f76d1a5eaf 100644 ---- a/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java -+++ b/core/tests/utiltests/src/com/android/internal/util/LockPatternUtilsTest.java -@@ -20,7 +20,9 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_MANAGED; - import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; - - import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_TRUSTAGENT_EXPIRED; -+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; - import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT; -+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN; - - import static com.google.common.truth.Truth.assertThat; - -@@ -70,12 +72,15 @@ import java.util.List; - @SmallTest - public class LockPatternUtilsTest { - -+ private ILockSettings mLockSettings; -+ private static final int USER_ID = 1; - private static final int DEMO_USER_ID = 5; - - private LockPatternUtils mLockPatternUtils; - - private void configureTest(boolean isSecure, boolean isDemoUser, int deviceDemoMode) - throws Exception { -+ mLockSettings = Mockito.mock(ILockSettings.class); - final Context context = spy(new ContextWrapper(InstrumentationRegistry.getTargetContext())); - - final MockContentResolver cr = new MockContentResolver(context); -@@ -83,15 +88,14 @@ public class LockPatternUtilsTest { - when(context.getContentResolver()).thenReturn(cr); - Settings.Global.putInt(cr, Settings.Global.DEVICE_DEMO_MODE, deviceDemoMode); - -- final ILockSettings ils = Mockito.mock(ILockSettings.class); -- when(ils.getCredentialType(DEMO_USER_ID)).thenReturn( -+ when(mLockSettings.getCredentialType(DEMO_USER_ID)).thenReturn( - isSecure ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD - : LockPatternUtils.CREDENTIAL_TYPE_NONE); -- when(ils.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, DEMO_USER_ID)) -- .thenReturn((long) PASSWORD_QUALITY_MANAGED); -+ when(mLockSettings.getLong("lockscreen.password_type", PASSWORD_QUALITY_UNSPECIFIED, -+ DEMO_USER_ID)).thenReturn((long) PASSWORD_QUALITY_MANAGED); - // TODO(b/63758238): stop spying the class under test - mLockPatternUtils = spy(new LockPatternUtils(context)); -- when(mLockPatternUtils.getLockSettings()).thenReturn(ils); -+ when(mLockPatternUtils.getLockSettings()).thenReturn(mLockSettings); - doReturn(true).when(mLockPatternUtils).hasSecureLockScreen(); - - final UserInfo userInfo = Mockito.mock(UserInfo.class); -@@ -101,6 +105,31 @@ public class LockPatternUtilsTest { - when(context.getSystemService(Context.USER_SERVICE)).thenReturn(um); - } - -+ @Test -+ public void isUserInLockDown() throws Exception { -+ configureTest(true, false, 2); -+ -+ // GIVEN strong auth not required -+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn(STRONG_AUTH_NOT_REQUIRED); -+ -+ // THEN user isn't in lockdown -+ assertFalse(mLockPatternUtils.isUserInLockdown(USER_ID)); -+ -+ // GIVEN lockdown -+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn( -+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); -+ -+ // THEN user is in lockdown -+ assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID)); -+ -+ // GIVEN lockdown and lockout -+ when(mLockSettings.getStrongAuthForUser(USER_ID)).thenReturn( -+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN | STRONG_AUTH_REQUIRED_AFTER_LOCKOUT); -+ -+ // THEN user is in lockdown -+ assertTrue(mLockPatternUtils.isUserInLockdown(USER_ID)); -+ } -+ - @Test - public void isLockScreenDisabled_isDemoUser_true() throws Exception { - configureTest(false, true, 2); --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/38_0038-Stop-marking-apps-as-privileged-if-they-are-not-sign.patch b/aosp_diff/preliminary/frameworks/base/38_0038-Stop-marking-apps-as-privileged-if-they-are-not-sign.patch deleted file mode 100644 index 3c52880b4c..0000000000 --- a/aosp_diff/preliminary/frameworks/base/38_0038-Stop-marking-apps-as-privileged-if-they-are-not-sign.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 4be50b3bf64c638e44d96f010fed50c4b6f3ccfe Mon Sep 17 00:00:00 2001 -From: Alex Buynytskyy -Date: Thu, 4 Jan 2024 00:18:16 +0000 -Subject: [PATCH 6/6] Stop marking apps as privileged if they are not signed - properly. - -Fixes: 311374917 -Test: atest android.content.pm.cts.PackageManagerTest -(cherry picked from commit 3ee5dfdcba047051ce81dca0696d6ddfeafe2d98) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:06775341ad7d77410798f95117cbee7a1a02c201) -Merged-In: I5b5b81cf43b06837a22c8dfd170a112106dd64c1 -Change-Id: I5b5b81cf43b06837a22c8dfd170a112106dd64c1 ---- - .../java/com/android/server/pm/InstallPackageHelper.java | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java -index d0304b43215e..f26a9f8f3aed 100644 ---- a/services/core/java/com/android/server/pm/InstallPackageHelper.java -+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java -@@ -4742,7 +4742,9 @@ final class InstallPackageHelper { - - private void assertPackageWithSharedUserIdIsPrivileged(AndroidPackage pkg) - throws PackageManagerException { -- if (!AndroidPackageUtils.isPrivileged(pkg) && (pkg.getSharedUserId() != null)) { -+ if (!AndroidPackageUtils.isPrivileged(pkg) -+ && (pkg.getSharedUserId() != null) -+ && !pkg.isLeavingSharedUser()) { - SharedUserSetting sharedUserSetting = null; - try { - synchronized (mPm.mLock) { -@@ -4783,7 +4785,8 @@ final class InstallPackageHelper { - if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) - && !AndroidPackageUtils.isPrivileged(pkg) - && (pkg.getSharedUserId() != null) -- && !skipVendorPrivilegeScan) { -+ && !skipVendorPrivilegeScan -+ && !pkg.isLeavingSharedUser()) { - SharedUserSetting sharedUserSetting = null; - synchronized (mPm.mLock) { - try { --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/base/39_0039-Fix-security-vulnerability-that-creates-user-with-no.patch b/aosp_diff/preliminary/frameworks/base/39_0039-Fix-security-vulnerability-that-creates-user-with-no.patch deleted file mode 100644 index 33bb85b92b..0000000000 --- a/aosp_diff/preliminary/frameworks/base/39_0039-Fix-security-vulnerability-that-creates-user-with-no.patch +++ /dev/null @@ -1,362 +0,0 @@ -From cbdb5b032c29a2376906c8ffdfbf1817ddd3ebcf Mon Sep 17 00:00:00 2001 -From: Tetiana Meronyk -Date: Wed, 10 Jan 2024 16:25:13 +0000 -Subject: [PATCH] Fix security vulnerability that creates user with no - restrictions when accountOptions are too long. - -Bug: 293602970 -Test: atest UserManagerTest#testAddUserAccountData_validStringValuesAreSaved_validBundleIsSaved && atest UserManagerTest#testAddUserAccountData_invalidStringValuesAreTruncated_invalidBundleIsDropped -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:33a90988cf3b59a3b8dc9f699d155688be8d5623) -Merged-In: I23c971f671546ac085060add89485cfac6691ca3 -Change-Id: I23c971f671546ac085060add89485cfac6691ca3 ---- - core/java/android/os/PersistableBundle.java | 37 +++++++ - core/java/android/os/UserManager.java | 23 +++- - .../app/ConfirmUserCreationActivity.java | 12 +++ - .../android/server/pm/UserManagerService.java | 29 ++--- - .../server/pm/UserManagerServiceTest.java | 2 +- - .../android/server/pm/UserManagerTest.java | 102 ++++++++++++++++++ - 6 files changed, 188 insertions(+), 17 deletions(-) - -diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java -index 02704f5b346b..236194d16ad8 100644 ---- a/core/java/android/os/PersistableBundle.java -+++ b/core/java/android/os/PersistableBundle.java -@@ -294,6 +294,43 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa - XmlUtils.writeMapXml(mMap, out, this); - } - -+ /** -+ * Checks whether all keys and values are within the given character limit. -+ * Note: Maximum character limit of String that can be saved to XML as part of bundle is 65535. -+ * Otherwise IOException is thrown. -+ * @param limit length of String keys and values in the PersistableBundle, including nested -+ * PersistableBundles to check against. -+ * -+ * @hide -+ */ -+ public boolean isBundleContentsWithinLengthLimit(int limit) { -+ unparcel(); -+ if (mMap == null) { -+ return true; -+ } -+ for (int i = 0; i < mMap.size(); i++) { -+ if (mMap.keyAt(i) != null && mMap.keyAt(i).length() > limit) { -+ return false; -+ } -+ final Object value = mMap.valueAt(i); -+ if (value instanceof String && ((String) value).length() > limit) { -+ return false; -+ } else if (value instanceof String[]) { -+ String[] stringArray = (String[]) value; -+ for (int j = 0; j < stringArray.length; j++) { -+ if (stringArray[j] != null -+ && stringArray[j].length() > limit) { -+ return false; -+ } -+ } -+ } else if (value instanceof PersistableBundle -+ && !((PersistableBundle) value).isBundleContentsWithinLengthLimit(limit)) { -+ return false; -+ } -+ } -+ return true; -+ } -+ - /** @hide */ - static class MyReadMapCallback implements XmlUtils.ReadMapCallback { - @Override -diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java -index 2d217186c9c7..13df1ce54c9b 100644 ---- a/core/java/android/os/UserManager.java -+++ b/core/java/android/os/UserManager.java -@@ -103,6 +103,21 @@ public class UserManager { - /** Whether the device is in headless system user mode; null until cached. */ - private static Boolean sIsHeadlessSystemUser = null; - -+ /** Maximum length of username. -+ * @hide -+ */ -+ public static final int MAX_USER_NAME_LENGTH = 100; -+ -+ /** Maximum length of user property String value. -+ * @hide -+ */ -+ public static final int MAX_ACCOUNT_STRING_LENGTH = 500; -+ -+ /** Maximum length of account options String values. -+ * @hide -+ */ -+ public static final int MAX_ACCOUNT_OPTIONS_LENGTH = 1000; -+ - /** - * User type representing a {@link UserHandle#USER_SYSTEM system} user that is a human user. - * This type of user cannot be created; it can only pre-exist on first boot. -@@ -4213,15 +4228,15 @@ public class UserManager { - * This API should only be called if the current user is an {@link #isAdminUser() admin} user, - * as otherwise the returned intent will not be able to create a user. - * -- * @param userName Optional name to assign to the user. -+ * @param userName Optional name to assign to the user. Character limit is 100. - * @param accountName Optional account name that will be used by the setup wizard to initialize -- * the user. -+ * the user. Character limit is 500. - * @param accountType Optional account type for the account to be created. This is required -- * if the account name is specified. -+ * if the account name is specified. Character limit is 500. - * @param accountOptions Optional bundle of data to be passed in during account creation in the - * new user via {@link AccountManager#addAccount(String, String, String[], - * Bundle, android.app.Activity, android.accounts.AccountManagerCallback, -- * Handler)}. -+ * Handler)}. Character limit is 1000. - * @return An Intent that can be launched from an Activity. - * @see #USER_CREATION_FAILED_NOT_PERMITTED - * @see #USER_CREATION_FAILED_NO_MORE_USERS -diff --git a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java -index 0a28997885ff..b4e87498f09b 100644 ---- a/core/java/com/android/internal/app/ConfirmUserCreationActivity.java -+++ b/core/java/com/android/internal/app/ConfirmUserCreationActivity.java -@@ -116,6 +116,14 @@ public class ConfirmUserCreationActivity extends AlertActivity - if (cantCreateUser) { - setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED); - return null; -+ } else if (!(isUserPropertyWithinLimit(mUserName, UserManager.MAX_USER_NAME_LENGTH) -+ && isUserPropertyWithinLimit(mAccountName, UserManager.MAX_ACCOUNT_STRING_LENGTH) -+ && isUserPropertyWithinLimit(mAccountType, UserManager.MAX_ACCOUNT_STRING_LENGTH)) -+ || (mAccountOptions != null && !mAccountOptions.isBundleContentsWithinLengthLimit( -+ UserManager.MAX_ACCOUNT_OPTIONS_LENGTH))) { -+ setResult(UserManager.USER_CREATION_FAILED_NOT_PERMITTED); -+ Log.i(TAG, "User properties must not exceed their character limits"); -+ return null; - } else if (cantCreateAnyMoreUsers) { - setResult(UserManager.USER_CREATION_FAILED_NO_MORE_USERS); - return null; -@@ -144,4 +152,8 @@ public class ConfirmUserCreationActivity extends AlertActivity - } - finish(); - } -+ -+ private boolean isUserPropertyWithinLimit(String property, int limit) { -+ return property == null || property.length() <= limit; -+ } - } -diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java -index a959fc10db49..d295976b5536 100644 ---- a/services/core/java/com/android/server/pm/UserManagerService.java -+++ b/services/core/java/com/android/server/pm/UserManagerService.java -@@ -285,8 +285,6 @@ public class UserManagerService extends IUserManager.Stub { - - private static final int USER_VERSION = 11; - -- private static final int MAX_USER_STRING_LENGTH = 500; -- - private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms - - static final int WRITE_USER_MSG = 1; -@@ -4262,16 +4260,18 @@ public class UserManagerService extends IUserManager.Stub { - if (userData.persistSeedData) { - if (userData.seedAccountName != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_NAME, -- truncateString(userData.seedAccountName)); -+ truncateString(userData.seedAccountName, -+ UserManager.MAX_ACCOUNT_STRING_LENGTH)); - } - if (userData.seedAccountType != null) { - serializer.attribute(null, ATTR_SEED_ACCOUNT_TYPE, -- truncateString(userData.seedAccountType)); -+ truncateString(userData.seedAccountType, -+ UserManager.MAX_ACCOUNT_STRING_LENGTH)); - } - } - if (userInfo.name != null) { - serializer.startTag(null, TAG_NAME); -- serializer.text(truncateString(userInfo.name)); -+ serializer.text(truncateString(userInfo.name, UserManager.MAX_USER_NAME_LENGTH)); - serializer.endTag(null, TAG_NAME); - } - synchronized (mRestrictionsLock) { -@@ -4320,11 +4320,11 @@ public class UserManagerService extends IUserManager.Stub { - serializer.endDocument(); - } - -- private String truncateString(String original) { -- if (original == null || original.length() <= MAX_USER_STRING_LENGTH) { -+ private String truncateString(String original, int limit) { -+ if (original == null || original.length() <= limit) { - return original; - } -- return original.substring(0, MAX_USER_STRING_LENGTH); -+ return original.substring(0, limit); - } - - /* -@@ -4772,7 +4772,7 @@ public class UserManagerService extends IUserManager.Stub { - @UserIdInt int parentId, boolean preCreate, @Nullable String[] disallowedPackages, - @NonNull TimingsTraceAndSlog t, @Nullable Object token) - throws UserManager.CheckedUserOperationException { -- String truncatedName = truncateString(name); -+ String truncatedName = truncateString(name, UserManager.MAX_USER_NAME_LENGTH); - final UserTypeDetails userTypeDetails = mUserTypes.get(userType); - if (userTypeDetails == null) { - throwCheckedUserOperationException( -@@ -6379,9 +6379,14 @@ public class UserManagerService extends IUserManager.Stub { - Slog.e(LOG_TAG, "No such user for settings seed data u=" + userId); - return; - } -- userData.seedAccountName = truncateString(accountName); -- userData.seedAccountType = truncateString(accountType); -- userData.seedAccountOptions = accountOptions; -+ userData.seedAccountName = truncateString(accountName, -+ UserManager.MAX_ACCOUNT_STRING_LENGTH); -+ userData.seedAccountType = truncateString(accountType, -+ UserManager.MAX_ACCOUNT_STRING_LENGTH); -+ if (accountOptions != null && accountOptions.isBundleContentsWithinLengthLimit( -+ UserManager.MAX_ACCOUNT_OPTIONS_LENGTH)) { -+ userData.seedAccountOptions = accountOptions; -+ } - userData.persistSeedData = persist; - } - if (persist) { -diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java -index 6acba3a52cbf..809fa167cfe4 100644 ---- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java -+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java -@@ -408,7 +408,7 @@ public final class UserManagerServiceTest { - @Test - public void testCreateUserWithLongName_TruncatesName() { - UserInfo user = mUms.createUserWithThrow(generateLongString(), USER_TYPE_FULL_SECONDARY, 0); -- assertThat(user.name.length()).isEqualTo(500); -+ assertThat(user.name.length()).isEqualTo(UserManager.MAX_USER_NAME_LENGTH); - UserInfo user1 = mUms.createUserWithThrow("Test", USER_TYPE_FULL_SECONDARY, 0); - assertThat(user1.name.length()).isEqualTo(4); - } -diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java -index dc86e5fbe1f3..8af2e2b42570 100644 ---- a/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java -+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerTest.java -@@ -19,6 +19,7 @@ package com.android.server.pm; - import static com.google.common.truth.Truth.assertThat; - import static com.google.common.truth.Truth.assertWithMessage; - -+import static org.junit.Assert.assertTrue; - import static org.junit.Assert.fail; - import static org.junit.Assume.assumeTrue; - import static org.testng.Assert.assertThrows; -@@ -31,6 +32,7 @@ import android.content.pm.UserInfo; - import android.content.pm.UserProperties; - import android.content.res.Resources; - import android.os.Bundle; -+import android.os.PersistableBundle; - import android.os.UserHandle; - import android.os.UserManager; - import android.platform.test.annotations.Postsubmit; -@@ -1431,6 +1433,106 @@ public final class UserManagerTest { - assertThat(userInfo.name).isEqualTo(newName); - } - -+ @Test -+ public void testAddUserAccountData_validStringValuesAreSaved_validBundleIsSaved() { -+ assumeManagedUsersSupported(); -+ -+ String userName = "User"; -+ String accountName = "accountName"; -+ String accountType = "accountType"; -+ String arrayKey = "StringArrayKey"; -+ String stringKey = "StringKey"; -+ String intKey = "IntKey"; -+ String nestedBundleKey = "PersistableBundleKey"; -+ String value1 = "Value 1"; -+ String value2 = "Value 2"; -+ String value3 = "Value 3"; -+ -+ UserInfo userInfo = mUserManager.createUser(userName, -+ UserManager.USER_TYPE_FULL_SECONDARY, 0); -+ -+ PersistableBundle accountOptions = new PersistableBundle(); -+ String[] stringArray = {value1, value2}; -+ accountOptions.putInt(intKey, 1234); -+ PersistableBundle nested = new PersistableBundle(); -+ nested.putString(stringKey, value3); -+ accountOptions.putPersistableBundle(nestedBundleKey, nested); -+ accountOptions.putStringArray(arrayKey, stringArray); -+ -+ mUserManager.clearSeedAccountData(); -+ mUserManager.setSeedAccountData(mContext.getUserId(), accountName, -+ accountType, accountOptions); -+ -+ //assert userName accountName and accountType were saved correctly -+ assertTrue(mUserManager.getUserInfo(userInfo.id).name.equals(userName)); -+ assertTrue(mUserManager.getSeedAccountName().equals(accountName)); -+ assertTrue(mUserManager.getSeedAccountType().equals(accountType)); -+ -+ //assert bundle with correct values was added -+ assertThat(mUserManager.getSeedAccountOptions().containsKey(arrayKey)).isTrue(); -+ assertThat(mUserManager.getSeedAccountOptions().getPersistableBundle(nestedBundleKey) -+ .getString(stringKey)).isEqualTo(value3); -+ assertThat(mUserManager.getSeedAccountOptions().getStringArray(arrayKey)[0]) -+ .isEqualTo(value1); -+ -+ mUserManager.removeUser(userInfo.id); -+ } -+ -+ @Test -+ public void testAddUserAccountData_invalidStringValuesAreTruncated_invalidBundleIsDropped() { -+ assumeManagedUsersSupported(); -+ -+ String tooLongString = generateLongString(); -+ String userName = "User " + tooLongString; -+ String accountType = "Account Type " + tooLongString; -+ String accountName = "accountName " + tooLongString; -+ String arrayKey = "StringArrayKey"; -+ String stringKey = "StringKey"; -+ String intKey = "IntKey"; -+ String nestedBundleKey = "PersistableBundleKey"; -+ String value1 = "Value 1"; -+ String value2 = "Value 2"; -+ -+ UserInfo userInfo = mUserManager.createUser(userName, -+ UserManager.USER_TYPE_FULL_SECONDARY, 0); -+ -+ PersistableBundle accountOptions = new PersistableBundle(); -+ String[] stringArray = {value1, value2}; -+ accountOptions.putInt(intKey, 1234); -+ PersistableBundle nested = new PersistableBundle(); -+ nested.putString(stringKey, tooLongString); -+ accountOptions.putPersistableBundle(nestedBundleKey, nested); -+ accountOptions.putStringArray(arrayKey, stringArray); -+ mUserManager.clearSeedAccountData(); -+ mUserManager.setSeedAccountData(mContext.getUserId(), accountName, -+ accountType, accountOptions); -+ -+ //assert userName was truncated -+ assertTrue(mUserManager.getUserInfo(userInfo.id).name.length() -+ == UserManager.MAX_USER_NAME_LENGTH); -+ -+ //assert accountName and accountType got truncated -+ assertTrue(mUserManager.getSeedAccountName().length() -+ == UserManager.MAX_ACCOUNT_STRING_LENGTH); -+ assertTrue(mUserManager.getSeedAccountType().length() -+ == UserManager.MAX_ACCOUNT_STRING_LENGTH); -+ -+ //assert bundle with invalid values was dropped -+ assertThat(mUserManager.getSeedAccountOptions() == null).isTrue(); -+ -+ mUserManager.removeUser(userInfo.id); -+ } -+ -+ private String generateLongString() { -+ String partialString = "Test Name Test Name Test Name Test Name Test Name Test Name Test " -+ + "Name Test Name Test Name Test Name "; //String of length 100 -+ StringBuilder resultString = new StringBuilder(); -+ for (int i = 0; i < 600; i++) { -+ resultString.append(partialString); -+ } -+ return resultString.toString(); -+ } -+ - private boolean isPackageInstalledForUser(String packageName, int userId) { - try { - return mPackageManager.getPackageInfoAsUser(packageName, 0, userId) != null; --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/40_0040-Prioritize-system-toasts.bulletin.patch b/aosp_diff/preliminary/frameworks/base/40_0040-Prioritize-system-toasts.bulletin.patch deleted file mode 100644 index 645c1cc81c..0000000000 --- a/aosp_diff/preliminary/frameworks/base/40_0040-Prioritize-system-toasts.bulletin.patch +++ /dev/null @@ -1,170 +0,0 @@ -From b9f175fb1f5ccc5ccf9bfd666286061633bccab2 Mon Sep 17 00:00:00 2001 -From: Valentin Iftime -Date: Mon, 16 Oct 2023 09:29:17 +0200 -Subject: [PATCH] Prioritize system toasts - - Insert toasts from system packages at the front of the queue - to ensure that apps can't spam with toast to delay system toasts from showing. - Also increase Clipboard paste warning toasts length to LENGTH_LONG. - -Test: atest NotificationManagerServiceTest -Bug: 293301736 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:939612739c280b0204fe36d7549a77b94d55f3db) -Merged-In: I13547f853476bc88d12026c545aba9f857ce8724 -Change-Id: I13547f853476bc88d12026c545aba9f857ce8724 ---- - .../server/clipboard/ClipboardService.java | 4 +- - .../NotificationManagerService.java | 32 ++++++++- - .../NotificationManagerServiceTest.java | 68 +++++++++++++++++++ - 3 files changed, 100 insertions(+), 4 deletions(-) - -diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java -index 4b8b43134e6c..b4e27d7f3f4e 100644 ---- a/services/core/java/com/android/server/clipboard/ClipboardService.java -+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java -@@ -1415,11 +1415,11 @@ public class ClipboardService extends SystemService { - .getDrawable(R.drawable.ic_safety_protection); - toastToShow = Toast.makeCustomToastWithIcon(toastContext, - UiThread.get().getLooper(), message, -- Toast.LENGTH_SHORT, safetyProtectionIcon); -+ Toast.LENGTH_LONG, safetyProtectionIcon); - } else { - toastToShow = Toast.makeText( - toastContext, UiThread.get().getLooper(), message, -- Toast.LENGTH_SHORT); -+ Toast.LENGTH_LONG); - } - toastToShow.show(); - } -diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index d997c8940b2f..20cf8c0e021d 100644 ---- a/services/core/java/com/android/server/notification/NotificationManagerService.java -+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java -@@ -3383,8 +3383,19 @@ public class NotificationManagerService extends SystemService { - null /* options */); - record = getToastRecord(callingUid, callingPid, pkg, isSystemToast, token, - text, callback, duration, windowToken, displayId, textCallback); -- mToastQueue.add(record); -- index = mToastQueue.size() - 1; -+ -+ // Insert system toasts at the front of the queue -+ int systemToastInsertIdx = mToastQueue.size(); -+ if (isSystemToast) { -+ systemToastInsertIdx = getInsertIndexForSystemToastLocked(); -+ } -+ if (systemToastInsertIdx < mToastQueue.size()) { -+ index = systemToastInsertIdx; -+ mToastQueue.add(index, record); -+ } else { -+ mToastQueue.add(record); -+ index = mToastQueue.size() - 1; -+ } - keepProcessAliveForToastIfNeededLocked(callingPid); - } - // If it's at index 0, it's the current toast. It doesn't matter if it's -@@ -3400,6 +3411,23 @@ public class NotificationManagerService extends SystemService { - } - } - -+ @GuardedBy("mToastQueue") -+ private int getInsertIndexForSystemToastLocked() { -+ // If there are other system toasts: insert after the last one -+ int idx = 0; -+ for (ToastRecord r : mToastQueue) { -+ if (idx == 0 && mIsCurrentToastShown) { -+ idx++; -+ continue; -+ } -+ if (!r.isSystemToast) { -+ return idx; -+ } -+ idx++; -+ } -+ return idx; -+ } -+ - private boolean checkCanEnqueueToast(String pkg, int callingUid, int displayId, - boolean isAppRenderedToast, boolean isSystemToast) { - final boolean isPackageSuspended = isPackagePaused(pkg); -diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -index c31d0d778025..30501fc9b2ca 100755 ---- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -@@ -7594,6 +7594,74 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { - assertEquals(NotificationManagerService.MAX_PACKAGE_TOASTS, mService.mToastQueue.size()); - } - -+ @Test -+ public void testPrioritizeSystemToasts() throws Exception { -+ // Insert non-system toasts -+ final String testPackage = "testPackageName"; -+ assertEquals(0, mService.mToastQueue.size()); -+ mService.isSystemUid = false; -+ mService.isSystemAppId = false; -+ setToastRateIsWithinQuota(true); -+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackage, false); -+ -+ // package is not suspended -+ when(mPackageManager.isPackageSuspendedForUser(testPackage, mUserId)) -+ .thenReturn(false); -+ -+ INotificationManager nmService = (INotificationManager) mService.mService; -+ -+ // Enqueue maximum number of toasts for test package -+ for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) { -+ enqueueTextToast(testPackage, "Text"); -+ } -+ -+ // Enqueue system toast -+ final String testPackageSystem = "testPackageNameSystem"; -+ mService.isSystemUid = true; -+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem, false); -+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem, mUserId)) -+ .thenReturn(false); -+ -+ enqueueToast(testPackageSystem, new TestableToastCallback()); -+ -+ // System toast is inserted at the front of the queue, behind current showing toast -+ assertEquals(testPackageSystem, mService.mToastQueue.get(1).pkg); -+ } -+ -+ @Test -+ public void testPrioritizeSystemToasts_enqueueAfterExistingSystemToast() throws Exception { -+ // Insert system toasts -+ final String testPackageSystem1 = "testPackageNameSystem1"; -+ assertEquals(0, mService.mToastQueue.size()); -+ mService.isSystemUid = true; -+ setToastRateIsWithinQuota(true); -+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem1, false); -+ -+ // package is not suspended -+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem1, mUserId)) -+ .thenReturn(false); -+ -+ INotificationManager nmService = (INotificationManager) mService.mService; -+ -+ // Enqueue maximum number of toasts for test package -+ for (int i = 0; i < NotificationManagerService.MAX_PACKAGE_TOASTS; i++) { -+ enqueueTextToast(testPackageSystem1, "Text"); -+ } -+ -+ // Enqueue another system toast -+ final String testPackageSystem2 = "testPackageNameSystem2"; -+ mService.isSystemUid = true; -+ setIfPackageHasPermissionToAvoidToastRateLimiting(testPackageSystem2, false); -+ when(mPackageManager.isPackageSuspendedForUser(testPackageSystem2, mUserId)) -+ .thenReturn(false); -+ -+ enqueueToast(testPackageSystem2, new TestableToastCallback()); -+ -+ // System toast is inserted at the back of the queue, after the other system toasts -+ assertEquals(testPackageSystem2, -+ mService.mToastQueue.get(mService.mToastQueue.size() - 1).pkg); -+ } -+ - private void setAppInForegroundForToasts(int uid, boolean inForeground) { - int importance = (inForeground) ? IMPORTANCE_FOREGROUND : IMPORTANCE_NONE; - when(mActivityManager.getUidImportance(mUid)).thenReturn(importance); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/41_0041-Added-throttle-when-reporting-shortcut-usage.bulletin.patch b/aosp_diff/preliminary/frameworks/base/41_0041-Added-throttle-when-reporting-shortcut-usage.bulletin.patch deleted file mode 100644 index a104172828..0000000000 --- a/aosp_diff/preliminary/frameworks/base/41_0041-Added-throttle-when-reporting-shortcut-usage.bulletin.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 6dc0f712dbe795fdd8b563b1fddbd1c0efe17e91 Mon Sep 17 00:00:00 2001 -From: Pinyao Ting -Date: Thu, 30 Nov 2023 23:12:39 +0000 -Subject: [PATCH] Added throttle when reporting shortcut usage - -Bug: 304290201 -Test: manual -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:bd88f35c6797b1795d1150af92760531ff73f14f) -Merged-In: I96370cbd4f6a55f894c1a93307e5f82dfd394652 -Change-Id: I96370cbd4f6a55f894c1a93307e5f82dfd394652 ---- - .../android/server/pm/ShortcutPackage.java | 32 +++++++++++ - .../android/server/pm/ShortcutService.java | 18 ++---- - .../server/pm/ShortcutManagerTest1.java | 55 ++++++++++++++++++- - .../server/pm/ShortcutManagerTest2.java | 2 + - 4 files changed, 92 insertions(+), 15 deletions(-) - -diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java -index 8456927b2cdf..00da2439ced8 100644 ---- a/services/core/java/com/android/server/pm/ShortcutPackage.java -+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java -@@ -33,6 +33,7 @@ import android.app.appsearch.SearchResult; - import android.app.appsearch.SearchResults; - import android.app.appsearch.SearchSpec; - import android.app.appsearch.SetSchemaRequest; -+import android.app.usage.UsageStatsManagerInternal; - import android.content.ComponentName; - import android.content.Intent; - import android.content.IntentFilter; -@@ -47,6 +48,7 @@ import android.graphics.drawable.Icon; - import android.os.Binder; - import android.os.PersistableBundle; - import android.os.StrictMode; -+import android.os.SystemClock; - import android.text.format.Formatter; - import android.util.ArrayMap; - import android.util.ArraySet; -@@ -160,6 +162,9 @@ class ShortcutPackage extends ShortcutPackageItem { - private static final String KEY_BITMAPS = "bitmaps"; - private static final String KEY_BITMAP_BYTES = "bitmapBytes"; - -+ @VisibleForTesting -+ public static final int REPORT_USAGE_BUFFER_SIZE = 3; -+ - private final Executor mExecutor; - - /** -@@ -195,6 +200,9 @@ class ShortcutPackage extends ShortcutPackageItem { - - private long mLastKnownForegroundElapsedTime; - -+ @GuardedBy("mLock") -+ private List mLastReportedTime = new ArrayList<>(); -+ - @GuardedBy("mLock") - private boolean mIsAppSearchSchemaUpToDate; - -@@ -1677,6 +1685,30 @@ class ShortcutPackage extends ShortcutPackageItem { - return condition[0]; - } - -+ void reportShortcutUsed(@NonNull final UsageStatsManagerInternal usageStatsManagerInternal, -+ @NonNull final String shortcutId) { -+ synchronized (mLock) { -+ final long currentTS = SystemClock.elapsedRealtime(); -+ final ShortcutService s = mShortcutUser.mService; -+ if (mLastReportedTime.isEmpty() -+ || mLastReportedTime.size() < REPORT_USAGE_BUFFER_SIZE) { -+ mLastReportedTime.add(currentTS); -+ } else if (currentTS - mLastReportedTime.get(0) > s.mSaveDelayMillis) { -+ mLastReportedTime.remove(0); -+ mLastReportedTime.add(currentTS); -+ } else { -+ return; -+ } -+ final long token = s.injectClearCallingIdentity(); -+ try { -+ usageStatsManagerInternal.reportShortcutUsage(getPackageName(), shortcutId, -+ getUser().getUserId()); -+ } finally { -+ s.injectRestoreCallingIdentity(token); -+ } -+ } -+ } -+ - public void dump(@NonNull PrintWriter pw, @NonNull String prefix, DumpFilter filter) { - pw.println(); - -diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java -index 365f332aff29..4fb14216baef 100644 ---- a/services/core/java/com/android/server/pm/ShortcutService.java -+++ b/services/core/java/com/android/server/pm/ShortcutService.java -@@ -369,7 +369,7 @@ public class ShortcutService extends IShortcutService.Stub { - private CompressFormat mIconPersistFormat; - private int mIconPersistQuality; - -- private int mSaveDelayMillis; -+ int mSaveDelayMillis; - - private final IPackageManager mIPackageManager; - private final PackageManagerInternal mPackageManagerInternal; -@@ -2282,7 +2282,7 @@ public class ShortcutService extends IShortcutService.Stub { - - packageShortcutsChanged(ps, changedShortcuts, removedShortcuts); - -- reportShortcutUsedInternal(packageName, shortcut.getId(), userId); -+ ps.reportShortcutUsed(mUsageStatsManagerInternal, shortcut.getId()); - - verifyStates(); - } -@@ -2686,25 +2686,17 @@ public class ShortcutService extends IShortcutService.Stub { - Slog.d(TAG, String.format("reportShortcutUsed: Shortcut %s package %s used on user %d", - shortcutId, packageName, userId)); - } -+ final ShortcutPackage ps; - synchronized (mLock) { - throwIfUserLockedL(userId); -- final ShortcutPackage ps = getPackageShortcutsForPublisherLocked(packageName, userId); -+ ps = getPackageShortcutsForPublisherLocked(packageName, userId); - if (ps.findShortcutById(shortcutId) == null) { - Log.w(TAG, String.format("reportShortcutUsed: package %s doesn't have shortcut %s", - packageName, shortcutId)); - return; - } - } -- reportShortcutUsedInternal(packageName, shortcutId, userId); -- } -- -- private void reportShortcutUsedInternal(String packageName, String shortcutId, int userId) { -- final long token = injectClearCallingIdentity(); -- try { -- mUsageStatsManagerInternal.reportShortcutUsage(packageName, shortcutId, userId); -- } finally { -- injectRestoreCallingIdentity(token); -- } -+ ps.reportShortcutUsed(mUsageStatsManagerInternal, shortcutId); - } - - @Override -diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java -index 7c1845fcd54e..77e3a988790f 100644 ---- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java -+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java -@@ -404,8 +404,8 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { - - public void testPushDynamicShortcut() { - // Change the max number of shortcuts. -- mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5"); -- -+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=5," -+ + ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1"); - setCaller(CALLING_PACKAGE_1, USER_0); - - final ShortcutInfo s1 = makeShortcut("s1"); -@@ -543,6 +543,57 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest { - eq(CALLING_PACKAGE_1), eq("s9"), eq(USER_0)); - } - -+ public void testPushDynamicShortcut_CallsToUsageStatsManagerAreThrottled() -+ throws InterruptedException { -+ mService.updateConfigurationLocked( -+ ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=500"); -+ -+ // Verify calls to UsageStatsManagerInternal#reportShortcutUsage are throttled. -+ setCaller(CALLING_PACKAGE_1, USER_0); -+ for (int i = 0; i < ShortcutPackage.REPORT_USAGE_BUFFER_SIZE; i++) { -+ final ShortcutInfo si = makeShortcut("s" + i); -+ mManager.pushDynamicShortcut(si); -+ } -+ verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( -+ eq(CALLING_PACKAGE_1), eq("s1"), eq(USER_0)); -+ Mockito.reset(mMockUsageStatsManagerInternal); -+ for (int i = ShortcutPackage.REPORT_USAGE_BUFFER_SIZE; i <= 10; i++) { -+ final ShortcutInfo si = makeShortcut("s" + i); -+ mManager.pushDynamicShortcut(si); -+ } -+ verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( -+ any(), any(), anyInt()); -+ -+ // Verify pkg2 isn't blocked by pkg1, but consecutive calls from pkg2 are throttled as well. -+ setCaller(CALLING_PACKAGE_2, USER_0); -+ for (int i = 0; i < ShortcutPackage.REPORT_USAGE_BUFFER_SIZE; i++) { -+ final ShortcutInfo si = makeShortcut("s" + i); -+ mManager.pushDynamicShortcut(si); -+ } -+ verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( -+ eq(CALLING_PACKAGE_2), eq("s1"), eq(USER_0)); -+ Mockito.reset(mMockUsageStatsManagerInternal); -+ for (int i = ShortcutPackage.REPORT_USAGE_BUFFER_SIZE; i <= 10; i++) { -+ final ShortcutInfo si = makeShortcut("s" + i); -+ mManager.pushDynamicShortcut(si); -+ } -+ verify(mMockUsageStatsManagerInternal, times(0)).reportShortcutUsage( -+ any(), any(), anyInt()); -+ -+ Mockito.reset(mMockUsageStatsManagerInternal); -+ // Let time passes which resets the throttle -+ Thread.sleep(505); -+ // Verify UsageStatsManagerInternal#reportShortcutUsed can be called again -+ setCaller(CALLING_PACKAGE_1, USER_0); -+ mManager.pushDynamicShortcut(makeShortcut("s10")); -+ setCaller(CALLING_PACKAGE_2, USER_0); -+ mManager.pushDynamicShortcut(makeShortcut("s10")); -+ verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( -+ eq(CALLING_PACKAGE_1), any(), eq(USER_0)); -+ verify(mMockUsageStatsManagerInternal, times(1)).reportShortcutUsage( -+ eq(CALLING_PACKAGE_2), any(), eq(USER_0)); -+ } -+ - public void testUnlimitedCalls() { - setCaller(CALLING_PACKAGE_1, USER_0); - -diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java -index 1cfaf7c83584..27c981aba85c 100644 ---- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java -+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java -@@ -2175,6 +2175,8 @@ public class ShortcutManagerTest2 extends BaseShortcutManagerTest { - - public void testReportShortcutUsed() { - mRunningUsers.put(USER_10, true); -+ mService.updateConfigurationLocked( -+ ShortcutService.ConfigConstants.KEY_SAVE_DELAY_MILLIS + "=1"); - - runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { - reset(mMockUsageStatsManagerInternal); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/42_0042-Verify-URI-permission-for-channel-sound-update-from-Notification.bulletin.patch b/aosp_diff/preliminary/frameworks/base/42_0042-Verify-URI-permission-for-channel-sound-update-from-Notification.bulletin.patch deleted file mode 100644 index 36d36f5b9a..0000000000 --- a/aosp_diff/preliminary/frameworks/base/42_0042-Verify-URI-permission-for-channel-sound-update-from-Notification.bulletin.patch +++ /dev/null @@ -1,137 +0,0 @@ -From f428043dbaafa5437d69ef5fa63d9fba39b851e8 Mon Sep 17 00:00:00 2001 -From: Valentin Iftime -Date: Thu, 1 Feb 2024 13:58:49 +0100 -Subject: [PATCH] Verify URI permission for channel sound update from - NotificationListenerService - - Check that a privileged NotificationListenerService (CDM) has the permission to access the sound URI - when updating a notification channel. - -Test: atest com.android.server.notification.NotificationManagerServiceTest#testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission -Bug: 317357401 -(cherry picked from commit 9b7bbbf5ad542ecf9ecbf8cd819b468791b443c0) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:71cfb89a1cdaf743b7b67c724dfbbaa0cca98efc) -Merged-In: Ic7d2e96e43565e98d2aa29b8f2ba35c142387ba9 -Change-Id: Ic7d2e96e43565e98d2aa29b8f2ba35c142387ba9 ---- - .../NotificationManagerService.java | 22 +++++++ - .../NotificationManagerServiceTest.java | 63 +++++++++++++++++++ - 2 files changed, 85 insertions(+) - -diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java -index 20cf8c0e021d..f1c2f7b92f5d 100644 ---- a/services/core/java/com/android/server/notification/NotificationManagerService.java -+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java -@@ -5772,6 +5772,10 @@ public class NotificationManagerService extends SystemService { - Objects.requireNonNull(user); - - verifyPrivilegedListener(token, user, false); -+ -+ final NotificationChannel originalChannel = mPreferencesHelper.getNotificationChannel( -+ pkg, getUidForPackageAndUser(pkg, user), channel.getId(), true); -+ verifyPrivilegedListenerUriPermission(Binder.getCallingUid(), channel, originalChannel); - updateNotificationChannelInt(pkg, getUidForPackageAndUser(pkg, user), channel, true); - } - -@@ -5863,6 +5867,24 @@ public class NotificationManagerService extends SystemService { - } - } - -+ private void verifyPrivilegedListenerUriPermission(int sourceUid, -+ @NonNull NotificationChannel updateChannel, -+ @Nullable NotificationChannel originalChannel) { -+ // Check that the NLS has the required permissions to access the channel -+ final Uri soundUri = updateChannel.getSound(); -+ final Uri originalSoundUri = -+ (originalChannel != null) ? originalChannel.getSound() : null; -+ if (soundUri != null && !Objects.equals(originalSoundUri, soundUri)) { -+ Binder.withCleanCallingIdentity(() -> { -+ mUgmInternal.checkGrantUriPermission(sourceUid, null, -+ ContentProvider.getUriWithoutUserId(soundUri), -+ Intent.FLAG_GRANT_READ_URI_PERMISSION, -+ ContentProvider.getUserIdFromUri(soundUri, -+ UserHandle.getUserId(sourceUid))); -+ }); -+ } -+ } -+ - private int getUidForPackageAndUser(String pkg, UserHandle user) throws RemoteException { - int uid = INVALID_UID; - final long identity = Binder.clearCallingIdentity(); -diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -index 30501fc9b2ca..d42700752ba9 100755 ---- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java -@@ -3587,6 +3587,69 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { - eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); - } - -+ @Test -+ public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission() -+ throws Exception { -+ mService.setPreferencesHelper(mPreferencesHelper); -+ when(mCompanionMgr.getAssociations(PKG, mUserId)) -+ .thenReturn(singletonList(mock(AssociationInfo.class))); -+ when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), -+ eq(mTestNotificationChannel.getId()), anyBoolean())) -+ .thenReturn(mTestNotificationChannel); -+ -+ final Uri soundUri = Uri.parse("content://media/test/sound/uri"); -+ final NotificationChannel updatedNotificationChannel = new NotificationChannel( -+ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); -+ updatedNotificationChannel.setSound(soundUri, -+ updatedNotificationChannel.getAudioAttributes()); -+ -+ doThrow(new SecurityException("no access")).when(mUgmInternal) -+ .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), -+ anyInt(), eq(Process.myUserHandle().getIdentifier())); -+ -+ assertThrows(SecurityException.class, -+ () -> mBinderService.updateNotificationChannelFromPrivilegedListener(null, PKG, -+ Process.myUserHandle(), updatedNotificationChannel)); -+ -+ verify(mPreferencesHelper, never()).updateNotificationChannel( -+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean()); -+ -+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), -+ eq(Process.myUserHandle()), eq(mTestNotificationChannel), -+ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); -+ } -+ -+ @Test -+ public void testUpdateNotificationChannelFromPrivilegedListener_noSoundUriPermission_sameSound() -+ throws Exception { -+ mService.setPreferencesHelper(mPreferencesHelper); -+ when(mCompanionMgr.getAssociations(PKG, mUserId)) -+ .thenReturn(singletonList(mock(AssociationInfo.class))); -+ when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(), -+ eq(mTestNotificationChannel.getId()), anyBoolean())) -+ .thenReturn(mTestNotificationChannel); -+ -+ final Uri soundUri = Settings.System.DEFAULT_NOTIFICATION_URI; -+ final NotificationChannel updatedNotificationChannel = new NotificationChannel( -+ TEST_CHANNEL_ID, TEST_CHANNEL_ID, IMPORTANCE_DEFAULT); -+ updatedNotificationChannel.setSound(soundUri, -+ updatedNotificationChannel.getAudioAttributes()); -+ -+ doThrow(new SecurityException("no access")).when(mUgmInternal) -+ .checkGrantUriPermission(eq(Process.myUid()), any(), eq(soundUri), -+ anyInt(), eq(Process.myUserHandle().getIdentifier())); -+ -+ mBinderService.updateNotificationChannelFromPrivilegedListener( -+ null, PKG, Process.myUserHandle(), updatedNotificationChannel); -+ -+ verify(mPreferencesHelper, times(1)).updateNotificationChannel( -+ anyString(), anyInt(), any(), anyBoolean(), anyInt(), anyBoolean()); -+ -+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG), -+ eq(Process.myUserHandle()), eq(mTestNotificationChannel), -+ eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED)); -+ } -+ - @Test - public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception { - mService.setPreferencesHelper(mPreferencesHelper); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/43_0043-Check-for-NLS-bind-permission-when-rebinding-services.bulletin.patch b/aosp_diff/preliminary/frameworks/base/43_0043-Check-for-NLS-bind-permission-when-rebinding-services.bulletin.patch deleted file mode 100644 index 586d9bd4cd..0000000000 --- a/aosp_diff/preliminary/frameworks/base/43_0043-Check-for-NLS-bind-permission-when-rebinding-services.bulletin.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 0a645bd7c46ffdff58a71e18b775e9816d69e1d2 Mon Sep 17 00:00:00 2001 -From: Valentin Iftime -Date: Thu, 22 Feb 2024 10:51:58 +0100 -Subject: [PATCH] Check for NLS bind permission when rebinding services - - Also, after updating packages with NLS components, check - the approved services and remove from approved list if missing permissions. - -Test: atest ManagedServicesTest -Bug: 321707289 - -(cherry picked from commit 24b13a64f9f5e5aa7f45a2132806d6c74e2c62dc) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4d4224c1b9f87a156324153854a1567e842ecb22) -Merged-In: I11901755ec430c6e3145def9d67e4e63cda00806 -Change-Id: I11901755ec430c6e3145def9d67e4e63cda00806 ---- - .../server/notification/ManagedServices.java | 51 +++++++++++++++-- - .../notification/ManagedServicesTest.java | 57 +++++++++++++++++++ - 2 files changed, 104 insertions(+), 4 deletions(-) - -diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java -index 12fc263e1c8c..98b288cd7676 100644 ---- a/services/core/java/com/android/server/notification/ManagedServices.java -+++ b/services/core/java/com/android/server/notification/ManagedServices.java -@@ -939,6 +939,23 @@ abstract public class ManagedServices { - return false; - } - -+ protected boolean isPackageOrComponentAllowedWithPermission(ComponentName component, -+ int userId) { -+ if (!(isPackageOrComponentAllowed(component.flattenToString(), userId) -+ || isPackageOrComponentAllowed(component.getPackageName(), userId))) { -+ return false; -+ } -+ return componentHasBindPermission(component, userId); -+ } -+ -+ private boolean componentHasBindPermission(ComponentName component, int userId) { -+ ServiceInfo info = getServiceInfo(component, userId); -+ if (info == null) { -+ return false; -+ } -+ return mConfig.bindPermission.equals(info.permission); -+ } -+ - boolean isPackageOrComponentUserSet(String pkgOrComponent, int userId) { - synchronized (mApproved) { - ArraySet services = mUserSetServices.get(userId); -@@ -1000,6 +1017,7 @@ abstract public class ManagedServices { - for (int uid : uidList) { - if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) { - anyServicesInvolved = true; -+ trimApprovedListsForInvalidServices(pkgName, UserHandle.getUserId(uid)); - } - } - } -@@ -1132,8 +1150,7 @@ abstract public class ManagedServices { - - synchronized (mMutex) { - if (enabled) { -- if (isPackageOrComponentAllowed(component.flattenToString(), userId) -- || isPackageOrComponentAllowed(component.getPackageName(), userId)) { -+ if (isPackageOrComponentAllowedWithPermission(component, userId)) { - registerServiceLocked(component, userId); - } else { - Slog.d(TAG, component + " no longer has permission to be bound"); -@@ -1252,6 +1269,33 @@ abstract public class ManagedServices { - return removed; - } - -+ private void trimApprovedListsForInvalidServices(String packageName, int userId) { -+ synchronized (mApproved) { -+ final ArrayMap> approvedByType = mApproved.get(userId); -+ if (approvedByType == null) { -+ return; -+ } -+ for (int i = 0; i < approvedByType.size(); i++) { -+ final ArraySet approved = approvedByType.valueAt(i); -+ for (int j = approved.size() - 1; j >= 0; j--) { -+ final String approvedPackageOrComponent = approved.valueAt(j); -+ if (TextUtils.equals(getPackageName(approvedPackageOrComponent), packageName)) { -+ final ComponentName component = ComponentName.unflattenFromString( -+ approvedPackageOrComponent); -+ if (component != null && !componentHasBindPermission(component, userId)) { -+ approved.removeAt(j); -+ if (DEBUG) { -+ Slog.v(TAG, "Removing " + approvedPackageOrComponent -+ + " from approved list; no bind permission found " -+ + mConfig.bindPermission); -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ - protected String getPackageName(String packageOrComponent) { - final ComponentName component = ComponentName.unflattenFromString(packageOrComponent); - if (component != null) { -@@ -1488,8 +1532,7 @@ abstract public class ManagedServices { - void reregisterService(final ComponentName cn, final int userId) { - // If rebinding a package that died, ensure it still has permission - // after the rebind delay -- if (isPackageOrComponentAllowed(cn.getPackageName(), userId) -- || isPackageOrComponentAllowed(cn.flattenToString(), userId)) { -+ if (isPackageOrComponentAllowedWithPermission(cn, userId)) { - registerService(cn, userId); - } - } -diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java -index 541739d50024..4ef3a6eb12ab 100644 ---- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java -+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java -@@ -36,6 +36,7 @@ import static org.mockito.Matchers.any; - import static org.mockito.Matchers.anyInt; - import static org.mockito.Matchers.anyLong; - import static org.mockito.Matchers.eq; -+import static org.mockito.Mockito.doReturn; - import static org.mockito.Mockito.mock; - import static org.mockito.Mockito.never; - import static org.mockito.Mockito.spy; -@@ -883,6 +884,7 @@ public class ManagedServicesTest extends UiServiceTestCase { - return true; - }); - -+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); - service.addApprovedList("a", 0, true); - - service.reregisterService(cn, 0); -@@ -913,6 +915,7 @@ public class ManagedServicesTest extends UiServiceTestCase { - return true; - }); - -+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); - service.addApprovedList("a", 0, false); - - service.reregisterService(cn, 0); -@@ -943,6 +946,7 @@ public class ManagedServicesTest extends UiServiceTestCase { - return true; - }); - -+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); - service.addApprovedList("a/a", 0, true); - - service.reregisterService(cn, 0); -@@ -973,6 +977,7 @@ public class ManagedServicesTest extends UiServiceTestCase { - return true; - }); - -+ mockServiceInfoWithMetaData(List.of(cn), service, new ArrayMap<>()); - service.addApprovedList("a/a", 0, false); - - service.reregisterService(cn, 0); -@@ -1129,6 +1134,58 @@ public class ManagedServicesTest extends UiServiceTestCase { - } - } - -+ @Test -+ public void testUpgradeAppNoPermissionNoRebind() throws Exception { -+ Context context = spy(getContext()); -+ doReturn(true).when(context).bindServiceAsUser(any(), any(), anyInt(), any()); -+ -+ ManagedServices service = new TestManagedServices(context, mLock, mUserProfiles, -+ mIpm, -+ APPROVAL_BY_COMPONENT); -+ -+ List packages = new ArrayList<>(); -+ packages.add("package"); -+ addExpectedServices(service, packages, 0); -+ -+ final ComponentName unapprovedComponent = ComponentName.unflattenFromString("package/C1"); -+ final ComponentName approvedComponent = ComponentName.unflattenFromString("package/C2"); -+ -+ // Both components are approved initially -+ mExpectedPrimaryComponentNames.clear(); -+ mExpectedPrimaryPackages.clear(); -+ mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2"); -+ mExpectedSecondaryComponentNames.clear(); -+ mExpectedSecondaryPackages.clear(); -+ -+ loadXml(service); -+ -+ //Component package/C1 loses bind permission -+ when(mIpm.getServiceInfo(any(), anyLong(), anyInt())).thenAnswer( -+ (Answer) invocation -> { -+ ComponentName invocationCn = invocation.getArgument(0); -+ if (invocationCn != null) { -+ ServiceInfo serviceInfo = new ServiceInfo(); -+ serviceInfo.packageName = invocationCn.getPackageName(); -+ serviceInfo.name = invocationCn.getClassName(); -+ if (invocationCn.equals(unapprovedComponent)) { -+ serviceInfo.permission = "none"; -+ } else { -+ serviceInfo.permission = service.getConfig().bindPermission; -+ } -+ serviceInfo.metaData = null; -+ return serviceInfo; -+ } -+ return null; -+ } -+ ); -+ -+ // Trigger package update -+ service.onPackagesChanged(false, new String[]{"package"}, new int[]{0}); -+ -+ assertFalse(service.isComponentEnabledForCurrentProfiles(unapprovedComponent)); -+ assertTrue(service.isComponentEnabledForCurrentProfiles(approvedComponent)); -+ } -+ - @Test - public void testSetPackageOrComponentEnabled() throws Exception { - for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) { --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/44_0044-Hide-window-immediately-if-itself-doesn-t-run-hide-animation.bulletin.patch b/aosp_diff/preliminary/frameworks/base/44_0044-Hide-window-immediately-if-itself-doesn-t-run-hide-animation.bulletin.patch deleted file mode 100644 index f6d521ac6e..0000000000 --- a/aosp_diff/preliminary/frameworks/base/44_0044-Hide-window-immediately-if-itself-doesn-t-run-hide-animation.bulletin.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 1ec80672496e40c7e07cef3f517c702e7ba50c36 Mon Sep 17 00:00:00 2001 -From: Riddle Hsu -Date: Tue, 6 Feb 2024 17:19:37 +0800 -Subject: [PATCH] Hide window immediately if itself doesn't run hide animation - -The condition was overextended in commit 9bca6b4 which checks if the -parent container of the window is animating. That causes the window to -wait for animation finish to update visibility, but the animation -finish callback won't happen because itself is not animating. Then the -window that should be hidden remains on screen. - -Bug: 302431573 -Test: atest WindowStateTests#testIsOnScreen_hiddenByPolicy -(cherry picked from commit 9add9281ffc120c81a7d125892803f1beb5ddcb3) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:10a7f0914c87f4af521b5cbb13e84a83dacebf82) -Merged-In: Iafc2b2c2a24d8fc8d147354ef2f0b4afeeb510c5 -Change-Id: Iafc2b2c2a24d8fc8d147354ef2f0b4afeeb510c5 ---- - .../com/android/server/wm/WindowState.java | 6 ++++-- - .../android/server/wm/WindowStateTests.java | 20 +++++++++++++++++++ - 2 files changed, 24 insertions(+), 2 deletions(-) - -diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java -index 06978a5338ea..3dfcf1ff55a8 100644 ---- a/services/core/java/com/android/server/wm/WindowState.java -+++ b/services/core/java/com/android/server/wm/WindowState.java -@@ -3089,8 +3089,10 @@ class WindowState extends WindowContainer implements WindowManagerP - return false; - } - if (doAnimation) { -- mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false); -- if (!isAnimating(TRANSITION | PARENTS)) { -+ // If a hide animation is applied, then let onAnimationFinished -+ // -> checkPolicyVisibilityChange hide the window. Otherwise make doAnimation false -+ // to commit invisible immediately. -+ if (!mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false /* isEntrance */)) { - doAnimation = false; - } - } -diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java -index 0ddd3135506e..7fb5c9687796 100644 ---- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java -+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java -@@ -229,6 +229,26 @@ public class WindowStateTests extends WindowTestsBase { - assertTrue(window.isOnScreen()); - window.hide(false /* doAnimation */, false /* requestAnim */); - assertFalse(window.isOnScreen()); -+ -+ // Verifies that a window without animation can be hidden even if its parent is animating. -+ window.show(false /* doAnimation */, false /* requestAnim */); -+ assertTrue(window.isVisibleByPolicy()); -+ window.getParent().startAnimation(mTransaction, mock(AnimationAdapter.class), -+ false /* hidden */, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION); -+ window.mAttrs.windowAnimations = 0; -+ window.hide(true /* doAnimation */, true /* requestAnim */); -+ assertFalse(window.isSelfAnimating(0, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION)); -+ assertFalse(window.isVisibleByPolicy()); -+ assertFalse(window.isOnScreen()); -+ -+ // Verifies that a window with animation can be hidden after the hide animation is finished. -+ window.show(false /* doAnimation */, false /* requestAnim */); -+ window.mAttrs.windowAnimations = android.R.style.Animation_Dialog; -+ window.hide(true /* doAnimation */, true /* requestAnim */); -+ assertTrue(window.isSelfAnimating(0, SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION)); -+ assertTrue(window.isVisibleByPolicy()); -+ window.cancelAnimation(); -+ assertFalse(window.isVisibleByPolicy()); - } - - @Test --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/45_0045-Add-more-checkKeyIntent-checks-to-AccountManagerService-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/45_0045-Add-more-checkKeyIntent-checks-to-AccountManagerService-.bulletin.patch deleted file mode 100644 index 657578dae3..0000000000 --- a/aosp_diff/preliminary/frameworks/base/45_0045-Add-more-checkKeyIntent-checks-to-AccountManagerService-.bulletin.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 3c59b877099d71494121ef9c4d3304fdd055c093 Mon Sep 17 00:00:00 2001 -From: Dmitry Dementyev -Date: Tue, 26 Mar 2024 10:31:44 -0700 -Subject: [PATCH] Add more checkKeyIntent checks to AccountManagerService. - -Another verification is needed after Bundle modification. -Bug: 321941232 -Test: manual -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:36db8a1d61a881f89fdd3911886adcda6e1f0d7f) -Merged-In: I9e45d758a2320328da5664b6341eafe6f285f297 -Change-Id: I9e45d758a2320328da5664b6341eafe6f285f297 ---- - .../android/server/accounts/AccountManagerService.java | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java -index cba28f3a596f..b45bcb405557 100644 ---- a/services/core/java/com/android/server/accounts/AccountManagerService.java -+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java -@@ -3612,6 +3612,11 @@ public class AccountManagerService - - // Strip auth token from result. - result.remove(AccountManager.KEY_AUTHTOKEN); -+ if (!checkKeyIntent(Binder.getCallingUid(), result)) { -+ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, -+ "invalid intent in bundle returned"); -+ return; -+ } - - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, -@@ -5201,6 +5206,11 @@ public class AccountManagerService - } else { - if (mStripAuthTokenFromResult) { - result.remove(AccountManager.KEY_AUTHTOKEN); -+ if (!checkKeyIntent(Binder.getCallingUid(), result)) { -+ onError(AccountManager.ERROR_CODE_INVALID_RESPONSE, -+ "invalid intent in bundle returned"); -+ return; -+ } - } - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, getClass().getSimpleName() --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/46_0046-Update-media_controls_lock_screen-setting-behavior.bulletin.patch b/aosp_diff/preliminary/frameworks/base/46_0046-Update-media_controls_lock_screen-setting-behavior.bulletin.patch deleted file mode 100644 index d8a66d1a51..0000000000 --- a/aosp_diff/preliminary/frameworks/base/46_0046-Update-media_controls_lock_screen-setting-behavior.bulletin.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 76d298d2e82cbc8ee48b4fa42702f5dfc09cbab0 Mon Sep 17 00:00:00 2001 -From: Beth Thibodeau -Date: Tue, 19 Mar 2024 16:49:51 -0500 -Subject: [PATCH] Update media_controls_lock_screen setting behavior - -When the setting is disabled, hide the media carousel everywhere when -the device is on lockscreen, not just in the keyguard layout - -Bug: 314333719 -Test: manual -Test: atest MediaHierarchyManagerTest -Flag: NONE -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a441f4acd62cce1059818ce8e9b7ab93b0079e50) -Merged-In: I4f618e4013db894291e6fca9d49bceb1cb7e4bd9 -Change-Id: I4f618e4013db894291e6fca9d49bceb1cb7e4bd9 ---- - .../controls/ui/KeyguardMediaController.kt | 40 --------------- - .../controls/ui/MediaHierarchyManager.kt | 27 +++++++--- - .../systemui/media/controls/ui/MediaHost.kt | 4 +- - .../ui/KeyguardMediaControllerTest.kt | 28 ----------- - .../controls/ui/MediaHierarchyManagerTest.kt | 50 +++++++++++++++++++ - 5 files changed, 72 insertions(+), 77 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt -index 2883210805d3..2359f6ad3b43 100644 ---- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt -+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt -@@ -18,16 +18,10 @@ package com.android.systemui.media.controls.ui - - import android.content.Context - import android.content.res.Configuration --import android.database.ContentObserver --import android.net.Uri --import android.os.Handler --import android.os.UserHandle --import android.provider.Settings - import android.view.View - import android.view.ViewGroup - import androidx.annotation.VisibleForTesting - import com.android.systemui.dagger.SysUISingleton --import com.android.systemui.dagger.qualifiers.Main - import com.android.systemui.media.dagger.MediaModule.KEYGUARD - import com.android.systemui.plugins.statusbar.StatusBarStateController - import com.android.systemui.statusbar.StatusBarState -@@ -36,7 +30,6 @@ import com.android.systemui.statusbar.notification.stack.MediaContainerView - import com.android.systemui.statusbar.phone.KeyguardBypassController - import com.android.systemui.statusbar.policy.ConfigurationController - import com.android.systemui.util.LargeScreenUtils --import com.android.systemui.util.settings.SecureSettings - import javax.inject.Inject - import javax.inject.Named - -@@ -52,8 +45,6 @@ constructor( - private val bypassController: KeyguardBypassController, - private val statusBarStateController: SysuiStatusBarStateController, - private val context: Context, -- private val secureSettings: SecureSettings, -- @Main private val handler: Handler, - configurationController: ConfigurationController, - ) { - -@@ -77,26 +68,6 @@ constructor( - } - ) - -- val settingsObserver: ContentObserver = -- object : ContentObserver(handler) { -- override fun onChange(selfChange: Boolean, uri: Uri?) { -- if (uri == lockScreenMediaPlayerUri) { -- allowMediaPlayerOnLockScreen = -- secureSettings.getBoolForUser( -- Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, -- true, -- UserHandle.USER_CURRENT -- ) -- refreshMediaPosition() -- } -- } -- } -- secureSettings.registerContentObserverForUser( -- Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, -- settingsObserver, -- UserHandle.USER_ALL -- ) -- - // First let's set the desired state that we want for this host - mediaHost.expansion = MediaHostState.EXPANDED - mediaHost.showsOnlyActiveMedia = true -@@ -142,16 +113,6 @@ constructor( - private set - private var splitShadeContainer: ViewGroup? = null - -- /** Track the media player setting status on lock screen. */ -- private var allowMediaPlayerOnLockScreen: Boolean = -- secureSettings.getBoolForUser( -- Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, -- true, -- UserHandle.USER_CURRENT -- ) -- private val lockScreenMediaPlayerUri = -- secureSettings.getUriFor(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN) -- - /** - * Attaches media container in single pane mode, situated at the top of the notifications list - */ -@@ -211,7 +172,6 @@ constructor( - mediaHost.visible && - !bypassController.bypassEnabled && - keyguardOrUserSwitcher && -- allowMediaPlayerOnLockScreen && - shouldBeVisibleForSplitShade() - if (visible) { - showMediaPlayer() -diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt -index fe8ebafdf9b4..6fcfa71c2f5d 100644 ---- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt -+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHierarchyManager.kt -@@ -104,7 +104,7 @@ constructor( - ) { - - /** Track the media player setting status on lock screen. */ -- private var allowMediaPlayerOnLockScreen: Boolean = true -+ private var allowMediaPlayerOnLockScreen: Boolean = getMediaLockScreenSetting() - private val lockScreenMediaPlayerUri = - secureSettings.getUriFor(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN) - -@@ -461,6 +461,7 @@ constructor( - mediaCarouselController.logSmartspaceImpression(qsExpanded) - } - updateUserVisibility() -+ mediaCarouselController.updateHostVisibility() - } - - override fun onDozeAmountChanged(linear: Float, eased: Float) { -@@ -533,7 +534,6 @@ constructor( - mediaCarouselController.updateHostVisibility = { - mediaHosts.forEach { it?.updateViewVisibility() } - } -- - panelEventsEvents.addShadeStateEventsListener( - object : ShadeStateEventsListener { - override fun onExpandImmediateChanged(isExpandImmediateEnabled: Boolean) { -@@ -547,12 +547,8 @@ constructor( - object : ContentObserver(handler) { - override fun onChange(selfChange: Boolean, uri: Uri?) { - if (uri == lockScreenMediaPlayerUri) { -- allowMediaPlayerOnLockScreen = -- secureSettings.getBoolForUser( -- Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, -- true, -- UserHandle.USER_CURRENT -- ) -+ allowMediaPlayerOnLockScreen = getMediaLockScreenSetting() -+ mediaCarouselController.updateHostVisibility() - } - } - } -@@ -563,6 +559,14 @@ constructor( - ) - } - -+ private fun getMediaLockScreenSetting(): Boolean { -+ return secureSettings.getBoolForUser( -+ Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, -+ true, -+ UserHandle.USER_CURRENT -+ ) -+ } -+ - private fun updateConfiguration() { - distanceForFullShadeTransition = - context.resources.getDimensionPixelSize( -@@ -602,6 +606,13 @@ constructor( - mediaCarouselController.closeGuts() - } - -+ /** Return true if the carousel should be hidden because lockscreen is currently visible */ -+ fun isLockedAndHidden(): Boolean { -+ return !allowMediaPlayerOnLockScreen && -+ (statusbarState == StatusBarState.SHADE_LOCKED || -+ statusbarState == StatusBarState.KEYGUARD) -+ } -+ - private fun createUniqueObjectHost(): UniqueObjectHostView { - val viewHost = UniqueObjectHostView(context) - viewHost.addOnAttachStateChangeListener( -diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt -index be570b4a1119..26580e54cd62 100644 ---- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt -+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaHost.kt -@@ -199,7 +199,9 @@ constructor( - */ - fun updateViewVisibility() { - state.visible = -- if (showsOnlyActiveMedia) { -+ if (mediaHierarchyManager.isLockedAndHidden()) { -+ false -+ } else if (showsOnlyActiveMedia) { - mediaDataManager.hasActiveMediaOrRecommendation() - } else { - mediaDataManager.hasAnyMediaOrRecommendation() -diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt -index 91b0245be8d3..c1cf7e07aee2 100644 ---- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt -+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/KeyguardMediaControllerTest.kt -@@ -16,7 +16,6 @@ - - package com.android.systemui.media.controls.ui - --import android.provider.Settings - import android.test.suitebuilder.annotation.SmallTest - import android.testing.AndroidTestingRunner - import android.testing.TestableLooper -@@ -32,8 +31,6 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController - import com.android.systemui.statusbar.policy.ConfigurationController - import com.android.systemui.util.animation.UniqueObjectHostView - import com.android.systemui.util.mockito.whenever --import com.android.systemui.util.settings.FakeSettings --import com.android.systemui.utils.os.FakeHandler - import com.google.common.truth.Truth.assertThat - import junit.framework.Assert.assertTrue - import org.junit.Before -@@ -60,10 +57,7 @@ class KeyguardMediaControllerTest : SysuiTestCase() { - - private val mediaContainerView: MediaContainerView = MediaContainerView(context, null) - private val hostView = UniqueObjectHostView(context) -- private val settings = FakeSettings() - private lateinit var keyguardMediaController: KeyguardMediaController -- private lateinit var testableLooper: TestableLooper -- private lateinit var fakeHandler: FakeHandler - private lateinit var statusBarStateListener: StatusBarStateController.StateListener - - @Before -@@ -79,16 +73,12 @@ class KeyguardMediaControllerTest : SysuiTestCase() { - whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD) - whenever(mediaHost.hostView).thenReturn(hostView) - hostView.layoutParams = FrameLayout.LayoutParams(100, 100) -- testableLooper = TestableLooper.get(this) -- fakeHandler = FakeHandler(testableLooper.looper) - keyguardMediaController = - KeyguardMediaController( - mediaHost, - bypassController, - statusBarStateController, - context, -- settings, -- fakeHandler, - configurationController, - ) - keyguardMediaController.attachSinglePaneContainer(mediaContainerView) -@@ -117,24 +107,6 @@ class KeyguardMediaControllerTest : SysuiTestCase() { - assertThat(mediaContainerView.visibility).isEqualTo(visibility) - } - -- @Test -- fun testHiddenOnKeyguard_whenMediaOnLockScreenDisabled() { -- settings.putInt(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, 0) -- -- keyguardMediaController.refreshMediaPosition() -- -- assertThat(mediaContainerView.visibility).isEqualTo(GONE) -- } -- -- @Test -- fun testAvailableOnKeyguard_whenMediaOnLockScreenEnabled() { -- settings.putInt(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, 1) -- -- keyguardMediaController.refreshMediaPosition() -- -- assertThat(mediaContainerView.visibility).isEqualTo(VISIBLE) -- } -- - @Test - fun testActivatesSplitShadeContainerInSplitShadeMode() { - val splitShadeContainer = FrameLayout(context) -diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt -index 2ce236d4ba89..69bf97f6545f 100644 ---- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt -+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaHierarchyManagerTest.kt -@@ -124,6 +124,7 @@ class MediaHierarchyManagerTest : SysuiTestCase() { - verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture()) - verify(statusBarStateController).addCallback(statusBarCallback.capture()) - verify(dreamOverlayStateController).addCallback(dreamOverlayCallback.capture()) -+ whenever(mediaCarouselController.updateHostVisibility).thenReturn({}) - setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN, LOCKSCREEN_TOP) - setupHost(qsHost, MediaHierarchyManager.LOCATION_QS, QS_TOP) - setupHost(qqsHost, MediaHierarchyManager.LOCATION_QQS, QQS_TOP) -@@ -485,6 +486,55 @@ class MediaHierarchyManagerTest : SysuiTestCase() { - assertThat(mediaCarouselScrollHandler.visibleToUser).isFalse() - } - -+ @Test -+ fun keyguardState_allowedOnLockscreen_updateVisibility() { -+ settings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, true) -+ clearInvocations(mediaCarouselController) -+ -+ statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD) -+ statusBarCallback.value.onStateChanged(StatusBarState.KEYGUARD) -+ -+ verify(mediaCarouselController).updateHostVisibility -+ assertThat(mediaHierarchyManager.isLockedAndHidden()).isFalse() -+ } -+ -+ @Test -+ fun keyguardState_notAllowedOnLockscreen_updateVisibility() { -+ settings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, false) -+ clearInvocations(mediaCarouselController) -+ -+ statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD) -+ statusBarCallback.value.onStateChanged(StatusBarState.KEYGUARD) -+ -+ verify(mediaCarouselController).updateHostVisibility -+ assertThat(mediaHierarchyManager.isLockedAndHidden()).isTrue() -+ } -+ -+ @Test -+ fun keyguardGone_updateVisibility() { -+ settings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, false) -+ clearInvocations(mediaCarouselController) -+ -+ statusBarCallback.value.onStatePreChange(StatusBarState.KEYGUARD, StatusBarState.SHADE) -+ statusBarCallback.value.onStateChanged(StatusBarState.SHADE) -+ -+ verify(mediaCarouselController).updateHostVisibility -+ assertThat(mediaHierarchyManager.isLockedAndHidden()).isFalse() -+ } -+ -+ @Test -+ fun lockscreenSettingChanged_updateVisibility() { -+ settings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, true) -+ statusBarCallback.value.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD) -+ statusBarCallback.value.onStateChanged(StatusBarState.KEYGUARD) -+ clearInvocations(mediaCarouselController) -+ -+ settings.putBool(Settings.Secure.MEDIA_CONTROLS_LOCK_SCREEN, false) -+ -+ verify(mediaCarouselController).updateHostVisibility -+ assertThat(mediaHierarchyManager.isLockedAndHidden()).isTrue() -+ } -+ - private fun enableSplitShade() { - context - .getOrCreateTestableResources() --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/47_0047-Resolve-message-conversation-image-Uris-with-the-cor.patch b/aosp_diff/preliminary/frameworks/base/47_0047-Resolve-message-conversation-image-Uris-with-the-cor.patch deleted file mode 100644 index b82a82303e..0000000000 --- a/aosp_diff/preliminary/frameworks/base/47_0047-Resolve-message-conversation-image-Uris-with-the-cor.patch +++ /dev/null @@ -1,287 +0,0 @@ -From 89d75d441f7091db73742a18346014c2be207f0b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Mat=C3=ADas=20Hern=C3=A1ndez?= -Date: Fri, 22 Mar 2024 14:26:23 +0100 -Subject: [PATCH] Resolve message/conversation image Uris with the correct user - id - -Bug: 317503801 -Test: atest ExpandableNotificationRowTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:44524f06f9d652c596d542e0882eb2f17594f154) -Merged-In: I11c5b39f2d9d8f0788acab43640a6d4abcd5a179 -Change-Id: I11c5b39f2d9d8f0788acab43640a6d4abcd5a179 ---- - .../row/ExpandableNotificationRow.java | 39 ++++++++++++++++--- - .../row/NotificationInlineImageResolver.java | 7 +++- - .../notification/row/RowInflaterTask.java | 34 +++++++++++++++- - .../row/ExpandableNotificationRowTest.java | 25 ++++++++++++ - .../systemui/SysuiTestableContext.java | 22 +++++++++++ - 5 files changed, 120 insertions(+), 7 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java -index d92d11b18d74..a8bd4e4a0c66 100644 ---- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java -+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java -@@ -40,6 +40,7 @@ import android.graphics.drawable.Drawable; - import android.os.Build; - import android.os.Bundle; - import android.os.Trace; -+import android.os.UserHandle; - import android.service.notification.StatusBarNotification; - import android.util.ArraySet; - import android.util.AttributeSet; -@@ -377,7 +378,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView - private boolean mUseIncreasedHeadsUpHeight; - private float mTranslationWhenRemoved; - private boolean mWasChildInGroupWhenRemoved; -- private NotificationInlineImageResolver mImageResolver; -+ private final NotificationInlineImageResolver mImageResolver; - @Nullable - private OnExpansionChangedListener mExpansionChangedListener; - @Nullable -@@ -1681,13 +1682,41 @@ public class ExpandableNotificationRow extends ActivatableNotificationView - } - - /** -- * Constructs an ExpandableNotificationRow. -- * @param context context passed to image resolver -+ * Constructs an ExpandableNotificationRow. Used by layout inflation. -+ * -+ * @param context passed to image resolver - * @param attrs attributes used to initialize parent view - */ - public ExpandableNotificationRow(Context context, AttributeSet attrs) { -- super(context, attrs); -- mImageResolver = new NotificationInlineImageResolver(context, -+ this(context, attrs, context); -+ Log.wtf(TAG, "This constructor shouldn't be called"); -+ } -+ -+ /** -+ * Constructs an ExpandableNotificationRow. Used by layout inflation (with a custom {@code -+ * AsyncLayoutFactory} in {@link RowInflaterTask}. -+ * -+ * @param context context context of the view -+ * @param attrs attributes used to initialize parent view -+ * @param entry notification that the row will be associated to (determines the user for the -+ * ImageResolver) -+ */ -+ public ExpandableNotificationRow(Context context, AttributeSet attrs, NotificationEntry entry) { -+ this(context, attrs, userContextForEntry(context, entry)); -+ } -+ -+ private static Context userContextForEntry(Context base, NotificationEntry entry) { -+ if (base.getUserId() == entry.getSbn().getNormalizedUserId()) { -+ return base; -+ } -+ return base.createContextAsUser( -+ UserHandle.of(entry.getSbn().getNormalizedUserId()), /* flags= */ 0); -+ } -+ -+ private ExpandableNotificationRow(Context sysUiContext, AttributeSet attrs, -+ Context userContext) { -+ super(sysUiContext, attrs); -+ mImageResolver = new NotificationInlineImageResolver(userContext, - new NotificationInlineImageCache()); - float radius = getResources().getDimension(R.dimen.notification_corner_radius_small); - mSmallRoundness = radius / getMaxRadius(); -diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java -index c620f448b3b7..3e932aa616b8 100644 ---- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java -+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInlineImageResolver.java -@@ -66,7 +66,7 @@ public class NotificationInlineImageResolver implements ImageResolver { - * @param imageCache The implementation of internal cache. - */ - public NotificationInlineImageResolver(Context context, ImageCache imageCache) { -- mContext = context.getApplicationContext(); -+ mContext = context; - mImageCache = imageCache; - - if (mImageCache != null) { -@@ -76,6 +76,11 @@ public class NotificationInlineImageResolver implements ImageResolver { - updateMaxImageSizes(); - } - -+ @VisibleForTesting -+ public Context getContext() { -+ return mContext; -+ } -+ - /** - * Check if this resolver has its internal cache implementation. - * @return True if has its internal cache, false otherwise. -diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java -index 6feffe654630..b2fe1d82945b 100644 ---- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java -+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowInflaterTask.java -@@ -17,10 +17,15 @@ - package com.android.systemui.statusbar.notification.row; - - import android.content.Context; -+import android.util.AttributeSet; - import android.util.Log; - import android.view.View; - import android.view.ViewGroup; - -+import androidx.annotation.NonNull; -+import androidx.annotation.Nullable; -+import androidx.annotation.VisibleForTesting; -+import androidx.asynclayoutinflater.view.AsyncLayoutFactory; - import androidx.asynclayoutinflater.view.AsyncLayoutInflater; - - import com.android.systemui.R; -@@ -55,12 +60,39 @@ public class RowInflaterTask implements InflationTask, AsyncLayoutInflater.OnInf - mInflateOrigin = new Throwable("inflate requested here"); - } - mListener = listener; -- AsyncLayoutInflater inflater = new AsyncLayoutInflater(context); -+ AsyncLayoutInflater inflater = new AsyncLayoutInflater(context, -+ new RowAsyncLayoutInflater(entry)); - mEntry = entry; - entry.setInflationTask(this); - inflater.inflate(R.layout.status_bar_notification_row, parent, this); - } - -+ @VisibleForTesting -+ static class RowAsyncLayoutInflater implements AsyncLayoutFactory { -+ private final NotificationEntry mEntry; -+ -+ RowAsyncLayoutInflater(NotificationEntry entry) { -+ mEntry = entry; -+ } -+ -+ @Nullable -+ @Override -+ public View onCreateView(@Nullable View parent, @NonNull String name, -+ @NonNull Context context, @NonNull AttributeSet attrs) { -+ if (name.equals(ExpandableNotificationRow.class.getName())) { -+ return new ExpandableNotificationRow(context, attrs, mEntry); -+ } -+ return null; -+ } -+ -+ @Nullable -+ @Override -+ public View onCreateView(@NonNull String name, @NonNull Context context, -+ @NonNull AttributeSet attrs) { -+ return null; -+ } -+ } -+ - @Override - public void abort() { - mCancelled = true; -diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java -index ac8b42afd4b2..15dffb0726a9 100644 ---- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java -+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java -@@ -20,6 +20,8 @@ import static android.app.NotificationManager.IMPORTANCE_DEFAULT; - - import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking; - import static com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.FLAG_CONTENT_VIEW_ALL; -+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.PKG; -+import static com.android.systemui.statusbar.notification.row.NotificationTestHelper.USER_HANDLE; - - import static com.google.common.truth.Truth.assertThat; - -@@ -41,10 +43,12 @@ import static org.mockito.Mockito.when; - - import android.app.Notification; - import android.app.NotificationChannel; -+import android.content.Context; - import android.graphics.Color; - import android.graphics.drawable.AnimatedVectorDrawable; - import android.graphics.drawable.AnimationDrawable; - import android.graphics.drawable.Drawable; -+import android.os.UserHandle; - import android.testing.AndroidTestingRunner; - import android.testing.TestableLooper; - import android.testing.TestableLooper.RunWithLooper; -@@ -57,6 +61,7 @@ import androidx.test.filters.SmallTest; - import com.android.internal.R; - import com.android.internal.widget.CachingIconView; - import com.android.systemui.SysuiTestCase; -+import com.android.systemui.SysuiTestableContext; - import com.android.systemui.flags.FakeFeatureFlags; - import com.android.systemui.flags.Flags; - import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; -@@ -833,6 +838,26 @@ public class ExpandableNotificationRowTest extends SysuiTestCase { - assertThat(row.isDrawingAppearAnimation()).isFalse(); - } - -+ @Test -+ public void imageResolver_sameNotificationUser_usesContext() throws Exception { -+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG, -+ USER_HANDLE.getUid(1234), USER_HANDLE); -+ -+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(mContext); -+ } -+ -+ @Test -+ public void imageResolver_differentNotificationUser_createsUserContext() throws Exception { -+ UserHandle user = new UserHandle(33); -+ Context userContext = new SysuiTestableContext(mContext); -+ mContext.prepareCreateContextAsUser(user, userContext); -+ -+ ExpandableNotificationRow row = mNotificationTestHelper.createRow(PKG, -+ user.getUid(1234), user); -+ -+ assertThat(row.getImageResolver().getContext()).isSameInstanceAs(userContext); -+ } -+ - private void setDrawableIconsInImageView(CachingIconView icon, Drawable iconDrawable, - Drawable rightIconDrawable) { - ImageView iconView = mock(ImageView.class); -diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java -index 5ff57aad9f5d..aa58b89f4676 100644 ---- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java -+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestableContext.java -@@ -14,6 +14,7 @@ - - package com.android.systemui; - -+import android.annotation.NonNull; - import android.content.BroadcastReceiver; - import android.content.Context; - import android.content.Intent; -@@ -29,12 +30,15 @@ import android.view.Display; - - import com.android.internal.annotations.GuardedBy; - -+import java.util.HashMap; -+import java.util.Map; - import java.util.Set; - - public class SysuiTestableContext extends TestableContext { - - @GuardedBy("mRegisteredReceivers") - private final Set mRegisteredReceivers = new ArraySet<>(); -+ private final Map mContextForUser = new HashMap<>(); - - public SysuiTestableContext(Context base) { - super(base); -@@ -152,4 +156,22 @@ public class SysuiTestableContext extends TestableContext { - } - super.unregisterReceiver(receiver); - } -+ -+ /** -+ * Sets a Context object that will be returned as the result of {@link #createContextAsUser} -+ * for a specific {@code user}. -+ */ -+ public void prepareCreateContextAsUser(UserHandle user, Context context) { -+ mContextForUser.put(user, context); -+ } -+ -+ @Override -+ @NonNull -+ public Context createContextAsUser(UserHandle user, int flags) { -+ Context userContext = mContextForUser.get(user); -+ if (userContext != null) { -+ return userContext; -+ } -+ return super.createContextAsUser(user, flags); -+ } - } --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/48_0048-CMD-Check-permissions-for-CDM-shell-commands.bulletin.patch b/aosp_diff/preliminary/frameworks/base/48_0048-CMD-Check-permissions-for-CDM-shell-commands.bulletin.patch deleted file mode 100644 index c18d0b4c43..0000000000 --- a/aosp_diff/preliminary/frameworks/base/48_0048-CMD-Check-permissions-for-CDM-shell-commands.bulletin.patch +++ /dev/null @@ -1,58 +0,0 @@ -From eb1fac15cd1d4ba1b4182a4e2f6ef6452e75bea9 Mon Sep 17 00:00:00 2001 -From: Guojing Yuan -Date: Thu, 14 Dec 2023 19:30:04 +0000 -Subject: [PATCH] Check permissions for CDM shell commands - -Override handleShellCommand instead of onShellCommand because -Binder.onShellCommand checks the necessary permissions of the caller. - -Bug: 313428840 - -Test: manually tested CDM shell commands -(cherry picked from commit 1761a0fee9c2cd9787bbb7fbdbe30b4c2b03396e) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:54c968aaa66e9364bc0380c9a57af5c6844759aa) -Merged-In: I5539b3594feb5544c458c0fd1061b51a0a808900 -Change-Id: I5539b3594feb5544c458c0fd1061b51a0a808900 ---- - .../CompanionDeviceManagerService.java | 17 ++++++++--------- - 1 file changed, 8 insertions(+), 9 deletions(-) - -diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java -index 0c6d053d4f3f..a3f66655795e 100644 ---- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java -+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java -@@ -84,9 +84,7 @@ import android.os.ParcelFileDescriptor; - import android.os.PowerWhitelistManager; - import android.os.RemoteCallbackList; - import android.os.RemoteException; --import android.os.ResultReceiver; - import android.os.ServiceManager; --import android.os.ShellCallback; - import android.os.SystemProperties; - import android.os.UserHandle; - import android.os.UserManager; -@@ -951,13 +949,14 @@ public class CompanionDeviceManagerService extends SystemService { - } - - @Override -- public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, -- String[] args, ShellCallback callback, ResultReceiver resultReceiver) -- throws RemoteException { -- new CompanionDeviceShellCommand(CompanionDeviceManagerService.this, mAssociationStore, -- mDevicePresenceMonitor, mTransportManager, mSystemDataTransferProcessor, -- mAssociationRequestsProcessor) -- .exec(this, in, out, err, args, callback, resultReceiver); -+ public int handleShellCommand(@NonNull ParcelFileDescriptor in, -+ @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err, -+ @NonNull String[] args) { -+ return new CompanionDeviceShellCommand(CompanionDeviceManagerService.this, -+ mAssociationStore, mDevicePresenceMonitor, mTransportManager, -+ mSystemDataTransferProcessor, mAssociationRequestsProcessor) -+ .exec(this, in.getFileDescriptor(), out.getFileDescriptor(), -+ err.getFileDescriptor(), args); - } - - @Override --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/49_0049-Fix-bug-in-screen-capture-and-lock-task-migrations.bulletin.patch b/aosp_diff/preliminary/frameworks/base/49_0049-Fix-bug-in-screen-capture-and-lock-task-migrations.bulletin.patch deleted file mode 100644 index 140f2ba828..0000000000 --- a/aosp_diff/preliminary/frameworks/base/49_0049-Fix-bug-in-screen-capture-and-lock-task-migrations.bulletin.patch +++ /dev/null @@ -1,248 +0,0 @@ -From 736462a777d0a0e1258bd7ab80d6e352ef797669 Mon Sep 17 00:00:00 2001 -From: Kholoud Mohamed -Date: Tue, 9 Jan 2024 17:53:40 +0000 -Subject: [PATCH] Fix bug in screen capture and lock task migrations - -Bug: 318497672 -Test: manual -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:9d809f92e8a026789115a0c6de7124da70101845) -Merged-In: Id0ac7d06b57f690d114217f2a34c2a1e8c60a277 -Change-Id: Id0ac7d06b57f690d114217f2a34c2a1e8c60a277 ---- - .../DevicePolicyManagerService.java | 85 +++++++++++++++++-- - .../android/server/devicepolicy/Owners.java | 13 +++ - .../server/devicepolicy/OwnersData.java | 7 ++ - ...vicePolicyManagerServiceMigrationTest.java | 3 + - 4 files changed, 100 insertions(+), 8 deletions(-) - -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -index 23a1d4e0b37b..5e67708b1adb 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -@@ -3389,6 +3389,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - if (shouldMigrateToDevicePolicyEngine()) { - migratePoliciesToDevicePolicyEngine(); - } -+ -+ maybeMigratePoliciesPostUpgradeToDevicePolicyEngineLocked(); - } - maybeStartSecurityLogMonitorOnActivityManagerReady(); - break; -@@ -24151,11 +24153,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - Preconditions.checkCallAuthorization( - hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)); - return mInjector.binderWithCleanCallingIdentity(() -> { -- boolean canForceMigration = forceMigration && !hasNonTestOnlyActiveAdmins(); -- if (!canForceMigration && !shouldMigrateToDevicePolicyEngine()) { -- return false; -+ synchronized (getLockObject()) { -+ boolean canForceMigration = forceMigration && !hasNonTestOnlyActiveAdmins(); -+ if (!canForceMigration && !shouldMigrateToDevicePolicyEngine()) { -+ return false; -+ } -+ boolean migrated = migratePoliciesToDevicePolicyEngine(); -+ migrated &= migratePoliciesPostUpgradeToDevicePolicyEngineLocked(); -+ return migrated; - } -- return migratePoliciesToDevicePolicyEngine(); - }); - } - -@@ -24184,6 +24190,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - && !mOwners.isMigratedToPolicyEngine()); - } - -+ /** -+ * [b/318497672] Migrate policies that weren't migrated properly in the initial migration on -+ * update from Android T to Android U -+ */ -+ private void maybeMigratePoliciesPostUpgradeToDevicePolicyEngineLocked() { -+ if (!mOwners.isMigratedToPolicyEngine() || mOwners.isMigratedPostUpdate()) { -+ return; -+ } -+ migratePoliciesPostUpgradeToDevicePolicyEngineLocked(); -+ mOwners.markPostUpgradeMigration(); -+ } -+ -+ private boolean migratePoliciesPostUpgradeToDevicePolicyEngineLocked() { -+ try { -+ migrateScreenCapturePolicyLocked(); -+ migrateLockTaskPolicyLocked(); -+ return true; -+ } catch (Exception e) { -+ Slogf.e(LOG_TAG, e, "Error occurred during post upgrade migration to the device " -+ + "policy engine."); -+ return false; -+ } -+ } -+ - /** - * @return {@code true} if policies were migrated successfully, {@code false} otherwise. - */ -@@ -24197,7 +24227,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - migrateAutoTimezonePolicy(); - migratePermissionGrantStatePolicies(); - } -- migrateScreenCapturePolicyLocked(); - migratePermittedInputMethodsPolicyLocked(); - migrateAccountManagementDisabledPolicyLocked(); - migrateUserControlDisabledPackagesLocked(); -@@ -24270,14 +24299,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - - private void migrateScreenCapturePolicyLocked() { - Binder.withCleanCallingIdentity(() -> { -- if (mPolicyCache.getScreenCaptureDisallowedUser() == UserHandle.USER_NULL) { -- return; -- } - ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(); - if (admin != null - && ((isDeviceOwner(admin) && admin.disableScreenCapture) - || (admin.getParentActiveAdmin() != null - && admin.getParentActiveAdmin().disableScreenCapture))) { -+ - EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( - admin.info.getComponent(), - admin.getUserHandle().getIdentifier(), -@@ -24306,6 +24333,48 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - }); - } - -+ private void migrateLockTaskPolicyLocked() { -+ Binder.withCleanCallingIdentity(() -> { -+ ActiveAdmin deviceOwner = getDeviceOwnerAdminLocked(); -+ if (deviceOwner != null) { -+ int doUserId = deviceOwner.getUserHandle().getIdentifier(); -+ DevicePolicyData policies = getUserData(doUserId); -+ List packages = policies.mLockTaskPackages; -+ int features = policies.mLockTaskFeatures; -+ // TODO: find out about persistent preferred activities -+ if (!packages.isEmpty()) { -+ setLockTaskPolicyInPolicyEngine(deviceOwner, doUserId, packages, features); -+ } -+ } -+ -+ for (int userId : mUserManagerInternal.getUserIds()) { -+ ActiveAdmin profileOwner = getProfileOwnerLocked(userId); -+ if (profileOwner != null && canDPCManagedUserUseLockTaskLocked(userId)) { -+ DevicePolicyData policies = getUserData(userId); -+ List packages = policies.mLockTaskPackages; -+ int features = policies.mLockTaskFeatures; -+ if (!packages.isEmpty()) { -+ setLockTaskPolicyInPolicyEngine(profileOwner, userId, packages, features); -+ } -+ } -+ } -+ }); -+ } -+ -+ private void setLockTaskPolicyInPolicyEngine( -+ ActiveAdmin admin, int userId, List packages, int features) { -+ EnforcingAdmin enforcingAdmin = -+ EnforcingAdmin.createEnterpriseEnforcingAdmin( -+ admin.info.getComponent(), -+ userId, -+ admin); -+ mDevicePolicyEngine.setLocalPolicy( -+ PolicyDefinition.LOCK_TASK, -+ enforcingAdmin, -+ new LockTaskPolicy(new HashSet<>(packages), features), -+ userId); -+ } -+ - private void migratePermittedInputMethodsPolicyLocked() { - Binder.withCleanCallingIdentity(() -> { - List users = mUserManager.getUsers(); -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java -index bb275e45b55a..c842e29e3c70 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java -@@ -616,6 +616,19 @@ class Owners { - } - } - -+ void markPostUpgradeMigration() { -+ synchronized (mData) { -+ mData.mPoliciesMigratedPostUpdate = true; -+ mData.writeDeviceOwner(); -+ } -+ } -+ -+ boolean isMigratedPostUpdate() { -+ synchronized (mData) { -+ return mData.mPoliciesMigratedPostUpdate; -+ } -+ } -+ - @GuardedBy("mData") - void pushToAppOpsLocked() { - if (!mSystemReady) { -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -index 37d4f95cac29..608ae140450e 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -@@ -87,6 +87,8 @@ class OwnersData { - - private static final String ATTR_MIGRATED_TO_POLICY_ENGINE = "migratedToPolicyEngine"; - -+ private static final String ATTR_MIGRATED_POST_UPGRADE = "migratedPostUpgrade"; -+ - // Internal state for the device owner package. - OwnerInfo mDeviceOwner; - int mDeviceOwnerUserId = UserHandle.USER_NULL; -@@ -114,6 +116,8 @@ class OwnersData { - - boolean mMigratedToPolicyEngine = false; - -+ boolean mPoliciesMigratedPostUpdate = false; -+ - OwnersData(PolicyPathProvider pathProvider) { - mPathProvider = pathProvider; - } -@@ -397,6 +401,7 @@ class OwnersData { - - out.startTag(null, TAG_POLICY_ENGINE_MIGRATION); - out.attributeBoolean(null, ATTR_MIGRATED_TO_POLICY_ENGINE, mMigratedToPolicyEngine); -+ out.attributeBoolean(null, ATTR_MIGRATED_POST_UPGRADE, mPoliciesMigratedPostUpdate); - out.endTag(null, TAG_POLICY_ENGINE_MIGRATION); - - } -@@ -457,6 +462,8 @@ class OwnersData { - case TAG_POLICY_ENGINE_MIGRATION: - mMigratedToPolicyEngine = parser.getAttributeBoolean( - null, ATTR_MIGRATED_TO_POLICY_ENGINE, false); -+ mPoliciesMigratedPostUpdate = parser.getAttributeBoolean( -+ null, ATTR_MIGRATED_POST_UPGRADE, false); - break; - default: - Slog.e(TAG, "Unexpected tag: " + tag); -diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java -index b539a76b521c..5eda84ba7629 100644 ---- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java -+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceMigrationTest.java -@@ -146,6 +146,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { - - @SmallTest - @Test -+ @Ignore("b/277916462") - public void testCompMigrationUnAffiliated_skipped() throws Exception { - prepareAdmin1AsDo(); - prepareAdminAnotherPackageAsPo(COPE_PROFILE_USER_ID); -@@ -217,6 +218,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { - - @SmallTest - @Test -+ @Ignore("b/277916462") - public void testCompMigration_keepSuspendedAppsWhenDpcIsRPlus() throws Exception { - prepareAdmin1AsDo(); - prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.R); -@@ -250,6 +252,7 @@ public class DevicePolicyManagerServiceMigrationTest extends DpmTestBase { - - @SmallTest - @Test -+ @Ignore("b/277916462") - public void testCompMigration_unsuspendAppsWhenDpcNotRPlus() throws Exception { - prepareAdmin1AsDo(); - prepareAdmin1AsPo(COPE_PROFILE_USER_ID, Build.VERSION_CODES.Q); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/50_0050--Bugfix-migrate-user-restrictions-to-DevicePolicyEngine.bulletin.patch b/aosp_diff/preliminary/frameworks/base/50_0050--Bugfix-migrate-user-restrictions-to-DevicePolicyEngine.bulletin.patch deleted file mode 100644 index 8f9392a70f..0000000000 --- a/aosp_diff/preliminary/frameworks/base/50_0050--Bugfix-migrate-user-restrictions-to-DevicePolicyEngine.bulletin.patch +++ /dev/null @@ -1,152 +0,0 @@ -From f1eb8e719dfbe15a38d40af0a73ead207eba9389 Mon Sep 17 00:00:00 2001 -From: Wen Zhang -Date: Fri, 2 Feb 2024 12:01:12 +0000 -Subject: [PATCH] [Bugfix]migrate user restrictions to DevicePolicyEngine - -Migrate user restrictions to DevicePolicyEngine, otherwise user restrictions will not be able to be queried when upgrading from Android 13 OTA to Android 14. - -Bug: 323452689 -Bug: 318497672 -Test: case 1:Android 13 upgrade to Android 14 -1.install TestDPC on Android 13 -2.set TestDPC as Device Owner -3.set disallow factory reset -4.update Android 14 via OTA -5.The reset to factory settings in the settings app is still unavailable. - -case 2:Android 14(bad version) upgrade to Android 14(new version) -1.install TestDPC on Android 13 -2.set TestDPC as Device Owner -3.set disallow factory reset -4.update Android 14(bad version) via OTA -5.The reset to factory settings in the settings app is still available. -6.update Android 14(new version) via OTA -7.The reset to factory settings in the settings app is unavailable. -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:93ba63a2bfdda47fb9376efaad792bc96a106947) -Merged-In: I7c63d52300a1c5aa0678f29c2e4b15195411517c -Change-Id: I7c63d52300a1c5aa0678f29c2e4b15195411517c ---- - .../DevicePolicyManagerService.java | 87 +++++++++++++++---- - 1 file changed, 72 insertions(+), 15 deletions(-) - -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -index 5e67708b1adb..1549677fdbb2 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java -@@ -13497,27 +13497,47 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - CallerIdentity caller, EnforcingAdmin admin, String key, boolean enabled, - boolean parent) { - synchronized (getLockObject()) { -+ -+ int ownerType; - if (isDeviceOwner(caller)) { -- if (UserRestrictionsUtils.isGlobal(OWNER_TYPE_DEVICE_OWNER, key)) { -- setGlobalUserRestrictionInternal(admin, key, enabled); -- } else { -- setLocalUserRestrictionInternal(admin, key, enabled, caller.getUserId()); -- } -+ ownerType = OWNER_TYPE_DEVICE_OWNER; -+ } else if (isProfileOwnerOfOrganizationOwnedDevice(caller)) { -+ ownerType = OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; - } else if (isProfileOwner(caller)) { -- if (UserRestrictionsUtils.isGlobal(OWNER_TYPE_PROFILE_OWNER, key) -- || (parent && isProfileOwnerOfOrganizationOwnedDevice(caller) -- && UserRestrictionsUtils.isGlobal( -- OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, key))) { -- setGlobalUserRestrictionInternal(admin, key, enabled); -- } else { -- int affectedUserId = parent -- ? getProfileParentId(caller.getUserId()) : caller.getUserId(); -- setLocalUserRestrictionInternal(admin, key, enabled, affectedUserId); -- } -+ ownerType = OWNER_TYPE_PROFILE_OWNER; - } else { - throw new IllegalStateException("Non-DO/Non-PO cannot set restriction " + key - + " while targetSdkVersion is less than UPSIDE_DOWN_CAKE"); - } -+ setBackwardCompatibleUserRestrictionLocked(ownerType, admin, caller.getUserId(), key, -+ enabled, parent); -+ } -+ } -+ -+ private void setBackwardCompatibleUserRestrictionLocked( -+ int ownerType, EnforcingAdmin admin, int userId, String key, boolean enabled, -+ boolean parent) { -+ if (ownerType == OWNER_TYPE_DEVICE_OWNER) { -+ if (UserRestrictionsUtils.isGlobal(OWNER_TYPE_DEVICE_OWNER, key)) { -+ setGlobalUserRestrictionInternal(admin, key, enabled); -+ } else { -+ setLocalUserRestrictionInternal(admin, key, enabled, userId); -+ } -+ } else if (ownerType == OWNER_TYPE_PROFILE_OWNER -+ || ownerType == OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE) { -+ if (UserRestrictionsUtils.isGlobal(OWNER_TYPE_PROFILE_OWNER, key) -+ || (parent && ownerType == OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE -+ && UserRestrictionsUtils.isGlobal( -+ OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE, key))) { -+ setGlobalUserRestrictionInternal(admin, key, enabled); -+ } else { -+ int affectedUserId = parent -+ ? getProfileParentId(userId) : userId; -+ setLocalUserRestrictionInternal(admin, key, enabled, affectedUserId); -+ } -+ } else { -+ throw new IllegalStateException("Non-DO/Non-PO cannot set restriction " + key -+ + " while targetSdkVersion is less than UPSIDE_DOWN_CAKE"); - } - } - -@@ -24206,6 +24226,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - try { - migrateScreenCapturePolicyLocked(); - migrateLockTaskPolicyLocked(); -+ migrateUserRestrictionsLocked(); - return true; - } catch (Exception e) { - Slogf.e(LOG_TAG, e, "Error occurred during post upgrade migration to the device " -@@ -24467,6 +24488,42 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - }); - } - -+ private void migrateUserRestrictionsLocked() { -+ Binder.withCleanCallingIdentity(() -> { -+ List users = mUserManager.getUsers(); -+ for (UserInfo userInfo : users) { -+ ActiveAdmin admin = getProfileOwnerOrDeviceOwnerLocked(userInfo.id); -+ if (admin == null) continue; -+ ComponentName adminComponent = admin.info.getComponent(); -+ int userId = userInfo.id; -+ EnforcingAdmin enforcingAdmin = EnforcingAdmin.createEnterpriseEnforcingAdmin( -+ adminComponent, -+ userId, -+ admin); -+ int ownerType; -+ if (isDeviceOwner(admin)) { -+ ownerType = OWNER_TYPE_DEVICE_OWNER; -+ } else if (isProfileOwnerOfOrganizationOwnedDevice(adminComponent, userId)) { -+ ownerType = OWNER_TYPE_PROFILE_OWNER_OF_ORGANIZATION_OWNED_DEVICE; -+ } else if (isProfileOwner(adminComponent, userId)) { -+ ownerType = OWNER_TYPE_PROFILE_OWNER; -+ } else { -+ throw new IllegalStateException("Invalid DO/PO state"); -+ } -+ -+ for (final String restriction : admin.ensureUserRestrictions().keySet()) { -+ setBackwardCompatibleUserRestrictionLocked(ownerType, enforcingAdmin, userId, -+ restriction, /* enabled */ true, /* parent */ false); -+ } -+ for (final String restriction : admin.getParentActiveAdmin() -+ .ensureUserRestrictions().keySet()) { -+ setBackwardCompatibleUserRestrictionLocked(ownerType, enforcingAdmin, userId, -+ restriction, /* enabled */ true, /* parent */ true); -+ } -+ } -+ }); -+ } -+ - private List getInstalledPackagesOnUser(int userId) { - return mInjector.binderWithCleanCallingIdentity(() -> - mContext.getPackageManager().getInstalledPackagesAsUser( --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/51_0051-Check-hidden-API-exemptions.bulletin.patch b/aosp_diff/preliminary/frameworks/base/51_0051-Check-hidden-API-exemptions.bulletin.patch deleted file mode 100644 index 4be320cc36..0000000000 --- a/aosp_diff/preliminary/frameworks/base/51_0051-Check-hidden-API-exemptions.bulletin.patch +++ /dev/null @@ -1,50 +0,0 @@ -From c0c2c1ef78f213b413d0ec129aae2e27f33aa698 Mon Sep 17 00:00:00 2001 -From: Hans Boehm -Date: Tue, 2 Jan 2024 16:53:13 -0800 -Subject: [PATCH] Check hidden API exemptions - -Refuse to deal with newlines and null characters in -HiddenApiSettings.update(). Also disallow nulls in process start -arguments. - -Bug: 316153291 -Test: Treehugger for now -(cherry picked from commit 7ba059e2cf0a2c20f9a849719cdc32b12c933a44) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:60669aa49aba34c0950d6246bd95b54f91a3c8e8) -Merged-In: I83cd60e46407a4a082f9f3c80e937dbd522dbac4 -Change-Id: I83cd60e46407a4a082f9f3c80e937dbd522dbac4 ---- - core/java/android/os/ZygoteProcess.java | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java -index 3cb5c60259eb..2b84b25b92e2 100644 ---- a/core/java/android/os/ZygoteProcess.java -+++ b/core/java/android/os/ZygoteProcess.java -@@ -424,6 +424,8 @@ public class ZygoteProcess { - throw new ZygoteStartFailedEx("Embedded newlines not allowed"); - } else if (arg.indexOf('\r') >= 0) { - throw new ZygoteStartFailedEx("Embedded carriage returns not allowed"); -+ } else if (arg.indexOf('\u0000') >= 0) { -+ throw new ZygoteStartFailedEx("Embedded nulls not allowed"); - } - } - -@@ -959,6 +961,14 @@ public class ZygoteProcess { - return true; - } - -+ for (/* NonNull */ String s : mApiDenylistExemptions) { -+ // indexOf() is intrinsified and faster than contains(). -+ if (s.indexOf('\n') >= 0 || s.indexOf('\r') >= 0 || s.indexOf('\u0000') >= 0) { -+ Slog.e(LOG_TAG, "Failed to set API denylist exemptions: Bad character"); -+ mApiDenylistExemptions = Collections.emptyList(); -+ return false; -+ } -+ } - try { - state.mZygoteOutputWriter.write(Integer.toString(mApiDenylistExemptions.size() + 1)); - state.mZygoteOutputWriter.newLine(); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/52_0052--DO-NOT-MERGE-Autofill-Framework-Add-in-check-for-intent-filte.bulletin.patch b/aosp_diff/preliminary/frameworks/base/52_0052--DO-NOT-MERGE-Autofill-Framework-Add-in-check-for-intent-filte.bulletin.patch deleted file mode 100644 index 16c675bc65..0000000000 --- a/aosp_diff/preliminary/frameworks/base/52_0052--DO-NOT-MERGE-Autofill-Framework-Add-in-check-for-intent-filte.bulletin.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 96bfc01a491bafc495dd1e8b4bbd41afb065fb56 Mon Sep 17 00:00:00 2001 -From: Haoran Zhang -Date: Wed, 13 Mar 2024 17:08:00 +0000 -Subject: [PATCH] [DO NOT MERGE][Autofill Framework] Add in check for intent - filter when setting/updating service - -For test, I registered two tests around on ABTD. CtsAutoFillServiceTestCases module is passing except three known failures: - -Test run link: -- https://android-build.corp.google.com/builds/abtd/run/L33300030002610600 -- https://android-build.corp.google.com/builds/abtd/run/L58100030002616607 - - -Bug: b/324874908 -Test: atest CtsAutoFillServiceTestCases -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:141d9d050346bfc4673c429382deb1b3d210f6ad) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e8a448f855ef6ba9ae4b655e6824631f8023c0a0) -Merged-In: I51c2e3788ac29ff4d6b86aa2a735ff2ea1463a77 -Change-Id: I51c2e3788ac29ff4d6b86aa2a735ff2ea1463a77 ---- - .../autofill/AutofillManagerServiceImpl.java | 27 +++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java -index 63a607c8d0d4..7be2dea3c2f6 100644 ---- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java -+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java -@@ -32,8 +32,10 @@ import android.annotation.NonNull; - import android.annotation.Nullable; - import android.app.ActivityManagerInternal; - import android.content.ComponentName; -+import android.content.Intent; - import android.content.pm.PackageManager; - import android.content.pm.PackageManager.NameNotFoundException; -+import android.content.pm.ResolveInfo; - import android.content.pm.ServiceInfo; - import android.graphics.Rect; - import android.metrics.LogMaker; -@@ -250,6 +252,31 @@ final class AutofillManagerServiceImpl - @Override // from PerUserSystemService - protected ServiceInfo newServiceInfoLocked(@NonNull ComponentName serviceComponent) - throws NameNotFoundException { -+ final List resolveInfos = -+ getContext().getPackageManager().queryIntentServicesAsUser( -+ new Intent(AutofillService.SERVICE_INTERFACE), -+ // The MATCH_INSTANT flag is added because curret autofill CTS module is -+ // defined in one apk, which makes the test autofill service installed in a -+ // instant app when the CTS tests are running in instant app mode. -+ // TODO: Remove MATCH_INSTANT flag after completing refactoring the CTS module -+ // to make the test autofill service a separate apk. -+ PackageManager.GET_META_DATA | PackageManager.MATCH_INSTANT, -+ mUserId); -+ boolean serviceHasAutofillIntentFilter = false; -+ for (ResolveInfo resolveInfo : resolveInfos) { -+ final ServiceInfo serviceInfo = resolveInfo.serviceInfo; -+ if (serviceInfo.getComponentName().equals(serviceComponent)) { -+ serviceHasAutofillIntentFilter = true; -+ break; -+ } -+ } -+ if (!serviceHasAutofillIntentFilter) { -+ Slog.w(TAG, -+ "Autofill service from '" + serviceComponent.getPackageName() + "' does" -+ + "not have intent filter " + AutofillService.SERVICE_INTERFACE); -+ throw new SecurityException("Service does not declare intent filter " -+ + AutofillService.SERVICE_INTERFACE); -+ } - mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId); - return mInfo.getServiceInfo(); - } --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/53_0053-Ported-CTS-fixes-from-Google-QPR1-Release.patch b/aosp_diff/preliminary/frameworks/base/53_0053-Ported-CTS-fixes-from-Google-QPR1-Release.patch deleted file mode 100644 index 8425c3a37a..0000000000 --- a/aosp_diff/preliminary/frameworks/base/53_0053-Ported-CTS-fixes-from-Google-QPR1-Release.patch +++ /dev/null @@ -1,65 +0,0 @@ -From f92937e44d26a20f87d0868a019ec5bf2d181469 Mon Sep 17 00:00:00 2001 -From: Ankit Agarwal -Date: Fri, 7 Jun 2024 11:37:13 +0530 -Subject: [PATCH] Ported CTS fixes from Google QPR1 Release. - -Porting below CTS fixes- - -https://android-review.googlesource.com/c/platform/frameworks/base/+/2855186 -https://android-review.googlesource.com/c/platform/frameworks/base/+/2855185 -https://android-review.googlesource.com/c/platform/frameworks/base/+/2855166 - -Disable `sync_disabled_mode` in `DeviceConfigTest` runs. -Fix HorizontalScrollViewFunctionsTest -Ensure that DebuggerWindow is shown on headless systems. - -Ensure that DebuggerWindow is shown on headless systems. - -on headless systems, user-0 is invisible. And hence windows started by -user-0 process are not visible. - -Tests: Build EB is successfull and booting to home screen. - -Tracked-On: OAM-120405 -Signed-off-by: Ankit Agarwal ---- - .../tests/coretests/src/android/provider/DeviceConfigTest.java | 1 + - .../com/android/server/am/AppWaitingForDebuggerDialog.java | 3 +++ - 2 files changed, 4 insertions(+) - -diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java -index 1ea20f162680..a68833c974e4 100644 ---- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java -+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java -@@ -67,6 +67,7 @@ public class DeviceConfigTest { - deleteViaContentProvider(NAMESPACE, KEY); - deleteViaContentProvider(NAMESPACE, KEY2); - deleteViaContentProvider(NAMESPACE, KEY3); -+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE); - } - - @Test -diff --git a/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java -index 9b5f18caf71a..710278d6b3c6 100644 ---- a/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java -+++ b/services/core/java/com/android/server/am/AppWaitingForDebuggerDialog.java -@@ -16,6 +16,8 @@ - - package com.android.server.am; - -+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; -+ - import android.content.Context; - import android.content.DialogInterface; - import android.os.Handler; -@@ -54,6 +56,7 @@ final class AppWaitingForDebuggerDialog extends BaseErrorDialog { - setButton(DialogInterface.BUTTON_POSITIVE, "Force Close", mHandler.obtainMessage(1, app)); - setTitle("Waiting For Debugger"); - WindowManager.LayoutParams attrs = getWindow().getAttributes(); -+ attrs.privateFlags |= SYSTEM_FLAG_SHOW_FOR_ALL_USERS; - attrs.setTitle("Waiting For Debugger: " + app.info.processName); - getWindow().setAttributes(attrs); - } --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/53_0053-RESTRICT-AUTOMERGE-AccessibilityManagerService-remove-uninsta.bulletin.patch b/aosp_diff/preliminary/frameworks/base/53_0053-RESTRICT-AUTOMERGE-AccessibilityManagerService-remove-uninsta.bulletin.patch deleted file mode 100644 index a7d681f6d5..0000000000 --- a/aosp_diff/preliminary/frameworks/base/53_0053-RESTRICT-AUTOMERGE-AccessibilityManagerService-remove-uninsta.bulletin.patch +++ /dev/null @@ -1,62 +0,0 @@ -From c1bc907a649addd5b97d489fd39afb956164a46c Mon Sep 17 00:00:00 2001 -From: Ameer Armaly -Date: Fri, 8 Mar 2024 19:41:06 +0000 -Subject: [PATCH] [RESTRICT AUTOMERGE] AccessibilityManagerService: remove - uninstalled services from enabled list after service update. - -Bug: 326485767 -Test: atest AccessibilityEndToEndTest#testUpdateServiceWithoutIntent_disablesService -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f6192d3a77520d40b6a93de8f45400e19f5ba29f) -Merged-In: Ia86857d58ebab925ec6e55f9e5fa64e265326ec0 -Change-Id: Ia86857d58ebab925ec6e55f9e5fa64e265326ec0 ---- - .../AccessibilityManagerService.java | 22 +++++++++++++++++++ - 1 file changed, 22 insertions(+) - -diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -index 531227947ba0..7bb7c4a81a7d 100644 ---- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java -@@ -2398,10 +2398,13 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub - userState.mComponentNameToServiceMap; - boolean isUnlockingOrUnlocked = mUmi.isUserUnlockingOrUnlocked(userState.mUserId); - -+ // Store the list of installed services. -+ mTempComponentNameSet.clear(); - for (int i = 0, count = userState.mInstalledServices.size(); i < count; i++) { - AccessibilityServiceInfo installedService = userState.mInstalledServices.get(i); - ComponentName componentName = ComponentName.unflattenFromString( - installedService.getId()); -+ mTempComponentNameSet.add(componentName); - - AccessibilityServiceConnection service = componentNameToServiceMap.get(componentName); - -@@ -2461,6 +2464,25 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub - audioManager.setAccessibilityServiceUids(mTempIntArray); - } - mActivityTaskManagerService.setAccessibilityServiceUids(mTempIntArray); -+ // If any services have been removed, remove them from the enabled list and the touch -+ // exploration granted list. -+ boolean anyServiceRemoved = -+ userState.mEnabledServices.removeIf((comp) -> !mTempComponentNameSet.contains(comp)) -+ || userState.mTouchExplorationGrantedServices.removeIf( -+ (comp) -> !mTempComponentNameSet.contains(comp)); -+ if (anyServiceRemoved) { -+ // Update the enabled services setting. -+ persistComponentNamesToSettingLocked( -+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, -+ userState.mEnabledServices, -+ userState.mUserId); -+ // Update the touch exploration granted services setting. -+ persistComponentNamesToSettingLocked( -+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES, -+ userState.mTouchExplorationGrantedServices, -+ userState.mUserId); -+ } -+ mTempComponentNameSet.clear(); - updateAccessibilityEnabledSettingLocked(userState); - } - --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/frameworks/base/54_0054-PM-Send-ACTION_PACKAGE_CHANGED-when-mimeGroups-are-changed.bulletin.patch b/aosp_diff/preliminary/frameworks/base/54_0054-PM-Send-ACTION_PACKAGE_CHANGED-when-mimeGroups-are-changed.bulletin.patch deleted file mode 100644 index 9ca9d5c6cf..0000000000 --- a/aosp_diff/preliminary/frameworks/base/54_0054-PM-Send-ACTION_PACKAGE_CHANGED-when-mimeGroups-are-changed.bulletin.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 352a84fa6c0f3a8df37df627ef0dbc0e08916e48 Mon Sep 17 00:00:00 2001 -From: Ivan Chiang -Date: Mon, 18 Mar 2024 02:46:56 +0000 -Subject: [PATCH] [PM] Send ACTION_PACKAGE_CHANGED when mimeGroups are changed - -Test: atest CtsPackageManagerTestCases:PackageManagerShellCommandMultiUserTest -Test: atest CtsPackageManagerTestCases:PackageManagerTest -Bug: 297517712 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:81eb9f8294645684ce1fad39d5d4a00ef11736e4) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c160424ef22bffd25a9cc9bc7b901ae1b9721a72) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4217415dbe8e83ba4c8bf56ac6ff21523187f59f) -Merged-In: I271a3526ea4555249e3a2797605269257330e0e9 -Change-Id: I271a3526ea4555249e3a2797605269257330e0e9 ---- - .../server/pm/PackageManagerService.java | 23 ++++++++++++++++--- - 1 file changed, 20 insertions(+), 3 deletions(-) - -diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java -index f2b62eaf25f8..cac96e544432 100644 ---- a/services/core/java/com/android/server/pm/PackageManagerService.java -+++ b/services/core/java/com/android/server/pm/PackageManagerService.java -@@ -6160,9 +6160,26 @@ public class PackageManagerService implements PackageSender, TestUtilityService - packageStateWrite.setMimeGroup(mimeGroup, mimeTypesSet); - }); - if (mComponentResolver.updateMimeGroup(snapshotComputer(), packageName, mimeGroup)) { -- Binder.withCleanCallingIdentity(() -> -- mPreferredActivityHelper.clearPackagePreferredActivities(packageName, -- UserHandle.USER_ALL)); -+ Binder.withCleanCallingIdentity(() -> { -+ mPreferredActivityHelper.clearPackagePreferredActivities(packageName, -+ UserHandle.USER_ALL); -+ // Send the ACTION_PACKAGE_CHANGED when the mimeGroup has changes -+ final Computer snapShot = snapshotComputer(); -+ final ArrayList components = new ArrayList<>( -+ Collections.singletonList(packageName)); -+ final int appId = packageState.getAppId(); -+ final int[] userIds = resolveUserIds(UserHandle.USER_ALL); -+ final String reason = "The mimeGroup is changed"; -+ for (int i = 0; i < userIds.length; i++) { -+ final PackageUserStateInternal pkgUserState = -+ packageState.getUserStates().get(userIds[i]); -+ if (pkgUserState != null && pkgUserState.isInstalled()) { -+ final int packageUid = UserHandle.getUid(userIds[i], appId); -+ sendPackageChangedBroadcast(snapShot, packageName, -+ true /* dontKillApp */, components, packageUid, reason); -+ } -+ } -+ }); - } - - scheduleWriteSettings(); --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/frameworks/base/55_0055-Fix-security-vulnerability-allowing-apps-to-start-from-backgroun.bulletin.patch b/aosp_diff/preliminary/frameworks/base/55_0055-Fix-security-vulnerability-allowing-apps-to-start-from-backgroun.bulletin.patch deleted file mode 100644 index 6af386e843..0000000000 --- a/aosp_diff/preliminary/frameworks/base/55_0055-Fix-security-vulnerability-allowing-apps-to-start-from-backgroun.bulletin.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 9c8c745df069b86bf81d586e0af910996809db51 Mon Sep 17 00:00:00 2001 -From: Bishoy Gendy -Date: Thu, 11 Apr 2024 16:37:10 +0000 -Subject: [PATCH] Fix security vulnerability allowing apps to start from - background - -Bug: 317048338 -Test: Using the steps in b/317048338#comment12 -(cherry picked from commit c5fc8ea92c0aabbb2fdccc23b743c18a8bf62e64) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df3584bb93ab89d7e174f7d39e42d4b22cb92fe0) -Merged-In: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759 -Change-Id: Ia91199fdb23beed27bde687fdca8fe5d3a5a4759 ---- - .../media/session/ParcelableListBinder.java | 13 +++++++++++-- - .../android/server/media/MediaSessionRecord.java | 14 ++++++++------ - 2 files changed, 19 insertions(+), 8 deletions(-) - -diff --git a/media/java/android/media/session/ParcelableListBinder.java b/media/java/android/media/session/ParcelableListBinder.java -index bbf1e0889b68..d78828462b1e 100644 ---- a/media/java/android/media/session/ParcelableListBinder.java -+++ b/media/java/android/media/session/ParcelableListBinder.java -@@ -45,6 +45,7 @@ public class ParcelableListBinder extends Binder { - private static final int END_OF_PARCEL = 0; - private static final int ITEM_CONTINUED = 1; - -+ private final Class mListElementsClass; - private final Consumer> mConsumer; - - private final Object mLock = new Object(); -@@ -61,9 +62,11 @@ public class ParcelableListBinder extends Binder { - /** - * Creates an instance. - * -+ * @param listElementsClass the class of the list elements. - * @param consumer a consumer that consumes the list received - */ -- public ParcelableListBinder(@NonNull Consumer> consumer) { -+ public ParcelableListBinder(Class listElementsClass, @NonNull Consumer> consumer) { -+ mListElementsClass = listElementsClass; - mConsumer = consumer; - } - -@@ -83,7 +86,13 @@ public class ParcelableListBinder extends Binder { - mCount = data.readInt(); - } - while (i < mCount && data.readInt() != END_OF_PARCEL) { -- mList.add(data.readParcelable(null)); -+ Object object = data.readParcelable(null); -+ if (mListElementsClass.isAssignableFrom(object.getClass())) { -+ // Checking list items are of compaitible types to validate against malicious -+ // apps calling it directly via reflection with non compilable items. -+ // See b/317048338 for more details -+ mList.add((T) object); -+ } - i++; - } - if (i >= mCount) { -diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java -index 4084462d3f28..4ff83b296a2a 100644 ---- a/services/core/java/com/android/server/media/MediaSessionRecord.java -+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java -@@ -1197,12 +1197,14 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR - - @Override - public IBinder getBinderForSetQueue() throws RemoteException { -- return new ParcelableListBinder((list) -> { -- synchronized (mLock) { -- mQueue = list; -- } -- mHandler.post(MessageHandler.MSG_UPDATE_QUEUE); -- }); -+ return new ParcelableListBinder( -+ QueueItem.class, -+ (list) -> { -+ synchronized (mLock) { -+ mQueue = list; -+ } -+ mHandler.post(MessageHandler.MSG_UPDATE_QUEUE); -+ }); - } - - @Override --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/frameworks/base/56_0056-Verify-UID-of-incoming-Zygote-connections-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/56_0056-Verify-UID-of-incoming-Zygote-connections-.bulletin.patch deleted file mode 100644 index 7b5794d4fd..0000000000 --- a/aosp_diff/preliminary/frameworks/base/56_0056-Verify-UID-of-incoming-Zygote-connections-.bulletin.patch +++ /dev/null @@ -1,179 +0,0 @@ -From 7905ffaa89e7a921d5a97f86fc320e336f359c32 Mon Sep 17 00:00:00 2001 -From: Martijn Coenen -Date: Thu, 29 Feb 2024 12:03:05 +0000 -Subject: [PATCH] Verify UID of incoming Zygote connections. - -Only the system UID should be allowed to connect to the Zygote. While -for generic Zygotes this is also covered by SELinux policy, this is not -true for App Zygotes: the preload code running in an app zygote could -connect to another app zygote socket, if it had access to its (random) -socket address. - -On the Java layer, simply check the UID when the connection is made. In -the native layer, this check was already present, but it actually didn't -work in the case where we receive a new incoming connection on the -socket, and receive a 'non-fork' command: in that case, we will simply -exit the native loop, and let the Java layer handle the command, without -any further UID checking. - -Modified the native logic to drop new connections with a mismatching -UID, and to keep serving the existing connection (if it was still -there). - -Bug: 319081336 -Test: manual -(cherry picked from commit 2ffc7cb220e4220b7e108c4043a3f0f2a85b6508) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e4b3ba817073b66ee37da8f1aba93b345309b435) -Merged-In: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532 -Change-Id: I3f85a17107849e2cd3e82d6ef15c90b9e2f26532 ---- - .../android/internal/os/ZygoteConnection.java | 3 + - ...ndroid_internal_os_ZygoteCommandBuffer.cpp | 82 ++++++++++++------- - 2 files changed, 56 insertions(+), 29 deletions(-) - -diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java -index 993e4e7b4b3d..765901a043a0 100644 ---- a/core/java/com/android/internal/os/ZygoteConnection.java -+++ b/core/java/com/android/internal/os/ZygoteConnection.java -@@ -93,6 +93,9 @@ class ZygoteConnection { - throw ex; - } - -+ if (peer.getUid() != Process.SYSTEM_UID) { -+ throw new ZygoteSecurityException("Only system UID is allowed to connect to Zygote."); -+ } - isEof = false; - } - -diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp -index 2b5b8f7a108e..b586b9c27dd8 100644 ---- a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp -+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp -@@ -353,6 +353,18 @@ jstring com_android_internal_os_ZygoteCommandBuffer_nativeNextArg(JNIEnv* env, j - return result; - } - -+static uid_t getSocketPeerUid(int socket, const std::function& fail_fn) { -+ struct ucred credentials; -+ socklen_t cred_size = sizeof credentials; -+ if (getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1 -+ || cred_size != sizeof credentials) { -+ fail_fn(CREATE_ERROR("Failed to get socket credentials, %s", -+ strerror(errno))); -+ } -+ -+ return credentials.uid; -+} -+ - // Read all lines from the current command into the buffer, and then reset the buffer, so - // we will start reading again at the beginning of the command, starting with the argument - // count. And we don't need access to the fd to do so. -@@ -412,19 +424,12 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( - fail_fn_z("Failed to retrieve session socket timeout"); - } - -- struct ucred credentials; -- socklen_t cred_size = sizeof credentials; -- if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1 -- || cred_size != sizeof credentials) { -- fail_fn_1(CREATE_ERROR("ForkRepeatedly failed to get initial credentials, %s", -- strerror(errno))); -+ uid_t peerUid = getSocketPeerUid(session_socket, fail_fn_1); -+ if (peerUid != static_cast(expected_uid)) { -+ return JNI_FALSE; - } -- - bool first_time = true; - do { -- if (credentials.uid != expected_uid) { -- return JNI_FALSE; -- } - n_buffer->readAllLines(first_time ? fail_fn_1 : fail_fn_n); - n_buffer->reset(); - int pid = zygote::forkApp(env, /* no pipe FDs */ -1, -1, session_socket_fds, -@@ -454,30 +459,56 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( - // Clear buffer and get count from next command. - n_buffer->clear(); - for (;;) { -+ bool valid_session_socket = true; - // Poll isn't strictly necessary for now. But without it, disconnect is hard to detect. - int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */)); - if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) { - if (n_buffer->getCount(fail_fn_z) != 0) { - break; -- } // else disconnected; -+ } else { -+ // Session socket was disconnected -+ valid_session_socket = false; -+ close(session_socket); -+ } - } else if (poll_res == 0 || (fd_structs[ZYGOTE_IDX].revents & POLLIN) == 0) { - fail_fn_z( - CREATE_ERROR("Poll returned with no descriptors ready! Poll returned %d", poll_res)); - } -- // We've now seen either a disconnect or connect request. -- close(session_socket); -- int new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr)); -+ int new_fd = -1; -+ do { -+ // We've now seen either a disconnect or connect request. -+ new_fd = TEMP_FAILURE_RETRY(accept(zygote_socket_fd, nullptr, nullptr)); -+ if (new_fd == -1) { -+ fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno))); -+ } -+ uid_t newPeerUid = getSocketPeerUid(new_fd, fail_fn_1); -+ if (newPeerUid != static_cast(expected_uid)) { -+ ALOGW("Dropping new connection with a mismatched uid %d\n", newPeerUid); -+ close(new_fd); -+ new_fd = -1; -+ } else { -+ // If we still have a valid session socket, close it now -+ if (valid_session_socket) { -+ close(session_socket); -+ } -+ valid_session_socket = true; -+ } -+ } while (!valid_session_socket); -+ -+ // At this point we either have a valid new connection (new_fd > 0), or -+ // an existing session socket we can poll on - if (new_fd == -1) { -- fail_fn_z(CREATE_ERROR("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno))); -+ // The new connection wasn't valid, and we still have an old one; retry polling -+ continue; - } - if (new_fd != session_socket) { -- // Move new_fd back to the old value, so that we don't have to change Java-level data -- // structures to reflect a change. This implicitly closes the old one. -- if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) { -- fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s", -- new_fd, session_socket, strerror(errno))); -- } -- close(new_fd); // On Linux, fd is closed even if EINTR is returned. -+ // Move new_fd back to the old value, so that we don't have to change Java-level data -+ // structures to reflect a change. This implicitly closes the old one. -+ if (TEMP_FAILURE_RETRY(dup2(new_fd, session_socket)) != session_socket) { -+ fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s", -+ new_fd, session_socket, strerror(errno))); -+ } -+ close(new_fd); // On Linux, fd is closed even if EINTR is returned. - } - // If we ever return, we effectively reuse the old Java ZygoteConnection. - // None of its state needs to change. -@@ -489,13 +520,6 @@ jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly( - fail_fn_z(CREATE_ERROR("Failed to set send timeout for socket %d: %s", - session_socket, strerror(errno))); - } -- if (getsockopt(session_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1) { -- fail_fn_z(CREATE_ERROR("ForkMany failed to get credentials: %s", strerror(errno))); -- } -- if (cred_size != sizeof credentials) { -- fail_fn_z(CREATE_ERROR("ForkMany credential size = %d, should be %d", -- cred_size, static_cast(sizeof credentials))); -- } - } - first_time = false; - } while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n)); --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/frameworks/base/57_0057-Avoid-HIGH_ACCURACY-request-from-stationary-throttli.patch b/aosp_diff/preliminary/frameworks/base/57_0057-Avoid-HIGH_ACCURACY-request-from-stationary-throttli.patch deleted file mode 100644 index 6f4e7f3c8f..0000000000 --- a/aosp_diff/preliminary/frameworks/base/57_0057-Avoid-HIGH_ACCURACY-request-from-stationary-throttli.patch +++ /dev/null @@ -1,72 +0,0 @@ -From d80992c115c6c4af39a4434a53434dee2aef2081 Mon Sep 17 00:00:00 2001 -From: Yu-Han Yang -Date: Thu, 11 Jul 2024 04:34:06 +0000 -Subject: [PATCH 1/2] Avoid HIGH_ACCURACY request from stationary throttling - -Bug: 319054085 -Test: atest StationThrottlingLocationProviderTest -Change-Id: I33e945b62c660db7e0ecce45ca6959213cd64bf4 ---- - .../StationaryThrottlingLocationProvider.java | 2 ++ - ...ationaryThrottlingLocationProviderTest.java | 18 ++++++++++++++++++ - 2 files changed, 20 insertions(+) - -diff --git a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java -index 5e38bca78a7c..da7c65ab2611 100644 ---- a/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java -+++ b/services/core/java/com/android/server/location/provider/StationaryThrottlingLocationProvider.java -@@ -27,6 +27,7 @@ import static java.lang.Math.max; - - import android.annotation.Nullable; - import android.location.Location; -+import android.location.LocationRequest; - import android.location.LocationResult; - import android.location.provider.ProviderRequest; - import android.os.SystemClock; -@@ -179,6 +180,7 @@ public final class StationaryThrottlingLocationProvider extends DelegateLocation - private void onThrottlingChangedLocked(boolean deliverImmediate) { - long throttlingIntervalMs = INTERVAL_DISABLED; - if (mDeviceStationary && mDeviceIdle && !mIncomingRequest.isLocationSettingsIgnored() -+ && mIncomingRequest.getQuality() != LocationRequest.QUALITY_HIGH_ACCURACY - && mLastLocation != null - && mLastLocation.getElapsedRealtimeAgeMillis(mDeviceStationaryRealtimeMs) - <= MAX_STATIONARY_LOCATION_AGE_MS) { -diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java -index 4eba21934a4e..82afaba96031 100644 ---- a/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java -+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/StationaryThrottlingLocationProviderTest.java -@@ -29,6 +29,7 @@ import static org.mockito.MockitoAnnotations.initMocks; - - import android.content.Context; - import android.location.Location; -+import android.location.LocationRequest; - import android.location.LocationResult; - import android.location.provider.ProviderRequest; - import android.platform.test.annotations.Presubmit; -@@ -213,6 +214,23 @@ public class StationaryThrottlingLocationProviderTest { - mDelegateProvider.reportLocation(loc); - verify(mListener, times(1)).onReportLocation(loc); - -+ mInjector.getDeviceStationaryHelper().setStationary(true); -+ mInjector.getDeviceIdleHelper().setIdle(true); -+ verify(mDelegate, never()).onSetRequest(ProviderRequest.EMPTY_REQUEST); -+ verify(mListener, after(75).times(1)).onReportLocation(any(LocationResult.class)); -+ } -+ @Test -+ public void testNoThrottle_highAccuracy() { -+ ProviderRequest request = new ProviderRequest.Builder().setIntervalMillis( -+ 50).setQuality(LocationRequest.QUALITY_HIGH_ACCURACY).build(); -+ -+ mProvider.getController().setRequest(request); -+ verify(mDelegate).onSetRequest(request); -+ -+ LocationResult loc = createLocationResult("test_provider", mRandom); -+ mDelegateProvider.reportLocation(loc); -+ verify(mListener, times(1)).onReportLocation(loc); -+ - mInjector.getDeviceStationaryHelper().setStationary(true); - mInjector.getDeviceIdleHelper().setIdle(true); - verify(mDelegate, never()).onSetRequest(ProviderRequest.EMPTY_REQUEST); --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/58_0058-Apply-pending-transactions-always.patch b/aosp_diff/preliminary/frameworks/base/58_0058-Apply-pending-transactions-always.patch deleted file mode 100644 index 5b88d5d49f..0000000000 --- a/aosp_diff/preliminary/frameworks/base/58_0058-Apply-pending-transactions-always.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 5765b54e8590aea70bbd51652e96e8d8293a08bd Mon Sep 17 00:00:00 2001 -From: John Reck -Date: Fri, 12 Jul 2024 09:20:37 +0000 -Subject: [PATCH 2/2] Apply pending transactions always - -Test: repro in bug -Bug: 334901521 - -Change-Id: I8f856e7be5917a1d01f0ee2bdbe613bf37045646 -(cherry picked from commit 54526e9b29556ede6c22a07fad83cc6cc8163915) ---- - core/java/android/view/ViewRootImpl.java | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java -index cd2d36c60ade..f47932fd32c3 100644 ---- a/core/java/android/view/ViewRootImpl.java -+++ b/core/java/android/view/ViewRootImpl.java -@@ -4024,7 +4024,15 @@ public final class ViewRootImpl implements ViewParent, - mReportNextDraw = false; - mLastReportNextDrawReason = null; - mActiveSurfaceSyncGroup = null; -- mSyncBuffer = false; -+ if (mHasPendingTransactions) { -+ // TODO: We shouldn't ever actually hit this, it means mPendingTransaction wasn't -+ // merged with a sync group or BLASTBufferQueue before making it to this point -+ // But better a one or two frame flicker than steady-state broken from dropping -+ // whatever is in this transaction -+ mPendingTransaction.apply(); -+ mHasPendingTransactions = false; -+ } -+ mSyncBuffer = false; - if (isInWMSRequestedSync()) { - mWmsRequestSyncGroup.markSyncReady(); - mWmsRequestSyncGroup = null; --- -2.34.1 - diff --git a/aosp_diff/preliminary/frameworks/base/59_0059-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch b/aosp_diff/preliminary/frameworks/base/59_0059-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch deleted file mode 100644 index ce8709e1de..0000000000 --- a/aosp_diff/preliminary/frameworks/base/59_0059-Fix-error-handling-for-non-dynamic-permissions.bulletin.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6c22d6c1e69676c5c68d21928aa5486bfd1bd131 Mon Sep 17 00:00:00 2001 -From: Yi-an Chen -Date: Wed, 21 Feb 2024 01:56:22 +0000 -Subject: [PATCH] Fix error handling for non-dynamic permissions - -We only allow removing dynamic permissions. When removePermission() is -called for a non-dynamic permission, in addition to logging it, we -should also return early to avoid the removePermission() call. - -Test: manual -Bug: 321555066 -Fixes: 321711213 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:528a87e90ff9354581d54fd37fbe9f95cccbcdb1) -Merged-In: Ie2f43663bc71a06ffadb868d2d0eea5ee78f76e5 -Change-Id: Ie2f43663bc71a06ffadb868d2d0eea5ee78f76e5 ---- - .../server/pm/permission/PermissionManagerServiceImpl.java | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java -index 2499529f0fc0..a79f912747cd 100644 ---- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java -+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java -@@ -695,6 +695,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt - // TODO: switch this back to SecurityException - Slog.wtf(TAG, "Not allowed to modify non-dynamic permission " - + permName); -+ return; - } - mRegistry.removePermission(permName); - } --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/60_0060-Security-fix-for-VPN-app-killable-via-lockscreen-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/60_0060-Security-fix-for-VPN-app-killable-via-lockscreen-.bulletin.patch deleted file mode 100644 index 4c72ef6d91..0000000000 --- a/aosp_diff/preliminary/frameworks/base/60_0060-Security-fix-for-VPN-app-killable-via-lockscreen-.bulletin.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 207584fb6f820eba14251251d7e9331bfd57adb8 Mon Sep 17 00:00:00 2001 -From: Faye Yan -Date: Mon, 22 Apr 2024 21:53:07 +0000 -Subject: [PATCH] Security fix for VPN app killable via lockscreen. - -Do not show the active apps dialog when the screen is locked. -Instead prompt the user to unlock directly if clicked and only open the dialog on -successsful unlock. - -Flag: NONE -Bug: 304772709 -Test: manually, locked and unlocked -Test: atest com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModelTest - -(cherry picked from commit d7628d5621c912399cefcddd9977199d62df320c) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:598d7a18601a04b9904f0e170cc7c1777a3389ff) -Merged-In: I384699d478e5abcee3a165afc45211b9ed96334a -Change-Id: I384699d478e5abcee3a165afc45211b9ed96334a ---- - .../footer/ui/viewmodel/FooterActionsViewModel.kt | 13 ++++++++++++- - .../systemui/qs/footer/FooterActionsTestUtils.kt | 4 +++- - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt -index b3596a254b7d..b9258ac1497a 100644 ---- a/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt -+++ b/packages/SystemUI/src/com/android/systemui/qs/footer/ui/viewmodel/FooterActionsViewModel.kt -@@ -30,6 +30,7 @@ import com.android.systemui.common.shared.model.Icon - import com.android.systemui.dagger.SysUISingleton - import com.android.systemui.dagger.qualifiers.Application - import com.android.systemui.globalactions.GlobalActionsDialogLite -+import com.android.systemui.plugins.ActivityStarter - import com.android.systemui.plugins.FalsingManager - import com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED - import com.android.systemui.qs.footer.data.model.UserSwitcherStatusModel -@@ -54,6 +55,7 @@ class FooterActionsViewModel( - private val footerActionsInteractor: FooterActionsInteractor, - private val falsingManager: FalsingManager, - private val globalActionsDialogLite: GlobalActionsDialogLite, -+ private val activityStarter: ActivityStarter, - showPowerButton: Boolean, - ) { - /** The context themed with the Quick Settings colors. */ -@@ -222,7 +224,14 @@ class FooterActionsViewModel( - return - } - -- footerActionsInteractor.showForegroundServicesDialog(expandable) -+ activityStarter.dismissKeyguardThenExecute( -+ { -+ footerActionsInteractor.showForegroundServicesDialog(expandable) -+ false /* if the dismiss should be deferred */ -+ }, -+ null /* cancelAction */, -+ true /* afterKeyguardGone */ -+ ) - } - - private fun onUserSwitcherClicked(expandable: Expandable) { -@@ -283,6 +292,7 @@ class FooterActionsViewModel( - private val falsingManager: FalsingManager, - private val footerActionsInteractor: FooterActionsInteractor, - private val globalActionsDialogLiteProvider: Provider, -+ private val activityStarter: ActivityStarter, - @Named(PM_LITE_ENABLED) private val showPowerButton: Boolean, - ) { - /** Create a [FooterActionsViewModel] bound to the lifecycle of [lifecycleOwner]. */ -@@ -308,6 +318,7 @@ class FooterActionsViewModel( - footerActionsInteractor, - falsingManager, - globalActionsDialogLite, -+ activityStarter, - showPowerButton, - ) - } -diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt -index 1a893f8c523c..a94acf9c8106 100644 ---- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt -+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/footer/FooterActionsTestUtils.kt -@@ -68,6 +68,7 @@ class FooterActionsTestUtils( - private val testableLooper: TestableLooper, - private val scheduler: TestCoroutineScheduler, - ) { -+ private val mockActivityStarter: ActivityStarter = mock() - /** Enable or disable the user switcher in the settings. */ - fun setUserSwitcherEnabled(settings: GlobalSettings, enabled: Boolean, userId: Int) { - settings.putBoolForUser(Settings.Global.USER_SWITCHER_ENABLED, enabled, userId) -@@ -90,13 +91,14 @@ class FooterActionsTestUtils( - footerActionsInteractor, - falsingManager, - globalActionsDialogLite, -+ mockActivityStarter, - showPowerButton, - ) - } - - /** Create a [FooterActionsInteractor] to be used in tests. */ - fun footerActionsInteractor( -- activityStarter: ActivityStarter = mock(), -+ activityStarter: ActivityStarter = mockActivityStarter, - metricsLogger: MetricsLogger = FakeMetricsLogger(), - uiEventLogger: UiEventLogger = UiEventLoggerFake(), - deviceProvisionedController: DeviceProvisionedController = mock(), --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/61_0061-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch b/aosp_diff/preliminary/frameworks/base/61_0061-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch deleted file mode 100644 index c2eed365b6..0000000000 --- a/aosp_diff/preliminary/frameworks/base/61_0061-Rate-limiting-PiP-aspect-ratio-change-request.bulletin.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 8b473b3f79642f42eeeffbfe572df6c6cbe9d79e Mon Sep 17 00:00:00 2001 -From: Hongwei Wang -Date: Tue, 1 Aug 2023 16:00:31 -0700 -Subject: [PATCH] Rate limiting PiP aspect ratio change request - -Using CountQuotaTrack to limit how frequent an app can request aspect -ratio change via PictureInPictureParams, which could result flood of PiP -resizing requests and freeze the PiP window. - -Note that CountQuotaTrack is initialized out of the WM lock to avoid -dead lock with the AM one. - -Bug: 283103220 -Test: Manually, using the POC app -Test: Manually, switching YT PiP video functions at a regular rate -Test: atest WindowOrganizerTests ActivityThreadTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8d814cc3b2fc94c8c47861abbcb3cec72aceb07e) -Merged-In: Icb7dd17bbf7df573a9bb28f3dc56e90e78384f4f -Change-Id: Icb7dd17bbf7df573a9bb28f3dc56e90e78384f4f ---- - .../server/wm/ActivityClientController.java | 39 +++++++++++++++++++ - .../server/wm/WindowOrganizerTests.java | 6 +++ - 2 files changed, 45 insertions(+) - -diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java -index aafff2c70b8b..f2567561ed8c 100644 ---- a/services/core/java/com/android/server/wm/ActivityClientController.java -+++ b/services/core/java/com/android/server/wm/ActivityClientController.java -@@ -96,6 +96,7 @@ import android.view.RemoteAnimationDefinition; - import android.window.SizeConfigurationBuckets; - import android.window.TransitionInfo; - -+import com.android.internal.annotations.VisibleForTesting; - import com.android.internal.app.AssistUtils; - import com.android.internal.policy.IKeyguardDismissCallback; - import com.android.internal.protolog.common.ProtoLog; -@@ -104,6 +105,9 @@ import com.android.server.Watchdog; - import com.android.server.pm.KnownPackages; - import com.android.server.pm.pkg.AndroidPackage; - import com.android.server.uri.NeededUriGrants; -+import com.android.server.utils.quota.Categorizer; -+import com.android.server.utils.quota.Category; -+import com.android.server.utils.quota.CountQuotaTracker; - import com.android.server.vr.VrManagerInternal; - - /** -@@ -119,6 +123,13 @@ class ActivityClientController extends IActivityClientController.Stub { - private final ActivityTaskSupervisor mTaskSupervisor; - private final Context mContext; - -+ // Prevent malicious app abusing the Activity#setPictureInPictureParams API -+ @VisibleForTesting CountQuotaTracker mSetPipAspectRatioQuotaTracker; -+ // Limit to 60 times / minute -+ private static final int SET_PIP_ASPECT_RATIO_LIMIT = 60; -+ // The timeWindowMs here can not be smaller than QuotaTracker#MIN_WINDOW_SIZE_MS -+ private static final long SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS = 60_000; -+ - /** Wrapper around VoiceInteractionServiceManager. */ - private AssistUtils mAssistUtils; - -@@ -869,6 +880,7 @@ class ActivityClientController extends IActivityClientController.Stub { - public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) { - final long origId = Binder.clearCallingIdentity(); - try { -+ ensureSetPipAspectRatioQuotaTracker(); - synchronized (mGlobalLock) { - final ActivityRecord r = ensureValidPictureInPictureActivityParams( - "enterPictureInPictureMode", token, params); -@@ -883,6 +895,7 @@ class ActivityClientController extends IActivityClientController.Stub { - public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) { - final long origId = Binder.clearCallingIdentity(); - try { -+ ensureSetPipAspectRatioQuotaTracker(); - synchronized (mGlobalLock) { - final ActivityRecord r = ensureValidPictureInPictureActivityParams( - "setPictureInPictureParams", token, params); -@@ -934,6 +947,19 @@ class ActivityClientController extends IActivityClientController.Stub { - } - } - -+ /** -+ * Initialize the {@link #mSetPipAspectRatioQuotaTracker} if applicable, which should happen -+ * out of {@link #mGlobalLock} to avoid deadlock (AM lock is used in QuotaTrack ctor). -+ */ -+ private void ensureSetPipAspectRatioQuotaTracker() { -+ if (mSetPipAspectRatioQuotaTracker == null) { -+ mSetPipAspectRatioQuotaTracker = new CountQuotaTracker(mContext, -+ Categorizer.SINGLE_CATEGORIZER); -+ mSetPipAspectRatioQuotaTracker.setCountLimit(Category.SINGLE_CATEGORY, -+ SET_PIP_ASPECT_RATIO_LIMIT, SET_PIP_ASPECT_RATIO_TIME_WINDOW_MS); -+ } -+ } -+ - /** - * Checks the state of the system and the activity associated with the given {@param token} to - * verify that picture-in-picture is supported for that activity. -@@ -958,6 +984,19 @@ class ActivityClientController extends IActivityClientController.Stub { - + ": Current activity does not support picture-in-picture."); - } - -+ // Rate limit how frequent an app can request aspect ratio change via -+ // Activity#setPictureInPictureParams -+ final int userId = UserHandle.getCallingUserId(); -+ if (r.pictureInPictureArgs.hasSetAspectRatio() -+ && params.hasSetAspectRatio() -+ && !r.pictureInPictureArgs.getAspectRatio().equals( -+ params.getAspectRatio()) -+ && !mSetPipAspectRatioQuotaTracker.noteEvent( -+ userId, r.packageName, "setPipAspectRatio")) { -+ throw new IllegalStateException(caller -+ + ": Too many PiP aspect ratio change requests from " + r.packageName); -+ } -+ - final float minAspectRatio = mContext.getResources().getFloat( - com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); - final float maxAspectRatio = mContext.getResources().getFloat( -diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java -index 600681fb332c..92135e4a0206 100644 ---- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java -+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java -@@ -1104,6 +1104,12 @@ public class WindowOrganizerTests extends WindowTestsBase { - assertNotNull(o.mInfo); - assertNotNull(o.mInfo.pictureInPictureParams); - -+ // Bypass the quota check, which causes NPE in current test setup. -+ if (mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker != null) { -+ mWm.mAtmService.mActivityClientController.mSetPipAspectRatioQuotaTracker -+ .setEnabled(false); -+ } -+ - final PictureInPictureParams p2 = new PictureInPictureParams.Builder() - .setAspectRatio(new Rational(3, 4)).build(); - mWm.mAtmService.mActivityClientController.setPictureInPictureParams(record.token, p2); --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/62_0062-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch b/aosp_diff/preliminary/frameworks/base/62_0062-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch deleted file mode 100644 index 70709119af..0000000000 --- a/aosp_diff/preliminary/frameworks/base/62_0062-Restrict-USB-poups-while-setup-is-in-progress.bulletin.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 50e1f8f36e32928d10e72324c05a203a6db9f7fb Mon Sep 17 00:00:00 2001 -From: Kiran S -Date: Mon, 13 May 2024 05:49:06 +0000 -Subject: [PATCH] Restrict USB poups while setup is in progress - -Test: Cherry pick of http://ag/27094197 -Bug: 294105066 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:2ce2e54a040342373e401f9c2e70035ede4e63ad) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:71042ac086b3470f4086c5c76fc2b6c4e3dff263) -Merged-In: I7d54534696fd73f3b94c5b4250142eed9341c5d8 -Change-Id: I7d54534696fd73f3b94c5b4250142eed9341c5d8 ---- - .../usb/UsbProfileGroupSettingsManager.java | 21 +++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java -index f91666081e82..47f565606a1d 100644 ---- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java -+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java -@@ -16,6 +16,8 @@ - - package com.android.server.usb; - -+import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; -+ - import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE; - - import android.annotation.NonNull; -@@ -42,6 +44,7 @@ import android.os.AsyncTask; - import android.os.Environment; - import android.os.UserHandle; - import android.os.UserManager; -+import android.provider.Settings; - import android.service.usb.UsbProfileGroupSettingsManagerProto; - import android.service.usb.UsbSettingsAccessoryPreferenceProto; - import android.service.usb.UsbSettingsDevicePreferenceProto; -@@ -914,10 +917,28 @@ class UsbProfileGroupSettingsManager { - return; - } - -+ if (shouldRestrictOverlayActivities()) { -+ return; -+ } -+ - // Start activity with registered intent - resolveActivity(intent, matches, defaultActivity, device, null); - } - -+ private boolean shouldRestrictOverlayActivities() { -+ if (Settings.Secure.getIntForUser( -+ mContext.getContentResolver(), -+ USER_SETUP_COMPLETE, -+ /* defaultValue= */ 1, -+ UserHandle.CURRENT.getIdentifier()) -+ == 0) { -+ Slog.d(TAG, "restricting usb overlay activities as setup is not complete"); -+ return true; -+ } -+ -+ return false; -+ } -+ - public void deviceAttachedForFixedHandler(UsbDevice device, ComponentName component) { - final Intent intent = createDeviceAttachedIntent(device); - --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/63_0063-Add-unit-test-to-test-data-overflow-when-using-BinaryXmlSerializ.bulletin.patch b/aosp_diff/preliminary/frameworks/base/63_0063-Add-unit-test-to-test-data-overflow-when-using-BinaryXmlSerializ.bulletin.patch deleted file mode 100644 index b638108e52..0000000000 --- a/aosp_diff/preliminary/frameworks/base/63_0063-Add-unit-test-to-test-data-overflow-when-using-BinaryXmlSerializ.bulletin.patch +++ /dev/null @@ -1,101 +0,0 @@ -From e8b6505647be558ed3a167a1e13c53dfc227d22b Mon Sep 17 00:00:00 2001 -From: lpeter -Date: Tue, 21 May 2024 07:58:43 +0000 -Subject: [PATCH] Add unit test to test data overflow when using - BinaryXmlSerializer - -Add the unit tests to test data overflow when calling: -1.BinaryXmlSerializer#attributeBytesHex -2.BinaryXmlSerializer#attributeBytesBase64 - -Bug: 307288067 -Test: atest BinaryXmlTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:eebe3b8baf112082c3178ba7d17b5318c53b3b5f) -Merged-In: I4e3f4881742f0e865eaefabb8ee134c67c6b53d9 -Change-Id: I4e3f4881742f0e865eaefabb8ee134c67c6b53d9 ---- - .../src/android/util/BinaryXmlTest.java | 50 +++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/core/tests/coretests/src/android/util/BinaryXmlTest.java b/core/tests/coretests/src/android/util/BinaryXmlTest.java -index 025e8314f5ed..da29828383b6 100644 ---- a/core/tests/coretests/src/android/util/BinaryXmlTest.java -+++ b/core/tests/coretests/src/android/util/BinaryXmlTest.java -@@ -24,6 +24,8 @@ import static android.util.XmlTest.doVerifyRead; - import static android.util.XmlTest.doVerifyWrite; - - import static org.junit.Assert.assertEquals; -+import static org.junit.Assert.assertThrows; -+import static org.junit.Assert.fail; - import static org.xmlpull.v1.XmlPullParser.START_TAG; - - import android.os.PersistableBundle; -@@ -41,12 +43,15 @@ import java.io.ByteArrayOutputStream; - import java.io.File; - import java.io.FileInputStream; - import java.io.FileOutputStream; -+import java.io.IOException; - import java.io.InputStream; - import java.io.OutputStream; - import java.nio.charset.StandardCharsets; - - @RunWith(AndroidJUnit4.class) - public class BinaryXmlTest { -+ private static final int MAX_UNSIGNED_SHORT = 65_535; -+ - /** - * Verify that we can write and read large numbers of interned - * {@link String} values. -@@ -170,4 +175,49 @@ public class BinaryXmlTest { - } - } - } -+ -+ @Test -+ public void testAttributeBytes_BinaryDataOverflow() throws Exception { -+ final TypedXmlSerializer out = Xml.newBinarySerializer(); -+ final ByteArrayOutputStream os = new ByteArrayOutputStream(); -+ out.setOutput(os, StandardCharsets.UTF_8.name()); -+ -+ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT + 1]; -+ assertThrows(IOException.class, -+ () -> out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", -+ testBytes)); -+ -+ assertThrows(IOException.class, -+ () -> out.attributeBytesBase64(/* namespace */ null, /* name */ -+ "attributeBytesBase64", testBytes)); -+ } -+ -+ @Test -+ public void testAttributeBytesHex_MaximumBinaryData() throws Exception { -+ final TypedXmlSerializer out = Xml.newBinarySerializer(); -+ final ByteArrayOutputStream os = new ByteArrayOutputStream(); -+ out.setOutput(os, StandardCharsets.UTF_8.name()); -+ -+ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT]; -+ try { -+ out.attributeBytesHex(/* namespace */ null, /* name */ "attributeBytesHex", testBytes); -+ } catch (Exception e) { -+ fail("testAttributeBytesHex fails with exception: " + e.toString()); -+ } -+ } -+ -+ @Test -+ public void testAttributeBytesBase64_MaximumBinaryData() throws Exception { -+ final TypedXmlSerializer out = Xml.newBinarySerializer(); -+ final ByteArrayOutputStream os = new ByteArrayOutputStream(); -+ out.setOutput(os, StandardCharsets.UTF_8.name()); -+ -+ final byte[] testBytes = new byte[MAX_UNSIGNED_SHORT]; -+ try { -+ out.attributeBytesBase64(/* namespace */ null, /* name */ "attributeBytesBase64", -+ testBytes); -+ } catch (Exception e) { -+ fail("testAttributeBytesBase64 fails with exception: " + e.toString()); -+ } -+ } - } --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/64_0064-Hide-SAW-subwindows.bulletin.patch b/aosp_diff/preliminary/frameworks/base/64_0064-Hide-SAW-subwindows.bulletin.patch deleted file mode 100644 index 5014152084..0000000000 --- a/aosp_diff/preliminary/frameworks/base/64_0064-Hide-SAW-subwindows.bulletin.patch +++ /dev/null @@ -1,41 +0,0 @@ -From abfaf702ef833dc4d374492d45c615c6e6de7f01 Mon Sep 17 00:00:00 2001 -From: Linus Tufvesson -Date: Mon, 29 Apr 2024 16:32:15 +0200 -Subject: [PATCH] Hide SAW subwindows - -.. when top window is hidden through Window#setHideOverlayWindows - -Bug: 318683640 -Test: atest CtsWindowManagerDeviceWindow:HideOverlayWindowsTest -Flag: EXEMPT securityfix -(cherry picked from commit c37bc9147086f497ac7b1595083836014f524d5f) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:55d02153259003b7552e7eef70b9e4f3f0dcd45c) -Merged-In: If19240f5aec2e048de80d75cbbdc00be47622d7f -Change-Id: If19240f5aec2e048de80d75cbbdc00be47622d7f ---- - services/core/java/com/android/server/wm/WindowState.java | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java -index 3dfcf1ff55a8..cdb3aa4c110d 100644 ---- a/services/core/java/com/android/server/wm/WindowState.java -+++ b/services/core/java/com/android/server/wm/WindowState.java -@@ -3121,12 +3121,13 @@ class WindowState extends WindowContainer implements WindowManagerP - } - - void setForceHideNonSystemOverlayWindowIfNeeded(boolean forceHide) { -+ final int baseType = getBaseType(); - if (mSession.mCanAddInternalSystemWindow -- || (!isSystemAlertWindowType(mAttrs.type) && mAttrs.type != TYPE_TOAST)) { -+ || (!isSystemAlertWindowType(baseType) && baseType != TYPE_TOAST)) { - return; - } - -- if (mAttrs.type == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay() -+ if (baseType == TYPE_APPLICATION_OVERLAY && mAttrs.isSystemApplicationOverlay() - && mSession.mCanCreateSystemApplicationOverlay) { - return; - } --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/65_0065-Ensure-device_owners2-xml-is-always-written-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/65_0065-Ensure-device_owners2-xml-is-always-written-.bulletin.patch deleted file mode 100644 index 551fc0402d..0000000000 --- a/aosp_diff/preliminary/frameworks/base/65_0065-Ensure-device_owners2-xml-is-always-written-.bulletin.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 688e5c3012eb0a4ea88361588cf5026c10e4a42c Mon Sep 17 00:00:00 2001 -From: Pavel Grafov -Date: Tue, 16 Apr 2024 18:28:16 +0100 -Subject: [PATCH] Ensure device_owners2.xml is always written. - -Bug: 335232744 -Test: Manual, upgrading from T-QPR3 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3abc07421d5bed187589d6deb48da07e4c407203) -Merged-In: I7a7dba56f2951e7e3699b19d2517d198dc8f9d35 -Change-Id: I7a7dba56f2951e7e3699b19d2517d198dc8f9d35 ---- - .../java/com/android/server/devicepolicy/OwnersData.java | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -index 608ae140450e..2ced224091a0 100644 ---- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java -@@ -354,8 +354,7 @@ class OwnersData { - - @Override - boolean shouldWrite() { -- return (mDeviceOwner != null) || (mSystemUpdatePolicy != null) -- || (mSystemUpdateInfo != null); -+ return true; - } - - @Override --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/base/66_0066-Fix-READ-WRITE-operation-access-issues-on-Restricted-appOps-.bulletin.patch b/aosp_diff/preliminary/frameworks/base/66_0066-Fix-READ-WRITE-operation-access-issues-on-Restricted-appOps-.bulletin.patch deleted file mode 100644 index dfcf20ecb7..0000000000 --- a/aosp_diff/preliminary/frameworks/base/66_0066-Fix-READ-WRITE-operation-access-issues-on-Restricted-appOps-.bulletin.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 21d764807b3dcd402d63e2b4c9fbae1c9965400a Mon Sep 17 00:00:00 2001 -From: Hao Ke -Date: Mon, 22 Apr 2024 15:13:58 +0000 -Subject: [PATCH] Fix READ/WRITE operation access issues on Restricted appOps. - -Problems were identified around read and write access to the restricted appOps, this change includes: - -- Filter out restricted appOps status for unprivileged readers. -- Allow additional privileged appOps permission holder reading restricted appOps status. - -Bug: 336273802 -Bug: 336323279 -Test: Local test see b/336273802#comment3 -Test: atest AppOpsTest#testRestrictedSettingsOpsRead -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e31c33ea3586531ca99dd4c6d68a34ce07c1cebb) -Merged-In: I09008b365e36b2c20c9a1fe5a1d52699ddb17d35 -Change-Id: I09008b365e36b2c20c9a1fe5a1d52699ddb17d35 ---- - core/java/android/app/AppOpInfo.java | 2 +- - core/java/android/app/AppOpsManager.java | 2 +- - .../android/server/appop/AppOpsService.java | 31 ++++++++++++++++--- - 3 files changed, 28 insertions(+), 7 deletions(-) - -diff --git a/core/java/android/app/AppOpInfo.java b/core/java/android/app/AppOpInfo.java -index 5268ec42e21c..a0f0ccaec58c 100644 ---- a/core/java/android/app/AppOpInfo.java -+++ b/core/java/android/app/AppOpInfo.java -@@ -88,7 +88,7 @@ class AppOpInfo { - - /** - * This specifies whether each option is only allowed to be read -- * by apps with manage appops permission. -+ * by apps with privileged appops permission. - */ - public final boolean restrictRead; - -diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java -index ccd83f756730..2ec54535cdb9 100644 ---- a/core/java/android/app/AppOpsManager.java -+++ b/core/java/android/app/AppOpsManager.java -@@ -2985,7 +2985,7 @@ public class AppOpsManager { - } - - /** -- * Retrieve whether the op can be read by apps with manage appops permission. -+ * Retrieve whether the op can be read by apps with privileged appops permission. - * @hide - */ - public static boolean opRestrictsRead(int op) { -diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java -index 33655f748230..e2388e2918ab 100644 ---- a/services/core/java/com/android/server/appop/AppOpsService.java -+++ b/services/core/java/com/android/server/appop/AppOpsService.java -@@ -1430,16 +1430,26 @@ public class AppOpsService extends IAppOpsService.Stub { - - private ArrayList collectOps(Ops pkgOps, int[] ops) { - ArrayList resOps = null; -+ boolean shouldReturnRestrictedAppOps = mContext.checkPermission( -+ Manifest.permission.GET_APP_OPS_STATS, -+ Binder.getCallingPid(), Binder.getCallingUid()) -+ == PackageManager.PERMISSION_GRANTED; - if (ops == null) { - resOps = new ArrayList<>(); -- for (int j=0; j(); - } -@@ -3615,10 +3625,21 @@ public class AppOpsService extends IAppOpsService.Stub { - - private void verifyIncomingOp(int op) { - if (op >= 0 && op < AppOpsManager._NUM_OP) { -- // Enforce manage appops permission if it's a restricted read op. -+ // Enforce privileged appops permission if it's a restricted read op. - if (opRestrictsRead(op)) { -- mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS, -- Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp"); -+ if (!(mContext.checkPermission(Manifest.permission.MANAGE_APPOPS, -+ Binder.getCallingPid(), Binder.getCallingUid()) -+ == PackageManager.PERMISSION_GRANTED || mContext.checkPermission( -+ Manifest.permission.GET_APP_OPS_STATS, -+ Binder.getCallingPid(), Binder.getCallingUid()) -+ == PackageManager.PERMISSION_GRANTED || mContext.checkPermission( -+ Manifest.permission.MANAGE_APP_OPS_MODES, -+ Binder.getCallingPid(), Binder.getCallingUid()) -+ == PackageManager.PERMISSION_GRANTED)) { -+ throw new SecurityException("verifyIncomingOp: uid " + Binder.getCallingUid() -+ + " does not have any of {MANAGE_APPOPS, GET_APP_OPS_STATS, " -+ + "MANAGE_APP_OPS_MODES}"); -+ } - } - return; - } --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/libs/modules-utils/0001-Add-the-protection-to-avoid-Integer-overflow-in-BinaryXmlSeriali.bulletin.patch b/aosp_diff/preliminary/frameworks/libs/modules-utils/0001-Add-the-protection-to-avoid-Integer-overflow-in-BinaryXmlSeriali.bulletin.patch deleted file mode 100644 index 407c132ede..0000000000 --- a/aosp_diff/preliminary/frameworks/libs/modules-utils/0001-Add-the-protection-to-avoid-Integer-overflow-in-BinaryXmlSeriali.bulletin.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 700c28908051ceb55e1456d2d21229bc17c6895a Mon Sep 17 00:00:00 2001 -From: lpeter -Date: Mon, 20 May 2024 12:35:32 +0000 -Subject: [PATCH] Add the protection to avoid Integer overflow in - BinaryXmlSerializer.java - -Ignore-AOSP-First: security vulnerabilities - -Bug: 307288067 -Test: atest BinaryXmlTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:8207203d4ee4210032a5d4e94d3cbf4635d7a890) -Merged-In: Id52bc0d0a0d46c3c31d9bb090466f8fbae4bd35a -Change-Id: Id52bc0d0a0d46c3c31d9bb090466f8fbae4bd35a ---- - .../com/android/modules/utils/BinaryXmlSerializer.java | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/java/com/android/modules/utils/BinaryXmlSerializer.java b/java/com/android/modules/utils/BinaryXmlSerializer.java -index 7c0217e..9fdb818 100644 ---- a/java/com/android/modules/utils/BinaryXmlSerializer.java -+++ b/java/com/android/modules/utils/BinaryXmlSerializer.java -@@ -16,6 +16,8 @@ - - package com.android.modules.utils; - -+import static com.android.modules.utils.FastDataOutput.MAX_UNSIGNED_SHORT; -+ - import static org.xmlpull.v1.XmlPullParser.CDSECT; - import static org.xmlpull.v1.XmlPullParser.COMMENT; - import static org.xmlpull.v1.XmlPullParser.DOCDECL; -@@ -224,6 +226,10 @@ public class BinaryXmlSerializer implements TypedXmlSerializer { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - mOut.writeByte(ATTRIBUTE | TYPE_BYTES_HEX); - mOut.writeInternedUTF(name); -+ if (value.length > MAX_UNSIGNED_SHORT) { -+ throw new IOException("attributeBytesHex: input size (" + value.length -+ + ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")"); -+ } - mOut.writeShort(value.length); - mOut.write(value); - return this; -@@ -235,6 +241,10 @@ public class BinaryXmlSerializer implements TypedXmlSerializer { - if (namespace != null && !namespace.isEmpty()) throw illegalNamespace(); - mOut.writeByte(ATTRIBUTE | TYPE_BYTES_BASE64); - mOut.writeInternedUTF(name); -+ if (value.length > MAX_UNSIGNED_SHORT) { -+ throw new IOException("attributeBytesBase64: input size (" + value.length -+ + ") exceeds maximum allowed size (" + MAX_UNSIGNED_SHORT + ")"); -+ } - mOut.writeShort(value.length); - mOut.write(value); - return this; --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/native/02_0002-File-size-seal-for-memory-mapped-region.bulletin.patch b/aosp_diff/preliminary/frameworks/native/02_0002-File-size-seal-for-memory-mapped-region.bulletin.patch deleted file mode 100644 index 9d1b60fc7e..0000000000 --- a/aosp_diff/preliminary/frameworks/native/02_0002-File-size-seal-for-memory-mapped-region.bulletin.patch +++ /dev/null @@ -1,84 +0,0 @@ -From aa98edf0ce9dde4886979658a459900ca987f193 Mon Sep 17 00:00:00 2001 -From: Keith Mok -Date: Fri, 4 Aug 2023 22:17:08 +0000 -Subject: [PATCH] File size seal for memory mapped region - -When using memfd for cross process communication, we always need to seal -the file size, otherwise remote process and shrink the size we memory -mapped and thus crash the originate process causing a DoS - -Bug: 294609150 -Test: Build -Ignore-AOSP-First: security -(cherry picked from commit 3d9f1e3b0a135b784b9ffa0e65d6a699c7ed1f8e) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:77b758c59f58a05d1c0d45350796951bc778745f) -Merged-In: Ibc263c4f78df897e884378e3d984a188ca8772c7 -Change-Id: Ibc263c4f78df897e884378e3d984a188ca8772c7 ---- - libs/binder/MemoryHeapBase.cpp | 4 ++-- - libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp | 13 +++++++++---- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp -index 8fe1d2bb3d..34e747ef21 100644 ---- a/libs/binder/MemoryHeapBase.cpp -+++ b/libs/binder/MemoryHeapBase.cpp -@@ -73,8 +73,8 @@ MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name) - ALOGV("MemoryHeapBase: Attempting to force MemFD"); - fd = memfd_create_region(name ? name : "MemoryHeapBase", size); - if (fd < 0 || (mapfd(fd, true, size) != NO_ERROR)) return; -- const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) | -- ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL); -+ const int SEAL_FLAGS = ((mFlags & READ_ONLY) ? F_SEAL_FUTURE_WRITE : 0) | F_SEAL_GROW | -+ F_SEAL_SHRINK | ((mFlags & MEMFD_ALLOW_SEALING_FLAG) ? 0 : F_SEAL_SEAL); - if (SEAL_FLAGS && (fcntl(fd, F_ADD_SEALS, SEAL_FLAGS) == -1)) { - ALOGE("MemoryHeapBase: MemFD %s sealing with flags %x failed with error %s", name, - SEAL_FLAGS, strerror(errno)); -diff --git a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp -index 278dd2bf81..140270f5a1 100644 ---- a/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp -+++ b/libs/binder/tests/binderMemoryHeapBaseUnitTest.cpp -@@ -37,7 +37,8 @@ TEST(MemoryHeapBase, MemfdSealed) { - ASSERT_NE(mHeap.get(), nullptr); - int fd = mHeap->getHeapID(); - EXPECT_NE(fd, -1); -- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL); -+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL); -+ EXPECT_EQ(ftruncate(fd, 4096), -1); - } - - TEST(MemoryHeapBase, MemfdUnsealed) { -@@ -48,7 +49,8 @@ TEST(MemoryHeapBase, MemfdUnsealed) { - ASSERT_NE(mHeap.get(), nullptr); - int fd = mHeap->getHeapID(); - EXPECT_NE(fd, -1); -- EXPECT_EQ(fcntl(fd, F_GET_SEALS), 0); -+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK); -+ EXPECT_EQ(ftruncate(fd, 4096), -1); - } - - TEST(MemoryHeapBase, MemfdSealedProtected) { -@@ -59,7 +61,9 @@ TEST(MemoryHeapBase, MemfdSealedProtected) { - ASSERT_NE(mHeap.get(), nullptr); - int fd = mHeap->getHeapID(); - EXPECT_NE(fd, -1); -- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_SEAL | F_SEAL_FUTURE_WRITE); -+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), -+ F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL | F_SEAL_FUTURE_WRITE); -+ EXPECT_EQ(ftruncate(fd, 4096), -1); - } - - TEST(MemoryHeapBase, MemfdUnsealedProtected) { -@@ -71,7 +75,8 @@ TEST(MemoryHeapBase, MemfdUnsealedProtected) { - ASSERT_NE(mHeap.get(), nullptr); - int fd = mHeap->getHeapID(); - EXPECT_NE(fd, -1); -- EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_FUTURE_WRITE); -+ EXPECT_EQ(fcntl(fd, F_GET_SEALS), F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_FUTURE_WRITE); -+ EXPECT_EQ(ftruncate(fd, 4096), -1); - } - - #else --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/frameworks/native/04_0004-Fix-transaction-sanitization.bulletin.patch b/aosp_diff/preliminary/frameworks/native/04_0004-Fix-transaction-sanitization.bulletin.patch deleted file mode 100644 index 11f989d423..0000000000 --- a/aosp_diff/preliminary/frameworks/native/04_0004-Fix-transaction-sanitization.bulletin.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3f85323b27d95a57bfa87cbf68dd4a143f9f88ad Mon Sep 17 00:00:00 2001 -From: Patrick Williams -Date: Tue, 23 Apr 2024 19:05:38 -0500 -Subject: [PATCH] Fix transaction sanitization - -Bug: 336648041 -Bug: 336648613 -Test: CredentialsTest -(cherry picked from commit 04e41761914c3c3aaca965103be3679b7a7af76f) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f1ad68a1a9fbdeb62999ccaee21643783101157c) -Merged-In: I53894d014bfabc9c958a6f533d7e3b3a6dcd0a34 -Change-Id: I53894d014bfabc9c958a6f533d7e3b3a6dcd0a34 ---- - services/surfaceflinger/SurfaceFlinger.cpp | 2 +- - .../surfaceflinger/tests/Credentials_test.cpp | 18 +++++++++++++----- - 2 files changed, 14 insertions(+), 6 deletions(-) - -diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp -index db205b8a95..d606788053 100644 ---- a/services/surfaceflinger/SurfaceFlinger.cpp -+++ b/services/surfaceflinger/SurfaceFlinger.cpp -@@ -4513,7 +4513,7 @@ status_t SurfaceFlinger::setTransactionState( - const int originPid = ipc->getCallingPid(); - const int originUid = ipc->getCallingUid(); - uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid); -- for (auto composerState : states) { -+ for (auto& composerState : states) { - composerState.state.sanitize(permissions); - } - -diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp -index 69e9a169e3..2d18166da5 100644 ---- a/services/surfaceflinger/tests/Credentials_test.cpp -+++ b/services/surfaceflinger/tests/Credentials_test.cpp -@@ -401,8 +401,13 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { - .apply(); - } - -- // Called from non privileged process -- Transaction().setTrustedOverlay(surfaceControl, true); -+ // Attempt to set a trusted overlay from a non-privileged process. This should fail silently. -+ { -+ UIDFaker f{AID_BIN}; -+ Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true); -+ } -+ -+ // Verify that the layer was not made a trusted overlay. - { - UIDFaker f(AID_SYSTEM); - auto windowIsPresentAndNotTrusted = [&](const std::vector& windowInfos) { -@@ -413,12 +418,14 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { - } - return !foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); - }; -- windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndNotTrusted); -+ ASSERT_TRUE( -+ windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndNotTrusted)); - } - -+ // Verify that privileged processes are able to set trusted overlays. - { - UIDFaker f(AID_SYSTEM); -- Transaction().setTrustedOverlay(surfaceControl, true); -+ Transaction().setTrustedOverlay(surfaceControl, true).apply(/*synchronous=*/true); - auto windowIsPresentAndTrusted = [&](const std::vector& windowInfos) { - auto foundWindowInfo = - WindowInfosListenerUtils::findMatchingWindowInfo(windowInfo, windowInfos); -@@ -427,7 +434,8 @@ TEST_F(CredentialsTest, TransactionPermissionTest) { - } - return foundWindowInfo->inputConfig.test(WindowInfo::InputConfig::TRUSTED_OVERLAY); - }; -- windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndTrusted); -+ ASSERT_TRUE( -+ windowInfosListenerUtils.waitForWindowInfosPredicate(windowIsPresentAndTrusted)); - } - } - --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/frameworks/opt/net/wifi/0001-Add-Intel-Wi-Fi-hal.patch b/aosp_diff/preliminary/frameworks/opt/net/wifi/0001-Add-Intel-Wi-Fi-hal.patch new file mode 100644 index 0000000000..00e0a594db --- /dev/null +++ b/aosp_diff/preliminary/frameworks/opt/net/wifi/0001-Add-Intel-Wi-Fi-hal.patch @@ -0,0 +1,40 @@ +From 99deb833d4e24ac1b2c27fdfed12a9dbb96c2d2e Mon Sep 17 00:00:00 2001 +From: Jeevaka Prabu Badrappan +Date: Thu, 1 Aug 2024 19:19:58 +0530 +Subject: [PATCH] Add Intel Wi-Fi hal + +Tests done: +- Build with libwifi-hal-intel enabled +- Wi-Fi on/off/scan + +Tracked-On: OAM-123043 +Signed-off-by: Jeevaka Prabu Badrappan +--- + libwifi_hal/Android.bp | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/libwifi_hal/Android.bp b/libwifi_hal/Android.bp +index 1af3df008..bc50d5c3e 100644 +--- a/libwifi_hal/Android.bp ++++ b/libwifi_hal/Android.bp +@@ -59,6 +59,7 @@ soong_config_string_variable { + "nxp", + "MediaTek", + "realtek", ++ "iwlwifi", + "emulator", + "rtl", + "slsi", +@@ -178,6 +179,9 @@ wifi_cc_defaults { + realtek: { + whole_static_libs: ["libwifi-hal-rtk"], + }, ++ iwlwifi: { ++ whole_static_libs: ["libwifi-hal-intel"], ++ }, + emulator: { + whole_static_libs: ["//device/generic/goldfish:libwifi-hal-emu"], + }, +-- +2.45.2 + diff --git a/aosp_diff/preliminary/frameworks/opt/net/wifi/01_0001-libwifi-hal-Add-libwifi-hal-for-intel.patch b/aosp_diff/preliminary/frameworks/opt/net/wifi/01_0001-libwifi-hal-Add-libwifi-hal-for-intel.patch deleted file mode 100644 index 4209c87e81..0000000000 --- a/aosp_diff/preliminary/frameworks/opt/net/wifi/01_0001-libwifi-hal-Add-libwifi-hal-for-intel.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 119a75a57901e99116f52063f13d499caf8fe8ee Mon Sep 17 00:00:00 2001 -From: Jeevaka Prabu Badrappan -Date: Tue, 8 Sep 2020 20:34:15 +0530 -Subject: [PATCH] libwifi-hal: Add libwifi-hal for intel - -Updated according to Android 14 build configuration - -Change-Id: Iba2d20c040baa5afde3e329a3abf584abfdc8d32 -Tracked-On: OAM-92722 -Signed-off-by: Jeevaka Prabu Badrappan ---- - libwifi_hal/Android.bp | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -diff --git a/libwifi_hal/Android.bp b/libwifi_hal/Android.bp -index cc8157b5e..00243de18 100644 ---- a/libwifi_hal/Android.bp -+++ b/libwifi_hal/Android.bp -@@ -57,6 +57,7 @@ soong_config_string_variable { - "nxp", - "MediaTek", - "realtek", -+ "iwlwifi", - "emulator", - "rtl", - "slsi", -@@ -172,6 +173,10 @@ wifi_cc_defaults { - realtek: { - whole_static_libs: ["libwifi-hal-rtk"], - }, -+ iwlwifi: { -+ //Support Intel WIFI HAL -+ whole_static_libs: ["libwifi-hal-intel"], -+ }, - emulator: { - whole_static_libs: ["//device/generic/goldfish:libwifi-hal-emu"], - }, -@@ -327,6 +332,38 @@ wifi_makefile_goal { - }, - } - -+// libwifi-hal-intel -+ -+wifi_cc_prebuilt_library_static { -+ name: "libwifi-hal-intel", -+ proprietary: true, -+ srcs: [":make-libwifi-hal-intel"], -+ compile_multilib: "first", -+ installable: false, -+ licenses: ["libwifi_hal_apache20_license", "libwifi_hal_bsd_license"], -+ enabled: false, -+ soong_config_variables: { -+ board_wlan_device: { -+ iwlwifi: { -+ enabled: true, -+ }, -+ }, -+ }, -+} -+ -+wifi_makefile_goal { -+ name: "make-libwifi-hal-intel", -+ product_out_path: "obj/STATIC_LIBRARIES/libwifi-hal-intel_intermediates/libwifi-hal-intel.a", -+ enabled: false, -+ soong_config_variables: { -+ board_wlan_device: { -+ iwlwifi: { -+ enabled: true, -+ }, -+ }, -+ }, -+} -+ - // libwifi-hal-qcom - - wifi_cc_prebuilt_library_static { --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/rs/0001-Generate-avx2-version-of-libRSCpuRef.so.patch b/aosp_diff/preliminary/frameworks/rs/0001-Generate-avx2-version-of-libRSCpuRef.so.patch deleted file mode 100644 index f8d1e5318b..0000000000 --- a/aosp_diff/preliminary/frameworks/rs/0001-Generate-avx2-version-of-libRSCpuRef.so.patch +++ /dev/null @@ -1,62 +0,0 @@ -From ecad322d261be38f7fe2e62d59dfb3d1dfb3b0bf Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 10 Nov 2023 13:00:58 +0530 -Subject: [PATCH] Generate avx2 version of libRSCpuRef.so - -Signed-off-by: Shalini Salomi Bodapati ---- - cpu_ref/Android.bp | 27 ++++++++++++++++++++++----- - 1 file changed, 22 insertions(+), 5 deletions(-) - -diff --git a/cpu_ref/Android.bp b/cpu_ref/Android.bp -index 32146e03..334b8751 100644 ---- a/cpu_ref/Android.bp -+++ b/cpu_ref/Android.bp -@@ -2,8 +2,8 @@ package { - default_applicable_licenses: ["Android-Apache-2.0"], - } - --cc_library_shared { -- name: "libRSCpuRef", -+cc_defaults { -+ name: "libRSCpuRef_generic", - defaults: ["libbcc-targets"], - vendor_available: true, - native_bridge_supported: true, -@@ -84,9 +84,6 @@ cc_library_shared { - x86_64: { - cflags: ["-DARCH_X86_HAVE_SSSE3"], - srcs: ["rsCpuIntrinsics_x86.cpp"], -- avx2: { -- cflags: ["-DARCH_X86_HAVE_AVX2", "-mavx2", "-mfma"], -- }, - }, - riscv64: { - enabled: false, -@@ -129,3 +126,23 @@ cc_library_shared { - }, - }, - } -+ -+cc_library_shared { -+ name: "libRSCpuRef", -+ defaults: ["libRSCpuRef_generic"], -+} -+ -+cc_library_shared { -+ name: "libRSCpuRef_avx2", -+ defaults: ["libRSCpuRef_generic"], -+ target: { -+ android: { -+ relative_install_path: "IA-Perf/avx2", -+ }, -+ }, -+ arch: { -+ x86_64: { -+ cflags: ["-DARCH_X86_HAVE_AVX2", "-mavx2", "-mfma"], -+ }, -+ } -+} --- -2.17.1 - diff --git a/aosp_diff/preliminary/frameworks/rs/0002-Modify-IA-Perf-variants-of-library-to-have-same-name.patch b/aosp_diff/preliminary/frameworks/rs/0002-Modify-IA-Perf-variants-of-library-to-have-same-name.patch deleted file mode 100644 index 6e2f999190..0000000000 --- a/aosp_diff/preliminary/frameworks/rs/0002-Modify-IA-Perf-variants-of-library-to-have-same-name.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 2750e9d363cd3c4a14517c626a187cf3163c93ae Mon Sep 17 00:00:00 2001 -From: "Reddy, Alavala Srinivasa" -Date: Fri, 10 Nov 2023 15:48:00 +0530 -Subject: [PATCH] Modify IA-Perf variants of library to have same name as - original - -Signed-off-by: ahs ---- - cpu_ref/Android.bp | 7 ++----- - 1 file changed, 2 insertions(+), 5 deletions(-) - -diff --git a/cpu_ref/Android.bp b/cpu_ref/Android.bp -index 334b8751..3c7b1bba 100644 ---- a/cpu_ref/Android.bp -+++ b/cpu_ref/Android.bp -@@ -134,12 +134,9 @@ cc_library_shared { - - cc_library_shared { - name: "libRSCpuRef_avx2", -+ override_lib_name: "libRSCpuRef", -+ relative_install_path: "IA-Perf/avx2", - defaults: ["libRSCpuRef_generic"], -- target: { -- android: { -- relative_install_path: "IA-Perf/avx2", -- }, -- }, - arch: { - x86_64: { - cflags: ["-DARCH_X86_HAVE_AVX2", "-mavx2", "-mfma"], --- -2.17.1 - diff --git a/aosp_diff/preliminary/hardware/interfaces/01_0001-Enable-AIDL-interface-for-Light-HAL.patch b/aosp_diff/preliminary/hardware/interfaces/0001-Enable-AIDL-interface-for-Light-HAL.patch similarity index 66% rename from aosp_diff/preliminary/hardware/interfaces/01_0001-Enable-AIDL-interface-for-Light-HAL.patch rename to aosp_diff/preliminary/hardware/interfaces/0001-Enable-AIDL-interface-for-Light-HAL.patch index f62ab88c6a..0c09ea672a 100644 --- a/aosp_diff/preliminary/hardware/interfaces/01_0001-Enable-AIDL-interface-for-Light-HAL.patch +++ b/aosp_diff/preliminary/hardware/interfaces/0001-Enable-AIDL-interface-for-Light-HAL.patch @@ -1,4 +1,4 @@ -From dce1da449ac9dbd1a107de742df5d63661755377 Mon Sep 17 00:00:00 2001 +From 6a53e6e03718da7473ecb086df2a51c4e03a1015 Mon Sep 17 00:00:00 2001 From: svenate Date: Fri, 11 Dec 2020 15:04:03 +0530 Subject: [PATCH] Enable AIDL interface for Light HAL @@ -11,10 +11,10 @@ Signed-off-by: svenate light/aidl/default/lights-default.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git light/aidl/default/lights-default.rc light/aidl/default/lights-default.rc -index 687ec97dd..4cdd038ad 100644 ---- light/aidl/default/lights-default.rc -+++ light/aidl/default/lights-default.rc +diff --git a/light/aidl/default/lights-default.rc b/light/aidl/default/lights-default.rc +index 687ec97dd1..4cdd038ad9 100644 +--- a/light/aidl/default/lights-default.rc ++++ b/light/aidl/default/lights-default.rc @@ -1,5 +1,5 @@ service vendor.light-default /vendor/bin/hw/android.hardware.lights-service.example class hal @@ -24,5 +24,5 @@ index 687ec97dd..4cdd038ad 100644 + group system shutdown critical -- -2.17.1 +2.45.2 diff --git a/aosp_diff/preliminary/hardware/interfaces/0002-Mark-USB-camera-to-back-camera-always.patch b/aosp_diff/preliminary/hardware/interfaces/0002-Mark-USB-camera-to-back-camera-always.patch new file mode 100644 index 0000000000..67936fc09c --- /dev/null +++ b/aosp_diff/preliminary/hardware/interfaces/0002-Mark-USB-camera-to-back-camera-always.patch @@ -0,0 +1,48 @@ +From 7f9c8714eb4ca307441a0997ebaef65514003df0 Mon Sep 17 00:00:00 2001 +From: shivasku82 +Date: Sat, 4 May 2024 08:37:40 +0530 +Subject: [PATCH] Mark USB camera to back camera always + +Google camera preview show mirror image when switching between +two USB camera. + +In case of 2 camera use-case app considering front and back camera +and based on this app is mirroring front camera preview. exposing +both camera as back camera to framework so mirrors wont happen. + +Tracked-On: OAM-117469 +Signed-off-by: shivasku82 +--- + camera/device/3.4/default/ExternalCameraDevice.cpp | 2 +- + camera/device/default/ExternalCameraDevice.cpp | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp +index 44b908b289..1a6ee2a8b8 100644 +--- a/camera/device/3.4/default/ExternalCameraDevice.cpp ++++ b/camera/device/3.4/default/ExternalCameraDevice.cpp +@@ -370,7 +370,7 @@ status_t ExternalCameraDevice::initDefaultCharsKeys( + UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, + &opticalStabilizationMode, 1); + +- const uint8_t facing = ANDROID_LENS_FACING_EXTERNAL; ++ const uint8_t facing = ANDROID_LENS_FACING_BACK; + UPDATE(ANDROID_LENS_FACING, &facing, 1); + + // android.noiseReduction +diff --git a/camera/device/default/ExternalCameraDevice.cpp b/camera/device/default/ExternalCameraDevice.cpp +index 8e8474800f..50fbdd4efe 100644 +--- a/camera/device/default/ExternalCameraDevice.cpp ++++ b/camera/device/default/ExternalCameraDevice.cpp +@@ -420,7 +420,7 @@ status_t ExternalCameraDevice::initDefaultCharsKeys( + const uint8_t opticalStabilizationMode = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; + UPDATE(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, &opticalStabilizationMode, 1); + +- const uint8_t facing = ANDROID_LENS_FACING_EXTERNAL; ++ const uint8_t facing = ANDROID_LENS_FACING_BACK; + UPDATE(ANDROID_LENS_FACING, &facing, 1); + + // android.noiseReduction +-- +2.45.2 + diff --git a/aosp_diff/preliminary/hardware/interfaces/0003-usb-camera-hot-plug-not-working.patch b/aosp_diff/preliminary/hardware/interfaces/0003-usb-camera-hot-plug-not-working.patch new file mode 100644 index 0000000000..e3dab05fba --- /dev/null +++ b/aosp_diff/preliminary/hardware/interfaces/0003-usb-camera-hot-plug-not-working.patch @@ -0,0 +1,62 @@ +From 9d5c4237afed351ce367305aed4af6fa209584bf Mon Sep 17 00:00:00 2001 +From: shivasku82 +Date: Mon, 6 May 2024 14:52:33 +0530 +Subject: [PATCH] usb camera hot plug not working + +Sometimes USB camera hot plug is not getting detected by camera +HAL. + +Camera HAL tries to open video nodes before is completely enumerated +in such cases opening of video nodes is getting failed. Added retry +logic before publish camera enumuration in hal is failed. + +Tests Done : Tested for Multi camera preview for multiple attempts of + USB camera plug in. + +Tracked-On: OAM-118092 +Signed-off-by: shivasku82 +--- + .../provider/default/ExternalCameraProvider.cpp | 17 +++++++++++++---- + 1 file changed, 13 insertions(+), 4 deletions(-) + +diff --git a/camera/provider/default/ExternalCameraProvider.cpp b/camera/provider/default/ExternalCameraProvider.cpp +index 54875abb20..bd8de06332 100644 +--- a/camera/provider/default/ExternalCameraProvider.cpp ++++ b/camera/provider/default/ExternalCameraProvider.cpp +@@ -28,6 +28,8 @@ + #include + #include + ++#define MAX_RETRY 3 ++ + namespace android { + namespace hardware { + namespace camera { +@@ -187,13 +189,20 @@ void ExternalCameraProvider::addExternalCamera(const char* devName) { + } + + void ExternalCameraProvider::deviceAdded(const char* devName) { +- { ++ int status = 0; ++ // sometimes device nodes not enumated hence it fails retry before confirm ++ for (int i = 0; i < MAX_RETRY; i++) { ++ if (status == 1) ++ break; + base::unique_fd fd(::open(devName, O_RDWR)); + if (fd.get() < 0) { +- ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno)); +- return; ++ ALOGE("%s open v4l2 device %s failed:%s and iteration %d", __FUNCTION__, devName, strerror(errno), i); ++ if(usleep(200000) < 0) { ++ ALOGE("%s Failed to sleep %s :%s and iteration %d", __FUNCTION__, devName, strerror(errno), i); ++ } ++ continue; + } +- ++ status = 1; + struct v4l2_capability capability; + int ret = ioctl(fd.get(), VIDIOC_QUERYCAP, &capability); + if (ret < 0) { +-- +2.45.2 + diff --git a/aosp_diff/preliminary/hardware/interfaces/05_0005-Add-support-for-advanced-USB-3.x-based-Cameras.patch b/aosp_diff/preliminary/hardware/interfaces/0004-Add-support-for-advanced-USB-3.x-based-Cameras.patch similarity index 89% rename from aosp_diff/preliminary/hardware/interfaces/05_0005-Add-support-for-advanced-USB-3.x-based-Cameras.patch rename to aosp_diff/preliminary/hardware/interfaces/0004-Add-support-for-advanced-USB-3.x-based-Cameras.patch index 46df9c42d9..f9772eff2b 100644 --- a/aosp_diff/preliminary/hardware/interfaces/05_0005-Add-support-for-advanced-USB-3.x-based-Cameras.patch +++ b/aosp_diff/preliminary/hardware/interfaces/0004-Add-support-for-advanced-USB-3.x-based-Cameras.patch @@ -1,4 +1,4 @@ -From 747d6759ab9eec0dfc1a89d150720a93beef611f Mon Sep 17 00:00:00 2001 +From 6f10cefd65c6927ce1bbe2d7724b36c4d0f460a1 Mon Sep 17 00:00:00 2001 From: Muhammad Aksar Date: Thu, 14 Nov 2019 18:31:41 +0530 Subject: [PATCH] Add support for advanced USB 3.x based Cameras @@ -23,10 +23,10 @@ Signed-off-by: Muhammad Aksar 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/camera/device/3.4/default/ExternalCameraDevice.cpp b/camera/device/3.4/default/ExternalCameraDevice.cpp -index 9a2fddf..c3c9627 100644 +index 469bf8d695..1a6ee2a8b8 100644 --- a/camera/device/3.4/default/ExternalCameraDevice.cpp +++ b/camera/device/3.4/default/ExternalCameraDevice.cpp -@@ -935,9 +935,11 @@ void ExternalCameraDevice::updateFpsBounds( +@@ -946,9 +946,11 @@ void ExternalCameraDevice::updateFpsBounds( } getFrameRateList(fd, fpsUpperBound, &format); @@ -42,5 +42,5 @@ index 9a2fddf..c3c9627 100644 void ExternalCameraDevice::initSupportedFormatsLocked(int fd) { -- -2.7.4 +2.45.2 diff --git a/aosp_diff/preliminary/hardware/interfaces/09_0009-Add-the-memtrack-AIDL-HAL-implement.patch b/aosp_diff/preliminary/hardware/interfaces/0005-Add-the-memtrack-AIDL-HAL-implement.patch similarity index 100% rename from aosp_diff/preliminary/hardware/interfaces/09_0009-Add-the-memtrack-AIDL-HAL-implement.patch rename to aosp_diff/preliminary/hardware/interfaces/0005-Add-the-memtrack-AIDL-HAL-implement.patch diff --git a/aosp_diff/preliminary/hardware/interfaces/12_0001-Fix-for-Camera-Issue.patch b/aosp_diff/preliminary/hardware/interfaces/0006-Fix-for-Camera-Issue.patch similarity index 80% rename from aosp_diff/preliminary/hardware/interfaces/12_0001-Fix-for-Camera-Issue.patch rename to aosp_diff/preliminary/hardware/interfaces/0006-Fix-for-Camera-Issue.patch index 1ace3875d2..1a652e4ca8 100644 --- a/aosp_diff/preliminary/hardware/interfaces/12_0001-Fix-for-Camera-Issue.patch +++ b/aosp_diff/preliminary/hardware/interfaces/0006-Fix-for-Camera-Issue.patch @@ -1,4 +1,4 @@ -From b0c0409226bb05788179c52f865e0a421ffb50ae Mon Sep 17 00:00:00 2001 +From 29ee8b682d3e1368477be195eac7078c35da7a14 Mon Sep 17 00:00:00 2001 From: "Pillai, Venkatesh" Date: Mon, 4 Sep 2023 14:01:44 +0530 Subject: [PATCH] Fix for Camera Issue @@ -16,10 +16,10 @@ Signed-off-by: Pillai, Venkatesh 1 file changed, 5 insertions(+) diff --git a/camera/device/default/ExternalCameraDeviceSession.cpp b/camera/device/default/ExternalCameraDeviceSession.cpp -index c9629744c..c5260608e 100644 +index 91196d4228..18f65f68d6 100644 --- a/camera/device/default/ExternalCameraDeviceSession.cpp +++ b/camera/device/default/ExternalCameraDeviceSession.cpp -@@ -233,6 +233,11 @@ void ExternalCameraDeviceSession::closeOutputThreadImpl() { +@@ -229,6 +229,11 @@ void ExternalCameraDeviceSession::closeOutputThread() { mOutputThread->requestExitAndWait(); mOutputThread.reset(); } @@ -30,7 +30,7 @@ index c9629744c..c5260608e 100644 + } - Status ExternalCameraDeviceSession::initStatus() const { + void ExternalCameraDeviceSession::closeBufferRequestThread() { -- -2.17.1 +2.45.2 diff --git a/aosp_diff/preliminary/hardware/interfaces/0007-Fix-to-boot-A15-with-Aidl-Gatekeeper.patch b/aosp_diff/preliminary/hardware/interfaces/0007-Fix-to-boot-A15-with-Aidl-Gatekeeper.patch new file mode 100644 index 0000000000..c6789e0b96 --- /dev/null +++ b/aosp_diff/preliminary/hardware/interfaces/0007-Fix-to-boot-A15-with-Aidl-Gatekeeper.patch @@ -0,0 +1,30 @@ +From 3d285e7dd913b406de332bb0b20644f1d4217eb9 Mon Sep 17 00:00:00 2001 +From: Gowtham Anandha Babu +Date: Wed, 14 Aug 2024 06:39:47 +0000 +Subject: [PATCH] Fix to boot A15 with Aidl Gatekeeper + +Falling back to the orginal Sepolicy Object + +Tests Done: +1. Flash the image Bare metal or CiV +2. Image is booting and service is running + +Tracked-On: OAM-123432 + +Signed-off-by: Aman Bhadouria +--- + gatekeeper/aidl/software/file_contexts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gatekeeper/aidl/software/file_contexts b/gatekeeper/aidl/software/file_contexts +index 23a62ea9df..cc4180e33e 100644 +--- a/gatekeeper/aidl/software/file_contexts ++++ b/gatekeeper/aidl/software/file_contexts +@@ -1,3 +1,3 @@ + (/.*)? u:object_r:vendor_file:s0 + /etc(/.*)? u:object_r:vendor_configs_file:s0 +-/bin/hw/android\.hardware\.gatekeeper-service\.nonsecure u:object_r:hal_gatekeeper_remote_exec:s0 ++/bin/hw/android\.hardware\.gatekeeper-service\.nonsecure u:object_r:hal_gatekeeper_default_exec:s0 +-- +2.34.1 + diff --git a/aosp_diff/preliminary/hardware/interfaces/06_0006-Retry-device-nodes-reading.patch b/aosp_diff/preliminary/hardware/interfaces/06_0006-Retry-device-nodes-reading.patch deleted file mode 100644 index 06e64a16fe..0000000000 --- a/aosp_diff/preliminary/hardware/interfaces/06_0006-Retry-device-nodes-reading.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 5d6576e5385426bf235f6e9a5668c285b948b8d8 Mon Sep 17 00:00:00 2001 -From: kbillore -Date: Wed, 10 Jun 2020 14:51:34 +0530 -Subject: [PATCH] Retry device nodes reading - -Signed-off-by: shivasku82 ---- - .../default/ExternalCameraProviderImpl_2_4.cpp | 16 ++++++++++++---- - 1 file changed, 12 insertions(+), 4 deletions(-) - -diff --git a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp -index 4fc743748..d4f81b4b9 100644 ---- a/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp -+++ b/camera/provider/2.4/default/ExternalCameraProviderImpl_2_4.cpp -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include "ExternalCameraProviderImpl_2_4.h" -@@ -229,13 +230,20 @@ void ExternalCameraProviderImpl_2_4::addExternalCamera(const char* devName) { - } - - void ExternalCameraProviderImpl_2_4::deviceAdded(const char* devName) { -- { -+ int status = 0; -+ // sometimes device nodes not enumated hence it fails retry before confirm -+ for (int i = 0; i < 3; i++) { -+ if (status == 1) -+ break; - base::unique_fd fd(::open(devName, O_RDWR)); - if (fd.get() < 0) { -- ALOGE("%s open v4l2 device %s failed:%s", __FUNCTION__, devName, strerror(errno)); -- return; -+ ALOGE("%s open v4l2 device %s failed:%s and iteration %d", __FUNCTION__, devName, strerror(errno), i); -+ if(usleep(200000) < 0) { -+ ALOGE("%s Failed to sleep %s :%s and iteration %d", __FUNCTION__, devName, strerror(errno), i); -+ } -+ continue; - } -- -+ status = 1; - struct v4l2_capability capability; - int ret = ioctl(fd.get(), VIDIOC_QUERYCAP, &capability); - if (ret < 0) { --- -2.17.1 - diff --git a/aosp_diff/preliminary/hardware/interfaces/07_0007-health-Health-HAL-needs-Intel-healthloop.patch b/aosp_diff/preliminary/hardware/interfaces/07_0007-health-Health-HAL-needs-Intel-healthloop.patch deleted file mode 100644 index 1ae4a830c5..0000000000 --- a/aosp_diff/preliminary/hardware/interfaces/07_0007-health-Health-HAL-needs-Intel-healthloop.patch +++ /dev/null @@ -1,31 +0,0 @@ -From b7e7290ad82b8b175b7efed5938b2ed34d880eb1 Mon Sep 17 00:00:00 2001 -From: saranya -Date: Thu, 1 Oct 2020 11:05:53 +0530 -Subject: [PATCH] health: Health HAL needs Intel healthloop - -This is to add Intel healthloop for health service. -Other than this dependency, AOSP health service itself is -sufficient. - -Signed-off-by: Saranya Gopal -Change-Id: Iccb90c515bee855e07c9c3291616cd6533dc4b22 ---- - health/2.1/default/Android.bp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/health/2.1/default/Android.bp b/health/2.1/default/Android.bp -index 3649853a3..f894bdc15 100644 ---- a/health/2.1/default/Android.bp -+++ b/health/2.1/default/Android.bp -@@ -29,7 +29,7 @@ cc_defaults { - static_libs: [ - "android.hardware.health@1.0-convert", - "libbatterymonitor", -- "libhealthloop", -+ "libhealthloop.intel", - "libhealth2impl", - ], - } --- -2.17.1 - diff --git a/aosp_diff/preliminary/hardware/interfaces/10_0010-Fix-for-VTS-issue-in-thermal.patch b/aosp_diff/preliminary/hardware/interfaces/10_0010-Fix-for-VTS-issue-in-thermal.patch deleted file mode 100644 index 46c815976a..0000000000 --- a/aosp_diff/preliminary/hardware/interfaces/10_0010-Fix-for-VTS-issue-in-thermal.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 90b93b6b58e6b6cfd293ecccd69c1119ff38634e Mon Sep 17 00:00:00 2001 -From: gkdeepa -Date: Tue, 27 Jul 2021 09:31:51 +0530 -Subject: [PATCH] Fix for VTS issue in thermal - -Removing the thermal 1.0 HAL interface from 2.0 -service. - -Tracked-On: OAM-97800 -Signed-off-by: Deepa g.k.deepa@intel.com ---- - thermal/2.0/default/android.hardware.thermal@2.0-service.rc | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc -index 4ff8bd69e..046c77176 100644 ---- a/thermal/2.0/default/android.hardware.thermal@2.0-service.rc -+++ b/thermal/2.0/default/android.hardware.thermal@2.0-service.rc -@@ -1,5 +1,4 @@ - service vendor.thermal-hal-2-0-mock /vendor/bin/hw/android.hardware.thermal@2.0-service.mock -- interface android.hardware.thermal@1.0::IThermal default - interface android.hardware.thermal@2.0::IThermal default - class hal - user system --- -2.17.1 - diff --git a/aosp_diff/preliminary/hardware/interfaces/13_0013-Use-onUnlinked-in-health-HAL.bulletin.patch b/aosp_diff/preliminary/hardware/interfaces/13_0013-Use-onUnlinked-in-health-HAL.bulletin.patch deleted file mode 100644 index e6d5393094..0000000000 --- a/aosp_diff/preliminary/hardware/interfaces/13_0013-Use-onUnlinked-in-health-HAL.bulletin.patch +++ /dev/null @@ -1,237 +0,0 @@ -From 0ff19d1f89614fce9454fb415bcbfcbcf3caf76e Mon Sep 17 00:00:00 2001 -From: Devin Moore -Date: Fri, 19 Jan 2024 22:22:01 +0000 -Subject: [PATCH] Use onUnlinked in health HAL - -It's possible to get an onBinderDied callback after a call to -AIBinder_unlinkToDeath() so we can't delete the objects in callbacks_ -until we are done using the void* cookie. -Handling the cleanup in onBinderUnlinked will handle the case where we -manually unlink it as well as the case where it's unlinked due to death. - -Test: atest VtsHalHealthTargetTest -Bug: 319210610 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e5e95bf5759a736f3debc6eb583fb1c82b38d847) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:1e1627a5da86782960a157a059aec816be5c82b1) -Merged-In: Iee4783217cc88134af6de0fe66128684ca984dba -Change-Id: Iee4783217cc88134af6de0fe66128684ca984dba ---- - health/aidl/default/Health.cpp | 55 ++++++++++++++----- - health/aidl/default/LinkedCallback.cpp | 28 ++++------ - health/aidl/default/LinkedCallback.h | 18 ++---- - .../aidl/default/include/health-impl/Health.h | 3 +- - 4 files changed, 59 insertions(+), 45 deletions(-) - -diff --git a/health/aidl/default/Health.cpp b/health/aidl/default/Health.cpp -index f401643cd..f485e5426 100644 ---- a/health/aidl/default/Health.cpp -+++ b/health/aidl/default/Health.cpp -@@ -36,6 +36,11 @@ void OnCallbackDiedWrapped(void* cookie) { - LinkedCallback* linked = reinterpret_cast(cookie); - linked->OnCallbackDied(); - } -+// Delete the owned cookie. -+void onCallbackUnlinked(void* cookie) { -+ LinkedCallback* linked = reinterpret_cast(cookie); -+ delete linked; -+} - } // namespace - - /* -@@ -57,6 +62,7 @@ Health::Health(std::string_view instance_name, std::unique_ptr lock(callbacks_lock_); -- callbacks_.emplace_back(LinkedCallback::Make(ref(), callback)); -+ LinkedCallback* linked_callback_result = LinkedCallback::Make(ref(), callback); -+ if (!linked_callback_result) { -+ return ndk::ScopedAStatus::fromStatus(STATUS_UNEXPECTED_NULL); -+ } -+ callbacks_[linked_callback_result] = callback; - // unlock - } - -@@ -298,12 +308,24 @@ ndk::ScopedAStatus Health::unregisterCallback( - - std::lock_guard lock(callbacks_lock_); - -- auto matches = [callback](const auto& linked) { -- return linked->callback()->asBinder() == callback->asBinder(); // compares binder object -+ auto matches = [callback](const auto& cb) { -+ return cb->asBinder() == callback->asBinder(); // compares binder object - }; -- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), matches); -- bool removed = (it != callbacks_.end()); -- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks. -+ bool removed = false; -+ for (auto it = callbacks_.begin(); it != callbacks_.end();) { -+ if (it->second->asBinder() == callback->asBinder()) { -+ auto status = AIBinder_unlinkToDeath(callback->asBinder().get(), death_recipient_.get(), -+ reinterpret_cast(it->first)); -+ if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) { -+ LOG(WARNING) << __func__ -+ << "Cannot unlink to death: " << ::android::statusToString(status); -+ } -+ it = callbacks_.erase(it); -+ removed = true; -+ } else { -+ it++; -+ } -+ } - return removed ? ndk::ScopedAStatus::ok() - : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); - } -@@ -331,13 +353,20 @@ ndk::ScopedAStatus Health::update() { - void Health::OnHealthInfoChanged(const HealthInfo& health_info) { - // Notify all callbacks - std::unique_lock lock(callbacks_lock_); -- // is_dead notifies a callback and return true if it is dead. -- auto is_dead = [&](const auto& linked) { -- auto res = linked->callback()->healthInfoChanged(health_info); -- return IsDeadObjectLogged(res); -- }; -- auto it = std::remove_if(callbacks_.begin(), callbacks_.end(), is_dead); -- callbacks_.erase(it, callbacks_.end()); // calls unlinkToDeath on deleted callbacks. -+ for (auto it = callbacks_.begin(); it != callbacks_.end();) { -+ auto res = it->second->healthInfoChanged(health_info); -+ if (IsDeadObjectLogged(res)) { -+ // if it's dead, remove it -+ it = callbacks_.erase(it); -+ } else { -+ it++; -+ if (!res.isOk()) { -+ LOG(DEBUG) -+ << "Cannot call healthInfoChanged:" << res.getDescription() -+ << ". Do nothing here if callback is dead as it will be cleaned up later."; -+ } -+ } -+ } - lock.unlock(); - - // Let HalHealthLoop::OnHealthInfoChanged() adjusts uevent / wakealarm periods -diff --git a/health/aidl/default/LinkedCallback.cpp b/health/aidl/default/LinkedCallback.cpp -index 2985ffe95..12a8df392 100644 ---- a/health/aidl/default/LinkedCallback.cpp -+++ b/health/aidl/default/LinkedCallback.cpp -@@ -24,35 +24,24 @@ - - namespace aidl::android::hardware::health { - --std::unique_ptr LinkedCallback::Make( -- std::shared_ptr service, std::shared_ptr callback) { -- std::unique_ptr ret(new LinkedCallback()); -+LinkedCallback* LinkedCallback::Make(std::shared_ptr service, -+ std::shared_ptr callback) { -+ LinkedCallback* ret(new LinkedCallback()); -+ // pass ownership of this object to the death recipient - binder_status_t linkRet = - AIBinder_linkToDeath(callback->asBinder().get(), service->death_recipient_.get(), -- reinterpret_cast(ret.get())); -+ reinterpret_cast(ret)); - if (linkRet != ::STATUS_OK) { - LOG(WARNING) << __func__ << "Cannot link to death: " << linkRet; - return nullptr; - } - ret->service_ = service; -- ret->callback_ = std::move(callback); -+ ret->callback_ = callback; - return ret; - } - - LinkedCallback::LinkedCallback() = default; - --LinkedCallback::~LinkedCallback() { -- if (callback_ == nullptr) { -- return; -- } -- auto status = -- AIBinder_unlinkToDeath(callback_->asBinder().get(), service()->death_recipient_.get(), -- reinterpret_cast(this)); -- if (status != STATUS_OK && status != STATUS_DEAD_OBJECT) { -- LOG(WARNING) << __func__ << "Cannot unlink to death: " << ::android::statusToString(status); -- } --} -- - std::shared_ptr LinkedCallback::service() { - auto service_sp = service_.lock(); - CHECK_NE(nullptr, service_sp); -@@ -60,7 +49,10 @@ std::shared_ptr LinkedCallback::service() { - } - - void LinkedCallback::OnCallbackDied() { -- service()->unregisterCallback(callback_); -+ auto sCb = callback_.lock(); -+ if (sCb) { -+ service()->unregisterCallback(sCb); -+ } - } - - } // namespace aidl::android::hardware::health -diff --git a/health/aidl/default/LinkedCallback.h b/health/aidl/default/LinkedCallback.h -index 82490a701..0494921d0 100644 ---- a/health/aidl/default/LinkedCallback.h -+++ b/health/aidl/default/LinkedCallback.h -@@ -31,18 +31,10 @@ namespace aidl::android::hardware::health { - class LinkedCallback { - public: - // Automatically linkToDeath upon construction with the returned object as the cookie. -- // service->death_reciepient() should be from CreateDeathRecipient(). -- // Not using a strong reference to |service| to avoid circular reference. The lifetime -- // of |service| must be longer than this LinkedCallback object. -- static std::unique_ptr Make(std::shared_ptr service, -- std::shared_ptr callback); -- -- // Automatically unlinkToDeath upon destruction. So, it is always safe to reinterpret_cast -- // the cookie back to the LinkedCallback object. -- ~LinkedCallback(); -- -- // The wrapped IHealthInfoCallback object. -- const std::shared_ptr& callback() const { return callback_; } -+ // The deathRecipient owns the LinkedCallback object and will delete it with -+ // cookie when it's unlinked. -+ static LinkedCallback* Make(std::shared_ptr service, -+ std::shared_ptr callback); - - // On callback died, unreigster it from the service. - void OnCallbackDied(); -@@ -54,7 +46,7 @@ class LinkedCallback { - std::shared_ptr service(); - - std::weak_ptr service_; -- std::shared_ptr callback_; -+ std::weak_ptr callback_; - }; - - } // namespace aidl::android::hardware::health -diff --git a/health/aidl/default/include/health-impl/Health.h b/health/aidl/default/include/health-impl/Health.h -index dc3a0ef8f..429ae2ab9 100644 ---- a/health/aidl/default/include/health-impl/Health.h -+++ b/health/aidl/default/include/health-impl/Health.h -@@ -16,6 +16,7 @@ - - #pragma once - -+#include - #include - #include - -@@ -112,7 +113,7 @@ class Health : public BnHealth, public HalHealthLoopCallback { - ndk::ScopedAIBinder_DeathRecipient death_recipient_; - int binder_fd_ = -1; - std::mutex callbacks_lock_; -- std::vector> callbacks_; -+ std::map> callbacks_; - }; - - } // namespace aidl::android::hardware::health --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/hardware/interfaces/14_0014-Keep-track-of-DeathMonitor-cookies.bulletin.patch b/aosp_diff/preliminary/hardware/interfaces/14_0014-Keep-track-of-DeathMonitor-cookies.bulletin.patch deleted file mode 100644 index 4c48ccd825..0000000000 --- a/aosp_diff/preliminary/hardware/interfaces/14_0014-Keep-track-of-DeathMonitor-cookies.bulletin.patch +++ /dev/null @@ -1,197 +0,0 @@ -From d63d09261806f7f1aa01406867f2a9e169356fca Mon Sep 17 00:00:00 2001 -From: Devin Moore -Date: Tue, 9 Apr 2024 21:50:41 +0000 -Subject: [PATCH] Keep track of DeathMonitor cookies - -This change keeps track of the objects that the cookies points to so the -serviceDied callback knows when it can use the cookie. - -Test: atest neuralnetworks_utils_hal_aidl_test -Tets: atest NeuralNetworksTest_static -Bug: 319210610 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:def7a3cf59fa17ba7faa9af14a24f4161bc276bd) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:49859a3b5542270363efe42a56b9145142bbfa60) -Merged-In: I418cbc6baa19aa702d9fd2e7d8096fe1a02b7794 -Change-Id: I418cbc6baa19aa702d9fd2e7d8096fe1a02b7794 ---- - .../include/nnapi/hal/aidl/ProtectCallback.h | 11 ++++ - .../aidl/utils/src/ProtectCallback.cpp | 56 ++++++++++++++++--- - neuralnetworks/aidl/utils/test/DeviceTest.cpp | 9 ++- - 3 files changed, 66 insertions(+), 10 deletions(-) - -diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h -index 92ed1cda5..9a7fe5e1c 100644 ---- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h -+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/ProtectCallback.h -@@ -56,6 +56,8 @@ class IProtectedCallback { - // Thread safe class - class DeathMonitor final { - public: -+ explicit DeathMonitor(uintptr_t cookieKey) : kCookieKey(cookieKey) {} -+ - static void serviceDied(void* cookie); - void serviceDied(); - // Precondition: `killable` must be non-null. -@@ -63,9 +65,18 @@ class DeathMonitor final { - // Precondition: `killable` must be non-null. - void remove(IProtectedCallback* killable) const; - -+ uintptr_t getCookieKey() const { return kCookieKey; } -+ -+ ~DeathMonitor(); -+ DeathMonitor(const DeathMonitor&) = delete; -+ DeathMonitor(DeathMonitor&&) noexcept = delete; -+ DeathMonitor& operator=(const DeathMonitor&) = delete; -+ DeathMonitor& operator=(DeathMonitor&&) noexcept = delete; -+ - private: - mutable std::mutex mMutex; - mutable std::vector mObjects GUARDED_BY(mMutex); -+ const uintptr_t kCookieKey; - }; - - class DeathHandler final { -diff --git a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp -index 54a673caf..4a7ac0889 100644 ---- a/neuralnetworks/aidl/utils/src/ProtectCallback.cpp -+++ b/neuralnetworks/aidl/utils/src/ProtectCallback.cpp -@@ -25,6 +25,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -33,6 +34,16 @@ - - namespace aidl::android::hardware::neuralnetworks::utils { - -+namespace { -+ -+// Only dereference the cookie if it's valid (if it's in this set) -+// Only used with ndk -+std::mutex sCookiesMutex; -+uintptr_t sCookieKeyCounter GUARDED_BY(sCookiesMutex) = 0; -+std::map> sCookies GUARDED_BY(sCookiesMutex); -+ -+} // namespace -+ - void DeathMonitor::serviceDied() { - std::lock_guard guard(mMutex); - std::for_each(mObjects.begin(), mObjects.end(), -@@ -40,8 +51,24 @@ void DeathMonitor::serviceDied() { - } - - void DeathMonitor::serviceDied(void* cookie) { -- auto deathMonitor = static_cast(cookie); -- deathMonitor->serviceDied(); -+ std::shared_ptr monitor; -+ { -+ std::lock_guard guard(sCookiesMutex); -+ if (auto it = sCookies.find(reinterpret_cast(cookie)); it != sCookies.end()) { -+ monitor = it->second.lock(); -+ sCookies.erase(it); -+ } else { -+ LOG(INFO) -+ << "Service died, but cookie is no longer valid so there is nothing to notify."; -+ return; -+ } -+ } -+ if (monitor) { -+ LOG(INFO) << "Notifying DeathMonitor from serviceDied."; -+ monitor->serviceDied(); -+ } else { -+ LOG(INFO) << "Tried to notify DeathMonitor from serviceDied but could not promote."; -+ } - } - - void DeathMonitor::add(IProtectedCallback* killable) const { -@@ -57,12 +84,25 @@ void DeathMonitor::remove(IProtectedCallback* killable) const { - mObjects.erase(removedIter); - } - -+DeathMonitor::~DeathMonitor() { -+ // lock must be taken so object is not used in OnBinderDied" -+ std::lock_guard guard(sCookiesMutex); -+ sCookies.erase(kCookieKey); -+} -+ - nn::GeneralResult DeathHandler::create(std::shared_ptr object) { - if (object == nullptr) { - return NN_ERROR(nn::ErrorStatus::INVALID_ARGUMENT) - << "utils::DeathHandler::create must have non-null object"; - } -- auto deathMonitor = std::make_shared(); -+ -+ std::shared_ptr deathMonitor; -+ { -+ std::lock_guard guard(sCookiesMutex); -+ deathMonitor = std::make_shared(sCookieKeyCounter++); -+ sCookies[deathMonitor->getCookieKey()] = deathMonitor; -+ } -+ - auto deathRecipient = ndk::ScopedAIBinder_DeathRecipient( - AIBinder_DeathRecipient_new(DeathMonitor::serviceDied)); - -@@ -70,8 +110,9 @@ nn::GeneralResult DeathHandler::create(std::shared_ptrisRemote()) { -- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_linkToDeath( -- object->asBinder().get(), deathRecipient.get(), deathMonitor.get())); -+ const auto ret = ndk::ScopedAStatus::fromStatus( -+ AIBinder_linkToDeath(object->asBinder().get(), deathRecipient.get(), -+ reinterpret_cast(deathMonitor->getCookieKey()))); - HANDLE_ASTATUS(ret) << "AIBinder_linkToDeath failed"; - } - -@@ -91,8 +132,9 @@ DeathHandler::DeathHandler(std::shared_ptr object, - - DeathHandler::~DeathHandler() { - if (kObject != nullptr && kDeathRecipient.get() != nullptr && kDeathMonitor != nullptr) { -- const auto ret = ndk::ScopedAStatus::fromStatus(AIBinder_unlinkToDeath( -- kObject->asBinder().get(), kDeathRecipient.get(), kDeathMonitor.get())); -+ const auto ret = ndk::ScopedAStatus::fromStatus( -+ AIBinder_unlinkToDeath(kObject->asBinder().get(), kDeathRecipient.get(), -+ reinterpret_cast(kDeathMonitor->getCookieKey()))); - const auto maybeSuccess = handleTransportError(ret); - if (!maybeSuccess.ok()) { - LOG(ERROR) << maybeSuccess.error().message; -diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp -index 73727b397..ffd3b8e5f 100644 ---- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp -+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp -@@ -697,7 +697,8 @@ TEST_P(DeviceTest, prepareModelAsyncCrash) { - const auto mockDevice = createMockDevice(); - const auto device = Device::create(kName, mockDevice, kVersion).value(); - const auto ret = [&device]() { -- DeathMonitor::serviceDied(device->getDeathMonitor()); -+ DeathMonitor::serviceDied( -+ reinterpret_cast(device->getDeathMonitor()->getCookieKey())); - return ndk::ScopedAStatus::ok(); - }; - EXPECT_CALL(*mockDevice, prepareModel(_, _, _, _, _, _, _, _)) -@@ -846,7 +847,8 @@ TEST_P(DeviceTest, prepareModelWithConfigAsyncCrash) { - const auto mockDevice = createMockDevice(); - const auto device = Device::create(kName, mockDevice, kVersion).value(); - const auto ret = [&device]() { -- DeathMonitor::serviceDied(device->getDeathMonitor()); -+ DeathMonitor::serviceDied( -+ reinterpret_cast(device->getDeathMonitor()->getCookieKey())); - return ndk::ScopedAStatus::ok(); - }; - EXPECT_CALL(*mockDevice, prepareModelWithConfig(_, _, _)) -@@ -970,7 +972,8 @@ TEST_P(DeviceTest, prepareModelFromCacheAsyncCrash) { - const auto mockDevice = createMockDevice(); - const auto device = Device::create(kName, mockDevice, kVersion).value(); - const auto ret = [&device]() { -- DeathMonitor::serviceDied(device->getDeathMonitor()); -+ DeathMonitor::serviceDied( -+ reinterpret_cast(device->getDeathMonitor()->getCookieKey())); - return ndk::ScopedAStatus::ok(); - }; - EXPECT_CALL(*mockDevice, prepareModelFromCache(_, _, _, _, _)) --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/hardware/libhardware/0001-Keymaster-Add-new-keymaster-error-code-for-provision.patch b/aosp_diff/preliminary/hardware/libhardware/0001-Keymaster-Add-new-keymaster-error-code-for-provision.patch index ff6c03c301..008d56f518 100644 --- a/aosp_diff/preliminary/hardware/libhardware/0001-Keymaster-Add-new-keymaster-error-code-for-provision.patch +++ b/aosp_diff/preliminary/hardware/libhardware/0001-Keymaster-Add-new-keymaster-error-code-for-provision.patch @@ -1,4 +1,4 @@ -From fd244dd548b6575db7aafd6512b564964dad73db Mon Sep 17 00:00:00 2001 +From 9547df70286d70d5889ae852aa89b9da937169cc Mon Sep 17 00:00:00 2001 From: "Zhong,Fangjian" Date: Mon, 8 Feb 2021 09:33:18 +0800 Subject: [PATCH] Keymaster: Add new keymaster error code for provisioning @@ -9,14 +9,14 @@ type of trying to provision device which has been already provisioned. Tracked-On: OAM-95939 Signed-off-by: Zhong,Fangjian --- - include/hardware/keymaster_defs.h | 1 + + include_all/hardware/keymaster_defs.h | 1 + 1 file changed, 1 insertion(+) -diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h -index 2fbfe46d..8cd82abf 100644 ---- a/include/hardware/keymaster_defs.h -+++ b/include/hardware/keymaster_defs.h -@@ -474,6 +474,7 @@ typedef enum { +diff --git a/include_all/hardware/keymaster_defs.h b/include_all/hardware/keymaster_defs.h +index dd286d6d..044dd55a 100644 +--- a/include_all/hardware/keymaster_defs.h ++++ b/include_all/hardware/keymaster_defs.h +@@ -520,6 +520,7 @@ typedef enum { KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, @@ -25,5 +25,5 @@ index 2fbfe46d..8cd82abf 100644 } keymaster_error_t; -- -2.25.1 +2.34.1 diff --git a/aosp_diff/preliminary/libcore/0001-Source-optimizations-in-luni.patch b/aosp_diff/preliminary/libcore/0001-Source-optimizations-in-luni.patch deleted file mode 100644 index b57d5b1892..0000000000 --- a/aosp_diff/preliminary/libcore/0001-Source-optimizations-in-luni.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 357d0cb97bd7cc6f9edf8868480ece358f8a041b Mon Sep 17 00:00:00 2001 -From: bodapati -Date: Wed, 29 Apr 2020 17:31:57 +0530 -Subject: [PATCH] Source optimizations in luni - -1.Replace %2 with & -2.Hoist invariant calculation outside loop - -Change-Id: Ie3f5f9a300b36e2a1c5ebf5f90607760e0b150b3 -Tracked-On: OAM-91030 -Signed-off-by: bodapati ---- - luni/src/main/native/libcore_io_Memory.cpp | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git luni/src/main/native/libcore_io_Memory.cpp luni/src/main/native/libcore_io_Memory.cpp -index 5f50751..a900c33 100644 ---- luni/src/main/native/libcore_io_Memory.cpp -+++ luni/src/main/native/libcore_io_Memory.cpp -@@ -64,11 +64,12 @@ static inline void swapShorts(jshort* dstShorts, const jshort* srcShorts, size_t - // Do 32-bit swaps as long as possible... - jint* dst = reinterpret_cast(dstShorts); - const jint* src = reinterpret_cast(srcShorts); -- for (size_t i = 0; i < count / 2; ++i) { -+ size_t sz = count/2; -+ for (size_t i = 0; i < sz; ++i) { - jint v = get_unaligned(src++); - put_unaligned(dst++, bswap_2x16(v)); - } -- if ((count % 2) != 0) { -+ if ((count & 1) != 0) { - jshort v = get_unaligned(reinterpret_cast(src)); - put_unaligned(reinterpret_cast(dst), bswap_16(v)); - } --- -2.7.4 - diff --git a/aosp_diff/preliminary/packages/apps/Car/LocalMediaPlayer/0001-Add-some-permissions-for-Local-Media-Player.patch b/aosp_diff/preliminary/packages/apps/Car/LocalMediaPlayer/0001-Add-some-permissions-for-Local-Media-Player.patch deleted file mode 100644 index f814c5a497..0000000000 --- a/aosp_diff/preliminary/packages/apps/Car/LocalMediaPlayer/0001-Add-some-permissions-for-Local-Media-Player.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 447c56f2f88a6d4a6d773eae878a8523eba87d2f Mon Sep 17 00:00:00 2001 -From: Xu Bing -Date: Wed, 31 Jul 2024 09:36:23 +0800 -Subject: [PATCH] Add some permissions for Local Media Player - -Local Media Player can't play audio and videos as the app has not -some permissions, add them to fix the issues. - -Test: Open Local Media Player and play audio and video files. - -Tracked-On: OAM-122382 -Signed-off-by: Xu Bing ---- - AndroidManifest.xml | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/AndroidManifest.xml b/AndroidManifest.xml -index 00dce55..e1d588d 100644 ---- a/AndroidManifest.xml -+++ b/AndroidManifest.xml -@@ -18,7 +18,12 @@ - package="com.android.car.media.localmediaplayer" - android:sharedUserId="com.android.car.media" > - -+ -+ -+ - -+ -+ - - - -Date: Wed, 3 Jan 2024 16:48:31 +0530 -Subject: [PATCH] Fixed to support playing .mkv & .ts videos from File App. - -When user trying to play .mkv/.ts video from File app, it could not -find any player app to play this file. - -Adding support in Gallery app to play these video files. - -Tests: -Open File app, and play .mkv/.ts video. it plays successfully. - -Tracked-On: OAM-118755 -Signed-off-by: Ankit Agrawal -Signed-off-by: Xu Bing ---- - AndroidManifest.xml | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/AndroidManifest.xml b/AndroidManifest.xml -index 6c78774f0..072adff9e 100644 ---- a/AndroidManifest.xml -+++ b/AndroidManifest.xml -@@ -74,6 +74,8 @@ - - - -+ -+ - - - --- -2.34.1 - diff --git a/aosp_diff/preliminary/packages/apps/Gallery2/0002-Fixed-for-crash-in-Gallery-during-monkey-test.patch b/aosp_diff/preliminary/packages/apps/Gallery2/0002-Fixed-for-crash-in-Gallery-during-monkey-test.patch deleted file mode 100644 index 001eed386e..0000000000 --- a/aosp_diff/preliminary/packages/apps/Gallery2/0002-Fixed-for-crash-in-Gallery-during-monkey-test.patch +++ /dev/null @@ -1,194 +0,0 @@ -From e4a2d22324792b43164398476877e1cbf231b9ff Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Thu, 17 Aug 2023 19:22:55 +0530 -Subject: [PATCH] Fixed for crash in Gallery during monkey test. - -Fragment Activity does not support action bar by default. Adding -toolbar in layout to create custom action bar. - -Crash log snippet looks like below: -java.lang.NullPointerException: Attempt to invoke virtual method -'void android.app.ActionBar.setDisplayOptions(int)' on a null object reference -at com.android.gallery3d.filtershow.FilterShowActivity.loadXML(FilterShowActivity.java:352) - -Test: run monkey test, no crash happen. - -Tracked-On: OAM-122773 -Signed-off-by: Ankit Agrawal -Signed-off-by: Xu Bing ---- - res/layout-land/filtershow_activity.xml | 11 +++++-- - res/layout/crop_activity.xml | 10 ++++++- - res/layout/filtershow_activity.xml | 10 ++++++- - .../filtershow/FilterShowActivity.java | 29 +++++++++++-------- - .../filtershow/crop/CropActivity.java | 3 ++ - 5 files changed, 47 insertions(+), 16 deletions(-) - -diff --git a/res/layout-land/filtershow_activity.xml b/res/layout-land/filtershow_activity.xml -index f4380126e..38984aa1d 100644 ---- a/res/layout-land/filtershow_activity.xml -+++ b/res/layout-land/filtershow_activity.xml -@@ -19,7 +19,8 @@ - android:layout_width="match_parent" - android:layout_height="match_parent" - android:id="@+id/mainView" -- android:background="@drawable/filtershow_tiled_background"> -+ android:background="@drawable/filtershow_tiled_background" -+ xmlns:app="http://schemas.android.com/apk/res-auto"> - - - -- - - -+ -+ - - - -diff --git a/res/layout/crop_activity.xml b/res/layout/crop_activity.xml -index 0620cf4d9..5d72f686b 100644 ---- a/res/layout/crop_activity.xml -+++ b/res/layout/crop_activity.xml -@@ -18,7 +18,8 @@ - -+ android:id="@+id/mainView" -+ xmlns:app="http://schemas.android.com/apk/res-auto"> - - - -+ -+ - - - -+ android:background="@drawable/filtershow_tiled_background" -+ xmlns:app="http://schemas.android.com/apk/res-auto"> -+ -+ - - - - -Date: Wed, 23 May 2018 16:37:47 +0800 -Subject: [PATCH 3/5] Fix the audio and video flicker problem when seeking. - -Change-Id: I6def085e62348f1336d5cb116ced5aa2fc8ac7d3 -Tracked-On: https://jira01.devtools.intel.com/browse/OAM-80081 -Signed-off-by: yingzhex -Signed-off-by: Yan, WalterX ---- - src/com/android/gallery3d/app/CommonControllerOverlay.java | 4 ++++ - src/com/android/gallery3d/app/MoviePlayer.java | 6 ++++++ - 2 files changed, 10 insertions(+) - -diff --git a/src/com/android/gallery3d/app/CommonControllerOverlay.java b/src/com/android/gallery3d/app/CommonControllerOverlay.java -index 9adb4e7a8..24bdeb306 100644 ---- a/src/com/android/gallery3d/app/CommonControllerOverlay.java -+++ b/src/com/android/gallery3d/app/CommonControllerOverlay.java -@@ -132,6 +132,10 @@ public abstract class CommonControllerOverlay extends FrameLayout implements - return view; - } - -+ public boolean isPlaying() { -+ return (mState == State.PLAYING); -+ } -+ - @Override - public void setListener(Listener listener) { - this.mListener = listener; -diff --git a/src/com/android/gallery3d/app/MoviePlayer.java b/src/com/android/gallery3d/app/MoviePlayer.java -index f6bd36725..b4052f1fe 100644 ---- a/src/com/android/gallery3d/app/MoviePlayer.java -+++ b/src/com/android/gallery3d/app/MoviePlayer.java -@@ -378,6 +378,9 @@ public class MoviePlayer implements - @Override - public void onSeekStart() { - mDragging = true; -+ if(mController.isPlaying()){ -+ mVideoView.pause(); -+ } - } - - @Override -@@ -388,6 +391,9 @@ public class MoviePlayer implements - @Override - public void onSeekEnd(int time, int start, int end) { - mDragging = false; -+ if(mController.isPlaying()){ -+ mVideoView.start(); -+ } - mVideoView.seekTo(time); - setProgress(); - } --- -2.21.0 diff --git a/aosp_diff/preliminary/packages/apps/Gallery2/04_0004-Fix-for-synchronization-error-in-image-cache.patch b/aosp_diff/preliminary/packages/apps/Gallery2/04_0004-Fix-for-synchronization-error-in-image-cache.patch deleted file mode 100644 index 4735d647cf..0000000000 --- a/aosp_diff/preliminary/packages/apps/Gallery2/04_0004-Fix-for-synchronization-error-in-image-cache.patch +++ /dev/null @@ -1,76 +0,0 @@ -From e8fc4ddb2a1a6de5326efc161134eb01ef8313aa Mon Sep 17 00:00:00 2001 -From: Tanuj Tekriwal -Date: Fri, 1 Sep 2023 17:18:20 +0000 -Subject: [PATCH] Fix for synchronization error in image cache - -The patch handles the cache null condition and avoids -the synchronize call if its null. - -Tracked-On: OAM-112051 -Change-Id: Ieabcf8a3061869fd87d1393f11674076450706de -Signed-off-by: Tanuj Tekriwal ---- - .../gallery3d/data/ImageCacheService.java | 33 ++++++++++--------- - 1 file changed, 18 insertions(+), 15 deletions(-) - -diff --git a/src/com/android/gallery3d/data/ImageCacheService.java b/src/com/android/gallery3d/data/ImageCacheService.java -index 1c7cb8c5e..e537107c0 100644 ---- a/src/com/android/gallery3d/data/ImageCacheService.java -+++ b/src/com/android/gallery3d/data/ImageCacheService.java -@@ -62,9 +62,10 @@ public class ImageCacheService { - LookupRequest request = new LookupRequest(); - request.key = cacheKey; - request.buffer = buffer.data; -- synchronized (mCache) { -- if (!mCache.lookup(request)) return false; -- } -+ if(mCache != null) -+ synchronized (mCache) { -+ if (!mCache.lookup(request)) return false; -+ } - if (isSameKey(key, request.buffer)) { - buffer.data = request.buffer; - buffer.offset = key.length; -@@ -83,25 +84,27 @@ public class ImageCacheService { - ByteBuffer buffer = ByteBuffer.allocate(key.length + value.length); - buffer.put(key); - buffer.put(value); -- synchronized (mCache) { -- try { -- mCache.insert(cacheKey, buffer.array()); -- } catch (IOException ex) { -- // ignore. -+ if(mCache != null) -+ synchronized (mCache) { -+ try { -+ mCache.insert(cacheKey, buffer.array()); -+ } catch (IOException ex) { -+ // ignore. -+ } - } -- } - } - - public void clearImageData(Path path, long timeModified, int type) { - byte[] key = makeKey(path, timeModified, type); - long cacheKey = Utils.crc64Long(key); -- synchronized (mCache) { -- try { -- mCache.clearEntry(cacheKey); -- } catch (IOException ex) { -- // ignore. -+ if(mCache != null) -+ synchronized (mCache) { -+ try { -+ mCache.clearEntry(cacheKey); -+ } catch (IOException ex) { -+ // ignore. -+ } - } -- } - } - - private static byte[] makeKey(Path path, long timeModified, int type) { --- -2.39.2 - diff --git a/aosp_diff/preliminary/packages/apps/Settings/0010-Change-the-intent-flag-to-immutable.patch b/aosp_diff/preliminary/packages/apps/Settings/0010-Change-the-intent-flag-to-immutable.patch deleted file mode 100644 index 62d7b8c596..0000000000 --- a/aosp_diff/preliminary/packages/apps/Settings/0010-Change-the-intent-flag-to-immutable.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0db4066637df67cd5ec26491a5b42a996ceb51cd Mon Sep 17 00:00:00 2001 -From: changbetty -Date: Wed, 21 Dec 2022 10:16:10 +0000 -Subject: [PATCH] Change the intent flag to immutable - -Bug: 256590210 -Test: make RunSettingsRoboTests ROBOTEST_FILTER=MediaVolumePreferenceControllerTest -Change-Id: I68132f863027fab19351b4fdbc363e5c274e3327 -Merged-In: I68132f863027fab19351b4fdbc363e5c274e3327 -(cherry picked from commit 0dcd6a5492fae67e0d7f1fb83f6d4db7eaa15b55) -Merged-In: I68132f863027fab19351b4fdbc363e5c274e3327 ---- - .../notification/MediaVolumePreferenceController.java | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/com/android/settings/notification/MediaVolumePreferenceController.java b/src/com/android/settings/notification/MediaVolumePreferenceController.java -index 2466b7747a..85c053e3b0 100644 ---- a/src/com/android/settings/notification/MediaVolumePreferenceController.java -+++ b/src/com/android/settings/notification/MediaVolumePreferenceController.java -@@ -124,7 +124,7 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont - getWorker().getActiveLocalMediaController().getPackageName()); - - pi = PendingIntent.getBroadcast(context, 0 /* requestCode */, intent, -- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); -+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - } else { - final CachedBluetoothDevice bluetoothDevice = - ((BluetoothMediaDevice) mMediaDevice).getCachedDevice(); -@@ -141,7 +141,7 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont - && getWorker().getActiveLocalMediaController() != null); - - pi = PendingIntent.getActivity(context, 0 /* requestCode */, intent, -- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE); -+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); - } - - final IconCompat icon = getBroadcastIcon(context); --- -2.17.1 - diff --git a/aosp_diff/preliminary/packages/apps/Settings/0011--RESTRICT-AUTOMERGE-Restrict-WifiDialogActivity.bulletin.patch b/aosp_diff/preliminary/packages/apps/Settings/0011--RESTRICT-AUTOMERGE-Restrict-WifiDialogActivity.bulletin.patch deleted file mode 100644 index 1dd7edfeaa..0000000000 --- a/aosp_diff/preliminary/packages/apps/Settings/0011--RESTRICT-AUTOMERGE-Restrict-WifiDialogActivity.bulletin.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 2e90322bab7de1deaf3c82e207bf4404b92743d7 Mon Sep 17 00:00:00 2001 -From: Weng Su -Date: Fri, 26 Jan 2024 17:59:40 +0800 -Subject: [PATCH] [RESTRICT AUTOMERGE] Restrict WifiDialogActivity - -- Don't show WifiDialogActivity if user has DISALLOW_ADD_WIFI_CONFIG - -Bug: 299931761 -Flag: None -Test: manual test with TestDPC -atest -c SettingsRoboTests:WifiDialogActivityTest - -(cherry picked from commit 51fa3d798ad0397122bbb2143bc24efe1a705be9) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a0409e582c30d2d6ff347eefd173ae169963df75) -Merged-In: Icbb8f45922ded163208976be9c2816060dcf09f1 -Change-Id: Icbb8f45922ded163208976be9c2816060dcf09f1 ---- - .../android/settings/wifi/WifiDialogActivity.java | 13 ++++++++++++- - .../settings/wifi/WifiDialogActivityTest.java | 15 +++++++++++++++ - 2 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/src/com/android/settings/wifi/WifiDialogActivity.java b/src/com/android/settings/wifi/WifiDialogActivity.java -index e3e77e8600..dda5929a98 100644 ---- a/src/com/android/settings/wifi/WifiDialogActivity.java -+++ b/src/com/android/settings/wifi/WifiDialogActivity.java -@@ -17,6 +17,7 @@ - package com.android.settings.wifi; - - import static android.Manifest.permission.ACCESS_FINE_LOCATION; -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; - import static android.os.UserManager.DISALLOW_CONFIG_WIFI; - - import android.app.KeyguardManager; -@@ -122,7 +123,7 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog - } - - super.onCreate(savedInstanceState); -- if (!isConfigWifiAllowed()) { -+ if (!isConfigWifiAllowed() || !isAddWifiConfigAllowed()) { - finish(); - return; - } -@@ -393,6 +394,16 @@ public class WifiDialogActivity extends ObservableActivity implements WifiDialog - return isConfigWifiAllowed; - } - -+ @VisibleForTesting -+ boolean isAddWifiConfigAllowed() { -+ UserManager userManager = getSystemService(UserManager.class); -+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { -+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); -+ return false; -+ } -+ return true; -+ } -+ - private boolean hasWifiManager() { - if (mWifiManager != null) return true; - mWifiManager = getSystemService(WifiManager.class); -diff --git a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java -index 8b9faf2ff0..ad3cfd4a2b 100644 ---- a/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java -+++ b/tests/robotests/src/com/android/settings/wifi/WifiDialogActivityTest.java -@@ -18,6 +18,7 @@ package com.android.settings.wifi; - - import static android.Manifest.permission.ACCESS_COARSE_LOCATION; - import static android.Manifest.permission.ACCESS_FINE_LOCATION; -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; - import static android.os.UserManager.DISALLOW_CONFIG_WIFI; - - import static com.android.settings.wifi.WifiDialogActivity.REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER; -@@ -240,6 +241,20 @@ public class WifiDialogActivityTest { - assertThat(mActivity.isConfigWifiAllowed()).isFalse(); - } - -+ @Test -+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); -+ -+ assertThat(mActivity.isAddWifiConfigAllowed()).isTrue(); -+ } -+ -+ @Test -+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); -+ -+ assertThat(mActivity.isAddWifiConfigAllowed()).isFalse(); -+ } -+ - @Test - public void hasPermissionForResult_noCallingPackage_returnFalse() { - when(mActivity.getCallingPackage()).thenReturn(null); --- -2.44.0.rc0.258.g7320e95886-goog - diff --git a/aosp_diff/preliminary/packages/apps/Settings/12_0012-Replace-getCallingActivity-with-getLaunchedFromPackage-.bulletin.patch b/aosp_diff/preliminary/packages/apps/Settings/12_0012-Replace-getCallingActivity-with-getLaunchedFromPackage-.bulletin.patch deleted file mode 100644 index 2be6b33290..0000000000 --- a/aosp_diff/preliminary/packages/apps/Settings/12_0012-Replace-getCallingActivity-with-getLaunchedFromPackage-.bulletin.patch +++ /dev/null @@ -1,175 +0,0 @@ -From f1d0079c91734168c150f839168544f407b17b06 Mon Sep 17 00:00:00 2001 -From: Jason Chiu -Date: Wed, 31 Jan 2024 16:29:01 +0800 -Subject: [PATCH] Replace getCallingActivity() with getLaunchedFromPackage() - -getLaunchedFromPackage() reports who launched this Activity or built -PendingIntent used to launch it, whereas getCallingActivity() reports -who will get result of Activity. - -Bug: 316891059 -Test: robotest, manual -(cherry picked from commit 901880a1d2e632179eb4ac708fc4bc18d9d50791) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ddc11bc03ab48e885f652b89df5f92ff283bcd4a) -Merged-In: If97018c2741caef622f0596bbfeaa42ef1788b78 -Change-Id: If97018c2741caef622f0596bbfeaa42ef1788b78 ---- - .../settings/search/SearchFeatureProvider.java | 2 +- - .../search/SearchFeatureProviderImpl.java | 18 ++++++++---------- - .../search/SearchResultTrampoline.java | 13 ++++++------- - .../search/SearchFeatureProviderImplTest.java | 15 ++++++++------- - 4 files changed, 23 insertions(+), 25 deletions(-) - -diff --git a/src/com/android/settings/search/SearchFeatureProvider.java b/src/com/android/settings/search/SearchFeatureProvider.java -index cd096ec6e1..c2257b47c9 100644 ---- a/src/com/android/settings/search/SearchFeatureProvider.java -+++ b/src/com/android/settings/search/SearchFeatureProvider.java -@@ -56,7 +56,7 @@ public interface SearchFeatureProvider { - * @throws IllegalArgumentException when caller is null - * @throws SecurityException when caller is not allowed to launch search result page - */ -- void verifyLaunchSearchResultPageCaller(Context context, @NonNull ComponentName caller) -+ void verifyLaunchSearchResultPageCaller(@NonNull Context context, @NonNull String callerPackage) - throws SecurityException, IllegalArgumentException; - - /** -diff --git a/src/com/android/settings/search/SearchFeatureProviderImpl.java b/src/com/android/settings/search/SearchFeatureProviderImpl.java -index 6f90970905..3a62ddfb67 100644 ---- a/src/com/android/settings/search/SearchFeatureProviderImpl.java -+++ b/src/com/android/settings/search/SearchFeatureProviderImpl.java -@@ -17,13 +17,14 @@ - - package com.android.settings.search; - --import android.content.ComponentName; - import android.content.Context; - import android.content.Intent; - import android.net.Uri; - import android.provider.Settings; - import android.text.TextUtils; - -+import androidx.annotation.NonNull; -+ - import com.android.settingslib.search.SearchIndexableResources; - import com.android.settingslib.search.SearchIndexableResourcesMobile; - -@@ -32,21 +33,18 @@ import com.android.settingslib.search.SearchIndexableResourcesMobile; - */ - public class SearchFeatureProviderImpl implements SearchFeatureProvider { - -- private static final String TAG = "SearchFeatureProvider"; -- - private SearchIndexableResources mSearchIndexableResources; - - @Override -- public void verifyLaunchSearchResultPageCaller(Context context, ComponentName caller) { -- if (caller == null) { -+ public void verifyLaunchSearchResultPageCaller(@NonNull Context context, -+ @NonNull String callerPackage) { -+ if (TextUtils.isEmpty(callerPackage)) { - throw new IllegalArgumentException("ExternalSettingsTrampoline intents " - + "must be called with startActivityForResult"); - } -- final String packageName = caller.getPackageName(); -- final boolean isSettingsPackage = TextUtils.equals(packageName, context.getPackageName()) -- || TextUtils.equals(getSettingsIntelligencePkgName(context), packageName); -- final boolean isAllowlistedPackage = -- isSignatureAllowlisted(context, caller.getPackageName()); -+ final boolean isSettingsPackage = TextUtils.equals(callerPackage, context.getPackageName()) -+ || TextUtils.equals(getSettingsIntelligencePkgName(context), callerPackage); -+ final boolean isAllowlistedPackage = isSignatureAllowlisted(context, callerPackage); - if (isSettingsPackage || isAllowlistedPackage) { - return; - } -diff --git a/src/com/android/settings/search/SearchResultTrampoline.java b/src/com/android/settings/search/SearchResultTrampoline.java -index 6ba0338bfc..504e298574 100644 ---- a/src/com/android/settings/search/SearchResultTrampoline.java -+++ b/src/com/android/settings/search/SearchResultTrampoline.java -@@ -20,7 +20,6 @@ import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENT - import static com.android.settings.SettingsActivity.EXTRA_SHOW_FRAGMENT_TAB; - - import android.app.Activity; --import android.content.ComponentName; - import android.content.Intent; - import android.net.Uri; - import android.os.Bundle; -@@ -52,11 +51,11 @@ public class SearchResultTrampoline extends Activity { - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - -- final ComponentName callingActivity = getCallingActivity(); -+ final String callerPackage = getLaunchedFromPackage(); - // First make sure caller has privilege to launch a search result page. - FeatureFactory.getFactory(this) - .getSearchFeatureProvider() -- .verifyLaunchSearchResultPageCaller(this, callingActivity); -+ .verifyLaunchSearchResultPageCaller(this, callerPackage); - // Didn't crash, proceed and launch the result as a subsetting. - Intent intent = getIntent(); - final String highlightMenuKey = intent.getStringExtra( -@@ -105,7 +104,7 @@ public class SearchResultTrampoline extends Activity { - if (!ActivityEmbeddingUtils.isEmbeddingActivityEnabled(this) - || ActivityEmbeddingUtils.isAlreadyEmbedded(this)) { - startActivity(intent); -- } else if (isSettingsIntelligence(callingActivity)) { -+ } else if (isSettingsIntelligence(callerPackage)) { - if (FeatureFlagUtils.isEnabled(this, FeatureFlags.SETTINGS_SEARCH_ALWAYS_EXPAND)) { - startActivity(SettingsActivity.getTrampolineIntent(intent, highlightMenuKey) - .setClass(this, DeepLinkHomepageActivityInternal.class) -@@ -138,9 +137,9 @@ public class SearchResultTrampoline extends Activity { - finish(); - } - -- private boolean isSettingsIntelligence(ComponentName callingActivity) { -- return callingActivity != null && TextUtils.equals( -- callingActivity.getPackageName(), -+ private boolean isSettingsIntelligence(String callerPackage) { -+ return TextUtils.equals( -+ callerPackage, - FeatureFactory.getFactory(this).getSearchFeatureProvider() - .getSettingsIntelligencePkgName(this)); - } -diff --git a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java -index 0aa49eb6d6..7a1b2606a9 100644 ---- a/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java -+++ b/tests/robotests/src/com/android/settings/search/SearchFeatureProviderImplTest.java -@@ -20,7 +20,6 @@ package com.android.settings.search; - import static com.google.common.truth.Truth.assertThat; - - import android.app.settings.SettingsEnums; --import android.content.ComponentName; - import android.content.Intent; - import android.content.pm.ActivityInfo; - import android.content.pm.ResolveInfo; -@@ -136,20 +135,22 @@ public class SearchFeatureProviderImplTest { - - @Test(expected = SecurityException.class) - public void verifyLaunchSearchResultPageCaller_badCaller_shouldCrash() { -- final ComponentName cn = new ComponentName("pkg", "class"); -- mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn); -+ final String packageName = "pkg"; -+ -+ mProvider.verifyLaunchSearchResultPageCaller(mActivity, packageName); - } - - @Test - public void verifyLaunchSearchResultPageCaller_settingsCaller_shouldNotCrash() { -- final ComponentName cn = new ComponentName(mActivity.getPackageName(), "class"); -- mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn); -+ final String packageName = mActivity.getPackageName(); -+ -+ mProvider.verifyLaunchSearchResultPageCaller(mActivity, packageName); - } - - @Test - public void verifyLaunchSearchResultPageCaller_settingsIntelligenceCaller_shouldNotCrash() { - final String packageName = mProvider.getSettingsIntelligencePkgName(mActivity); -- final ComponentName cn = new ComponentName(packageName, "class"); -- mProvider.verifyLaunchSearchResultPageCaller(mActivity, cn); -+ -+ mProvider.verifyLaunchSearchResultPageCaller(mActivity, packageName); - } - } --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/packages/apps/Settings/13_0013-RESTRICT-AUTOMERGE-Restrict-WifiDppConfiguratorActivity.bulletin.patch b/aosp_diff/preliminary/packages/apps/Settings/13_0013-RESTRICT-AUTOMERGE-Restrict-WifiDppConfiguratorActivity.bulletin.patch deleted file mode 100644 index ebb720f033..0000000000 --- a/aosp_diff/preliminary/packages/apps/Settings/13_0013-RESTRICT-AUTOMERGE-Restrict-WifiDppConfiguratorActivity.bulletin.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 20b312f86a7082351d9d2ab45a100d8e278277ec Mon Sep 17 00:00:00 2001 -From: Weng Su -Date: Wed, 3 Apr 2024 10:45:43 +0800 -Subject: [PATCH] [RESTRICT AUTOMERGE] Restrict WifiDppConfiguratorActivity - -- Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG - -- Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG - -Fix: 299931076 -Flag: None -Test: manual test with TestDPC -atest -c SettingsUnitTests:AddNetworkFragmentTest \ - SettingsUnitTests:WifiDppConfiguratorActivityTest -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:0ea027a71cc97ca07576fa4bdaff608eec326f78) -Merged-In: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a -Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a ---- - .../settings/wifi/AddNetworkFragment.java | 20 +++++ - .../wifi/dpp/WifiDppConfiguratorActivity.java | 20 +++++ - .../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++ - .../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++ - 4 files changed, 188 insertions(+) - create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java - create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java - -diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java -index 9fd8626f3b..f5bf5eec9d 100644 ---- a/src/com/android/settings/wifi/AddNetworkFragment.java -+++ b/src/com/android/settings/wifi/AddNetworkFragment.java -@@ -16,12 +16,17 @@ - - package com.android.settings.wifi; - -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; -+ - import android.app.Activity; - import android.app.settings.SettingsEnums; -+import android.content.Context; - import android.content.Intent; - import android.net.wifi.WifiConfiguration; - import android.net.wifi.WifiManager; - import android.os.Bundle; -+import android.os.UserManager; -+import android.util.Log; - import android.view.LayoutInflater; - import android.view.View; - import android.view.ViewGroup; -@@ -43,6 +48,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils; - */ - public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2, - View.OnClickListener { -+ private static final String TAG = "AddNetworkFragment"; - - public static final String WIFI_CONFIG_KEY = "wifi_config_key"; - @VisibleForTesting -@@ -62,6 +68,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); -+ if (!isAddWifiConfigAllowed(getContext())) { -+ getActivity().finish(); -+ return; -+ } - } - - @Override -@@ -237,4 +247,14 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf - activity.setResult(Activity.RESULT_CANCELED); - activity.finish(); - } -+ -+ @VisibleForTesting -+ static boolean isAddWifiConfigAllowed(Context context) { -+ UserManager userManager = context.getSystemService(UserManager.class); -+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { -+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); -+ return false; -+ } -+ return true; -+ } - } -diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java -index e6f0b31f38..a7527d7332 100644 ---- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java -+++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java -@@ -16,6 +16,8 @@ - - package com.android.settings.wifi.dpp; - -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; -+ - import android.app.settings.SettingsEnums; - import android.content.Context; - import android.content.Intent; -@@ -99,6 +101,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); -+ if (!isAddWifiConfigAllowed(getApplicationContext())) { -+ finish(); -+ return; -+ } - - if (savedInstanceState != null) { - String qrCode = savedInstanceState.getString(KEY_QR_CODE); -@@ -119,6 +125,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements - - @Override - protected void handleIntent(Intent intent) { -+ if (!isAddWifiConfigAllowed(getApplicationContext())) { -+ finish(); -+ return; -+ } - if (isGuestUser(getApplicationContext())) { - Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!"); - EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest"); -@@ -402,4 +412,14 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements - if (userManager == null) return false; - return userManager.isGuestUser(); - } -+ -+ @VisibleForTesting -+ static boolean isAddWifiConfigAllowed(Context context) { -+ UserManager userManager = context.getSystemService(UserManager.class); -+ if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { -+ Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); -+ return false; -+ } -+ return true; -+ } - } -diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java -new file mode 100644 -index 0000000000..22d43c9bb4 ---- /dev/null -+++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java -@@ -0,0 +1,74 @@ -+/* -+ * 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 com.android.settings.wifi; -+ -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; -+ -+import static com.google.common.truth.Truth.assertThat; -+ -+import static org.mockito.Mockito.when; -+ -+import android.content.Context; -+import android.os.UserManager; -+ -+import androidx.test.annotation.UiThreadTest; -+import androidx.test.core.app.ApplicationProvider; -+import androidx.test.ext.junit.runners.AndroidJUnit4; -+ -+import org.junit.Before; -+import org.junit.Rule; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.mockito.Mock; -+import org.mockito.Spy; -+import org.mockito.junit.MockitoJUnit; -+import org.mockito.junit.MockitoRule; -+ -+@RunWith(AndroidJUnit4.class) -+@UiThreadTest -+public class AddNetworkFragmentTest { -+ -+ @Rule -+ public final MockitoRule mMockitoRule = MockitoJUnit.rule(); -+ @Spy -+ private final Context mContext = ApplicationProvider.getApplicationContext(); -+ @Mock -+ private UserManager mUserManager; -+ -+ private AddNetworkFragment mFragment; -+ -+ @Before -+ public void setUp() { -+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); -+ -+ mFragment = new AddNetworkFragment(); -+ } -+ -+ @Test -+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); -+ -+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue(); -+ } -+ -+ @Test -+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); -+ -+ assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse(); -+ } -+} -diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java -new file mode 100644 -index 0000000000..4d723dc184 ---- /dev/null -+++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java -@@ -0,0 +1,74 @@ -+/* -+ * 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 com.android.settings.wifi.dpp; -+ -+import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; -+ -+import static com.google.common.truth.Truth.assertThat; -+ -+import static org.mockito.Mockito.when; -+ -+import android.content.Context; -+import android.os.UserManager; -+ -+import androidx.test.annotation.UiThreadTest; -+import androidx.test.core.app.ApplicationProvider; -+import androidx.test.ext.junit.runners.AndroidJUnit4; -+ -+import org.junit.Before; -+import org.junit.Rule; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.mockito.Mock; -+import org.mockito.Spy; -+import org.mockito.junit.MockitoJUnit; -+import org.mockito.junit.MockitoRule; -+ -+@RunWith(AndroidJUnit4.class) -+@UiThreadTest -+public class WifiDppConfiguratorActivityTest { -+ -+ @Rule -+ public final MockitoRule mMockitoRule = MockitoJUnit.rule(); -+ @Spy -+ private final Context mContext = ApplicationProvider.getApplicationContext(); -+ @Mock -+ private UserManager mUserManager; -+ -+ private WifiDppConfiguratorActivity mActivity; -+ -+ @Before -+ public void setUp() { -+ when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); -+ -+ mActivity = new WifiDppConfiguratorActivity(); -+ } -+ -+ @Test -+ public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); -+ -+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue(); -+ } -+ -+ @Test -+ public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { -+ when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); -+ -+ assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse(); -+ } -+} --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0001-Fix-bluetooth-crash-when-stack-unable-to-start-HCI_M.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0001-Fix-bluetooth-crash-when-stack-unable-to-start-HCI_M.patch deleted file mode 100644 index 0d79705fc8..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0001-Fix-bluetooth-crash-when-stack-unable-to-start-HCI_M.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 31646ee20b6dd8ce07a5c2f7e4583a20a0486146 Mon Sep 17 00:00:00 2001 -From: Aiswarya Cyriac -Date: Wed, 13 Jul 2022 19:47:18 +0530 -Subject: [PATCH] Fix bluetooth crash when stack unable to start HCI_MODULE - -When BT is in Host controlled mode for CIV, if user tries -to turn ON, Bluetooth crashes continously. Added fix in -stack to gracefully shutdown HCI_MODULE if it is unable to -start it. - -Change-Id: I98d3df271c9c7d97d78e7c426414b65c1946f9fc -Tracked-On: OAM-89874 -Signed-off-by: Aiswarya Cyriac -Co-authored-by: Gowtham Anandha Babu ---- - system/btcore/src/module.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/system/btcore/src/module.cc b/system/btcore/src/module.cc -index f0d643d63f..8df9defceb 100644 ---- a/system/btcore/src/module.cc -+++ b/system/btcore/src/module.cc -@@ -100,7 +100,7 @@ void module_shut_down(const module_t* module) { - CHECK(state <= MODULE_STATE_STARTED); - - // Only something to do if the module was actually started -- if (state < MODULE_STATE_STARTED) return; -+ if (state < MODULE_STATE_STARTED && strcmp(module->name, "hci_module")) return; - - LOG_INFO("%s Shutting down module \"%s\"", __func__, module->name); - if (!call_lifecycle_function(module->shut_down)) { --- -2.17.1 - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0002-Fix-for-crash-during-SDP-due-to-garbage-memory-acces.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0002-Fix-for-crash-during-SDP-due-to-garbage-memory-acces.patch deleted file mode 100644 index ee0b8ec53f..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0002-Fix-for-crash-during-SDP-due-to-garbage-memory-acces.patch +++ /dev/null @@ -1,106 +0,0 @@ -From a57c9eea0fc1f85628eb5ba163df103a4559cef6 Mon Sep 17 00:00:00 2001 -From: Aiswarya Cyriac -Date: Wed, 13 Jul 2022 19:48:39 +0530 -Subject: [PATCH] Fix for crash during SDP due to garbage memory access - -Issue: Crash is seen when repeated connection and disconnection -is made for OPP file transfer. crash happens during SDP result parsing - -Root cause: tSDP_PROTOCOL_ELEM pe is not initialized - -Change-Id: I46be0b05165debe36babf7182b30eec11cac756c -Tracked-On: OAM-97127 -Signed-off-by: Aiswarya Cyriac -Co-authored-by: Gowtham Anandha Babu ---- - system/bta/ag/bta_ag_sdp.cc | 4 +++- - system/bta/dm/bta_dm_act.cc | 8 ++++++-- - system/bta/hf_client/bta_hf_client_sdp.cc | 5 +++-- - system/bta/jv/bta_jv_act.cc | 4 +++- - 4 files changed, 15 insertions(+), 6 deletions(-) - -diff --git a/system/bta/ag/bta_ag_sdp.cc b/system/bta/ag/bta_ag_sdp.cc -index e9af15c918..1359404b2e 100644 ---- a/system/bta/ag/bta_ag_sdp.cc -+++ b/system/bta/ag/bta_ag_sdp.cc -@@ -326,9 +326,11 @@ bool bta_ag_sdp_find_attr(tBTA_AG_SCB* p_scb, tBTA_SERVICE_MASK service) { - break; - } - -+ memset(&pe, 0, sizeof(tSDP_PROTOCOL_ELEM)); - /* get scn from proto desc list if initiator */ - if (p_scb->role == BTA_AG_INT) { -- if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { -+ if ((SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) -+ && (pe.num_params != 0)) { - p_scb->peer_scn = (uint8_t)pe.params[0]; - } else { - continue; -diff --git a/system/bta/dm/bta_dm_act.cc b/system/bta/dm/bta_dm_act.cc -index 52bb6448f0..0fa56823c1 100644 ---- a/system/bta/dm/bta_dm_act.cc -+++ b/system/bta/dm/bta_dm_act.cc -@@ -1095,11 +1095,15 @@ void bta_dm_sdp_result(tBTA_DM_MSG* p_data) { - do { - p_sdp_rec = NULL; - if (bta_dm_search_cb.service_index == (BTA_USER_SERVICE_ID + 1)) { -- if (p_sdp_rec && SDP_FindProtocolListElemInRec( -- p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) { -+ memset(&pe, 0, sizeof(tSDP_PROTOCOL_ELEM)); -+ if (p_sdp_rec && (SDP_FindProtocolListElemInRec( -+ p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) -+ && (pe.num_params != 0)) { - bta_dm_search_cb.peer_scn = (uint8_t)pe.params[0]; - scn_found = true; - } -+ if (pe.num_params == 0) -+ APPL_TRACE_ERROR("%s pe.num_params = 0", __func__); - } else { - service = - bta_service_id_to_uuid_lkup_tbl[bta_dm_search_cb.service_index - 1]; -diff --git a/system/bta/hf_client/bta_hf_client_sdp.cc b/system/bta/hf_client/bta_hf_client_sdp.cc -index 96b7a6d14b..8fc232ab06 100755 ---- a/system/bta/hf_client/bta_hf_client_sdp.cc -+++ b/system/bta/hf_client/bta_hf_client_sdp.cc -@@ -226,7 +226,7 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { - bool result = false; - - client_cb->peer_version = HFP_VERSION_1_1; /* Default version */ -- -+ memset(&pe, 0, sizeof(tSDP_PROTOCOL_ELEM)); - /* loop through all records we found */ - while (true) { - /* get next record; if none found, we're done */ -@@ -238,7 +238,8 @@ bool bta_hf_client_sdp_find_attr(tBTA_HF_CLIENT_CB* client_cb) { - - /* get scn from proto desc list if initiator */ - if (client_cb->role == BTA_HF_CLIENT_INT) { -- if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) { -+ if ((SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) -+ && (pe.num_params != 0)) { - client_cb->peer_scn = (uint8_t)pe.params[0]; - } else { - continue; -diff --git a/system/bta/jv/bta_jv_act.cc b/system/bta/jv/bta_jv_act.cc -index 6f50077f9c..3993868637 100644 ---- a/system/bta/jv/bta_jv_act.cc -+++ b/system/bta/jv/bta_jv_act.cc -@@ -766,12 +766,14 @@ static void bta_jv_start_discovery_cback(tSDP_RESULT result, - if (result == SDP_SUCCESS || result == SDP_DB_FULL) { - tSDP_DISC_REC* p_sdp_rec = NULL; - tSDP_PROTOCOL_ELEM pe; -+ memset(&pe, 0, sizeof(tSDP_PROTOCOL_ELEM)); - VLOG(2) << __func__ << ": bta_jv_cb.uuid=" << bta_jv_cb.uuid; - p_sdp_rec = SDP_FindServiceUUIDInDb(p_bta_jv_cfg->p_sdp_db, - bta_jv_cb.uuid, p_sdp_rec); - VLOG(2) << __func__ << ": p_sdp_rec=" << p_sdp_rec; - if (p_sdp_rec && -- SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) { -+ (SDP_FindProtocolListElemInRec(p_sdp_rec, UUID_PROTOCOL_RFCOMM, &pe)) -+ && (pe.num_params != 0)) { - dcomp.scn = (uint8_t)pe.params[0]; - status = BTA_JV_SUCCESS; - } --- -2.17.1 - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0003-Fix-an-OOB-bug-in-btif_to_bta_response-and-attp_build_value_cmd.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0003-Fix-an-OOB-bug-in-btif_to_bta_response-and-attp_build_value_cmd.bulletin.patch deleted file mode 100644 index db887cbbca..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0003-Fix-an-OOB-bug-in-btif_to_bta_response-and-attp_build_value_cmd.bulletin.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 57b823f4f758e2ef530909da07552b5aa80c6a7d Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Sat, 29 Apr 2023 18:04:37 +0000 -Subject: [PATCH] Fix an OOB bug in btif_to_bta_response and - attp_build_value_cmd - -1. The size of `p_src->attr_value.value` is dependent on - `p_src->attr_value.len`. While copying `p_src->attr_value.value`, - to `p_dest->attr_value.value`, it always copies GATT_MAX_ATTR_LEN - bytes, it may result in OOB read in `p_src->attr_value.value`; - -2. As the `p_dest->attr_value.len` does not map the length of - `p_dest->attr_value.value`, it may result in OOB read in - attp_build_value_cmd; - -Bug: 276898739 -Test: manual -Tag: #security -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:59c9e84bd31d4935a875d588bf4d2cc5bfb07d59) -Merged-In: Iefa66f3a293ac2072ba79853a9ec23cdfe4c1368 -Change-Id: Iefa66f3a293ac2072ba79853a9ec23cdfe4c1368 ---- - system/btif/src/btif_gatt_util.cc | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/system/btif/src/btif_gatt_util.cc b/system/btif/src/btif_gatt_util.cc -index 26dd79049d..db4d045087 100644 ---- a/system/btif/src/btif_gatt_util.cc -+++ b/system/btif/src/btif_gatt_util.cc -@@ -18,6 +18,8 @@ - - #define LOG_TAG "bt_btif_gatt" - -+#include -+ - #include "btif_gatt_util.h" - - #include -@@ -52,9 +54,9 @@ using bluetooth::Uuid; - void btif_to_bta_response(tGATTS_RSP* p_dest, btgatt_response_t* p_src) { - p_dest->attr_value.auth_req = p_src->attr_value.auth_req; - p_dest->attr_value.handle = p_src->attr_value.handle; -- p_dest->attr_value.len = p_src->attr_value.len; -+ p_dest->attr_value.len = std::min(p_src->attr_value.len, GATT_MAX_ATTR_LEN); - p_dest->attr_value.offset = p_src->attr_value.offset; -- memcpy(p_dest->attr_value.value, p_src->attr_value.value, GATT_MAX_ATTR_LEN); -+ memcpy(p_dest->attr_value.value, p_src->attr_value.value, p_dest->attr_value.len); - } - - /******************************************************************************* --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0004-Fix-an-OOB-write-bug-in-attp_build_read_by_type_value_cmd.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0004-Fix-an-OOB-write-bug-in-attp_build_read_by_type_value_cmd.bulletin.patch deleted file mode 100644 index 67de0037b6..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0004-Fix-an-OOB-write-bug-in-attp_build_read_by_type_value_cmd.bulletin.patch +++ /dev/null @@ -1,38 +0,0 @@ -From de53890aaca2ae08b3ee2d6e3fd25f702fdfa661 Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Tue, 17 Oct 2023 00:39:31 +0000 -Subject: [PATCH] Fix an OOB write bug in attp_build_read_by_type_value_cmd - -Bug: 297524203 -Test: m com.android.btservices -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:140c41e3553bc59fe97e3f5ee96c64e2251971e2) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e9b40c3dfd81c3fa99b3f115135de7e2c356ece9) -Merged-In: I2a95bbcce9a16ac84dd714eb4561428711a9872e -Change-Id: I2a95bbcce9a16ac84dd714eb4561428711a9872e ---- - system/stack/gatt/att_protocol.cc | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc -index 01dc10516c..da3cf51e0e 100644 ---- a/system/stack/gatt/att_protocol.cc -+++ b/system/stack/gatt/att_protocol.cc -@@ -165,7 +165,13 @@ static BT_HDR* attp_build_read_by_type_value_cmd( - uint16_t payload_size, tGATT_FIND_TYPE_VALUE* p_value_type) { - uint8_t* p; - uint16_t len = p_value_type->value_len; -- BT_HDR* p_buf = -+ BT_HDR* p_buf = nullptr; -+ -+ if (payload_size < 5) { -+ return nullptr; -+ } -+ -+ p_buf = - (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET); - - p = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0005-Fix-an-OOB-bug-in-smp_proc_sec_req.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0005-Fix-an-OOB-bug-in-smp_proc_sec_req.bulletin.patch deleted file mode 100644 index 83af1e82e6..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0005-Fix-an-OOB-bug-in-smp_proc_sec_req.bulletin.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 16c3f8dc40b2f8fded9c51e4beb759ee8170a353 Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Fri, 20 Oct 2023 00:11:24 +0000 -Subject: [PATCH] Fix an OOB bug in smp_proc_sec_req - -Bug: 300903400 -Test: m com.android.btservices -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:f20a759c149b739f8dfc3790287ad1b954115c18) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a4704e7519d0a02c1caf8b4d8ed874bc201a4b91) -Merged-In: I400cfa3523c6d8b25c233205748c2db5dc803d1d -Change-Id: I400cfa3523c6d8b25c233205748c2db5dc803d1d ---- - system/stack/smp/smp_act.cc | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc -index 5748169072..b45447849e 100644 ---- a/system/stack/smp/smp_act.cc -+++ b/system/stack/smp/smp_act.cc -@@ -460,6 +460,13 @@ void smp_send_ltk_reply(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - * Description process security request. - ******************************************************************************/ - void smp_proc_sec_req(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { -+ if (smp_command_has_invalid_length(p_cb)) { -+ tSMP_INT_DATA smp_int_data; -+ smp_int_data.status = SMP_INVALID_PARAMETERS; -+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); -+ return; -+ } -+ - tBTM_LE_AUTH_REQ auth_req = *(tBTM_LE_AUTH_REQ*)p_data->p_data; - tBTM_BLE_SEC_REQ_ACT sec_req_act; - --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0006-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0006-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch deleted file mode 100644 index fa736890ee..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0006-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch +++ /dev/null @@ -1,114 +0,0 @@ -From bd2d00da33f0de28768b9dcd79c334088316604d Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Tue, 29 Aug 2023 12:05:45 -0700 -Subject: [PATCH] Fix an OOB write bug in attp_build_value_cmd - -Bug: 295887535 -Test: m com.android.btservices -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:b927f3fb660dafaf97b2fa0398353a8c39125efc) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a0d4425c3964f99f589d449deed2f1bbe520218c) -Merged-In: Ie16251c3a2b7c0f807ecb53bbf125d1e8c276e48 -Change-Id: Ie16251c3a2b7c0f807ecb53bbf125d1e8c276e48 ---- - system/stack/gatt/att_protocol.cc | 55 ++++++++++++++++++++++++------- - 1 file changed, 44 insertions(+), 11 deletions(-) - -diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc -index da3cf51e0e..9da7d6ffe1 100644 ---- a/system/stack/gatt/att_protocol.cc -+++ b/system/stack/gatt/att_protocol.cc -@@ -287,46 +287,79 @@ static BT_HDR* attp_build_opcode_cmd(uint8_t op_code) { - static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, - uint16_t handle, uint16_t offset, - uint16_t len, uint8_t* p_data) { -- uint8_t *p, *pp, pair_len, *p_pair_len; -+ uint8_t *p, *pp, *p_pair_len; -+ size_t pair_len; -+ size_t size_now = 1; -+ -+ #define CHECK_SIZE() do { \ -+ if (size_now > payload_size) { \ -+ LOG(ERROR) << "payload size too small"; \ -+ osi_free(p_buf); \ -+ return nullptr; \ -+ } \ -+ } while (false) -+ - BT_HDR* p_buf = - (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET); - - p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; -+ -+ CHECK_SIZE(); - UINT8_TO_STREAM(p, op_code); - p_buf->offset = L2CAP_MIN_OFFSET; -- p_buf->len = 1; - - if (op_code == GATT_RSP_READ_BY_TYPE) { - p_pair_len = p; - pair_len = len + 2; -- UINT8_TO_STREAM(p, pair_len); -- p_buf->len += 1; -+ size_now += 1; -+ CHECK_SIZE(); -+ // this field will be backfilled in the end of this function - } -+ - if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) { -+ size_now += 2; -+ CHECK_SIZE(); - UINT16_TO_STREAM(p, handle); -- p_buf->len += 2; - } - - if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) { -+ size_now += 2; -+ CHECK_SIZE(); - UINT16_TO_STREAM(p, offset); -- p_buf->len += 2; - } - -- if (len > 0 && p_data != NULL) { -+ if (len > 0 && p_data != NULL && payload_size > size_now) { - /* ensure data not exceed MTU size */ -- if (payload_size - p_buf->len < len) { -- len = payload_size - p_buf->len; -+ if (payload_size - size_now < len) { -+ len = payload_size - size_now; - /* update handle value pair length */ -- if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2); -+ if (op_code == GATT_RSP_READ_BY_TYPE) { -+ pair_len = (len + 2); -+ } - - LOG(WARNING) << StringPrintf( - "attribute value too long, to be truncated to %d", len); - } - -+ size_now += len; -+ CHECK_SIZE(); - ARRAY_TO_STREAM(p, p_data, len); -- p_buf->len += len; - } - -+ // backfill pair len field -+ if (op_code == GATT_RSP_READ_BY_TYPE) { -+ if (pair_len > UINT8_MAX) { -+ LOG(ERROR) << "pair_len greater than" << UINT8_MAX; -+ osi_free(p_buf); -+ return nullptr; -+ } -+ -+ *p_pair_len = (uint8_t) pair_len; -+ } -+ -+ #undef CHECK_SIZE -+ -+ p_buf->len = (uint16_t) size_now; - return p_buf; - } - --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0007-Revert-Fix-an-OOB-write-bug-in-attp_build_value_cmd-.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0007-Revert-Fix-an-OOB-write-bug-in-attp_build_value_cmd-.bulletin.patch deleted file mode 100644 index d764d25621..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0007-Revert-Fix-an-OOB-write-bug-in-attp_build_value_cmd-.bulletin.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 354b019bbbe8bcdf356b08631cc7720540cb758e Mon Sep 17 00:00:00 2001 -From: Mehmet Murat Sevim -Date: Wed, 6 Dec 2023 14:54:05 +0000 -Subject: [PATCH] Revert "Fix an OOB write bug in attp_build_value_cmd" - -This reverts commit a0d4425c3964f99f589d449deed2f1bbe520218c. - -Reason for revert: LE Device name is incorrect after the change. See b/315127634 -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6dbe94fe556ef67f3bbb7d7bb2da3320d68619df) -Merged-In: I93906e7ab768b4015fe3491e171fdb0ec8cf3077 -Change-Id: I93906e7ab768b4015fe3491e171fdb0ec8cf3077 ---- - system/stack/gatt/att_protocol.cc | 55 +++++++------------------------ - 1 file changed, 11 insertions(+), 44 deletions(-) - -diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc -index 9da7d6ffe1..da3cf51e0e 100644 ---- a/system/stack/gatt/att_protocol.cc -+++ b/system/stack/gatt/att_protocol.cc -@@ -287,79 +287,46 @@ static BT_HDR* attp_build_opcode_cmd(uint8_t op_code) { - static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, - uint16_t handle, uint16_t offset, - uint16_t len, uint8_t* p_data) { -- uint8_t *p, *pp, *p_pair_len; -- size_t pair_len; -- size_t size_now = 1; -- -- #define CHECK_SIZE() do { \ -- if (size_now > payload_size) { \ -- LOG(ERROR) << "payload size too small"; \ -- osi_free(p_buf); \ -- return nullptr; \ -- } \ -- } while (false) -- -+ uint8_t *p, *pp, pair_len, *p_pair_len; - BT_HDR* p_buf = - (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET); - - p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; -- -- CHECK_SIZE(); - UINT8_TO_STREAM(p, op_code); - p_buf->offset = L2CAP_MIN_OFFSET; -+ p_buf->len = 1; - - if (op_code == GATT_RSP_READ_BY_TYPE) { - p_pair_len = p; - pair_len = len + 2; -- size_now += 1; -- CHECK_SIZE(); -- // this field will be backfilled in the end of this function -+ UINT8_TO_STREAM(p, pair_len); -+ p_buf->len += 1; - } -- - if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) { -- size_now += 2; -- CHECK_SIZE(); - UINT16_TO_STREAM(p, handle); -+ p_buf->len += 2; - } - - if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) { -- size_now += 2; -- CHECK_SIZE(); - UINT16_TO_STREAM(p, offset); -+ p_buf->len += 2; - } - -- if (len > 0 && p_data != NULL && payload_size > size_now) { -+ if (len > 0 && p_data != NULL) { - /* ensure data not exceed MTU size */ -- if (payload_size - size_now < len) { -- len = payload_size - size_now; -+ if (payload_size - p_buf->len < len) { -+ len = payload_size - p_buf->len; - /* update handle value pair length */ -- if (op_code == GATT_RSP_READ_BY_TYPE) { -- pair_len = (len + 2); -- } -+ if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2); - - LOG(WARNING) << StringPrintf( - "attribute value too long, to be truncated to %d", len); - } - -- size_now += len; -- CHECK_SIZE(); - ARRAY_TO_STREAM(p, p_data, len); -+ p_buf->len += len; - } - -- // backfill pair len field -- if (op_code == GATT_RSP_READ_BY_TYPE) { -- if (pair_len > UINT8_MAX) { -- LOG(ERROR) << "pair_len greater than" << UINT8_MAX; -- osi_free(p_buf); -- return nullptr; -- } -- -- *p_pair_len = (uint8_t) pair_len; -- } -- -- #undef CHECK_SIZE -- -- p_buf->len = (uint16_t) size_now; - return p_buf; - } - --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0008-Reland-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0008-Reland-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch deleted file mode 100644 index d19952b2c4..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0008-Reland-Fix-an-OOB-write-bug-in-attp_build_value_cmd.bulletin.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 06f9a5f1526b576503b92994e6e02746bddb95d0 Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Tue, 29 Aug 2023 12:05:45 -0700 -Subject: [PATCH] Reland: Fix an OOB write bug in attp_build_value_cmd - -Bug: 295887535 -Bug: 315127634 -Test: m com.android.btservices -Test: atest net_test_stack_gatt -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4ae5e736813bf2928bfc8c71e3dacf3b78394046) -Merged-In: I291fd665a68d90813b8c21c80d23cc438f84f285 -Change-Id: I291fd665a68d90813b8c21c80d23cc438f84f285 ---- - system/stack/gatt/att_protocol.cc | 56 +++++++++++++++++++++++++------ - 1 file changed, 45 insertions(+), 11 deletions(-) - -diff --git a/system/stack/gatt/att_protocol.cc b/system/stack/gatt/att_protocol.cc -index da3cf51e0e..1c3fc0fa40 100644 ---- a/system/stack/gatt/att_protocol.cc -+++ b/system/stack/gatt/att_protocol.cc -@@ -287,46 +287,80 @@ static BT_HDR* attp_build_opcode_cmd(uint8_t op_code) { - static BT_HDR* attp_build_value_cmd(uint16_t payload_size, uint8_t op_code, - uint16_t handle, uint16_t offset, - uint16_t len, uint8_t* p_data) { -- uint8_t *p, *pp, pair_len, *p_pair_len; -+ uint8_t *p, *pp, *p_pair_len; -+ size_t pair_len; -+ size_t size_now = 1; -+ -+#define CHECK_SIZE() \ -+ do { \ -+ if (size_now > payload_size) { \ -+ LOG_ERROR("payload size too small"); \ -+ osi_free(p_buf); \ -+ return nullptr; \ -+ } \ -+ } while (false) -+ - BT_HDR* p_buf = - (BT_HDR*)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET); - - p = pp = (uint8_t*)(p_buf + 1) + L2CAP_MIN_OFFSET; -+ -+ CHECK_SIZE(); - UINT8_TO_STREAM(p, op_code); - p_buf->offset = L2CAP_MIN_OFFSET; -- p_buf->len = 1; - - if (op_code == GATT_RSP_READ_BY_TYPE) { -- p_pair_len = p; -+ p_pair_len = p++; - pair_len = len + 2; -- UINT8_TO_STREAM(p, pair_len); -- p_buf->len += 1; -+ size_now += 1; -+ CHECK_SIZE(); -+ // this field will be backfilled in the end of this function - } -+ - if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ) { -+ size_now += 2; -+ CHECK_SIZE(); - UINT16_TO_STREAM(p, handle); -- p_buf->len += 2; - } - - if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) { -+ size_now += 2; -+ CHECK_SIZE(); - UINT16_TO_STREAM(p, offset); -- p_buf->len += 2; - } - - if (len > 0 && p_data != NULL) { - /* ensure data not exceed MTU size */ -- if (payload_size - p_buf->len < len) { -- len = payload_size - p_buf->len; -+ if (payload_size - size_now < len) { -+ len = payload_size - size_now; - /* update handle value pair length */ -- if (op_code == GATT_RSP_READ_BY_TYPE) *p_pair_len = (len + 2); -+ if (op_code == GATT_RSP_READ_BY_TYPE) { -+ pair_len = (len + 2); -+ } - - LOG(WARNING) << StringPrintf( - "attribute value too long, to be truncated to %d", len); - } - -+ size_now += len; -+ CHECK_SIZE(); - ARRAY_TO_STREAM(p, p_data, len); -- p_buf->len += len; - } - -+ // backfill pair len field -+ if (op_code == GATT_RSP_READ_BY_TYPE) { -+ if (pair_len > UINT8_MAX) { -+ LOG_ERROR("pair_len greater than %d", UINT8_MAX); -+ osi_free(p_buf); -+ return nullptr; -+ } -+ -+ *p_pair_len = (uint8_t)pair_len; -+ } -+ -+#undef CHECK_SIZE -+ -+ p_buf->len = (uint16_t)size_now; - return p_buf; - } - --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0009-Fix-a-security-bypass-issue-in-access_secure_service_from_temp_b.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0009-Fix-a-security-bypass-issue-in-access_secure_service_from_temp_b.bulletin.patch deleted file mode 100644 index 9ff4149f73..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0009-Fix-a-security-bypass-issue-in-access_secure_service_from_temp_b.bulletin.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 618374db66c05c67a9c31eeb43cdf9205549fff0 Mon Sep 17 00:00:00 2001 -From: Hui Peng -Date: Thu, 4 Jan 2024 06:27:52 +0000 -Subject: [PATCH] Fix a security bypass issue in - access_secure_service_from_temp_bond - -Bug: 318374503 -Test: m com.android.btservices | manual test against PoC | QA -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:62944f39f502b28687a5142ec2d77585525591bc) -Merged-In: I48df2c2d77810077e97d4131540277273d441998 -Change-Id: I48df2c2d77810077e97d4131540277273d441998 ---- - system/stack/btm/btm_sec.cc | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/system/stack/btm/btm_sec.cc b/system/stack/btm/btm_sec.cc -index c07875a8eb..9a363568f9 100644 ---- a/system/stack/btm/btm_sec.cc -+++ b/system/stack/btm/btm_sec.cc -@@ -245,8 +245,7 @@ static bool access_secure_service_from_temp_bond(const tBTM_SEC_DEV_REC* p_dev_r - bool locally_initiated, - uint16_t security_req) { - return !locally_initiated && (security_req & BTM_SEC_IN_AUTHENTICATE) && -- p_dev_rec->is_device_authenticated() && -- p_dev_rec->is_bond_type_temporary(); -+ p_dev_rec->is_bond_type_temporary(); - } - - /******************************************************************************* --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0010-Fix-an-authentication-bypass-bug-in-SMP.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0010-Fix-an-authentication-bypass-bug-in-SMP.bulletin.patch deleted file mode 100644 index ec1bccd849..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0010-Fix-an-authentication-bypass-bug-in-SMP.bulletin.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 317b4e293cefe18fe8c58c1de0c4a6741bd05629 Mon Sep 17 00:00:00 2001 -From: Brian Delwiche -Date: Mon, 22 Apr 2024 21:10:09 +0000 -Subject: [PATCH] Fix an authentication bypass bug in SMP - -When pairing with BLE legacy pairing initiated -from remote, authentication can be bypassed. -This change fixes it. - -Bug: 251514170 -Test: m com.android.btservices -Test: manual run against PoC -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:25a3fcd487c799d5d9029b8646159a0b10143d97) -Merged-In: I369a8fdd675eca731a7a488ed6a2be645058b795 -Change-Id: I369a8fdd675eca731a7a488ed6a2be645058b795 ---- - system/stack/smp/smp_act.cc | 12 ++++++++++++ - system/stack/smp/smp_int.h | 1 + - 2 files changed, 13 insertions(+) - -diff --git a/system/stack/smp/smp_act.cc b/system/stack/smp/smp_act.cc -index b45447849e..a5b1581070 100644 ---- a/system/stack/smp/smp_act.cc -+++ b/system/stack/smp/smp_act.cc -@@ -315,6 +315,7 @@ void smp_send_pair_rsp(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - void smp_send_confirm(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - SMP_TRACE_DEBUG("%s", __func__); - smp_send_cmd(SMP_OPCODE_CONFIRM, p_cb); -+ p_cb->flags |= SMP_PAIR_FLAGS_CMD_CONFIRM_SENT; - } - - /******************************************************************************* -@@ -689,6 +690,17 @@ void smp_proc_init(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) { - return; - } - -+ if (!((p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) && -+ (p_cb->peer_auth_req & SMP_SC_SUPPORT_BIT)) && -+ !(p_cb->flags & SMP_PAIR_FLAGS_CMD_CONFIRM_SENT)) { -+ // in legacy pairing, the peer should send its rand after -+ // we send our confirm -+ tSMP_INT_DATA smp_int_data{}; -+ smp_int_data.status = SMP_INVALID_PARAMETERS; -+ smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &smp_int_data); -+ return; -+ } -+ - /* save the SRand for comparison */ - STREAM_TO_ARRAY(p_cb->rrand.data(), p, OCTET16_LEN); - } -diff --git a/system/stack/smp/smp_int.h b/system/stack/smp/smp_int.h -index 1cf316ef30..59c3a09b21 100644 ---- a/system/stack/smp/smp_int.h -+++ b/system/stack/smp/smp_int.h -@@ -222,6 +222,7 @@ typedef union { - (1 << 7) /* used to resolve race condition */ - #define SMP_PAIR_FLAG_HAVE_LOCAL_PUBL_KEY \ - (1 << 8) /* used on peripheral to resolve race condition */ -+#define SMP_PAIR_FLAGS_CMD_CONFIRM_SENT (1 << 9) - - /* check if authentication requirement need MITM protection */ - #define SMP_NO_MITM_REQUIRED(x) (((x)&SMP_AUTH_YN_BIT) == 0) --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/packages/modules/Bluetooth/0011-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch b/aosp_diff/preliminary/packages/modules/Bluetooth/0011-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch deleted file mode 100644 index d66f2c754d..0000000000 --- a/aosp_diff/preliminary/packages/modules/Bluetooth/0011-Fix-heap-buffer-overflow-in-sdp_utils-cc.bulletin.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 6afad4b377b5bc3f38b28296e746b674173f99d8 Mon Sep 17 00:00:00 2001 -From: Brian Delwiche -Date: Mon, 22 Apr 2024 17:21:30 +0000 -Subject: [PATCH] Fix heap-buffer overflow in sdp_utils.cc - -Fuzzer identifies a case where sdpu_compare_uuid_with_attr crashes with -an out of bounds comparison. Although the bug claims this is due to a -comparison of a uuid with a smaller data field thana the discovery -attribute, my research suggests that this instead stems from a -comparison of a 128 bit UUID with a discovery attribute of some other, -invalid size. - -Add checks for discovery attribute size. - -Bug: 287184435 -Test: atest bluetooth_test_gd_unit, net_test_stack_sdp -Tag: #security -Ignore-AOSP-First: Security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7bbdb139bf91dca86c72c33a74c0e3407938c487) -Merged-In: I8e16ae525815bcdd47a2379ee8e5a6de47a3ac43 -Change-Id: I8e16ae525815bcdd47a2379ee8e5a6de47a3ac43 ---- - system/stack/sdp/sdp_utils.cc | 24 ++++++++++++++++++++++-- - 1 file changed, 22 insertions(+), 2 deletions(-) - -diff --git a/system/stack/sdp/sdp_utils.cc b/system/stack/sdp/sdp_utils.cc -index 0523aa07a7..b3dbe6c79a 100644 ---- a/system/stack/sdp/sdp_utils.cc -+++ b/system/stack/sdp/sdp_utils.cc -@@ -1122,8 +1122,28 @@ bool sdpu_compare_uuid_arrays(const uint8_t* p_uuid1, uint32_t len1, - ******************************************************************************/ - bool sdpu_compare_uuid_with_attr(const Uuid& uuid, tSDP_DISC_ATTR* p_attr) { - int len = uuid.GetShortestRepresentationSize(); -- if (len == 2) return uuid.As16Bit() == p_attr->attr_value.v.u16; -- if (len == 4) return uuid.As32Bit() == p_attr->attr_value.v.u32; -+ if (len == 2) { -+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes16) { -+ return uuid.As16Bit() == p_attr->attr_value.v.u16; -+ } else { -+ LOG(ERROR) << "invalid length for discovery attribute"; -+ return (false); -+ } -+ } -+ if (len == 4) { -+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == Uuid::kNumBytes32) { -+ return uuid.As32Bit() == p_attr->attr_value.v.u32; -+ } else { -+ LOG(ERROR) << "invalid length for discovery attribute"; -+ return (false); -+ } -+ } -+ -+ if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) != Uuid::kNumBytes128) { -+ LOG(ERROR) << "invalid length for discovery attribute"; -+ return (false); -+ } -+ - if (memcmp(uuid.To128BitBE().data(), (void*)p_attr->attr_value.v.array, - Uuid::kNumBytes128) == 0) - return (true); --- -2.45.2.505.gda0bf45e8d-goog - diff --git a/aosp_diff/preliminary/packages/modules/HealthFitness/0001-Exclude-exercise-routes-from-ExerciseSessionRecord-changelogs-.bulletin.patch b/aosp_diff/preliminary/packages/modules/HealthFitness/0001-Exclude-exercise-routes-from-ExerciseSessionRecord-changelogs-.bulletin.patch deleted file mode 100644 index d11fca0240..0000000000 --- a/aosp_diff/preliminary/packages/modules/HealthFitness/0001-Exclude-exercise-routes-from-ExerciseSessionRecord-changelogs-.bulletin.patch +++ /dev/null @@ -1,807 +0,0 @@ -From 178f4824574fdf33ed4ac584d092240d1c771b04 Mon Sep 17 00:00:00 2001 -From: Roman Didukh -Date: Mon, 9 Oct 2023 18:39:54 +0000 -Subject: [PATCH] Exclude exercise routes from ExerciseSessionRecord - changelogs. - -Routes are directly accessible from changelogs only by - - the app which wrote the route. - - apps which hold READ_EXERCISE_ROUTE signature permission. - -Bug: 303664370, 303871379 -Test: Added unit and CTS tests. Tested manually. -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:69c320af3eff7e5b094c235a49e98d0e64fc26a3) -Merged-In: I5ab3835a2ff451ef4ed18863858bb86af6a455c8 -Change-Id: I5ab3835a2ff451ef4ed18863858bb86af6a455c8 ---- - .../recentaccess/RecentAccessViewModelTest.kt | 2 +- - .../datatypes/ExerciseSessionRecord.java | 1 + - .../HealthConnectServiceImpl.java | 42 +-- - .../permission/DataPermissionEnforcer.java | 25 +- - .../datatypehelpers/AppInfoHelper.java | 5 + - .../ExerciseSessionRecordHelper.java | 66 +++-- - .../storage/datatypehelpers/RecordHelper.java | 21 +- - .../request/ReadTransactionRequest.java | 15 +- - .../testhelper/HealthConnectUiTestHelper.kt | 1 + - .../cts/device/ExerciseRouteAccessTest.java | 265 +++++++++++++++++- - .../healthconnect/cts/lib/TestUtils.java | 5 +- - 11 files changed, 381 insertions(+), 67 deletions(-) - -diff --git a/apk/tests/src/com/android/healthconnect/controller/tests/recentaccess/RecentAccessViewModelTest.kt b/apk/tests/src/com/android/healthconnect/controller/tests/recentaccess/RecentAccessViewModelTest.kt -index c7f7107a..46f02003 100644 ---- a/apk/tests/src/com/android/healthconnect/controller/tests/recentaccess/RecentAccessViewModelTest.kt -+++ b/apk/tests/src/com/android/healthconnect/controller/tests/recentaccess/RecentAccessViewModelTest.kt -@@ -419,7 +419,7 @@ class RecentAccessViewModelTest { - - fakeRecentAccessUseCase.updateList(accessLogs) - viewModel.loadRecentAccessApps(timeSource = timeSource) -- val actual = viewModel.recentAccessApps.getOrAwaitValue(time = 5, callsCount = 2) -+ val actual = viewModel.recentAccessApps.getOrAwaitValue(callsCount = 2) - val expected = - listOf( - RecentAccessEntry( -diff --git a/framework/java/android/health/connect/datatypes/ExerciseSessionRecord.java b/framework/java/android/health/connect/datatypes/ExerciseSessionRecord.java -index eaceb07f..9975479f 100644 ---- a/framework/java/android/health/connect/datatypes/ExerciseSessionRecord.java -+++ b/framework/java/android/health/connect/datatypes/ExerciseSessionRecord.java -@@ -409,6 +409,7 @@ public final class ExerciseSessionRecord extends IntervalRecord { - recordInternal.setTitle(getTitle().toString()); - } - -+ recordInternal.setHasRoute(hasRoute()); - if (getRoute() != null) { - recordInternal.setRoute(getRoute().toRouteInternal()); - } -diff --git a/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java b/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -index 3075d155..578db339 100644 ---- a/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -+++ b/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -@@ -157,6 +157,7 @@ import java.util.Map; - import java.util.Map.Entry; - import java.util.Objects; - import java.util.Set; -+import java.util.UUID; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.stream.Collectors; - -@@ -540,7 +541,7 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - Collections.unmodifiableMap( - mDataPermissionEnforcer - .collectExtraReadPermissionToStateMapping( -- request.getRecordType(), -+ Set.of(request.getRecordType()), - attributionSource)); - - Trace.traceBegin(TRACE_TAG_READ, TAG_READ); -@@ -846,9 +847,10 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - IChangeLogsResponseCallback callback) { - final int uid = Binder.getCallingUid(); - final UserHandle userHandle = Binder.getCallingUserHandle(); -+ final String callerPackageName = Objects.requireNonNull(attributionSource.getPackageName()); - final HealthConnectServiceLogger.Builder builder = - new HealthConnectServiceLogger.Builder(false, GET_CHANGES) -- .setPackageName(attributionSource.getPackageName()); -+ .setPackageName(callerPackageName); - - HealthConnectThreadScheduler.schedule( - mContext, -@@ -881,12 +883,22 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - ChangeLogsHelper.getInstance() - .getChangeLogs(changeLogsTokenRequest, token); - -+ Map> recordTypeToInsertedUuids = -+ ChangeLogsHelper.getRecordTypeToInsertedUuids( -+ changeLogsResponse.getChangeLogsMap()); -+ -+ Map extraReadPermsToGrantState = -+ mDataPermissionEnforcer.collectExtraReadPermissionToStateMapping( -+ recordTypeToInsertedUuids.keySet(), attributionSource); -+ - List> recordInternals = - mTransactionManager.readRecords( - new ReadTransactionRequest( -- ChangeLogsHelper.getRecordTypeToInsertedUuids( -- changeLogsResponse.getChangeLogsMap()), -- startDateAccess)); -+ callerPackageName, -+ recordTypeToInsertedUuids, -+ startDateAccess, -+ extraReadPermsToGrantState)); -+ - List deletedLogs = - ChangeLogsHelper.getDeletedLogs( - changeLogsResponse.getChangeLogsMap()); -@@ -1629,14 +1641,11 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - } catch (SecurityException | IllegalStateException e) { - Log.e(TAG, "Exception encountered while staging", e); - try { -- @HealthConnectException.ErrorCode int errorCode = -- (e instanceof SecurityException) ? ERROR_SECURITY : ERROR_INTERNAL; -- exceptionsByFileName.put("", new HealthConnectException( -- errorCode, -- e.getMessage())); -+ @HealthConnectException.ErrorCode -+ int errorCode = (e instanceof SecurityException) ? ERROR_SECURITY : ERROR_INTERNAL; -+ exceptionsByFileName.put("", new HealthConnectException(errorCode, e.getMessage())); - -- callback.onError( -- new StageRemoteDataException(exceptionsByFileName)); -+ callback.onError(new StageRemoteDataException(exceptionsByFileName)); - } catch (RemoteException remoteException) { - Log.e(TAG, "Restore permission response could not be sent to the caller.", e); - } -@@ -1744,15 +1753,12 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - }); - } catch (SecurityException | IllegalStateException e) { - Log.e(TAG, "getHealthConnectDataState: Exception encountered", e); -- @HealthConnectException.ErrorCode int errorCode = -- (e instanceof SecurityException) ? ERROR_SECURITY -- : ERROR_INTERNAL; -+ @HealthConnectException.ErrorCode -+ int errorCode = (e instanceof SecurityException) ? ERROR_SECURITY : ERROR_INTERNAL; - try { - callback.onError( - new HealthConnectExceptionParcel( -- new HealthConnectException( -- errorCode, -- e.getMessage()))); -+ new HealthConnectException(errorCode, e.getMessage()))); - } catch (RemoteException remoteException) { - Log.e(TAG, "getHealthConnectDataState error could not be sent", e); - } -diff --git a/service/java/com/android/server/healthconnect/permission/DataPermissionEnforcer.java b/service/java/com/android/server/healthconnect/permission/DataPermissionEnforcer.java -index 2ea5c2cd..82b8c861 100644 ---- a/service/java/com/android/server/healthconnect/permission/DataPermissionEnforcer.java -+++ b/service/java/com/android/server/healthconnect/permission/DataPermissionEnforcer.java -@@ -18,6 +18,8 @@ package com.android.server.healthconnect.permission; - - import static android.content.pm.PackageManager.PERMISSION_GRANTED; - -+import static java.util.stream.Collectors.toMap; -+ - import android.annotation.NonNull; - import android.content.AttributionSource; - import android.content.Context; -@@ -36,6 +38,7 @@ import java.util.Collections; - import java.util.List; - import java.util.Map; - import java.util.Set; -+import java.util.function.Function; - - /** - * Helper class to force caller of data apis to hold api required permissions. -@@ -150,18 +153,16 @@ public class DataPermissionEnforcer { - * doesn't have corresponding permission. - */ - public Map collectExtraReadPermissionToStateMapping( -- int recordTypeId, AttributionSource attributionSource) { -- RecordHelper recordHelper = -- RecordHelperProvider.getInstance().getRecordHelper(recordTypeId); -- if (recordHelper.getExtraReadPermissions().isEmpty()) { -- return Collections.emptyMap(); -- } -- -- Map mapping = new ArrayMap<>(); -- for (String permissionName : recordHelper.getExtraReadPermissions()) { -- mapping.put(permissionName, isPermissionGranted(permissionName, attributionSource)); -- } -- return mapping; -+ Set recordTypeIds, AttributionSource attributionSource) { -+ RecordHelperProvider recordHelperProvider = RecordHelperProvider.getInstance(); -+ return recordTypeIds.stream() -+ .map(recordHelperProvider::getRecordHelper) -+ .flatMap(recordHelper -> recordHelper.getExtraReadPermissions().stream()) -+ .distinct() -+ .collect( -+ toMap( -+ Function.identity(), -+ permission -> isPermissionGranted(permission, attributionSource))); - } - - public Map collectExtraWritePermissionStateMapping( -diff --git a/service/java/com/android/server/healthconnect/storage/datatypehelpers/AppInfoHelper.java b/service/java/com/android/server/healthconnect/storage/datatypehelpers/AppInfoHelper.java -index 56bd1ae9..7dc25c1c 100644 ---- a/service/java/com/android/server/healthconnect/storage/datatypehelpers/AppInfoHelper.java -+++ b/service/java/com/android/server/healthconnect/storage/datatypehelpers/AppInfoHelper.java -@@ -100,6 +100,7 @@ public final class AppInfoHelper { - *

TO HAVE THREAD SAFETY DON'T USE THESE VARIABLES DIRECTLY, INSTEAD USE ITS GETTER - */ - private volatile ConcurrentHashMap mIdPackageNameMap; -+ - /** - * Map to store application package-name -> AppInfo mapping (such as packageName -> appName, - * icon, rowId in the DB etc.) -@@ -222,6 +223,10 @@ public final class AppInfoHelper { - * @return id of {@code packageName} or {@link Constants#DEFAULT_LONG} if the id is not found - */ - public long getAppInfoId(String packageName) { -+ if (packageName == null) { -+ return DEFAULT_LONG; -+ } -+ - AppInfoInternal appInfo = getAppInfoMap().getOrDefault(packageName, null); - - if (appInfo == null) { -diff --git a/service/java/com/android/server/healthconnect/storage/datatypehelpers/ExerciseSessionRecordHelper.java b/service/java/com/android/server/healthconnect/storage/datatypehelpers/ExerciseSessionRecordHelper.java -index 0c2516a6..eac95de6 100644 ---- a/service/java/com/android/server/healthconnect/storage/datatypehelpers/ExerciseSessionRecordHelper.java -+++ b/service/java/com/android/server/healthconnect/storage/datatypehelpers/ExerciseSessionRecordHelper.java -@@ -90,6 +90,10 @@ public final class ExerciseSessionRecordHelper - private static final String TITLE_COLUMN_NAME = "title"; - private static final String HAS_ROUTE_COLUMN_NAME = "has_route"; - -+ private static final int ROUTE_READ_ACCESS_TYPE_NONE = 0; -+ private static final int ROUTE_READ_ACCESS_TYPE_OWN = 1; -+ private static final int ROUTE_READ_ACCESS_TYPE_ALL = 2; -+ - public ExerciseSessionRecordHelper() { - super(RecordTypeIdentifier.RECORD_TYPE_EXERCISE_SESSION); - } -@@ -245,25 +249,17 @@ public final class ExerciseSessionRecordHelper - String packageName, - long startDateAccess, - Map extraPermsState) { -- if (!isExerciseRouteFeatureEnabled()) { -- return Collections.emptyList(); -- } -+ int routeAccessType = getExerciseRouteReadAccessType(packageName, extraPermsState); - -- boolean canReadAnyRoute = extraPermsState.get(READ_EXERCISE_ROUTE); -- if (!canReadAnyRoute -- && AppInfoHelper.getInstance().getAppInfoId(packageName) == DEFAULT_LONG) { -- // If the package doesn't have app info and cannot read any route, -- // then no route is accessible for it. -+ if (routeAccessType == ROUTE_READ_ACCESS_TYPE_NONE) { - return Collections.emptyList(); - } - -- WhereClauses whereClause = -- getReadTableWhereClause( -- request, -- packageName, -- /* enforceSelfRead= */ !canReadAnyRoute, -- startDateAccess); -- return List.of(getRouteReadRequest(whereClause)); -+ boolean enforceSelfRead = routeAccessType == ROUTE_READ_ACCESS_TYPE_OWN; -+ -+ WhereClauses sessionsWithAccessibleRouteClause = -+ getReadTableWhereClause(request, packageName, enforceSelfRead, startDateAccess); -+ return List.of(getRouteReadRequest(sessionsWithAccessibleRouteClause)); - } - - @Override -@@ -315,17 +311,30 @@ public final class ExerciseSessionRecordHelper - } - - @Override -- List getExtraDataReadRequests(List uuids, long startDateAccess) { -- if (!isExerciseRouteFeatureEnabled()) { -+ List getExtraDataReadRequests( -+ String packageName, -+ List uuids, -+ long startDateAccess, -+ Map extraPermsState) { -+ int routeAccessType = getExerciseRouteReadAccessType(packageName, extraPermsState); -+ -+ if (routeAccessType == ROUTE_READ_ACCESS_TYPE_NONE) { - return Collections.emptyList(); - } - -- WhereClauses whereClause = -+ WhereClauses sessionsWithAccessibleRouteClause = - new WhereClauses() - .addWhereInClauseWithoutQuotes( -- UUID_COLUMN_NAME, StorageUtils.getListOfHexString(uuids)); -- whereClause.addWhereLaterThanTimeClause(getStartTimeColumnName(), startDateAccess); -- return List.of(getRouteReadRequest(whereClause)); -+ UUID_COLUMN_NAME, StorageUtils.getListOfHexString(uuids)) -+ .addWhereLaterThanTimeClause(getStartTimeColumnName(), startDateAccess); -+ -+ if (routeAccessType == ROUTE_READ_ACCESS_TYPE_OWN) { -+ long appId = AppInfoHelper.getInstance().getAppInfoId(packageName); -+ sessionsWithAccessibleRouteClause.addWhereInLongsClause( -+ APP_INFO_ID_COLUMN_NAME, List.of(appId)); -+ } -+ -+ return List.of(getRouteReadRequest(sessionsWithAccessibleRouteClause)); - } - - @Override -@@ -408,4 +417,19 @@ public final class ExerciseSessionRecordHelper - routeReadRequest.setWhereClause(inClause); - return routeReadRequest; - } -+ -+ private int getExerciseRouteReadAccessType( -+ String packageName, Map extraPermsState) { -+ if (!isExerciseRouteFeatureEnabled()) { -+ return ROUTE_READ_ACCESS_TYPE_NONE; -+ } -+ -+ if (extraPermsState.getOrDefault(READ_EXERCISE_ROUTE, false)) { -+ return ROUTE_READ_ACCESS_TYPE_ALL; -+ } -+ -+ long appId = AppInfoHelper.getInstance().getAppInfoId(packageName); -+ -+ return appId == DEFAULT_LONG ? ROUTE_READ_ACCESS_TYPE_NONE : ROUTE_READ_ACCESS_TYPE_OWN; -+ } - } -diff --git a/service/java/com/android/server/healthconnect/storage/datatypehelpers/RecordHelper.java b/service/java/com/android/server/healthconnect/storage/datatypehelpers/RecordHelper.java -index ec9f0a30..9fba3e57 100644 ---- a/service/java/com/android/server/healthconnect/storage/datatypehelpers/RecordHelper.java -+++ b/service/java/com/android/server/healthconnect/storage/datatypehelpers/RecordHelper.java -@@ -298,10 +298,7 @@ public abstract class RecordHelper> { - } - } - -- /** -- * Returns ReadSingleTableRequest for {@code request} and package name {@code packageName} -- * -- */ -+ /** Returns ReadSingleTableRequest for {@code request} and package name {@code packageName} */ - public ReadTableRequest getReadTableRequest( - ReadRecordsRequestParcel request, - String packageName, -@@ -344,7 +341,11 @@ public abstract class RecordHelper> { - } - - /** Returns ReadTableRequest for {@code uuids} */ -- public ReadTableRequest getReadTableRequest(List uuids, long startDateAccess) { -+ public ReadTableRequest getReadTableRequest( -+ String packageName, -+ List uuids, -+ long startDateAccess, -+ Map extraPermsState) { - return new ReadTableRequest(getMainTableName()) - .setJoinClause(getJoinForReadRequest()) - .setWhereClause( -@@ -354,7 +355,9 @@ public abstract class RecordHelper> { - .addWhereLaterThanTimeClause( - getStartTimeColumnName(), startDateAccess)) - .setRecordHelper(this) -- .setExtraReadRequests(getExtraDataReadRequests(uuids, startDateAccess)); -+ .setExtraReadRequests( -+ getExtraDataReadRequests( -+ packageName, uuids, startDateAccess, extraPermsState)); - } - - /** -@@ -373,7 +376,11 @@ public abstract class RecordHelper> { - * Returns list if ReadSingleTableRequest for {@code uuids} to populate extra data. Called in - * change logs read requests. - */ -- List getExtraDataReadRequests(List uuids, long startDateAccess) { -+ List getExtraDataReadRequests( -+ String packageName, -+ List uuids, -+ long startDateAccess, -+ Map extraPermsState) { - return Collections.emptyList(); - } - -diff --git a/service/java/com/android/server/healthconnect/storage/request/ReadTransactionRequest.java b/service/java/com/android/server/healthconnect/storage/request/ReadTransactionRequest.java -index a6fb737f..e289a8e4 100644 ---- a/service/java/com/android/server/healthconnect/storage/request/ReadTransactionRequest.java -+++ b/service/java/com/android/server/healthconnect/storage/request/ReadTransactionRequest.java -@@ -45,7 +45,7 @@ public class ReadTransactionRequest { - ReadRecordsRequestParcel request, - long startDateAccess, - boolean enforceSelfRead, -- Map extraReadPermsMapping) { -+ Map extraPermsState) { - RecordHelper recordHelper = - RecordHelperProvider.getInstance().getRecordHelper(request.getRecordType()); - mReadTableRequests = -@@ -55,18 +55,25 @@ public class ReadTransactionRequest { - packageName, - enforceSelfRead, - startDateAccess, -- extraReadPermsMapping)); -+ extraPermsState)); - } - - public ReadTransactionRequest( -- Map> recordTypeToUuids, long startDateAccess) { -+ String packageName, -+ Map> recordTypeToUuids, -+ long startDateAccess, -+ Map extraPermsState) { - mReadTableRequests = new ArrayList<>(); - recordTypeToUuids.forEach( - (recordType, uuids) -> - mReadTableRequests.add( - RecordHelperProvider.getInstance() - .getRecordHelper(recordType) -- .getReadTableRequest(uuids, startDateAccess))); -+ .getReadTableRequest( -+ packageName, -+ uuids, -+ startDateAccess, -+ extraPermsState))); - } - - @NonNull -diff --git a/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectUiTestHelper.kt b/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectUiTestHelper.kt -index 3ec5ca62..bc08b2e1 100644 ---- a/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectUiTestHelper.kt -+++ b/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectUiTestHelper.kt -@@ -92,6 +92,7 @@ class HealthConnectUiTestHelper { - TestHelperUtils.getStepsRecord()), - mHealthConnectManager) - context.launchMainActivity { -+ UiTestUtils.skipOnboardingIfAppears() - UiTestUtils.waitDisplayed(By.text("Data and access")) - UiTestUtils.clickOnText("Data and access") - -diff --git a/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/ExerciseRouteAccessTest.java b/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/ExerciseRouteAccessTest.java -index ba78d087..89179e19 100644 ---- a/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/ExerciseRouteAccessTest.java -+++ b/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/ExerciseRouteAccessTest.java -@@ -18,15 +18,23 @@ package android.healthconnect.cts.device; - - import static android.health.connect.HealthPermissions.WRITE_EXERCISE_ROUTE; - import static android.healthconnect.cts.device.HealthConnectDeviceTest.APP_A_WITH_READ_WRITE_PERMS; -+import static android.healthconnect.cts.lib.TestUtils.READ_EXERCISE_ROUTE_PERMISSION; - import static android.healthconnect.cts.lib.TestUtils.READ_RECORDS_SIZE; -+import static android.healthconnect.cts.lib.TestUtils.RECORD_IDS; - import static android.healthconnect.cts.lib.TestUtils.SUCCESS; - import static android.healthconnect.cts.lib.TestUtils.deleteAllStagedRemoteData; -+import static android.healthconnect.cts.lib.TestUtils.getChangeLogToken; -+import static android.healthconnect.cts.lib.TestUtils.getChangeLogs; -+import static android.healthconnect.cts.lib.TestUtils.getExerciseSessionRecord; - import static android.healthconnect.cts.lib.TestUtils.insertRecordAs; -+import static android.healthconnect.cts.lib.TestUtils.insertRecords; - import static android.healthconnect.cts.lib.TestUtils.insertSessionNoRouteAs; - import static android.healthconnect.cts.lib.TestUtils.readRecords; - import static android.healthconnect.cts.lib.TestUtils.readRecordsAs; - import static android.healthconnect.cts.lib.TestUtils.updateRouteAs; - -+import static androidx.test.core.app.ApplicationProvider.getApplicationContext; -+ - import static com.android.compatibility.common.util.FeatureUtil.AUTOMOTIVE_FEATURE; - import static com.android.compatibility.common.util.FeatureUtil.hasSystemFeature; - -@@ -35,7 +43,12 @@ import static com.google.common.truth.Truth.assertThat; - import android.app.UiAutomation; - import android.health.connect.HealthConnectException; - import android.health.connect.ReadRecordsRequestUsingFilters; -+import android.health.connect.ReadRecordsRequestUsingIds; -+import android.health.connect.changelog.ChangeLogTokenRequest; -+import android.health.connect.changelog.ChangeLogsRequest; -+import android.health.connect.changelog.ChangeLogsResponse; - import android.health.connect.datatypes.ExerciseSessionRecord; -+import android.healthconnect.cts.lib.TestUtils.RecordTypeAndRecordIds; - import android.os.Bundle; - - import androidx.test.platform.app.InstrumentationRegistry; -@@ -47,7 +60,11 @@ import org.junit.Before; - import org.junit.Test; - - import java.util.ArrayList; -+import java.util.Collection; - import java.util.List; -+import java.util.Map; -+import java.util.function.Function; -+import java.util.stream.Collectors; - - public class ExerciseRouteAccessTest { - -@@ -63,7 +80,7 @@ public class ExerciseRouteAccessTest { - } - - @After -- public void tearDown() { -+ public void tearDown() throws InterruptedException { - deleteAllStagedRemoteData(); - - mAutomation.grantRuntimePermission( -@@ -71,7 +88,7 @@ public class ExerciseRouteAccessTest { - } - - @Test -- public void testRouteRead_cannotAccessOtherAppRoute() throws Exception { -+ public void readRecords_usingFilters_cannotAccessOtherAppRoute() throws Exception { - assertThat(insertRecordAs(APP_A_WITH_READ_WRITE_PERMS).getBoolean(SUCCESS)).isTrue(); - - List records = -@@ -85,6 +102,225 @@ public class ExerciseRouteAccessTest { - assertThat(records.get(0).getRoute()).isNull(); - } - -+ @Test -+ public void readRecords_usingFilters_withReadExerciseRoutePermission_canAccessOtherAppRoute() -+ throws Exception { -+ assertThat(insertRecordAs(APP_A_WITH_READ_WRITE_PERMS).getBoolean(SUCCESS)).isTrue(); -+ mAutomation.adoptShellPermissionIdentity(READ_EXERCISE_ROUTE_PERMISSION); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingFilters.Builder<>(ExerciseSessionRecord.class) -+ .build()); -+ -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isNotNull(); -+ } -+ -+ @Test -+ public void readRecords_usingFilters_canAccessOwnRoute() throws Exception { -+ ExerciseSessionRecord record = -+ getExerciseSessionRecord( -+ getApplicationContext().getPackageName(), 0.0, /* withRoute= */ true); -+ insertRecords(List.of(record), getApplicationContext()); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingFilters.Builder<>(ExerciseSessionRecord.class) -+ .build()); -+ -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isEqualTo(record.getRoute()); -+ } -+ -+ @Test -+ public void readRecords_usingFilters_mixedOwnAndOtherAppSession() throws Exception { -+ Bundle bundle = insertRecordAs(APP_A_WITH_READ_WRITE_PERMS); -+ assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -+ String otherAppSessionId = getInsertedSessionId(bundle); -+ ExerciseSessionRecord ownSession = -+ getExerciseSessionRecord( -+ getApplicationContext().getPackageName(), 0.0, /* withRoute= */ true); -+ String ownSessionId = -+ insertRecords(List.of(ownSession), getApplicationContext()) -+ .get(0) -+ .getMetadata() -+ .getId(); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingFilters.Builder<>(ExerciseSessionRecord.class) -+ .build()); -+ -+ Map idToRecordMap = -+ records.stream() -+ .collect( -+ Collectors.toMap( -+ record -> record.getMetadata().getId(), -+ Function.identity())); -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(2); -+ assertThat(idToRecordMap.get(otherAppSessionId).hasRoute()).isTrue(); -+ assertThat(idToRecordMap.get(otherAppSessionId).getRoute()).isNull(); -+ assertThat(idToRecordMap.get(ownSessionId).hasRoute()).isTrue(); -+ assertThat(idToRecordMap.get(ownSessionId).getRoute()).isEqualTo(ownSession.getRoute()); -+ } -+ -+ @Test -+ public void readRecords_usingIds_cannotAccessOtherAppRoute() throws Exception { -+ Bundle bundle = insertRecordAs(APP_A_WITH_READ_WRITE_PERMS); -+ assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -+ String sessionId = getInsertedSessionId(bundle); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingIds.Builder<>(ExerciseSessionRecord.class) -+ .addId(sessionId) -+ .build()); -+ -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isNull(); -+ } -+ -+ @Test -+ public void readRecords_usingIds_withReadExerciseRoutePermission_canAccessOtherAppRoute() -+ throws Exception { -+ Bundle bundle = insertRecordAs(APP_A_WITH_READ_WRITE_PERMS); -+ assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -+ String sessionId = getInsertedSessionId(bundle); -+ mAutomation.adoptShellPermissionIdentity(READ_EXERCISE_ROUTE_PERMISSION); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingIds.Builder<>(ExerciseSessionRecord.class) -+ .addId(sessionId) -+ .build()); -+ -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isNotNull(); -+ } -+ -+ @Test -+ public void readRecords_usingIds_canAccessOwnRoute() throws Exception { -+ ExerciseSessionRecord record = -+ getExerciseSessionRecord( -+ getApplicationContext().getPackageName(), 0.0, /* withRoute= */ true); -+ String sessionId = -+ insertRecords(List.of(record), getApplicationContext()) -+ .get(0) -+ .getMetadata() -+ .getId(); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingIds.Builder<>(ExerciseSessionRecord.class) -+ .addId(sessionId) -+ .build()); -+ -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isEqualTo(record.getRoute()); -+ } -+ -+ @Test -+ public void readRecords_usingIds__mixedOwnAndOtherAppSession() throws Exception { -+ Bundle bundle = insertRecordAs(APP_A_WITH_READ_WRITE_PERMS); -+ assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -+ String otherAppSessionId = getInsertedSessionId(bundle); -+ ExerciseSessionRecord ownSession = -+ getExerciseSessionRecord( -+ getApplicationContext().getPackageName(), 0.0, /* withRoute= */ true); -+ String ownSessionId = -+ insertRecords(List.of(ownSession), getApplicationContext()) -+ .get(0) -+ .getMetadata() -+ .getId(); -+ -+ List records = -+ readRecords( -+ new ReadRecordsRequestUsingIds.Builder<>(ExerciseSessionRecord.class) -+ .addId(otherAppSessionId) -+ .addId(ownSessionId) -+ .build()); -+ -+ Map idToRecordMap = -+ records.stream() -+ .collect( -+ Collectors.toMap( -+ record -> record.getMetadata().getId(), -+ Function.identity())); -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(2); -+ assertThat(idToRecordMap.get(otherAppSessionId).hasRoute()).isTrue(); -+ assertThat(idToRecordMap.get(otherAppSessionId).getRoute()).isNull(); -+ assertThat(idToRecordMap.get(ownSessionId).hasRoute()).isTrue(); -+ assertThat(idToRecordMap.get(ownSessionId).getRoute()).isEqualTo(ownSession.getRoute()); -+ } -+ -+ @Test -+ public void getChangelogs_withReadExerciseRoutePermission_canAccessOtherAppRoute() -+ throws Exception { -+ String token = -+ getChangeLogToken( -+ new ChangeLogTokenRequest.Builder() -+ .addRecordType(ExerciseSessionRecord.class) -+ .build(), -+ getApplicationContext()) -+ .getToken(); -+ assertThat(insertRecordAs(APP_A_WITH_READ_WRITE_PERMS).getBoolean(SUCCESS)).isTrue(); -+ mAutomation.adoptShellPermissionIdentity(READ_EXERCISE_ROUTE_PERMISSION); -+ -+ ChangeLogsResponse response = -+ getChangeLogs( -+ new ChangeLogsRequest.Builder(token).build(), getApplicationContext()); -+ -+ List records = -+ response.getUpsertedRecords().stream() -+ .map(ExerciseSessionRecord.class::cast) -+ .toList(); -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isNotNull(); -+ } -+ -+ @Test -+ public void getChangelogs_canAccessOwnRoute() throws Exception { -+ String token = -+ getChangeLogToken( -+ new ChangeLogTokenRequest.Builder() -+ .addRecordType(ExerciseSessionRecord.class) -+ .build(), -+ getApplicationContext()) -+ .getToken(); -+ ExerciseSessionRecord record = -+ getExerciseSessionRecord( -+ getApplicationContext().getPackageName(), 0.0, /* withRoute= */ true); -+ insertRecords(List.of(record), getApplicationContext()); -+ -+ ChangeLogsResponse response = -+ getChangeLogs( -+ new ChangeLogsRequest.Builder(token).build(), getApplicationContext()); -+ -+ List records = -+ response.getUpsertedRecords().stream() -+ .map(ExerciseSessionRecord.class::cast) -+ .toList(); -+ assertThat(records).isNotNull(); -+ assertThat(records).hasSize(1); -+ assertThat(records.get(0).hasRoute()).isTrue(); -+ assertThat(records.get(0).getRoute()).isEqualTo(record.getRoute()); -+ } -+ - @Test - public void testRouteInsert_cannotInsertRouteWithoutPerm() throws Exception { - mAutomation.revokeRuntimePermission( -@@ -103,11 +339,17 @@ public class ExerciseRouteAccessTest { - - @Test - public void testRouteUpdate_updateRouteWithPerm_noRouteAfterUpdate() throws Exception { -- assertThat(insertRecordAs(APP_A_WITH_READ_WRITE_PERMS).getBoolean(SUCCESS)).isTrue(); - List records = - readRecords( - new ReadRecordsRequestUsingFilters.Builder<>(ExerciseSessionRecord.class) - .build()); -+ assertThat(records).isEmpty(); -+ -+ assertThat(insertRecordAs(APP_A_WITH_READ_WRITE_PERMS).getBoolean(SUCCESS)).isTrue(); -+ records = -+ readRecords( -+ new ReadRecordsRequestUsingFilters.Builder<>(ExerciseSessionRecord.class) -+ .build()); - assertThat(records).isNotNull(); - assertThat(records).hasSize(1); - assertThat(records.get(0).hasRoute()).isTrue(); -@@ -181,4 +423,21 @@ public class ExerciseRouteAccessTest { - assertThat(records).hasSize(1); - assertThat(records.get(0).hasRoute()).isFalse(); - } -+ -+ private static String getInsertedSessionId(Bundle bundle) { -+ List ids = -+ ((List) bundle.getSerializable(RECORD_IDS)) -+ .stream() -+ .filter( -+ it -> -+ it.getRecordType() -+ .equals( -+ ExerciseSessionRecord.class -+ .getName())) -+ .map(RecordTypeAndRecordIds::getRecordIds) -+ .flatMap(Collection::stream) -+ .toList(); -+ assertThat(ids).hasSize(1); -+ return ids.get(0); -+ } - } -diff --git a/tests/cts/hostsidetests/healthconnect/libs/HealthConnectTestLib/src/android/healthconnect/cts/lib/TestUtils.java b/tests/cts/hostsidetests/healthconnect/libs/HealthConnectTestLib/src/android/healthconnect/cts/lib/TestUtils.java -index 557df94c..56aace8c 100644 ---- a/tests/cts/hostsidetests/healthconnect/libs/HealthConnectTestLib/src/android/healthconnect/cts/lib/TestUtils.java -+++ b/tests/cts/hostsidetests/healthconnect/libs/HealthConnectTestLib/src/android/healthconnect/cts/lib/TestUtils.java -@@ -58,6 +58,7 @@ import com.android.cts.install.lib.TestApp; - import java.io.Serializable; - import java.time.Instant; - import java.time.ZoneOffset; -+import java.time.temporal.ChronoUnit; - import java.util.ArrayList; - import java.util.Arrays; - import java.util.Collections; -@@ -72,6 +73,8 @@ import java.util.concurrent.atomic.AtomicReference; - - public class TestUtils { - static final String TAG = "HealthConnectTest"; -+ public static final String READ_EXERCISE_ROUTE_PERMISSION = -+ "android.permission.health.READ_EXERCISE_ROUTE"; - public static final String QUERY_TYPE = "android.healthconnect.cts.queryType"; - public static final String INTENT_EXTRA_CALLING_PKG = "android.healthconnect.cts.calling_pkg"; - public static final String APP_PKG_NAME_USED_IN_DATA_ORIGIN = -@@ -352,7 +355,7 @@ public class TestUtils { - - public static ExerciseSessionRecord getExerciseSessionRecord( - String packageName, double clientId, boolean withRoute) { -- Instant startTime = Instant.now().minusSeconds(3000); -+ Instant startTime = Instant.now().minusSeconds(3000).truncatedTo(ChronoUnit.MILLIS); - Instant endTime = Instant.now(); - ExerciseSessionRecord.Builder builder = - new ExerciseSessionRecord.Builder( --- -2.43.0.594.gd9cf4e227d-goog - diff --git a/aosp_diff/preliminary/packages/modules/HealthFitness/0002-Throw-exception-when-trying-to-instantiate-a-change-log-token-wi.bulletin.patch b/aosp_diff/preliminary/packages/modules/HealthFitness/0002-Throw-exception-when-trying-to-instantiate-a-change-log-token-wi.bulletin.patch deleted file mode 100644 index 0dcc1a62c9..0000000000 --- a/aosp_diff/preliminary/packages/modules/HealthFitness/0002-Throw-exception-when-trying-to-instantiate-a-change-log-token-wi.bulletin.patch +++ /dev/null @@ -1,357 +0,0 @@ -From 6e6896c3fd8139779ff8d51a99ee06667e849d87 Mon Sep 17 00:00:00 2001 -From: Pratyush More -Date: Tue, 27 Feb 2024 18:38:29 +0000 -Subject: [PATCH] Throw exception when trying to instantiate a change log token - with no record types. - -Note that this does mean that any developers that were previously -requesting change logs without specifying record types will no longer be -able to. However, the APK doesn't allow this anyway, so it is likely ok. - - -Test: atest CtsHealthFitnessDeviceTestCases:HealthConnectChangeLogsTests#testGetChangeLogToken_emptyRecordTypes_throwsException -Bug: 327332482 -(cherry picked from commit cd228a3e21c9c8df83bc3851736d6f4e19956e46) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c47251b82509773719b4b797d508b03216ab0e71) -Merged-In: I5dd49131fbe5eaa8bc138be03550f7fc739786d9 -Change-Id: I5dd49131fbe5eaa8bc138be03550f7fc739786d9 ---- - .../changelog/ChangeLogTokenRequest.java | 7 +- - .../HealthConnectServiceImpl.java | 16 +++++ - .../HealthConnectServiceLogsTests.java | 6 +- - .../cts/device/HealthConnectDeviceTest.java | 66 ------------------- - .../cts/HealthConnectChangeLogsTests.java | 34 ++++++---- - .../cts/HealthConnectManagerTest.java | 3 +- - .../android/healthconnect/cts/TestUtils.java | 8 +++ - 7 files changed, 58 insertions(+), 82 deletions(-) - -diff --git a/framework/java/android/health/connect/changelog/ChangeLogTokenRequest.java b/framework/java/android/health/connect/changelog/ChangeLogTokenRequest.java -index 28241f88..e630e3c5 100644 ---- a/framework/java/android/health/connect/changelog/ChangeLogTokenRequest.java -+++ b/framework/java/android/health/connect/changelog/ChangeLogTokenRequest.java -@@ -49,6 +49,9 @@ public final class ChangeLogTokenRequest implements Parcelable { - private ChangeLogTokenRequest( - @NonNull Set dataOriginFilters, - @NonNull Set> recordTypes) { -+ if (recordTypes.isEmpty()) { -+ throw new IllegalArgumentException("Requested record types must not be empty"); -+ } - Objects.requireNonNull(recordTypes); - Objects.requireNonNull(dataOriginFilters); - -@@ -161,8 +164,8 @@ public final class ChangeLogTokenRequest implements Parcelable { - private final Set mDataOriginFilters = new ArraySet<>(); - - /** -- * @param recordType type of record for which change log is required. If not set includes -- * all record types -+ * @param recordType type of record for which change log is required. At least one record -+ * type must be set. - */ - @NonNull - public Builder addRecordType(@NonNull Class recordType) { -diff --git a/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java b/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -index 578db339..9becd0c3 100644 ---- a/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -+++ b/service/java/com/android/server/healthconnect/HealthConnectServiceImpl.java -@@ -798,6 +798,10 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - mAppOpsManagerLocal.isUidInForeground(uid), - builder); - throwExceptionIfDataSyncInProgress(); -+ if (request.getRecordTypes().isEmpty()) { -+ throw new IllegalArgumentException( -+ "Requested record types must not be empty."); -+ } - mDataPermissionEnforcer.enforceRecordIdsReadPermissions( - request.getRecordTypesList(), attributionSource); - callback.onResult( -@@ -816,6 +820,14 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - builder.setHealthDataServiceApiStatusError(ERROR_SECURITY); - Slog.e(TAG, "SecurityException: ", securityException); - tryAndThrowException(callback, securityException, ERROR_SECURITY); -+ } catch (IllegalArgumentException illegalArgumentException) { -+ builder.setHealthDataServiceApiStatusError( -+ HealthConnectException.ERROR_INVALID_ARGUMENT); -+ Slog.e(TAG, "IllegalArgumentException: ", illegalArgumentException); -+ tryAndThrowException( -+ callback, -+ illegalArgumentException, -+ HealthConnectException.ERROR_INVALID_ARGUMENT); - } catch (HealthConnectException healthConnectException) { - builder.setHealthDataServiceApiStatusError( - healthConnectException.getErrorCode()); -@@ -862,6 +874,10 @@ final class HealthConnectServiceImpl extends IHealthConnectService.Stub { - ChangeLogsRequestHelper.TokenRequest changeLogsTokenRequest = - ChangeLogsRequestHelper.getRequest( - attributionSource.getPackageName(), token.getToken()); -+ if (changeLogsTokenRequest.getRecordTypes().isEmpty()) { -+ throw new IllegalArgumentException( -+ "Requested record types must not be empty."); -+ } - mDataPermissionEnforcer.enforceRecordIdsReadPermissions( - changeLogsTokenRequest.getRecordTypes(), attributionSource); - boolean isInForeground = mAppOpsManagerLocal.isUidInForeground(uid); -diff --git a/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectServiceLogsTests.java b/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectServiceLogsTests.java -index 9eaa71ac..d983442b 100644 ---- a/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectServiceLogsTests.java -+++ b/tests/cts/hostsidetests/healthconnect/HealthConnectTestHelper/src/android/healthconnect/cts/testhelper/HealthConnectServiceLogsTests.java -@@ -43,6 +43,7 @@ import android.health.connect.changelog.ChangeLogTokenResponse; - import android.health.connect.changelog.ChangeLogsRequest; - import android.health.connect.changelog.ChangeLogsResponse; - import android.health.connect.datatypes.BloodPressureRecord; -+import android.health.connect.datatypes.HeartRateRecord; - import android.health.connect.datatypes.HeightRecord; - import android.health.connect.datatypes.Record; - import android.health.connect.datatypes.StepsRecord; -@@ -356,7 +357,10 @@ public class HealthConnectServiceLogsTests { - CountDownLatch latch = new CountDownLatch(1); - assertThat(mHealthConnectManager).isNotNull(); - mHealthConnectManager.getChangeLogToken( -- new ChangeLogTokenRequest.Builder().build(), -+ new ChangeLogTokenRequest.Builder() -+ .addRecordType(BloodPressureRecord.class) -+ .addRecordType(HeartRateRecord.class) -+ .build(), - Executors.newSingleThreadExecutor(), - new OutcomeReceiver<>() { - -diff --git a/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/HealthConnectDeviceTest.java b/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/HealthConnectDeviceTest.java -index ec1afc4b..659c362e 100644 ---- a/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/HealthConnectDeviceTest.java -+++ b/tests/cts/hostsidetests/healthconnect/device/src/android/healthconnect/cts/device/HealthConnectDeviceTest.java -@@ -279,70 +279,4 @@ public class HealthConnectDeviceTest { - APP_A_WITH_READ_WRITE_PERMS, recordClassesToRead); - assertThat(bundle.getInt(READ_RECORDS_SIZE)).isEqualTo(noOfRecordsInsertedByAppA); - } -- -- @Test -- public void testAppCanReadChangeLogsUsingDataOriginFilters() throws Exception { -- Bundle bundle = -- getChangeLogTokenAs( -- APP_B_WITH_READ_WRITE_PERMS, APP_A_WITH_READ_WRITE_PERMS.getPackageName()); -- String changeLogTokenForAppB = bundle.getString(CHANGE_LOG_TOKEN); -- -- bundle = -- getChangeLogTokenAs( -- APP_A_WITH_READ_WRITE_PERMS, APP_B_WITH_READ_WRITE_PERMS.getPackageName()); -- String changeLogTokenForAppA = bundle.getString(CHANGE_LOG_TOKEN); -- -- bundle = insertRecordAs(APP_A_WITH_READ_WRITE_PERMS); -- assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -- -- List listOfRecordIdsAndClass = -- (List) bundle.getSerializable(RECORD_IDS); -- -- List listOfRecordIdsInsertedByAppA = new ArrayList<>(); -- int noOfRecordsInsertedByAppA = 0; -- for (TestUtils.RecordTypeAndRecordIds recordTypeAndRecordIds : listOfRecordIdsAndClass) { -- noOfRecordsInsertedByAppA += recordTypeAndRecordIds.getRecordIds().size(); -- listOfRecordIdsInsertedByAppA.addAll(recordTypeAndRecordIds.getRecordIds()); -- } -- -- updateRecordsAs(APP_A_WITH_READ_WRITE_PERMS, listOfRecordIdsAndClass); -- -- bundle = insertRecordAs(APP_B_WITH_READ_WRITE_PERMS); -- assertThat(bundle.getBoolean(SUCCESS)).isTrue(); -- -- listOfRecordIdsAndClass = -- (List) bundle.getSerializable(RECORD_IDS); -- -- int noOfRecordsInsertedByAppB = 0; -- for (TestUtils.RecordTypeAndRecordIds recordTypeAndRecordIds : listOfRecordIdsAndClass) { -- noOfRecordsInsertedByAppB += recordTypeAndRecordIds.getRecordIds().size(); -- } -- -- deleteRecordsAs(APP_B_WITH_READ_WRITE_PERMS, listOfRecordIdsAndClass); -- -- bundle = -- readChangeLogsUsingDataOriginFiltersAs( -- APP_B_WITH_READ_WRITE_PERMS, changeLogTokenForAppB); -- -- ChangeLogsResponse response = bundle.getParcelable(CHANGE_LOGS_RESPONSE); -- -- assertThat(response.getUpsertedRecords().size()).isEqualTo(noOfRecordsInsertedByAppA); -- assertThat( -- response.getUpsertedRecords().stream() -- .map(Record::getMetadata) -- .map(Metadata::getId) -- .toList()) -- .containsExactlyElementsIn(listOfRecordIdsInsertedByAppA); -- -- assertThat(response.getDeletedLogs().size()).isEqualTo(0); -- -- bundle = -- readChangeLogsUsingDataOriginFiltersAs( -- APP_A_WITH_READ_WRITE_PERMS, changeLogTokenForAppA); -- -- response = bundle.getParcelable(CHANGE_LOGS_RESPONSE); -- -- assertThat(response.getUpsertedRecords().size()).isEqualTo(0); -- assertThat(response.getDeletedLogs().size()).isEqualTo(noOfRecordsInsertedByAppB); -- } - } -diff --git a/tests/cts/src/android/healthconnect/cts/HealthConnectChangeLogsTests.java b/tests/cts/src/android/healthconnect/cts/HealthConnectChangeLogsTests.java -index 71e38ef5..c58bae23 100644 ---- a/tests/cts/src/android/healthconnect/cts/HealthConnectChangeLogsTests.java -+++ b/tests/cts/src/android/healthconnect/cts/HealthConnectChangeLogsTests.java -@@ -18,6 +18,8 @@ package android.healthconnect.cts; - - import static com.google.common.truth.Truth.assertThat; - -+import static org.junit.Assert.assertThrows; -+ - import android.content.Context; - import android.health.connect.changelog.ChangeLogTokenRequest; - import android.health.connect.changelog.ChangeLogTokenResponse; -@@ -53,7 +55,8 @@ public class HealthConnectChangeLogsTests { - - @Test - public void testGetChangeLogToken() throws InterruptedException { -- ChangeLogTokenRequest changeLogTokenRequest = new ChangeLogTokenRequest.Builder().build(); -+ ChangeLogTokenRequest changeLogTokenRequest = -+ new ChangeLogTokenRequest.Builder().addRecordType(StepsRecord.class).build(); - assertThat(TestUtils.getChangeLogToken(changeLogTokenRequest)).isNotNull(); - assertThat(changeLogTokenRequest.getRecordTypes()).isNotNull(); - assertThat(changeLogTokenRequest.getDataOriginFilters()).isNotNull(); -@@ -62,7 +65,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insert_default() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).build(); - assertThat(changeLogsRequest.getToken()).isNotNull(); -@@ -82,7 +86,7 @@ public class HealthConnectChangeLogsTests { - public void testChangeLogs_insert_dataOrigin_filter_incorrect() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = - TestUtils.getChangeLogToken( -- new ChangeLogTokenRequest.Builder() -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes() - .addDataOriginFilter( - new DataOrigin.Builder().setPackageName("random").build()) - .build()); -@@ -106,7 +110,7 @@ public class HealthConnectChangeLogsTests { - Context context = ApplicationProvider.getApplicationContext(); - ChangeLogTokenResponse tokenResponse = - TestUtils.getChangeLogToken( -- new ChangeLogTokenRequest.Builder() -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes() - .addDataOriginFilter( - new DataOrigin.Builder() - .setPackageName(context.getPackageName()) -@@ -160,7 +164,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insertAndDelete_default() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -@@ -186,7 +191,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insertAndDelete_beforePermission() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().addRecordType( -+ StepsRecord.class).build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -@@ -212,7 +218,7 @@ public class HealthConnectChangeLogsTests { - throws InterruptedException { - ChangeLogTokenResponse tokenResponse = - TestUtils.getChangeLogToken( -- new ChangeLogTokenRequest.Builder() -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes() - .addDataOriginFilter( - new DataOrigin.Builder().setPackageName("random").build()) - .build()); -@@ -237,7 +243,7 @@ public class HealthConnectChangeLogsTests { - Context context = ApplicationProvider.getApplicationContext(); - ChangeLogTokenResponse tokenResponse = - TestUtils.getChangeLogToken( -- new ChangeLogTokenRequest.Builder() -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes() - .addDataOriginFilter( - new DataOrigin.Builder() - .setPackageName(context.getPackageName()) -@@ -295,7 +301,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insert_default_withPageSize() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).setPageSize(1).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -@@ -310,7 +317,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insert_default_withNextPageToken() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).setPageSize(1).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -@@ -340,7 +348,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_insert_default_withSamePageToken() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -@@ -358,7 +367,8 @@ public class HealthConnectChangeLogsTests { - @Test - public void testChangeLogs_checkToken_hasMorePages_False() throws InterruptedException { - ChangeLogTokenResponse tokenResponse = -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ TestUtils.getChangeLogTokenRequestForTestRecordTypes().build()); - ChangeLogsRequest changeLogsRequest = - new ChangeLogsRequest.Builder(tokenResponse.getToken()).build(); - ChangeLogsResponse response = TestUtils.getChangeLogs(changeLogsRequest); -diff --git a/tests/cts/src/android/healthconnect/cts/HealthConnectManagerTest.java b/tests/cts/src/android/healthconnect/cts/HealthConnectManagerTest.java -index c76dd1e2..ca8d225c 100644 ---- a/tests/cts/src/android/healthconnect/cts/HealthConnectManagerTest.java -+++ b/tests/cts/src/android/healthconnect/cts/HealthConnectManagerTest.java -@@ -1560,7 +1560,8 @@ public class HealthConnectManagerTest { - } - - try { -- TestUtils.getChangeLogToken(new ChangeLogTokenRequest.Builder().build()); -+ TestUtils.getChangeLogToken( -+ new ChangeLogTokenRequest.Builder().addRecordType(StepsRecord.class).build()); - Assert.fail(); - } catch (HealthConnectException exception) { - assertThat(exception).isNotNull(); -diff --git a/tests/cts/src/android/healthconnect/cts/TestUtils.java b/tests/cts/src/android/healthconnect/cts/TestUtils.java -index 8f3ec4c8..f89e81e8 100644 ---- a/tests/cts/src/android/healthconnect/cts/TestUtils.java -+++ b/tests/cts/src/android/healthconnect/cts/TestUtils.java -@@ -301,6 +301,14 @@ public class TestUtils { - buildExerciseSession()); - } - -+ public static ChangeLogTokenRequest.Builder getChangeLogTokenRequestForTestRecordTypes() { -+ return new ChangeLogTokenRequest.Builder() -+ .addRecordType(StepsRecord.class) -+ .addRecordType(HeartRateRecord.class) -+ .addRecordType(BasalMetabolicRateRecord.class) -+ .addRecordType(ExerciseSessionRecord.class); -+ } -+ - public static List getRecordsAndIdentifiers() { - return Arrays.asList( - new RecordAndIdentifier(RECORD_TYPE_STEPS, getStepsRecord()), --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/packages/modules/HealthFitness/0003-Add-flag-to-prevent-non-system-apps-from-showing-overlay-on-HC-U.bulletin.patch b/aosp_diff/preliminary/packages/modules/HealthFitness/0003-Add-flag-to-prevent-non-system-apps-from-showing-overlay-on-HC-U.bulletin.patch deleted file mode 100644 index d757647cba..0000000000 --- a/aosp_diff/preliminary/packages/modules/HealthFitness/0003-Add-flag-to-prevent-non-system-apps-from-showing-overlay-on-HC-U.bulletin.patch +++ /dev/null @@ -1,191 +0,0 @@ -From c4e13d15e8dd1df1bd827117d1a74c187ed2b3c2 Mon Sep 17 00:00:00 2001 -From: Mridul Agarwal -Date: Tue, 12 Mar 2024 10:48:16 +0000 -Subject: [PATCH] Add flag to prevent non-system apps from showing overlay on - HC UI. - -Test: manual -Bug: 328561789 -(cherry picked from commit 85c7c82115c8935a0b22067c76c525ffea2459e3) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:271dcafb550877589f83ec0690bd1a5d2d83d773) -Merged-In: I7b667f51c4a0952be20cafa852c13857d57cadc2 -Change-Id: I7b667f51c4a0952be20cafa852c13857d57cadc2 ---- - apk/AndroidManifest.xml | 2 ++ - apk/src/com/android/healthconnect/controller/MainActivity.kt | 4 ++++ - .../healthconnect/controller/data/DataManagementActivity.kt | 5 +++++ - .../healthconnect/controller/migration/MigrationActivity.kt | 3 +++ - .../controller/onboarding/OnboardingActivity.kt | 3 +++ - .../controller/permissions/request/PermissionsActivity.kt | 4 ++++ - .../controller/permissions/shared/SettingsActivity.kt | 3 +++ - .../healthconnect/controller/route/RouteRequestActivity.kt | 4 ++++ - 8 files changed, 28 insertions(+) - -diff --git a/apk/AndroidManifest.xml b/apk/AndroidManifest.xml -index 11094c77..41ccd3c1 100644 ---- a/apk/AndroidManifest.xml -+++ b/apk/AndroidManifest.xml -@@ -26,6 +26,8 @@ - - - -+ -+ - - -Date: Wed, 27 Mar 2024 23:21:03 +0000 -Subject: [PATCH] [libstatssocket] Added validation for adding new data into - StatsEvent - -Bug: 330054251 -Test: atest StatsEventTest#TestHeapBufferOverflowError -Ignore-AOSP-First: security -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:4f6c56889356a5a422b59c71e9142875d00e43bf) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:e440696c4fd6d44d21451467294b3e31c6867e08) -Merged-In: I27c69d9875b494f98a2a961cdd4fe139cd809387 -Change-Id: I27c69d9875b494f98a2a961cdd4fe139cd809387 ---- - lib/libstatssocket/stats_event.c | 3 ++ - lib/libstatssocket/tests/stats_event_test.cpp | 44 +++++++++++++++++++ - 2 files changed, 47 insertions(+) - -diff --git a/lib/libstatssocket/stats_event.c b/lib/libstatssocket/stats_event.c -index 9bb4c52c..828ff3e4 100644 ---- a/lib/libstatssocket/stats_event.c -+++ b/lib/libstatssocket/stats_event.c -@@ -330,6 +330,9 @@ void AStatsEvent_writeStringArray(AStatsEvent* event, const char* const* element - - // Side-effect: modifies event->errors if field has too many annotations - static void increment_annotation_count(AStatsEvent* event) { -+ if (event->lastFieldPos >= event->bufSize) { -+ return; -+ } - uint8_t fieldType = event->buf[event->lastFieldPos] & 0x0F; - uint32_t oldAnnotationCount = (event->buf[event->lastFieldPos] & 0xF0) >> 4; - uint32_t newAnnotationCount = oldAnnotationCount + 1; -diff --git a/lib/libstatssocket/tests/stats_event_test.cpp b/lib/libstatssocket/tests/stats_event_test.cpp -index 93a99f1b..dea81c25 100644 ---- a/lib/libstatssocket/tests/stats_event_test.cpp -+++ b/lib/libstatssocket/tests/stats_event_test.cpp -@@ -536,6 +536,50 @@ TEST(StatsEventTest, TestPushOverflowError) { - AStatsEvent_release(event); - } - -+TEST(StatsEventTest, TestHeapBufferOverflowError) { -+ const std::string testString(4039, 'A'); -+ const std::string testString2(47135, 'B'); -+ -+ AStatsEvent* event = AStatsEvent_obtain(); -+ AStatsEvent_setAtomId(event, 100); -+ -+ AStatsEvent_writeString(event, testString.c_str()); -+ size_t bufferSize = 0; -+ AStatsEvent_getBuffer(event, &bufferSize); -+ EXPECT_EQ(bufferSize, 4060); -+ uint32_t errors = AStatsEvent_getErrors(event); -+ EXPECT_EQ(errors, 0); -+ -+ // expand the buffer and fill with data up to the very last byte -+ AStatsEvent_writeString(event, testString2.c_str()); -+ bufferSize = 0; -+ AStatsEvent_getBuffer(event, &bufferSize); -+ EXPECT_EQ(bufferSize, 50 * 1024); -+ -+ errors = AStatsEvent_getErrors(event); -+ EXPECT_EQ(errors, 0); -+ -+ // this write is no-op due to buffer reached its max capacity -+ // should set the overflow flag -+ AStatsEvent_writeString(event, testString2.c_str()); -+ bufferSize = 0; -+ AStatsEvent_getBuffer(event, &bufferSize); -+ EXPECT_EQ(bufferSize, 50 * 1024); -+ -+ errors = AStatsEvent_getErrors(event); -+ EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW); -+ -+ // here should be crash -+ AStatsEvent_addBoolAnnotation(event, 1, false); -+ -+ AStatsEvent_write(event); -+ -+ errors = AStatsEvent_getErrors(event); -+ EXPECT_EQ(errors & ERROR_OVERFLOW, ERROR_OVERFLOW); -+ -+ AStatsEvent_release(event); -+} -+ - TEST(StatsEventTest, TestPullOverflowError) { - const uint32_t atomId = 10100; - const vector bytes(430 /* number of elements */, 1 /* value of each element */); --- -2.44.0.396.g6e790dbe36-goog - diff --git a/aosp_diff/preliminary/packages/modules/StatsD/0002-statsd-Make-executor-thread-a-class-member-of-MultiConditionTr.bulletin.patch b/aosp_diff/preliminary/packages/modules/StatsD/0002-statsd-Make-executor-thread-a-class-member-of-MultiConditionTr.bulletin.patch deleted file mode 100644 index 31530a5a27..0000000000 --- a/aosp_diff/preliminary/packages/modules/StatsD/0002-statsd-Make-executor-thread-a-class-member-of-MultiConditionTr.bulletin.patch +++ /dev/null @@ -1,371 +0,0 @@ -From cb201622f3d45df6de019e993012563a14d8c0aa Mon Sep 17 00:00:00 2001 -From: Vova Sharaienko -Date: Thu, 20 Jul 2023 23:25:31 +0000 -Subject: [PATCH] [statsd] Make executor thread a class member of - MultiConditionTrigger - -executorThread references class members after detaching. Making -executorThread as class member and joining in MultiConditionTrigger -destructor. - -Ignore-AOSP-First: Security bugs merged into internal branch first -Test: atest statsd_test -Bug: 292160348 -Flag: NONE mainline module bug fix -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:30775d2bb2e2070bc49def70f97af4724342c4c2) -Merged-In: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee -Change-Id: I7036eb3d506e8ca88e4a5faa6275dc4cba8020ee ---- - statsd/src/StatsService.cpp | 21 ++- - statsd/src/StatsService.h | 17 ++- - statsd/src/utils/MultiConditionTrigger.cpp | 21 ++- - statsd/src/utils/MultiConditionTrigger.h | 10 +- - .../utils/MultiConditionTrigger_test.cpp | 121 ++++++++++++++++++ - 5 files changed, 179 insertions(+), 11 deletions(-) - -diff --git a/statsd/src/StatsService.cpp b/statsd/src/StatsService.cpp -index c34964dd..c2c71612 100644 ---- a/statsd/src/StatsService.cpp -+++ b/statsd/src/StatsService.cpp -@@ -235,6 +235,7 @@ StatsService::StatsService(const sp& uidMap, shared_ptr q - } - - StatsService::~StatsService() { -+ onStatsdInitCompletedHandlerTermination(); - if (mEventQueue != nullptr) { - stopReadingLogs(); - mLogsReaderThread->join(); -@@ -1099,6 +1100,7 @@ Status StatsService::systemRunning() { - Status StatsService::informDeviceShutdown() { - ENFORCE_UID(AID_SYSTEM); - VLOG("StatsService::informDeviceShutdown"); -+ onStatsdInitCompletedHandlerTermination(); - int64_t elapsedRealtimeNs = getElapsedRealtimeNs(); - int64_t wallClockNs = getWallClockNs(); - mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, elapsedRealtimeNs, wallClockNs); -@@ -1152,7 +1154,14 @@ void StatsService::onStatsdInitCompleted() { - // This function is called from a dedicated thread without holding locks, so sleeping is ok. - // See MultiConditionTrigger::markComplete() executorThread for details - // For more details see http://b/277958338 -- std::this_thread::sleep_for(std::chrono::seconds(mInitEventDelaySecs)); -+ -+ std::unique_lock lk(mStatsdInitCompletedHandlerTerminationFlagMutex); -+ if (mStatsdInitCompletedHandlerTerminationFlag.wait_for( -+ lk, std::chrono::seconds(mInitEventDelaySecs), -+ [this] { return mStatsdInitCompletedHandlerTerminationRequested; })) { -+ VLOG("StatsService::onStatsdInitCompleted() Early termination is requested"); -+ return; -+ } - } - - mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); -@@ -1169,6 +1178,7 @@ void StatsService::Startup() { - - void StatsService::Terminate() { - ALOGI("StatsService::Terminating"); -+ onStatsdInitCompletedHandlerTermination(); - if (mProcessor != nullptr) { - int64_t elapsedRealtimeNs = getElapsedRealtimeNs(); - int64_t wallClockNs = getWallClockNs(); -@@ -1179,6 +1189,14 @@ void StatsService::Terminate() { - } - } - -+void StatsService::onStatsdInitCompletedHandlerTermination() { -+ { -+ std::unique_lock lk(mStatsdInitCompletedHandlerTerminationFlagMutex); -+ mStatsdInitCompletedHandlerTerminationRequested = true; -+ } -+ mStatsdInitCompletedHandlerTerminationFlag.notify_all(); -+} -+ - // Test only interface!!! - void StatsService::OnLogEvent(LogEvent* event) { - mProcessor->OnLogEvent(event); -@@ -1402,6 +1420,7 @@ void StatsService::statsCompanionServiceDied(void* cookie) { - void StatsService::statsCompanionServiceDiedImpl() { - ALOGW("statscompanion service died"); - StatsdStats::getInstance().noteSystemServerRestart(getWallClockSec()); -+ onStatsdInitCompletedHandlerTermination(); - if (mProcessor != nullptr) { - ALOGW("Reset statsd upon system server restarts."); - int64_t systemServerRestartNs = getElapsedRealtimeNs(); -diff --git a/statsd/src/StatsService.h b/statsd/src/StatsService.h -index da1b4ab5..2c030fd8 100644 ---- a/statsd/src/StatsService.h -+++ b/statsd/src/StatsService.h -@@ -408,11 +408,16 @@ private: - */ - void onStatsdInitCompleted(); - -- /** -- * This method is used to stop log reader thread. -+ /* -+ * This method is used to stop log reader thread. - */ - void stopReadingLogs(); - -+ /* -+ * Notify async StatsdInitCompleted handler about termination event -+ */ -+ void onStatsdInitCompletedHandlerTermination(); -+ - std::atomic mIsStopRequested = false; - - /** -@@ -461,6 +466,14 @@ private: - - std::unique_ptr mLogsReaderThread; - -+ std::condition_variable mStatsdInitCompletedHandlerTerminationFlag; -+ std::mutex mStatsdInitCompletedHandlerTerminationFlagMutex; -+ /** -+ * @brief Used to communicated early termination request to onStatsdInitCompleted Handler -+ * @see onStatsdInitCompleted -+ */ -+ bool mStatsdInitCompletedHandlerTerminationRequested = false; -+ - MultiConditionTrigger mBootCompleteTrigger; - static const inline string kBootCompleteTag = "BOOT_COMPLETE"; - static const inline string kUidMapReceivedTag = "UID_MAP"; -diff --git a/statsd/src/utils/MultiConditionTrigger.cpp b/statsd/src/utils/MultiConditionTrigger.cpp -index 5ef50ee0..5078cae6 100644 ---- a/statsd/src/utils/MultiConditionTrigger.cpp -+++ b/statsd/src/utils/MultiConditionTrigger.cpp -@@ -14,11 +14,10 @@ - * limitations under the License. - */ - #define STATSD_DEBUG false // STOPSHIP if true -+#include "Log.h" - - #include "MultiConditionTrigger.h" - --#include -- - using namespace std; - - namespace android { -@@ -31,8 +30,7 @@ MultiConditionTrigger::MultiConditionTrigger(const set& conditionNames, - mTrigger(trigger), - mCompleted(mRemainingConditionNames.empty()) { - if (mCompleted) { -- thread executorThread([this] { mTrigger(); }); -- executorThread.detach(); -+ startExecutorThread(); - } - } - -@@ -48,10 +46,21 @@ void MultiConditionTrigger::markComplete(const string& conditionName) { - doTrigger = mCompleted; - } - if (doTrigger) { -- std::thread executorThread([this] { mTrigger(); }); -- executorThread.detach(); -+ startExecutorThread(); - } - } -+ -+void MultiConditionTrigger::startExecutorThread() { -+ mExecutorThread = make_unique([this] { mTrigger(); }); -+} -+ -+MultiConditionTrigger::~MultiConditionTrigger() { -+ if (mExecutorThread != nullptr && mExecutorThread->joinable()) { -+ VLOG("MultiConditionTrigger waiting on execution thread termination"); -+ mExecutorThread->join(); -+ } -+} -+ - } // namespace statsd - } // namespace os - } // namespace android -diff --git a/statsd/src/utils/MultiConditionTrigger.h b/statsd/src/utils/MultiConditionTrigger.h -index 51f60299..dee00713 100644 ---- a/statsd/src/utils/MultiConditionTrigger.h -+++ b/statsd/src/utils/MultiConditionTrigger.h -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - namespace android { - namespace os { -@@ -27,8 +28,8 @@ namespace statsd { - /** - * This class provides a utility to wait for a set of named conditions to occur. - * -- * It will execute the trigger runnable in a detached thread once all conditions have been marked -- * true. -+ * It will execute the trigger runnable in a separate thread (which will be joined at instance -+ * destructor time) once all conditions have been marked true. - */ - class MultiConditionTrigger { - public: -@@ -37,19 +38,24 @@ public: - - MultiConditionTrigger(const MultiConditionTrigger&) = delete; - MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete; -+ ~MultiConditionTrigger(); - - // Mark a specific condition as true. If this condition has called markComplete already or if - // the event was not specified in the constructor, the function is a no-op. - void markComplete(const std::string& eventName); - - private: -+ void startExecutorThread(); -+ - mutable std::mutex mMutex; - std::set mRemainingConditionNames; - std::function mTrigger; - bool mCompleted; -+ std::unique_ptr mExecutorThread; - - FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName); - }; -+ - } // namespace statsd - } // namespace os - } // namespace android -diff --git a/statsd/tests/utils/MultiConditionTrigger_test.cpp b/statsd/tests/utils/MultiConditionTrigger_test.cpp -index 32cecd3b..b525f75e 100644 ---- a/statsd/tests/utils/MultiConditionTrigger_test.cpp -+++ b/statsd/tests/utils/MultiConditionTrigger_test.cpp -@@ -22,6 +22,8 @@ - #include - #include - -+#include "tests/statsd_test_util.h" -+ - #ifdef __ANDROID__ - - using namespace std; -@@ -166,6 +168,125 @@ TEST(MultiConditionTrigger, TestTriggerOnlyCalledOnce) { - } - } - -+namespace { -+ -+class TriggerDependency { -+public: -+ TriggerDependency(mutex& lock, condition_variable& cv, bool& triggerCalled, int& triggerCount) -+ : mLock(lock), mCv(cv), mTriggerCalled(triggerCalled), mTriggerCount(triggerCount) { -+ } -+ -+ void someMethod() { -+ lock_guard lg(mLock); -+ mTriggerCount++; -+ mTriggerCalled = true; -+ mCv.notify_all(); -+ } -+ -+private: -+ mutex& mLock; -+ condition_variable& mCv; -+ bool& mTriggerCalled; -+ int& mTriggerCount; -+}; -+ -+} // namespace -+ -+TEST(MultiConditionTrigger, TestTriggerHasSleep) { -+ const string t1 = "t1"; -+ set conditionNames = {t1}; -+ -+ mutex lock; -+ condition_variable cv; -+ bool triggerCalled = false; -+ int triggerCount = 0; -+ -+ { -+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount); -+ MultiConditionTrigger trigger(conditionNames, [&dependency] { -+ std::this_thread::sleep_for(std::chrono::milliseconds(50)); -+ dependency.someMethod(); -+ }); -+ trigger.markComplete(t1); -+ -+ // Here dependency instance will go out of scope and the thread within MultiConditionTrigger -+ // after delay will try to call method of already destroyed class instance -+ // with leading crash if trigger execution thread is detached in MultiConditionTrigger -+ // Instead since the MultiConditionTrigger destructor happens before TriggerDependency -+ // destructor, MultiConditionTrigger destructor is waiting on execution thread termination -+ // with thread::join -+ } -+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor -+ -+ // Ensure that the trigger fired. -+ { -+ unique_lock unique_lk(lock); -+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); -+ EXPECT_TRUE(triggerCalled); -+ EXPECT_EQ(triggerCount, 1); -+ } -+} -+ -+TEST(MultiConditionTrigger, TestTriggerHasSleepEarlyTermination) { -+ const string t1 = "t1"; -+ set conditionNames = {t1}; -+ -+ mutex lock; -+ condition_variable cv; -+ bool triggerCalled = false; -+ int triggerCount = 0; -+ -+ std::condition_variable triggerTerminationFlag; -+ std::mutex triggerTerminationFlagMutex; -+ bool terminationRequested = false; -+ -+ // used for error threshold tolerance due to wait_for() is involved -+ const int64_t errorThresholdMs = 25; -+ const int64_t triggerEarlyTerminationDelayMs = 100; -+ const int64_t triggerStartNs = getElapsedRealtimeNs(); -+ { -+ TriggerDependency dependency(lock, cv, triggerCalled, triggerCount); -+ MultiConditionTrigger trigger( -+ conditionNames, [&dependency, &triggerTerminationFlag, &triggerTerminationFlagMutex, -+ &lock, &triggerCalled, &cv, &terminationRequested] { -+ std::unique_lock lk(triggerTerminationFlagMutex); -+ if (triggerTerminationFlag.wait_for( -+ lk, std::chrono::seconds(1), -+ [&terminationRequested] { return terminationRequested; })) { -+ // triggerTerminationFlag was notified - early termination is requested -+ lock_guard lg(lock); -+ triggerCalled = true; -+ cv.notify_all(); -+ return; -+ } -+ dependency.someMethod(); -+ }); -+ trigger.markComplete(t1); -+ -+ // notify to terminate trigger executor thread after triggerEarlyTerminationDelayMs -+ std::this_thread::sleep_for(std::chrono::milliseconds(triggerEarlyTerminationDelayMs)); -+ { -+ std::unique_lock lk(triggerTerminationFlagMutex); -+ terminationRequested = true; -+ } -+ triggerTerminationFlag.notify_all(); -+ } -+ // At this moment the executor thread guaranteed terminated by MultiConditionTrigger destructor -+ -+ // check that test duration is closer to 100ms rather to 1s -+ const int64_t triggerEndNs = getElapsedRealtimeNs(); -+ EXPECT_LE(NanoToMillis(triggerEndNs - triggerStartNs), -+ triggerEarlyTerminationDelayMs + errorThresholdMs); -+ -+ // Ensure that the trigger fired but not the dependency.someMethod(). -+ { -+ unique_lock unique_lk(lock); -+ cv.wait(unique_lk, [&triggerCalled] { return triggerCalled; }); -+ EXPECT_TRUE(triggerCalled); -+ EXPECT_EQ(triggerCount, 0); -+ } -+} -+ - } // namespace statsd - } // namespace os - } // namespace android --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/packages/modules/adb/0001-adb-dbc-tty-add-adb-over-dbc-tty-support.patch b/aosp_diff/preliminary/packages/modules/adb/0001-adb-dbc-tty-add-adb-over-dbc-tty-support.patch deleted file mode 100644 index 2537b6b9d0..0000000000 --- a/aosp_diff/preliminary/packages/modules/adb/0001-adb-dbc-tty-add-adb-over-dbc-tty-support.patch +++ /dev/null @@ -1,491 +0,0 @@ -From 8090a6ff0df7e660ea3c11e11ab4544df05b120b Mon Sep 17 00:00:00 2001 -From: Prabhat Chand Pandey -Date: Tue, 25 May 2021 17:32:05 +0530 -Subject: [PATCH] adb: dbc: tty: add adb over dbc tty support - -Added adb over dbc tty support in adb framework. - -This implementation is based on Blocking I/O calls. - -Set "persist.vendor.sys.usb.adbover" android property to "dbc" -to use adb over dbc tty otherwise set thisproperty to "dwc" -(which is the default valueof this property) to use adb over -normal USB (which need USB Device Mode IP to be enabled). - -Change-Id: If4f394a9577c97e9146987a4d36d1c89c4b8269d -Tracked-On: -Signed-off-by: Prabhat Chand Pandey ---- - adb.h | 6 +++ - client/commandline.cpp | 13 +++-- - client/transport_usb.cpp | 7 ++- - client/usb_linux.cpp | 35 ++++++++++++ - daemon/main.cpp | 2 +- - daemon/usb.cpp | 22 +++++++- - daemon/usb_ffs.cpp | 67 +++++++++++++++++++++++ - daemon/usb_ffs.h | 1 + - transport.cpp | 111 +++++++++++++++++++++++++++++++++++++++ - transport.h | 25 +++++++++ - 10 files changed, 281 insertions(+), 8 deletions(-) - -diff --git a/adb.h b/adb.h -index 0911f462..ff6fb1e9 100644 ---- a/adb.h -+++ b/adb.h -@@ -198,6 +198,10 @@ void put_apacket(apacket* p); - #define ADB_SUBCLASS 0x42 - #define ADB_PROTOCOL 0x1 - -+#define ADB_DBC_CLASS 0xDC -+#define ADB_DBC_SUBCLASS 0x2 -+#define ADB_DBC_PROTOCOL 0x1 -+ - void local_init(const std::string& addr); - bool local_connect(int port); - int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error); -@@ -216,6 +220,8 @@ extern const char* adb_device_banner; - #define USB_FFS_ADB_EP0 USB_FFS_ADB_EP(ep0) - #define USB_FFS_ADB_OUT USB_FFS_ADB_EP(ep1) - #define USB_FFS_ADB_IN USB_FFS_ADB_EP(ep2) -+ -+#define USB_DBC_ADB_PATH "/dev/ttyDBC0" - #endif - - enum class HostRequestResult { -diff --git a/client/commandline.cpp b/client/commandline.cpp -index dfe15948..f13dae42 100644 ---- a/client/commandline.cpp -+++ b/client/commandline.cpp -@@ -1057,7 +1057,8 @@ static bool adb_root(const char* command) { - } - - // Figure out whether we actually did anything. -- char buf[256]; -+ // adb root blocked here as at time there is no any read happening from target. -+/* char buf[256]; - char* cur = buf; - ssize_t bytes_left = sizeof(buf); - while (bytes_left > 0) { -@@ -1082,15 +1083,17 @@ static bool adb_root(const char* command) { - if (cur != buf && strstr(buf, "restarting") == nullptr) { - return true; - } -- -+*/ - // Wait for the device to go away. - TransportType previous_type; - const char* previous_serial; - TransportId previous_id; - adb_get_transport(&previous_type, &previous_serial, &previous_id); - -- adb_set_transport(kTransportAny, nullptr, transport_id); -- wait_for_device("wait-for-disconnect"); -+ // adb_set_transport(kTransportAny, nullptr, transport_id); -+ // wait_for_device("wait-for-disconnect"); -+ // Let transport destructor to remove transport at target disconnect -+ std::this_thread::sleep_for(1s); - - // Wait for the device to come back. - // If we were using a specific transport ID, there's nothing we can wait for. -@@ -1837,7 +1840,7 @@ int adb_commandline(int argc, const char** argv) { - } - return adb_connect_command(command); - } else if (!strcmp(argv[0], "root") || !strcmp(argv[0], "unroot")) { -- return adb_root(argv[0]) ? 0 : 1; -+ return adb_root(argv[0]) ? adb_query_command(format_host_command("reconnect")) : 1; - } else if (!strcmp(argv[0], "bugreport")) { - Bugreport bugreport; - return bugreport.DoIt(argc, argv); -diff --git a/client/transport_usb.cpp b/client/transport_usb.cpp -index 777edde0..e7b0a83f 100644 ---- a/client/transport_usb.cpp -+++ b/client/transport_usb.cpp -@@ -199,7 +199,12 @@ void init_usb_transport(atransport* t, usb_handle* h) { - } - - int is_adb_interface(int usb_class, int usb_subclass, int usb_protocol) { -- return (usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL); -+ if ((usb_class == ADB_CLASS && usb_subclass == ADB_SUBCLASS && usb_protocol == ADB_PROTOCOL) || -+ (usb_class == ADB_DBC_CLASS && usb_subclass == ADB_DBC_SUBCLASS && -+ usb_protocol == ADB_DBC_PROTOCOL)) -+ return true; -+ else -+ return false; - } - - bool should_use_libusb() { -diff --git a/client/usb_linux.cpp b/client/usb_linux.cpp -index b2e4634a..7472f486 100644 ---- a/client/usb_linux.cpp -+++ b/client/usb_linux.cpp -@@ -356,6 +356,9 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) { - urb->buffer = data; - urb->buffer_length = len; - -+ usbdevfs_ctrltransfer ufs; -+ unsigned short int ufsdata; -+ - if (h->dead) { - errno = EINVAL; - return -1; -@@ -370,6 +373,38 @@ static int usb_bulk_read(usb_handle* h, void* data, int len) { - D("[ reap urb - wait ]"); - h->reaper_thread = pthread_self(); - int fd = h->fd; -+ -+ ufsdata = 0; -+ ufs.bRequestType = 0x82; -+ ufs.bRequest = USB_REQ_GET_STATUS; -+ ufs.wValue = 0x0000; -+ ufs.wIndex = h->ep_in; -+ ufs.wLength = 0x0002; -+ ufs.data = &ufsdata; -+ -+ if (TEMP_FAILURE_RETRY(ioctl(h->fd,USBDEVFS_CONTROL,&ufs))== -1) { -+ D("clear_halt read failed"); -+ } else { -+ D("clear_halt read successful %d",ufsdata); -+ } -+ -+ if (ufsdata) { -+ ufs.bRequestType = 0x02; -+ ufs.bRequest = USB_REQ_CLEAR_FEATURE; -+ ufs.wValue = 0x0000; -+ ufs.wIndex = h->ep_out; -+ ufs.wLength = 0x0000; -+ ufs.data = NULL; -+ -+ if (TEMP_FAILURE_RETRY(ioctl(h->fd,USBDEVFS_CONTROL,&ufs))== -1) { -+ D("clear_halt read2 failed"); -+ } else { -+ D("clear_halt read2 successful "); -+ } -+ errno = ETIMEDOUT; -+ return -1; -+ } -+ - lock.unlock(); - - // This ioctl must not have TEMP_FAILURE_RETRY because we send SIGALRM to break out. -diff --git a/daemon/main.cpp b/daemon/main.cpp -index 677e853b..1999662f 100644 ---- a/daemon/main.cpp -+++ b/daemon/main.cpp -@@ -253,7 +253,7 @@ int adbd_main(int server_port) { - bool is_usb = false; - - #if defined(__ANDROID__) -- if (access(USB_FFS_ADB_EP0, F_OK) == 0) { -+ if ((access(USB_FFS_ADB_EP0, F_OK) == 0) || (access(USB_DBC_ADB_PATH,F_OK) == 0)) { - // Listen on USB. - usb_init(); - is_usb = true; -diff --git a/daemon/usb.cpp b/daemon/usb.cpp -index f9e085fb..6c713ebe 100644 ---- a/daemon/usb.cpp -+++ b/daemon/usb.cpp -@@ -741,6 +741,23 @@ struct UsbFfsConnection : public Connection { - static constexpr int kInterruptionSignal = SIGUSR1; - }; - -+static void usb_dbc_open_thread() { -+ adb_thread_setname("usb dbc open"); -+ -+ while (true) { -+ unique_fd bulk_out; -+ unique_fd bulk_in; -+ -+ if (!open_dbc(&bulk_out, &bulk_in)) { -+ std::this_thread::sleep_for(1s); -+ continue; -+ } -+ -+ register_dbc_transport(std::move(bulk_out), std::move(bulk_in), "UsbDbC"); -+ } -+} -+ -+ - static void usb_ffs_open_thread() { - adb_thread_setname("usb ffs open"); - -@@ -786,5 +803,8 @@ static void usb_ffs_open_thread() { - } - - void usb_init() { -- std::thread(usb_ffs_open_thread).detach(); -+ if (access(USB_DBC_ADB_PATH,F_OK) == 0) -+ std::thread(usb_dbc_open_thread).detach(); -+ else -+ std::thread(usb_ffs_open_thread).detach(); - } -diff --git a/daemon/usb_ffs.cpp b/daemon/usb_ffs.cpp -index e538ca88..8cb83c07 100644 ---- a/daemon/usb_ffs.cpp -+++ b/daemon/usb_ffs.cpp -@@ -27,6 +27,8 @@ - #include - #include - -+#include -+ - #include "adb.h" - - #define MAX_PACKET_SIZE_FS 64 -@@ -249,6 +251,71 @@ static const struct { - }; - // clang-format on - -+bool open_dbc(android::base::unique_fd* out_bulk_out, android::base::unique_fd* out_bulk_in) { -+ unique_fd bulk_out, bulk_in; -+ struct termios SerialPortSettings; -+ -+ // BULK OUT -+ if (out_bulk_out->get() < 0) { // might have already done this before -+ LOG(INFO) << "opening DbC BULK OUT endpoint " << USB_DBC_ADB_PATH; -+ bulk_out.reset(adb_open(USB_DBC_ADB_PATH, O_RDWR)); -+ if (bulk_out < 0) { -+ PLOG(ERROR) << "cannot open DbC BULK OUT endpoint " << USB_DBC_ADB_PATH; -+ return false; -+ } -+ tcgetattr(bulk_out.get(), &SerialPortSettings); -+ -+ cfsetispeed(&SerialPortSettings,B9600); -+ cfsetospeed(&SerialPortSettings,B9600); -+ -+ SerialPortSettings.c_cflag &= ~PARENB; -+ SerialPortSettings.c_cflag &= ~CSTOPB; -+ SerialPortSettings.c_cflag &= ~CSIZE; -+ SerialPortSettings.c_cflag &= CS8; -+ SerialPortSettings.c_cflag &= ~CRTSCTS; -+ SerialPortSettings.c_cflag &= CREAD | CLOCAL; -+ SerialPortSettings.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG); -+ SerialPortSettings.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); -+ SerialPortSettings.c_oflag &= ~OPOST; -+ SerialPortSettings.c_cc[VMIN] = 10; -+ SerialPortSettings.c_cc[VTIME] = 10; -+ -+ tcsetattr(bulk_out.get(), TCSANOW, &SerialPortSettings); -+ } -+ -+ // Bulk IN -+ if (out_bulk_in->get() < 0) { // might have already done this before -+ LOG(INFO) << "opening DbC BULK IN endpoint " << USB_DBC_ADB_PATH; -+ bulk_in.reset(adb_open(USB_DBC_ADB_PATH, O_RDWR)); -+ if (bulk_in < 0) { -+ PLOG(ERROR) << "cannot open DbC BULK IN endpoint " << USB_DBC_ADB_PATH; -+ return false; -+ } -+ tcgetattr(bulk_in.get(), &SerialPortSettings); -+ -+ cfsetispeed(&SerialPortSettings,B9600); -+ cfsetospeed(&SerialPortSettings,B9600); -+ -+ SerialPortSettings.c_cflag &= ~PARENB; -+ SerialPortSettings.c_cflag &= ~CSTOPB; -+ SerialPortSettings.c_cflag &= ~CSIZE; -+ SerialPortSettings.c_cflag &= CS8; -+ SerialPortSettings.c_cflag &= ~CRTSCTS; -+ SerialPortSettings.c_cflag &= CREAD | CLOCAL; -+ SerialPortSettings.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG); -+ SerialPortSettings.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); -+ SerialPortSettings.c_oflag &= ~OPOST; -+ SerialPortSettings.c_cc[VMIN] = 10; -+ SerialPortSettings.c_cc[VTIME] = 10; -+ -+ tcsetattr(bulk_in.get(), TCSANOW, &SerialPortSettings); -+ } -+ -+ *out_bulk_out = std::move(bulk_out); -+ *out_bulk_in = std::move(bulk_in); -+ return true; -+} -+ - bool open_functionfs(android::base::unique_fd* out_control, android::base::unique_fd* out_bulk_out, - android::base::unique_fd* out_bulk_in) { - unique_fd control, bulk_out, bulk_in; -diff --git a/daemon/usb_ffs.h b/daemon/usb_ffs.h -index a19d7ccc..485798a8 100644 ---- a/daemon/usb_ffs.h -+++ b/daemon/usb_ffs.h -@@ -18,5 +18,6 @@ - - #include - -+bool open_dbc(android::base::unique_fd* bulk_out, android::base::unique_fd* bulk_in); - bool open_functionfs(android::base::unique_fd* control, android::base::unique_fd* bulk_out, - android::base::unique_fd* bulk_in); -diff --git a/transport.cpp b/transport.cpp -index 35db37c7..b00edea0 100644 ---- a/transport.cpp -+++ b/transport.cpp -@@ -1507,6 +1507,117 @@ bool validate_transport_list(const std::list& list, const std::stri - return true; - } - -+DbcConnection::DbcConnection(unique_fd bulk_out, unique_fd bulk_in, -+ std::promise destruction_notifier) : -+ bulk_out_(std::move(bulk_out)), bulk_in_(std::move(bulk_in)), -+ destruction_notifier_(std::move(destruction_notifier)) { -+ LOG(INFO) << "DbcConnection being constructed"; -+} -+ -+DbcConnection::~DbcConnection() { -+ LOG(INFO) << "DbcConnection being destroyed"; -+ destruction_notifier_.set_value(); -+} -+ -+bool DbcConnection::DispatchRead(void* buf, size_t len) { -+ return ReadFdExactly(bulk_out_.get(), buf, len); -+} -+ -+bool DbcConnection::DispatchWrite(void* buf, size_t len) { -+ return WriteFdExactly(bulk_in_.get(), buf, len); -+} -+ -+bool DbcConnection::Read(apacket* packet) { -+ if (!DispatchRead(&packet->msg, sizeof(amessage))) { -+ D("remote local: read terminated (message)"); -+ return false; -+ } -+ -+ if (packet->msg.data_length > MAX_PAYLOAD) { -+ D("remote local: read overflow (data length = %" PRIu32 ")", packet->msg.data_length); -+ return false; -+ } -+ -+ packet->payload.resize(packet->msg.data_length); -+ -+ if (!DispatchRead(&packet->payload[0], packet->payload.size())) { -+ D("remote local: terminated (data)"); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool DbcConnection::Write(apacket* packet) { -+ if (!DispatchWrite(&packet->msg, sizeof(packet->msg))) { -+ D("remote local: write terminated"); -+ return false; -+ } -+ -+ if (packet->msg.data_length) { -+ if (!DispatchWrite(&packet->payload[0], packet->msg.data_length)) { -+ D("remote local: write terminated"); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+bool DbcConnection::DoTlsHandshake(RSA* key, std::string* auth_key) { -+ return true; -+} -+ -+void DbcConnection::Close() { -+ adb_shutdown(bulk_out_.get()); -+ adb_shutdown(bulk_in_.get()); -+ bulk_out_.reset(); -+ bulk_in_.reset(); -+} -+ -+bool register_dbc_transport(unique_fd bulk_out, unique_fd bulk_in, std::string serial) { -+ atransport* t = new atransport(); -+ t->serial = std::move(serial); -+ -+ std::promise destruction_notifier; -+ std::future future = destruction_notifier.get_future(); -+ -+ t->type = kTransportUsb; -+ -+ auto dbc_connection = std::make_unique(std::move(bulk_out), std::move(bulk_in), -+ std::move(destruction_notifier)); -+ t->SetConnection(std::make_unique(std::move(dbc_connection))); -+ -+ std::unique_lock lock(transport_lock); -+ for (const auto& transport : pending_list) { -+ if (t->serial == transport->serial) { -+ VLOG(TRANSPORT) << "DbC transport " << transport->serial -+ << " is already in pending_list and fails to register"; -+ delete t; -+ return false; -+ } -+ } -+ -+ for (const auto& transport : transport_list) { -+ if (t->serial == transport->serial) { -+ VLOG(TRANSPORT) << "DbC transport " << transport->serial -+ << " is already in transport_list and fails to register"; -+ delete t; -+ return false; -+ } -+ } -+ -+ pending_list.push_front(t); -+ -+ lock.unlock(); -+ -+ register_transport(t); -+ -+ future.wait(); -+ -+ return true; -+} -+ - bool register_socket_transport(unique_fd s, std::string serial, int port, int local, - atransport::ReconnectCallback reconnect, bool use_tls, int* error) { - atransport* t = new atransport(std::move(reconnect), kCsOffline); -diff --git a/transport.h b/transport.h -index fc0e322d..c234c9d0 100644 ---- a/transport.h -+++ b/transport.h -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -192,6 +193,28 @@ struct BlockingConnectionAdapter : public Connection { - std::once_flag error_flag_; - }; - -+struct DbcConnection : public BlockingConnection { -+ explicit DbcConnection(unique_fd bulk_out, unique_fd bulk_in, std::promise destruction_notifier); -+ ~DbcConnection(); -+ -+ bool Read(apacket* packet) override final; -+ bool Write(apacket* packet) override final; -+ bool DoTlsHandshake(RSA* key, std::string* auth_key) override final; -+ -+ void Close() override; -+ virtual void Reset() override final { Close(); } -+ -+ private: -+ bool DispatchRead(void* buf, size_t len); -+ bool DispatchWrite(void* buf, size_t len); -+ -+ unique_fd bulk_out_; -+ unique_fd bulk_in_; -+ std::unique_ptr tls_; -+ -+ std::promise destruction_notifier_; -+}; -+ - struct FdConnection : public BlockingConnection { - explicit FdConnection(unique_fd fd); - ~FdConnection(); -@@ -513,6 +536,8 @@ bool register_socket_transport(unique_fd s, std::string serial, int port, int lo - atransport::ReconnectCallback reconnect, bool use_tls, - int* error = nullptr); - -+bool register_dbc_transport(unique_fd bulk_out, unique_fd bulk_in, std::string serial); -+ - bool check_header(apacket* p, atransport* t); - - void close_usb_devices(bool reset = false); --- -2.17.1 - diff --git a/aosp_diff/preliminary/packages/providers/DownloadProvider/0001-Consolidate-queryChildDocumentsXxx-implementations.bulletin.patch b/aosp_diff/preliminary/packages/providers/DownloadProvider/0001-Consolidate-queryChildDocumentsXxx-implementations.bulletin.patch deleted file mode 100644 index 382fdb045d..0000000000 --- a/aosp_diff/preliminary/packages/providers/DownloadProvider/0001-Consolidate-queryChildDocumentsXxx-implementations.bulletin.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 5acd646e0cf63e2c9c0862da7e03531ef0074394 Mon Sep 17 00:00:00 2001 -From: Sergey Nikolaienkov -Date: Mon, 3 Jul 2023 17:09:28 +0200 -Subject: [PATCH] Consolidate queryChildDocumentsXxx() implementations - -Make sure to override the single right variant of the -FileSystemProvider#queryChildDocuments() method: the one that takes the -"includeHidden" boolean argument. - -Bug: 200034476 -Bug: 220066255 -Bug: 283962634 -Test: make, install and run manually -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:eae60a878ffa8eafe854539d3381ceba9ff6cca4) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:7a75edeba64b72058e143801ada107cb2a610632) -Merged-In: I4c00693e28f3d50d716350a65e9e6bfd7482b085 -Change-Id: I4c00693e28f3d50d716350a65e9e6bfd7482b085 ---- - .../downloads/DownloadStorageProvider.java | 38 ++++++------------- - 1 file changed, 12 insertions(+), 26 deletions(-) - -diff --git a/src/com/android/providers/downloads/DownloadStorageProvider.java b/src/com/android/providers/downloads/DownloadStorageProvider.java -index 421c2613..f5ba1e5d 100644 ---- a/src/com/android/providers/downloads/DownloadStorageProvider.java -+++ b/src/com/android/providers/downloads/DownloadStorageProvider.java -@@ -307,39 +307,26 @@ public class DownloadStorageProvider extends FileSystemProvider { - } - - @Override -- public Cursor queryChildDocuments(String parentDocId, String[] projection, String sortOrder) -- throws FileNotFoundException { -- return queryChildDocuments(parentDocId, projection, sortOrder, false); -- } -- -- @Override -- public Cursor queryChildDocumentsForManage( -- String parentDocId, String[] projection, String sortOrder) -- throws FileNotFoundException { -- return queryChildDocuments(parentDocId, projection, sortOrder, true); -- } -- -- private Cursor queryChildDocuments(String parentDocId, String[] projection, -- String sortOrder, boolean manage) throws FileNotFoundException { -- -+ protected Cursor queryChildDocuments(String documentId, String[] projection, String sortOrder, -+ boolean includeHidden) throws FileNotFoundException { - // Delegate to real provider - final long token = Binder.clearCallingIdentity(); - Cursor cursor = null; - try { -- if (RawDocumentsHelper.isRawDocId(parentDocId)) { -- return super.queryChildDocuments(parentDocId, projection, sortOrder); -+ if (RawDocumentsHelper.isRawDocId(documentId)) { -+ return super.queryChildDocuments(documentId, projection, sortOrder, includeHidden); - } - - final DownloadsCursor result = new DownloadsCursor(projection, - getContext().getContentResolver()); - final ArrayList notificationUris = new ArrayList<>(); -- if (isMediaStoreDownloadDir(parentDocId)) { -+ if (isMediaStoreDownloadDir(documentId)) { - includeDownloadsFromMediaStore(result, null /* queryArgs */, - null /* filePaths */, notificationUris, -- getMediaStoreIdString(parentDocId), NO_LIMIT, manage); -+ getMediaStoreIdString(documentId), NO_LIMIT, includeHidden); - } else { -- assert (DOC_ID_ROOT.equals(parentDocId)); -- if (manage) { -+ assert (DOC_ID_ROOT.equals(documentId)); -+ if (includeHidden) { - cursor = mDm.query( - new DownloadManager.Query().setOnlyIncludeVisibleInDownloadsUi(true)); - } else { -@@ -354,7 +341,7 @@ public class DownloadStorageProvider extends FileSystemProvider { - notificationUris.add(cursor.getNotificationUri()); - includeDownloadsFromMediaStore(result, null /* queryArgs */, - filePaths, notificationUris, -- null /* parentId */, NO_LIMIT, manage); -+ null /* parentId */, NO_LIMIT, includeHidden); - includeFilesFromSharedStorage(result, filePaths, null); - } - result.setNotificationUris(getContext().getContentResolver(), notificationUris); -@@ -476,12 +463,11 @@ public class DownloadStorageProvider extends FileSystemProvider { - return result; - } - -- private void includeSearchFilesFromSharedStorage(DownloadsCursor result, -- String[] projection, Set filePaths, -- Bundle queryArgs) throws FileNotFoundException { -+ private void includeSearchFilesFromSharedStorage(DownloadsCursor result, String[] projection, -+ Set filePaths, Bundle queryArgs) throws FileNotFoundException { - final File downloadDir = getPublicDownloadsDirectory(); - try (Cursor rawFilesCursor = super.querySearchDocuments(downloadDir, -- projection, filePaths, queryArgs)) { -+ projection, /* exclusion */ filePaths, queryArgs)) { - - final boolean shouldExcludeMedia = queryArgs.getBoolean( - DocumentsContract.QUERY_ARG_EXCLUDE_MEDIA, false /* defaultValue */); --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/packages/providers/MediaProvider/0001-Prevent-insertion-in-other-users-storage-volumes.bulletin.patch b/aosp_diff/preliminary/packages/providers/MediaProvider/0001-Prevent-insertion-in-other-users-storage-volumes.bulletin.patch deleted file mode 100644 index e749a8786f..0000000000 --- a/aosp_diff/preliminary/packages/providers/MediaProvider/0001-Prevent-insertion-in-other-users-storage-volumes.bulletin.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 520edca27f2da9671ce78de4faf501bcdadf7b4c Mon Sep 17 00:00:00 2001 -From: Omar Eissa -Date: Mon, 15 Apr 2024 12:04:56 +0000 -Subject: [PATCH] Prevent insertion in other users storage volumes - -Don't allow file insertion in other users storage volumes. -This was already handled if DATA was explicitly set in content values, -but was allowed if DATA was generated based on other values like RELATIVE_PATH and DISPLAY_NAME. - -Insertion of files in other users storage volumes can be used by malicious apps -to get access to other users files, since the same file would exist in both users MP databases -which would lead to MP falsely assuming that the user has access to this file. - -Bug: 294406604 -Test: atest MediaProviderTests -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df39f8486b25473d0bdbeed896ad917e3c793bf9) -Merged-In: Ie219bbdbe28819421040e4c083b65ab47d8ebde6 -Change-Id: Ie219bbdbe28819421040e4c083b65ab47d8ebde6 ---- - src/com/android/providers/media/MediaProvider.java | 1 + - tests/src/com/android/providers/media/MediaProviderTest.java | 5 ++--- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/com/android/providers/media/MediaProvider.java b/src/com/android/providers/media/MediaProvider.java -index 7aa43dbcb..693c5f57f 100644 ---- a/src/com/android/providers/media/MediaProvider.java -+++ b/src/com/android/providers/media/MediaProvider.java -@@ -4169,6 +4169,7 @@ public class MediaProvider extends ContentProvider { - - FileUtils.sanitizeValues(values, /*rewriteHiddenFileName*/ !isFuseThread()); - FileUtils.computeDataFromValues(values, volumePath, isFuseThread()); -+ assertFileColumnsConsistent(match, uri, values); - - // Create result file - File res = new File(values.getAsString(MediaColumns.DATA)); -diff --git a/tests/src/com/android/providers/media/MediaProviderTest.java b/tests/src/com/android/providers/media/MediaProviderTest.java -index 823e9018f..c74fb7c58 100644 ---- a/tests/src/com/android/providers/media/MediaProviderTest.java -+++ b/tests/src/com/android/providers/media/MediaProviderTest.java -@@ -410,9 +410,8 @@ public class MediaProviderTest { - @Test - public void testInsertionWithInvalidFilePath_throwsIllegalArgumentException() { - final ContentValues values = new ContentValues(); -- values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example"); -- values.put(MediaStore.Images.Media.DISPLAY_NAME, -- "./../../../../../../../../../../../data/media/test.txt"); -+ values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Android/media/com.example/"); -+ values.put(MediaStore.Images.Media.DISPLAY_NAME, "data/media/test.txt"); - - IllegalArgumentException illegalArgumentException = Assert.assertThrows( - IllegalArgumentException.class, () -> sIsolatedResolver.insert( --- -2.45.0.rc1.225.g2a3ae87e7f-goog - diff --git a/aosp_diff/preliminary/system/core/01_1-Add-support-for-creation-of-usb-pri.patch b/aosp_diff/preliminary/system/core/01_1-Add-support-for-creation-of-usb-pri.patch index 2c147b9b40..cd429f6369 100644 --- a/aosp_diff/preliminary/system/core/01_1-Add-support-for-creation-of-usb-pri.patch +++ b/aosp_diff/preliminary/system/core/01_1-Add-support-for-creation-of-usb-pri.patch @@ -1,4 +1,4 @@ -From 8f4cca64bf2117f4f62667ce6603db028fb5f740 Mon Sep 17 00:00:00 2001 +From 5b9d851c82ec89bd6d309e9638251fc65430e157 Mon Sep 17 00:00:00 2001 From: Tanuj Tekriwal Date: Mon, 24 Feb 2020 11:49:20 +0530 Subject: [PATCH] Add support for creation of usb printer in android @@ -15,10 +15,10 @@ Signed-off-by: Tanuj Tekriwal 2 files changed, 5 insertions(+) diff --git a/init/devices.cpp b/init/devices.cpp -index 9fbec641b..07adfb80c 100644 +index 5560c20bcb..a8fafdc367 100644 --- a/init/devices.cpp +++ b/init/devices.cpp -@@ -492,6 +492,10 @@ void DeviceHandler::HandleUevent(const Uevent& uevent) { +@@ -576,6 +576,10 @@ void DeviceHandler::HandleUevent(const Uevent& uevent) { int device_id = uevent.minor % 128 + 1; devpath = StringPrintf("/dev/bus/usb/%03d/%03d", bus_id, device_id); } @@ -30,17 +30,17 @@ index 9fbec641b..07adfb80c 100644 // ignore other USB events return; diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc -index 9c2cdf27f..45ab2ca59 100644 +index 3927501a47..833d780c20 100644 --- a/rootdir/ueventd.rc +++ b/rootdir/ueventd.rc -@@ -37,6 +37,7 @@ subsystem sound +@@ -48,6 +48,7 @@ subsystem vfio /dev/binder 0666 root root /dev/hwbinder 0666 root root /dev/vndbinder 0666 root root -+/dev/usb/lp* 0666 root root ++/dev/usb/lp* 0666 root root + /dev/vfio/* 0666 root root /dev/pmsg0 0222 root log - -- -2.21.0 +2.34.1 diff --git a/aosp_diff/preliminary/system/core/02_2-Fixed-Boot-Issue-in-First-Stage-Init.patch b/aosp_diff/preliminary/system/core/02_2-Fixed-Boot-Issue-in-First-Stage-Init.patch deleted file mode 100644 index 1f0e62f1e7..0000000000 --- a/aosp_diff/preliminary/system/core/02_2-Fixed-Boot-Issue-in-First-Stage-Init.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 86dd09dcd97dc80df5919d1a7285011217daae99 Mon Sep 17 00:00:00 2001 -From: Ankit Agrawal -Date: Mon, 19 Jun 2023 09:14:54 +0530 -Subject: [PATCH] Fixed Boot Issue in First Stage Init. - -During first stage init boot, it tries to symlink between /system/bin/snapuserd -and /first_stage_ramdisk/system/bin/snapuserd and it fails because -it already is creating symlink during build time. - -Removing symlink creation at build time. - -Tracked-On: OAM-110092 -Change-Id: Ib3db21eab03d29ffc7ff6b0c383d96786fbe9ffc -Signed-off-by: Ankit Agrawal ---- - fs_mgr/libsnapshot/snapuserd/Android.bp | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/fs_mgr/libsnapshot/snapuserd/Android.bp b/fs_mgr/libsnapshot/snapuserd/Android.bp -index 9261482017..749216cdce 100644 ---- a/fs_mgr/libsnapshot/snapuserd/Android.bp -+++ b/fs_mgr/libsnapshot/snapuserd/Android.bp -@@ -159,7 +159,6 @@ cc_binary { - ramdisk_available: true, - vendor_ramdisk_available: false, - ramdisk: true, -- symlinks: ["snapuserd"], - } - - cc_test { --- -2.17.1 - diff --git a/aosp_diff/preliminary/system/core/03_0003-Add-seal-if-ashmem-dev-is-backed-by-memfd.bulletin.patch b/aosp_diff/preliminary/system/core/03_0003-Add-seal-if-ashmem-dev-is-backed-by-memfd.bulletin.patch deleted file mode 100644 index 835db55f51..0000000000 --- a/aosp_diff/preliminary/system/core/03_0003-Add-seal-if-ashmem-dev-is-backed-by-memfd.bulletin.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 46d46dc46446f14f26fbe8fb102dd36c1dfc1229 Mon Sep 17 00:00:00 2001 -From: Keith Mok -Date: Thu, 31 Aug 2023 00:31:35 +0000 -Subject: [PATCH] Add seal if ashmem-dev is backed by memfd - -Need to seal the buffer size in align with ashmem if set to PROT_READ -only to prevent untrusted remote process to shrink the buffer size and -crash it. - -Bug: 294609150 -Test: build -Ignore-AOSP-First: Security -(cherry picked from commit f83c5c8fecf89d9315945368aa20350c2f235cc0) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:61a2897733e15a12b7aa2dfd99957e83cbe59351) -Merged-In: I9288cf30b41e84ad8d3247c204e20482912bff69 -Change-Id: I9288cf30b41e84ad8d3247c204e20482912bff69 ---- - libcutils/ashmem-dev.cpp | 29 +++++++++++++++++++++++++---- - 1 file changed, 25 insertions(+), 4 deletions(-) - -diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp -index 6a27f9a20..56d68759f 100644 ---- a/libcutils/ashmem-dev.cpp -+++ b/libcutils/ashmem-dev.cpp -@@ -349,6 +349,12 @@ static int memfd_create_region(const char* name, size_t size) { - return -1; - } - -+ // forbid size changes to match ashmem behaviour -+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK) == -1) { -+ ALOGE("memfd_create(%s, %zd) F_ADD_SEALS failed: %m", name, size); -+ return -1; -+ } -+ - if (debug_log) { - ALOGE("memfd_create(%s, %zd) success. fd=%d\n", name, size, fd.get()); - } -@@ -400,14 +406,29 @@ error: - } - - static int memfd_set_prot_region(int fd, int prot) { -- /* Only proceed if an fd needs to be write-protected */ -+ int seals = fcntl(fd, F_GET_SEALS); -+ if (seals == -1) { -+ ALOGE("memfd_set_prot_region(%d, %d): F_GET_SEALS failed: %s\n", fd, prot, strerror(errno)); -+ return -1; -+ } -+ - if (prot & PROT_WRITE) { -+ /* Now we want the buffer to be read-write, let's check if the buffer -+ * has been previously marked as read-only before, if so return error -+ */ -+ if (seals & F_SEAL_FUTURE_WRITE) { -+ ALOGE("memfd_set_prot_region(%d, %d): region is write protected\n", fd, prot); -+ errno = EINVAL; // inline with ashmem error code, if already in -+ // read-only mode -+ return -1; -+ } - return 0; - } - -- if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE) == -1) { -- ALOGE("memfd_set_prot_region(%d, %d): F_SEAL_FUTURE_WRITE seal failed: %s\n", fd, prot, -- strerror(errno)); -+ /* We would only allow read-only for any future file operations */ -+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE | F_SEAL_SEAL) == -1) { -+ ALOGE("memfd_set_prot_region(%d, %d): F_SEAL_FUTURE_WRITE | F_SEAL_SEAL seal failed: %s\n", -+ fd, prot, strerror(errno)); - return -1; - } - --- -2.43.0.195.gebba966016-goog - diff --git a/aosp_diff/preliminary/system/libfmq/0001-Use-the-values-of-the-ptrs-that-we-check.bulletin.patch b/aosp_diff/preliminary/system/libfmq/0001-Use-the-values-of-the-ptrs-that-we-check.bulletin.patch deleted file mode 100644 index 52ef2d6321..0000000000 --- a/aosp_diff/preliminary/system/libfmq/0001-Use-the-values-of-the-ptrs-that-we-check.bulletin.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 7903ae2f7f31a485d6a7ea24bed5cf9fa61e55ed Mon Sep 17 00:00:00 2001 -From: Devin Moore -Date: Mon, 22 Jan 2024 17:52:16 +0000 -Subject: [PATCH] Use the values of the ptrs that we check - -Test: fmq_fuzzer -Bug: 321326147 -Bug: 321341508 -Bug: 321383085 -(cherry picked from https://android-review.googlesource.com/q/commit:38963310ad5789b625ca0bca9f9c2c8e24666651) -(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:da080aa565f0cd1158bde3b8100dc73604959035) -Merged-In: I56fe4fe72180e39ecef066353969c1ae9fbcd44e -Change-Id: I56fe4fe72180e39ecef066353969c1ae9fbcd44e ---- - include/fmq/MessageQueueBase.h | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/include/fmq/MessageQueueBase.h b/include/fmq/MessageQueueBase.h -index f99e335..7a027ec 100644 ---- a/include/fmq/MessageQueueBase.h -+++ b/include/fmq/MessageQueueBase.h -@@ -1044,8 +1044,16 @@ bool MessageQueueBase::readBlocking(T* data, size_t - } - - template