summaryrefslogtreecommitdiff
path: root/perfprofd/dropbox/dropbox.cc
diff options
context:
space:
mode:
Diffstat (limited to 'perfprofd/dropbox/dropbox.cc')
-rw-r--r--perfprofd/dropbox/dropbox.cc129
1 files changed, 129 insertions, 0 deletions
diff --git a/perfprofd/dropbox/dropbox.cc b/perfprofd/dropbox/dropbox.cc
new file mode 100644
index 00000000..2b1dc2ef
--- /dev/null
+++ b/perfprofd/dropbox/dropbox.cc
@@ -0,0 +1,129 @@
+/*
+ *
+ * Copyright 2017, 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.
+ */
+
+#include "dropbox.h"
+
+#include <cstdio>
+#include <cstdlib>
+#include <memory>
+
+#include <inttypes.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+#include <android/os/DropBoxManager.h>
+#include <binder/Status.h>
+#include <utils/String8.h>
+
+#include "perfprofd_record.pb.h"
+
+#include "perfprofd_io.h"
+
+namespace android {
+namespace perfprofd {
+namespace dropbox {
+
+namespace {
+
+bool WriteDropboxFile(android::perfprofd::PerfprofdRecord* encodedProfile,
+ const std::string& temp_dir,
+ std::string* error_msg) {
+ android::base::unique_fd tmp_fd;
+ {
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "%s/dropboxtmp-XXXXXX", temp_dir.c_str());
+ tmp_fd.reset(mkstemp(path));
+ if (tmp_fd.get() == -1) {
+ *error_msg = android::base::StringPrintf("Could not create temp file %s: %s",
+ path,
+ strerror(errno));
+ return false;
+ }
+ if (unlink(path) != 0) {
+ PLOG(WARNING) << "Could not unlink binder temp file";
+ }
+ }
+
+ // Dropbox takes ownership of the fd, and if it is not readonly,
+ // a selinux violation will occur. Get a read-only version.
+ android::base::unique_fd read_only;
+ {
+ char fdpath[64];
+ snprintf(fdpath, arraysize(fdpath), "/proc/self/fd/%d", tmp_fd.get());
+ read_only.reset(open(fdpath, O_RDONLY | O_CLOEXEC));
+ if (read_only.get() < 0) {
+ *error_msg = android::base::StringPrintf("Could not create read-only fd: %s",
+ strerror(errno));
+ return false;
+ }
+ }
+
+ constexpr bool kCompress = true; // Ignore the config here. Dropbox will always end up
+ // compressing the data, might as well make the temp
+ // file smaller and help it out.
+ using DropBoxManager = android::os::DropBoxManager;
+ constexpr int kDropboxFlags = DropBoxManager::IS_GZIPPED;
+
+ if (!SerializeProtobuf(encodedProfile, std::move(tmp_fd), kCompress)) {
+ *error_msg = "Could not serialize to temp file";
+ return false;
+ }
+
+ sp<DropBoxManager> dropbox(new DropBoxManager());
+ android::binder::Status status = dropbox->addFile(String16("perfprofd"),
+ read_only.release(),
+ kDropboxFlags);
+ if (!status.isOk()) {
+ *error_msg = status.toString8();
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+bool SendToDropbox(android::perfprofd::PerfprofdRecord* profile,
+ const std::string& temp_directory,
+ std::string* error_msg) {
+ size_t size = profile->ByteSize();
+ if (size < 1024 * 1024) {
+ // For a small size, send as a byte buffer directly.
+ std::unique_ptr<uint8_t[]> data(new uint8_t[size]);
+ profile->SerializeWithCachedSizesToArray(data.get());
+
+ using DropBoxManager = android::os::DropBoxManager;
+ sp<DropBoxManager> dropbox(new DropBoxManager());
+ android::binder::Status status = dropbox->addData(String16("perfprofd"),
+ data.get(),
+ size,
+ 0);
+ if (!status.isOk()) {
+ *error_msg = status.toString8();
+ return false;
+ }
+ return true;
+ } else {
+ // For larger buffers, we need to go through the filesystem.
+ return WriteDropboxFile(profile, temp_directory, error_msg);
+ }
+}
+
+} // namespace dropbox
+} // namespace perfprofd
+} // namespace android