Merge "Create user_de directory for user 0."
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index c13872a..73c8912 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -591,14 +591,15 @@
     std::vector<std::string> args;
     if (use_shell_protocol) {
         args.push_back(kShellServiceArgShellProtocol);
+
+        const char* terminal_type = getenv("TERM");
+        if (terminal_type != nullptr) {
+            args.push_back(std::string("TERM=") + terminal_type);
+        }
     }
     if (!type_arg.empty()) {
         args.push_back(type_arg);
     }
-    const char* terminal_type = getenv("TERM");
-    if (terminal_type != nullptr) {
-        args.push_back(std::string("TERM=") + terminal_type);
-    }
 
     // Shell service string can look like: shell[,arg1,arg2,...]:[command].
     return android::base::StringPrintf("shell%s%s:%s",
diff --git a/base/include/base/unique_fd.h b/base/include/base/unique_fd.h
new file mode 100644
index 0000000..4117775
--- /dev/null
+++ b/base/include/base/unique_fd.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2015 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 ANDROID_BASE_UNIQUE_FD_H
+#define ANDROID_BASE_UNIQUE_FD_H
+
+#include <unistd.h>
+
+#include <base/macros.h>
+
+/* Container for a file descriptor that automatically closes the descriptor as
+ * it goes out of scope.
+ *
+ *      unique_fd ufd(open("/some/path", "r"));
+ *
+ *      if (ufd.get() < 0) // invalid descriptor
+ *          return error;
+ *
+ *      // Do something useful
+ *
+ *      return 0; // descriptor is closed here
+ */
+namespace android {
+namespace base {
+
+class unique_fd final {
+ public:
+  unique_fd() : value_(-1) {}
+
+  explicit unique_fd(int value) : value_(value) {}
+  ~unique_fd() { clear(); }
+
+  unique_fd(unique_fd&& other) : value_(other.release()) {}
+  unique_fd& operator = (unique_fd&& s) {
+    reset(s.release());
+    return *this;
+  }
+
+  void reset(int new_value) {
+    if (value_ >= 0)
+      close(value_);
+    value_ = new_value;
+  }
+
+  void clear() {
+    reset(-1);
+  }
+
+  int get() const { return value_; }
+
+  int release() {
+    int ret = value_;
+    value_ = -1;
+    return ret;
+  }
+
+ private:
+  int value_;
+
+  DISALLOW_COPY_AND_ASSIGN(unique_fd);
+};
+
+}  // namespace base
+}  // namespace android
+
+#endif // ANDROID_BASE_UNIQUE_FD_H
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 582821d..3e618c0 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -40,8 +40,6 @@
 #define FAKE_BATTERY_CAPACITY 42
 #define FAKE_BATTERY_TEMPERATURE 424
 #define ALWAYS_PLUGGED_CAPACITY 100
-#define MILLION 10000000.0
-#define DEFAULT_VBUS_VOLTAGE 5000000
 
 namespace android {
 
@@ -190,7 +188,6 @@
     props.batteryStatus = BATTERY_STATUS_UNKNOWN;
     props.batteryHealth = BATTERY_HEALTH_UNKNOWN;
     props.maxChargingCurrent = 0;
-    props.maxChargingVoltage = 0;
 
     if (!mHealthdConfig->batteryPresentPath.isEmpty())
         props.batteryPresent = getBooleanField(mHealthdConfig->batteryPresentPath);
@@ -238,7 +235,6 @@
         props.batteryTechnology = String8(buf);
 
     unsigned int i;
-    double MaxPower = 0;
 
     for (i = 0; i < mChargerNames.size(); i++) {
         String8 path;
@@ -267,23 +263,11 @@
                 path.clear();
                 path.appendFormat("%s/%s/current_max", POWER_SUPPLY_SYSFS_PATH,
                                   mChargerNames[i].string());
-                int ChargingCurrent =
-                    (access(path.string(), R_OK) == 0) ? getIntField(path) : 0;
-
-                path.clear();
-                path.appendFormat("%s/%s/voltage_max", POWER_SUPPLY_SYSFS_PATH,
-                                  mChargerNames[i].string());
-
-                int ChargingVoltage =
-                    (access(path.string(), R_OK) == 0) ? getIntField(path) :
-                    DEFAULT_VBUS_VOLTAGE;
-
-                double power = ((double)ChargingCurrent / MILLION) *
-                        ((double)ChargingVoltage / MILLION);
-                if (MaxPower < power) {
-                    props.maxChargingCurrent = ChargingCurrent;
-                    props.maxChargingVoltage = ChargingVoltage;
-                    MaxPower = power;
+                if (access(path.string(), R_OK) == 0) {
+                    int maxChargingCurrent = getIntField(path);
+                    if (props.maxChargingCurrent < maxChargingCurrent) {
+                        props.maxChargingCurrent = maxChargingCurrent;
+                    }
                 }
             }
         }
@@ -421,10 +405,9 @@
     int v;
     char vs[128];
 
-    snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d voltage_max: %d\n",
+    snprintf(vs, sizeof(vs), "ac: %d usb: %d wireless: %d current_max: %d\n",
              props.chargerAcOnline, props.chargerUsbOnline,
-             props.chargerWirelessOnline, props.maxChargingCurrent,
-             props.maxChargingVoltage);
+             props.chargerWirelessOnline, props.maxChargingCurrent);
     write(fd, vs, strlen(vs));
     snprintf(vs, sizeof(vs), "status: %d health: %d present: %d\n",
              props.batteryStatus, props.batteryHealth, props.batteryPresent);
diff --git a/metricsd/Android.mk b/metricsd/Android.mk
index 291c983..97c0d28 100644
--- a/metricsd/Android.mk
+++ b/metricsd/Android.mk
@@ -25,11 +25,14 @@
 metrics_client_sources := \
   metrics_client.cc
 
-metrics_daemon_common := \
+metrics_collector_common := \
   collectors/averaged_statistics_collector.cc \
   collectors/cpu_usage_collector.cc \
   collectors/disk_usage_collector.cc \
-  metrics_daemon.cc \
+  metrics_collector.cc \
+  persistent_integer.cc \
+
+metricsd_common := \
   persistent_integer.cc \
   serialization/metric_sample.cc \
   serialization/serialization_utils.cc \
@@ -40,14 +43,16 @@
   uploader/system_profile_cache.cc \
   uploader/upload_service.cc \
 
-metrics_tests_sources := \
+metrics_collector_tests_sources := \
   collectors/averaged_statistics_collector_test.cc \
   collectors/cpu_usage_collector_test.cc \
-  metrics_daemon_test.cc \
+  metrics_collector_test.cc \
   metrics_library_test.cc \
   persistent_integer_test.cc \
   serialization/serialization_utils_unittest.cc \
   timer_test.cc \
+
+metricsd_tests_sources := \
   uploader/metrics_hashes_unittest.cc \
   uploader/metrics_log_base_unittest.cc \
   uploader/mock/sender_mock.cc \
@@ -56,7 +61,6 @@
 metrics_CFLAGS := -Wall \
   -Wno-char-subscripts \
   -Wno-missing-field-initializers \
-  -Wno-unused-function \
   -Wno-unused-parameter \
   -Werror \
   -fvisibility=default
@@ -67,17 +71,22 @@
 metrics_includes := external/gtest/include \
   $(LOCAL_PATH)/include
 libmetrics_shared_libraries := libchrome libbrillo
-metrics_daemon_shared_libraries := $(libmetrics_shared_libraries) \
-  libbrillo-http \
+metrics_collector_shared_libraries := $(libmetrics_shared_libraries) \
   libbrillo-dbus \
+  libbrillo-http \
   libchrome-dbus \
   libdbus \
   libmetrics \
-  libprotobuf-cpp-lite \
   librootdev \
-  libupdate_engine_client \
   libweaved \
 
+metricsd_shared_libraries := \
+  libbrillo \
+  libbrillo-http \
+  libchrome \
+  libprotobuf-cpp-lite \
+  libupdate_engine_client \
+
 # Shared library for metrics.
 # ========================================================
 include $(CLEAR_VARS)
@@ -107,10 +116,10 @@
 LOCAL_SRC_FILES := $(metrics_client_sources)
 include $(BUILD_EXECUTABLE)
 
-# Protobuf library for metrics_daemon.
+# Protobuf library for metricsd.
 # ========================================================
 include $(CLEAR_VARS)
-LOCAL_MODULE := metrics_daemon_protos
+LOCAL_MODULE := metricsd_protos
 LOCAL_MODULE_CLASS := STATIC_LIBRARIES
 generated_sources_dir := $(call local-generated-sources-dir)
 LOCAL_EXPORT_C_INCLUDE_DIRS += \
@@ -118,40 +127,71 @@
 LOCAL_SRC_FILES :=  $(call all-proto-files-under,uploader/proto)
 include $(BUILD_STATIC_LIBRARY)
 
-# metrics daemon.
+# metrics_collector daemon.
 # ========================================================
 include $(CLEAR_VARS)
-LOCAL_MODULE := metrics_daemon
+LOCAL_MODULE := metrics_collector
 LOCAL_C_INCLUDES := $(metrics_includes)
 LOCAL_CFLAGS := $(metrics_CFLAGS)
+LOCAL_CLANG := true
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS)
-LOCAL_INIT_RC := metrics_daemon.rc
+LOCAL_INIT_RC := metrics_collector.rc
 LOCAL_REQUIRED_MODULES := \
   metrics.json \
