Merge "Add libbinder_rpc_unstable.so to linker.config.json"
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp
index feafa73..f615780 100644
--- a/debuggerd/handler/debuggerd_fallback.cpp
+++ b/debuggerd/handler/debuggerd_fallback.cpp
@@ -87,6 +87,12 @@
 
     // TODO: Create this once and store it in a global?
     unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
+    // Do not use the thread cache here because it will call pthread_key_create
+    // which doesn't work in linker code. See b/189803009.
+    // Use a normal cached object because the process is stopped, and there
+    // is no chance of data changing between reads.
+    auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(getpid());
+    unwinder.SetProcessMemory(process_memory);
     dump_backtrace_thread(output_fd, &unwinder, thread);
   }
   __linker_disable_fallback_allocator();
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 6a49fdf..c87ce60 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -104,8 +104,6 @@
 static bool g_disable_verity = false;
 static bool g_disable_verification = false;
 
-static const std::string convert_fbe_marker_filename("convert_fbe");
-
 fastboot::FastBootDriver* fb = nullptr;
 
 enum fb_buffer_type {
@@ -429,7 +427,7 @@
             " snapshot-update merge      On devices that support snapshot-based updates, finish\n"
             "                            an in-progress update if it is in the \"merging\"\n"
             "                            phase.\n"
-            " fetch PARTITION            Fetch a partition image from the device."
+            " fetch PARTITION OUT_FILE   Fetch a partition image from the device."
             "\n"
             "boot image:\n"
             " boot KERNEL [RAMDISK [SECOND]]\n"
@@ -473,9 +471,6 @@
             " --disable-verification     Sets disable-verification when flashing vbmeta.\n"
             " --fs-options=OPTION[,OPTION]\n"
             "                            Enable filesystem features. OPTION supports casefold, projid, compress\n"
-#if !defined(_WIN32)
-            " --wipe-and-use-fbe         Enable file-based encryption, wiping userdata.\n"
-#endif
             // TODO: remove --unbuffered?
             " --unbuffered               Don't buffer input or output.\n"
             " --verbose, -v              Verbose output.\n"
@@ -593,10 +588,6 @@
 
 #define tmpfile win32_tmpfile
 
-static std::string make_temporary_directory() {
-    die("make_temporary_directory not supported under Windows, sorry!");
-}
-
 static int make_temporary_fd(const char* /*what*/) {
     // TODO: reimplement to avoid leaking a FILE*.
     return fileno(tmpfile());
@@ -610,15 +601,6 @@
     return std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
 }
 
-static std::string make_temporary_directory() {
-    std::string result(make_temporary_template());
-    if (mkdtemp(&result[0]) == nullptr) {
-        die("unable to create temporary directory with template %s: %s",
-            result.c_str(), strerror(errno));
-    }
-    return result;
-}
-
 static int make_temporary_fd(const char* what) {
     std::string path_template(make_temporary_template());
     int fd = mkstemp(&path_template[0]);
@@ -632,32 +614,6 @@
 
 #endif
 
-static std::string create_fbemarker_tmpdir() {
-    std::string dir = make_temporary_directory();
-    std::string marker_file = dir + "/" + convert_fbe_marker_filename;
-    int fd = open(marker_file.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0666);
-    if (fd == -1) {
-        die("unable to create FBE marker file %s locally: %s",
-            marker_file.c_str(), strerror(errno));
-    }
-    close(fd);
-    return dir;
-}
-
-static void delete_fbemarker_tmpdir(const std::string& dir) {
-    std::string marker_file = dir + "/" + convert_fbe_marker_filename;
-    if (unlink(marker_file.c_str()) == -1) {
-        fprintf(stderr, "Unable to delete FBE marker file %s locally: %d, %s\n",
-            marker_file.c_str(), errno, strerror(errno));
-        return;
-    }
-    if (rmdir(dir.c_str()) == -1) {
-        fprintf(stderr, "Unable to delete FBE marker directory %s locally: %d, %s\n",
-            dir.c_str(), errno, strerror(errno));
-        return;
-    }
-}
-
 static unique_fd unzip_to_file(ZipArchiveHandle zip, const char* entry_name) {
     unique_fd fd(make_temporary_fd(entry_name));
 
@@ -1895,7 +1851,6 @@
     bool skip_reboot = false;
     bool wants_set_active = false;
     bool skip_secondary = false;
-    bool set_fbe_marker = false;
     bool force_flash = false;
     unsigned fs_options = 0;
     int longindex;
@@ -1933,9 +1888,6 @@
         {"unbuffered", no_argument, 0, 0},
         {"verbose", no_argument, 0, 'v'},
         {"version", no_argument, 0, 0},
-#if !defined(_WIN32)
-        {"wipe-and-use-fbe", no_argument, 0, 0},
-#endif
         {0, 0, 0, 0}
     };
 
@@ -1989,11 +1941,6 @@
                 fprintf(stdout, "fastboot version %s-%s\n", PLATFORM_TOOLS_VERSION, android::build::GetBuildNumber().c_str());
                 fprintf(stdout, "Installed as %s\n", android::base::GetExecutablePath().c_str());
                 return 0;
-#if !defined(_WIN32)
-            } else if (name == "wipe-and-use-fbe") {
-                wants_wipe = true;
-                set_fbe_marker = true;
-#endif
             } else {
                 die("unknown option %s", longopts[longindex].name);
             }
@@ -2305,14 +2252,7 @@
             }
             if (partition_type.empty()) continue;
             fb->Erase(partition);
