diff options
author | 2024-11-13 13:57:20 -0800 | |
---|---|---|
committer | 2024-11-13 14:01:00 -0800 | |
commit | de53d9657cd5e352984697fc130159c474e819a9 (patch) | |
tree | 79b7d2c74d20c83b9adaddfde7862240e4d3725e /cmds | |
parent | 70a1e5dcf316f8ddf6d1b3b00341c7a35a8dcc58 (diff) | |
parent | 8eecb1a1afe454e3233f27b06f9e5d41b5bec011 (diff) |
Merge 24Q4 (ab/12406339) into aosp-main-future
Bug: 370570306
Merged-In: Ic2ffd5a1f4420121b958cadb726c3e805cda1434
Change-Id: If0f7008f8e699bf1fca8d20ee5e05877a61ea002
Diffstat (limited to 'cmds')
-rw-r--r-- | cmds/idmap2/idmap2d/Idmap2Service.cpp | 11 | ||||
-rw-r--r-- | cmds/idmap2/idmap2d/Idmap2Service.h | 17 | ||||
-rw-r--r-- | cmds/screencap/Android.bp | 1 | ||||
-rw-r--r-- | cmds/screencap/screencap.cpp | 135 |
4 files changed, 116 insertions, 48 deletions
diff --git a/cmds/idmap2/idmap2d/Idmap2Service.cpp b/cmds/idmap2/idmap2d/Idmap2Service.cpp index f264125cfde5..6902d6db6751 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.cpp +++ b/cmds/idmap2/idmap2d/Idmap2Service.cpp @@ -78,6 +78,11 @@ PolicyBitmask ConvertAidlArgToPolicyBitmask(int32_t arg) { namespace android::os { +template <typename T> +const T* Idmap2Service::GetPointer(const OwningPtr<T>& ptr) { + return std::visit([](auto&& ptr) { return ptr.get(); }, ptr); +} + Status Idmap2Service::getIdmapPath(const std::string& overlay_path, int32_t user_id ATTRIBUTE_UNUSED, std::string* _aidl_return) { assert(_aidl_return); @@ -224,7 +229,7 @@ idmap2::Result<Idmap2Service::TargetResourceContainerPtr> Idmap2Service::GetTarg if (is_framework || (item.dev == st.st_dev && item.inode == st.st_ino && item.size == st.st_size && item.mtime.tv_sec == st.st_mtim.tv_sec && item.mtime.tv_nsec == st.st_mtim.tv_nsec)) { - return {item.apk.get()}; + return {item.apk}; } container_cache_.erase(cache_it); } @@ -238,14 +243,14 @@ idmap2::Result<Idmap2Service::TargetResourceContainerPtr> Idmap2Service::GetTarg return {std::move(*target)}; } - const auto res = target->get(); + auto res = std::shared_ptr(std::move(*target)); std::lock_guard lock(container_cache_mutex_); container_cache_.emplace(target_path, CachedContainer { .dev = dev_t(st.st_dev), .inode = ino_t(st.st_ino), .size = st.st_size, .mtime = st.st_mtim, - .apk = std::move(*target) + .apk = res }); return {res}; } diff --git a/cmds/idmap2/idmap2d/Idmap2Service.h b/cmds/idmap2/idmap2d/Idmap2Service.h index a69fa6119974..272ec6be3bac 100644 --- a/cmds/idmap2/idmap2d/Idmap2Service.h +++ b/cmds/idmap2/idmap2d/Idmap2Service.h @@ -85,7 +85,7 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { ino_t inode; int64_t size; struct timespec mtime; - std::unique_ptr<idmap2::TargetResourceContainer> apk; + std::shared_ptr<idmap2::TargetResourceContainer> apk; }; std::unordered_map<std::string, CachedContainer> container_cache_; std::mutex container_cache_mutex_; @@ -95,24 +95,15 @@ class Idmap2Service : public BinderService<Idmap2Service>, public BnIdmap2 { std::mutex frro_iter_mutex_; template <typename T> - using MaybeUniquePtr = std::variant<std::unique_ptr<T>, T*>; + using OwningPtr = std::variant<std::unique_ptr<T>, std::shared_ptr<T>>; - using TargetResourceContainerPtr = MaybeUniquePtr<idmap2::TargetResourceContainer>; + using TargetResourceContainerPtr = OwningPtr<idmap2::TargetResourceContainer>; idmap2::Result<TargetResourceContainerPtr> GetTargetContainer(const std::string& target_path); template <typename T> - WARN_UNUSED static const T* GetPointer(const MaybeUniquePtr<T>& ptr); + WARN_UNUSED static const T* GetPointer(const OwningPtr<T>& ptr); }; -template <typename T> -const T* Idmap2Service::GetPointer(const MaybeUniquePtr<T>& ptr) { - auto u = std::get_if<T*>(&ptr); - if (u != nullptr) { - return *u; - } - return std::get<std::unique_ptr<T>>(ptr).get(); -} - } // namespace android::os #endif // IDMAP2_IDMAP2D_IDMAP2SERVICE_H_ diff --git a/cmds/screencap/Android.bp b/cmds/screencap/Android.bp index c009c1f5b08b..16026eca2980 100644 --- a/cmds/screencap/Android.bp +++ b/cmds/screencap/Android.bp @@ -17,6 +17,7 @@ cc_binary { "libutils", "libbinder", "libjnigraphics", + "libhwui", "libui", "libgui", ], diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index 7e4f95bc9274..12de82a46263 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -14,35 +14,29 @@ * limitations under the License. */ -#include <errno.h> -#include <unistd.h> -#include <stdio.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> - -#include <linux/fb.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/wait.h> - #include <android/bitmap.h> - +#include <android/graphics/bitmap.h> +#include <android/gui/DisplayCaptureArgs.h> #include <binder/ProcessState.h> - +#include <errno.h> +#include <fcntl.h> #include <ftl/concat.h> #include <ftl/optional.h> -#include <gui/DisplayCaptureArgs.h> +#include <getopt.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <gui/SyncScreenCaptureListener.h> - +#include <linux/fb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/wait.h> +#include <system/graphics.h> #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> -#include <system/graphics.h> - using namespace android; #define COLORSPACE_UNKNOWN 0 @@ -83,11 +77,12 @@ enum { }; } -static const struct option LONG_OPTIONS[] = { - {"png", no_argument, nullptr, 'p'}, - {"help", no_argument, nullptr, 'h'}, - {"hint-for-seamless", no_argument, nullptr, LongOpts::HintForSeamless}, - {0, 0, 0, 0}}; +static const struct option LONG_OPTIONS[] = {{"png", no_argument, nullptr, 'p'}, + {"jpeg", no_argument, nullptr, 'j'}, + {"help", no_argument, nullptr, 'h'}, + {"hint-for-seamless", no_argument, nullptr, + LongOpts::HintForSeamless}, + {0, 0, 0, 0}}; static int32_t flinger2bitmapFormat(PixelFormat f) { @@ -168,10 +163,11 @@ status_t capture(const DisplayId displayId, return 0; } -status_t saveImage(const char* fn, bool png, const ScreenCaptureResults& captureResults) { +status_t saveImage(const char* fn, std::optional<AndroidBitmapCompressFormat> format, + const ScreenCaptureResults& captureResults) { void* base = nullptr; ui::Dataspace dataspace = captureResults.capturedDataspace; - sp<GraphicBuffer> buffer = captureResults.buffer; + const sp<GraphicBuffer>& buffer = captureResults.buffer; status_t result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base); @@ -186,22 +182,48 @@ status_t saveImage(const char* fn, bool png, const ScreenCaptureResults& capture return 1; } + void* gainmapBase = nullptr; + sp<GraphicBuffer> gainmap = captureResults.optionalGainMap; + + if (gainmap) { + result = gainmap->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &gainmapBase); + if (gainmapBase == nullptr || result != NO_ERROR) { + fprintf(stderr, "Failed to capture gainmap with error code (%d)\n", result); + gainmapBase = nullptr; + // Fall-through: just don't attempt to write the gainmap + } + } + int fd = -1; if (fn == nullptr) { fd = dup(STDOUT_FILENO); if (fd == -1) { fprintf(stderr, "Error writing to stdout. (%s)\n", strerror(errno)); + if (gainmapBase) { + gainmap->unlock(); + } + + if (base) { + buffer->unlock(); + } return 1; } } else { fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664); if (fd == -1) { fprintf(stderr, "Error opening file: %s (%s)\n", fn, strerror(errno)); + if (gainmapBase) { + gainmap->unlock(); + } + + if (base) { + buffer->unlock(); + } return 1; } } - if (png) { + if (format) { AndroidBitmapInfo info; info.format = flinger2bitmapFormat(buffer->getPixelFormat()); info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL; @@ -209,16 +231,31 @@ status_t saveImage(const char* fn, bool png, const ScreenCaptureResults& capture info.height = buffer->getHeight(); info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat()); - int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base, - ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd, + int result; + + if (gainmapBase) { + result = ABitmap_compressWithGainmap(&info, static_cast<ADataSpace>(dataspace), base, + gainmapBase, captureResults.hdrSdrRatio, *format, + 100, &fd, + [](void* fdPtr, const void* data, + size_t size) -> bool { + int bytesWritten = + write(*static_cast<int*>(fdPtr), data, + size); + return bytesWritten == size; + }); + } else { + result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base, *format, + 100, &fd, [](void* fdPtr, const void* data, size_t size) -> bool { int bytesWritten = write(*static_cast<int*>(fdPtr), data, size); return bytesWritten == size; }); + } if (result != ANDROID_BITMAP_RESULT_SUCCESS) { - fprintf(stderr, "Failed to compress PNG (error code: %d)\n", result); + fprintf(stderr, "Failed to compress (error code: %d)\n", result); } if (fn != NULL) { @@ -243,6 +280,14 @@ status_t saveImage(const char* fn, bool png, const ScreenCaptureResults& capture } close(fd); + if (gainmapBase) { + gainmap->unlock(); + } + + if (base) { + buffer->unlock(); + } + return 0; } @@ -260,13 +305,17 @@ int main(int argc, char** argv) gui::CaptureArgs captureArgs; const char* pname = argv[0]; bool png = false; + bool jpeg = false; bool all = false; int c; - while ((c = getopt_long(argc, argv, "aphd:", LONG_OPTIONS, nullptr)) != -1) { + while ((c = getopt_long(argc, argv, "apjhd:", LONG_OPTIONS, nullptr)) != -1) { switch (c) { case 'p': png = true; break; + case 'j': + jpeg = true; + break; case 'd': { errno = 0; char* end = nullptr; @@ -323,6 +372,14 @@ int main(int argc, char** argv) baseName = filename.substr(0, filename.size()-4); suffix = ".png"; png = true; + } else if (filename.ends_with(".jpeg")) { + baseName = filename.substr(0, filename.size() - 5); + suffix = ".jpeg"; + jpeg = true; + } else if (filename.ends_with(".jpg")) { + baseName = filename.substr(0, filename.size() - 4); + suffix = ".jpg"; + jpeg = true; } else { baseName = filename; } @@ -348,6 +405,20 @@ int main(int argc, char** argv) } } + if (png && jpeg) { + fprintf(stderr, "Ambiguous file type"); + return 1; + } + + std::optional<AndroidBitmapCompressFormat> format = std::nullopt; + + if (png) { + format = ANDROID_BITMAP_COMPRESS_FORMAT_PNG; + } else if (jpeg) { + format = ANDROID_BITMAP_COMPRESS_FORMAT_JPEG; + captureArgs.attachGainmap = true; + } + // setThreadPoolMaxThreadCount(0) actually tells the kernel it's // not allowed to spawn any additional threads, but we still spawn // a binder thread from userspace when we call startThreadPool(). @@ -383,7 +454,7 @@ int main(int argc, char** argv) if (!filename.empty()) { fn = filename.c_str(); } - if (const status_t saveImageStatus = saveImage(fn, png, result) != 0) { + if (const status_t saveImageStatus = saveImage(fn, format, result) != 0) { fprintf(stderr, "Saving image failed.\n"); return saveImageStatus; } |