summaryrefslogtreecommitdiff
path: root/cmds
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2024-11-13 13:57:20 -0800
committer Xin Li <delphij@google.com> 2024-11-13 14:01:00 -0800
commitde53d9657cd5e352984697fc130159c474e819a9 (patch)
tree79b7d2c74d20c83b9adaddfde7862240e4d3725e /cmds
parent70a1e5dcf316f8ddf6d1b3b00341c7a35a8dcc58 (diff)
parent8eecb1a1afe454e3233f27b06f9e5d41b5bec011 (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.cpp11
-rw-r--r--cmds/idmap2/idmap2d/Idmap2Service.h17
-rw-r--r--cmds/screencap/Android.bp1
-rw-r--r--cmds/screencap/screencap.cpp135
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;
}