-  metrics.schema.json \
-
+  metrics.schema.json
 LOCAL_RTTI_FLAG := -frtti
-LOCAL_SHARED_LIBRARIES := $(metrics_daemon_shared_libraries)
-LOCAL_CLANG := true
-LOCAL_SRC_FILES := $(metrics_daemon_common) \
-  metrics_daemon_main.cc
-LOCAL_STATIC_LIBRARIES := metrics_daemon_protos
+LOCAL_SHARED_LIBRARIES := $(metrics_collector_shared_libraries)
+LOCAL_SRC_FILES := $(metrics_collector_common) \
+  metrics_collector_main.cc
 include $(BUILD_EXECUTABLE)
 
-# Unit tests for metrics.
+# metricsd daemon.
 # ========================================================
 include $(CLEAR_VARS)
-LOCAL_MODULE := metrics_tests
-LOCAL_CLANG := true
+LOCAL_MODULE := metricsd
+LOCAL_C_INCLUDES := $(metrics_includes)
 LOCAL_CFLAGS := $(metrics_CFLAGS)
+LOCAL_CLANG := true
+LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
+LOCAL_CPPFLAGS := $(metrics_CPPFLAGS)
+LOCAL_INIT_RC := metricsd.rc
+LOCAL_REQUIRED_MODULES := \
+  metrics_collector
+LOCAL_RTTI_FLAG := -frtti
+LOCAL_SHARED_LIBRARIES := $(metricsd_shared_libraries)
+LOCAL_STATIC_LIBRARIES := metricsd_protos
+LOCAL_SRC_FILES := $(metricsd_common) \
+  metricsd_main.cc
+include $(BUILD_EXECUTABLE)
+
+# Unit tests for metricsd.
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := metricsd_tests
+LOCAL_CFLAGS := $(metrics_CFLAGS)
+LOCAL_CLANG := true
 LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
 LOCAL_CPPFLAGS := $(metrics_CPPFLAGS) -Wno-sign-compare
 LOCAL_RTTI_FLAG := -frtti
-LOCAL_SHARED_LIBRARIES := $(metrics_daemon_shared_libraries)
-LOCAL_SRC_FILES := $(metrics_tests_sources) $(metrics_daemon_common)
-LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock metrics_daemon_protos
+LOCAL_SHARED_LIBRARIES := $(metricsd_shared_libraries) libmetrics
+LOCAL_SRC_FILES := $(metricsd_tests_sources) $(metricsd_common)
+LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock metricsd_protos
+include $(BUILD_NATIVE_TEST)
 
+# Unit tests for metrics_collector.
+# ========================================================
+include $(CLEAR_VARS)
+LOCAL_MODULE := metrics_collector_tests
+LOCAL_CFLAGS := $(metrics_CFLAGS)
+LOCAL_CLANG := true
+LOCAL_CPP_EXTENSION := $(metrics_cpp_extension)
+LOCAL_CPPFLAGS := $(metrics_CPPFLAGS) -Wno-sign-compare
+LOCAL_RTTI_FLAG := -frtti
+LOCAL_SHARED_LIBRARIES := $(metrics_collector_shared_libraries)
+LOCAL_SRC_FILES := $(metrics_collector_tests_sources) \
+  $(metrics_collector_common)
+LOCAL_STATIC_LIBRARIES := libBionicGtestMain libgmock
 include $(BUILD_NATIVE_TEST)
 
 # Weave schema files
diff --git a/metricsd/collectors/averaged_statistics_collector.cc b/metricsd/collectors/averaged_statistics_collector.cc
index 0931e7b..bac2870 100644
--- a/metricsd/collectors/averaged_statistics_collector.cc
+++ b/metricsd/collectors/averaged_statistics_collector.cc
@@ -21,7 +21,7 @@
 #include <base/strings/string_number_conversions.h>
 #include <base/strings/string_split.h>
 
-#include "metrics_daemon.h"
+#include "metrics_collector.h"
 
 namespace {
 
@@ -90,7 +90,7 @@
 }
 
 void AveragedStatisticsCollector::ReadInitialValues() {
-  stats_start_time_ = MetricsDaemon::GetActiveTime();
+  stats_start_time_ = MetricsCollector::GetActiveTime();
   DiskStatsReadStats(&read_sectors_, &write_sectors_);
   VmStatsReadStats(&vmstats_);
 }
@@ -168,7 +168,7 @@
 void AveragedStatisticsCollector::Collect() {
   uint64_t read_sectors_now, write_sectors_now;
   struct VmstatRecord vmstats_now;
-  double time_now = MetricsDaemon::GetActiveTime();
+  double time_now = MetricsCollector::GetActiveTime();
   double delta_time = time_now - stats_start_time_;
   bool diskstats_success = DiskStatsReadStats(&read_sectors_now,
                                               &write_sectors_now);
diff --git a/metricsd/metrics_daemon.cc b/metricsd/metrics_collector.cc
similarity index 82%
rename from metricsd/metrics_daemon.cc
rename to metricsd/metrics_collector.cc
index e711660..28194a1 100644
--- a/metricsd/metrics_daemon.cc
+++ b/metricsd/metrics_collector.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "metrics_daemon.h"
+#include "metrics_collector.h"
 
 #include <sysexits.h>
 #include <time.h>
@@ -33,7 +33,6 @@
 #include <dbus/message.h>
 
 #include "constants.h"
-#include "uploader/upload_service.h"
 
 using base::FilePath;
 using base::StringPrintf;
@@ -78,9 +77,9 @@
 
 // Zram sysfs entries.
 
-const char MetricsDaemon::kComprDataSizeName[] = "compr_data_size";
-const char MetricsDaemon::kOrigDataSizeName[] = "orig_data_size";
-const char MetricsDaemon::kZeroPagesName[] = "zero_pages";
+const char MetricsCollector::kComprDataSizeName[] = "compr_data_size";
+const char MetricsCollector::kOrigDataSizeName[] = "orig_data_size";
+const char MetricsCollector::kZeroPagesName[] = "zero_pages";
 
 // Memory use stats collection intervals.  We collect some memory use interval
 // at these intervals after boot, and we stop collecting after the last one,
@@ -94,15 +93,15 @@
   600 * kSecondsPerMinute,  // 12.5 hour mark
 };
 