-            if (partition == "userdata" && set_fbe_marker) {
-                fprintf(stderr, "setting FBE marker on initial userdata...\n");
-                std::string initial_userdata_dir = create_fbemarker_tmpdir();
-                fb_perform_format(partition, 1, partition_type, "", initial_userdata_dir, fs_options);
-                delete_fbemarker_tmpdir(initial_userdata_dir);
-            } else {
-                fb_perform_format(partition, 1, partition_type, "", "", fs_options);
-            }
+            fb_perform_format(partition, 1, partition_type, "", "", fs_options);
         }
     }
     if (wants_set_active) {
diff --git a/fs_mgr/libdm/dm_target.cpp b/fs_mgr/libdm/dm_target.cpp
index b0639e6..90d91a0 100644
--- a/fs_mgr/libdm/dm_target.cpp
+++ b/fs_mgr/libdm/dm_target.cpp
@@ -109,6 +109,10 @@
     optional_args_.emplace_back("ignore_zero_blocks");
 }
 
+void DmTargetVerity::CheckAtMostOnce() {
+    optional_args_.emplace_back("check_at_most_once");
+}
+
 std::string DmTargetVerity::GetParameterString() const {
     std::string base = android::base::Join(base_args_, " ");
     if (optional_args_.empty()) {
diff --git a/fs_mgr/libdm/include/libdm/dm_target.h b/fs_mgr/libdm/include/libdm/dm_target.h
index 478a3c6..9543058 100644
--- a/fs_mgr/libdm/include/libdm/dm_target.h
+++ b/fs_mgr/libdm/include/libdm/dm_target.h
@@ -127,6 +127,7 @@
     void UseFec(const std::string& device, uint32_t num_roots, uint32_t num_blocks, uint32_t start);
     void SetVerityMode(const std::string& mode);
     void IgnoreZeroBlocks();
+    void CheckAtMostOnce();
 
     std::string name() const override { return "verity"; }
     std::string GetParameterString() const override;
diff --git a/fs_mgr/libfs_avb/avb_util.cpp b/fs_mgr/libfs_avb/avb_util.cpp
index 31494c1..e913d50 100644
--- a/fs_mgr/libfs_avb/avb_util.cpp
+++ b/fs_mgr/libfs_avb/avb_util.cpp
@@ -92,6 +92,10 @@
     // Always use ignore_zero_blocks.
     target.IgnoreZeroBlocks();
 
+    if (hashtree_desc.flags & AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE) {
+        target.CheckAtMostOnce();
+    }
+
     LINFO << "Built verity table: '" << target.GetParameterString() << "'";
 
     return table->AddTarget(std::make_unique<android::dm::DmTargetVerity>(target));
diff --git a/fs_mgr/libsnapshot/cow_writer.cpp b/fs_mgr/libsnapshot/cow_writer.cpp
index 51c00a9..0a7ceab 100644
--- a/fs_mgr/libsnapshot/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/cow_writer.cpp
@@ -58,6 +58,12 @@
     return EmitRawBlocks(new_block_start, data, size);
 }
 
+bool AddXorBlocks(uint32_t /*new_block_start*/, const void* /*data*/, size_t /*size*/,
+                  uint32_t /*old_block*/, uint16_t /*offset*/) {
+    LOG(ERROR) << "AddXorBlocks not yet implemented";
+    return false;
+}
+
 bool ICowWriter::AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) {
     uint64_t last_block = new_block_start + num_blocks - 1;
     if (!ValidateNewBlock(last_block)) {
@@ -70,6 +76,11 @@
     return EmitLabel(label);
 }
 
+bool AddSequenceData(size_t /*num_ops*/, const uint32_t* /*data*/) {
+    LOG(ERROR) << "AddSequenceData not yet implemented";
+    return false;
+}
+
 bool ICowWriter::ValidateNewBlock(uint64_t new_block) {
     if (options_.max_blocks && new_block >= options_.max_blocks.value()) {
         LOG(ERROR) << "New block " << new_block << " exceeds maximum block count "
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
index f43ea68..fbe6461 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_writer.h
@@ -55,12 +55,19 @@
     // Encode a sequence of raw blocks. |size| must be a multiple of the block size.
     bool AddRawBlocks(uint64_t new_block_start, const void* data, size_t size);
 
+    // Add a sequence of xor'd blocks. |size| must be a multiple of the block size.
+    bool AddXorBlocks(uint32_t new_block_start, const void* data, size_t size, uint32_t old_block,
+                      uint16_t offset);
+
     // Encode a sequence of zeroed blocks. |size| must be a multiple of the block size.
     bool AddZeroBlocks(uint64_t new_block_start, uint64_t num_blocks);
 
     // Add a label to the op sequence.
     bool AddLabel(uint64_t label);
 
+    // Add sequence data for op merging. Data is a list of the destination block numbers.
+    bool AddSequenceData(size_t num_ops, const uint32_t* data);
+
     // Flush all pending writes. This must be called before closing the writer
     // to ensure that the correct headers and footers are written.
     virtual bool Finalize() = 0;
diff --git a/fs_mgr/libsnapshot/inspect_cow.cpp b/fs_mgr/libsnapshot/inspect_cow.cpp
index 4a84fba..1dc61af 100644
--- a/fs_mgr/libsnapshot/inspect_cow.cpp
+++ b/fs_mgr/libsnapshot/inspect_cow.cpp
@@ -106,6 +106,8 @@
         std::cout << "Header size: " << header.header_size << "\n";
         std::cout << "Footer size: " << header.footer_size << "\n";
         std::cout << "Block size: " << header.block_size << "\n";
+        std::cout << "Num merge ops: " << header.num_merge_ops << "\n";
+        std::cout << "RA buffer size: " << header.buffer_size << "\n";
         std::cout << "\n";
         if (has_footer) {
             std::cout << "Total Ops size: " << footer.op.ops_size << "\n";
diff --git a/init/README.md b/init/README.md
index 75dc328..4b04628 100644
--- a/init/README.md
+++ b/init/README.md
@@ -406,6 +406,33 @@
    3. Any time that property c transitions to value d, while property a already equals b.
 
 
+Trigger Sequence
+----------------
+
+Init uses the following sequence of triggers during early boot. These are the
+built-in triggers defined in init.cpp.
+
+   1. `early-init` - The first in the sequence, triggered after cgroups has been configured
+      but before ueventd's coldboot is complete.
+   2. `init` - Triggered after coldboot is complete.
+   3. `charger` - Triggered if `ro.bootmode == "charger"`.
+   4. `late-init` - Triggered if `ro.bootmode != "charger"`, or via healthd triggering a boot
+      from charging mode.
+
+Remaining triggers are configured in `init.rc` and are not built-in. The default sequence for
+these is specified under the "on late-init" event in `init.rc`. Actions internal to `init.rc`
+have been omitted.
+
+   1. `early-fs` - Start vold.
+   2. `fs` - Vold is up. Mount partitions not marked as first-stage or latemounted.
+   3. `post-fs` - Configure anything dependent on early mounts.
+   4. `late-fs` - Mount partitions marked as latemounted.
+   5. `post-fs-data` - Mount and configure `/data`; set up encryption. `/metadata` is
+      reformatted here if it couldn't mount in first-stage init.
+   6. `zygote-start` - Start the zygote.
+   7. `early-boot` - After zygote has started.
+   8. `boot` - After `early-boot` actions have completed.
+
 Commands
 --------
 
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index bd94621..b5fa475 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -476,6 +476,33 @@
     },
 
     {
+      "Name": "SFMainPolicy",
+      "Actions": [
+        {
+          "Name": "JoinCgroup",
+          "Params":
+          {
+            "Controller": "cpuset",
+            "Path": "system-background"
+          }
+        }
+      ]
+    },
+    {
+      "Name": "SFRenderEnginePolicy",
+      "Actions": [
+        {
+          "Name": "JoinCgroup",
+          "Params":
+          {
+            "Controller": "cpuset",
+            "Path": "system-background"
+          }
+        }
+      ]
+    },
+
+    {
       "Name": "PerfBoost",
       "Actions": [
         {
diff --git a/rootdir/init.rc b/rootdir/init.rc
index c6b74bc..7ba476b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -884,6 +884,8 @@
     # Create mirror directory for jit profiles
     mkdir /data_mirror/cur_profiles 0700 root root
     mount none /data/misc/profiles/cur /data_mirror/cur_profiles bind rec
+    mkdir /data_mirror/ref_profiles 0700 root root
+    mount none /data/misc/profiles/ref /data_mirror/ref_profiles bind rec
 
     mkdir /data/cache 0770 system cache encryption=Require
     mkdir /data/cache/recovery 0770 system cache
@@ -1265,6 +1267,7 @@
   umount /data_mirror/data_ce/null
   umount /data_mirror/data_de/null
   umount /data_mirror/cur_profiles
+  umount /data_mirror/ref_profiles
   umount /data_mirror
   remount_userdata
   start bootanim