Merge "Implement basic libsnapshot functionality."
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index be88eae..7c9804c 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -150,6 +150,25 @@
     return base_device_ + " " + cow_device_ + " " + mode + " " + std::to_string(chunk_size_);
 }
 
+// Computes the percentage of complition for snapshot status.
+// @sectors_initial is the number of sectors_allocated stored right before
+// starting the merge.
+double DmTargetSnapshot::MergePercent(const DmTargetSnapshot::Status& status,
+                                      uint64_t sectors_initial) {
+    uint64_t s = status.sectors_allocated;
+    uint64_t t = status.total_sectors;
+    uint64_t m = status.metadata_sectors;
+    uint64_t i = sectors_initial == 0 ? t : sectors_initial;
+
+    if (t <= s || i <= s) {
+        return 0.0;
+    }
+    if (s == 0 || t == 0 || s <= m) {
+        return 100.0;
+    }
+    return 100.0 / (i - m) * (i - s);
+}
+
 bool DmTargetSnapshot::ReportsOverflow(const std::string& target_type) {
     DeviceMapper& dm = DeviceMapper::Instance();
     DmTargetTypeInfo info;
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 16be0d5..eed21dc 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -483,6 +483,60 @@
     EXPECT_TRUE(DmTargetSnapshot::ParseStatusText("Overflow", &status));
 }
 
+TEST(libdm, DmSnapshotMergePercent) {
+    DmTargetSnapshot::Status status;
+
+    // Correct input
+    status.sectors_allocated = 1000;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 0;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status), 1.0);
+
+    status.sectors_allocated = 500;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 0;
+    EXPECT_GE(DmTargetSnapshot::MergePercent(status), 49.0);
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status), 51.0);
+
+    status.sectors_allocated = 0;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 0;
+    EXPECT_GE(DmTargetSnapshot::MergePercent(status), 99.0);
+
+    status.sectors_allocated = 500;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 500;
+    EXPECT_GE(DmTargetSnapshot::MergePercent(status), 99.0);
+
+    status.sectors_allocated = 500;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 0;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status, 500), 1.0);
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status, 1000), 51.0);
+    EXPECT_GE(DmTargetSnapshot::MergePercent(status, 1000), 49.0);
+
+    // Robustness
+    status.sectors_allocated = 2000;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 0;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
+
+    status.sectors_allocated = 2000;
+    status.total_sectors = 1000;
+    status.metadata_sectors = 2000;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
+
+    status.sectors_allocated = 2000;
+    status.total_sectors = 0;
+    status.metadata_sectors = 2000;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status), 0.0);
+
+    status.sectors_allocated = 1000;
+    status.total_sectors = 0;
+    status.metadata_sectors = 1000;
+    EXPECT_LE(DmTargetSnapshot::MergePercent(status, 0), 0.0);
+}
+
 TEST(libdm, CryptArgs) {
     DmTargetCrypt target1(0, 512, "sha1", "abcdefgh", 50, "/dev/loop0", 100);
     ASSERT_EQ(target1.name(), "crypt");
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index 6754920..a66ab7a 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -216,6 +216,7 @@
         std::string error;
     };
 
+    static double MergePercent(const Status& status, uint64_t sectors_initial = 0);
     static bool ParseStatusText(const std::string& text, Status* status);
     static bool ReportsOverflow(const std::string& target_type);
     static bool GetDevicesFromParams(const std::string& params, std::string* base_device,
diff --git a/fs_mgr/tools/dmctl.cpp b/fs_mgr/tools/dmctl.cpp
index 4fb0b83..2738457 100644
--- a/fs_mgr/tools/dmctl.cpp
+++ b/fs_mgr/tools/dmctl.cpp
@@ -197,19 +197,12 @@
     char** argv_;
 };
 