-MetricsDaemon::MetricsDaemon()
+MetricsCollector::MetricsCollector()
     : memuse_final_time_(0),
       memuse_interval_index_(0) {}
 
-MetricsDaemon::~MetricsDaemon() {
+MetricsCollector::~MetricsCollector() {
 }
 
 // static
-double MetricsDaemon::GetActiveTime() {
+double MetricsCollector::GetActiveTime() {
   struct timespec ts;
   int r = clock_gettime(CLOCK_MONOTONIC, &ts);
   if (r < 0) {
@@ -113,7 +112,7 @@
   }
 }
 
-int MetricsDaemon::Run() {
+int MetricsCollector::Run() {
   if (CheckSystemCrash(kKernelCrashDetectedFile)) {
     ProcessKernelCrash();
   }
@@ -134,16 +133,7 @@
   return brillo::DBusDaemon::Run();
 }
 
-void MetricsDaemon::RunUploaderTest() {
-  upload_service_.reset(new UploadService(
-      new SystemProfileCache(true, metrics_directory_),
-      metrics_lib_,
-      server_));
-  upload_service_->Init(upload_interval_, metrics_directory_);
-  upload_service_->UploadEvent();
-}
-
-uint32_t MetricsDaemon::GetOsVersionHash() {
+uint32_t MetricsCollector::GetOsVersionHash() {
   brillo::OsReleaseReader reader;
   reader.Load();
   string version;
@@ -159,24 +149,15 @@
   return version_hash;
 }
 
-void MetricsDaemon::Init(bool testing,
-                         bool uploader_active,
-                         bool dbus_enabled,
+void MetricsCollector::Init(bool testing,
                          MetricsLibraryInterface* metrics_lib,
                          const string& diskstats_path,
-                         const base::TimeDelta& upload_interval,
-                         const string& server,
                          const base::FilePath& metrics_directory) {
   CHECK(metrics_lib);
   testing_ = testing;
-  uploader_active_ = uploader_active;
-  dbus_enabled_ = dbus_enabled;
   metrics_directory_ = metrics_directory;
   metrics_lib_ = metrics_lib;
 
-  upload_interval_ = upload_interval;
-  server_ = server;
-
   daily_active_use_.reset(
       new PersistentInteger("Platform.UseTime.PerDay"));
   version_cumulative_active_use_.reset(
@@ -221,9 +202,8 @@
   cpu_usage_collector_.reset(new CpuUsageCollector(metrics_lib_));
 }
 
-int MetricsDaemon::OnInit() {
-  int return_code = dbus_enabled_ ? brillo::DBusDaemon::OnInit() :
-      brillo::Daemon::OnInit();
+int MetricsCollector::OnInit() {
+  int return_code = brillo::DBusDaemon::OnInit();
   if (return_code != EX_OK)
     return return_code;
 
@@ -237,66 +217,58 @@
   if (testing_)
     return EX_OK;
 
-  if (dbus_enabled_) {
-    bus_->AssertOnDBusThread();
-    CHECK(bus_->SetUpAsyncOperations());
+  bus_->AssertOnDBusThread();
+  CHECK(bus_->SetUpAsyncOperations());
 
-    if (bus_->is_connected()) {
-      const std::string match_rule =
-          base::StringPrintf(kCrashReporterMatchRule,
-                             kCrashReporterInterface,
-                             kCrashReporterUserCrashSignal);
-
-      bus_->AddFilterFunction(&MetricsDaemon::MessageFilter, this);
-
-      DBusError error;
-      dbus_error_init(&error);
-      bus_->AddMatch(match_rule, &error);
-
-      if (dbus_error_is_set(&error)) {
-        LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got "
-            << error.name << ": " << error.message;
-        return EX_SOFTWARE;
-      }
-    } else {
-      LOG(ERROR) << "DBus isn't connected.";
-      return EX_UNAVAILABLE;
-    }
-
-    device_ = weaved::Device::CreateInstance(
-        bus_,
-        base::Bind(&MetricsDaemon::UpdateWeaveState, base::Unretained(this)));
-    device_->AddCommandHandler(
-        "_metrics._enableAnalyticsReporting",
-        base::Bind(&MetricsDaemon::OnEnableMetrics, base::Unretained(this)));
-    device_->AddCommandHandler(
-        "_metrics._disableAnalyticsReporting",
-        base::Bind(&MetricsDaemon::OnDisableMetrics, base::Unretained(this)));
-  }
-
-  latest_cpu_use_microseconds_ = cpu_usage_collector_->GetCumulativeCpuUse();
-  base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-      base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout,
-                 base::Unretained(this)),
-      base::TimeDelta::FromMilliseconds(kUpdateStatsIntervalMs));
-
-  if (uploader_active_) {
-    upload_service_.reset(
-        new UploadService(new SystemProfileCache(), metrics_lib_, server_));
-    upload_service_->Init(upload_interval_, metrics_directory_);
-  }
-
-  return EX_OK;
-}
-
-void MetricsDaemon::OnShutdown(int* return_code) {
-  if (!testing_ && dbus_enabled_ && bus_->is_connected()) {
+  if (bus_->is_connected()) {
     const std::string match_rule =
         base::StringPrintf(kCrashReporterMatchRule,
                            kCrashReporterInterface,
                            kCrashReporterUserCrashSignal);
 
-    bus_->RemoveFilterFunction(&MetricsDaemon::MessageFilter, this);
+    bus_->AddFilterFunction(&MetricsCollector::MessageFilter, this);
+
+    DBusError error;
+    dbus_error_init(&error);
+    bus_->AddMatch(match_rule, &error);
+
+    if (dbus_error_is_set(&error)) {
+      LOG(ERROR) << "Failed to add match rule \"" << match_rule << "\". Got "
+          << error.name << ": " << error.message;
+      return EX_SOFTWARE;
+    }
+  } else {
+    LOG(ERROR) << "DBus isn't connected.";
+    return EX_UNAVAILABLE;
+  }
+
+  device_ = weaved::Device::CreateInstance(
+      bus_,
+      base::Bind(&MetricsCollector::UpdateWeaveState, base::Unretained(this)));
+  device_->AddCommandHandler(
+      "_metrics._enableAnalyticsReporting",
+      base::Bind(&MetricsCollector::OnEnableMetrics, base::Unretained(this)));
+  device_->AddCommandHandler(
+      "_metrics._disableAnalyticsReporting",
+      base::Bind(&MetricsCollector::OnDisableMetrics, base::Unretained(this)));
+
+  latest_cpu_use_microseconds_ = cpu_usage_collector_->GetCumulativeCpuUse();
+  base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
+      base::Bind(&MetricsCollector::HandleUpdateStatsTimeout,
+                 base::Unretained(this)),
+      base::TimeDelta::FromMilliseconds(kUpdateStatsIntervalMs));
+
+  return EX_OK;
+}
+
+void MetricsCollector::OnShutdown(int* return_code) {
+  if (!testing_ && bus_->is_connected()) {
+    const std::string match_rule =
+        base::StringPrintf(kCrashReporterMatchRule,
+                           kCrashReporterInterface,
+                           kCrashReporterUserCrashSignal);
+
+    bus_->RemoveFilterFunction(&MetricsCollector::MessageFilter, this);
 
     DBusError error;
     dbus_error_init(&error);
@@ -310,7 +282,8 @@
   brillo::DBusDaemon::OnShutdown(return_code);
 }
 
-void MetricsDaemon::OnEnableMetrics(const std::weak_ptr<weaved::Command>& cmd) {
+void MetricsCollector::OnEnableMetrics(
+    const std::weak_ptr<weaved::Command>& cmd) {
   auto command = cmd.lock();
   if (!command)
     return;
@@ -327,7 +300,7 @@
   command->Complete({}, nullptr);
 }
 
-void MetricsDaemon::OnDisableMetrics(
+void MetricsCollector::OnDisableMetrics(
     const std::weak_ptr<weaved::Command>& cmd) {
   auto command = cmd.lock();
   if (!command)
@@ -345,7 +318,7 @@
   command->Complete({}, nullptr);
 }
 
-void MetricsDaemon::UpdateWeaveState() {
+void MetricsCollector::UpdateWeaveState() {
   if (!device_)
     return;
 
@@ -360,9 +333,9 @@
 }
 
 // static
-DBusHandlerResult MetricsDaemon::MessageFilter(DBusConnection* connection,
-                                               DBusMessage* message,
-                                               void* user_data) {
+DBusHandlerResult MetricsCollector::MessageFilter(DBusConnection* connection,
+                                                   DBusMessage* message,
+                                                   void* user_data) {
   int message_type = dbus_message_get_type(message);
   if (message_type != DBUS_MESSAGE_TYPE_SIGNAL) {
     DLOG(WARNING) << "unexpected message type " << message_type;
@@ -374,7 +347,7 @@
   const std::string member(dbus_message_get_member(message));
   DLOG(INFO) << "Got " << interface << "." << member << " D-Bus signal";
 
-  MetricsDaemon* daemon = static_cast<MetricsDaemon*>(user_data);
+  MetricsCollector* daemon = static_cast<MetricsCollector*>(user_data);
 
   DBusMessageIter iter;
   dbus_message_iter_init(message, &iter);
@@ -389,7 +362,7 @@
   return DBUS_HANDLER_RESULT_HANDLED;
 }
 
-void MetricsDaemon::ProcessUserCrash() {
+void MetricsCollector::ProcessUserCrash() {
   // Counts the active time up to now.
   UpdateStats(TimeTicks::Now(), Time::Now());
 
@@ -402,7 +375,7 @@
   user_crashes_weekly_count_->Add(1);
 }
 
-void MetricsDaemon::ProcessKernelCrash() {
+void MetricsCollector::ProcessKernelCrash() {
   // Counts the active time up to now.
   UpdateStats(TimeTicks::Now(), Time::Now());
 
@@ -417,7 +390,7 @@
   kernel_crashes_version_count_->Add(1);
 }
 
-void MetricsDaemon::ProcessUncleanShutdown() {
+void MetricsCollector::ProcessUncleanShutdown() {
   // Counts the active time up to now.
   UpdateStats(TimeTicks::Now(), Time::Now());
 
@@ -430,7 +403,7 @@
   any_crashes_weekly_count_->Add(1);
 }
 
-bool MetricsDaemon::CheckSystemCrash(const string& crash_file) {
+bool MetricsCollector::CheckSystemCrash(const string& crash_file) {
   FilePath crash_detected(crash_file);
   if (!base::PathExists(crash_detected))
     return false;
@@ -441,7 +414,7 @@
   return true;
 }
 
-void MetricsDaemon::StatsReporterInit() {
+void MetricsCollector::StatsReporterInit() {
   disk_usage_collector_->Schedule();
 
   cpu_usage_collector_->Init();
@@ -452,18 +425,18 @@
   averaged_stats_collector_->ScheduleWait();
 }
 
-void MetricsDaemon::ScheduleMeminfoCallback(int wait) {
+void MetricsCollector::ScheduleMeminfoCallback(int wait) {
   if (testing_) {
     return;
   }
   base::TimeDelta waitDelta = base::TimeDelta::FromSeconds(wait);
   base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-      base::Bind(&MetricsDaemon::MeminfoCallback, base::Unretained(this),
+      base::Bind(&MetricsCollector::MeminfoCallback, base::Unretained(this),
                  waitDelta),
       waitDelta);
 }
 
-void MetricsDaemon::MeminfoCallback(base::TimeDelta wait) {
+void MetricsCollector::MeminfoCallback(base::TimeDelta wait) {
   string meminfo_raw;
   const FilePath meminfo_path(kMeminfoFileName);
   if (!base::ReadFileToString(meminfo_path, &meminfo_raw)) {
@@ -473,15 +446,15 @@
   // Make both calls even if the first one fails.
   if (ProcessMeminfo(meminfo_raw)) {
     base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-        base::Bind(&MetricsDaemon::MeminfoCallback, base::Unretained(this),
+        base::Bind(&MetricsCollector::MeminfoCallback, base::Unretained(this),
                    wait),
         wait);
   }
 }
 
 // static
-bool MetricsDaemon::ReadFileToUint64(const base::FilePath& path,
-                                     uint64_t* value) {
+bool MetricsCollector::ReadFileToUint64(const base::FilePath& path,
+                                         uint64_t* value) {
   std::string content;
   if (!base::ReadFileToString(path, &content)) {
     PLOG(WARNING) << "cannot read " << path.MaybeAsASCII();
@@ -496,7 +469,7 @@
   return true;
 }
 
-bool MetricsDaemon::ReportZram(const base::FilePath& zram_dir) {
+bool MetricsCollector::ReportZram(const base::FilePath& zram_dir) {
   // Data sizes are in bytes.  |zero_pages| is in number of pages.
   uint64_t compr_data_size, orig_data_size, zero_pages;
   const size_t page_size = 4096;
@@ -533,7 +506,7 @@
   return true;
 }
 
-bool MetricsDaemon::ProcessMeminfo(const string& meminfo_raw) {
+bool MetricsCollector::ProcessMeminfo(const string& meminfo_raw) {
   static const MeminfoRecord fields_array[] = {
     { "MemTotal", "MemTotal" },  // SPECIAL CASE: total system memory
     { "MemFree", "MemFree" },
@@ -604,8 +577,8 @@
   return true;
 }
 
-bool MetricsDaemon::FillMeminfo(const string& meminfo_raw,
-                                vector<MeminfoRecord>* fields) {
+bool MetricsCollector::FillMeminfo(const string& meminfo_raw,
+                                    vector<MeminfoRecord>* fields) {
   vector<string> lines;
   unsigned int nlines = Tokenize(meminfo_raw, "\n", &lines);
 
@@ -636,16 +609,16 @@
   return true;
 }
 
-void MetricsDaemon::ScheduleMemuseCallback(double interval) {
+void MetricsCollector::ScheduleMemuseCallback(double interval) {
   if (testing_) {
     return;
   }
   base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-      base::Bind(&MetricsDaemon::MemuseCallback, base::Unretained(this)),
+      base::Bind(&MetricsCollector::MemuseCallback, base::Unretained(this)),
       base::TimeDelta::FromSeconds(interval));
 }
 
-void MetricsDaemon::MemuseCallback() {
+void MetricsCollector::MemuseCallback() {
   // Since we only care about active time (i.e. uptime minus sleep time) but
   // the callbacks are driven by real time (uptime), we check if we should
   // reschedule this callback due to intervening sleep periods.
@@ -666,7 +639,7 @@
   }
 }
 
-bool MetricsDaemon::MemuseCallbackWork() {
+bool MetricsCollector::MemuseCallbackWork() {
   string meminfo_raw;
   const FilePath meminfo_path(kMeminfoFileName);
   if (!base::ReadFileToString(meminfo_path, &meminfo_raw)) {
@@ -676,7 +649,7 @@
   return ProcessMemuse(meminfo_raw);
 }
 
-bool MetricsDaemon::ProcessMemuse(const string& meminfo_raw) {
+bool MetricsCollector::ProcessMemuse(const string& meminfo_raw) {
   static const MeminfoRecord fields_array[] = {
     { "MemTotal", "MemTotal" },  // SPECIAL CASE: total system memory
     { "ActiveAnon", "Active(anon)" },
@@ -702,12 +675,12 @@
   return true;
 }
 
-void MetricsDaemon::SendSample(const string& name, int sample,
-                               int min, int max, int nbuckets) {
+void MetricsCollector::SendSample(const string& name, int sample,
+                                   int min, int max, int nbuckets) {
   metrics_lib_->SendToUMA(name, sample, min, max, nbuckets);
 }
 
-void MetricsDaemon::SendKernelCrashesCumulativeCountStats() {
+void MetricsCollector::SendKernelCrashesCumulativeCountStats() {
   // Report the number of crashes for this OS version, but don't clear the
   // counter.  It is cleared elsewhere on version change.
   int64_t crashes_count = kernel_crashes_version_count_->Get();
@@ -752,7 +725,7 @@
   }
 }
 
-void MetricsDaemon::SendAndResetDailyUseSample(
+void MetricsCollector::SendAndResetDailyUseSample(
     const scoped_ptr<PersistentInteger>& use) {
   SendSample(use->Name(),
              use->GetAndClear(),
@@ -761,7 +734,7 @@
              50);                      // number of buckets
 }
 
-void MetricsDaemon::SendAndResetCrashIntervalSample(
+void MetricsCollector::SendAndResetCrashIntervalSample(
     const scoped_ptr<PersistentInteger>& interval) {
   SendSample(interval->Name(),
              interval->GetAndClear(),
@@ -770,7 +743,7 @@
              50);                      // number of buckets
 }
 
-void MetricsDaemon::SendAndResetCrashFrequencySample(
+void MetricsCollector::SendAndResetCrashFrequencySample(
     const scoped_ptr<PersistentInteger>& frequency) {
   SendSample(frequency->Name(),
              frequency->GetAndClear(),
@@ -779,16 +752,16 @@
              50);                      // number of buckets
 }
 
-void MetricsDaemon::SendLinearSample(const string& name, int sample,
-                                     int max, int nbuckets) {
+void MetricsCollector::SendLinearSample(const string& name, int sample,
+                                         int max, int nbuckets) {
   // TODO(semenzato): add a proper linear histogram to the Chrome external
   // metrics API.
   LOG_IF(FATAL, nbuckets != max + 1) << "unsupported histogram scale";
   metrics_lib_->SendEnumToUMA(name, sample, max);
 }
 
-void MetricsDaemon::UpdateStats(TimeTicks now_ticks,
-                                Time now_wall_time) {
+void MetricsCollector::UpdateStats(TimeTicks now_ticks,
+                                    Time now_wall_time) {
   const int elapsed_seconds = (now_ticks - last_update_stats_time_).InSeconds();
   daily_active_use_->Add(elapsed_seconds);
   version_cumulative_active_use_->Add(elapsed_seconds);
@@ -823,10 +796,10 @@
   }
 }
 
-void MetricsDaemon::HandleUpdateStatsTimeout() {
+void MetricsCollector::HandleUpdateStatsTimeout() {
   UpdateStats(TimeTicks::Now(), Time::Now());
   base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-      base::Bind(&MetricsDaemon::HandleUpdateStatsTimeout,
+      base::Bind(&MetricsCollector::HandleUpdateStatsTimeout,
                  base::Unretained(this)),
       base::TimeDelta::FromMilliseconds(kUpdateStatsIntervalMs));
 }
diff --git a/metricsd/metrics_daemon.h b/metricsd/metrics_collector.h
similarity index 84%
rename from metricsd/metrics_daemon.h
rename to metricsd/metrics_collector.h
index 54ae188..e080ac0 100644
--- a/metricsd/metrics_daemon.h
+++ b/metricsd/metrics_collector.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef METRICS_METRICS_DAEMON_H_
-#define METRICS_METRICS_DAEMON_H_
+#ifndef METRICS_METRICS_COLLECTOR_H_
+#define METRICS_METRICS_COLLECTOR_H_
 
 #include <stdint.h>
 
@@ -36,23 +36,18 @@
 #include "collectors/disk_usage_collector.h"
 #include "metrics/metrics_library.h"
 #include "persistent_integer.h"
-#include "uploader/upload_service.h"
 
 using chromeos_metrics::PersistentInteger;
 
-class MetricsDaemon : public brillo::DBusDaemon {
+class MetricsCollector : public brillo::DBusDaemon {
  public:
-  MetricsDaemon();
-  ~MetricsDaemon();
+  MetricsCollector();
+  ~MetricsCollector();
 
   // Initializes metrics class variables.
   void Init(bool testing,
-            bool uploader_active,
-            bool dbus_enabled,
             MetricsLibraryInterface* metrics_lib,
             const std::string& diskstats_path,
-            const base::TimeDelta& upload_interval,
-            const std::string& server,
             const base::FilePath& metrics_directory);
 
   // Initializes DBus and MessageLoop variables before running the MessageLoop.
@@ -64,9 +59,6 @@
   // Does all the work.
   int Run() override;
 
-  // Triggers an upload event and exit. (Used to test UploadService)
-  void RunUploaderTest();
-
   // Returns the active time since boot (uptime minus sleep time) in seconds.
   static double GetActiveTime();
 
@@ -77,24 +69,24 @@
   static const char kZeroPagesName[];
 
  private:
-  friend class MetricsDaemonTest;
-  FRIEND_TEST(MetricsDaemonTest, CheckSystemCrash);
-  FRIEND_TEST(MetricsDaemonTest, ComputeEpochNoCurrent);
-  FRIEND_TEST(MetricsDaemonTest, ComputeEpochNoLast);
-  FRIEND_TEST(MetricsDaemonTest, GetHistogramPath);
-  FRIEND_TEST(MetricsDaemonTest, IsNewEpoch);
-  FRIEND_TEST(MetricsDaemonTest, MessageFilter);
-  FRIEND_TEST(MetricsDaemonTest, ProcessKernelCrash);
-  FRIEND_TEST(MetricsDaemonTest, ProcessMeminfo);
-  FRIEND_TEST(MetricsDaemonTest, ProcessMeminfo2);
-  FRIEND_TEST(MetricsDaemonTest, ProcessUncleanShutdown);
-  FRIEND_TEST(MetricsDaemonTest, ProcessUserCrash);
-  FRIEND_TEST(MetricsDaemonTest, ReportCrashesDailyFrequency);
-  FRIEND_TEST(MetricsDaemonTest, ReportKernelCrashInterval);
-  FRIEND_TEST(MetricsDaemonTest, ReportUncleanShutdownInterval);
-  FRIEND_TEST(MetricsDaemonTest, ReportUserCrashInterval);
-  FRIEND_TEST(MetricsDaemonTest, SendSample);
-  FRIEND_TEST(MetricsDaemonTest, SendZramMetrics);
+  friend class MetricsCollectorTest;
+  FRIEND_TEST(MetricsCollectorTest, CheckSystemCrash);
+  FRIEND_TEST(MetricsCollectorTest, ComputeEpochNoCurrent);
+  FRIEND_TEST(MetricsCollectorTest, ComputeEpochNoLast);
+  FRIEND_TEST(MetricsCollectorTest, GetHistogramPath);
+  FRIEND_TEST(MetricsCollectorTest, IsNewEpoch);
+  FRIEND_TEST(MetricsCollectorTest, MessageFilter);
+  FRIEND_TEST(MetricsCollectorTest, ProcessKernelCrash);
+  FRIEND_TEST(MetricsCollectorTest, ProcessMeminfo);
+  FRIEND_TEST(MetricsCollectorTest, ProcessMeminfo2);
+  FRIEND_TEST(MetricsCollectorTest, ProcessUncleanShutdown);
+  FRIEND_TEST(MetricsCollectorTest, ProcessUserCrash);
+  FRIEND_TEST(MetricsCollectorTest, ReportCrashesDailyFrequency);
+  FRIEND_TEST(MetricsCollectorTest, ReportKernelCrashInterval);
+  FRIEND_TEST(MetricsCollectorTest, ReportUncleanShutdownInterval);
+  FRIEND_TEST(MetricsCollectorTest, ReportUserCrashInterval);
+  FRIEND_TEST(MetricsCollectorTest, SendSample);
+  FRIEND_TEST(MetricsCollectorTest, SendZramMetrics);
 
   // Type of scale to use for meminfo histograms.  For most of them we use
   // percent of total RAM, but for some we use absolute numbers, usually in
@@ -233,13 +225,6 @@
   // Test mode.
   bool testing_;
 
-  // Whether the uploader is enabled or disabled.
-  bool uploader_active_;
-
-  // Whether or not dbus should be used.
-  // If disabled, we will not collect the frequency of crashes.
-  bool dbus_enabled_;
-
   // Root of the configuration files to use.
   base::FilePath metrics_directory_;
 
@@ -291,11 +276,7 @@
   scoped_ptr<DiskUsageCollector> disk_usage_collector_;
   scoped_ptr<AveragedStatisticsCollector> averaged_stats_collector_;
 
-  base::TimeDelta upload_interval_;
-  std::string server_;
-
-  scoped_ptr<UploadService> upload_service_;
   std::unique_ptr<weaved::Device> device_;
 };
 
-#endif  // METRICS_METRICS_DAEMON_H_
+#endif  // METRICS_METRICS_COLLECTOR_H_
diff --git a/metricsd/metrics_collector.rc b/metricsd/metrics_collector.rc
new file mode 100644
index 0000000..2e7e0ae
--- /dev/null
+++ b/metricsd/metrics_collector.rc
@@ -0,0 +1,4 @@
+service metricscollector /system/bin/metrics_collector --foreground --logtosyslog
+    class late_start
+    user system
+    group system dbus
diff --git a/metricsd/metrics_daemon_main.cc b/metricsd/metrics_collector_main.cc
similarity index 72%
rename from metricsd/metrics_daemon_main.cc
rename to metricsd/metrics_collector_main.cc
index 9bb67e8..117426e 100644
--- a/metricsd/metrics_daemon_main.cc
+++ b/metricsd/metrics_collector_main.cc
@@ -23,7 +23,7 @@
 #include <rootdev.h>
 
 #include "constants.h"
-#include "metrics_daemon.h"
+#include "metrics_collector.h"
 
 
 // Returns the path to the disk stats in the sysfs.  Returns the null string if
@@ -51,26 +51,6 @@
 int main(int argc, char** argv) {
   DEFINE_bool(foreground, false, "Don't daemonize");
 
-  // The uploader is disabled by default on ChromeOS as Chrome is responsible
-  // for sending the metrics.
-  DEFINE_bool(uploader, false, "activate the uploader");
-
-  // Upload the metrics once and exit. (used for testing)
-  DEFINE_bool(uploader_test,
-              false,
-              "run the uploader once and exit");
-
-  // Enable dbus.
-  DEFINE_bool(withdbus, true, "Enable dbus");
-
-  // Upload Service flags.
-  DEFINE_int32(upload_interval_secs,
-               1800,
-               "Interval at which metrics_daemon sends the metrics. (needs "
-               "-uploader)");
-  DEFINE_string(server,
-                metrics::kMetricsServer,
-                "Server to upload the metrics to. (needs -uploader)");
   DEFINE_string(metrics_directory,
                 metrics::kMetricsDirectory,
                 "Root of the configuration files (testing only)");
@@ -102,20 +82,11 @@
 
   MetricsLibrary metrics_lib;
   metrics_lib.InitWithNoCaching();
-  MetricsDaemon daemon;
-  daemon.Init(FLAGS_uploader_test,
-              FLAGS_uploader | FLAGS_uploader_test,
-              FLAGS_withdbus,
+  MetricsCollector daemon;
+  daemon.Init(false,
               &metrics_lib,
               MetricsMainDiskStatsPath(),
-              base::TimeDelta::FromSeconds(FLAGS_upload_interval_secs),
-              FLAGS_server,
               base::FilePath(FLAGS_metrics_directory));
 
-  if (FLAGS_uploader_test) {
-    daemon.RunUploaderTest();
-    return 0;
-  }
-
   daemon.Run();
 }
diff --git a/metricsd/metrics_daemon_test.cc b/metricsd/metrics_collector_test.cc
similarity index 88%
rename from metricsd/metrics_daemon_test.cc
rename to metricsd/metrics_collector_test.cc
index 2e8a85b..a0e7087 100644
--- a/metricsd/metrics_daemon_test.cc
+++ b/metricsd/metrics_collector_test.cc
@@ -24,7 +24,7 @@
 #include <gtest/gtest.h>
 
 #include "constants.h"
-#include "metrics_daemon.h"
+#include "metrics_collector.h"
 #include "metrics/metrics_library_mock.h"
 #include "persistent_integer_mock.h"
 
@@ -40,7 +40,7 @@
 using chromeos_metrics::PersistentIntegerMock;
 
 
-class MetricsDaemonTest : public testing::Test {
+class MetricsCollectorTest : public testing::Test {
  protected:
   virtual void SetUp() {
     brillo::FlagHelper::Init(0, nullptr, "");
@@ -48,14 +48,7 @@
 
     chromeos_metrics::PersistentInteger::SetMetricsDirectory(
         temp_dir_.path().value());
-    daemon_.Init(true,
-                 false,
-                 true,
-                 &metrics_lib_,
-                 "",
-                 base::TimeDelta::FromMinutes(30),
-                 metrics::kMetricsServer,
-                 temp_dir_.path());
+    daemon_.Init(true, &metrics_lib_, "", temp_dir_.path());
   }
 
   // Adds a metrics library mock expectation that the specified metric
@@ -107,8 +100,8 @@
                               value_string.length()));
   }
 
-  // The MetricsDaemon under test.
-  MetricsDaemon daemon_;
+  // The MetricsCollector under test.
+  MetricsCollector daemon_;
 
   // Temporary directory used for tests.
   base::ScopedTempDir temp_dir_;
@@ -118,13 +111,13 @@
   StrictMock<MetricsLibraryMock> metrics_lib_;
 };
 
-TEST_F(MetricsDaemonTest, MessageFilter) {
+TEST_F(MetricsCollectorTest, MessageFilter) {
   // Ignore calls to SendToUMA.
   EXPECT_CALL(metrics_lib_, SendToUMA(_, _, _, _, _)).Times(AnyNumber());
 
   DBusMessage* msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
   DBusHandlerResult res =
-      MetricsDaemon::MessageFilter(/* connection */ nullptr, msg, &daemon_);
+      MetricsCollector::MessageFilter(/* connection */ nullptr, msg, &daemon_);
   EXPECT_EQ(DBUS_HANDLER_RESULT_NOT_YET_HANDLED, res);
   DeleteDBusMessage(msg);
 
@@ -133,7 +126,7 @@
                             "org.chromium.CrashReporter",
                             "UserCrash",
                             signal_args);
-  res = MetricsDaemon::MessageFilter(/* connection */ nullptr, msg, &daemon_);
+  res = MetricsCollector::MessageFilter(/* connection */ nullptr, msg, &daemon_);
   EXPECT_EQ(DBUS_HANDLER_RESULT_HANDLED, res);
   DeleteDBusMessage(msg);
 
@@ -144,18 +137,18 @@
                             "org.chromium.UnknownService.Manager",
                             "StateChanged",
                             signal_args);
-  res = MetricsDaemon::MessageFilter(/* connection */ nullptr, msg, &daemon_);
+  res = MetricsCollector::MessageFilter(/* connection */ nullptr, msg, &daemon_);
   EXPECT_EQ(DBUS_HANDLER_RESULT_NOT_YET_HANDLED, res);
   DeleteDBusMessage(msg);
 }
 
-TEST_F(MetricsDaemonTest, SendSample) {
+TEST_F(MetricsCollectorTest, SendSample) {
   ExpectSample("Dummy.Metric", 3);
   daemon_.SendSample("Dummy.Metric", /* sample */ 3,
                      /* min */ 1, /* max */ 100, /* buckets */ 50);
 }
 
-TEST_F(MetricsDaemonTest, ProcessMeminfo) {
+TEST_F(MetricsCollectorTest, ProcessMeminfo) {
   string meminfo =
       "MemTotal:        2000000 kB\nMemFree:          500000 kB\n"
       "Buffers:         1000000 kB\nCached:           213652 kB\n"
@@ -192,13 +185,13 @@
   EXPECT_TRUE(daemon_.ProcessMeminfo(meminfo));
 }
 
-TEST_F(MetricsDaemonTest, ProcessMeminfo2) {
+TEST_F(MetricsCollectorTest, ProcessMeminfo2) {
   string meminfo = "MemTotal:        2000000 kB\nMemFree:         1000000 kB\n";
   // Not enough fields.
   EXPECT_FALSE(daemon_.ProcessMeminfo(meminfo));
 }
 
-TEST_F(MetricsDaemonTest, SendZramMetrics) {
+TEST_F(MetricsCollectorTest, SendZramMetrics) {
   EXPECT_TRUE(daemon_.testing_);
 
   // |compr_data_size| is the size in bytes of compressed data.
@@ -210,13 +203,13 @@
   const uint64_t zero_pages = 10 * 1000 * 1000 / page_size;
 
   CreateUint64ValueFile(
-      temp_dir_.path().Append(MetricsDaemon::kComprDataSizeName),
+      temp_dir_.path().Append(MetricsCollector::kComprDataSizeName),
       compr_data_size);
   CreateUint64ValueFile(
-      temp_dir_.path().Append(MetricsDaemon::kOrigDataSizeName),
+      temp_dir_.path().Append(MetricsCollector::kOrigDataSizeName),
       orig_data_size);
   CreateUint64ValueFile(
-      temp_dir_.path().Append(MetricsDaemon::kZeroPagesName), zero_pages);
+      temp_dir_.path().Append(MetricsCollector::kZeroPagesName), zero_pages);
 
   const uint64_t real_orig_size = orig_data_size + zero_pages * page_size;
   const uint64_t zero_ratio_percent =
diff --git a/metricsd/metrics_daemon.rc b/metricsd/metrics_daemon.rc
deleted file mode 100644
index 8b24749..0000000
--- a/metricsd/metrics_daemon.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-on post-fs-data
-    mkdir /data/misc/metrics 0770 system system
-
-service metrics_daemon /system/bin/metrics_daemon --uploader --foreground --logtosyslog
-    class late_start
-    user system
-    group system dbus inet
diff --git a/metricsd/metricsd.rc b/metricsd/metricsd.rc
new file mode 100644
index 0000000..b5e7b82
--- /dev/null
+++ b/metricsd/metricsd.rc
@@ -0,0 +1,7 @@
+on post-fs-data
+    mkdir /data/misc/metrics 0770 system system
+
+service metricsd /system/bin/metricsd --foreground --logtosyslog
+    class late_start
+    user system
+    group system dbus inet
diff --git a/metricsd/metricsd_main.cc b/metricsd/metricsd_main.cc
new file mode 100644
index 0000000..ab71e6b
--- /dev/null
+++ b/metricsd/metricsd_main.cc
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2015 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 <base/at_exit.h>
+#include <base/command_line.h>
+#include <base/files/file_path.h>
+#include <base/logging.h>
+#include <base/strings/string_util.h>
+#include <base/time/time.h>
+#include <brillo/flag_helper.h>
+#include <brillo/syslog_logging.h>
+
+#include "constants.h"
+#include "uploader/upload_service.h"
+
+
+int main(int argc, char** argv) {
+  DEFINE_bool(foreground, false, "Don't daemonize");
+
+  // Upload the metrics once and exit. (used for testing)
+  DEFINE_bool(uploader_test,
+              false,
+              "run the uploader once and exit");
+
+  // Upload Service flags.
+  DEFINE_int32(upload_interval_secs,
+               1800,
+               "Interval at which metrics_daemon sends the metrics. (needs "
+               "-uploader)");
+  DEFINE_string(server,
+                metrics::kMetricsServer,
+                "Server to upload the metrics to. (needs -uploader)");
+  DEFINE_string(metrics_directory,
+                metrics::kMetricsDirectory,
+                "Root of the configuration files (testing only)");
+
+  DEFINE_bool(logtostderr, false, "Log to standard error");
+  DEFINE_bool(logtosyslog, false, "Log to syslog");
+
+  brillo::FlagHelper::Init(argc, argv, "Brillo metrics daemon.");
+
+  int logging_location = (FLAGS_foreground ? brillo::kLogToStderr
+                          : brillo::kLogToSyslog);
+  if (FLAGS_logtosyslog)
+    logging_location = brillo::kLogToSyslog;
+
+  if (FLAGS_logtostderr)
+    logging_location = brillo::kLogToStderr;
+
+  // Also log to stderr when not running as daemon.
+  brillo::InitLog(logging_location | brillo::kLogHeader);
+
+  if (FLAGS_logtostderr && FLAGS_logtosyslog) {
+    LOG(ERROR) << "only one of --logtosyslog and --logtostderr can be set";
+    return 1;
+  }
+
+  if (!FLAGS_foreground && daemon(0, 0) != 0) {
+    return errno;
+  }
+
+  UploadService service(FLAGS_server,
+                        base::TimeDelta::FromSeconds(FLAGS_upload_interval_secs),
+                        base::FilePath(FLAGS_metrics_directory));
+
+  service.Run();
+}
diff --git a/metricsd/persistent_integer.cc b/metricsd/persistent_integer.cc
index e849f00..ddc4b50 100644
--- a/metricsd/persistent_integer.cc
+++ b/metricsd/persistent_integer.cc
@@ -22,7 +22,6 @@
 #include <base/posix/eintr_wrapper.h>
 
 #include "constants.h"
-#include "metrics/metrics_library.h"
 
 
 namespace chromeos_metrics {
diff --git a/metricsd/uploader/system_profile_cache.cc b/metricsd/uploader/system_profile_cache.cc
index 7a5eb93..8928a0d 100644
--- a/metricsd/uploader/system_profile_cache.cc
+++ b/metricsd/uploader/system_profile_cache.cc
@@ -84,6 +84,7 @@
     auto client = update_engine::UpdateEngineClient::CreateInstance();
     if (!client->GetChannel(&channel)) {
       LOG(ERROR) << "failed to read the current channel from update engine.";
+      return false;
     }
   }
 
diff --git a/metricsd/uploader/upload_service.cc b/metricsd/uploader/upload_service.cc
index b630cec..ca5024e 100644
--- a/metricsd/uploader/upload_service.cc
+++ b/metricsd/uploader/upload_service.cc
@@ -16,6 +16,8 @@
 
 #include "uploader/upload_service.h"
 
+#include <sysexits.h>
+
 #include <string>
 
 #include <base/bind.h>
@@ -39,38 +41,34 @@
 
 const int UploadService::kMaxFailedUpload = 10;
 
-UploadService::UploadService(SystemProfileSetter* setter,
-                             MetricsLibraryInterface* metrics_lib,
-                             const std::string& server)
-    : system_profile_setter_(setter),
-      metrics_lib_(metrics_lib),
-      histogram_snapshot_manager_(this),
+UploadService::UploadService(const std::string& server,
+                             const base::TimeDelta& upload_interval,
+                             const base::FilePath& metrics_directory)
+    : histogram_snapshot_manager_(this),
       sender_(new HttpSender(server)),
       failed_upload_count_(metrics::kFailedUploadCountName),
-      testing_(false) {
-}
-
-UploadService::UploadService(SystemProfileSetter* setter,
-                             MetricsLibraryInterface* metrics_lib,
-                             const std::string& server,
-                             bool testing)
-    : UploadService(setter, metrics_lib, server) {
-  testing_ = testing;
-}
-
-void UploadService::Init(const base::TimeDelta& upload_interval,
-                         const base::FilePath& metrics_directory) {
-  base::StatisticsRecorder::Initialize();
+      upload_interval_(upload_interval) {
   metrics_file_ = metrics_directory.Append(metrics::kMetricsEventsFileName);
   staged_log_path_ = metrics_directory.Append(metrics::kStagedLogName);
+  consent_file_ = metrics_directory.Append(metrics::kConsentFileName);
+}
 
-  if (!testing_) {
-    base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
-        base::Bind(&UploadService::UploadEventCallback,
-                   base::Unretained(this),
-                   upload_interval),
-        upload_interval);
-  }
+int UploadService::OnInit() {
+  base::StatisticsRecorder::Initialize();
+
+  system_profile_setter_.reset(new SystemProfileCache());
+
+  base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
+      base::Bind(&UploadService::UploadEventCallback,
+                 base::Unretained(this),
+                 upload_interval_),
+      upload_interval_);
+  return EX_OK;
+}
+
+void UploadService::InitForTest(SystemProfileSetter* setter) {
+  base::StatisticsRecorder::Initialize();
+  system_profile_setter_.reset(setter);
 }
 
 void UploadService::StartNewLog() {
@@ -114,7 +112,7 @@
 
 void UploadService::SendStagedLog() {
   // If metrics are not enabled, discard the log and exit.
-  if (!metrics_lib_->AreMetricsEnabled()) {
+  if (!AreMetricsEnabled()) {
     LOG(INFO) << "Metrics disabled. Don't upload metrics samples.";
     base::DeleteFile(staged_log_path_, false);
     return;
@@ -263,3 +261,8 @@
     failed_upload_count_.Set(0);
   }
 }
+
+bool UploadService::AreMetricsEnabled() {
+  return base::PathExists(consent_file_);
+}
+
diff --git a/metricsd/uploader/upload_service.h b/metricsd/uploader/upload_service.h
index 77df74b..7faf357 100644
--- a/metricsd/uploader/upload_service.h
+++ b/metricsd/uploader/upload_service.h
@@ -19,11 +19,11 @@
 
 #include <string>
 
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_flattener.h"
-#include "base/metrics/histogram_snapshot_manager.h"
+#include <base/metrics/histogram_base.h>
+#include <base/metrics/histogram_flattener.h>
+#include <base/metrics/histogram_snapshot_manager.h>
+#include <brillo/daemons/daemon.h>
 
-#include "metrics/metrics_library.h"
 #include "persistent_integer.h"
 #include "uploader/metrics_log.h"
 #include "uploader/sender.h"
@@ -67,14 +67,14 @@
 //    - if the upload fails, we keep the staged log in memory to retry
 //      uploading later.
 //
-class UploadService : public base::HistogramFlattener {
+class UploadService : public base::HistogramFlattener, public brillo::Daemon {
  public:
-  explicit UploadService(SystemProfileSetter* setter,
-                         MetricsLibraryInterface* metrics_lib,
-                         const std::string& server);
+  UploadService(const std::string& server,
+                const base::TimeDelta& upload_interval,
+                const base::FilePath& metrics_directory);
 
-  void Init(const base::TimeDelta& upload_interval,
-            const base::FilePath& metrics_directory);
+  // Initializes the upload service.
+  int OnInit();
 
   // Starts a new log. The log needs to be regenerated after each successful
   // launch as it is destroyed when staging the log.
@@ -114,11 +114,8 @@
   FRIEND_TEST(UploadServiceTest, UnknownCrashIgnored);
   FRIEND_TEST(UploadServiceTest, ValuesInConfigFileAreSent);
 
-  // Private constructor for use in unit testing.
-  UploadService(SystemProfileSetter* setter,
-                MetricsLibraryInterface* metrics_lib,
-                const std::string& server,
-                bool testing);
+  // Initializes the upload service for testing.
+  void InitForTest(SystemProfileSetter* setter);
 
   // If a staged log fails to upload more than kMaxFailedUpload times, it
   // will be discarded.
@@ -136,6 +133,9 @@
   // Adds a crash to the current log.
   void AddCrash(const std::string& crash_name);
 
+  // Returns true iff metrics reporting is enabled.
+  bool AreMetricsEnabled();
+
   // Aggregates all histogram available in memory and store them in the current
   // log.
   void GatherHistograms();
@@ -158,12 +158,14 @@
   MetricsLog* GetOrCreateCurrentLog();
 
   scoped_ptr<SystemProfileSetter> system_profile_setter_;
-  MetricsLibraryInterface* metrics_lib_;
   base::HistogramSnapshotManager histogram_snapshot_manager_;
   scoped_ptr<Sender> sender_;
   chromeos_metrics::PersistentInteger failed_upload_count_;
   scoped_ptr<MetricsLog> current_log_;
+  
+  base::TimeDelta upload_interval_;
 
+  base::FilePath consent_file_;
   base::FilePath metrics_file_;
   base::FilePath staged_log_path_;
 
diff --git a/metricsd/uploader/upload_service_test.cc b/metricsd/uploader/upload_service_test.cc
index e80db96..24e3127 100644
--- a/metricsd/uploader/upload_service_test.cc
+++ b/metricsd/uploader/upload_service_test.cc
@@ -44,11 +44,11 @@
     metrics_lib_.InitForTest(dir_.path());
     ASSERT_EQ(0, base::WriteFile(
         dir_.path().Append(metrics::kConsentFileName), "", 0));
-    upload_service_.reset(new UploadService(new MockSystemProfileSetter(),
-                                            &metrics_lib_, "", true));
+    upload_service_.reset(new UploadService("", base::TimeDelta(),
+                                            dir_.path()));
 
     upload_service_->sender_.reset(new SenderMock);
-    upload_service_->Init(base::TimeDelta::FromMinutes(30), dir_.path());
+    upload_service_->InitForTest(new MockSystemProfileSetter);
     upload_service_->GatherHistograms();
     upload_service_->Reset();
   }
@@ -58,7 +58,8 @@
   }
 
   void SetTestingProperty(const std::string& name, const std::string& value) {
-    base::FilePath filepath = dir_.path().Append("etc/os-release.d").Append(name);
+    base::FilePath filepath =
+        dir_.path().Append("etc/os-release.d").Append(name);
     ASSERT_TRUE(base::CreateDirectory(filepath.DirName()));
     ASSERT_EQ(
         value.size(),
@@ -159,8 +160,7 @@
 }
 
 TEST_F(UploadServiceTest, LogEmptyByDefault) {
-  UploadService upload_service(new MockSystemProfileSetter(), &metrics_lib_,
-                               "");
+  UploadService upload_service("", base::TimeDelta(), dir_.path());
 
   // current_log_ should be initialized later as it needs AtExitManager to exit
   // in order to gather system information from SysInfo.