OSDN Git Service

Perfprofd: Move dropbox code to its own static library
authorAndreas Gampe <agampe@google.com>
Wed, 28 Mar 2018 19:43:07 +0000 (12:43 -0700)
committerAndreas Gampe <agampe@google.com>
Fri, 30 Mar 2018 03:52:12 +0000 (20:52 -0700)
Preparation to move this to generic code.

(cherry picked from commit db1628647e81dc2d9a62471d4f3b78c84069040e)

Bug: 73175642
Test: mmma system/extras/perfprofd
Test: perfprofd_test
Merged-In: I2cad55f201ff8af9acfe8e8e34c6bafea8ef1285
Change-Id: I2cad55f201ff8af9acfe8e8e34c6bafea8ef1285

perfprofd/binder_interface/Android.bp
perfprofd/binder_interface/perfprofd_binder.cc
perfprofd/dropbox/Android.bp [new file with mode: 0644]
perfprofd/dropbox/dropbox.cc [new file with mode: 0644]
perfprofd/dropbox/dropbox.h [new file with mode: 0644]
perfprofd/dropbox/dropbox_host.cc [new file with mode: 0644]

index d7bff41..4ec851d 100644 (file)
@@ -30,8 +30,8 @@ cc_library_static {
         "libperfprofdcore",
         "libprotobuf-cpp-lite",
     ],
-    shared_libs: [
-        "libservices",
+    whole_static_libs: [
+        "libperfprofd_dropbox",
     ],
     srcs: [
         "perfprofd_binder.cc",
index eeb5360..3047620 100644 (file)
@@ -35,7 +35,6 @@
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
-#include <android/os/DropBoxManager.h>
 #include <binder/BinderService.h>
 #include <binder/IResultReceiver.h>
 #include <binder/Status.h>
@@ -49,6 +48,7 @@
 #include "perfprofd_record.pb.h"
 
 #include "config.h"
+#include "dropbox.h"
 #include "perfprofdcore.h"
 #include "perfprofd_io.h"
 
@@ -151,79 +151,21 @@ class PerfProfdNativeService : public BinderService<PerfProfdNativeService>,
   int seq_ = 0;
 };
 
-static Status WriteDropboxFile(android::perfprofd::PerfprofdRecord* encodedProfile,
-                               Config* config) {
-  android::base::unique_fd tmp_fd;
-  {
-    char path[PATH_MAX];
-    snprintf(path,
-             sizeof(path),
-             "%s%cdropboxtmp-XXXXXX",
-             config->destination_directory.c_str(),
-             OS_PATH_SEPARATOR);
-    tmp_fd.reset(mkstemp(path));
-    if (tmp_fd.get() == -1) {
-      PLOG(ERROR) << "Could not create temp file " << path;
-      return Status::fromExceptionCode(1, "Could not create temp file");
-    }
-    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) {
-      PLOG(ERROR) << "Could not create read-only fd";
-      return Status::fromExceptionCode(1, "Could not create read-only fd");
-    }
-  }
-
-  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)) {
-    return Status::fromExceptionCode(1, "Could not serialize to temp file");
-  }
-
-  sp<DropBoxManager> dropbox(new DropBoxManager());
-  return dropbox->addFile(String16("perfprofd"), read_only.release(), kDropboxFlags);
-}
-
 bool PerfProfdNativeService::BinderHandler(
     android::perfprofd::PerfprofdRecord* encodedProfile,
     Config* config) {
   CHECK(config != nullptr);
+  if (encodedProfile == nullptr) {
+    return false;
+  }
+
   if (static_cast<BinderConfig*>(config)->send_to_dropbox) {
-    size_t size = encodedProfile->ByteSize();
-    Status status;
-    if (size < 1024 * 1024) {
-      // For a small size, send as a byte buffer directly.
-      std::unique_ptr<uint8_t[]> data(new uint8_t[size]);
-      encodedProfile->SerializeWithCachedSizesToArray(data.get());
-
-      using DropBoxManager = android::os::DropBoxManager;
-      sp<DropBoxManager> dropbox(new DropBoxManager());
-      status = dropbox->addData(String16("perfprofd"),
-                                data.get(),
-                                size,
-                                0);
-    } else {
-      // For larger buffers, we need to go through the filesystem.
-      status = WriteDropboxFile(encodedProfile, config);
+    std::string error_msg;
+    if (!dropbox::SendToDropbox(encodedProfile, config->destination_directory, &error_msg)) {
+      LOG(WARNING) << "Failed dropbox submission: " << error_msg;
+      return false;
     }
-    if (!status.isOk()) {
-      LOG(WARNING) << "Failed dropbox submission: " << status.toString8();
-    }
-    return status.isOk();
+    return true;
   }
 
   if (encodedProfile == nullptr) {
diff --git a/perfprofd/dropbox/Android.bp b/perfprofd/dropbox/Android.bp
new file mode 100644 (file)
index 0000000..72c749b
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// Copyright (C) 2018 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.
+//
+
+//
+// Static library for dropbox submission.
+//
+cc_library_static {
+    name: "libperfprofd_dropbox",
+    defaults: [
+        "perfprofd_defaults",
+    ],
+    host_supported: true,
+
+    export_include_dirs: ["."],
+    static_libs: [
+        "libbase",
+        "libperfprofdcore",
+        "libprotobuf-cpp-lite",
+    ],
+    target: {
+        android: {
+            srcs: [
+                "dropbox.cc",
+            ],
+            static_libs: [
+                "libbinder",
+                "libutils",
+            ],
+            shared_libs: [
+                "libservices",
+            ],
+        },
+        host: {
+            srcs: [
+                "dropbox_host.cc",
+            ],
+        },
+    },
+}
diff --git a/perfprofd/dropbox/dropbox.cc b/perfprofd/dropbox/dropbox.cc
new file mode 100644 (file)
index 0000000..2b1dc2e
--- /dev/null
@@ -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
diff --git a/perfprofd/dropbox/dropbox.h b/perfprofd/dropbox/dropbox.h
new file mode 100644 (file)
index 0000000..b25d2cc
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright 2018, 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 SYSTEM_EXTRAS_PERFPROFD_DROPBOX_DROPBOX_H_
+#define SYSTEM_EXTRAS_PERFPROFD_DROPBOX_DROPBOX_H_
+
+#include <string>
+
+#include "perfprofd_record-fwd.h"
+
+namespace android {
+namespace perfprofd {
+namespace dropbox {
+
+bool SendToDropbox(android::perfprofd::PerfprofdRecord* profile,
+                   const std::string& temp_directory,
+                   std::string* error_msg);
+
+}  // namespace dropbox
+}  // namespace perfprofd
+}  // namespace android
+
+#endif  // SYSTEM_EXTRAS_PERFPROFD_DROPBOX_DROPBOX_H_
diff --git a/perfprofd/dropbox/dropbox_host.cc b/perfprofd/dropbox/dropbox_host.cc
new file mode 100644 (file)
index 0000000..5c08aa8
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright 2018, 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 <android-base/macros.h>
+
+namespace android {
+namespace perfprofd {
+namespace dropbox {
+
+bool SendToDropbox(android::perfprofd::PerfprofdRecord* profile,
+                   const std::string& temp_directory ATTRIBUTE_UNUSED,
+                   std::string* error_msg) {
+  *error_msg = "Dropbox not supported on host";
+  return false;
+}
+
+}  // namespace dropbox
+}  // namespace perfprofd
+}  // namespace android