-static int DmCreateCmdHandler(int argc, char** argv) {
-    if (argc < 1) {
-        std::cerr << "Usage: dmctl create <dm-name> [-ro] <targets...>" << std::endl;
-        return -EINVAL;
-    }
-    std::string name = argv[0];
-
+static bool parse_table_args(DmTable* table, int argc, char** argv) {
     // Parse extended options first.
-    DmTable table;
     int arg_index = 1;
     while (arg_index < argc && argv[arg_index][0] == '-') {
         if (strcmp(argv[arg_index], "-ro") == 0) {
-            table.set_readonly(true);
+            table->set_readonly(true);
             arg_index++;
         } else {
             std::cerr << "Unrecognized option: " << argv[arg_index] << std::endl;
@@ -221,15 +214,30 @@
     TargetParser parser(argc - arg_index, argv + arg_index);
     while (parser.More()) {
         std::unique_ptr<DmTarget> target = parser.Next();
-        if (!target || !table.AddTarget(std::move(target))) {
+        if (!target || !table->AddTarget(std::move(target))) {
             return -EINVAL;
         }
     }
 
-    if (table.num_targets() == 0) {
+    if (table->num_targets() == 0) {
         std::cerr << "Must define at least one target." << std::endl;
         return -EINVAL;
     }
+    return 0;
+}
+
+static int DmCreateCmdHandler(int argc, char** argv) {
+    if (argc < 1) {
+        std::cerr << "Usage: dmctl create <dm-name> [-ro] <targets...>" << std::endl;
+        return -EINVAL;
+    }
+    std::string name = argv[0];
+
+    DmTable table;
+    int ret = parse_table_args(&table, argc, argv);
+    if (ret) {
+        return ret;
+    }
 
     DeviceMapper& dm = DeviceMapper::Instance();
     if (!dm.CreateDevice(name, table)) {
@@ -255,6 +263,27 @@
     return 0;
 }
 
+static int DmReplaceCmdHandler(int argc, char** argv) {
+    if (argc < 1) {
+        std::cerr << "Usage: dmctl replace <dm-name> <targets...>" << std::endl;
+        return -EINVAL;
+    }
+    std::string name = argv[0];
+
+    DmTable table;
+    int ret = parse_table_args(&table, argc, argv);
+    if (ret) {
+        return ret;
+    }
+
+    DeviceMapper& dm = DeviceMapper::Instance();
+    if (!dm.LoadTableAndActivate(name, table)) {
+        std::cerr << "Failed to replace device-mapper table to: " << name << std::endl;
+        return -EIO;
+    }
+    return 0;
+}
+
 static int DmListTargets(DeviceMapper& dm, [[maybe_unused]] int argc,
                          [[maybe_unused]] char** argv) {
     std::vector<DmTargetTypeInfo> targets;
@@ -469,6 +498,7 @@
         // clang-format off
         {"create", DmCreateCmdHandler},
         {"delete", DmDeleteCmdHandler},
+        {"replace", DmReplaceCmdHandler},
         {"list", DmListCmdHandler},
         {"help", HelpCmdHandler},
         {"getpath", GetPathCmdHandler},
diff --git a/init/Android.bp b/init/Android.bp
index 31e4173..6501900 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -93,12 +93,16 @@
         "libutils",
     ],
     bootstrap: true,
+    visibility: [":__subpackages__"],
 }
 
 cc_library_static {
     name: "libinit",
     recovery_available: true,
-    defaults: ["init_defaults", "selinux_policy_version"],
+    defaults: [
+        "init_defaults",
+        "selinux_policy_version",
+    ],
     srcs: [
         "action.cpp",
         "action_manager.cpp",
@@ -143,7 +147,10 @@
         "ueventd_parser.cpp",
         "util.cpp",
     ],
-    whole_static_libs: ["libcap", "com.android.sysprop.apex"],
+    whole_static_libs: [
+        "libcap",
+        "com.android.sysprop.apex",
+    ],
     header_libs: ["bootimg_headers"],
     proto: {
         type: "lite",
@@ -153,7 +160,10 @@
     target: {
         recovery: {
             cflags: ["-DRECOVERY"],
-            exclude_shared_libs: ["libbinder", "libutils"],
+            exclude_shared_libs: [
+                "libbinder",
+                "libutils",
+            ],
         },
     },
 }
@@ -182,7 +192,10 @@
     target: {
         recovery: {
             cflags: ["-DRECOVERY"],
-            exclude_shared_libs: ["libbinder", "libutils"],
+            exclude_shared_libs: [
+                "libbinder",
+                "libutils",
+            ],
         },
     },
 }
@@ -283,7 +296,7 @@
     },
     generated_headers: [
         "generated_stub_builtin_function_map",
-        "generated_android_ids"
+        "generated_android_ids",
     ],
     target: {
         android: {
diff --git a/init/host_init_verifier.cpp b/init/host_init_verifier.cpp
index a5a5b1b..dce3eda 100644
--- a/init/host_init_verifier.cpp
+++ b/init/host_init_verifier.cpp
@@ -171,12 +171,12 @@
 #include "generated_stub_builtin_function_map.h"
 
 void PrintUsage() {
-    std::cout << "usage: host_init_verifier [-p FILE] -k FILE <init rc file>\n"
+    std::cout << "usage: host_init_verifier [-p FILE] -i FILE <init rc file>\n"
                  "\n"
                  "Tests an init script for correctness\n"
                  "\n"
                  "-p FILE\tSearch this passwd file for users and groups\n"
-                 "-k FILE\tUse this file as a space-separated list of known interfaces\n"
+                 "-i FILE\tParse this JSON file for the HIDL interface inheritance hierarchy\n"
               << std::endl;
 }
 
@@ -217,7 +217,7 @@
     argc -= optind;
     argv += optind;
 
-    if (argc != 1) {
+    if (argc != 1 || interface_inheritance_hierarchy_file.empty()) {
         PrintUsage();
         return EXIT_FAILURE;
     }
diff --git a/init/service.cpp b/init/service.cpp
index e60c20d..9537843 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -167,6 +167,15 @@
             property_set(boottime_property, std::to_string(start_ns));
         }
     }
+
+    // init.svc_debug_pid.* properties are only for tests, and should not be used
+    // on device for security checks.
+    std::string pid_property = "init.svc_debug_pid." + name_;
+    if (new_state == "running") {
+        property_set(pid_property, std::to_string(pid_));
+    } else if (new_state == "stopped") {
+        property_set(pid_property, "");
+    }
 }
 
 void Service::KillProcessGroup(int signal) {
diff --git a/init/test_utils/Android.bp b/init/test_utils/Android.bp
new file mode 100644
index 0000000..1cb05b6
--- /dev/null
+++ b/init/test_utils/Android.bp
@@ -0,0 +1,27 @@
+cc_library_static {
+    name: "libinit_test_utils",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Wno-unused-parameter",
+        "-Werror",
+    ],
+    srcs: [
+        "service_utils.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libjsoncpp",
+        "libprotobuf-cpp-lite",
+        "libhidl-gen-utils",
+    ],
+    whole_static_libs: [
+        "libinit",
+        "libpropertyinfoparser",
+    ],
+    static_libs: [
+        "libbase",
+    ],
+    export_include_dirs: ["include"], // for tests
+}
diff --git a/init/test_utils/include/init-test-utils/service_utils.h b/init/test_utils/include/init-test-utils/service_utils.h
new file mode 100644
index 0000000..3ec61d4
--- /dev/null
+++ b/init/test_utils/include/init-test-utils/service_utils.h
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2019 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.
+//
+
+#pragma once
+
+#include <map>
+#include <set>
+
+#include <android-base/result.h>
+#include <hidl-util/FqInstance.h>
+
+namespace android {
+namespace init {
+
+using ServiceInterfacesMap = std::map<std::string, std::set<android::FqInstance>>;
+android::base::Result<ServiceInterfacesMap> GetOnDeviceServiceInterfacesMap();
+
+}  // namespace init
+}  // namespace android
diff --git a/init/test_utils/service_utils.cpp b/init/test_utils/service_utils.cpp
new file mode 100644
index 0000000..bc00702
--- /dev/null
+++ b/init/test_utils/service_utils.cpp
@@ -0,0 +1,63 @@
+//
+// Copyright (C) 2019 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 <string>
+
+#include <android-base/logging.h>
+
+#include "../parser.h"
+#include "../service.h"
+#include "../service_list.h"
+#include "../service_parser.h"
+#include "include/init-test-utils/service_utils.h"
+
+namespace android {
+namespace init {
+
+android::base::Result<ServiceInterfacesMap> GetOnDeviceServiceInterfacesMap() {
+    ServiceList& service_list = ServiceList::GetInstance();
+    Parser parser;
+    parser.AddSectionParser("service",
+                            std::make_unique<ServiceParser>(&service_list, nullptr, std::nullopt));
+    for (const auto& location : {
+                 "/init.rc",
+                 "/system/etc/init",
+                 "/system_ext/etc/init",
+                 "/product/etc/init",
+                 "/odm/etc/init",
+                 "/vendor/etc/init",
+         }) {
+        parser.ParseConfig(location);
+    }
+
+    ServiceInterfacesMap result;
+    for (const auto& service : service_list.services()) {
+        // Create an entry for all services, including services that may not
+        // have any declared interfaces.
+        result[service->name()] = std::set<android::FqInstance>();
+        for (const auto& intf : service->interfaces()) {
+            android::FqInstance fqInstance;
+            if (!fqInstance.setTo(intf)) {
+                return android::base::Error() << "Unable to parse interface: '" << intf << "'";
+            }
+            result[service->name()].insert(fqInstance);
+        }
+    }
+    return result;
+}
+
+}  // namespace init
+}  // namespace android
diff --git a/libutils/Unicode.cpp b/libutils/Unicode.cpp
index 24a745a..b08e061 100644
--- a/libutils/Unicode.cpp
+++ b/libutils/Unicode.cpp
@@ -452,48 +452,6 @@
     *codePoint |= 0x3F & byte;
 }
 
-size_t utf8_to_utf32_length(const char *src, size_t src_len)
-{
-    if (src == nullptr || src_len == 0) {
-        return 0;
-    }
-    size_t ret = 0;
-    const char* cur;
-    const char* end;
-    size_t num_to_skip;
-    for (cur = src, end = src + src_len, num_to_skip = 1;
-         cur < end;
-         cur += num_to_skip, ret++) {
-        const char first_char = *cur;
-        num_to_skip = 1;
-        if ((first_char & 0x80) == 0) {  // ASCII
-            continue;
-        }
-        int32_t mask;
-
-        for (mask = 0x40; (first_char & mask); num_to_skip++, mask >>= 1) {
-        }
-    }
-    return ret;
-}
-
-void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst)
-{
-    if (src == nullptr || src_len == 0 || dst == nullptr) {
-        return;
-    }
-
-    const char* cur = src;
-    const char* const end = src + src_len;
-    char32_t* cur_utf32 = dst;
-    while (cur < end) {
-        size_t num_read;
-        *cur_utf32++ = static_cast<char32_t>(utf32_at_internal(cur, &num_read));
-        cur += num_read;
-    }
-    *cur_utf32 = 0;
-}
-
 static inline uint32_t utf8_to_utf32_codepoint(const uint8_t *src, size_t length)
 {
     uint32_t unicode;
diff --git a/libutils/include/utils/Unicode.h b/libutils/include/utils/Unicode.h
index a2aaa47..fc6712d 100644
--- a/libutils/include/utils/Unicode.h
+++ b/libutils/include/utils/Unicode.h
@@ -129,18 +129,6 @@
 ssize_t utf8_length(const char *src);
 
 /**
- * Measure the length of a UTF-32 string.
- */
-size_t utf8_to_utf32_length(const char *src, size_t src_len);
-
-/**
- * Stores a UTF-32 string converted from "src" in "dst". "dst" must be large
- * enough to store the entire converted string as measured by
- * utf8_to_utf32_length plus space for a NUL terminator.
- */
-void utf8_to_utf32(const char* src, size_t src_len, char32_t* dst);
-
-/**
  * Returns the UTF-16 length of UTF-8 string "src". Returns -1 in case
  * it's invalid utf8. No buffer over-read occurs because of bound checks. Using overreadIsFatal you
  * can ask to log a message and fail in case the invalid utf8 could have caused an override if no
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 6e38d95..6507711 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -899,6 +899,11 @@
             case 0:
                 // only long options
                 if (long_options[option_index].name == pid_str) {
+                    if (pid != 0) {
+                        logcat_panic(context, HELP_TRUE, "Only supports one PID argument.\n");
+                        goto exit;
+                    }
+
                     // ToDo: determine runtime PID_MAX?
                     if (!getSizeTArg(optarg, &pid, 1)) {
                         logcat_panic(context, HELP_TRUE, "%s %s out of range\n",
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 6897663..1d934a2 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -164,8 +164,10 @@
 }
 
 void storaged_t::add_user_ce(userid_t user_id) {
-    load_proto(user_id);
-    proto_loaded[user_id] = true;
+    if (!proto_loaded[user_id]) {
+        load_proto(user_id);
+        proto_loaded[user_id] = true;
+    }
 }
 
 void storaged_t::remove_user_ce(userid_t user_id) {