Update NDK prebuilts to build 5824028.

Taken from branch aosp-simpleperf-release.

Bug: None
Test: run test.py on linux/mac/windows.

Change-Id: Ifac9ba61fc07300208b7ef25d46be137da70d801
diff --git a/api_profiler.py b/api_profiler.py
new file mode 100755
index 0000000..424de69
--- /dev/null
+++ b/api_profiler.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# 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.
+#
+
+"""
+    This script is part of controlling simpleperf recording in user code. It is used to prepare
+    profiling environment (upload simpleperf to device and enable profiling) before recording
+    and collect recording data on host after recording.
+    Controlling simpleperf recording is done in below steps:
+    1. Add simpleperf Java API/C++ API to the app's source code. And call the API in user code.
+    2. Run `api_profiler.py prepare` to prepare profiling environment.
+    3. Run the app one or more times to generate recording data.
+    4. Run `api_profiler.py collect` to collect recording data on host.
+"""
+
+from __future__ import print_function
+import argparse
+import os
+import os.path
+import shutil
+import zipfile
+
+from utils import AdbHelper, get_target_binary_path, log_exit, log_info, remove
+
+def prepare_recording(args):
+    adb = AdbHelper()
+    enable_profiling_on_device(adb, args)
+    upload_simpleperf_to_device(adb)
+    run_simpleperf_prepare_cmd(adb)
+
+def enable_profiling_on_device(adb, args):
+    android_version = adb.get_android_version()
+    if android_version >= 10:
+        adb.set_property('debug.perf_event_max_sample_rate', str(args.max_sample_rate[0]))
+        adb.set_property('debug.perf_cpu_time_max_percent', str(args.max_cpu_percent[0]))
+        adb.set_property('debug.perf_event_mlock_kb', str(args.max_memory_in_kb[0]))
+    adb.set_property('security.perf_harden', '0')
+
+def upload_simpleperf_to_device(adb):
+    device_arch = adb.get_device_arch()
+    simpleperf_binary = get_target_binary_path(device_arch, 'simpleperf')
+    adb.check_run(['push', simpleperf_binary, '/data/local/tmp'])
+    adb.check_run(['shell', 'chmod', 'a+x', '/data/local/tmp/simpleperf'])
+
+def run_simpleperf_prepare_cmd(adb):
+    adb.check_run(['shell', '/data/local/tmp/simpleperf', 'api-prepare'])
+
+
+def collect_data(args):
+    adb = AdbHelper()
+    if not os.path.isdir(args.out_dir):
+        os.makedirs(args.out_dir)
+    download_recording_data(adb, args)
+    unzip_recording_data(args)
+
+def download_recording_data(adb, args):
+    """ download recording data to simpleperf_data.zip."""
+    upload_simpleperf_to_device(adb)
+    adb.check_run(['shell', '/data/local/tmp/simpleperf', 'api-collect', '--app', args.app[0],
+                   '-o', '/data/local/tmp/simpleperf_data.zip'])
+    adb.check_run(['pull', '/data/local/tmp/simpleperf_data.zip', args.out_dir])
+    adb.check_run(['shell', 'rm', '-rf', '/data/local/tmp/simpleperf_data'])
+
+def unzip_recording_data(args):
+    zip_file_path = os.path.join(args.out_dir, 'simpleperf_data.zip')
+    with zipfile.ZipFile(zip_file_path, 'r') as zip_fh:
+        names = zip_fh.namelist()
+        log_info('There are %d recording data files.' % len(names))
+        for name in names:
+            log_info('recording file: %s' % os.path.join(args.out_dir, name))
+            zip_fh.extract(name, args.out_dir)
+    remove(zip_file_path)
+
+class ArgumentHelpFormatter(argparse.ArgumentDefaultsHelpFormatter,
+                            argparse.RawDescriptionHelpFormatter):
+    pass
+
+def main():
+    parser = argparse.ArgumentParser(description=__doc__,
+                                     formatter_class=ArgumentHelpFormatter)
+    subparsers = parser.add_subparsers()
+    prepare_parser = subparsers.add_parser('prepare', help='Prepare recording on device.',
+                                           formatter_class=ArgumentHelpFormatter)
+    prepare_parser.add_argument('--max-sample-rate', nargs=1, type=int, default=[100000], help="""
+                                Set max sample rate (only on Android >= Q).""")
+    prepare_parser.add_argument('--max-cpu-percent', nargs=1, type=int, default=[25], help="""
+                                Set max cpu percent for recording (only on Android >= Q).""")
+    prepare_parser.add_argument('--max-memory-in-kb', nargs=1, type=int,
+                                default=[(1024 + 1) * 4 * 8], help="""
+                                Set max kernel buffer size for recording (only on Android >= Q).
+                                """)
+    prepare_parser.set_defaults(func=prepare_recording)
+    collect_parser = subparsers.add_parser('collect', help='Collect recording data.',
+                                           formatter_class=ArgumentHelpFormatter)
+    collect_parser.add_argument('-p', '--app', nargs=1, required=True, help="""
+                                The app package name of the app profiled.""")
+    collect_parser.add_argument('-o', '--out-dir', default='simpleperf_data', help="""
+                                The directory to store recording data.""")
+    collect_parser.set_defaults(func=collect_data)
+    args = parser.parse_args()
+    args.func(args)
+
+if __name__ == '__main__':
+    main()
diff --git a/app_api/cpp/simpleperf.cpp b/app_api/cpp/simpleperf.cpp
new file mode 100644
index 0000000..54b331a
--- /dev/null
+++ b/app_api/cpp/simpleperf.cpp
@@ -0,0 +1,504 @@
+/*
+ * 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 "simpleperf.h"
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <mutex>
+#include <sstream>
+#include <android/log.h>
+
+namespace simpleperf {
+
+enum RecordCmd {
+  CMD_PAUSE_RECORDING = 1,
+  CMD_RESUME_RECORDING,
+};
+
+class RecordOptionsImpl {
+ public:
+  std::string output_filename;
+  std::string event = "cpu-cycles";
+  size_t freq = 4000;
+  double duration_in_second = 0.0;
+  std::vector<pid_t> threads;
+  bool dwarf_callgraph = false;
+  bool fp_callgraph = false;
+  bool trace_offcpu = false;
+};
+
+RecordOptions::RecordOptions() : impl_(new RecordOptionsImpl) {
+}
+
+RecordOptions::~RecordOptions() {
+  delete impl_;
+}
+
+RecordOptions& RecordOptions::SetOutputFilename(const std::string &filename) {
+  impl_->output_filename = filename;
+  return *this;
+}
+
+RecordOptions& RecordOptions::SetEvent(const std::string &event) {
+  impl_->event = event;
+  return *this;
+}
+
+RecordOptions& RecordOptions::SetSampleFrequency(size_t freq) {
+  impl_->freq = freq;
+  return *this;
+}
+
+RecordOptions& RecordOptions::SetDuration(double duration_in_second) {
+  impl_->duration_in_second = duration_in_second;
+  return *this;
+}
+
+RecordOptions& RecordOptions::SetSampleThreads(const std::vector<pid_t> &threads) {
+  impl_->threads = threads;
+  return *this;
+}
+
+RecordOptions& RecordOptions::RecordDwarfCallGraph() {
+  impl_->dwarf_callgraph = true;
+  impl_->fp_callgraph = false;
+  return *this;
+}
+
+RecordOptions& RecordOptions::RecordFramePointerCallGraph() {
+  impl_->fp_callgraph = true;
+  impl_->dwarf_callgraph = false;
+  return *this;
+}
+
+RecordOptions& RecordOptions::TraceOffCpu() {
+  impl_->trace_offcpu = true;
+  return *this;
+}
+
+static std::string GetDefaultOutputFilename() {
+  time_t t = time(nullptr);
+  struct tm tm;
+  if (localtime_r(&t, &tm) != &tm) {
+    return "perf.data";
+  }
+  char* buf = nullptr;
+  asprintf(&buf, "perf-%02d-%02d-%02d-%02d-%02d.data", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
+           tm.tm_min, tm.tm_sec);
+  std::string result = buf;
+  free(buf);
+  return result;
+}
+
+std::vector<std::string> RecordOptions::ToRecordArgs() const {
+  std::vector<std::string> args;
+  std::string output_filename = impl_->output_filename;
+  if (output_filename.empty()) {
+    output_filename = GetDefaultOutputFilename();
+  }
+  args.insert(args.end(), {"-o", output_filename});
+  args.insert(args.end(), {"-e", impl_->event});
+  args.insert(args.end(), {"-f", std::to_string(impl_->freq)});
+  if (impl_->duration_in_second != 0.0) {
+    args.insert(args.end(), {"--duration", std::to_string(impl_->duration_in_second)});
+  }
+  if (impl_->threads.empty()) {
+    args.insert(args.end(), {"-p", std::to_string(getpid())});
+  } else {
+    std::ostringstream os;
+    os << *(impl_->threads.begin());
+    for (auto it = std::next(impl_->threads.begin()); it != impl_->threads.end(); ++it) {
+      os << "," << *it;
+    }
+    args.insert(args.end(), {"-t", os.str()});
+  }
+  if (impl_->dwarf_callgraph) {
+    args.push_back("-g");
+  } else if (impl_->fp_callgraph) {
+    args.insert(args.end(), {"--call-graph", "fp"});
+  }
+  if (impl_->trace_offcpu) {
+    args.push_back("--trace-offcpu");
+  }
+  return args;
+}
+
+static void Abort(const char* fmt, ...) {
+  va_list vl;
+  va_start(vl, fmt);
+  __android_log_vprint(ANDROID_LOG_FATAL, "simpleperf", fmt, vl);
+  va_end(vl);
+  abort();
+}
+
+class ProfileSessionImpl {
+ public:
+  ProfileSessionImpl(const std::string& app_data_dir)
+      : app_data_dir_(app_data_dir),
+        simpleperf_data_dir_(app_data_dir + "/simpleperf_data") {}
+  ~ProfileSessionImpl();
+  void StartRecording(const std::vector<std::string>& args);
+  void PauseRecording();
+  void ResumeRecording();
+  void StopRecording();
+
+ private:
+  std::string FindSimpleperf();
+  std::string FindSimpleperfInTempDir();
+  void CheckIfPerfEnabled();
+  void CreateSimpleperfDataDir();
+  void CreateSimpleperfProcess(const std::string& simpleperf_path,
+                               const std::vector<std::string>& record_args);
+  void SendCmd(const std::string& cmd);
+  std::string ReadReply();
+
+  enum State {
+    NOT_YET_STARTED,
+    STARTED,
+    PAUSED,
+    STOPPED,
+  };
+
+  const std::string app_data_dir_;
+  const std::string simpleperf_data_dir_;
+  std::mutex lock_;  // Protect all members below.
+  State state_ = NOT_YET_STARTED;
+  pid_t simpleperf_pid_ = -1;
+  int control_fd_ = -1;
+  int reply_fd_ = -1;
+  bool trace_offcpu_ = false;
+};
+
+ProfileSessionImpl::~ProfileSessionImpl() {
+  if (control_fd_ != -1) {
+    close(control_fd_);
+  }
+  if (reply_fd_ != -1) {
+    close(reply_fd_);
+  }
+}
+
+void ProfileSessionImpl::StartRecording(const std::vector<std::string> &args) {
+  std::lock_guard<std::mutex> guard(lock_);
+  if (state_ != NOT_YET_STARTED) {
+    Abort("startRecording: session in wrong state %d", state_);
+  }
+  for (const auto& arg : args) {
+    if (arg == "--trace-offcpu") {
+      trace_offcpu_ = true;
+    }
+  }
+  std::string simpleperf_path = FindSimpleperf();
+  CheckIfPerfEnabled();
+  CreateSimpleperfDataDir();
+  CreateSimpleperfProcess(simpleperf_path, args);
+  state_ = STARTED;
+}
+
+void ProfileSessionImpl::PauseRecording() {
+  std::lock_guard<std::mutex> guard(lock_);
+  if (state_ != STARTED) {
+    Abort("pauseRecording: session in wrong state %d", state_);
+  }
+  if (trace_offcpu_) {
+    Abort("--trace-offcpu doesn't work well with pause/resume recording");
+  }
+  SendCmd("pause");
+  state_ = PAUSED;
+}
+
+void ProfileSessionImpl::ResumeRecording() {
+  std::lock_guard<std::mutex> guard(lock_);
+  if (state_ != PAUSED) {
+    Abort("resumeRecording: session in wrong state %d", state_);
+  }
+  SendCmd("resume");
+  state_ = STARTED;
+}
+
+void ProfileSessionImpl::StopRecording() {
+  std::lock_guard<std::mutex> guard(lock_);
+  if (state_ != STARTED && state_ != PAUSED) {
+    Abort("stopRecording: session in wrong state %d", state_);
+  }
+  // Send SIGINT to simpleperf to stop recording.
+  if (kill(simpleperf_pid_, SIGINT) == -1) {
+    Abort("failed to stop simpleperf: %s", strerror(errno));
+  }
+  int status;
+  pid_t result = TEMP_FAILURE_RETRY(waitpid(simpleperf_pid_, &status, 0));
+  if (result == -1) {
+    Abort("failed to call waitpid: %s", strerror(errno));
+  }
+  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+    Abort("simpleperf exited with error, status = 0x%x", status);
+  }
+  state_ = STOPPED;
+}
+
+void ProfileSessionImpl::SendCmd(const std::string& cmd) {
+  std::string data = cmd + "\n";
+  if (TEMP_FAILURE_RETRY(write(control_fd_, &data[0], data.size())) !=
+                         static_cast<ssize_t>(data.size())) {
+    Abort("failed to send cmd to simpleperf: %s", strerror(errno));
+  }
+  if (ReadReply() != "ok") {
+    Abort("failed to run cmd in simpleperf: %s", cmd.c_str());
+  }
+}
+
+static bool IsExecutableFile(const std::string& path) {
+  struct stat st;
+  if (stat(path.c_str(), &st) == 0) {
+    if (S_ISREG(st.st_mode) && (st.st_mode & S_IXUSR)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static std::string ReadFile(FILE* fp) {
+  std::string s;
+  if (fp == nullptr) {
+    return s;
+  }
+  char buf[200];
+  while (true) {
+    ssize_t n = fread(buf, 1, sizeof(buf), fp);
+    if (n <= 0) {
+      break;
+    }
+    s.insert(s.end(), buf, buf + n);
+  }
+  fclose(fp);
+  return s;
+}
+
+static bool RunCmd(std::vector<const char*> args, std::string* stdout) {
+  int stdout_fd[2];
+  if (pipe(stdout_fd) != 0) {
+    return false;
+  }
+  args.push_back(nullptr);
+  // Fork handlers (like gsl_library_close) may hang in a multi-thread environment.
+  // So we use vfork instead of fork to avoid calling them.
+  int pid = vfork();
+  if (pid == -1) {
+    return false;
+  }
+  if (pid == 0) {
+    // child process
+    close(stdout_fd[0]);
+    dup2(stdout_fd[1], 1);
+    close(stdout_fd[1]);
+    execvp(const_cast<char*>(args[0]), const_cast<char**>(args.data()));
+    _exit(1);
+  }
+  // parent process
+  close(stdout_fd[1]);
+  int status;
+  pid_t result = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
+  if (result == -1) {
+    Abort("failed to call waitpid: %s", strerror(errno));
+  }
+  if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+    return false;
+  }
+  if (stdout == nullptr) {
+    close(stdout_fd[0]);
+  } else {
+    *stdout = ReadFile(fdopen(stdout_fd[0], "r"));
+  }
+  return true;
+}
+
+std::string ProfileSessionImpl::FindSimpleperf() {
+  // 1. Try /data/local/tmp/simpleperf first. Probably it's newer than /system/bin/simpleperf.
+  std::string simpleperf_path = FindSimpleperfInTempDir();
+  if (!simpleperf_path.empty()) {
+    return simpleperf_path;
+  }
+  // 2. Try /system/bin/simpleperf, which is available on Android >= Q.
+  simpleperf_path = "/system/bin/simpleperf";
+  if (IsExecutableFile(simpleperf_path)) {
+    return simpleperf_path;
+  }
+  Abort("can't find simpleperf on device. Please run api_profiler.py.");
+  return "";
+}
+
+std::string ProfileSessionImpl::FindSimpleperfInTempDir() {
+  const std::string path = "/data/local/tmp/simpleperf";
+  if (!IsExecutableFile(path)) {
+    return "";
+  }
+  // Copy it to app_dir to execute it.
+  const std::string to_path = app_data_dir_ + "/simpleperf";
+  if (!RunCmd({"/system/bin/cp", path.c_str(), to_path.c_str()}, nullptr)) {
+    return "";
+  }
+  // For apps with target sdk >= 29, executing app data file isn't allowed. So test executing it.
+  if (!RunCmd({to_path.c_str()}, nullptr)) {
+    return "";
+  }
+  return to_path;
+}
+
+void ProfileSessionImpl::CheckIfPerfEnabled() {
+  std::string s;
+  if (!RunCmd({"/system/bin/getprop", "security.perf_harden"}, &s)) {
+    return;  // Omit check if getprop doesn't exist.
+  }
+  if (!s.empty() && s[0] == '1') {
+    Abort("linux perf events aren't enabled on the device. Please run api_profiler.py.");
+  }
+}
+
+void ProfileSessionImpl::CreateSimpleperfDataDir() {
+  struct stat st;
+  if (stat(simpleperf_data_dir_.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) {
+    return;
+  }
+  if (mkdir(simpleperf_data_dir_.c_str(), 0700) == -1) {
+    Abort("failed to create simpleperf data dir %s: %s", simpleperf_data_dir_.c_str(),
+          strerror(errno));
+  }
+}
+
+void ProfileSessionImpl::CreateSimpleperfProcess(const std::string &simpleperf_path,
+                                                 const std::vector<std::string> &record_args) {
+  // 1. Create control/reply pips.
+  int control_fd[2];
+  int reply_fd[2];
+  if (pipe(control_fd) != 0 || pipe(reply_fd) != 0) {
+    Abort("failed to call pipe: %s", strerror(errno));
+  }
+
+  // 2. Prepare simpleperf arguments.
+  std::vector<std::string> args;
+  args.emplace_back(simpleperf_path);
+  args.emplace_back("record");
+  args.emplace_back("--log-to-android-buffer");
+  args.insert(args.end(), {"--log", "debug"});
+  args.emplace_back("--stdio-controls-profiling");
+  args.emplace_back("--in-app");
+  args.insert(args.end(), {"--tracepoint-events", "/data/local/tmp/tracepoint_events"});
+  args.insert(args.end(), record_args.begin(), record_args.end());
+  char* argv[args.size() + 1];
+  for (size_t i = 0; i < args.size(); ++i) {
+    argv[i] = &args[i][0];
+  }
+  argv[args.size()] = nullptr;
+
+  // 3. Start simpleperf process.
+  // Fork handlers (like gsl_library_close) may hang in a multi-thread environment.
+  // So we use vfork instead of fork to avoid calling them.
+  int pid = vfork();
+  if (pid == -1) {
+    Abort("failed to fork: %s", strerror(errno));
+  }
+  if (pid == 0) {
+    // child process
+    close(control_fd[1]);
+    dup2(control_fd[0], 0);  // simpleperf read control cmd from fd 0.
+    close(control_fd[0]);
+    close(reply_fd[0]);
+    dup2(reply_fd[1], 1);  // simpleperf writes reply to fd 1.
+    close(reply_fd[0]);
+    chdir(simpleperf_data_dir_.c_str());
+    execvp(argv[0], argv);
+    Abort("failed to call exec: %s", strerror(errno));
+  }
+  // parent process
+  close(control_fd[0]);
+  control_fd_ = control_fd[1];
+  close(reply_fd[1]);
+  reply_fd_ = reply_fd[0];
+  simpleperf_pid_ = pid;
+
+  // 4. Wait until simpleperf starts recording.
+  std::string start_flag = ReadReply();
+  if (start_flag != "started") {
+    Abort("failed to receive simpleperf start flag");
+  }
+}
+
+std::string ProfileSessionImpl::ReadReply() {
+  std::string s;
+  while (true) {
+    char c;
+    ssize_t result = TEMP_FAILURE_RETRY(read(reply_fd_, &c, 1));
+    if (result <= 0 || c == '\n') {
+      break;
+    }
+    s.push_back(c);
+  }
+  return s;
+}
+
+ProfileSession::ProfileSession() {
+  FILE* fp = fopen("/proc/self/cmdline", "r");
+  if (fp == nullptr) {
+    Abort("failed to open /proc/self/cmdline: %s", strerror(errno));
+  }
+  std::string s = ReadFile(fp);
+  for (int i = 0; i < s.size(); i++) {
+    if (s[i] == '\0') {
+      s = s.substr(0, i);
+      break;
+    }
+  }
+  std::string app_data_dir = "/data/data/" + s;
+  impl_ = new ProfileSessionImpl(app_data_dir);
+}
+
+ProfileSession::ProfileSession(const std::string& app_data_dir)
+    : impl_(new ProfileSessionImpl(app_data_dir)) {}
+
+ProfileSession::~ProfileSession() {
+  delete impl_;
+}
+
+void ProfileSession::StartRecording(const RecordOptions &options) {
+  StartRecording(options.ToRecordArgs());
+}
+
+void ProfileSession::StartRecording(const std::vector<std::string> &record_args) {
+   impl_->StartRecording(record_args);
+}
+
+void ProfileSession::PauseRecording() {
+  impl_->PauseRecording();
+}
+
+void ProfileSession::ResumeRecording() {
+  impl_->ResumeRecording();
+}
+
+void ProfileSession::StopRecording() {
+  impl_->StopRecording();
+}
+
+}  // namespace simpleperf
diff --git a/app_api/cpp/simpleperf.h b/app_api/cpp/simpleperf.h
new file mode 100644
index 0000000..309b37b
--- /dev/null
+++ b/app_api/cpp/simpleperf.h
@@ -0,0 +1,160 @@
+/*
+ * 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 <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+// A C++ API used to control simpleperf recording.
+namespace simpleperf {
+
+/**
+ * RecordOptions sets record options used by ProfileSession. The options are
+ * converted to a string list in toRecordArgs(), which is then passed to
+ * `simpleperf record` cmd. Run `simpleperf record -h` or
+ * `run_simpleperf_on_device.py record -h` for help messages.
+ *
+ * Example:
+ *   RecordOptions options;
+ *   options.setDuration(3).recordDwarfCallGraph().setOutputFilename("perf.data");
+ *   ProfileSession session;
+ *   session.startRecording(options);
+ */
+class RecordOptionsImpl;
+class RecordOptions {
+ public:
+  RecordOptions();
+  ~RecordOptions();
+  /**
+   * Set output filename. Default is perf-<month>-<day>-<hour>-<minute>-<second>.data.
+   * The file will be generated under simpleperf_data/.
+   */
+  RecordOptions& SetOutputFilename(const std::string& filename);
+
+  /**
+   * Set event to record. Default is cpu-cycles. See `simpleperf list` for all available events.
+   */
+  RecordOptions& SetEvent(const std::string& event);
+
+  /**
+   * Set how many samples to generate each second running. Default is 4000.
+   */
+  RecordOptions& SetSampleFrequency(size_t freq);
+
+  /**
+   * Set record duration. The record stops after `durationInSecond` seconds. By default,
+   * record stops only when stopRecording() is called.
+   */
+  RecordOptions& SetDuration(double duration_in_second);
+
+  /**
+   * Record some threads in the app process. By default, record all threads in the process.
+   */
+  RecordOptions& SetSampleThreads(const std::vector<pid_t>& threads);
+
+  /**
+   * Record dwarf based call graph. It is needed to get Java callstacks.
+   */
+  RecordOptions& RecordDwarfCallGraph();
+
+  /**
+   * Record frame pointer based call graph. It is suitable to get C++ callstacks on 64bit devices.
+   */
+  RecordOptions& RecordFramePointerCallGraph();
+
+  /**
+   * Trace context switch info to show where threads spend time off cpu.
+   */
+  RecordOptions& TraceOffCpu();
+
+  /**
+   * Translate record options into arguments for `simpleperf record` cmd.
+   */
+  std::vector<std::string> ToRecordArgs() const;
+
+ private:
+  RecordOptionsImpl* impl_;
+};
+
+/**
+ * ProfileSession uses `simpleperf record` cmd to generate a recording file.
+ * It allows users to start recording with some options, pause/resume recording
+ * to only profile interested code, and stop recording.
+ *
+ * Example:
+ *   RecordOptions options;
+ *   options.setDwarfCallGraph();
+ *   ProfileSession session;
+ *   session.StartRecording(options);
+ *   sleep(1);
+ *   session.PauseRecording();
+ *   sleep(1);
+ *   session.ResumeRecording();
+ *   sleep(1);
+ *   session.StopRecording();
+ *
+ * It aborts when error happens. To read error messages of simpleperf record
+ * process, filter logcat with `simpleperf`.
+ */
+class ProfileSessionImpl;
+class ProfileSession {
+ public:
+  /**
+   * @param appDataDir the same as android.content.Context.getDataDir().
+   *                   ProfileSession stores profiling data in appDataDir/simpleperf_data/.
+   */
+  ProfileSession(const std::string& app_data_dir);
+
+  /**
+   * ProfileSession assumes appDataDir as /data/data/app_package_name.
+   */
+  ProfileSession();
+  ~ProfileSession();
+
+  /**
+   * Start recording.
+   * @param options RecordOptions
+   */
+  void StartRecording(const RecordOptions& options);
+
+  /**
+   * Start recording.
+   * @param args arguments for `simpleperf record` cmd.
+   */
+  void StartRecording(const std::vector<std::string>& record_args);
+
+  /**
+   * Pause recording. No samples are generated in paused state.
+   */
+  void PauseRecording();
+
+  /**
+   * Resume a paused session.
+   */
+  void ResumeRecording();
+
+  /**
+   * Stop recording and generate a recording file under appDataDir/simpleperf_data/.
+   */
+  void StopRecording();
+ private:
+  ProfileSessionImpl* impl_;
+};
+
+}  // namespace simpleperf
diff --git a/app_api/java/com/android/simpleperf/ProfileSession.java b/app_api/java/com/android/simpleperf/ProfileSession.java
new file mode 100644
index 0000000..cb0eac3
--- /dev/null
+++ b/app_api/java/com/android/simpleperf/ProfileSession.java
@@ -0,0 +1,350 @@
+/*
+ * 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.
+ */
+
+package com.android.simpleperf;
+
+import android.os.Build;
+import android.system.OsConstants;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * This class uses `simpleperf record` cmd to generate a recording file.
+ * It allows users to start recording with some options, pause/resume recording
+ * to only profile interested code, and stop recording.
+ * </p>
+ *
+ * <p>
+ * Example:
+ *   RecordOptions options = new RecordOptions();
+ *   options.setDwarfCallGraph();
+ *   ProfileSession session = new ProfileSession();
+ *   session.StartRecording(options);
+ *   Thread.sleep(1000);
+ *   session.PauseRecording();
+ *   Thread.sleep(1000);
+ *   session.ResumeRecording();
+ *   Thread.sleep(1000);
+ *   session.StopRecording();
+ * </p>
+ *
+ * <p>
+ * It throws an Error when error happens. To read error messages of simpleperf record
+ * process, filter logcat with `simpleperf`.
+ * </p>
+ */
+public class ProfileSession {
+    private static final String SIMPLEPERF_PATH_IN_IMAGE = "/system/bin/simpleperf";
+
+    enum State {
+        NOT_YET_STARTED,
+        STARTED,
+        PAUSED,
+        STOPPED,
+    }
+
+    private State state = State.NOT_YET_STARTED;
+    private String appDataDir;
+    private String simpleperfPath;
+    private String simpleperfDataDir;
+    private Process simpleperfProcess;
+    private boolean traceOffcpu = false;
+
+    /**
+     * @param appDataDir the same as android.content.Context.getDataDir().
+     *                   ProfileSession stores profiling data in appDataDir/simpleperf_data/.
+     */
+    public ProfileSession(String appDataDir) {
+        this.appDataDir = appDataDir;
+        simpleperfDataDir = appDataDir + "/simpleperf_data";
+    }
+
+    /**
+     * ProfileSession assumes appDataDir as /data/data/app_package_name.
+     */
+    public ProfileSession() {
+        String packageName = "";
+        try {
+            String s = readInputStream(new FileInputStream("/proc/self/cmdline"));
+            for (int i = 0; i < s.length(); i++) {
+                if (s.charAt(i) == '\0') {
+                    s = s.substring(0, i);
+                    break;
+                }
+            }
+            packageName = s;
+        } catch (IOException e) {
+            throw new Error("failed to find packageName: " + e.getMessage());
+        }
+        if (packageName.isEmpty()) {
+            throw new Error("failed to find packageName");
+        }
+        appDataDir = "/data/data/" + packageName;
+        simpleperfDataDir = appDataDir + "/simpleperf_data";
+    }
+
+    /**
+     * Start recording.
+     * @param options RecordOptions
+     */
+    public void startRecording(RecordOptions options) {
+        startRecording(options.toRecordArgs());
+    }
+
+    /**
+     * Start recording.
+     * @param args arguments for `simpleperf record` cmd.
+     */
+    public synchronized void startRecording(List<String> args) {
+        if (state != State.NOT_YET_STARTED) {
+            throw new AssertionError("startRecording: session in wrong state " + state);
+        }
+        for (String arg : args) {
+            if (arg.equals("--trace-offcpu")) {
+                traceOffcpu = true;
+            }
+        }
+        simpleperfPath = findSimpleperf();
+        checkIfPerfEnabled();
+        createSimpleperfDataDir();
+        createSimpleperfProcess(simpleperfPath, args);
+        state = State.STARTED;
+    }
+
+    /**
+     * Pause recording. No samples are generated in paused state.
+     */
+    public synchronized void pauseRecording() {
+        if (state != State.STARTED) {
+            throw new AssertionError("pauseRecording: session in wrong state " + state);
+        }
+        if (traceOffcpu) {
+            throw new AssertionError(
+                    "--trace-offcpu option doesn't work well with pause/resume recording");
+        }
+        sendCmd("pause");
+        state = State.PAUSED;
+    }
+
+    /**
+     * Resume a paused session.
+     */
+    public synchronized void resumeRecording() {
+        if (state != State.PAUSED) {
+            throw new AssertionError("resumeRecording: session in wrong state " + state);
+        }
+        sendCmd("resume");
+        state = State.STARTED;
+    }
+
+    /**
+     * Stop recording and generate a recording file under appDataDir/simpleperf_data/.
+     */
+    public synchronized void stopRecording() {
+        if (state != State.STARTED && state != State.PAUSED) {
+            throw new AssertionError("stopRecording: session in wrong state " + state);
+        }
+        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P + 1 &&
+                simpleperfPath.equals(SIMPLEPERF_PATH_IN_IMAGE)) {
+            // The simpleperf shipped on Android Q contains a bug, which may make it abort if
+            // calling simpleperfProcess.destroy().
+            destroySimpleperfProcessWithoutClosingStdin();
+        } else {
+            simpleperfProcess.destroy();
+        }
+        try {
+            int exitCode = simpleperfProcess.waitFor();
+            if (exitCode != 0) {
+                throw new AssertionError("simpleperf exited with error: " + exitCode);
+            }
+        } catch (InterruptedException e) {
+        }
+        simpleperfProcess = null;
+        state = State.STOPPED;
+    }
+
+    private void destroySimpleperfProcessWithoutClosingStdin() {
+        // In format "Process[pid=? ..."
+        String s = simpleperfProcess.toString();
+        final String prefix = "Process[pid=";
+        if (s.startsWith(prefix)) {
+            int startIndex = prefix.length();
+            int endIndex = s.indexOf(',');
+            if (endIndex > startIndex) {
+                int pid = Integer.parseInt(s.substring(startIndex, endIndex).trim());
+                android.os.Process.sendSignal(pid, OsConstants.SIGTERM);
+                return;
+            }
+        }
+        simpleperfProcess.destroy();
+    }
+
+    private String readInputStream(InputStream in) {
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        String result = reader.lines().collect(Collectors.joining("\n"));
+        try {
+            reader.close();
+        } catch (IOException e) {
+        }
+        return result;
+    }
+
+    private String findSimpleperf() {
+        // 1. Try /data/local/tmp/simpleperf. Probably it's newer than /system/bin/simpleperf.
+        String simpleperfPath = findSimpleperfInTempDir();
+        if (simpleperfPath != null) {
+            return simpleperfPath;
+        }
+        // 2. Try /system/bin/simpleperf, which is available on Android >= Q.
+        simpleperfPath = SIMPLEPERF_PATH_IN_IMAGE;
+        if (isExecutableFile(simpleperfPath)) {
+            return simpleperfPath;
+        }
+        throw new Error("can't find simpleperf on device. Please run api_profiler.py.");
+    }
+
+    private boolean isExecutableFile(String path) {
+        File file = new File(path);
+        return file.canExecute();
+    }
+
+    private String findSimpleperfInTempDir() {
+        String path = "/data/local/tmp/simpleperf";
+        File file = new File(path);
+        if (!file.isFile()){
+            return null;
+        }
+        // Copy it to app dir to execute it.
+        String toPath = appDataDir + "/simpleperf";
+        try {
+            Process process = new ProcessBuilder()
+                    .command("cp", path, toPath).start();
+            process.waitFor();
+        } catch (Exception e) {
+            return null;
+        }
+        if (!isExecutableFile(toPath)) {
+            return null;
+        }
+        // For apps with target sdk >= 29, executing app data file isn't allowed. So test executing
+        // it.
+        try {
+            Process process = new ProcessBuilder()
+                    .command(toPath).start();
+            process.waitFor();
+        } catch (Exception e) {
+            return null;
+        }
+        return toPath;
+    }
+
+    private void checkIfPerfEnabled() {
+        String value = "";
+        Process process;
+        try {
+            process = new ProcessBuilder()
+                    .command("/system/bin/getprop", "security.perf_harden").start();
+        } catch (IOException e) {
+            // Omit check if getprop doesn't exist.
+            return;
+        }
+        try {
+            process.waitFor();
+        } catch (InterruptedException e) {
+        }
+        value = readInputStream(process.getInputStream());
+        if (value.startsWith("1")) {
+            throw new Error("linux perf events aren't enabled on the device." +
+                            " Please run api_profiler.py.");
+        }
+    }
+
+    private void createSimpleperfDataDir() {
+        File file = new File(simpleperfDataDir);
+        if (!file.isDirectory()) {
+            file.mkdir();
+        }
+    }
+
+    private void createSimpleperfProcess(String simpleperfPath, List<String> recordArgs) {
+        // 1. Prepare simpleperf arguments.
+        ArrayList<String> args = new ArrayList<>();
+        args.add(simpleperfPath);
+        args.add("record");
+        args.add("--log-to-android-buffer");
+        args.add("--log");
+        args.add("debug");
+        args.add("--stdio-controls-profiling");
+        args.add("--in-app");
+        args.add("--tracepoint-events");
+        args.add("/data/local/tmp/tracepoint_events");
+        args.addAll(recordArgs);
+
+        // 2. Create the simpleperf process.
+        ProcessBuilder pb = new ProcessBuilder(args).directory(new File(simpleperfDataDir));
+        try {
+            simpleperfProcess = pb.start();
+        } catch (IOException e) {
+            throw new Error("failed to create simpleperf process: " + e.getMessage());
+        }
+
+        // 3. Wait until simpleperf starts recording.
+        String startFlag = readReply();
+        if (!startFlag.equals("started")) {
+            throw new Error("failed to receive simpleperf start flag");
+        }
+    }
+
+    private void sendCmd(String cmd) {
+        cmd += "\n";
+        try {
+            simpleperfProcess.getOutputStream().write(cmd.getBytes());
+            simpleperfProcess.getOutputStream().flush();
+        } catch (IOException e) {
+            throw new Error("failed to send cmd to simpleperf: " + e.getMessage());
+        }
+        if (!readReply().equals("ok")) {
+            throw new Error("failed to run cmd in simpleperf: " + cmd);
+        }
+    }
+
+    private String readReply() {
+        // Read one byte at a time to stop at line break or EOF. BufferedReader will try to read
+        // more than available and make us blocking, so don't use it.
+        String s = "";
+        while (true) {
+            int c = -1;
+            try {
+                c = simpleperfProcess.getInputStream().read();
+            } catch (IOException e) {
+            }
+            if (c == -1 || c == '\n') {
+                break;
+            }
+            s += (char)c;
+        }
+        return s;
+    }
+}
diff --git a/app_api/java/com/android/simpleperf/RecordOptions.java b/app_api/java/com/android/simpleperf/RecordOptions.java
new file mode 100644
index 0000000..3ed39fb
--- /dev/null
+++ b/app_api/java/com/android/simpleperf/RecordOptions.java
@@ -0,0 +1,172 @@
+/*
+ * 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.
+ */
+
+package com.android.simpleperf;
+
+import android.system.Os;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * This class sets record options used by ProfileSession. The options are
+ * converted to a string list in toRecordArgs(), which is then passed to
+ * `simpleperf record` cmd. Run `simpleperf record -h` or
+ * `run_simpleperf_on_device.py record -h` for help messages.
+ * </p>
+ *
+ * <p>
+ * Example:
+ *   RecordOptions options = new RecordOptions();
+ *   options.setDuration(3).recordDwarfCallGraph().setOutputFilename("perf.data");
+ *   ProfileSession session = new ProfileSession();
+ *   session.startRecording(options);
+ * </p>
+ */
+public class RecordOptions {
+
+    /**
+     * Set output filename. Default is perf-<month>-<day>-<hour>-<minute>-<second>.data.
+     * The file will be generated under simpleperf_data/.
+     */
+    public RecordOptions setOutputFilename(String filename) {
+        outputFilename = filename;
+        return this;
+    }
+
+    /**
+     * Set event to record. Default is cpu-cycles. See `simpleperf list` for all available events.
+     */
+    public RecordOptions setEvent(String event) {
+        this.event = event;
+        return this;
+    }
+
+    /**
+     * Set how many samples to generate each second running. Default is 4000.
+     */
+    public RecordOptions setSampleFrequency(int freq) {
+        this.freq = freq;
+        return this;
+    }
+
+    /**
+     * Set record duration. The record stops after `durationInSecond` seconds. By default,
+     * record stops only when stopRecording() is called.
+     */
+    public RecordOptions setDuration(double durationInSecond) {
+        this.durationInSecond = durationInSecond;
+        return this;
+    }
+
+    /**
+     * Record some threads in the app process. By default, record all threads in the process.
+     */
+    public RecordOptions setSampleThreads(List<Integer> threads) {
+        this.threads.addAll(threads);
+        return this;
+    }
+
+    /**
+     * Record dwarf based call graph. It is needed to get Java callstacks.
+     */
+    public RecordOptions recordDwarfCallGraph() {
+        this.dwarfCallGraph = true;
+        this.fpCallGraph = false;
+        return this;
+    }
+
+    /**
+     * Record frame pointer based call graph. It is suitable to get C++ callstacks on 64bit devices.
+     */
+    public RecordOptions recordFramePointerCallGraph() {
+        this.fpCallGraph = true;
+        this.dwarfCallGraph = false;
+        return this;
+    }
+
+    /**
+     * Trace context switch info to show where threads spend time off cpu.
+     */
+    public RecordOptions traceOffCpu() {
+        this.traceOffCpu = true;
+        return this;
+    }
+
+    /**
+     * Translate record options into arguments for `simpleperf record` cmd.
+     */
+    public List<String> toRecordArgs() {
+        ArrayList<String> args = new ArrayList<>();
+
+        String filename = outputFilename;
+        if (filename == null) {
+            filename = getDefaultOutputFilename();
+        }
+        args.add("-o");
+        args.add(filename);
+        args.add("-e");
+        args.add(event);
+        args.add("-f");
+        args.add(String.valueOf(freq));
+        if (durationInSecond != 0.0) {
+            args.add("--duration");
+            args.add(String.valueOf(durationInSecond));
+        }
+        if (threads.isEmpty()) {
+            args.add("-p");
+            args.add(String.valueOf(Os.getpid()));
+        } else {
+            String s = "";
+            for (int i = 0; i < threads.size(); i++) {
+                if (i > 0) {
+                    s += ",";
+                }
+                s += threads.get(i).toString();
+            }
+            args.add("-t");
+            args.add(s);
+        }
+        if (dwarfCallGraph) {
+            args.add("-g");
+        } else if (fpCallGraph) {
+            args.add("--call-graph");
+            args.add("fp");
+        }
+        if (traceOffCpu) {
+            args.add("--trace-offcpu");
+        }
+        return args;
+    }
+
+    private String getDefaultOutputFilename() {
+        LocalDateTime time = LocalDateTime.now();
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("'perf'-MM-dd-HH-mm-ss'.data'");
+        return time.format(formatter);
+    }
+
+    private String outputFilename;
+    private String event = "cpu-cycles";
+    private int freq = 4000;
+    private double durationInSecond = 0.0;
+    private ArrayList<Integer> threads = new ArrayList<>();
+    private boolean dwarfCallGraph = false;
+    private boolean fpCallGraph = false;
+    private boolean traceOffCpu = false;
+}
diff --git a/app_profiler.py b/app_profiler.py
index 546b614..0080b7f 100755
--- a/app_profiler.py
+++ b/app_profiler.py
@@ -30,7 +30,7 @@
 import time
 
 from utils import AdbHelper, bytes_to_str, extant_dir, get_script_dir, get_target_binary_path
-from utils import log_debug, log_info, log_exit, ReadElf, remove, str_to_bytes
+from utils import log_debug, log_info, log_exit, ReadElf, remove, set_log_level, str_to_bytes
 
 NATIVE_LIBS_DIR_ON_DEVICE = '/data/local/tmp/native_libs/'
 
@@ -117,6 +117,12 @@
         self.adb.check_run(['shell', 'mkdir', '-p', self.dir_on_device])
         if os.path.exists(self.build_id_list_file):
             os.remove(self.build_id_list_file)
+        result, output = self.adb.run_and_return_output(['shell', 'ls', self.dir_on_device])
+        if not result:
+            return
+        file_set = set(output.strip().split())
+        if self.build_id_list_file not in file_set:
+            return
         self.adb.run(['pull', self.dir_on_device + self.build_id_list_file])
         if os.path.exists(self.build_id_list_file):
             with open(self.build_id_list_file, 'rb') as fh:
@@ -124,7 +130,9 @@
                     line = bytes_to_str(line).strip()
                     items = line.split('=')
                     if len(items) == 2:
-                        self.device_build_id_map[items[0]] = items[1]
+                        build_id, filename = items
+                        if filename in file_set:
+                            self.device_build_id_map[build_id] = filename
             remove(self.build_id_list_file)
 
     def sync_natives_libs_on_device(self):
@@ -195,11 +203,12 @@
         """Start simpleperf reocrd process on device."""
         args = ['/data/local/tmp/simpleperf', 'record', '-o', '/data/local/tmp/perf.data',
                 self.args.record_options]
-        if self.adb.run(['shell', 'ls', NATIVE_LIBS_DIR_ON_DEVICE]):
+        if self.adb.run(['shell', 'ls', NATIVE_LIBS_DIR_ON_DEVICE, '>/dev/null', '2>&1']):
             args += ['--symfs', NATIVE_LIBS_DIR_ON_DEVICE]
+        args += ['--log', self.args.log]
         args += target_args
         adb_args = [self.adb.adb_path, 'shell'] + args
-        log_debug('run adb cmd: %s' % adb_args)
+        log_info('run adb cmd: %s' % adb_args)
         self.record_subproc = subprocess.Popen(adb_args)
 
     def wait_profiling(self):
@@ -236,7 +245,7 @@
         if not self.args.skip_collect_binaries:
             binary_cache_args = [sys.executable,
                                  os.path.join(get_script_dir(), 'binary_cache_builder.py')]
-            binary_cache_args += ['-i', self.args.perf_data_path]
+            binary_cache_args += ['-i', self.args.perf_data_path, '--log', self.args.log]
             if self.args.native_lib_dir:
                 binary_cache_args += ['-lib', self.args.native_lib_dir]
             if self.args.disable_adb_root:
@@ -304,7 +313,7 @@
             log_exit("Can't start activity %s" % activity)
 
     def start_test(self):
-        runner = self.args.app + '/android.support.test.runner.AndroidJUnitRunner'
+        runner = self.args.app + '/androidx.test.runner.AndroidJUnitRunner'
         result = self.adb.run(['shell', 'am', 'instrument', '-e', 'class',
                                self.args.test, runner])
         if not result:
@@ -417,12 +426,15 @@
                              help="""Force adb to run in non root mode. By default, app_profiler.py
                                      will try to switch to root mode to be able to profile released
                                      Android apps.""")
+    other_group.add_argument(
+        '--log', choices=['debug', 'info', 'warning'], default='info', help='set log level')
 
     def check_args(args):
         if (not args.app) and (args.compile_java_code or args.activity or args.test):
             log_exit('--compile_java_code, -a, -t can only be used when profiling an Android app.')
 
     args = parser.parse_args()
+    set_log_level(args.log)
     check_args(args)
     if args.app:
         profiler = AppProfiler(args)
diff --git a/bin/android/arm/simpleperf b/bin/android/arm/simpleperf
index c0ae332..d901e07 100755
--- a/bin/android/arm/simpleperf
+++ b/bin/android/arm/simpleperf
Binary files differ
diff --git a/bin/android/arm64/simpleperf b/bin/android/arm64/simpleperf
index 4f22d54..9cf3a23 100755
--- a/bin/android/arm64/simpleperf
+++ b/bin/android/arm64/simpleperf
Binary files differ
diff --git a/bin/android/x86/simpleperf b/bin/android/x86/simpleperf
index 0ee64b0..de5a1c2 100755
--- a/bin/android/x86/simpleperf
+++ b/bin/android/x86/simpleperf
Binary files differ
diff --git a/bin/android/x86_64/simpleperf b/bin/android/x86_64/simpleperf
index 45bce5c..8e29188 100755
--- a/bin/android/x86_64/simpleperf
+++ b/bin/android/x86_64/simpleperf
Binary files differ
diff --git a/bin/darwin/x86/libsimpleperf_report.dylib b/bin/darwin/x86/libsimpleperf_report.dylib
deleted file mode 100755
index 3277d66..0000000
--- a/bin/darwin/x86/libsimpleperf_report.dylib
+++ /dev/null
Binary files differ
diff --git a/bin/darwin/x86/simpleperf b/bin/darwin/x86/simpleperf
deleted file mode 100755
index 7cdd5e7..0000000
--- a/bin/darwin/x86/simpleperf
+++ /dev/null
Binary files differ
diff --git a/bin/darwin/x86_64/libsimpleperf_report.dylib b/bin/darwin/x86_64/libsimpleperf_report.dylib
index a668fc5..b5364a3 100755
--- a/bin/darwin/x86_64/libsimpleperf_report.dylib
+++ b/bin/darwin/x86_64/libsimpleperf_report.dylib
Binary files differ
diff --git a/bin/darwin/x86_64/simpleperf b/bin/darwin/x86_64/simpleperf
index b2e19b4..2f544ef 100755
--- a/bin/darwin/x86_64/simpleperf
+++ b/bin/darwin/x86_64/simpleperf
Binary files differ
diff --git a/bin/linux/x86/libsimpleperf_report.so b/bin/linux/x86/libsimpleperf_report.so
deleted file mode 100755
index a3b8c8e..0000000
--- a/bin/linux/x86/libsimpleperf_report.so
+++ /dev/null
Binary files differ
diff --git a/bin/linux/x86/simpleperf b/bin/linux/x86/simpleperf
deleted file mode 100755
index 9bdbdd8..0000000
--- a/bin/linux/x86/simpleperf
+++ /dev/null
Binary files differ
diff --git a/bin/linux/x86_64/libsimpleperf_report.so b/bin/linux/x86_64/libsimpleperf_report.so
index 741b9ef..61e4f95 100755
--- a/bin/linux/x86_64/libsimpleperf_report.so
+++ b/bin/linux/x86_64/libsimpleperf_report.so
Binary files differ
diff --git a/bin/linux/x86_64/simpleperf b/bin/linux/x86_64/simpleperf
index 91f9dd0..b55a765 100755
--- a/bin/linux/x86_64/simpleperf
+++ b/bin/linux/x86_64/simpleperf
Binary files differ
diff --git a/bin/windows/x86/libsimpleperf_report.dll b/bin/windows/x86/libsimpleperf_report.dll
index 0c42f18..683fdb5 100755
--- a/bin/windows/x86/libsimpleperf_report.dll
+++ b/bin/windows/x86/libsimpleperf_report.dll
Binary files differ
diff --git a/bin/windows/x86/simpleperf.exe b/bin/windows/x86/simpleperf.exe
index d5a2107..daf2d7d 100755
--- a/bin/windows/x86/simpleperf.exe
+++ b/bin/windows/x86/simpleperf.exe
Binary files differ
diff --git a/bin/windows/x86_64/libsimpleperf_report.dll b/bin/windows/x86_64/libsimpleperf_report.dll
index a2ebe7e..f3bf4ed 100755
--- a/bin/windows/x86_64/libsimpleperf_report.dll
+++ b/bin/windows/x86_64/libsimpleperf_report.dll
Binary files differ
diff --git a/bin/windows/x86_64/simpleperf.exe b/bin/windows/x86_64/simpleperf.exe
index 7f3def9..eabf155 100755
--- a/bin/windows/x86_64/simpleperf.exe
+++ b/bin/windows/x86_64/simpleperf.exe
Binary files differ
diff --git a/binary_cache_builder.py b/binary_cache_builder.py
index 50fcc54..97d169c 100755
--- a/binary_cache_builder.py
+++ b/binary_cache_builder.py
@@ -27,7 +27,7 @@
 
 from simpleperf_report_lib import ReportLib
 from utils import AdbHelper, extant_dir, extant_file, flatten_arg_list, log_info, log_warning
-from utils import ReadElf
+from utils import ReadElf, set_log_level
 
 def is_jit_symfile(dso_name):
     return dso_name.split('/')[-1].startswith('TemporaryFile')
@@ -209,7 +209,7 @@
         if os.path.isfile(file_path):
             os.remove(file_path)
         if self.adb.switch_to_root():
-            self.adb.run(['shell', '"echo 0 >/proc/sys/kernel/kptr_restrict"'])
+            self.adb.run(['shell', 'echo', '0', '>/proc/sys/kernel/kptr_restrict'])
             self.adb.run(['pull', '/proc/kallsyms', file_path])
 
 
@@ -223,8 +223,10 @@
     parser.add_argument('--disable_adb_root', action='store_true', help="""
         Force adb to run in non root mode.""")
     parser.add_argument('--ndk_path', nargs=1, help='Find tools in the ndk path.')
+    parser.add_argument(
+        '--log', choices=['debug', 'info', 'warning'], default='info', help='set log level')
     args = parser.parse_args()
-
+    set_log_level(args.log)
     ndk_path = None if not args.ndk_path else args.ndk_path[0]
     builder = BinaryCacheBuilder(ndk_path, args.disable_adb_root)
     symfs_dirs = flatten_arg_list(args.native_lib_dir)
diff --git a/doc/README.md b/doc/README.md
index 372db1a..eeaeead 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -1,11 +1,12 @@
 # Simpleperf
 
-Simpleperf is a native profiling tool for Android. It can be used to profile
+Simpleperf is a native CPU profiling tool for Android. It can be used to profile
 both Android applications and native processes running on Android. It can
-profile both Java and C++ code on Android. It can be used on Android L
-and above.
+profile both Java and C++ code on Android. The simpleperf executable can run on Android >=L,
+and Python scripts can be used on Android >= N.
 
-Simpleperf is part of the Android Open Source Project. The source code is [here](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/).
+Simpleperf is part of the Android Open Source Project.
+The source code is [here](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/).
 The latest document is [here](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md).
 
 ## Table of Contents
@@ -13,57 +14,16 @@
 - [Introduction](#introduction)
 - [Tools in simpleperf](#tools-in-simpleperf)
 - [Android application profiling](#android-application-profiling)
-    - [Prepare an Android application](#prepare-an-android-application)
-    - [Record and report profiling data](#record-and-report-profiling-data)
-    - [Record and report call graph](#record-and-report-call-graph)
-    - [Report in html interface](#report-in-html-interface)
-    - [Show flame graph](#show-flame-graph)
-    - [Record both on CPU time and off CPU time](#record-both-on-cpu-time-and-off-cpu-time)
-    - [Profile from launch](#profile-from-launch)
-    - [Parse profiling data manually](#parse-profiling-data-manually)
 - [Android platform profiling](#android-platform-profiling)
 - [Executable commands reference](#executable-commands-reference)
-    - [How simpleperf works](#how-simpleperf-works)
-    - [Commands](#commands)
-    - [The list command](#the-list-command)
-    - [The stat command](#the-stat-command)
-        - [Select events to stat](#select-events-to-stat)
-        - [Select target to stat](#select-target-to-stat)
-        - [Decide how long to stat](#decide-how-long-to-stat)
-        - [Decide the print interval](#decide-the-print-interval)
-        - [Display counters in systrace](#display-counters-in-systrace)
-    - [The record command](#the-record-command)
-        - [Select events to record](#select-events-to-record)
-        - [Select target to record](#select-target-to-record)
-        - [Set the frequency to record](#set-the-frequency-to-record)
-        - [Decide how long to record](#decide-how-long-to-record)
-        - [Set the path to store profiling data](#set-the-path-to-store-profiling-data)
-        - [Record call graphs](#record-call-graphs-in-record-cmd)
-        - [Record both on CPU time and off CPU time](#record-both-on-cpu-time-and-off-cpu-time-in-record-cmd)
-    - [The report command](#the-report-command)
-        - [Set the path to read profiling data](#set-the-path-to-read-profiling-data)
-        - [Set the path to find binaries](#set-the-path-to-find-binaries)
-        - [Filter samples](#filter-samples)
-        - [Group samples into sample entries](#group-samples-into-sample-entries)
-        - [Report call graphs](#report-call-graphs-in-report-cmd)
 - [Scripts reference](#scripts-reference)
-    - [app_profiler.py](#app_profiler-py)
-        - [Profile from launch of an application](#profile-from-launch-of-an-application)
-    - [run_simpleperf_without_usb_connection.py](#run_simpleperf_without_usb_connection-py)
-    - [binary_cache_builder.py](#binary_cache_builder-py)
-    - [run_simpleperf_on_device.py](#run_simpleperf_on_device-py)
-    - [report.py](#report-py)
-    - [report_html.py](#report_html-py)
-    - [inferno](#inferno)
-    - [pprof_proto_generator.py](#pprof_proto_generator-py)
-    - [report_sample.py](#report_sample-py)
-    - [simpleperf_report_lib.py](#simpleperf_report_lib-py)
 - [Answers to common issues](#answers-to-common-issues)
     - [Why we suggest profiling on android >= N devices](#why-we-suggest-profiling-on-android-n-devices)
     - [Suggestions about recording call graphs](#suggestions-about-recording-call-graphs)
     - [How to solve missing symbols in report](#how-to-solve-missing-symbols-in-report)
 - [Bugs and contribution](#bugs-and-contribution)
 
+
 ## Introduction
 
 Simpleperf contains two parts: the simpleperf executable and Python scripts.
@@ -110,6 +70,7 @@
 
 Detailed documentation for the Python scripts is [here](#scripts-reference).
 
+
 ## Tools in simpleperf
 
 The simpleperf executables and Python scripts are located in simpleperf/ in ndk releases, and in
@@ -123,1114 +84,28 @@
 
 bin/${host}/${arch}/libsimpleperf_report.${so/dylib/dll}: report shared libraries used on the host.
 
-[app_profiler.py](#app_profiler-py): recording profiling data.
-
-[run_simpleperf_without_usb_connection.py](#run_simpleperf_without_usb_connection-py):
-    recording profiling data while the USB cable isn't connected.
-
-[binary_cache_builder.py](#binary_cache_builder-py): building binary cache for profiling data.
-
-[report.py](#report-py): reporting in stdio interface.
-
-[report_html.py](#report_html-py): reporting in html interface.
-
-[inferno.sh](#inferno) (or inferno.bat on Windows): generating flamegraph in html interface.
-
-inferno/: implementation of inferno. Used by inferno.sh.
-
-[pprof_proto_generator.py](#pprof_proto_generator-py): converting profiling data to the format
-       used by [pprof](https://github.com/google/pprof).
-
-[report_sample.py](#report_sample-py): converting profiling data to the format used by [FlameGraph](https://github.com/brendangregg/FlameGraph).
-
-[simpleperf_report_lib.py](#simpleperf_report_lib-py): library for parsing profiling data.
+*.py, inferno: Python scripts used for recording and reporting.
 
 
 ## Android application profiling
 
-This section shows how to profile an Android application.
-Some examples are [Here](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/demo/README.md).
+See [android_application_profiling.md](./android_application_profiling.md).
 
-Profiling an Android application involves three steps:
-1. Prepare an Android application.
-2. Record profiling data.
-3. Report profiling data.
-
-### Prepare an Android application
-
-Based on the profiling situation, we may need to customize the build script to generate an apk file
-specifically for profiling. Below are some suggestions.
-
-1. If you want to profile a debug build of an application:
-
-For the debug build type, Android studio sets android::debuggable="true" in AndroidManifest.xml,
-enables JNI checks and may not optimize C/C++ code. It can be profiled by simpleperf without any
-change.
-
-2. If you want to profile a release build of an application:
-
-For the release build type, Android studio sets android::debuggable="false" in AndroidManifest.xml,
-disables JNI checks and optimizes C/C++ code. However, security restrictions mean that only apps
-with android::debuggable set to true can be profiled. So simpleperf can only profile a release
-build under these two circumstances:
-If you are on a rooted device, you can profile any app.
-
-If you are on Android >= O, we can use [wrap.sh](#https://developer.android.com/ndk/guides/wrap-script.html)
-to profile a release build:
-Step 1: Add android::debuggable="true" in AndroidManifest.xml to enable profiling.
-```
-<manifest ...>
-    <application android::debuggable="true" ...>
-```
-
-Step 2: Add wrap.sh in lib/`arch` directories. wrap.sh runs the app without passing any debug flags
-to ART, so the app runs as a release app. wrap.sh can be done by adding the script below in
-app/build.gradle.
-```
-android {
-    buildTypes {
-        release {
-            sourceSets {
-                release {
-                    resources {
-                        srcDir {
-                            "wrap_sh_lib_dir"
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-task createWrapShLibDir
-    for (String abi : ["armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"]) {
-        def dir = new File("app/wrap_sh_lib_dir/lib/" + abi)
-        dir.mkdirs()
-        def wrapFile = new File(dir, "wrap.sh")
-        wrapFile.withWriter { writer ->
-            writer.write('#!/system/bin/sh\n\$@\n')
-        }
-    }
-}
-```
-
-3. If you want to profile C/C++ code:
-
-Android studio strips symbol table and debug info of native libraries in the apk. So the profiling
-results may contain unknown symbols or broken callgraphs. To fix this, we can pass app_profiler.py
-a directory containing unstripped native libraries via the -lib option. Usually the directory can
-be the path of your Android Studio project.
-
-
-4. If you want to profile Java code:
-
-On Android >= P, simpleperf supports profiling Java code, no matter whether it is executed by
-the interpreter, or JITed, or compiled into native instructions. So you don't need to do anything.
-
-On Android O, simpleperf supports profiling Java code which is compiled into native instructions,
-and it also needs wrap.sh to use the compiled Java code. To compile Java code, we can pass
-app_profiler.py the --compile_java_code option.
-
-On Android N, simpleperf supports profiling Java code that is compiled into native instructions.
-To compile java code, we can pass app_profiler.py the --compile_java_code option.
-
-On Android <= M, simpleperf doesn't support profiling Java code.
-
-
-Below I use application [SimpleperfExampleWithNative](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/demo/SimpleperfExampleWithNative).
-It builds an app-profiling.apk for profiling.
-
-```sh
-$ git clone https://android.googlesource.com/platform/system/extras
-$ cd extras/simpleperf/demo
-# Open SimpleperfExamplesWithNative project with Android studio, and build this project
-# successfully, otherwise the `./gradlew` command below will fail.
-$ cd SimpleperfExampleWithNative
-
-# On windows, use "gradlew" instead.
-$ ./gradlew clean assemble
-$ adb install -r app/build/outputs/apk/profiling/app-profiling.apk
-```
-
-### Record and report profiling data
-
-We can use [app-profiler.py](#app_profiler-py) to profile Android applications.
-
-```sh
-# Cd to the directory of simpleperf scripts. Record perf.data.
-# -p option selects the profiled app using its package name.
-# --compile_java_code option compiles Java code into native instructions, which isn't needed on
-# Android >= P.
-# -a option selects the Activity to profile.
-# -lib option gives the directory to find debug native libraries.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative --compile_java_code \
-    -a .MixActivity -lib path_of_SimpleperfExampleWithNative
-```
-
-This will collect profiling data in perf.data in the current directory, and related native
-binaries in binary_cache/.
-
-Normally we need to use the app when profiling, otherwise we may record no samples. But in this
-case, the MixActivity starts a busy thread. So we don't need to use the app while profiling.
-
-```sh
-# Report perf.data in stdio interface.
-$ python report.py
-Cmdline: /data/data/com.example.simpleperf.simpleperfexamplewithnative/simpleperf record ...
-Arch: arm64
-Event: task-clock:u (type 1, config 1)
-Samples: 10023
-Event count: 10023000000
-
-Overhead  Command     Pid   Tid   Shared Object              Symbol
-27.04%    BusyThread  5703  5729  /system/lib64/libart.so    art::JniMethodStart(art::Thread*)
-25.87%    BusyThread  5703  5729  /system/lib64/libc.so      long StrToI<long, ...
-...
-```
-
-[report.py](#report-py) reports profiling data in stdio interface. If there are a lot of unknown
-symbols in the report, check [here](#how-to-solve-missing-symbols-in-report).
-
-```sh
-# Report perf.data in html interface.
-$ python report_html.py
-
-# Add source code and disassembly. Change the path of source_dirs if it not correct.
-$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative \
-      --add_disassembly
-```
-
-[report_html.py](#report_html-py) generates report in report.html, and pops up a browser tab to
-show it.
-
-### Record and report call graph
-
-We can record and report [call graphs](#record-call-graphs-in-record-cmd) as below.
-
-```sh
-# Record dwarf based call graphs: add "-g" in the -r option.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
-        -r "-e task-clock:u -f 1000 --duration 10 -g" -lib path_of_SimpleperfExampleWithNative
-
-# Record stack frame based call graphs: add "--call-graph fp" in the -r option.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
-        -r "-e task-clock:u -f 1000 --duration 10 --call-graph fp" \
-        -lib path_of_SimpleperfExampleWithNative
-
-# Report call graphs in stdio interface.
-$ python report.py -g
-
-# Report call graphs in python Tk interface.
-$ python report.py -g --gui
-
-# Report call graphs in html interface.
-$ python report_html.py
-
-# Report call graphs in flame graphs.
-# On Windows, use inferno.bat instead of ./inferno.sh.
-$ ./inferno.sh -sc
-```
-
-### Report in html interface
-
-We can use [report_html.py](#report_html-py) to show profiling results in a web browser.
-report_html.py integrates chart statistics, sample table, flame graphs, source code annotation
-and disassembly annotation. It is the recommended way to show reports.
-
-```sh
-$ python report_html.py
-```
-
-### Show flame graph
-
-To show flame graphs, we need to first record call graphs. Flame graphs are shown by
-report_html.py in the "Flamegraph" tab.
-We can also use [inferno](#inferno) to show flame graphs directly.
-
-```sh
-# On Windows, use inferno.bat instead of ./inferno.sh.
-$ ./inferno.sh -sc
-```
-
-We can also build flame graphs using https://github.com/brendangregg/FlameGraph.
-Please make sure you have perl installed.
-
-```sh
-$ git clone https://github.com/brendangregg/FlameGraph.git
-$ python report_sample.py --symfs binary_cache >out.perf
-$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded
-$ FlameGraph/flamegraph.pl out.folded >a.svg
-```
-
-### Record both on CPU time and off CPU time
-
-We can [record both on CPU time and off CPU time](#record-both-on-cpu-time-and-off-cpu-time-in-record-cmd).
-
-First check if trace-offcpu feature is supported on the device.
-
-```sh
-$ python run_simpleperf_on_device.py list --show-features
-dwarf-based-call-graph
-trace-offcpu
-```
-
-If trace-offcpu is supported, it will be shown in the feature list. Then we can try it.
-
-```sh
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
-    -r "-g -e task-clock:u -f 1000 --duration 10 --trace-offcpu" \
-    -lib path_of_SimpleperfExampleWithNative
-$ python report_html.py --add_disassembly --add_source_code \
-    --source_dirs path_of_SimpleperfExampleWithNative
-```
-
-### Profile from launch
-
-We can [profile from launch of an application](#profile-from-launch-of-an-application).
-
-```sh
-# Start simpleperf recording, then start the Activity to profile.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .MainActivity
-
-# We can also start the Activity on the device manually.
-# 1. Make sure the application isn't running or one of the recent apps.
-# 2. Start simpleperf recording.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
-# 3. Start the app manually on the device.
-```
-
-### Parse profiling data manually
-
-We can also write python scripts to parse profiling data manually, by using
-[simpleperf_report_lib.py](#simpleperf_report_lib-py). Examples are report_sample.py,
-report_html.py.
 
 ## Android platform profiling
 
-Here are some tips for Android platform developers, who build and flash system images on rooted
-devices:
-1. After running `adb root`, simpleperf can be used to profile any process or system wide.
-2. It is recommended to use the latest simpleperf available in AOSP master, if you are not working
-on the current master branch. Scripts are in `system/extras/simpleperf/scripts`, binaries are in
-`system/extras/simpleperf/scripts/bin/android`.
-3. It is recommended to use `app_profiler.py` for recording, and `report_html.py` for reporting.
-Below is an example.
-
-```sh
-# Record surfaceflinger process for 10 seconds with dwarf based call graph. More examples are in
-# scripts reference in the doc.
-$ python app_profiler.py -np surfaceflinger -r "-g --duration 10"
-
-# Generate html report.
-$ python report_html.py
-```
-
-4. Since Android >= O has symbols for system libraries on device, we don't need to use unstripped
-binaries in `$ANDROID_PRODUCT_OUT/symbols` to report call graphs. However, they are needed to add
-source code and disassembly (with line numbers) in the report. Below is an example.
-
-```sh
-# Doing recording with app_profiler.py or simpleperf on device, and generates perf.data on host.
-$ python app_profiler.py -np surfaceflinger -r "--call-graph fp --duration 10"
-
-# Collect unstripped binaries from $ANDROID_PRODUCT_OUT/symbols to binary_cache/.
-$ python binary_cache_builder.py -lib $ANDROID_PRODUCT_OUT/symbols
-
-# Report source code and disassembly. Disassembling all binaries is slow, so it's better to add
-# --binary_filter option to only disassemble selected binaries.
-$ python report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly \
-  --binary_filter surfaceflinger.so
-```
+See [android_platform_profiling.md](./android_platform_profiling.md).
 
 
 ## Executable commands reference
 
-### How simpleperf works
-
-Modern CPUs have a hardware component called the performance monitoring unit (PMU). The PMU has
-several hardware counters, counting events like how many cpu cycles have happened, how many
-instructions have executed, or how many cache misses have happened.
-
-The Linux kernel wraps these hardware counters into hardware perf events. In addition, the Linux
-kernel also provides hardware independent software events and tracepoint events. The Linux kernel
-exposes all events to userspace via the perf_event_open system call, which is used by simpleperf.
-
-Simpleperf has three main commands: stat, record and report.
-
-The stat command gives a summary of how many events have happened in the profiled processes in a
-time period. Here’s how it works:
-1. Given user options, simpleperf enables profiling by making a system call to the kernel.
-2. The kernel enables counters while the profiled processes are running.
-3. After profiling, simpleperf reads counters from the kernel, and reports a counter summary.
-
-The record command records samples of the profiled processes in a time period. Here’s how it works:
-1. Given user options, simpleperf enables profiling by making a system call to the kernel.
-2. Simpleperf creates mapped buffers between simpleperf and the kernel.
-3. The kernel enables counters while the profiled processes are running.
-4. Each time a given number of events happen, the kernel dumps a sample to the mapped buffers.
-5. Simpleperf reads samples from the mapped buffers and stores profiling data in a file called
-   perf.data.
-
-The report command reads perf.data and any shared libraries used by the profiled processes,
-and outputs a report showing where the time was spent.
-
-### Commands
-
-Simpleperf supports several commands, listed below:
-
-```
-The debug-unwind command: debug/test dwarf based offline unwinding, used for debugging simpleperf.
-The dump command: dumps content in perf.data, used for debugging simpleperf.
-The help command: prints help information for other commands.
-The kmem command: collects kernel memory allocation information (will be replaced by Python scripts).
-The list command: lists all event types supported on the Android device.
-The record command: profiles processes and stores profiling data in perf.data.
-The report command: reports profiling data in perf.data.
-The report-sample command: reports each sample in perf.data, used for supporting integration of
-                           simpleperf in Android Studio.
-The stat command: profiles processes and prints counter summary.
-
-```
-
-Each command supports different options, which can be seen through help message.
-
-```sh
-# List all commands.
-$ simpleperf --help
-
-# Print help message for record command.
-$ simpleperf record --help
-```
-
-Below describes the most frequently used commands, which are list, stat, record and report.
-
-### The list command
-
-The list command lists all events available on the device. Different devices may support different
-events because they have different hardware and kernels.
-
-```sh
-$ simpleperf list
-List of hw-cache events:
-  branch-loads
-  ...
-List of hardware events:
-  cpu-cycles
-  instructions
-  ...
-List of software events:
-  cpu-clock
-  task-clock
-  ...
-```
-
-On ARM/ARM64, the list command also shows a list of raw events, they are the events supported by
-the ARM PMU on the device. The kernel has wrapped part of them into hardware events and hw-cache
-events. For example, raw-cpu-cycles is wrapped into cpu-cycles, raw-instruction-retired is wrapped
-into instructions. The raw events are provided in case we want to use some events supported on the
-device, but unfortunately not wrapped by the kernel.
-
-### The stat command
-
-The stat command is used to get event counter values of the profiled processes. By passing options,
-we can select which events to use, which processes/threads to monitor, how long to monitor and the
-print interval.
-
-```sh
-# Stat using default events (cpu-cycles,instructions,...), and monitor process 7394 for 10 seconds.
-$ simpleperf stat -p 7394 --duration 10
-Performance counter statistics:
-
- 1,320,496,145  cpu-cycles         # 0.131736 GHz                     (100%)
-   510,426,028  instructions       # 2.587047 cycles per instruction  (100%)
-     4,692,338  branch-misses      # 468.118 K/sec                    (100%)
-886.008130(ms)  task-clock         # 0.088390 cpus used               (100%)
-           753  context-switches   # 75.121 /sec                      (100%)
-           870  page-faults        # 86.793 /sec                      (100%)
-
-Total test time: 10.023829 seconds.
-```
-
-#### Select events to stat
-
-We can select which events to use via -e.
-
-```sh
-# Stat event cpu-cycles.
-$ simpleperf stat -e cpu-cycles -p 11904 --duration 10
-
-# Stat event cache-references and cache-misses.
-$ simpleperf stat -e cache-references,cache-misses -p 11904 --duration 10
-```
-
-When running the stat command, if the number of hardware events is larger than the number of
-hardware counters available in the PMU, the kernel shares hardware counters between events, so each
-event is only monitored for part of the total time. In the example below, there is a percentage at
-the end of each row, showing the percentage of the total time that each event was actually
-monitored.
-
-```sh
-# Stat using event cache-references, cache-references:u,....
-$ simpleperf stat -p 7394 -e cache-references,cache-references:u,cache-references:k \
-      -e cache-misses,cache-misses:u,cache-misses:k,instructions --duration 1
-Performance counter statistics:
-
-4,331,018  cache-references     # 4.861 M/sec    (87%)
-3,064,089  cache-references:u   # 3.439 M/sec    (87%)
-1,364,959  cache-references:k   # 1.532 M/sec    (87%)
-   91,721  cache-misses         # 102.918 K/sec  (87%)
-   45,735  cache-misses:u       # 51.327 K/sec   (87%)
-   38,447  cache-misses:k       # 43.131 K/sec   (87%)
-9,688,515  instructions         # 10.561 M/sec   (89%)
-
-Total test time: 1.026802 seconds.
-```
-
-In the example above, each event is monitored about 87% of the total time. But there is no
-guarantee that any pair of events are always monitored at the same time. If we want to have some
-events monitored at the same time, we can use --group.
-
-```sh
-# Stat using event cache-references, cache-references:u,....
-$ simpleperf stat -p 7964 --group cache-references,cache-misses \
-      --group cache-references:u,cache-misses:u --group cache-references:k,cache-misses:k \
-      -e instructions --duration 1
-Performance counter statistics:
-
-3,638,900  cache-references     # 4.786 M/sec          (74%)
-   65,171  cache-misses         # 1.790953% miss rate  (74%)
-2,390,433  cache-references:u   # 3.153 M/sec          (74%)
-   32,280  cache-misses:u       # 1.350383% miss rate  (74%)
-  879,035  cache-references:k   # 1.251 M/sec          (68%)
-   30,303  cache-misses:k       # 3.447303% miss rate  (68%)
-8,921,161  instructions         # 10.070 M/sec         (86%)
-
-Total test time: 1.029843 seconds.
-```
-
-#### Select target to stat
-
-We can select which processes or threads to monitor via -p or -t. Monitoring a
-process is the same as monitoring all threads in the process. Simpleperf can also fork a child
-process to run the new command and then monitor the child process.
-
-```sh
-# Stat process 11904 and 11905.
-$ simpleperf stat -p 11904,11905 --duration 10
-
-# Stat thread 11904 and 11905.
-$ simpleperf stat -t 11904,11905 --duration 10
-
-# Start a child process running `ls`, and stat it.
-$ simpleperf stat ls
-
-# Stat the process of an Android application. This only works for debuggable apps on non-rooted
-# devices.
-$ simpleperf stat --app com.example.simpleperf.simpleperfexamplewithnative
-
-# Stat system wide using -a.
-$ simpleperf stat -a --duration 10
-```
-
-#### Decide how long to stat
-
-When monitoring existing threads, we can use --duration to decide how long to monitor. When
-monitoring a child process running a new command, simpleperf monitors until the child process ends.
-In this case, we can use Ctrl-C to stop monitoring at any time.
-
-```sh
-# Stat process 11904 for 10 seconds.
-$ simpleperf stat -p 11904 --duration 10
-
-# Stat until the child process running `ls` finishes.
-$ simpleperf stat ls
-
-# Stop monitoring using Ctrl-C.
-$ simpleperf stat -p 11904 --duration 10
-^C
-```
-
-If you want to write a script to control how long to monitor, you can send one of SIGINT, SIGTERM,
-SIGHUP signals to simpleperf to stop monitoring.
-
-#### Decide the print interval
-
-When monitoring perf counters, we can also use --interval to decide the print interval.
-
-```sh
-# Print stat for process 11904 every 300ms.
-$ simpleperf stat -p 11904 --duration 10 --interval 300
-
-# Print system wide stat at interval of 300ms for 10 seconds. Note that system wide profiling needs
-# root privilege.
-$ su 0 simpleperf stat -a --duration 10 --interval 300
-```
-
-#### Display counters in systrace
-
-Simpleperf can also work with systrace to dump counters in the collected trace. Below is an example
-to do a system wide stat.
-
-```sh
-# Capture instructions (kernel only) and cache misses with interval of 300 milliseconds for 15
-# seconds.
-$ su 0 simpleperf stat -e instructions:k,cache-misses -a --interval 300 --duration 15
-# On host launch systrace to collect trace for 10 seconds.
-(HOST)$ external/chromium-trace/systrace.py --time=10 -o new.html sched gfx view
-# Open the collected new.html in browser and perf counters will be shown up.
-```
-
-### The record command
-
-The record command is used to dump samples of the profiled processes. Each sample can contain
-information like the time at which the sample was generated, the number of events since last
-sample, the program counter of a thread, the call chain of a thread.
-
-By passing options, we can select which events to use, which processes/threads to monitor,
-what frequency to dump samples, how long to monitor, and where to store samples.
-
-```sh
-# Record on process 7394 for 10 seconds, using default event (cpu-cycles), using default sample
-# frequency (4000 samples per second), writing records to perf.data.
-$ simpleperf record -p 7394 --duration 10
-simpleperf I cmd_record.cpp:316] Samples recorded: 21430. Samples lost: 0.
-```
-
-#### Select events to record
-
-By default, the cpu-cycles event is used to evaluate consumed cpu cycles. But we can also use other
-events via -e.
-
-```sh
-# Record using event instructions.
-$ simpleperf record -e instructions -p 11904 --duration 10
-
-# Record using task-clock, which shows the passed CPU time in nanoseconds.
-$ simpleperf record -e task-clock -p 11904 --duration 10
-```
-
-#### Select target to record
-
-The way to select target in record command is similar to that in the stat command.
-
-```sh
-# Record process 11904 and 11905.
-$ simpleperf record -p 11904,11905 --duration 10
-
-# Record thread 11904 and 11905.
-$ simpleperf record -t 11904,11905 --duration 10
-
-# Record a child process running `ls`.
-$ simpleperf record ls
-
-# Record the process of an Android application. This only works for debuggable apps on non-rooted
-# devices.
-$ simpleperf record --app com.example.simpleperf.simpleperfexamplewithnative
-
-# Record system wide.
-$ simpleperf record -a --duration 10
-```
-
-#### Set the frequency to record
-
-We can set the frequency to dump records via -f or -c. For example, -f 4000 means
-dumping approximately 4000 records every second when the monitored thread runs. If a monitored
-thread runs 0.2s in one second (it can be preempted or blocked in other times), simpleperf dumps
-about 4000 * 0.2 / 1.0 = 800 records every second. Another way is using -c. For example, -c 10000
-means dumping one record whenever 10000 events happen.
-
-```sh
-# Record with sample frequency 1000: sample 1000 times every second running.
-$ simpleperf record -f 1000 -p 11904,11905 --duration 10
-
-# Record with sample period 100000: sample 1 time every 100000 events.
-$ simpleperf record -c 100000 -t 11904,11905 --duration 10
-```
-
-To avoid taking too much time generating samples, kernel >= 3.10 sets the max percent of cpu time
-used for generating samples (default is 25%), and decreases the max allowed sample frequency when
-hitting that limit. Simpleperf uses --cpu-percent option to adjust it, but it needs either root
-privilege or to be on Android >= Q.
-
-```sh
-# Record with sample frequency 10000, with max allowed cpu percent to be 50%.
-$ simpleperf record -f 1000 -p 11904,11905 --duration 10 --cpu-percent 50
-```
-
-#### Decide how long to record
-
-The way to decide how long to monitor in record command is similar to that in the stat command.
-
-```sh
-# Record process 11904 for 10 seconds.
-$ simpleperf record -p 11904 --duration 10
-
-# Record until the child process running `ls` finishes.
-$ simpleperf record ls
-
-# Stop monitoring using Ctrl-C.
-$ simpleperf record -p 11904 --duration 10
-^C
-```
-
-If you want to write a script to control how long to monitor, you can send one of SIGINT, SIGTERM,
-SIGHUP signals to simpleperf to stop monitoring.
-
-#### Set the path to store profiling data
-
-By default, simpleperf stores profiling data in perf.data in the current directory. But the path
-can be changed using -o.
-
-```sh
-# Write records to data/perf2.data.
-$ simpleperf record -p 11904 -o data/perf2.data --duration 10
-```
-
-<a name="record-call-graphs-in-record-cmd"></a>
-#### Record call graphs
-
-A call graph is a tree showing function call relations. Below is an example.
-
-```
-main() {
-    FunctionOne();
-    FunctionTwo();
-}
-FunctionOne() {
-    FunctionTwo();
-    FunctionThree();
-}
-a call graph:
-    main-> FunctionOne
-       |    |
-       |    |-> FunctionTwo
-       |    |-> FunctionThree
-       |
-       |-> FunctionTwo
-```
-
-A call graph shows how a function calls other functions, and a reversed call graph shows how
-a function is called by other functions. To show a call graph, we need to first record it, then
-report it.
-
-There are two ways to record a call graph, one is recording a dwarf based call graph, the other is
-recording a stack frame based call graph. Recording dwarf based call graphs needs support of debug
-information in native binaries. While recording stack frame based call graphs needs support of
-stack frame registers.
-
-```sh
-# Record a dwarf based call graph
-$ simpleperf record -p 11904 -g --duration 10
-
-# Record a stack frame based call graph
-$ simpleperf record -p 11904 --call-graph fp --duration 10
-```
-
-[Here](#suggestions-about-recording-call-graphs) are some suggestions about recording call graphs.
-
-<a name="record-both-on-cpu-time-and-off-cpu-time-in-record-cmd"></a>
-#### Record both on CPU time and off CPU time
-
-Simpleperf is a CPU profiler, it generates samples for a thread only when it is running on a CPU.
-However, sometimes we want to figure out where the time of a thread is spent, whether it is running
-on a CPU, or staying in the kernel's ready queue, or waiting for something like I/O events.
-
-To support this, the record command uses --trace-offcpu to trace both on CPU time and off CPU time.
-When --trace-offcpu is used, simpleperf generates a sample when a running thread is scheduled out,
-so we know the callstack of a thread when it is scheduled out. And when reporting a perf.data
-generated with --trace-offcpu, we use time to the next sample (instead of event counts from the
-previous sample) as the weight of the current sample. As a result, we can get a call graph based
-on timestamps, including both on CPU time and off CPU time.
-
-trace-offcpu is implemented using sched:sched_switch tracepoint event, which may not be supported
-on old kernels. But it is guaranteed to be supported on devices >= Android O MR1. We can check
-whether trace-offcpu is supported as below.
-
-```sh
-$ simpleperf list --show-features
-dwarf-based-call-graph
-trace-offcpu
-```
-
-If trace-offcpu is supported, it will be shown in the feature list. Then we can try it.
-
-```sh
-# Record with --trace-offcpu.
-$ simpleperf record -g -p 11904 --duration 10 --trace-offcpu
-
-# Record with --trace-offcpu using app_profiler.py.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
-    -r "-g -e task-clock:u -f 1000 --duration 10 --trace-offcpu"
-```
-
-Below is an example comparing the profiling result with / without --trace-offcpu.
-First we record without --trace-offcpu.
-
-```sh
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity
-
-$ python report_html.py --add_disassembly --add_source_code --source_dirs ../demo
-```
-
-The result is [here](./without_trace_offcpu.html).
-In the result, all time is taken by RunFunction(), and sleep time is ignored.
-But if we add --trace-offcpu, the result changes.
-
-```sh
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
-    -r "-g -e task-clock:u --trace-offcpu -f 1000 --duration 10"
-
-$ python report_html.py --add_disassembly --add_source_code --source_dirs ../demo
-```
-
-The result is [here](./trace_offcpu.html).
-In the result, half of the time is taken by RunFunction(), and the other half is taken by
-SleepFunction(). So it traces both on CPU time and off CPU time.
-
-### The report command
-
-The report command is used to report profiling data generated by the record command. The report
-contains a table of sample entries. Each sample entry is a row in the report. The report command
-groups samples belong to the same process, thread, library, function in the same sample entry. Then
-sort the sample entries based on the event count a sample entry has.
-
-By passing options, we can decide how to filter out uninteresting samples, how to group samples
-into sample entries, and where to find profiling data and binaries.
-
-Below is an example. Records are grouped into 4 sample entries, each entry is a row. There are
-several columns, each column shows piece of information belonging to a sample entry. The first
-column is Overhead, which shows the percentage of events inside the current sample entry in total
-events. As the perf event is cpu-cycles, the overhead is the percentage of CPU cycles used in each
-function.
-
-```sh
-# Reports perf.data, using only records sampled in libsudo-game-jni.so, grouping records using
-# thread name(comm), process id(pid), thread id(tid), function name(symbol), and showing sample
-# count for each row.
-$ simpleperf report --dsos /data/app/com.example.sudogame-2/lib/arm64/libsudo-game-jni.so \
-      --sort comm,pid,tid,symbol -n
-Cmdline: /data/data/com.example.sudogame/simpleperf record -p 7394 --duration 10
-Arch: arm64
-Event: cpu-cycles (type 0, config 0)
-Samples: 28235
-Event count: 546356211
-
-Overhead  Sample  Command    Pid   Tid   Symbol
-59.25%    16680   sudogame  7394  7394  checkValid(Board const&, int, int)
-20.42%    5620    sudogame  7394  7394  canFindSolution_r(Board&, int, int)
-13.82%    4088    sudogame  7394  7394  randomBlock_r(Board&, int, int, int, int, int)
-6.24%     1756    sudogame  7394  7394  @plt
-```
-
-#### Set the path to read profiling data
-
-By default, the report command reads profiling data from perf.data in the current directory.
-But the path can be changed using -i.
-
-```sh
-$ simpleperf report -i data/perf2.data
-```
-
-#### Set the path to find binaries
-
-To report function symbols, simpleperf needs to read executable binaries used by the monitored
-processes to get symbol table and debug information. By default, the paths are the executable
-binaries used by monitored processes while recording. However, these binaries may not exist when
-reporting or not contain symbol table and debug information. So we can use --symfs to redirect
-the paths.
-
-```sh
-# In this case, when simpleperf wants to read executable binary /A/b, it reads file in /A/b.
-$ simpleperf report
-
-# In this case, when simpleperf wants to read executable binary /A/b, it prefers file in
-# /debug_dir/A/b to file in /A/b.
-$ simpleperf report --symfs /debug_dir
-
-# Read symbols for system libraries built locally. Note that this is not needed since Android O,
-# which ships symbols for system libraries on device.
-$ simpleperf report --symfs $ANDROID_PRODUCT_OUT/symbols
-```
-
-#### Filter samples
-
-When reporting, it happens that not all records are of interest. The report command supports four
-filters to select samples of interest.
-
-```sh
-# Report records in threads having name sudogame.
-$ simpleperf report --comms sudogame
-
-# Report records in process 7394 or 7395
-$ simpleperf report --pids 7394,7395
-
-# Report records in thread 7394 or 7395.
-$ simpleperf report --tids 7394,7395
-
-# Report records in libsudo-game-jni.so.
-$ simpleperf report --dsos /data/app/com.example.sudogame-2/lib/arm64/libsudo-game-jni.so
-```
-
-#### Group samples into sample entries
-
-The report command uses --sort to decide how to group sample entries.
-
-```sh
-# Group records based on their process id: records having the same process id are in the same
-# sample entry.
-$ simpleperf report --sort pid
-
-# Group records based on their thread id and thread comm: records having the same thread id and
-# thread name are in the same sample entry.
-$ simpleperf report --sort tid,comm
-
-# Group records based on their binary and function: records in the same binary and function are in
-# the same sample entry.
-$ simpleperf report --sort dso,symbol
-
-# Default option: --sort comm,pid,tid,dso,symbol. Group records in the same thread, and belong to
-# the same function in the same binary.
-$ simpleperf report
-```
-
-<a name="report-call-graphs-in-report-cmd"></a>
-#### Report call graphs
-
-To report a call graph, please make sure the profiling data is recorded with call graphs,
-as [here](#record-call-graphs-in-record-cmd).
+See [executable_commands_reference.md](./executable_commands_reference.md).
 
-```
-$ simpleperf report -g
-```
 
 ## Scripts reference
 
-<a name="app_profiler-py"></a>
-### app_profiler.py
+See [scripts_reference.md](./scripts_reference.md).
 
-app_profiler.py is used to record profiling data for Android applications and native executables.
-
-```sh
-# Record an Android application.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
-
-# Record an Android application with Java code compiled into native instructions.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative --compile_java_code
-
-# Record the launch of an Activity of an Android application.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity
-
-# Record a native process.
-$ python app_profiler.py -np surfaceflinger
-
-# Record a native process given its pid.
-$ python app_profiler.py --pid 11324
-
-# Record a command.
-$ python app_profiler.py -cmd \
-    "dex2oat --dex-file=/data/local/tmp/app-profiling.apk --oat-file=/data/local/tmp/a.oat"
-
-# Record an Android application, and use -r to send custom options to the record command.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
-    -r "-e cpu-clock -g --duration 30"
-
-# Record both on CPU time and off CPU time.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
-    -r "-e task-clock -g -f 1000 --duration 10 --trace-offcpu"
-
-# Save profiling data in a custom file (like perf_custom.data) instead of perf.data.
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -o perf_custom.data
-```
-
-#### Profile from launch of an application
-
-Sometimes we want to profile the launch-time of an application. To support this, we added --app in
-the record command. The --app option sets the package name of the Android application to profile.
-If the app is not already running, the record command will poll for the app process in a loop with
-an interval of 1ms. So to profile from launch of an application, we can first start the record
-command with --app, then start the app. Below is an example.
-
-```sh
-$ python run_simpleperf_on_device.py record
-    --app com.example.simpleperf.simpleperfexamplewithnative \
-    -g --duration 1 -o /data/local/tmp/perf.data
-# Start the app manually or using the `am` command.
-```
-
-To make it convenient to use, app_profiler.py supports using the -a option to start an Activity
-after recording has started.
-
-```sh
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .MainActivity
-```
-
-<a name="run_simpleperf_without_usb_connection-py"></a>
-### run_simpleperf_without_usb_connection.py
-
-run_simpleperf_without_usb_connection.py records profiling data while the USB cable isn't
-connected. Below is an example.
-
-```sh
-$ python run_simpleperf_without_usb_connection.py start \
-    -p com.example.simpleperf.simpleperfexamplewithnative
-# After the command finishes successfully, unplug the USB cable, run the
-# SimpleperfExampleWithNative app. After a few seconds, plug in the USB cable.
-$ python run_simpleperf_without_usb_connection.py stop
-# It may take a while to stop recording. After that, the profiling data is collected in perf.data
-# on host.
-```
-
-<a name="binary_cache_builder-py"></a>
-### binary_cache_builder.py
-
-The binary_cache directory is a directory holding binaries needed by a profiling data file. The
-binaries are expected to be unstripped, having debug information and symbol tables. The
-binary_cache directory is used by report scripts to read symbols of binaries. It is also used by
-report_html.py to generate annotated source code and disassembly.
-
-By default, app_profiler.py builds the binary_cache directory after recording. But we can also
-build binary_cache for existing profiling data files using binary_cache_builder.py. It is useful
-when you record profiling data using `simpleperf record` directly, to do system wide profiling or
-record without the USB cable connected.
-
-binary_cache_builder.py can either pull binaries from an Android device, or find binaries in
-directories on the host (via -lib).
-
-```sh
-# Generate binary_cache for perf.data, by pulling binaries from the device.
-$ python binary_cache_builder.py
-
-# Generate binary_cache, by pulling binaries from the device and finding binaries in
-# SimpleperfExampleWithNative.
-$ python binary_cache_builder.py -lib path_of_SimpleperfExampleWithNative
-```
-
-<a name="run_simpleperf_on_device-py"></a>
-### run_simpleperf_on_device.py
-
-This script pushes the simpleperf executable on the device, and run a simpleperf command on the
-device. It is more convenient than running adb commands manually.
-
-<a name="report-py"></a>
-### report.py
-
-report.py is a wrapper of the report command on the host. It accepts all options of the report
-command.
-
-```sh
-# Report call graph
-$ python report.py -g
-
-# Report call graph in a GUI window implemented by Python Tk.
-$ python report.py -g --gui
-```
-
-<a name="report_html-py"></a>
-### report_html.py
-
-report_html.py generates report.html based on the profiling data. Then the report.html can show
-the profiling result without depending on other files. So it can be shown in local browsers or
-passed to other machines. Depending on which command-line options are used, the content of the
-report.html can include: chart statistics, sample table, flame graphs, annotated source code for
-each function, annotated disassembly for each function.
-
-```sh
-# Generate chart statistics, sample table and flame graphs, based on perf.data.
-$ python report_html.py
-
-# Add source code.
-$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative
-
-# Add disassembly.
-$ python report_html.py --add_disassembly
-
-# Adding disassembly for all binaries can cost a lot of time. So we can choose to only add
-# disassembly for selected binaries.
-$ python report_html.py --add_disassembly --binary_filter libgame.so
-
-# report_html.py accepts more than one recording data file.
-$ python report_html.py -i perf1.data perf2.data
-```
-
-Below is an example of generating html profiling results for SimpleperfExampleWithNative.
-
-```sh
-$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
-$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative \
-    --add_disassembly
-```
-
-After opening the generated [report.html](./report_html.html) in a browser, there are several tabs:
-
-The first tab is "Chart Statistics". You can click the pie chart to show the time consumed by each
-process, thread, library and function.
-
-The second tab is "Sample Table". It shows the time taken by each function. By clicking one row in
-the table, we can jump to a new tab called "Function".
-
-The third tab is "Flamegraph". It shows the flame graphs generated by [inferno](./inferno.md).
-
-The fourth tab is "Function". It only appears when users click a row in the "Sample Table" tab.
-It shows information of a function, including:
-
-1. A flame graph showing functions called by that function.
-2. A flame graph showing functions calling that function.
-3. Annotated source code of that function. It only appears when there are source code files for
-   that function.
-4. Annotated disassembly of that function. It only appears when there are binaries containing that
-   function.
-
-### inferno
-
-[inferno](./inferno.md) is a tool used to generate flame graph in a html file.
-
-```sh
-# Generate flame graph based on perf.data.
-# On Windows, use inferno.bat instead of ./inferno.sh.
-$ ./inferno.sh -sc --record_file perf.data
-
-# Record a native program and generate flame graph.
-$ ./inferno.sh -np surfaceflinger
-```
-
-<a name="pprof_proto_generator-py"></a>
-### pprof_proto_generator.py
-
-It converts a profiling data file into pprof.proto, a format used by [pprof](https://github.com/google/pprof).
-
-```sh
-# Convert perf.data in the current directory to pprof.proto format.
-$ python pprof_proto_generator.py
-$ pprof -pdf pprof.profile
-```
-
-<a name="report_sample-py"></a>
-### report_sample.py
-
-It converts a profiling data file into a format used by [FlameGraph](https://github.com/brendangregg/FlameGraph).
-
-```sh
-# Convert perf.data in the current directory to a format used by FlameGraph.
-$ python report_sample.py --symfs binary_cache >out.perf
-$ git clone https://github.com/brendangregg/FlameGraph.git
-$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded
-$ FlameGraph/flamegraph.pl out.folded >a.svg
-```
-
-<a name="simpleperf_report_lib-py"></a>
-### simpleperf_report_lib.py
-
-simpleperf_report_lib.py is a Python library used to parse profiling data files generated by the
-record command. Internally, it uses libsimpleperf_report.so to do the work. Generally, for each
-profiling data file, we create an instance of ReportLib, pass it the file path (via SetRecordFile).
-Then we can read all samples through GetNextSample(). For each sample, we can read its event info
-(via GetEventOfCurrentSample), symbol info (via GetSymbolOfCurrentSample) and call chain info
-(via GetCallChainOfCurrentSample). We can also get some global information, like record options
-(via GetRecordCmd), the arch of the device (via GetArch) and meta strings (via MetaInfo).
-
-Examples of using simpleperf_report_lib.py are in report_sample.py, report_html.py,
-pprof_proto_generator.py and inferno/inferno.py.
 
 ## Answers to common issues
 
@@ -1253,7 +128,7 @@
 dwarf based call graphs:
 1. Need support of debug information in binaries.
 2. Behave normally well on both ARM and ARM64, for both fully compiled Java code and C++ code.
-3. Can only unwind 64K stack for each sample. So usually can't show complete flame-graph. But
+3. Can only unwind 64K stack for each sample. So usually can't show complete flamegraph. But
    probably is enough for users to identify hot places.
 4. Take more CPU time than stack frame based call graphs. So the sample frequency is suggested
    to be 1000 Hz. Thus at most 1000 samples per second.
@@ -1265,7 +140,7 @@
 3. Also don't work well on fully compiled Java code on ARM64. Because the ART compiler doesn't
    reserve stack frame registers.
 4. Work well when profiling native programs on ARM64. One example is profiling surfacelinger. And
-   usually shows complete flame-graph when it works well.
+   usually shows complete flamegraph when it works well.
 5. Take less CPU time than dwarf based call graphs. So the sample frequency can be 4000 Hz or
    higher.
 
@@ -1323,5 +198,5 @@
 $ mmma system/extras/simpleperf -j30
 ```
 
-If built successfully, out/target/product/generic_arm64/system/xbin/simpleperf is for ARM64, and
-out/target/product/generic_arm64/system/xbin/simpleperf32 is for ARM.
+If built successfully, out/target/product/generic_arm64/system/bin/simpleperf is for ARM64, and
+out/target/product/generic_arm64/system/bin/simpleperf32 is for ARM.
diff --git a/doc/android_application_profiling.md b/doc/android_application_profiling.md
new file mode 100644
index 0000000..fae33df
--- /dev/null
+++ b/doc/android_application_profiling.md
@@ -0,0 +1,272 @@
+# Android application profiling
+
+This section shows how to profile an Android application.
+Some examples are [Here](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/demo/README.md).
+
+Profiling an Android application involves three steps:
+1. Prepare an Android application.
+2. Record profiling data.
+3. Report profiling data.
+
+
+## Table of Contents
+
+- [Prepare an Android application](#prepare-an-android-application)
+- [Record and report profiling data](#record-and-report-profiling-data)
+- [Record and report call graph](#record-and-report-call-graph)
+- [Report in html interface](#report-in-html-interface)
+- [Show flamegraph](#show-flamegraph)
+- [Record both on CPU time and off CPU time](#record-both-on-cpu-time-and-off-cpu-time)
+- [Profile from launch](#profile-from-launch)
+- [Parse profiling data manually](#parse-profiling-data-manually)
+
+
+## Prepare an Android application
+
+Based on the profiling situation, we may need to customize the build script to generate an apk file
+specifically for profiling. Below are some suggestions.
+
+1. If you want to profile a debug build of an application:
+
+For the debug build type, Android studio sets android::debuggable="true" in AndroidManifest.xml,
+enables JNI checks and may not optimize C/C++ code. It can be profiled by simpleperf without any
+change.
+
+2. If you want to profile a release build of an application:
+
+For the release build type, Android studio sets android::debuggable="false" in AndroidManifest.xml,
+disables JNI checks and optimizes C/C++ code. However, security restrictions mean that only apps
+with android::debuggable set to true can be profiled. So simpleperf can only profile a release
+build under these two circumstances:
+If you are on a rooted device, you can profile any app.
+
+If you are on Android >= O, we can use [wrap.sh](https://developer.android.com/ndk/guides/wrap-script.html)
+to profile a release build:
+Step 1: Add android::debuggable="true" in AndroidManifest.xml to enable profiling.
+```
+<manifest ...>
+    <application android::debuggable="true" ...>
+```
+
+Step 2: Add wrap.sh in lib/`arch` directories. wrap.sh runs the app without passing any debug flags
+to ART, so the app runs as a release app. wrap.sh can be done by adding the script below in
+app/build.gradle.
+```
+android {
+    buildTypes {
+        release {
+            sourceSets {
+                release {
+                    resources {
+                        srcDir {
+                            "wrap_sh_lib_dir"
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+task createWrapShLibDir
+    for (String abi : ["armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"]) {
+        def dir = new File("app/wrap_sh_lib_dir/lib/" + abi)
+        dir.mkdirs()
+        def wrapFile = new File(dir, "wrap.sh")
+        wrapFile.withWriter { writer ->
+            writer.write('#!/system/bin/sh\n\$@\n')
+        }
+    }
+}
+```
+
+3. If you want to profile C/C++ code:
+
+Android studio strips symbol table and debug info of native libraries in the apk. So the profiling
+results may contain unknown symbols or broken callgraphs. To fix this, we can pass app_profiler.py
+a directory containing unstripped native libraries via the -lib option. Usually the directory can
+be the path of your Android Studio project.
+
+
+4. If you want to profile Java code:
+
+On Android >= P, simpleperf supports profiling Java code, no matter whether it is executed by
+the interpreter, or JITed, or compiled into native instructions. So you don't need to do anything.
+
+On Android O, simpleperf supports profiling Java code which is compiled into native instructions,
+and it also needs wrap.sh to use the compiled Java code. To compile Java code, we can pass
+app_profiler.py the --compile_java_code option.
+
+On Android N, simpleperf supports profiling Java code that is compiled into native instructions.
+To compile java code, we can pass app_profiler.py the --compile_java_code option.
+
+On Android <= M, simpleperf doesn't support profiling Java code.
+
+
+Below I use application [SimpleperfExampleWithNative](https://android.googlesource.com/platform/system/extras/+/master/simpleperf/demo/SimpleperfExampleWithNative).
+It builds an app-profiling.apk for profiling.
+
+```sh
+$ git clone https://android.googlesource.com/platform/system/extras
+$ cd extras/simpleperf/demo
+# Open SimpleperfExamplesWithNative project with Android studio, and build this project
+# successfully, otherwise the `./gradlew` command below will fail.
+$ cd SimpleperfExampleWithNative
+
+# On windows, use "gradlew" instead.
+$ ./gradlew clean assemble
+$ adb install -r app/build/outputs/apk/profiling/app-profiling.apk
+```
+
+## Record and report profiling data
+
+We can use [app-profiler.py](scripts_reference.md#app_profilerpy) to profile Android applications.
+
+```sh
+# Cd to the directory of simpleperf scripts. Record perf.data.
+# -p option selects the profiled app using its package name.
+# --compile_java_code option compiles Java code into native instructions, which isn't needed on
+# Android >= P.
+# -a option selects the Activity to profile.
+# -lib option gives the directory to find debug native libraries.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative --compile_java_code \
+    -a .MixActivity -lib path_of_SimpleperfExampleWithNative
+```
+
+This will collect profiling data in perf.data in the current directory, and related native
+binaries in binary_cache/.
+
+Normally we need to use the app when profiling, otherwise we may record no samples. But in this
+case, the MixActivity starts a busy thread. So we don't need to use the app while profiling.
+
+```sh
+# Report perf.data in stdio interface.
+$ python report.py
+Cmdline: /data/data/com.example.simpleperf.simpleperfexamplewithnative/simpleperf record ...
+Arch: arm64
+Event: task-clock:u (type 1, config 1)
+Samples: 10023
+Event count: 10023000000
+
+Overhead  Command     Pid   Tid   Shared Object              Symbol
+27.04%    BusyThread  5703  5729  /system/lib64/libart.so    art::JniMethodStart(art::Thread*)
+25.87%    BusyThread  5703  5729  /system/lib64/libc.so      long StrToI<long, ...
+...
+```
+
+[report.py](scripts_reference.md#reportpy) reports profiling data in stdio interface. If there
+are a lot of unknown symbols in the report, check [here](README.md#how-to-solve-missing-symbols-in-report).
+
+```sh
+# Report perf.data in html interface.
+$ python report_html.py
+
+# Add source code and disassembly. Change the path of source_dirs if it not correct.
+$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative \
+      --add_disassembly
+```
+
+[report_html.py](scripts_reference.md#report_htmlpy) generates report in report.html, and pops up
+a browser tab to show it.
+
+## Record and report call graph
+
+We can record and report [call graphs](executable_commands_reference.md#record-call-graphs) as below.
+
+```sh
+# Record dwarf based call graphs: add "-g" in the -r option.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
+        -r "-e task-clock:u -f 1000 --duration 10 -g" -lib path_of_SimpleperfExampleWithNative
+
+# Record stack frame based call graphs: add "--call-graph fp" in the -r option.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
+        -r "-e task-clock:u -f 1000 --duration 10 --call-graph fp" \
+        -lib path_of_SimpleperfExampleWithNative
+
+# Report call graphs in stdio interface.
+$ python report.py -g
+
+# Report call graphs in python Tk interface.
+$ python report.py -g --gui
+
+# Report call graphs in html interface.
+$ python report_html.py
+
+# Report call graphs in flamegraphs.
+# On Windows, use inferno.bat instead of ./inferno.sh.
+$ ./inferno.sh -sc
+```
+
+## Report in html interface
+
+We can use [report_html.py](scripts_reference.md#report_htmlpy) to show profiling results in a web browser.
+report_html.py integrates chart statistics, sample table, flamegraphs, source code annotation
+and disassembly annotation. It is the recommended way to show reports.
+
+```sh
+$ python report_html.py
+```
+
+## Show flamegraph
+
+To show flamegraphs, we need to first record call graphs. Flamegraphs are shown by
+report_html.py in the "Flamegraph" tab.
+We can also use [inferno](scripts_reference.md#inferno) to show flamegraphs directly.
+
+```sh
+# On Windows, use inferno.bat instead of ./inferno.sh.
+$ ./inferno.sh -sc
+```
+
+We can also build flamegraphs using https://github.com/brendangregg/FlameGraph.
+Please make sure you have perl installed.
+
+```sh
+$ git clone https://github.com/brendangregg/FlameGraph.git
+$ python report_sample.py --symfs binary_cache >out.perf
+$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded
+$ FlameGraph/flamegraph.pl out.folded >a.svg
+```
+
+## Record both on CPU time and off CPU time
+
+We can [record both on CPU time and off CPU time](executable_commands_reference.md#record-both-on-cpu-time-and-off-cpu-time).
+
+First check if trace-offcpu feature is supported on the device.
+
+```sh
+$ python run_simpleperf_on_device.py list --show-features
+dwarf-based-call-graph
+trace-offcpu
+```
+
+If trace-offcpu is supported, it will be shown in the feature list. Then we can try it.
+
+```sh
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
+    -r "-g -e task-clock:u -f 1000 --duration 10 --trace-offcpu" \
+    -lib path_of_SimpleperfExampleWithNative
+$ python report_html.py --add_disassembly --add_source_code \
+    --source_dirs path_of_SimpleperfExampleWithNative
+```
+
+## Profile from launch
+
+We can [profile from launch of an application](scripts_reference.md#profile-from-launch-of-an-application).
+
+```sh
+# Start simpleperf recording, then start the Activity to profile.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .MainActivity
+
+# We can also start the Activity on the device manually.
+# 1. Make sure the application isn't running or one of the recent apps.
+# 2. Start simpleperf recording.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
+# 3. Start the app manually on the device.
+```
+
+## Parse profiling data manually
+
+We can also write python scripts to parse profiling data manually, by using
+[simpleperf_report_lib.py](scripts_reference.md#simpleperf_report_libpy). Examples are report_sample.py,
+report_html.py.
diff --git a/doc/android_platform_profiling.md b/doc/android_platform_profiling.md
new file mode 100644
index 0000000..afa1927
--- /dev/null
+++ b/doc/android_platform_profiling.md
@@ -0,0 +1,36 @@
+# Android platform profiling
+
+Here are some tips for Android platform developers, who build and flash system images on rooted
+devices:
+1. After running `adb root`, simpleperf can be used to profile any process or system wide.
+2. It is recommended to use the latest simpleperf available in AOSP master, if you are not working
+on the current master branch. Scripts are in `system/extras/simpleperf/scripts`, binaries are in
+`system/extras/simpleperf/scripts/bin/android`.
+3. It is recommended to use `app_profiler.py` for recording, and `report_html.py` for reporting.
+Below is an example.
+
+```sh
+# Record surfaceflinger process for 10 seconds with dwarf based call graph. More examples are in
+# scripts reference in the doc.
+$ python app_profiler.py -np surfaceflinger -r "-g --duration 10"
+
+# Generate html report.
+$ python report_html.py
+```
+
+4. Since Android >= O has symbols for system libraries on device, we don't need to use unstripped
+binaries in `$ANDROID_PRODUCT_OUT/symbols` to report call graphs. However, they are needed to add
+source code and disassembly (with line numbers) in the report. Below is an example.
+
+```sh
+# Doing recording with app_profiler.py or simpleperf on device, and generates perf.data on host.
+$ python app_profiler.py -np surfaceflinger -r "--call-graph fp --duration 10"
+
+# Collect unstripped binaries from $ANDROID_PRODUCT_OUT/symbols to binary_cache/.
+$ python binary_cache_builder.py -lib $ANDROID_PRODUCT_OUT/symbols
+
+# Report source code and disassembly. Disassembling all binaries is slow, so it's better to add
+# --binary_filter option to only disassemble selected binaries.
+$ python report_html.py --add_source_code --source_dirs $ANDROID_BUILD_TOP --add_disassembly \
+  --binary_filter surfaceflinger.so
+```
diff --git a/doc/executable_commands_reference.md b/doc/executable_commands_reference.md
new file mode 100644
index 0000000..ef5c339
--- /dev/null
+++ b/doc/executable_commands_reference.md
@@ -0,0 +1,583 @@
+# Executable commands reference
+
+## Table of Contents
+
+- [How simpleperf works](#how-simpleperf-works)
+- [Commands](#commands)
+- [The list command](#the-list-command)
+- [The stat command](#the-stat-command)
+    - [Select events to stat](#select-events-to-stat)
+    - [Select target to stat](#select-target-to-stat)
+    - [Decide how long to stat](#decide-how-long-to-stat)
+    - [Decide the print interval](#decide-the-print-interval)
+    - [Display counters in systrace](#display-counters-in-systrace)
+- [The record command](#the-record-command)
+    - [Select events to record](#select-events-to-record)
+    - [Select target to record](#select-target-to-record)
+    - [Set the frequency to record](#set-the-frequency-to-record)
+    - [Decide how long to record](#decide-how-long-to-record)
+    - [Set the path to store profiling data](#set-the-path-to-store-profiling-data)
+    - [Record call graphs](#record-call-graphs)
+    - [Record both on CPU time and off CPU time](#record-both-on-cpu-time-and-off-cpu-time)
+- [The report command](#the-report-command)
+    - [Set the path to read profiling data](#set-the-path-to-read-profiling-data)
+    - [Set the path to find binaries](#set-the-path-to-find-binaries)
+    - [Filter samples](#filter-samples)
+    - [Group samples into sample entries](#group-samples-into-sample-entries)
+    - [Report call graphs](#report-call-graphs)
+
+
+## How simpleperf works
+
+Modern CPUs have a hardware component called the performance monitoring unit (PMU). The PMU has
+several hardware counters, counting events like how many cpu cycles have happened, how many
+instructions have executed, or how many cache misses have happened.
+
+The Linux kernel wraps these hardware counters into hardware perf events. In addition, the Linux
+kernel also provides hardware independent software events and tracepoint events. The Linux kernel
+exposes all events to userspace via the perf_event_open system call, which is used by simpleperf.
+
+Simpleperf has three main commands: stat, record and report.
+
+The stat command gives a summary of how many events have happened in the profiled processes in a
+time period. Here’s how it works:
+1. Given user options, simpleperf enables profiling by making a system call to the kernel.
+2. The kernel enables counters while the profiled processes are running.
+3. After profiling, simpleperf reads counters from the kernel, and reports a counter summary.
+
+The record command records samples of the profiled processes in a time period. Here’s how it works:
+1. Given user options, simpleperf enables profiling by making a system call to the kernel.
+2. Simpleperf creates mapped buffers between simpleperf and the kernel.
+3. The kernel enables counters while the profiled processes are running.
+4. Each time a given number of events happen, the kernel dumps a sample to the mapped buffers.
+5. Simpleperf reads samples from the mapped buffers and stores profiling data in a file called
+   perf.data.
+
+The report command reads perf.data and any shared libraries used by the profiled processes,
+and outputs a report showing where the time was spent.
+
+## Commands
+
+Simpleperf supports several commands, listed below:
+
+```
+The debug-unwind command: debug/test dwarf based offline unwinding, used for debugging simpleperf.
+The dump command: dumps content in perf.data, used for debugging simpleperf.
+The help command: prints help information for other commands.
+The kmem command: collects kernel memory allocation information (will be replaced by Python scripts).
+The list command: lists all event types supported on the Android device.
+The record command: profiles processes and stores profiling data in perf.data.
+The report command: reports profiling data in perf.data.
+The report-sample command: reports each sample in perf.data, used for supporting integration of
+                           simpleperf in Android Studio.
+The stat command: profiles processes and prints counter summary.
+
+```
+
+Each command supports different options, which can be seen through help message.
+
+```sh
+# List all commands.
+$ simpleperf --help
+
+# Print help message for record command.
+$ simpleperf record --help
+```
+
+Below describes the most frequently used commands, which are list, stat, record and report.
+
+## The list command
+
+The list command lists all events available on the device. Different devices may support different
+events because they have different hardware and kernels.
+
+```sh
+$ simpleperf list
+List of hw-cache events:
+  branch-loads
+  ...
+List of hardware events:
+  cpu-cycles
+  instructions
+  ...
+List of software events:
+  cpu-clock
+  task-clock
+  ...
+```
+
+On ARM/ARM64, the list command also shows a list of raw events, they are the events supported by
+the ARM PMU on the device. The kernel has wrapped part of them into hardware events and hw-cache
+events. For example, raw-cpu-cycles is wrapped into cpu-cycles, raw-instruction-retired is wrapped
+into instructions. The raw events are provided in case we want to use some events supported on the
+device, but unfortunately not wrapped by the kernel.
+
+## The stat command
+
+The stat command is used to get event counter values of the profiled processes. By passing options,
+we can select which events to use, which processes/threads to monitor, how long to monitor and the
+print interval.
+
+```sh
+# Stat using default events (cpu-cycles,instructions,...), and monitor process 7394 for 10 seconds.
+$ simpleperf stat -p 7394 --duration 10
+Performance counter statistics:
+
+ 1,320,496,145  cpu-cycles         # 0.131736 GHz                     (100%)
+   510,426,028  instructions       # 2.587047 cycles per instruction  (100%)
+     4,692,338  branch-misses      # 468.118 K/sec                    (100%)
+886.008130(ms)  task-clock         # 0.088390 cpus used               (100%)
+           753  context-switches   # 75.121 /sec                      (100%)
+           870  page-faults        # 86.793 /sec                      (100%)
+
+Total test time: 10.023829 seconds.
+```
+
+### Select events to stat
+
+We can select which events to use via -e.
+
+```sh
+# Stat event cpu-cycles.
+$ simpleperf stat -e cpu-cycles -p 11904 --duration 10
+
+# Stat event cache-references and cache-misses.
+$ simpleperf stat -e cache-references,cache-misses -p 11904 --duration 10
+```
+
+When running the stat command, if the number of hardware events is larger than the number of
+hardware counters available in the PMU, the kernel shares hardware counters between events, so each
+event is only monitored for part of the total time. In the example below, there is a percentage at
+the end of each row, showing the percentage of the total time that each event was actually
+monitored.
+
+```sh
+# Stat using event cache-references, cache-references:u,....
+$ simpleperf stat -p 7394 -e cache-references,cache-references:u,cache-references:k \
+      -e cache-misses,cache-misses:u,cache-misses:k,instructions --duration 1
+Performance counter statistics:
+
+4,331,018  cache-references     # 4.861 M/sec    (87%)
+3,064,089  cache-references:u   # 3.439 M/sec    (87%)
+1,364,959  cache-references:k   # 1.532 M/sec    (87%)
+   91,721  cache-misses         # 102.918 K/sec  (87%)
+   45,735  cache-misses:u       # 51.327 K/sec   (87%)
+   38,447  cache-misses:k       # 43.131 K/sec   (87%)
+9,688,515  instructions         # 10.561 M/sec   (89%)
+
+Total test time: 1.026802 seconds.
+```
+
+In the example above, each event is monitored about 87% of the total time. But there is no
+guarantee that any pair of events are always monitored at the same time. If we want to have some
+events monitored at the same time, we can use --group.
+
+```sh
+# Stat using event cache-references, cache-references:u,....
+$ simpleperf stat -p 7964 --group cache-references,cache-misses \
+      --group cache-references:u,cache-misses:u --group cache-references:k,cache-misses:k \
+      -e instructions --duration 1
+Performance counter statistics:
+
+3,638,900  cache-references     # 4.786 M/sec          (74%)
+   65,171  cache-misses         # 1.790953% miss rate  (74%)
+2,390,433  cache-references:u   # 3.153 M/sec          (74%)
+   32,280  cache-misses:u       # 1.350383% miss rate  (74%)
+  879,035  cache-references:k   # 1.251 M/sec          (68%)
+   30,303  cache-misses:k       # 3.447303% miss rate  (68%)
+8,921,161  instructions         # 10.070 M/sec         (86%)
+
+Total test time: 1.029843 seconds.
+```
+
+### Select target to stat
+
+We can select which processes or threads to monitor via -p or -t. Monitoring a
+process is the same as monitoring all threads in the process. Simpleperf can also fork a child
+process to run the new command and then monitor the child process.
+
+```sh
+# Stat process 11904 and 11905.
+$ simpleperf stat -p 11904,11905 --duration 10
+
+# Stat thread 11904 and 11905.
+$ simpleperf stat -t 11904,11905 --duration 10
+
+# Start a child process running `ls`, and stat it.
+$ simpleperf stat ls
+
+# Stat the process of an Android application. This only works for debuggable apps on non-rooted
+# devices.
+$ simpleperf stat --app com.example.simpleperf.simpleperfexamplewithnative
+
+# Stat system wide using -a.
+$ simpleperf stat -a --duration 10
+```
+
+### Decide how long to stat
+
+When monitoring existing threads, we can use --duration to decide how long to monitor. When
+monitoring a child process running a new command, simpleperf monitors until the child process ends.
+In this case, we can use Ctrl-C to stop monitoring at any time.
+
+```sh
+# Stat process 11904 for 10 seconds.
+$ simpleperf stat -p 11904 --duration 10
+
+# Stat until the child process running `ls` finishes.
+$ simpleperf stat ls
+
+# Stop monitoring using Ctrl-C.
+$ simpleperf stat -p 11904 --duration 10
+^C
+```
+
+If you want to write a script to control how long to monitor, you can send one of SIGINT, SIGTERM,
+SIGHUP signals to simpleperf to stop monitoring.
+
+### Decide the print interval
+
+When monitoring perf counters, we can also use --interval to decide the print interval.
+
+```sh
+# Print stat for process 11904 every 300ms.
+$ simpleperf stat -p 11904 --duration 10 --interval 300
+
+# Print system wide stat at interval of 300ms for 10 seconds. Note that system wide profiling needs
+# root privilege.
+$ su 0 simpleperf stat -a --duration 10 --interval 300
+```
+
+### Display counters in systrace
+
+Simpleperf can also work with systrace to dump counters in the collected trace. Below is an example
+to do a system wide stat.
+
+```sh
+# Capture instructions (kernel only) and cache misses with interval of 300 milliseconds for 15
+# seconds.
+$ su 0 simpleperf stat -e instructions:k,cache-misses -a --interval 300 --duration 15
+# On host launch systrace to collect trace for 10 seconds.
+(HOST)$ external/chromium-trace/systrace.py --time=10 -o new.html sched gfx view
+# Open the collected new.html in browser and perf counters will be shown up.
+```
+
+## The record command
+
+The record command is used to dump samples of the profiled processes. Each sample can contain
+information like the time at which the sample was generated, the number of events since last
+sample, the program counter of a thread, the call chain of a thread.
+
+By passing options, we can select which events to use, which processes/threads to monitor,
+what frequency to dump samples, how long to monitor, and where to store samples.
+
+```sh
+# Record on process 7394 for 10 seconds, using default event (cpu-cycles), using default sample
+# frequency (4000 samples per second), writing records to perf.data.
+$ simpleperf record -p 7394 --duration 10
+simpleperf I cmd_record.cpp:316] Samples recorded: 21430. Samples lost: 0.
+```
+
+### Select events to record
+
+By default, the cpu-cycles event is used to evaluate consumed cpu cycles. But we can also use other
+events via -e.
+
+```sh
+# Record using event instructions.
+$ simpleperf record -e instructions -p 11904 --duration 10
+
+# Record using task-clock, which shows the passed CPU time in nanoseconds.
+$ simpleperf record -e task-clock -p 11904 --duration 10
+```
+
+### Select target to record
+
+The way to select target in record command is similar to that in the stat command.
+
+```sh
+# Record process 11904 and 11905.
+$ simpleperf record -p 11904,11905 --duration 10
+
+# Record thread 11904 and 11905.
+$ simpleperf record -t 11904,11905 --duration 10
+
+# Record a child process running `ls`.
+$ simpleperf record ls
+
+# Record the process of an Android application. This only works for debuggable apps on non-rooted
+# devices.
+$ simpleperf record --app com.example.simpleperf.simpleperfexamplewithnative
+
+# Record system wide.
+$ simpleperf record -a --duration 10
+```
+
+### Set the frequency to record
+
+We can set the frequency to dump records via -f or -c. For example, -f 4000 means
+dumping approximately 4000 records every second when the monitored thread runs. If a monitored
+thread runs 0.2s in one second (it can be preempted or blocked in other times), simpleperf dumps
+about 4000 * 0.2 / 1.0 = 800 records every second. Another way is using -c. For example, -c 10000
+means dumping one record whenever 10000 events happen.
+
+```sh
+# Record with sample frequency 1000: sample 1000 times every second running.
+$ simpleperf record -f 1000 -p 11904,11905 --duration 10
+
+# Record with sample period 100000: sample 1 time every 100000 events.
+$ simpleperf record -c 100000 -t 11904,11905 --duration 10
+```
+
+To avoid taking too much time generating samples, kernel >= 3.10 sets the max percent of cpu time
+used for generating samples (default is 25%), and decreases the max allowed sample frequency when
+hitting that limit. Simpleperf uses --cpu-percent option to adjust it, but it needs either root
+privilege or to be on Android >= Q.
+
+```sh
+# Record with sample frequency 10000, with max allowed cpu percent to be 50%.
+$ simpleperf record -f 1000 -p 11904,11905 --duration 10 --cpu-percent 50
+```
+
+### Decide how long to record
+
+The way to decide how long to monitor in record command is similar to that in the stat command.
+
+```sh
+# Record process 11904 for 10 seconds.
+$ simpleperf record -p 11904 --duration 10
+
+# Record until the child process running `ls` finishes.
+$ simpleperf record ls
+
+# Stop monitoring using Ctrl-C.
+$ simpleperf record -p 11904 --duration 10
+^C
+```
+
+If you want to write a script to control how long to monitor, you can send one of SIGINT, SIGTERM,
+SIGHUP signals to simpleperf to stop monitoring.
+
+### Set the path to store profiling data
+
+By default, simpleperf stores profiling data in perf.data in the current directory. But the path
+can be changed using -o.
+
+```sh
+# Write records to data/perf2.data.
+$ simpleperf record -p 11904 -o data/perf2.data --duration 10
+```
+
+#### Record call graphs
+
+A call graph is a tree showing function call relations. Below is an example.
+
+```
+main() {
+    FunctionOne();
+    FunctionTwo();
+}
+FunctionOne() {
+    FunctionTwo();
+    FunctionThree();
+}
+a call graph:
+    main-> FunctionOne
+       |    |
+       |    |-> FunctionTwo
+       |    |-> FunctionThree
+       |
+       |-> FunctionTwo
+```
+
+A call graph shows how a function calls other functions, and a reversed call graph shows how
+a function is called by other functions. To show a call graph, we need to first record it, then
+report it.
+
+There are two ways to record a call graph, one is recording a dwarf based call graph, the other is
+recording a stack frame based call graph. Recording dwarf based call graphs needs support of debug
+information in native binaries. While recording stack frame based call graphs needs support of
+stack frame registers.
+
+```sh
+# Record a dwarf based call graph
+$ simpleperf record -p 11904 -g --duration 10
+
+# Record a stack frame based call graph
+$ simpleperf record -p 11904 --call-graph fp --duration 10
+```
+
+[Here](README.md#suggestions-about-recording-call-graphs) are some suggestions about recording call graphs.
+
+### Record both on CPU time and off CPU time
+
+Simpleperf is a CPU profiler, it generates samples for a thread only when it is running on a CPU.
+However, sometimes we want to figure out where the time of a thread is spent, whether it is running
+on a CPU, or staying in the kernel's ready queue, or waiting for something like I/O events.
+
+To support this, the record command uses --trace-offcpu to trace both on CPU time and off CPU time.
+When --trace-offcpu is used, simpleperf generates a sample when a running thread is scheduled out,
+so we know the callstack of a thread when it is scheduled out. And when reporting a perf.data
+generated with --trace-offcpu, we use time to the next sample (instead of event counts from the
+previous sample) as the weight of the current sample. As a result, we can get a call graph based
+on timestamps, including both on CPU time and off CPU time.
+
+trace-offcpu is implemented using sched:sched_switch tracepoint event, which may not be supported
+on old kernels. But it is guaranteed to be supported on devices >= Android O MR1. We can check
+whether trace-offcpu is supported as below.
+
+```sh
+$ simpleperf list --show-features
+dwarf-based-call-graph
+trace-offcpu
+```
+
+If trace-offcpu is supported, it will be shown in the feature list. Then we can try it.
+
+```sh
+# Record with --trace-offcpu.
+$ simpleperf record -g -p 11904 --duration 10 --trace-offcpu
+
+# Record with --trace-offcpu using app_profiler.py.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
+    -r "-g -e task-clock:u -f 1000 --duration 10 --trace-offcpu"
+```
+
+Below is an example comparing the profiling result with / without --trace-offcpu.
+First we record without --trace-offcpu.
+
+```sh
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity
+
+$ python report_html.py --add_disassembly --add_source_code --source_dirs ../demo
+```
+
+The result is [here](./without_trace_offcpu.html).
+In the result, all time is taken by RunFunction(), and sleep time is ignored.
+But if we add --trace-offcpu, the result changes.
+
+```sh
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity \
+    -r "-g -e task-clock:u --trace-offcpu -f 1000 --duration 10"
+
+$ python report_html.py --add_disassembly --add_source_code --source_dirs ../demo
+```
+
+The result is [here](./trace_offcpu.html).
+In the result, half of the time is taken by RunFunction(), and the other half is taken by
+SleepFunction(). So it traces both on CPU time and off CPU time.
+
+## The report command
+
+The report command is used to report profiling data generated by the record command. The report
+contains a table of sample entries. Each sample entry is a row in the report. The report command
+groups samples belong to the same process, thread, library, function in the same sample entry. Then
+sort the sample entries based on the event count a sample entry has.
+
+By passing options, we can decide how to filter out uninteresting samples, how to group samples
+into sample entries, and where to find profiling data and binaries.
+
+Below is an example. Records are grouped into 4 sample entries, each entry is a row. There are
+several columns, each column shows piece of information belonging to a sample entry. The first
+column is Overhead, which shows the percentage of events inside the current sample entry in total
+events. As the perf event is cpu-cycles, the overhead is the percentage of CPU cycles used in each
+function.
+
+```sh
+# Reports perf.data, using only records sampled in libsudo-game-jni.so, grouping records using
+# thread name(comm), process id(pid), thread id(tid), function name(symbol), and showing sample
+# count for each row.
+$ simpleperf report --dsos /data/app/com.example.sudogame-2/lib/arm64/libsudo-game-jni.so \
+      --sort comm,pid,tid,symbol -n
+Cmdline: /data/data/com.example.sudogame/simpleperf record -p 7394 --duration 10
+Arch: arm64
+Event: cpu-cycles (type 0, config 0)
+Samples: 28235
+Event count: 546356211
+
+Overhead  Sample  Command    Pid   Tid   Symbol
+59.25%    16680   sudogame  7394  7394  checkValid(Board const&, int, int)
+20.42%    5620    sudogame  7394  7394  canFindSolution_r(Board&, int, int)
+13.82%    4088    sudogame  7394  7394  randomBlock_r(Board&, int, int, int, int, int)
+6.24%     1756    sudogame  7394  7394  @plt
+```
+
+### Set the path to read profiling data
+
+By default, the report command reads profiling data from perf.data in the current directory.
+But the path can be changed using -i.
+
+```sh
+$ simpleperf report -i data/perf2.data
+```
+
+### Set the path to find binaries
+
+To report function symbols, simpleperf needs to read executable binaries used by the monitored
+processes to get symbol table and debug information. By default, the paths are the executable
+binaries used by monitored processes while recording. However, these binaries may not exist when
+reporting or not contain symbol table and debug information. So we can use --symfs to redirect
+the paths.
+
+```sh
+# In this case, when simpleperf wants to read executable binary /A/b, it reads file in /A/b.
+$ simpleperf report
+
+# In this case, when simpleperf wants to read executable binary /A/b, it prefers file in
+# /debug_dir/A/b to file in /A/b.
+$ simpleperf report --symfs /debug_dir
+
+# Read symbols for system libraries built locally. Note that this is not needed since Android O,
+# which ships symbols for system libraries on device.
+$ simpleperf report --symfs $ANDROID_PRODUCT_OUT/symbols
+```
+
+### Filter samples
+
+When reporting, it happens that not all records are of interest. The report command supports four
+filters to select samples of interest.
+
+```sh
+# Report records in threads having name sudogame.
+$ simpleperf report --comms sudogame
+
+# Report records in process 7394 or 7395
+$ simpleperf report --pids 7394,7395
+
+# Report records in thread 7394 or 7395.
+$ simpleperf report --tids 7394,7395
+
+# Report records in libsudo-game-jni.so.
+$ simpleperf report --dsos /data/app/com.example.sudogame-2/lib/arm64/libsudo-game-jni.so
+```
+
+### Group samples into sample entries
+
+The report command uses --sort to decide how to group sample entries.
+
+```sh
+# Group records based on their process id: records having the same process id are in the same
+# sample entry.
+$ simpleperf report --sort pid
+
+# Group records based on their thread id and thread comm: records having the same thread id and
+# thread name are in the same sample entry.
+$ simpleperf report --sort tid,comm
+
+# Group records based on their binary and function: records in the same binary and function are in
+# the same sample entry.
+$ simpleperf report --sort dso,symbol
+
+# Default option: --sort comm,pid,tid,dso,symbol. Group records in the same thread, and belong to
+# the same function in the same binary.
+$ simpleperf report
+```
+
+#### Report call graphs
+
+To report a call graph, please make sure the profiling data is recorded with call graphs,
+as [here](#record-call-graphs).
+
+```
+$ simpleperf report -g
+```
diff --git a/doc/scripts_reference.md b/doc/scripts_reference.md
new file mode 100644
index 0000000..746da76
--- /dev/null
+++ b/doc/scripts_reference.md
@@ -0,0 +1,233 @@
+# Scripts reference
+
+## Table of Contents
+
+- [app_profiler.py](#app_profilerpy)
+    - [Profile from launch of an application](#profile-from-launch-of-an-application)
+- [run_simpleperf_without_usb_connection.py](#run_simpleperf_without_usb_connectionpy)
+- [binary_cache_builder.py](#binary_cache_builderpy)
+- [run_simpleperf_on_device.py](#run_simpleperf_on_devicepy)
+- [report.py](#reportpy)
+- [report_html.py](#report_htmlpy)
+- [inferno](#inferno)
+- [pprof_proto_generator.py](#pprof_proto_generatorpy)
+- [report_sample.py](#report_samplepy)
+- [simpleperf_report_lib.py](#simpleperf_report_libpy)
+
+
+## app_profiler.py
+
+app_profiler.py is used to record profiling data for Android applications and native executables.
+
+```sh
+# Record an Android application.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
+
+# Record an Android application with Java code compiled into native instructions.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative --compile_java_code
+
+# Record the launch of an Activity of an Android application.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .SleepActivity
+
+# Record a native process.
+$ python app_profiler.py -np surfaceflinger
+
+# Record a native process given its pid.
+$ python app_profiler.py --pid 11324
+
+# Record a command.
+$ python app_profiler.py -cmd \
+    "dex2oat --dex-file=/data/local/tmp/app-profiling.apk --oat-file=/data/local/tmp/a.oat"
+
+# Record an Android application, and use -r to send custom options to the record command.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
+    -r "-e cpu-clock -g --duration 30"
+
+# Record both on CPU time and off CPU time.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative \
+    -r "-e task-clock -g -f 1000 --duration 10 --trace-offcpu"
+
+# Save profiling data in a custom file (like perf_custom.data) instead of perf.data.
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -o perf_custom.data
+```
+
+### Profile from launch of an application
+
+Sometimes we want to profile the launch-time of an application. To support this, we added --app in
+the record command. The --app option sets the package name of the Android application to profile.
+If the app is not already running, the record command will poll for the app process in a loop with
+an interval of 1ms. So to profile from launch of an application, we can first start the record
+command with --app, then start the app. Below is an example.
+
+```sh
+$ python run_simpleperf_on_device.py record
+    --app com.example.simpleperf.simpleperfexamplewithnative \
+    -g --duration 1 -o /data/local/tmp/perf.data
+# Start the app manually or using the `am` command.
+```
+
+To make it convenient to use, app_profiler.py supports using the -a option to start an Activity
+after recording has started.
+
+```sh
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative -a .MainActivity
+```
+
+### run_simpleperf_without_usb_connection.py
+
+run_simpleperf_without_usb_connection.py records profiling data while the USB cable isn't
+connected. Below is an example.
+
+```sh
+$ python run_simpleperf_without_usb_connection.py start \
+    -p com.example.simpleperf.simpleperfexamplewithnative
+# After the command finishes successfully, unplug the USB cable, run the
+# SimpleperfExampleWithNative app. After a few seconds, plug in the USB cable.
+$ python run_simpleperf_without_usb_connection.py stop
+# It may take a while to stop recording. After that, the profiling data is collected in perf.data
+# on host.
+```
+
+## binary_cache_builder.py
+
+The binary_cache directory is a directory holding binaries needed by a profiling data file. The
+binaries are expected to be unstripped, having debug information and symbol tables. The
+binary_cache directory is used by report scripts to read symbols of binaries. It is also used by
+report_html.py to generate annotated source code and disassembly.
+
+By default, app_profiler.py builds the binary_cache directory after recording. But we can also
+build binary_cache for existing profiling data files using binary_cache_builder.py. It is useful
+when you record profiling data using `simpleperf record` directly, to do system wide profiling or
+record without the USB cable connected.
+
+binary_cache_builder.py can either pull binaries from an Android device, or find binaries in
+directories on the host (via -lib).
+
+```sh
+# Generate binary_cache for perf.data, by pulling binaries from the device.
+$ python binary_cache_builder.py
+
+# Generate binary_cache, by pulling binaries from the device and finding binaries in
+# SimpleperfExampleWithNative.
+$ python binary_cache_builder.py -lib path_of_SimpleperfExampleWithNative
+```
+
+## run_simpleperf_on_device.py
+
+This script pushes the simpleperf executable on the device, and run a simpleperf command on the
+device. It is more convenient than running adb commands manually.
+
+## report.py
+
+report.py is a wrapper of the report command on the host. It accepts all options of the report
+command.
+
+```sh
+# Report call graph
+$ python report.py -g
+
+# Report call graph in a GUI window implemented by Python Tk.
+$ python report.py -g --gui
+```
+
+## report_html.py
+
+report_html.py generates report.html based on the profiling data. Then the report.html can show
+the profiling result without depending on other files. So it can be shown in local browsers or
+passed to other machines. Depending on which command-line options are used, the content of the
+report.html can include: chart statistics, sample table, flamegraphs, annotated source code for
+each function, annotated disassembly for each function.
+
+```sh
+# Generate chart statistics, sample table and flamegraphs, based on perf.data.
+$ python report_html.py
+
+# Add source code.
+$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative
+
+# Add disassembly.
+$ python report_html.py --add_disassembly
+
+# Adding disassembly for all binaries can cost a lot of time. So we can choose to only add
+# disassembly for selected binaries.
+$ python report_html.py --add_disassembly --binary_filter libgame.so
+
+# report_html.py accepts more than one recording data file.
+$ python report_html.py -i perf1.data perf2.data
+```
+
+Below is an example of generating html profiling results for SimpleperfExampleWithNative.
+
+```sh
+$ python app_profiler.py -p com.example.simpleperf.simpleperfexamplewithnative
+$ python report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleWithNative \
+    --add_disassembly
+```
+
+After opening the generated [report.html](./report_html.html) in a browser, there are several tabs:
+
+The first tab is "Chart Statistics". You can click the pie chart to show the time consumed by each
+process, thread, library and function.
+
+The second tab is "Sample Table". It shows the time taken by each function. By clicking one row in
+the table, we can jump to a new tab called "Function".
+
+The third tab is "Flamegraph". It shows the graphs generated by [inferno](./inferno.md).
+
+The fourth tab is "Function". It only appears when users click a row in the "Sample Table" tab.
+It shows information of a function, including:
+
+1. A flamegraph showing functions called by that function.
+2. A flamegraph showing functions calling that function.
+3. Annotated source code of that function. It only appears when there are source code files for
+   that function.
+4. Annotated disassembly of that function. It only appears when there are binaries containing that
+   function.
+
+## inferno
+
+[inferno](./inferno.md) is a tool used to generate flamegraph in a html file.
+
+```sh
+# Generate flamegraph based on perf.data.
+# On Windows, use inferno.bat instead of ./inferno.sh.
+$ ./inferno.sh -sc --record_file perf.data
+
+# Record a native program and generate flamegraph.
+$ ./inferno.sh -np surfaceflinger
+```
+
+## pprof_proto_generator.py
+
+It converts a profiling data file into pprof.proto, a format used by [pprof](https://github.com/google/pprof).
+
+```sh
+# Convert perf.data in the current directory to pprof.proto format.
+$ python pprof_proto_generator.py
+$ pprof -pdf pprof.profile
+```
+
+## report_sample.py
+
+It converts a profiling data file into a format used by [FlameGraph](https://github.com/brendangregg/FlameGraph).
+
+```sh
+# Convert perf.data in the current directory to a format used by FlameGraph.
+$ python report_sample.py --symfs binary_cache >out.perf
+$ git clone https://github.com/brendangregg/FlameGraph.git
+$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded
+$ FlameGraph/flamegraph.pl out.folded >a.svg
+```
+
+## simpleperf_report_lib.py
+
+simpleperf_report_lib.py is a Python library used to parse profiling data files generated by the
+record command. Internally, it uses libsimpleperf_report.so to do the work. Generally, for each
+profiling data file, we create an instance of ReportLib, pass it the file path (via SetRecordFile).
+Then we can read all samples through GetNextSample(). For each sample, we can read its event info
+(via GetEventOfCurrentSample), symbol info (via GetSymbolOfCurrentSample) and call chain info
+(via GetCallChainOfCurrentSample). We can also get some global information, like record options
+(via GetRecordCmd), the arch of the device (via GetArch) and meta strings (via MetaInfo).
+
+Examples of using simpleperf_report_lib.py are in report_sample.py, report_html.py,
+pprof_proto_generator.py and inferno/inferno.py.
diff --git a/inferno/data_types.py b/inferno/data_types.py
index deb9f51..35ef4c0 100644
--- a/inferno/data_types.py
+++ b/inferno/data_types.py
@@ -113,15 +113,16 @@
                                                               self._get_next_callsite_id())
         return child
 
-    def trim_callchain(self, min_num_events):
+    def trim_callchain(self, min_num_events, max_depth, depth=0):
         """ Remove call sites with num_events < min_num_events in the subtree.
             Remaining children are collected in a list.
         """
-        for key in self.child_dict:
-            child = self.child_dict[key]
-            if child.num_events >= min_num_events:
-                child.trim_callchain(min_num_events)
-                self.children.append(child)
+        if depth <= max_depth:
+            for key in self.child_dict:
+                child = self.child_dict[key]
+                if child.num_events >= min_num_events:
+                    child.trim_callchain(min_num_events, max_depth, depth + 1)
+                    self.children.append(child)
         # Relese child_dict since it will not be used.
         self.child_dict = None
 
diff --git a/inferno/inferno.py b/inferno/inferno.py
index 4566f3e..12b9d90 100755
--- a/inferno/inferno.py
+++ b/inferno/inferno.py
@@ -40,7 +40,7 @@
 SCRIPTS_PATH = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
 sys.path.append(SCRIPTS_PATH)
 from simpleperf_report_lib import ReportLib
-from utils import log_exit, log_info, AdbHelper, open_report_in_browser
+from utils import log_exit, log_fatal, log_info, AdbHelper, open_report_in_browser
 
 from data_types import Process
 from svg_renderer import get_proper_scaled_time_string, render_svg
@@ -55,8 +55,10 @@
         app_profiler_args += ["-np", args.native_program]
     elif args.pid != -1:
         app_profiler_args += ['--pid', str(args.pid)]
+    elif args.system_wide:
+        app_profiler_args += ['--system_wide']
     else:
-        log_exit("Please set profiling target with -p, -np or --pid option.")
+        log_exit("Please set profiling target with -p, -np, --pid or --system_wide option.")
     if args.compile_java_code:
         app_profiler_args.append("--compile_java_code")
     if args.disable_adb_root:
@@ -141,7 +143,7 @@
 
     for thread in process.threads.values():
         min_event_count = thread.num_events * args.min_callchain_percentage * 0.01
-        thread.flamegraph.trim_callchain(min_event_count)
+        thread.flamegraph.trim_callchain(min_event_count, args.max_callchain_depth)
 
     log_info("Parsed %s callchains." % process.num_samples)
 
@@ -271,6 +273,7 @@
     record_group.add_argument('--record_file', default='perf.data', help='Default is perf.data.')
     record_group.add_argument('-sc', '--skip_collection', action='store_true', help="""Skip data
                               collection""")
+    record_group.add_argument('--system_wide', action='store_true', help='Profile system wide.')
     record_group.add_argument('-t', '--capture_duration', type=int, default=10, help="""Capture
                               duration in seconds.""")
 
@@ -286,6 +289,11 @@
                               It is used to limit nodes shown in the flamegraph. For example,
                               when set to 0.01, only callchains taking >= 0.01%% of the event
                               count of the owner thread are collected in the report.""")
+    report_group.add_argument('--max_callchain_depth', default=1000000000, type=int, help="""
+                              Set maximum depth of callchains shown in the report. It is used
+                              to limit the nodes shown in the flamegraph and avoid processing
+                              limits. For example, when set to 10, callstacks will be cut after
+                              the tenth frame.""")
     report_group.add_argument('--no_browser', action='store_true', help="""Don't open report
                               in browser.""")
     report_group.add_argument('-o', '--report_path', default='report.html', help="""Set report
@@ -308,9 +316,15 @@
         if args.pid != -1:
             process.pid = args.pid
             args.native_program = ''
+        if args.system_wide:
+            process.pid = -1
+            args.native_program = ''
 
-        process.name = args.app or args.native_program or ('Process %d' % args.pid)
-        log_info("Starting data collection stage for process '%s'." % process.name)
+        if args.system_wide:
+            process.name = 'system_wide'
+        else:
+            process.name = args.app or args.native_program or ('Process %d' % args.pid)
+        log_info("Starting data collection stage for '%s'." % process.name)
         if not collect_data(args):
             log_exit("Unable to collect data.")
         if process.pid == 0:
@@ -334,11 +348,16 @@
             args.title = ''
         args.title += '(One Flamegraph)'
 
-    parse_samples(process, args, sample_filter_fn)
-    generate_threads_offsets(process)
-    report_path = output_report(process, args)
-    if not args.no_browser:
-        open_report_in_browser(report_path)
+    try:
+        parse_samples(process, args, sample_filter_fn)
+        generate_threads_offsets(process)
+        report_path = output_report(process, args)
+        if not args.no_browser:
+            open_report_in_browser(report_path)
+    except RuntimeError as r:
+        if 'maximum recursion depth' in r.__str__():
+            log_fatal("Recursion limit exceeded (%s), try --max_callchain_depth." % r)
+        raise r
 
     log_info("Flamegraph generated at '%s'." % report_path)
 
diff --git a/pprof_proto_generator.py b/pprof_proto_generator.py
index d0b4da9..4c59cc5 100755
--- a/pprof_proto_generator.py
+++ b/pprof_proto_generator.py
@@ -30,8 +30,8 @@
 import os.path
 
 from simpleperf_report_lib import ReportLib
-from utils import Addr2Nearestline, bytes_to_str, extant_dir, find_tool_path, flatten_arg_list
-from utils import log_info, log_exit, str_to_bytes
+from utils import Addr2Nearestline, extant_dir, find_tool_path, flatten_arg_list
+from utils import log_info, log_exit
 try:
     import profile_pb2
 except ImportError:
@@ -40,13 +40,13 @@
 def load_pprof_profile(filename):
     profile = profile_pb2.Profile()
     with open(filename, "rb") as f:
-        profile.ParseFromString(bytes_to_str(f.read()))
+        profile.ParseFromString(f.read())
     return profile
 
 
 def store_pprof_profile(filename, profile):
     with open(filename, 'wb') as f:
-        f.write(str_to_bytes(profile.SerializeToString()))
+        f.write(profile.SerializeToString())
 
 
 class PprofProfilePrinter(object):
@@ -256,6 +256,8 @@
         kallsyms = 'binary_cache/kallsyms'
         if os.path.isfile(kallsyms):
             self.lib.SetKallsymsFile(kallsyms)
+        if config.get('show_art_frames'):
+            self.lib.ShowArtFrames()
         self.comm_filter = set(config['comm_filters']) if config.get('comm_filters') else None
         if config.get('pid_filters'):
             self.pid_filter = {int(x) for x in config['pid_filters']}
@@ -266,6 +268,7 @@
         else:
             self.tid_filter = None
         self.dso_filter = set(config['dso_filters']) if config.get('dso_filters') else None
+        self.max_chain_length = config['max_chain_length']
         self.profile = profile_pb2.Profile()
         self.profile.string_table.append('')
         self.string_table = {}
@@ -300,7 +303,7 @@
             if self._filter_symbol(symbol):
                 location_id = self.get_location_id(symbol.vaddr_in_file, symbol)
                 sample.add_location_id(location_id)
-            for i in range(callchain.nr):
+            for i in range(max(0, callchain.nr - self.max_chain_length), callchain.nr):
                 entry = callchain.entries[i]
                 if self._filter_symbol(symbol):
                     location_id = self.get_location_id(entry.ip, entry.symbol)
@@ -328,12 +331,12 @@
         if self.comm_filter:
             if sample.thread_comm not in self.comm_filter:
                 return False
-            if self.pid_filter:
-                if sample.pid not in self.pid_filter:
-                    return False
-            if self.tid_filter:
-                if sample.tid not in self.tid_filter:
-                    return False
+        if self.pid_filter:
+            if sample.pid not in self.pid_filter:
+                return False
+        if self.tid_filter:
+            if sample.tid not in self.tid_filter:
+                return False
         return True
 
     def _filter_symbol(self, symbol):
@@ -560,7 +563,11 @@
         Use samples only in threads with selected thread ids.""")
     parser.add_argument('--dso', nargs='+', action='append', help="""
         Use samples only in selected binaries.""")
+    parser.add_argument('--max_chain_length', type=int, default=1000000000, help="""
+        Maximum depth of samples to be converted.""")  # Large value as infinity standin.
     parser.add_argument('--ndk_path', type=extant_dir, help='Set the path of a ndk release.')
+    parser.add_argument('--show_art_frames', action='store_true',
+                        help='Show frames of internal methods in the ART Java interpreter.')
 
     args = parser.parse_args()
     if args.show:
@@ -578,6 +585,8 @@
     config['tid_filters'] = flatten_arg_list(args.tid)
     config['dso_filters'] = flatten_arg_list(args.dso)
     config['ndk_path'] = args.ndk_path
+    config['show_art_frames'] = args.show_art_frames
+    config['max_chain_length'] = args.max_chain_length
     generator = PprofProfileGenerator(config)
     profile = generator.gen()
     store_pprof_profile(config['output_file'], profile)
diff --git a/repo.prop b/repo.prop
index 6ba371d..ffb1a46 100644
--- a/repo.prop
+++ b/repo.prop
@@ -1,714 +1,748 @@
-device/common 6970adda2ffe9c8c88e45c4f4ecf3251bbacf22f
-device/generic/arm64 a3d1b745ea3f5d4c3c8fefd5a8dc3e4880de7de6
-device/generic/armv7-a-neon 133e4a7fac01e7f425e329c190eeb444b6278684
-device/generic/car a096a2ce344a477ea160a2e80fab4bf09a50c3b9
-device/generic/common e4dedcd0131501afd9b2258fb3a360c201a54c40
-device/generic/goldfish ace354ca9e967e0228be09b42b2d2a8e93a114b9
-device/generic/goldfish-opengl def88ba65d2f8768e2e6979f81766c7a23a4f607
+device/amlogic/yukawa 081ef6ccba4ad00f3d991957e2c4da9dbc559ff2
+device/amlogic/yukawa-kernel c56ef788cbc28b5b682e53a5ba241258a59bf4f8
+device/common 76763e9bb3a7626dfdd56bee9d0623d97718f990
+device/generic/arm64 e666c6c44e9fa2a932fdb42bad2b8bf7e1a1a410
+device/generic/armv7-a-neon 8f2d84097dd6a8d60f01723c84b8bf6bd8bd48c3
+device/generic/car 464df04b1b53a28c05f38c3f5fd0702dcfc3d48f
+device/generic/common 3e69a3ed31c97d036af02203c605e61b692336f3
+device/generic/goldfish c908b9879175b0a146be4565aaad61ca75245005
+device/generic/goldfish-opengl addde2aed3779327b696117732cdb66a51900bfa
 device/generic/mini-emulator-arm64 595ad51d88bfbd3e680b290b69bbb28f6ee41f27
 device/generic/mini-emulator-armv7-a-neon c65b46a1a0d89411e666244423555c860413e911
 device/generic/mini-emulator-x86 eed5690b365f4859bf718d48345902ac99484cc4
 device/generic/mini-emulator-x86_64 e7cbff5118aefe44a397bc793e944b0f1eb7c84c
-device/generic/opengl-transport 816a8bb0375be3c581cb7b1ab77b377cf51d4714
-device/generic/qemu b74a1466ebfc21bfb24dcab7a277556e3ac37022
-device/generic/uml 501be3709a9e2d9481ae0065ea6453d104301b35
-device/generic/x86 1350fd322b2a1aac1bc937adaa6332ddb717d4bd
+device/generic/opengl-transport 0aef3e23b0d8baf292ec0f26c23f9d16cc907926
+device/generic/qemu 95b7523627888b579b3a5cde36128d14c773b987
+device/generic/trusty 73919b3cb2a8fc4144a775d1f0f40750ce290f02
+device/generic/uml 9476e9fe155ce43b451b8766f405c1010c4842cd
+device/generic/x86 cfaf488774b46c9ddb5adbd4678c1a89a33d448a
 device/generic/x86_64 506952733fdebb5a2ef086b519ceebe86a95ae31
-device/google/accessory/arduino abc5159a3ca9dbb5c7e364a1eab99901a4440ac5
-device/google/accessory/demokit 7dfe7f89a3b174709c773fe319531006e46440d9
-device/google/atv 6e89be81da7f23f8957b1e8fc257b40f1c3d525b
-device/google/contexthub c8917ff19187ba6591ae3e8939f9420511a17619
-device/google/crosshatch 2e2b5cb006e2bcd181f47d652662c8ee7e10866b
-device/google/crosshatch-kernel 7379c9d6518fbcd32d3e9047bab55d488826abc8
-device/google/crosshatch-sepolicy d32fa3d01bc2c88da917bd322634d01e1da4bba9
-device/google/cuttlefish 0a51a70c4eef4ec94ecfa1a5bd8deee97b0d8ffb
-device/google/cuttlefish_common d915c8cdb014c73edcdae6b2b1132eb5640f63fe
-device/google/cuttlefish_kernel 3f7e47d0a05806008974e479eb265e0fb5c79b9e
-device/google/fuchsia 1a3b88b18fdabbbef0453128e1a00414d88809e6
-device/google/marlin 8caf5218fb9f33cb73b5a6286df3d9532a146625
-device/google/marlin-kernel 8ab7076806ff5a22e5ac2cfaa4d764adc7debddd
-device/google/muskie c5d86934ee66c88618667348d828786d90ad8ed2
-device/google/taimen a063e91433339f732a379a9b3f6a40df344a7357
-device/google/vrservices 5471f7ac4c9aeaba6591d97c36d4848819069ede
-device/google/wahoo f79d38f578151cec1c6d33561fac3dccc801e21f
-device/google/wahoo-kernel 8576225f7aee11f492201f770051e00a93077634
-device/linaro/bootloader/OpenPlatformPkg a06ae199a4412f5333e19b1614599bf8b3081699
-device/linaro/bootloader/arm-trusted-firmware 9ad008461f280700c253cfaca9d1856b85131994
-device/linaro/bootloader/edk2 829ea1ae4e36fb4aafc4ddeb506810233e98819e
-device/linaro/hikey 7c420689f032652d81aafabf99ac29f28d11bb39
-device/linaro/hikey-kernel 4a1cb4e1e7a91248608edde4dc48fb0862c9f784
-device/linaro/poplar 23719d9164359d1452b5a712733d4d45eed9e35d
-device/linaro/poplar-kernel d7bb1d4b42aa0a8464462db3cf6bbbb440ee7f2b
-device/sample 6c9c5c0c6902bcb7bab01725217ee7fdf087fd4c
-device/ti/beagle-x15 914f4849f8d5ccbb5a07d685d573740d9928e928
-device/ti/beagle-x15-kernel 8693a5622727e348844a335494de68bd2267f17d
-kernel/configs 5b4cda38d49639cd1b1eb6cc04383319e52ca434
-kernel/tests 47610ab0d1532478b4c1d87ccac161fbc9359b44
-platform/art 252dd18a225d360c172f13f92165a564391f2996
-platform/bionic 9ea997a2ac4eeb26230e65d2b680ebff6fe0b8a4
-platform/bootable/recovery c456aab7e26ceaa8a322668122029c85a4eb4c31
-platform/build 9c9ea97fa04083d87fd0ecc74112a1319f22471b
-platform/build/blueprint 8983c5359002a8e6991c29d2339858cd9714ed5d
-platform/build/kati 679d6bb847abadde3f61ba773eb34b6b7929b674
-platform/build/soong fee2bff77ce6d5c6a9c4f3971c385432dd7d8859
-platform/compatibility/cdd 252136202b40994ee021ed9a9e56c79974291a7d
-platform/cts e1559aa5bb07e1b385cb4c13cee99ef59b42e0ee
-platform/dalvik 906f0f6c078316281f64f20a4da3209b79468ed7
-platform/developers/build 6ab5ca782457a92c824cd81a0042f06bd6dcd5cd
+device/google/atv 496dd68bef5800a3b617a1cc2f5b40e661938b17
+device/google/bonito e6924cdda504d1ec4a08a0532ff29613725ee70a
+device/google/bonito-kernel 7afe38eee9c5fbc8eaf104099a61f6dd8b1c2834
+device/google/bonito-sepolicy 1abcc94e32f9c5b4b870d4efe4f08bdb51281894
+device/google/contexthub 7373b667c4ae2bc9857065a94b0812661d99f803
+device/google/crosshatch c6accf19180e7c330fc0e8185c71bd8cb0cc8e3d
+device/google/crosshatch-kernel b62bfff81bec4927707ff29d28bc71a9bea070f2
+device/google/crosshatch-sepolicy 15b47541cde380b64d9fccb7efc2462976d6d867
+device/google/cuttlefish 20048fb498422563bd679f50781fd0019a401f19
+device/google/cuttlefish_common 730ce9521015ba2f2602e90504ba602b21a537d4
+device/google/cuttlefish_kernel 1a78cd1c2f6bd745ee77e8451f0bf8c909254a2e
+device/google/cuttlefish_vmm 59dbd1ec9bb6efecb7fa9f15378d65f5bd3849cc
+device/google/fuchsia 6267441d7abca8bd0a82ec1965ed0b17ef290b4d
+device/google/marlin 9c2d1e5e92921313386014a3f0283f264ceef1cb
+device/google/marlin-kernel 03f9e4e844cbc79061583d99f2d7c78225e5597a
+device/google/muskie f945a6f897fb984ae2a1f464bf4b7761a71b4131
+device/google/taimen b29ba86b2c864f887daeb71c610589b4c11a68e9
+device/google/vrservices 1744f0c3820958d5b40adc2d2590d004ac5c48d9
+device/google/wahoo 4d4ef8b97a09218a7c26bf42a4a805f783407805
+device/google/wahoo-kernel f64da58e7c64ed3411a740ed81c36520e32e1d7a
+device/linaro/bootloader/OpenPlatformPkg 2ebd72eda8b32a764d7d5b8c66e8ae4eff4bf421
+device/linaro/bootloader/arm-trusted-firmware 2b9adb6b6c8fe65ac5f60b7eacb7a7f2e216d482
+device/linaro/bootloader/edk2 074bf0f924d17e2cf1c9a679e92dc5681bdfeea6
+device/linaro/hikey 5a34763669fb4b68e4fb4d3b1b6bde5c6fead64f
+device/linaro/hikey-kernel 09f21f5731c840647965781fe0b22d87a72b62e3
+device/linaro/poplar 7f477e411dba54620b27e28d14572601521dedd4
+device/linaro/poplar-kernel be0f9775a099a8fc08c49b33340b1a7777a14c1b
+device/sample 921835519e89233727b861e4397bd251fa15d880
+device/ti/beagle-x15 5ffb31d6c2720a3c8e8486f747b554daff599840
+device/ti/beagle-x15-kernel c035f466e6bcf4f683eefc6ad5ef42e3eacd2109
+kernel/build 96dd5f06ae1e8d0acdfa01403b37d60303e9bae9
+kernel/configs c7e90932be2f130b366fe0c4a15748e64a87a37d
+kernel/tests 95eba960191e2fb6d05ec4a78528bda471b768a5
+platform/art 0671f7f1f394966d23fbc7017b9f47eb7dcb157b
+platform/bionic 777403a1dc8ecc5a7c7609c481e8058d6d81acc3
+platform/bootable/recovery 6b00bfbf69c097be28e7ece062e69f7f3e7bb8ed
+platform/build c2bb9b607aa962e4a758557113df4fab4de532fc
+platform/build/blueprint e90e70062985a067711fe981621bb2964de5e29e
+platform/build/soong af0f3016a42fb86a92766667589f855ceebf9f63
+platform/compatibility/cdd e8531774f7036bc417c5751aa8740c56e132bed9
+platform/cts f124640054f883ecae93eb754275677ebfa86d97
+platform/dalvik 6a4ee7337c569a31a44b6f8ac21fb0ce847456a5
+platform/developers/build 26d5686d5fc436c2d015669fd74e6cc44059b0da
 platform/developers/demos 03814c35b8ee0a1284c667556260124d97466b28
-platform/developers/samples/android c49a1fdd75528e566b834d7b7f3f8eaf90244d44
-platform/development 6d1c7d843d39a68076ec0fd5e5c0ee39ba8899bc
-platform/external/ImageMagick 3bdbec44dbcde69928d9a7176d8bb2611201985c
-platform/external/Microsoft-GSL 8a14b6e73def1f379c3bc1ab7e3246d6c1892275
-platform/external/Reactive-Extensions/RxCpp a83ddb5e6c88d8a76783f454bd4f03f819ffaf58
-platform/external/aac c75797cfaa5199247c53cf40dcc3329e6cdf3cce
-platform/external/adeb 692d7ecef5d5b5f77f77dbd78cda52d86b0df15f
-platform/external/adhd f82d9aa8d55139543282d698c42189b01f458ad8
-platform/external/adt-infra 384926a70c35cf8925b393c74316162f75c2fdea
-platform/external/android-clat 5d1b880412a2abbc2178138e0e2a8a85c0bbdbbe
-platform/external/androidplot 8a7b69889c2c12d7198447e1f4d7d19aa6739eda
-platform/external/ant-glob 85522dde56ebac6e2c2b5453a506f3736d899126
-platform/external/antlr 19d7c9b63eda5bc1eafe8e9ee6f536700ccc11a7
-platform/external/apache-commons-bcel 004293c4d15b334c890d6276b8d058e4ef6b9b21
-platform/external/apache-commons-compress 14c558973fadd298cd0c00f724c51c09a1ef90fa
-platform/external/apache-commons-math fe016bc48e7f159cd47a15845c620ad8e0bfdfc5
-platform/external/apache-harmony f1afb5d8e0cd1d1c5412015b1a10e3ba3c553ae7
-platform/external/apache-http 6bc2bfedbf6f1f24ea1c420aacdbbbfbbae817b6
-platform/external/apache-xml ccc2296752f71b250bc8b5ea24eff53fb331743d
-platform/external/archive-patcher 1f771185267e54f8ff3c065d6953d358a51128ed
-platform/external/arm-neon-tests a0b9d7a1d9d042f0faaf4a855556e45af20b81bf
-platform/external/arm-optimized-routines 35edf4582e96d16113db352b74eebc5d4bfbe0f3
-platform/external/autotest 35fd72cbcd452b381711ed256eec54b013dc99e8
-platform/external/avb 4ee43b8ce34fc03e30f9f0f2d0e74ada2f8b3f34
-platform/external/bart c881adf3d899b14adcce9b7453921e0095671d67
-platform/external/bcc 89ce85a2002563bd4a5b1031e068cd8cf21026ba
-platform/external/boringssl 6e8c9598d925ab3001605150c2bc5edd6b135622
-platform/external/bouncycastle 6e7c76e5eb7589e7bbecd3ce3326611bf30328ad
-platform/external/brotli 40644ada0e4ef6922324fc368c3a1fa19e8d5ffc
-platform/external/bsdiff df9b6528ca94730baeb24c876d9b068b241ce6b1
-platform/external/bzip2 d3f226c5294865ab8c07f170067ffa48bb3413a9
-platform/external/caliper ca1021253184c55c90f5cbbea3fc8bc3f164c151
-platform/external/capstone 3d35b0acd9f749504547918019a5e61f31699473
-platform/external/catch2 d1d69deb3e85922ee26af62f1b374dbe41ad74f5
-platform/external/cblas de266f4cf4dcabee5b45f28fd0ed701f84726844
-platform/external/chromium-libpac 72cdaf370537142a90244f0baaf234a095f7dd22
-platform/external/chromium-trace 8b0d177e925a0e11afc956c6ec9cf971cf5994a5
-platform/external/chromium-webview 440e14d037667cea456d821e16aa69514cf75c95
-platform/external/clang 32290d3463d1ca9037fc8a1f3aa15129c46f3567
-platform/external/cldr e55918306dd739514d99c7ff50236cb59bd4de34
+platform/developers/samples/android f8e1b925991f097e4508060d94cb1a8cf5b83e30
+platform/development d882086d15ad313a77e760eb4714e685edd13056
+platform/external/ARMComputeLibrary 23a16533b968b01c0fab733dd13dc418bd8434ef
+platform/external/ImageMagick 2239c598d3d52551da1a4b760e887e0197cabd8a
+platform/external/Microsoft-GSL be41fa18df06c702cdaa173d1d5312f66ca0da7a
+platform/external/OpenCSD f5e655cc270ea1a836070d8e5e18cbc58c12b0f0
+platform/external/Reactive-Extensions/RxCpp 606ec2251c62fcb706d255c4401bd0a5de31c8e2
+platform/external/aac d91a410182afdd108821e40a083e40f4c528dac5
+platform/external/adeb 6165e791fe9066babd1a2a333ad6afac36a67ff6
+platform/external/adhd a6fd3da2a48682ac12d998213d652db2594c6465
+platform/external/adt-infra 4d637d3d91cefb11079d5c7bfc243830a14eb8a8
+platform/external/android-clat cc4432c350e744552b343cbb3fb5ddbedd9ab0dc
+platform/external/androidplot 38a0c55b36cd53f768b58f381e8aa556c1e663e0
+platform/external/ant-glob a7d4f07162e260f90b9525add818b3d496a9428e
+platform/external/antlr b9248b49377a6a9167eacbe68e2fcd3710a0c32c
+platform/external/apache-commons-bcel 0571aa8e3291944e1b3697f40f237a556f3c2f35
+platform/external/apache-commons-compress b5c92874f556f121834b67f521bf0430ee2e8134
+platform/external/apache-commons-math 452474d71096fa5d09aa6f5f01dd0220dbafd9ad
+platform/external/apache-harmony 434616ae8d157c688944e708a041d8b0ee8f0786
+platform/external/apache-http af398cf848ef524cd78d43c98d53e8afce6e22fd
+platform/external/apache-xml 43f4c8f5453fee2e79a90daf0b33c0268fccdf4b
+platform/external/archive-patcher e0d500039b9ee2c979134b8138b694597e888068
+platform/external/arm-neon-tests 20e7a91aa7d3050739f3a9f2bd74299c095da8bc
+platform/external/arm-optimized-routines c5ee22cab532fe461b427ac1c483ea0ec8b17207
+platform/external/autotest 89947a6de586e355173ef3041b331f24fba84bb5
+platform/external/avb 23a8ba6444a088034c89bc14b61f5a812c9d6b18
+platform/external/bcc c5b46d096fa6314b506445dbbc372139cc826919
+platform/external/blktrace 35c47c861c3cecdb4a90db6fdae426fc91550c60
+platform/external/boringssl 52be98f88a43c7213011e4c7e5c8359a1dff0753
+platform/external/bouncycastle 56c470d7e1e1eb5fa667e639cb50f6c9545817e6
+platform/external/brotli a6a3ee496f847993f00a0bad249ce9c01f5a7bb8
+platform/external/bsdiff 8ba2d1058e0d6d6020f65112ac5a5c3d0b5bb4b5
+platform/external/bzip2 15fc73bf1757db8249e1443294fc48d4eab477e4
+platform/external/caliper 60d50e0bde059a24e84a99bccc57e579bda58bbe
+platform/external/capstone 551895ca20eff53053ce67ca13868547f5859715
+platform/external/catch2 892460f4b5082e69e7137cc369e5ab3291e51074
+platform/external/cblas 8f0fb15f3bfd353faef3963eeeeac1033ba5d2d0
+platform/external/chromium-libpac 1e857fa957d097efc5a34a38064fcf4b7298ea6a
+platform/external/chromium-trace efec282241adaaf52f1cd456771facd6d4616af1
+platform/external/chromium-webview 2a45723ee7f2725c795116ce7d86b937e306a5c3
+platform/external/clang 6bba0494af68cce862946fbbd834b4c824cc9ef6
+platform/external/cldr 7105dcf672668d86e3f937a909025c5fab6ed44b
 platform/external/cmockery 9199c7bfafefea32d1884182fa655b6e4578c1c4
-platform/external/cn-cbor 7fe9f01990a97be4df5e46d2decd894c06678072
-platform/external/compiler-rt 112e3846757fdd107f63101e6bd7e201ff3c6820
-platform/external/conscrypt d205a6c2af5717ccd1b2bb1bb6f57c7f381d48c0
-platform/external/crcalc 9e6e7043bfcab14fee5ff43cecbf043fc79a11b8
-platform/external/cros/system_api 9eaf8f485b7af9070cae71d1f6295b49b341fc46
-platform/external/curl e64a242cb0773b180a0d3ae24ec2fc39cfdf7268
-platform/external/dagger2 e163fb460c9568db361e8dba6ce724fefeda99c9
-platform/external/deqp 876c479eb58a96c7d655e42d8afd2aeacf751da2
-platform/external/desugar 1b8781e72f7e038dcfaac925588d90c4f29ee28d
-platform/external/devlib 4b549587bd8eaa6e42f99e2cbf6d8b05ef0f7935
-platform/external/dexmaker a45c093416b99a24fce6aae4d0e1edeeeee1580d
-platform/external/dlmalloc 6661f3ca66b55d8f5a57b96fec97efaf8f3897a5
-platform/external/dng_sdk 33c601f0f325f31b89d106e5ebee37a68b2788f2
-platform/external/dnsmasq 926a9ca483f498bba024356f1dba1daedb8ba7de
-platform/external/doclava 868494cd346b2ec7ad094cef13a18b1169861228
-platform/external/dokka f31077e09de860d88c2fa41965ba1f013c1161df
-platform/external/drm_hwcomposer 6caaa8724f6d53498c57159e67af94432381ea28
+platform/external/cn-cbor d35a6c11143f473888afdbb1d518426d7367b0bd
+platform/external/compiler-rt 98f064be0742575e2c73f528cae3ec46c3484bad
+platform/external/conscrypt b342558fa65e0a8bd88789722f77e5fb6c0b3d26
+platform/external/cpu_features e39557cb8d029feed28cc83ef15a384eefb19875
+platform/external/crcalc ffb3fa9a866d53a57f04fb3fa45232a895676367
+platform/external/cros/system_api 488b3566637fe87d92ea5636cb82a899f5d8e895
+platform/external/crosvm 636788cfcc6b49d460cb7b37b854e4ae7e89d01b
+platform/external/curl cbb37608a2f6f8106cd032c1ab1129995698d62e
+platform/external/dagger2 7c315c0e9f26f15185495b7ab7783d4950dfa000
+platform/external/deqp 6af382e1fb4524f247117ca32a0dd8ba68702071
+platform/external/desugar 881ef14388b2ceb99f53fa9c382a71988835c499
+platform/external/dexmaker ed404cbe0c48bce745255aecb59afba33e04e857
+platform/external/dlmalloc 93e4923e04cbc34bbf5307e9b69792c81bb6baa4
+platform/external/dng_sdk 3c92feffad0851b828b2ad698ebfdd81bf4eb98d
+platform/external/dnsmasq 6b2b6d59af27e88be094d04dd0fd3521020dc63d
+platform/external/doclava 836715caaf48012354638cbf5007cdc4c6b9771f
+platform/external/dokka 71f2fab75c08b8f0857b03257a56167d7c93eeb9
+platform/external/drm_hwcomposer 31828c9e57ccac01dd6258da279dfc407a1ee18f
 platform/external/droiddriver ef618d981947f6d8242755516269a0026c07126c
-platform/external/drrickorang 26a4ca77474f7c31ce16a606a3ee8bead0ca235b
-platform/external/dtc b9548b70742ac3557a5dd3f71a18da5650c5dbed
-platform/external/e2fsprogs 73ee4372dfa51a1a882a195ee48abdee4c00fbc6
-platform/external/easymock 72e4600733b68fdd321b68d3fb4d246b97b5f9ee
-platform/external/eigen 42a8b92ebacba59d0032b0e39bed8c6220bed7de
-platform/external/elfutils 046365e0b7b65afa66fb114c6b50845ab2928d9a
-platform/external/emma a3fc9da4663f0ee58b9b545841bfe10f84e7022f
-platform/external/epid-sdk a610fd9ba05d02fe8d5ad24495b8edf5e45b3000
-platform/external/error_prone 457da02d2352b40f168431191ee5ac8cf6d66533
-platform/external/expat 9dbf600223aa6e35535af2eee64f0bdc8169cc21
-platform/external/f2fs-tools 64279e4131f66dd44e4816914ad3e95d8f166d07
-platform/external/fdlibm 6bf9da63b74020968b95f3ad77758088027174c2
-platform/external/fec 85e4f9b5d9aa18722ec4a073f844a5abeb6c3d1e
-platform/external/flac 63fa08c60538d9f96c606c9c8dd1981764445074
-platform/external/flatbuffers f5272f22afe09c1fc23afbc05035f4f562eae57a
-platform/external/fonttools 69c9acab6a81c7bce36329972332cdbd0d11f449
-platform/external/freetype 98a65e49f3c56b2d3ba34b43ad5815ec0bf5e319
-platform/external/fsck_msdos 0e6d79856a4c73525b3f42733645a3efb1803150
-platform/external/fsverity-utils 1769fe3896c4aa523f3feaa2ff494cc1a83bdc4d
-platform/external/gemmlowp 42dfa434ecbfa67624298ee90edd82569112cbd9
-platform/external/gflags c5a33aeb934d9f5583a2938fbcce14b5a6aee7c6
-platform/external/giflib e784ad659f79e15cac1efb518b9b044f85821ce3
-platform/external/glide 371485f971145ad2850b08637e3a7d76d414c04f
-platform/external/golang-protobuf ad5c1b9ef69897a3ce3d9239e2e0c0ed22ac5fcd
-platform/external/google-benchmark bfefb418aa215b976a523f5317dbdb919d8c0290
-platform/external/google-breakpad 334a5a386cbb17c09f480ca367c90ba8551a8bb8
-platform/external/google-fonts/carrois-gothic-sc 0062a10458d4c357f3082d66bcb129d11913aaae
-platform/external/google-fonts/coming-soon 2c5cb418c690815545bbb0316eae5fd33b9fc859
-platform/external/google-fonts/cutive-mono bce2136662854076023066602526ba299e6556b2
-platform/external/google-fonts/dancing-script 7b6623bd54cee3e48ae8a4f477f616366643cc78
-platform/external/google-fruit b4524887e735fafa1a7e09e4bfdb506f84e24baa
+platform/external/drrickorang e059743678c666f957f3d4b84c44ec8e71ba55cd
+platform/external/dtc e96f80e509004c0c8a8cc90404d7e551b6463d1e
+platform/external/e2fsprogs 7216e9a425cfe9600945a164fe7b3c0f2e251ffd
+platform/external/easymock aa0cceff39a59cdbba7f244e305dc3592b8c21de
+platform/external/eigen 906b5551ea36a0a2ba5fb50db416d78fd047703e
+platform/external/elfutils b0fd3570c06ea17c920ebd1022846f9860e14fa6
+platform/external/emma 9029ef6807ec8e85037628709e6be54f170b9bf8
+platform/external/epid-sdk 4fe34e754efe968469e9c058be099173614809a8
+platform/external/error_prone a6c015cd17dbd2307cb74aae09599537aa16bab5
+platform/external/expat 3cc591f236295416dfe6604f5c83135f58ee959b
+platform/external/f2fs-tools 42df8eb21c5358b4410c6c2006c6718e0523a903
+platform/external/fdlibm 7f2972cc0499377d9ec88114b06c8b3d9fa0a1b4
+platform/external/fec 1d31c953fdab717169301f5251c4e7c1d3534fa5
+platform/external/flac be88b61c3cc0e9f6306a95b4b90396a3b0e0c3f0
+platform/external/flatbuffers 4ee4af5b0dd3390e22557c7ef850db85aa8e664f
+platform/external/fmtlib 17b3fc8df3a7c9dc7ebb240d9a9698153b8429cb
+platform/external/fonttools 0ac0cff8e36051daa5001f7e91aeaf758c0c840e
+platform/external/freetype 0b6caa8fc72be8fca8e8321ce4e17db6eeaa4ea0
+platform/external/fsck_msdos fa2b1644fd2453567dcf2a603beb96552e557b37
+platform/external/fsverity-utils 2bbb1c2f47c1940250df1e81f64428e2056f924a
+platform/external/gemmlowp 708216e8e9f12d184d3192239838cd08f977d7d7
+platform/external/gflags ce02cd3c9c152e6850384e5df425cf9dda078c37
+platform/external/giflib 78c1c6c238076140ec9e55ef99999a2fb4a52f5f
+platform/external/glide 70520d290e09b0c09ad7cc34f3b4f58505a767ed
+platform/external/golang-protobuf 03c544783879a17dc4b484dc2977bb9c717e2990
+platform/external/google-benchmark ce8e17bd562500bc32d62f8418560f5485270703
+platform/external/google-breakpad cbbaf3bb68fa3e404fb8911a0d45f9865b03e05a
+platform/external/google-fonts/carrois-gothic-sc 7eb073e6ea77451a4c534cb26d8e105c56344964
+platform/external/google-fonts/coming-soon db485f8e4312b130cd8e5fe7d9a528c5450e0968
+platform/external/google-fonts/cutive-mono 5ee936c29d6ab6e041f8bfc96104f29fabbe54fa
+platform/external/google-fonts/dancing-script 73e75e2d9c79c0ca00bcafdc330fe9ea9a735fce
+platform/external/google-fruit 703fda01e5186db4ce0539191d925057b56be724
 platform/external/google-styleguide 749f7ae008c0d2dd9767fdfe202e6873e864a956
-platform/external/googletest 511a7d7cc060fba303f377d7100ec8f5cbe817c8
-platform/external/gptfdisk 646af625ced09e5d81e07fe8c02c32017e3cbc07
-platform/external/grpc-grpc fca6ce30b8dfa92cfd39302f11b4c2b373ebce91
-platform/external/grpc-grpc-java 4d84fe10a43381259238fa11d5fa04d35647e5e7
-platform/external/guava 9e71488ac9dd5e54cd6a8cf1c4ea62174c3bfcaf
-platform/external/guice 657e75933ff3c5def222d732b233409c2c0efeae
-platform/external/hamcrest 99a5e3baf7dc84db89d4c41ede8ec9d5d4b06223
-platform/external/harfbuzz_ng 04e2a2995ed343fd6c291602dfc685b5326b795b
-platform/external/honggfuzz fd841908724507bae9bd12e94dc91a26c61dceb0
-platform/external/hyphenation-patterns bdc0be413faf5333f3cacbf1fc5c1d9556647f6f
-platform/external/icu 9df558b1654850407b0ef78bbfbc958f9ab7b7ff
-platform/external/ims 103cd11ce00770da1fd2e53578aa917e5389d9d8
-platform/external/iproute2 d81c8f26048597532bdfe6625f7d29a07b6b8af0
-platform/external/ipsec-tools d816e00057aa4ab938e4427ac47ec370ac772cd0
-platform/external/iptables 892176652576063b69509de66c578f839ef5f17f
-platform/external/iputils 92f5573dbfd1e5340f2a107cf0f9b59062f7dc95
-platform/external/iw 79333d44a9114d41b52e5b741ac3191d9b90d68a
-platform/external/jacoco bd1bc6aef13385b76e74cb408e8f261370529f9a
-platform/external/jarjar 56bc6a456edb7f27104dc9e6feabb6f32716601f
-platform/external/javaparser dce775396b7515e476a2c36dd8a37f580f68ce2c
-platform/external/javasqlite 61eea37fdcbaa1fc7b8bbb1703180407a71c5e66
-platform/external/jcommander 09ddacfea3d462b19c1e7eac8240ee64a1c0822b
-platform/external/jdiff 5db7586e8dbb885090389f362e9d8213e6824fb2
-platform/external/jemalloc bb10eec3d268fa2254afbda4624d8d7859048acf
-platform/external/jemalloc_new 759026fed99941195d71ea827045bad3aec25d2b
-platform/external/jline 486ecfedc8a054176ffc95db49d59b01115da202
-platform/external/jmdns 0c71647deb7f7835c473fd3dfb45943083e47794
-platform/external/jsilver 148b445673232504e8e8bcdf9087ac2ccbd0089f
-platform/external/jsmn ab3f53ade39a753e411ce37febdd1bc770cbd69d
-platform/external/jsoncpp 4169f6396fbb2ae1e1c9f5c9c6ab801d614e3692
-platform/external/jsr305 e62928e355b62c41d11c4d3dafac4a485920a1fa
-platform/external/jsr330 c749ade438c346a7a8be370991b87cd7c9c7213b
-platform/external/junit c1ef60500312126bac7e1a6c749ee2125bc7af9c
-platform/external/junit-params d4c2ffb2d96d1d9549c25de1257c35cb3e05fd77
-platform/external/kernel-headers f53102e5156c0bd551a5f46aae62edff3d8436ba
-platform/external/kmod 3548f5a47e20a9cb60b1b7e7ebd3880dd190088f
-platform/external/kotlinc 590f0ad3eed87ef30010da42bd5eed7be1703d6e
-platform/external/ksoap2 5d56aac23a27c86beeb1f34e8a4eca9ebe321c2c
-platform/external/libavc 9908df5214c1360ffb2bc1aad4318147bba93eda
-platform/external/libbackup 7b45ebf39d87509f9ed31d4d5fd586372dcd131c
-platform/external/libbrillo f6035ae5e8d20900e7903efa2807ce9869e2a057
-platform/external/libcap ffda9d2ca383b418a78cd01f9f643d14b3c915e6
-platform/external/libcap-ng 795ce1d85d55a84e73a612bc1c2a6e48e9538300
-platform/external/libchrome 9525530ea4ee4d70b55b5b376ad96ecdd587bd39
-platform/external/libcups a9d627d142364eb209eb806e919e13bb59a66afb
-platform/external/libcxx ddc3fb3dcf3dc12e0b24078dc7e9c0550112bdf6
-platform/external/libcxxabi e839674b344b94a5b8da4f4e5d88060e0e57a466
-platform/external/libdaemon 2be91dee92b694a04707029ea75dffd1dc5f6659
-platform/external/libdivsufsort 931bd18af75e23ec1048bf5235dc29e53294fb45
-platform/external/libdrm 9dbd75059d77338ab34793a656d56e6baeedf825
-platform/external/libedit 67e14dfc833aafa400a3aad8cb329cbaec503445
-platform/external/libese 1bcb0ea0e08391a8ad6efd1d680162b73d54b6b7
-platform/external/libevent 8d3f9ca461eb26cbdacdaa94840cb00a00f0e2bd
-platform/external/libexif 1614773045029735bdbb7e4c558cd9a3750f0ef9
-platform/external/libffi c5db7f8f228262f8acf483f61c9dc6ec32b2c8c5
-platform/external/libgsm c7af9eaf53d251590ba05502cf2208c82d957810
-platform/external/libhevc a3f4272f8a52758cf7e1158017ed09af6fe66dea
-platform/external/libjpeg-turbo 0aa895e6dfc491ca26acb46192d221e6b6675403
-platform/external/libkmsxx c39eaab1655aa676104fd105cf9f5243c99e6573
-platform/external/libldac 1118a8c6e3e81dddbacf7e8a8086b6893e4980c3
-platform/external/libmicrohttpd a822da88606192bc3bc7b91537e2bd1a18719037
-platform/external/libmpeg2 78f645adf38c86a6741c95bdf090487ba1c58ab2
-platform/external/libmtp 9f6b4eb0b8f04d43e368b39eb8a746d21392b782
-platform/external/libnetfilter_conntrack baea0ca8cd5ba32eb01032b7486855430f75e15d
-platform/external/libnfnetlink 6ef7fd10f6ce9415fadbe3a31f6752a08efcff09
-platform/external/libnl 99d9f8b3205cfe524c88dcc89de6a939f64d5446
-platform/external/libogg c1b7d64555d060fe83bbcd1b10902ae597326ac7
-platform/external/libopus 6a6a485651f54adc81c80c0960739f4cc8dd736e
-platform/external/libpcap 58fd79c867dbf69ec812a5ac140271437a036028
-platform/external/libphonenumber cb92ecc12809cdb79cb45a6660eef3b595e3753e
-platform/external/libpng 2f4a5d7c42cf1f3220fc652c83343ad9c256444f
-platform/external/libprotobuf-mutator 66e4e1c3230e95f9951a23134365ded8573db5bd
-platform/external/libtextclassifier 3b7fdbe6c3330e107e7053378ae48429fe66f47d
-platform/external/libunwind 8ba86320a71bcdc7b411070c0c0f101cf2131cf2
-platform/external/libunwind_llvm 6611fedd1a568d258ee28b715d2b4f46854f037c
-platform/external/libusb 6800ca9cdc24f07bffb4673da39fb0d477c9d1da
-platform/external/libusb-compat 759481ae400d02fe99488dcdcd653b4f8139a39c
-platform/external/libutf 7d295310673278d6c413be25500fbdeb715396f4
-platform/external/libvpx 48cc3ac04e11995a3d4c730ee1c30d6b9b85af55
-platform/external/libvterm fca7e21b597c2f3365c19b176b5605273363129c
-platform/external/libxaac 52167e2df66d5ba6eaf03c3184738575acf03de8
-platform/external/libxcam 6dd8140c703f25164bd50e34a9976ac58a2b7bed
-platform/external/libxkbcommon 76969e5154c2558b05b228fcb539ca18bcb19f8e
-platform/external/libxml2 de852f7593e33e3ca7bd3dfe74e59548c02c24f9
-platform/external/libyuv a0fcb3087c07da29b7cd001d794b62e9c2898db0
-platform/external/linux-kselftest 0ad9c2125dfef4cda13e73ee3c929f2653ebb3d5
-platform/external/lisa a249bdb47e674da8ba6ad5dae4008cb299c68c6f
-platform/external/llvm 051915de205532bf2fea744406427b23be180604
-platform/external/lmfit c9fcaeff379da5107d31b22229dae111ac5cd66d
-platform/external/ltp 46f9a2fd9b5e5018c386f5b06304d35ec42da7dd
-platform/external/lz4 8bd741837f08278acf1ef290272475982c15414d
-platform/external/lzma 2eee35ce752b830347d42f1dfff17173f9063375
-platform/external/markdown 06a8f8b914d477183f68b84424bce8ff4dae7e84
-platform/external/mdnsresponder 58fb6e3d04caae1b10ebd7a892f65f943602b4a1
-platform/external/mesa3d 2a94bb000538d2edcd32438d9749cc617182a947
-platform/external/minigbm 386c14aaebff6e0e6fce257d8d6b430433e25566
-platform/external/minijail c3e17727c6ac127b0033ef011cb07c08385f448f
-platform/external/mksh 7c1686fd08bdca5e154a5caf9df2f04fcc43484c
-platform/external/mmc-utils ecb66312dd2b0d82d462c14af4acef00d93f2375
-platform/external/mockftpserver 0b86de2fb01630736138aed533cf821c98ec38e6
-platform/external/mockito 4275f54d9964486d85dd9cfcab5a1442b067547f
-platform/external/mockwebserver ecf79042619f970581304ee250de87427e34a599
-platform/external/modp_b64 df5b9e2d80b310a9d084ba20929a1848297f63f4
-platform/external/mp4parser 88bd0c6cfa7fcfbbebcc15c2c565f714cb36b065
-platform/external/mtpd 4b307d4c447e8052c3a5aeb1def6e6ecbfd1e2d4
-platform/external/nanohttpd c6783c32331b3fe78ffd5077e7f180995d0e268e
-platform/external/nanopb-c c8cd40fafa296b17f5d34fb290bdaf9c69274677
-platform/external/naver-fonts 91e6e9f94d1d769a8f742649674149ba98ce7d45
-platform/external/neven ebd7fbf8d78368adc0a97e8cee7add1b8ccb0089
-platform/external/newfs_msdos 0ff97691c937dfa093f3e685ad23cad3c7e03dd1
-platform/external/nfacct 8000958af8b60ed392b4f55003ba2a9b27e69afb
-platform/external/nist-pkits 81e663ed489983f4fbf69ec0986182ccb24425b8
-platform/external/nist-sip d642bf4c36af2e6ef12d7732aa4cbff6c7d4bbb7
-platform/external/nos/host/android 0e851a4561e70df0344a698858c57b7cdaf4229f
-platform/external/nos/host/generic 49936fa5d4302c23ffaa5d9ee66ee71a1dc2fb86
-platform/external/nos/test/system-test-harness 0fbb25006e1c4b31918af8eeb712f7bce7cc7391
-platform/external/noto-fonts 400654c9b55c1e08195464dc2c2bce7d1576b8c8
-platform/external/oauth 49f3624a6d3307b640a012f15b94d04174473501
-platform/external/objenesis aba884e011bedf4a639cb54574adfec831799728
-platform/external/oj-libjdwp cb8790eaad40cf3a01018e9e69bebd8f49c868fa
-platform/external/okhttp 47167645e9a10c9c816594196cd16cc9fee63cbf
-platform/external/one-true-awk ff0b4402c160545951cd58e150e25447b975ab47
-platform/external/opencensus-java dd3cabeacc5c8079b0d8674230819f3c54dca590
-platform/external/owasp/sanitizer bbfb25464ff30c5a62dce351d719a8c533afb2a3
-platform/external/parameter-framework b802d2f4644ec85a68c903267ccee5bef3d82408
-platform/external/pcre 289c6169f5307a2063669129772d7fed0e5b0f8b
-platform/external/pdfium 12f666012b784f95b5edb51016193497dd937a9d
-platform/external/perf_data_converter 75b02aca5be735adcce39275e7a6c51d24ff34c1
-platform/external/perfetto 4447823aa71d4f539cedbadafefef3924b65e32b
-platform/external/piex 1ef9d0c0f4bfbe0aa14b42e7a2d62eefb82fa124
-platform/external/ply 31eacf2e1b82db1af8ba174853650ffa2c537c77
-platform/external/ppp ea404bace2399139dc0dd234ea85a08e44bf4c91
-platform/external/proguard dc8cf27bfbb01669a11a02fc2cdced28dd3e0e17
-platform/external/protobuf 0dac9ed696ff64f707c59abf77cafbe4de9c539a
-platform/external/protobuf-javalite 61f57327388b1c133011da01545f0a24e09fddf0
-platform/external/puffin 6d30f049ed4cfc5d4bfa4fdbf6529c9e3522e951
-platform/external/python/Pillow d9c0fcc955e4fe0662cd0580a412a20cb328f039
-platform/external/python/apitools 9450d7e7bde0eecbe401d3c0c9a60750f9cc928d
-platform/external/python/appdirs 0d9b51147cd55a9ee45382c534bcfa4df4a2e3fa
-platform/external/python/atomicwrites e002d4e443fd4a9e9046873303f0cfc702726537
-platform/external/python/attrs 5159336e542ee78cae6ace5b7e954ca8521573e6
-platform/external/python/cachetools ee4588a2a8743a550de2a7e18d306d5f6a436702
-platform/external/python/cpython2 892b1a8e115520781e9a83e5dce9760fdcc185d2
-platform/external/python/cpython3 c9de24c3d11c8eef629e8998dbf71d8612209bfb
-platform/external/python/dateutil c0ec852fca382f255d75271f8bb0244fe21956f9
-platform/external/python/dill 01988c5fa063836e457bdb7134d4d300d1276e5e
-platform/external/python/enum 6706fcd5d4054a9dcbd517142f2be8c9498fcecc
-platform/external/python/enum34 ed56821ca06c8ba80bc083069c9f5672cf834e2a
-platform/external/python/funcsigs 7fe2218d0130e27ac1dea2da3748d121f7bba435
-platform/external/python/future fa8e703fd259f8056cb817219041eb0e20c00ada
-platform/external/python/futures 002b94693295349f2fcd2cf5389d0293e5e30e9d
-platform/external/python/gapic-google-cloud-pubsub-v1 44cde1e4892ce518b1927ab3f8f45a22f0f67a1d
-platform/external/python/google-api-python-client 5906871076e78a0bd746022694e9a0905d65e487
-platform/external/python/google-auth 51bbd38e9129785729a71abea8ae0bae1ac9784c
-platform/external/python/google-auth-httplib2 c4201f1bd596e5b17b7e461af2dd8b0d676834a6
-platform/external/python/google-cloud-core 1b76945730adf9762a680dde8facca6acd864df0
-platform/external/python/google-cloud-pubsub 0f0dec2c3076169da00aadb6de8f621da301b908
-platform/external/python/google-gax 70dddff9a898e0ea662d27451f13f4262c43b1ef
-platform/external/python/googleapis 67d384ef2d9bad424bce05c79899a1c6e6baee25
-platform/external/python/grpc-google-iam-v1 6ce59f644bd5e99279b020b6fa9b8851fccb7c50
-platform/external/python/grpcio c059a54af916df11ead84a19bb4e2faca19e3682
-platform/external/python/httplib2 4cb66851a643549e9b4908e4b931728c8e6c8d04
-platform/external/python/matplotlib bbaf4f40479b90f583faf080bb472499439ee2fa
-platform/external/python/mock b44695a467445d1c4c15c810f652db62c05b873c
-platform/external/python/more-itertools 4e4e2532f22d73b2cba084e3394e4e5481d7131d
-platform/external/python/numpy b12e87119e636214f5d41688ec4ea9ba4b4e58b5
-platform/external/python/oauth2client 937bfe8961ef8b69b0f3532b5d23a48278fc6277
-platform/external/python/olefile 1221d9b12619499cd798e73598a074b8cb6d7b31
-platform/external/python/packaging 28b23ad183cfe53c9f848e1cd55595dcd11b22f8
-platform/external/python/parse aebfe77d79bd5f84e82bbb23bc3f0e7ce817064e
-platform/external/python/pluggy 4a5aa2c3218e1d54b9c77e7b027bc1c066648858
-platform/external/python/ply 2b3c386a04f92d292ea289ea10d6508a3bae2c2d
-platform/external/python/proto-google-cloud-pubsub-v1 ea95753aa8bc0d8d7766a36917b488b331dbabee
-platform/external/python/protobuf 6e9cbd59578771e8005e4d3ca73c167521f4e4d5
-platform/external/python/py 36780d78e0e79380dc605b0c70f13f6ca4869cda
-platform/external/python/pyasn1 f269ffa895ee80300eb70cdd2aacf95a183313c3
-platform/external/python/pyasn1-modules 11370fdfe2f549f54c2bfdb002ace8ccac7a0d2d
-platform/external/python/pyparsing 349ddcef3f7641faf4d11327c959da6568b84635
-platform/external/python/pytest 84089c930427bb933747cf5e78fb83c5be5731f2
-platform/external/python/requests f51a28912b8571f0276a633a85578a8ded94d37c
-platform/external/python/rsa 0b85440d31715ee76a7a78716c3f630f2e5769e6
-platform/external/python/scipy 626da5975f8d3d1ee9de56180b57b6dee8ede15d
-platform/external/python/setuptools 21d497cb588c40b2a891d9a862f56e108b427e4c
-platform/external/python/six 8cf04836b3cfa9194ca6e33ce19800b86f4e405f
-platform/external/python/uritemplates 87f7b2447ed02e26bfe1fc3db379d8e1ff166572
-platform/external/rappor ff12d06e4dadf02873ec950e4037cbee2bb53bbc
-platform/external/replicaisland e5ce7ade9b6ed69b9fe67361c04d4072d613aafe
-platform/external/rmi4utils b45b36d6c3e9f74780741e748dbc502c6ca77b3f
-platform/external/robolectric ea2fd1fde2131c147a66507cbe15d5528a05c122
-platform/external/robolectric-shadows 65847e6eda4d932209ed0c0126ad481aedfa721b
-platform/external/roboto-fonts 114e3e918b0451dbdf89e8fae2e4a7c176642576
-platform/external/rootdev 0be0d1548f5857ad6ab72afb88394bd70bf1c97b
-platform/external/scapy 2244bd112ca693e8165a0215118603675b69690c
-platform/external/scrypt e35afdb1421a9834b4c7a9b5c55ffc1d0c2b4588
-platform/external/seccomp-tests ac56b768c6ca2fd2548cb26d61111e76beb0ff81
-platform/external/selinux b744f16fd2626c87778927566297be51e6a3b329
-platform/external/sfntly f4d5f4c3cb74b04a5da30b5e074c136c73979d0b
-platform/external/shaderc/spirv-headers c45eff4a3dc7fe9e0717353a64d1f7b448a15f5d
-platform/external/shflags b0afbdb369abc2bff68f0c3a6477f34e0cfc92d8
-platform/external/skia dc2184d089357341bade67b5ffdb28a244e11e4a
-platform/external/skqp 135cc4e65c00f9d3c85cc58608336107b9f8f4b8
-platform/external/sl4a 8c4354ccf8d38fa0e57ddda72955697efed5fe74
-platform/external/slf4j af8a97c80354f818ad5f86058988dbe6849fb244
-platform/external/smali 8253611aa11b16181ca9c28929760fc80845649f
-platform/external/snakeyaml 2539dbe2d7c3b5b37f62c4e44f9e248cef45886b
-platform/external/sonic d9a1860a3776ea305dd6f5fce1be9a13d27f21e0
-platform/external/sonivox 9b0f31a578a9cd7fdea862162928684fd84544bb
-platform/external/speex a28a1bb442bc3fccbdc94ce2b826f7e11e87eed2
-platform/external/spirv-llvm f2d8a8efb5e033a00d4e4dd8cc587b7d5001df7c
-platform/external/sqlite 8449ca3050fa1072ac4fb56c885fb0b93219a2ea
-platform/external/squashfs-tools cca6b086e8ec25caf14b7f8b867f54bef437f8be
-platform/external/strace 37c5c783b1103f213e98406255c34ea914d91b67
-platform/external/stressapptest 43255662e6ef02fb1de06e64cf740abfb8b06630
-platform/external/subsampling-scale-image-view 5ffef6ff20822be19bcc9cfac35b0c6563331cd6
-platform/external/swiftshader 91c6078e665d393cf07fdd861af2d30c6d1a2800
-platform/external/syslinux 64c351c59ba88d0b452b62c31a70a86516a72ea9
-platform/external/syzkaller 93cb3a5941261937527e41b9803d4fd781436a59
-platform/external/tagsoup 0b0a7dc2ad85513d14a82ae6c0f7a433cd7e60ee
-platform/external/tcpdump 50ea5d32cd987ffa1f95c99ca39424852247355a
-platform/external/tensorflow 438240aa676bd632013f9aaad97d384913bf27d9
-platform/external/testng c3d177209a43ab80b506bf2d8567567ad699ecb8
-platform/external/tinyalsa f45936847abdf3ed65a77ac097bc53f7f07d97c3
-platform/external/tinycompress 4fddf72944e4ba4b68ed681825771ccaf06b24ea
-platform/external/tinyxml 040807802b79749d6375e3c1c1857c952f14209e
-platform/external/tinyxml2 9a086af735f4d35ab79bdaf52f2115705bd8f66d
-platform/external/toolchain-utils b06102ab29b5b9e662f4dbcec99b3186d4552f54
-platform/external/toybox 5a3e83c86386802b2000d9be07c72efa1b2de632
-platform/external/trappy d9f624f5147fa556eef4e472cbd3355c9f178126
-platform/external/tremolo c75c06c0d4fbf907c765200b6f0476792de4daa1
-platform/external/turbine 18281a601c7e534c4684a5dbf7e6c6ba799d1177
-platform/external/u-boot e1aa1967e2e8852a2338034e29af88436f61ba99
-platform/external/unicode 99cf0054e553e72ef1ac618586dcbb2212a8904c
-platform/external/universal-tween-engine 011a03a518f18442c6deeb030b6b6bd5d33139f6
-platform/external/v4l2_codec2 c3865be4077e8dcbf9ca3efb160c408dc3bf493b
-platform/external/v8 f4d931ce6550eaf3929edc281f132bf807b739c2
-platform/external/vboot_reference 416897179464dbf8fd5f8c3a59cc979805034d31
-platform/external/virglrenderer 26f468c0eae70095f7c45fb2d91b002346f56ca7
-platform/external/vixl f95bed507f0fdbbbbc7774dcd77e8894bdce2b35
-platform/external/vogar df56643f3bdb4675e65a1263a895ade09dbd5576
-platform/external/volley e636520a251b37c313731666bcff1f39ecf41b35
-platform/external/vulkan-headers dd712447ecf6e2ed50a8cca54fc06ea6095133f5
-platform/external/vulkan-validation-layers 980f75e3eecbbd2db7d67961af5a27a289e69d29
-platform/external/walt 089435131f8ab3d8174f9c456fe3f33ee8bd5a6b
-platform/external/wayland 35f3525e36e721ba467921d58897f96f886ede2c
-platform/external/wayland-protocols ceaa3109e6e12af7839596fc1e7f7b12d8c0671b
-platform/external/webp fed1aac803200ba420b3a182736c7b8de773d0d1
-platform/external/webrtc 92197c43df19f9afb8a090f0c54be3c75f638e90
-platform/external/webview_support_interfaces 5f84f9fb8f6dd4ad71fae22a12d1a8a21eaabd42
-platform/external/wpa_supplicant_8 dda66abd971cbc46d8202bae7904a1c86e7652f8
-platform/external/wycheproof b3ac8bf78316dd660d2a9899a5636e99749799ba
-platform/external/x264 56089b6cfec1a8ce96db7f4bf5aa0a9ca971b6f3
-platform/external/xmp_toolkit 42ea4dc6d1fc2206a7778029070ed9213e3b0fbf
-platform/external/xz-embedded 19d3ceb83bbebc932d124cd2ae3da2b9a866c3c1
-platform/external/yapf 9efceab84d9f234148c4f2206fafb00a94b7c35e
-platform/external/zlib ca1678799a04b3832c04f96b9930f5a00c92cfe3
-platform/external/zopfli ae7a7d47375836ccc3b442bea7f30b31e7853d43
-platform/external/zxing bcf363796549dc11dc9c331fcb7c48e48e86f7ce
-platform/frameworks/av 1ce37f1de3f7185ccffd4d9145b036941a582fe4
-platform/frameworks/base 94becc7b4f3a7dfcb810899a00c93f25c2c482fb
-platform/frameworks/compile/libbcc c879fc728b1a653b6dfffa33f8d575b42e194017
-platform/frameworks/compile/mclinker 9e649433ae7a22d443fb9c24600e4b2f609df8f7
-platform/frameworks/compile/slang 2f4af84489c80e28fbb6b28a75dbf6726f97808f
-platform/frameworks/data-binding 55c07c2dbc18caf9bd4dc041b25d3ab628c6f168
-platform/frameworks/ex d264fd171aeef0370f3ea9ed6fba701ad5efe999
-platform/frameworks/hardware/interfaces 393c85614176bc771469c55260143e62578b5eba
-platform/frameworks/layoutlib a796f29166c67054c216e83d536665b564e887d4
-platform/frameworks/minikin a243b36b9404616563521ea524a1c8f20eceaf3a
-platform/frameworks/ml 6a79c3b83df398b275a04c0d023e0d173bb3bb1a
-platform/frameworks/multidex 44d3900a5d8fd343e1041ae61481534353f56316
-platform/frameworks/native 18469210f68168e2f018cb7a94fe761da65d305b
-platform/frameworks/opt/bitmap e79ad82087133b2dda6747a70d88d307232b79c2
-platform/frameworks/opt/calendar 72af45fd2b6a6fd0f14b25fdb4b98b435a0c24e3
-platform/frameworks/opt/car/services 322dcd5a80d6d0ee82447e60af8049c8a9de7e09
-platform/frameworks/opt/car/setupwizard a876b2132171b1fcc4e45032e78a68f2ae329759
-platform/frameworks/opt/chips 57e47c5d7d123729dd81b038c857afb6bb9a5721
-platform/frameworks/opt/colorpicker e7de9c54d16aa90b210294c3c5ec20211d01f3a3
-platform/frameworks/opt/datetimepicker d74021df6b00ac88c091a26d71e7b39c01a7d44d
-platform/frameworks/opt/gamesdk 5930505c91be4ec18ed3d3fc4602533b1cffe15d
-platform/frameworks/opt/inputmethodcommon b651a1c9a39342ca3810ff5575c2471714cc176c
-platform/frameworks/opt/net/ethernet 8af1c3493fa8a855813a538135e274c97aa0a99b
-platform/frameworks/opt/net/ims 043ccdc179ea7513448e48280251fa4a2b9ec3ce
-platform/frameworks/opt/net/lowpan dcec4f82cfff4fa5d3846737916ac665a0382d3c
-platform/frameworks/opt/net/voip 40cad85af7ca9d2c156d30447dfdce23c414340b
-platform/frameworks/opt/net/wifi f9df0133c061810f78b43d6a4923be8be25282e6
-platform/frameworks/opt/photoviewer 6bbf601c42b650dfdec32a6049a1c264b8bfefa7
-platform/frameworks/opt/setupwizard 0bfed820908c7a1e7248b4392916ee8bf89b2c4e
-platform/frameworks/opt/telephony 62932ba3d2300064789070a944aa02d33dfc3909
-platform/frameworks/opt/timezonepicker 72e62a14985da480f5f6f28f3d22a123b61de3b3
-platform/frameworks/opt/vcard 797c23cd652a880ef8d901a5ff6d4384fb1a7502
-platform/frameworks/rs f646481822caf9a1e9c744a8bb76820adc32ae72
-platform/frameworks/support 48beb83b59b0062adb88694e875b3e4ac8a48757
-platform/frameworks/wilhelm 221fe916fe9a23a6ec0fbd662c8c1ab3c27f73f9
-platform/hardware/akm 6eadeabb4931321dcf046019d71b1194e8c932ea
-platform/hardware/broadcom/libbt 566c7ceefad5552a843dd66f9c320d473e725e39
-platform/hardware/broadcom/wlan ddba384eca13906662b88f431e161f2c63942dd0
-platform/hardware/google/apf b7af00686bcea796c72e3315dc1ce8169a85045a
-platform/hardware/google/av 8cefb8fff467b5e53270cb8a12f304de56ea55de
-platform/hardware/google/easel d0e7fcebc4f926f541ca9eb7c4b04bd1ae299335
-platform/hardware/google/interfaces 787038e86b6c805a90cb7ac4753ca8e4f9f16555
-platform/hardware/interfaces d25bffff74ede381854f9436fd584ef1cfa38231
-platform/hardware/invensense 972634999c89de283f6fc8b05cbd1781e52dc92c
-platform/hardware/libhardware 48d500c9e3e06fe1276cf5a9d381e549172de94c
-platform/hardware/libhardware_legacy 899b195ce798fd957bccd224b3c252285e3d3017
-platform/hardware/marvell/bt 3f33d194e8300816b94d1d7b68b1d48c8f903251
-platform/hardware/nxp/nfc 5023739280f82fd773713912b59a910454b0d443
-platform/hardware/nxp/secure_element b40413839d0a4d15de5d1bb87e3b89d7af7716a0
-platform/hardware/qcom/audio bc44bd9a13e5e826c49295c3a6f4c664d77e84c0
-platform/hardware/qcom/bootctrl 30d1d22c70adc51f2a8d6810102ec8cd62585dc9
-platform/hardware/qcom/bt 84ef44b8851aa4c9132e878964027ed08b6d66af
-platform/hardware/qcom/camera a023277f947a1ff220fe0562b71af0f3fa60b517
-platform/hardware/qcom/data/ipacfg-mgr a954a762119a90b84fbb2cc7cfb493ad41a139a8
-platform/hardware/qcom/display 46ee9a1b043256399918e7277e7547bc546e159d
-platform/hardware/qcom/gps b39241c8b5a0fd9a9f2b19a2d0e49fd0be3056cf
-platform/hardware/qcom/keymaster 437b089a6dc858d67362550bacc007fb5d2e7349
-platform/hardware/qcom/media 64c507509d5c769dda8fc821a85cb59ff76697ca
+platform/external/googletest c4464882ff6a8401d271f5b99f5ff34eb5bf9f52
+platform/external/gptfdisk ccb2b01c844db800ee40deba44f7e72a10ce845a
+platform/external/grpc-grpc 9ad49a0469fcb53848ee84ae31da634ed794b7fd
+platform/external/grpc-grpc-java 4e675722e2c87e8f750d09ecdf13cb38e06f7b12
+platform/external/guava c73d593fd2a54f522605c1aa42ac0bfbb6dd7269
+platform/external/guice ad20276d1abe2c3126f38937e3829963dd544bab
+platform/external/gwp_asan 43b4c5d99e2e3992c5c3af8a680c8ace682e525a
+platform/external/hamcrest f778d95e36e5087b999aadcfef6b3f59cb39370b
+platform/external/harfbuzz_ng 95e8d382e5e2265c23b5d3bebc119622794f9b4a
+platform/external/honggfuzz b47af6fa914b77eb07196f9e2cb282343a379a6c
+platform/external/hyphenation-patterns b0abe8eea5b01129ea8ab067e3256dc88a7cf864
+platform/external/icu 361fedf8075b1e8b949189aabc89016a04c23cda
+platform/external/igt-gpu-tools cad05e08f4eb352fa05ae314d0411796cca22874
+platform/external/ims 6ab1677b7c8b3a790b574fcc4b5f361ec7ca8a02
+platform/external/iperf3 27d8de532316e291fdc045aff05dbd1007389526
+platform/external/iproute2 4531b9118a9348ff5770336d26881e64a33842b1
+platform/external/ipsec-tools 39ee1473609044e20fd8e65281a2257dda28e9fb
+platform/external/iptables 016bd57558c7571a280979dd694d717e40b7e4ca
+platform/external/iputils 47115a56fda5f3971da0518e58b79bef91f7ca9b
+platform/external/iw 4ea2a3e0f59a2c35f5e196c9d3b3879136954f90
+platform/external/jacoco fd0117f5a5f721e5909f83a9b261dc0b35719137
+platform/external/jarjar e75749fa6818918f829d3674ea7db39d06473708
+platform/external/javaparser 0e82ab9d1c3830c886b3314ac4217dd51bc793f4
+platform/external/javapoet 74af6f11fc90cab010ae4342db2402b7cd8d324e
+platform/external/javasqlite a075483582db207aaae77e4294e9ecc2b5ba1012
+platform/external/jcommander 0a77c1b1b8385e68fe7c385c07f63add01eadd24
+platform/external/jdiff e09b8368598e8a8b1d4497789f4968525ce64077
+platform/external/jemalloc 38ad735d81c2696158255ce0ee26acd058574308
+platform/external/jemalloc_new ecba6d7c8c03938dfd15d2fd9f45fc7308c7eb32
+platform/external/jline 6750a50a3b7ba5ba7862731a7db2202ecce28c34
+platform/external/jsilver aa467632bfb8647efdbaa90f8859503c9fa1e2fc
+platform/external/jsmn 8ffd2fe46c2d19cc6bb4b1bb6f0f3a799d89d912
+platform/external/jsoncpp 0ba16e9627d91ccdc46017a16f846bdd37add937
+platform/external/jsr305 e90847ee51419c91e8a9940f7951a0a7bb69dd28
+platform/external/jsr330 9df1034d4bb29a433a1ffa5c361aef72b6b4f0d6
+platform/external/junit f9da4ba5c691761a7d11a64937ba3fcfaa4d6a57
+platform/external/junit-params 36dca2f5bc7e5e52f1465c234e6ad8d9aebb56bc
+platform/external/kernel-headers 58086320ab0c13f384cf5973a250b4b4a17b024d
+platform/external/kmod c9c885455b39db9fd5d5f7bc4216f15514e85f01
+platform/external/kotlinc 349602a59689e5c4d1dc4b7816aa792f6ec03a98
+platform/external/kotlinx.coroutines e347054e79c6800142265bb1b6446c41e7f3ecc0
+platform/external/ksoap2 26c3550e180cfdca25356d155bb3fc684a026d83
+platform/external/libavc 1b40ab8f3c329ccd2062d3438bf21b1fa0fbe3c5
+platform/external/libbackup a7b0e0ea1b4494eb8684d994060924b49a8b7059
+platform/external/libbrillo 3a8aedc30356c1c6b82b491d33b3c0bf053a1f4c
+platform/external/libcap d7229d8fa91c68797cd5e66565d01eee4301c5c2
+platform/external/libcap-ng fc5b4eba9b319347794ea7361e7082e0bee0a527
+platform/external/libchrome d24ccea82d0304497be6b20dc8c3fdcabf1afabe
+platform/external/libcups 6e8e063ccb4422b51f0fba53abebffffa439bbb9
+platform/external/libcxx f4597b2328d32f7f83b6cf9d129d764e10dd00df
+platform/external/libcxxabi 1ce22cf361f5becea66adf2ef5491bfbb8de1790
+platform/external/libdaemon 7e37193bd4053c93967175714995c568659b4669
+platform/external/libdivsufsort 48a2c2f42caf69038b633af1c3468d8af39c0a97
+platform/external/libdrm 85862ad2830c71b9bbfa6a0e0079872623bf4554
+platform/external/libepoxy 174d1194015fb352615417da636ca26d6a4829b6
+platform/external/libese 4321f587aee73dcbd6f5519e51518f3078d25732
+platform/external/libevent 053bc07b74608c35d8d50d5c58421394e1046412
+platform/external/libexif 5d5fc21cfb5b450eb346c1f78fc6c356571430d2
+platform/external/libffi 6942c1e38c6e44866c382a17cc63a477daaa0e2e
+platform/external/libfuse 8e056f46aff12dad31bb1c7de57eefbea225c08e
+platform/external/libgsm 583d92eac7e3e30c92ea3d57356bcb67560cec41
+platform/external/libhevc 3bf83b93fa7b8775923198c6c2af524ef64a2a9f
+platform/external/libjpeg-turbo 70e2d3cbf15f63929b9d75d94802f7427bb0cb57
+platform/external/libkmsxx c9093bcb613bddb3ec8abe64028f7dcdbadc8511
+platform/external/libldac 9513e593d8545df3c7195418331599dde1844666
+platform/external/libmpeg2 37c8019743dc5ff657ab63123b1db858e554b1bc
+platform/external/libmtp b00567f8964a9ebac67ed9b02c7c40b8ab36c1be
+platform/external/libnetfilter_conntrack cbd4e00a0fe2e5d75d1f982805602dded8814276
+platform/external/libnfnetlink b3cb039d6b0f658c22ebc1e2c4529827481791a4
+platform/external/libnl 3bb38a5a25054c2f6438411fa5a4556edd08900c
+platform/external/libogg 53565970cb13943f14e038d315dd4f7f1c5f7e3a
+platform/external/libopus 7be7713bf979a537d4d7bef4326500f12ec32e48
+platform/external/libpcap d5c6a5a3859d35604d9c64ea37846c9c8d044241
+platform/external/libphonenumber d9c6bdaa14d05631d45ef65a74e102a0799c4536
+platform/external/libpng 9ae353f872650b18d9d13523638b5d1768a4c557
+platform/external/libprotobuf-mutator 5821b7519c2967e54f4d2776a20df0c35bb4ff9f
+platform/external/libtextclassifier edd27795449773d980ad347db6a6577922d157f6
+platform/external/libunwind 6eefe77f1a6990c336ad29bb4583d7954d9915be
+platform/external/libunwind_llvm 3221152c851580aa9ba54da8c36d94763efb3feb
+platform/external/libusb a6fe5a369de2647f89f177b05afe8ef519b29350
+platform/external/libusb-compat eda6bdbdf3262df67a553b65436a349bbe00fe31
+platform/external/libutf 70c4d402c49427615ab9149cbfcc39d158aab74c
+platform/external/libvpx 759b10b572aa8d882a4e891787fa470b17b1991e
+platform/external/libvterm 6c0deffd856c32598500b7f7e1f8dc82027abd6f
+platform/external/libxaac 73d7de8180a708cffa8f7a3baa8631037c5065d7
+platform/external/libxcam b147656bb5a4eea82e4f7be83773a49d9266150e
+platform/external/libxkbcommon ccd27eab3a0e694d968069ee2c7d918e7a9c1ece
+platform/external/libxml2 f419eda77be55b6a6502aecff975685b9ef247c2
+platform/external/libyuv f98db06d087efa2ee69b322cd8e31a8637ab76b9
+platform/external/linux-kselftest 69565e18769d0d31e8c96748d6254a857eab0f55
+platform/external/llvm fd44911d9fdf47a2dde1d3869494317b8b6bc124
+platform/external/lmfit c374b57f19b3c911db155b7044d319f6cbcafaea
+platform/external/lottie d5ae520ccb358b7ebe0aee1f8fa46a19d7a187a9
+platform/external/ltp 65ab6f1e869a80ccfc3cba7475553be7f232e951
+platform/external/lua 1be0f9fe7df4e1250bd60c6f9d2571bc20e91887
+platform/external/lz4 1905bd525f73c808f275c8a61d1c883bd3336b77
+platform/external/lzma f26cd190115d4432f59fc992283a283ccbf4846c
+platform/external/markdown 25df5f0a65b6e1b4f8ea854e3e0d2e2a998284ee
+platform/external/mdnsresponder 1e3fb1cfd8d6299ec210236791afe6e31baadad3
+platform/external/mesa3d 776bd8abbd19280a42ab426176091e2bcb4e5231
+platform/external/mime-support e9ca40b1e71797a24e96b20b74e692f2fa3e4137
+platform/external/minigbm 175544177f39ea5b8b6118372a6ebc0ad5e2bf89
+platform/external/minijail cf8cdf9e826cd0d2293f4d2f4066c54461346018
+platform/external/mksh bce8c8f3e07cdd472d7fccdb747f37dc712ca15f
+platform/external/mockftpserver 400b45e156438929b557681e340a24865a586e93
+platform/external/mockito f925b4ec95ae6a95597588c5b0d062a3f1345ff3
+platform/external/mockwebserver 19b850e1d70a5d4efaee6760e9db61a92379e1ca
+platform/external/modp_b64 e1f906533288648575edcabd198cdc815233ac12
+platform/external/mp4parser e8d2057241e371a5113fd89d3cad05fd312e8e20
+platform/external/mtpd 851adbf27a605edaec9d51f1f2c85a73e02e028c
+platform/external/nanohttpd f37afa8648dfc6309c3c4ec8de004e236ed7c451
+platform/external/nanopb-c dc24a09ddfce3f73728f0ac854ae12ce0ea069af
+platform/external/naver-fonts 4cf8e59cf9378c9632f380af4cb8f658abe0eb75
+platform/external/neon_2_sse 93a290431c80e691291bbb867923d4d8fc97375a
+platform/external/neven 34c2f8e5e57fed19ff10d6760881af992d9e3b28
+platform/external/newfs_msdos d488a474772db53a1d223a2d15dee7aae6de2e90
+platform/external/nfacct 9948eab99144d6363b0a133164a1922ee28a7756
+platform/external/nist-pkits e5f3885aee2b8f15f17150332a301f4a3eea294d
+platform/external/nist-sip 43449134ebca215bbf396a063c0b6af033d53510
+platform/external/nos/host/android fc19dbcca30575ae8d92f812ee05351cb8354af7
+platform/external/nos/host/generic 9719191b8c71af01f8b09178d05767b0220d7e8e
+platform/external/nos/test/system-test-harness a4a0fb7457eb9afea956bc481ad7623aa13a6c19
+platform/external/noto-fonts 1916e160ba36fed52650d59b1743141b822c63da
+platform/external/oauth ccef8bda7971a511e364e854a18f6a2b7e31cade
+platform/external/objenesis adb7dde7d2438e4f782f42604c4673292be7e5c9
+platform/external/oj-libjdwp 646f7a7962910f50ee28395be7f2a6533610b84c
+platform/external/okhttp 6568ee62b353e8b3476542f075c1ff0ea98a3548
+platform/external/one-true-awk 332afae283561e2e234d0ffcff1c2359dc3ffb47
+platform/external/opencensus-java 0e07cca418aff23a639a44ca465ba8b6a9f917cf
+platform/external/owasp/sanitizer 88a77766c01079ebeca0bf9d0eaf31622a8702f1
+platform/external/parameter-framework f55f3b49141b2e33549aa0a79f7293f81a526de0
+platform/external/pcre 029f78b3dd73e95751e77a790ceb7c977b1ddff0
+platform/external/pdfium acb875c7511405a385f16cc3b717bd5a51c9c841
+platform/external/perfetto e238af7d89757887df330aaacdc34d0226fa8ee9
+platform/external/piex 2860bcbec7b1da7f24097a6f7c8430a77d1be041
+platform/external/ply bd68d8287c7b2b62558e881896fb4fa67a91bfd5
+platform/external/ppp 7a04cdffe16f4f26d85c0f766a5d5fd7fd37984f
+platform/external/proguard 5421389140ebf71e1559427d1baa384815eb0ec8
+platform/external/protobuf 2f68d605491b22bfac84fce75300a0defff07d3e
+platform/external/protobuf-javalite 004ed30b52a39cb68e8b00e9f37260cb8fba1806
+platform/external/puffin 905bbba565e2f78585b8c606cc4872b443d0c749
+platform/external/python/Pillow d72f4f1cd84e416a59a8f57f491c567a7650e65f
+platform/external/python/apitools d0142dd460aa2af6568b7898246a969dc5ba875d
+platform/external/python/appdirs c70c940cf3d28d2f3e01c41ecb758da1ae37c699
+platform/external/python/asn1crypto 4dc1bc9adffde69291d315926361f6135fde5d93
+platform/external/python/atomicwrites 90f4c6fb7a2d31fc5e099919c708307cbb149140
+platform/external/python/attrs 759f9676d76414dad028addb959f7610a1f22008
+platform/external/python/cachetools 598fd64b867f9dae50f0d4f62b0b23c3b1dc8da2
+platform/external/python/cffi 934d3e96800a7210ad0e5e074a61d4fa78dba181
+platform/external/python/cpython2 0567bdaad7e6280c0b6001e969a4810f9b144347
+platform/external/python/cpython3 105a3288b53ba4395c1efdb451e6bd9a2838f9a1
+platform/external/python/cryptography 4827460c67c2f19639fb6736ce903035840d1ad8
+platform/external/python/dateutil aec597880592a34330d5b71f7f1aa5a9279622c3
+platform/external/python/dill f75b7b4bb53f71751244c102b9a8b29e7f79cd7a
+platform/external/python/enum bc983ebbfe611ca08967469c3f67ac99beefcd0c
+platform/external/python/enum34 ddb73576f7865072e0f12e92d7199fb7795af1c3
+platform/external/python/funcsigs 4afd27bf245c2757464c5f9492eb00ff3271150c
+platform/external/python/future 34c27d1b01d0656cbb7752efbddbbb25a4ffec43
+platform/external/python/futures 89b0df8e2990040a6f435c95f73fddd3e3a1bf21
+platform/external/python/gapic-google-cloud-pubsub-v1 a7f3616024b3fba70452687948218648d5e8606e
+platform/external/python/google-api-python-client 71ef10a8eedbbf5198bbf2f879b1a1bc1130cfb7
+platform/external/python/google-auth 1b4c85fd5ab413b08fd7ca72cddec22ef41aae0e
+platform/external/python/google-auth-httplib2 e2d430024389106380703e13a4fd1d94cae75a27
+platform/external/python/google-cloud-core 0d0c511028c56b01fb49c8cfa9967da5506fe8f5
+platform/external/python/google-cloud-pubsub c0f84beb4e8bb31105063ee3c65bb4486510d544
+platform/external/python/google-gax 402bc6b8644483374b73b4cd3812a845d5c3597a
+platform/external/python/googleapis 7e8c2d62d0a6cdade74674c2212c9072bf0e43eb
+platform/external/python/grpc-google-iam-v1 fe6c657f282121fddaf41a77495525b575c1e344
+platform/external/python/grpcio a30f14ae1264b318eb749ce97bd255f9bdbc17c4
+platform/external/python/httplib2 b04e9524517e2103da8f45be995be8e7aad9b18c
+platform/external/python/ipaddress a13f2c58fc98976d87cd3673bd99b7634b3c3f34
+platform/external/python/matplotlib 6a7194b8506110e33796e20887c5af121d2045fd
+platform/external/python/mock 54ea75c0e66e5d9d0efc2a26d202dcd97180186d
+platform/external/python/more-itertools 5c7ddf33a3b11d7d60776c6860e582b837f1f102
+platform/external/python/numpy 19ac03b6a03f19170946fbeed893277f745342df
+platform/external/python/oauth2client 8c5a6494c267068ab7b4dcfb7b1657ef4f6f3648
+platform/external/python/olefile 77ea07605882f1cedc84092507e133fce232150e
+platform/external/python/packaging a87805bbd88b433315505873aeb500dd05c0a7b3
+platform/external/python/parse c22445bf8f6e209c564a7fe3bb83d5f4158c605a
+platform/external/python/pluggy 443e36f8097799479097649aee7f338f0e38d05a
+platform/external/python/ply 38f91dcd5769ff89721335a65a96ce714900e638
+platform/external/python/proto-google-cloud-pubsub-v1 3e2c928660479fa26a6cde22ea68e4f007935708
+platform/external/python/protobuf 2afb2d6e505f14627c1893b107e4e397cf22b170
+platform/external/python/py 524dc948aa5659bfd0bdb9d3872adc33f28a901d
+platform/external/python/pyasn1 01ec1875a2395df0f17ff240fcbd22ec1e622606
+platform/external/python/pyasn1-modules d5c35aa313cf3f1b55d50b06471ea9f24246089a
+platform/external/python/pycparser 0203d46c571a1cbe888bec375c6fc335a72501bf
+platform/external/python/pyopenssl c9ee934dbb5c604f7cd697a6712b732235762b61
+platform/external/python/pyparsing 077449cce1b7299e9870fc5e56a3ebf19d7216d7
+platform/external/python/pytest 16acc5cb60831d67dc1216d42e86f22e303fcadc
+platform/external/python/requests 487a0c5fd358f12a4a7ed3b483bf4a2f67458a58
+platform/external/python/rsa 1d1c533e89ba587a8193c1964e32dc7702160b5f
+platform/external/python/scipy dd3ca6d21860c6bdaa5ebc7ac99b3691c7e4dbf3
+platform/external/python/setuptools 48bd447fd5056330001312d0270f1da3d17fdc52
+platform/external/python/six 01b976b5608ef8d1a300fc41652cce8700f6f446
+platform/external/python/uritemplates 9d2ab247e7145266be3414d565fe0b39d6f3fc25
+platform/external/rapidjson c99717d773b7e4b752e8272ce1e658968427eb28
+platform/external/rappor d7f1b24dd5cce31780da88a67526f800bcae24b4
+platform/external/replicaisland 71beacc05f3f0959e330772e79097d89bdf6c969
+platform/external/rmi4utils 54696e641fba0ffc863435ec3cd86b48cc06e67c
+platform/external/robolectric-shadows 0eac7eca35cd84c66c7ab2417d4fd1e8a9de510a
+platform/external/roboto-fonts 2f06fbbed26f7950ee5bf92152ee54a5b398075e
+platform/external/rootdev 2295e443c294df4638dd79ae09ff74da584a6f56
+platform/external/rust/crates/byteorder 6b8a5a7461c299ee8f268e185078f7183a846f53
+platform/external/rust/crates/libc 44bf1c6bf55bf9ee01d44ebc827e26153876a239
+platform/external/rust/crates/remain 46a888dcabc80678e25d77d9c4ef203c988fda29
+platform/external/scapy fdc0c472f4d91c2d5d675326d7f13be837420a51
+platform/external/scrypt 1f40be36f94f651566655afa7ff11aa685f671a3
+platform/external/seccomp-tests b24a5a0eea45f30fa17542337d07352420fcde96
+platform/external/selinux 0952ccb96b4c7132c964d62a46e4c566abf66a7a
+platform/external/sfntly 73d4cd93295c0edf4f4ae9518194f51cc6106ca1
+platform/external/shaderc/spirv-headers aedfd8c21914f59cd668126545c006cf1ae51eaa
+platform/external/shflags 31cf51b2e9f82452dd3f7ee9f6aefbcad98a537c
+platform/external/skia 93740f612ddcc3a1a07bc4aa977e3b5222db5b60
+platform/external/skqp 321180fb81b7c1fffca2b41bf2ead698bc748ca3
+platform/external/sl4a c47e5aee39f585c7242c501e1b58e39ea6abbdc1
+platform/external/slf4j d5500aeb359d9523a44f3a947acb0751ca573f5c
+platform/external/smali 127eb62df12b457db0d6f5c99cc3aeb6c037eedc
+platform/external/snakeyaml 03aec882ae400d324bd0f2c4d0e6d02faa779e81
+platform/external/sonic ef3a000b977987fc729e336857195ca6201c9c16
+platform/external/sonivox ffadc79c4b4a470318fa39d9a4463b12e27b6925
+platform/external/speex 0834bba401e0d08be188d35deda1cfcfb70331a4
+platform/external/sqlite 9c908e198d8fe91a4707b0e014651a7035d32844
+platform/external/squashfs-tools d1af1dd1b3b0a00872aea88dc2f76da7125bc2eb
+platform/external/strace 47464654f9db6e843e2d6a2300eabd01d4ecb9ac
+platform/external/stressapptest cfb06af48d4df27329f8f0324e4530b7b130c4f0
+platform/external/swiftshader eb9d360c4cff767bf0848f7fae80571e1a67b107
+platform/external/syzkaller 9f3f193c06d06a769cf90242665aabbb4ff0a70f
+platform/external/tagsoup 8700ee44c7b29cdf963b9438bcdfe3d1733bc31c
+platform/external/tcpdump 8e15a2552ce25fe53ed5a292e4cc68b3bf9dfc37
+platform/external/tensorflow ca397eb7ed3d37035b772ccdaae79cb06eea93f1
+platform/external/testng 1a5a8241bfe4957b4054d4be86e8243aed45b3ff
+platform/external/tinyalsa 3d161217c03bce6ce418a16fba8e1910a304f85d
+platform/external/tinycompress 683bb324caa9d318f5dc1bb30f6c7499b2b0b9d9
+platform/external/tinyxml 3635bcc08fc3a0391028dfdd1b0a4d00777edaeb
+platform/external/tinyxml2 1ff1d11f7683dffe0fcee0fb8f890dcd32659781
+platform/external/toolchain-utils cde86f41626061a6b178a74aafc970b6adf8e8a5
+platform/external/toybox 0135330bceb2810fe2333504e0fe7cc3b6cdf2cd
+platform/external/tremolo 7a22090109d7ba391333e29b855740d10c292c2d
+platform/external/turbine f8280df3531bcca03e2ad3a5c3175bc3fe9f6178
+platform/external/u-boot 111f850a1f00369d92021c810b05ddcea107b9af
+platform/external/ukey2 7015f7a6bd9ef47f8de34db481c7e457ca6f138c
+platform/external/unicode e32e29b5edb3802cd0a5a333f858aaa8bc2db73e
+platform/external/universal-tween-engine a8ee7e685a3c41584f5dbcc8c692804189ef8de4
+platform/external/v4l2_codec2 eec3db7c291c09dcc92766c1b28bfce6b2e74f9f
+platform/external/v8 b520e2eab71c5c7fd8746a4d9c875194a1541ae5
+platform/external/vboot_reference 362ebfd7294f7d0ff23514d4208328733b12f493
+platform/external/virglrenderer 228b20a777c2f7cfdc2bbdf28faac27f67d991ae
+platform/external/vixl 94c2dcab4ef2091205284f6285b1928cdee8d181
+platform/external/vogar d206a40b8963549bea2461270e67a96cdbfe54d8
+platform/external/volley 219f5f6c780b3210d3aedf0a9cd803011a7bc4c6
+platform/external/vulkan-headers 13d8e262665e8ec9870c87f6aff7574d35636aaa
+platform/external/vulkan-validation-layers 15e43fbf6429eb55d7039a1c04fb15b9145f44d2
+platform/external/walt ab11cad8869bb6b5191b4f2301b4bc610eda64b9
+platform/external/wayland 565640eeef2660ebc7f2154457f9e2dcefb34a82
+platform/external/wayland-protocols 20da51c30ee4f17c8d3fd3b99cdefdc2aec78f02
+platform/external/webp 394adb5318db885a911a797f931e88de29f7f94d
+platform/external/webrtc 480bea77d35453cd160a23447dd85b1c7b261699
+platform/external/wpa_supplicant_8 cd2f60707b72b074baf120ca26cf4834578bd143
+platform/external/wycheproof 476c11cbb8d3aae6d8ec23dbbcfdd2ec5f308091
+platform/external/xmp_toolkit 796725d5588b17e5e0b4ca8560926b1f97e89180
+platform/external/xz-embedded 1fde8bd249e1a0e705173800c6e3c5e84f376fe0
+platform/external/xz-java 160a9877a4a457f2c3e1ddd1079e46b5960b467d
+platform/external/yapf 069dcdd82023ebf52feef58939d1be861b754c6e
+platform/external/zlib 670150db5a680784fd58dc9c5f26275abde752ea
+platform/external/zopfli 69a4c40111f5a7a2d158140305c070ae77710bb2
+platform/external/zxing ec2e4334658bdab8860f88c6414996167cdedc37
+platform/frameworks/av 4818e08347703105f83c8030510a39ffed0d867d
+platform/frameworks/base 44b119efe92d0dfa1a90a9b4dc7b8c4ea5a6390c
+platform/frameworks/compile/libbcc 7544e307cc26c9ebeb58098f9eb0e82f32fcf488
+platform/frameworks/compile/mclinker f2624ef41bf97234874b473404595cc9dbba2ad3
+platform/frameworks/compile/slang 82481b52d91a2edcb7292a9b450804eb98e96edb
+platform/frameworks/ex d61bd1cc377fc024e40b00c0860115cc31a68e6c
+platform/frameworks/hardware/interfaces 8c871318fda01686043c653c21d896dbca9e7787
+platform/frameworks/layoutlib 4bafdbd0acc0fe5af4b302a2541b01bb724f8013
+platform/frameworks/minikin 9314661eaca2a919a0e83303ab31345979a78a29
+platform/frameworks/ml d26782f2e44aa73ac8cc1da075c56884fa2bbad8
+platform/frameworks/multidex 7c523a2cbfd2fc4e845ccad60b4e53723a25a0ef
+platform/frameworks/native d5377d995657feaa5bb57eec43ab0402441239ec
+platform/frameworks/opt/bitmap 8a9e20c7cacd022ff928341ecdc1369cc1600931
+platform/frameworks/opt/calendar 73e6a611dfa86c12c061d762d8b3bb513040f579
+platform/frameworks/opt/car/services 6d07be0c8ac4f6a4a1a82dea760f33635311d02b
+platform/frameworks/opt/car/setupwizard 6ee0abefce7eff1bedf1d06b442c39dc9c8a90ec
+platform/frameworks/opt/chips 487bd7ab88e941c1cf09b2d170302419df184d93
+platform/frameworks/opt/colorpicker 8bedd1dd4a996fe48c5f40c17043289e71ed358f
+platform/frameworks/opt/inputmethodcommon ec9c44153ba1aa9d14171123c23777c006bcf7d1
+platform/frameworks/opt/net/ethernet e0b4a8955f88c39943d691b47c9a011cd21a79dc
+platform/frameworks/opt/net/ike a152ed71411b077a22e48314a81fd8f838118435
+platform/frameworks/opt/net/ims 061d331192825a267015a503226ba6468946cc1c
+platform/frameworks/opt/net/voip 1b53bf0be749e09a2e46fa86b78179f37bbe9987
+platform/frameworks/opt/net/wifi 6d91e29a4a235bbfb1a14cf01a35fe05cd5c548f
+platform/frameworks/opt/photoviewer 54874ac60eab445b020bb513f5b8a3b4542cf131
+platform/frameworks/opt/setupwizard 2f8146865182c4330d39b50a2e1674ce493d9b6e
+platform/frameworks/opt/telephony 57d3b494215a303f3f68779e5bc27e27130c16bf
+platform/frameworks/opt/timezonepicker 639a11846a8bd72962f47e3cfea0b7385150e482
+platform/frameworks/opt/vcard ded13d2482707b8610fc32993dd8b48e345b26e4
+platform/frameworks/rs 4b40e24bef537e4256d5807f76c9fe9ecad857d4
+platform/frameworks/support ac0e825c79186314651efd16fc5438bf294a5730
+platform/frameworks/wilhelm 62fa89482ee32213c1e09c8909ffe2ce17f74c05
+platform/hardware/broadcom/libbt 875846c1aaeee01600ec0da70de0396e10bb1b50
+platform/hardware/broadcom/wlan 31d64b6507a8e006659b532a3a6060c9aa52c245
+platform/hardware/google/apf 66e0ac6d1fd753eb062fb5763a202022e3a2adf5
+platform/hardware/google/av 6bc45db08cb4c328783ecc39b655e864588468e2
+platform/hardware/google/easel dceb7bf6db182304a30f21f6e518da6ad4c61e43
+platform/hardware/google/interfaces 2525139faf4b11fbc4500345cf130d606f22b67b
+platform/hardware/google/pixel f15a96a559e1ffc84a4217debcf3fc650aade41e
+platform/hardware/interfaces a81b30047b88805967dc873e0575206cc4d7078a
+platform/hardware/invensense 25d0988bbd77838681cc9bdc91317570e960538b
+platform/hardware/libhardware aa8beea09ea0536ea0e86a19292c3145bf69d9a5
+platform/hardware/libhardware_legacy db928eb65ef1c2c50f27e221da35188fba3bf9c0
+platform/hardware/nxp/nfc 35ea5d304b44f6fc7a9bc44769c927c80c945d75
+platform/hardware/nxp/secure_element 3b9e13ed47c1e61f5133fe8d5c1711560f4f2cdd
+platform/hardware/qcom/audio 31ed4a0b8662bb42273d9bf6ea24d111c97aa019
+platform/hardware/qcom/bootctrl f0e79f591a3284f3cc8f0877a64c0fe2562187b8
+platform/hardware/qcom/bt e8bb1c5e6a759dd21bfd9572b0b4a0f2da71ee14
+platform/hardware/qcom/camera 0af91873bf48c4f37ce66715e5f50724ef3152a3
+platform/hardware/qcom/data/ipacfg-mgr 8878111da5e3e02703326fb7de7a774a4b04ed09
+platform/hardware/qcom/display 6f649fe0f066c6f02aaa6ecedbebd4c27d43461a
+platform/hardware/qcom/gps 35f5e5ded411dc49e3cbaa787d8ac69c8b2806d9
+platform/hardware/qcom/keymaster 420af58ecddfc46796b21a594555c6d051dc0d2a
+platform/hardware/qcom/media f52474b60eebc18c8f56dc52a7900a56ea646e79
 platform/hardware/qcom/msm8960 c25a431842a26b5756b58a9d4a42c776e0457ba2
 platform/hardware/qcom/msm8994 8e0383f6f41a2c49461f381c8d066ea21b20c674
-platform/hardware/qcom/msm8996 42c2f014f23d32ca01136525d5acdc3bff7d6a56
-platform/hardware/qcom/msm8998 2b4c1a84f4367adc8240fc5ace5825811c731a09
-platform/hardware/qcom/msm8x09 d3fb2be4cccde23fad1960b3c9dbf96efe0c383f
+platform/hardware/qcom/msm8996 396eafc85712eab82894256e816a341c4b257a83
+platform/hardware/qcom/msm8998 5d3b48877790d7f4f4805d58c0dab215d53fab36
+platform/hardware/qcom/msm8x09 bcbf10addeb35787a42dbadd06d4f874e9d8c2be
 platform/hardware/qcom/msm8x26 85c1a5282ae28663335e55ce96a4c0487de6c578
 platform/hardware/qcom/msm8x27 8ff5c0057cbdecfa09410c1710ba043e191a2862
 platform/hardware/qcom/msm8x84 582b414269d8472d17eef65d8a8965aa8105042f
-platform/hardware/qcom/neuralnetworks/hvxservice 5aa42775fed2d57ff7721815b5f672f78c671997
-platform/hardware/qcom/power b208421e1541768c135e12ff42f53d2d901b1311
-platform/hardware/qcom/sdm845/bt 9dc9663766cc734b330d6a5e99d5e17d218685e5
-platform/hardware/qcom/sdm845/data/ipacfg-mgr c44dfdf5b291d2eb420673cabc9d8914882dc38f
-platform/hardware/qcom/sdm845/display eefc1a942b8cc7a2d3c061bbddbde7d450dae52a
-platform/hardware/qcom/sdm845/gps fbee4e958951355e18074537330bff3cbee74e59
-platform/hardware/qcom/sdm845/media 669cdf068380535603146b83714860a498cd63e2
-platform/hardware/qcom/sdm845/thermal ec430959607cc3c747e8954400ace5f475b86355
-platform/hardware/qcom/sdm845/vr 306bad0089a9d8cf912e07b2d3f3017c0d808e74
-platform/hardware/qcom/wlan 136eb4d05fd2221f5184e27ded211241a5355d25
-platform/hardware/ril 902fa44011ebd47dcde18e62bd7241f217ad33dc
-platform/hardware/st/nfc 9030f51e8bf7a154a6ade027c3d1ede95fc63eda
-platform/hardware/st/secure_element 013554ca37c1b3416173a4d14066f1b0f615f615
-platform/hardware/ti/am57x e5c62581cc36e29f99971d83c06b5711fa878af1
-platform/libcore f47d9b9e625ba93486c720bb925c7eabdb540597
-platform/libnativehelper c7e658e8e516a3a84bd53fed5e04d921c90d4107
-platform/manifest 3775f156f7b655035e4c65383d15a42a7194b3d8
-platform/packages/apps/BasicSmsReceiver 157c0199e36283f18e3dfa9ae2b24e25b5bf2e3a
-platform/packages/apps/Bluetooth 5d5b33d9acbe4b0458822c6f702d52cae5b92f53
-platform/packages/apps/Browser2 178143830600d6ae41ffe2c39c289faf8c9f9761
-platform/packages/apps/Calendar 0bd5cedb0dab02419e0d0b84ce8cec6ba33d7dc7
-platform/packages/apps/Camera2 25a33ce5e705cc16cf67fc4641238def1579112a
-platform/packages/apps/Car/Dialer f0a878beed1509ed38bce3b20d452cd29a538b93
-platform/packages/apps/Car/Hvac 0ca7c3f7a0ff69cb9574eca7471c083755d9ee2d
-platform/packages/apps/Car/LatinIME 71c274c6b964a67c18488315a426a3786d3d8815
-platform/packages/apps/Car/Launcher f0e4032a61cb5043e3cd653f26e0207cea111324
-platform/packages/apps/Car/LensPicker e6c275ee60c3d0a376c233aebd6a2079a4053e25
-platform/packages/apps/Car/LocalMediaPlayer b6d4a69ae9fbfd0c63e76b92f6656039f3a97274
-platform/packages/apps/Car/Media 276f6265520c712a5421cd5b02bdae750ae6f77e
-platform/packages/apps/Car/Messenger f16768161e6eb693e3f466392b53cb5c807f2ce3
-platform/packages/apps/Car/Notification f2c9b2ddee9757b12b86706f6d3391bb37857c7d
-platform/packages/apps/Car/Overview e669c287268e237df5c4060ddf98f4cdfbc9f285
-platform/packages/apps/Car/Radio 64cf9ef05ba0dbc7a7ef314bcae5d4f361fecf11
-platform/packages/apps/Car/Settings da9f7e252fffd16e3269c08454df45344c4d90f3
-platform/packages/apps/Car/Stream 8d0242a0a84a197116748f0270bf014d0e051115
-platform/packages/apps/Car/SystemUpdater 0dcd36d719f958eb7181993258946899fb734cbd
-platform/packages/apps/Car/libs 6525ba03c120eef2a2cacbaf58411ea9dbd088cb
-platform/packages/apps/CarrierConfig 263dfaa8edcf0f4f840229d651a2ebbb53f3ccdf
-platform/packages/apps/CellBroadcastReceiver b92a75a783211c3d8801cff255d11898f98e6112
-platform/packages/apps/CertInstaller 331dfdd6936431c77f4bb8b35231aaf5199bf0be
-platform/packages/apps/Contacts 897d0e4635b3f4c42c2287911d1256e1297a25e1
-platform/packages/apps/DeskClock dc2d3a4df11343295a39f8d4a9e0ffb350ddecf6
-platform/packages/apps/DevCamera aafe9c777684baf2ab9a3fcb02eb4c0f9fa60940
-platform/packages/apps/Dialer f844e0d526a585442ced01637dc906428e95e77e
-platform/packages/apps/DocumentsUI 7a28e3e8db4192f981443ca40638f076f06e34e6
-platform/packages/apps/Email 7c1928e5b2b01729303f19c678d41bddfd6c82fc
-platform/packages/apps/EmergencyInfo db2ec81ae507a8b130f7e212dc5f8dcd369f7445
-platform/packages/apps/ExactCalculator 3cf0e4d2ddcfc3b94e3da2c2ed631063d07f6542
-platform/packages/apps/Gallery f88d30990c40b31f281f72f307615dc7c9b611af
-platform/packages/apps/Gallery2 13faf565ff6432dacddeab03aa6ec9ff78157803
-platform/packages/apps/HTMLViewer 40c123ea89c9da4fb7308994ac4ca929de3afd62
-platform/packages/apps/KeyChain 493afa6675f10b3b09b4dcaba521c4fc1c938473
-platform/packages/apps/Launcher2 973de6ee214376225ebe71d710f4d668d2b4b2ad
-platform/packages/apps/Launcher3 b7d8cd1e48dc2e085bd0fca3c233948ce3bf6499
-platform/packages/apps/LegacyCamera 98083b6e1abffba62f89996925b78b0d2e4813cd
-platform/packages/apps/ManagedProvisioning 7398fe25c3e8faf3d3b46b8a7f6951e5b497b390
-platform/packages/apps/Messaging c020ac4b780c1d58448f223a3d31a7347e617291
-platform/packages/apps/Music 89bcf1519ab956f681a1a713aff4bd77a881e623
-platform/packages/apps/MusicFX 359d972523a519a1470b36a6d8dfd6b6f471c718
-platform/packages/apps/Nfc 9fda9cb55dbb7ae04bc50eb5ac020689ffe66f6d
-platform/packages/apps/OneTimeInitializer 4286f0f191f6aa17432e4b9214127f82b6ca6547
-platform/packages/apps/PackageInstaller b359d3dca33c4960ab5857e22121eb03064b46b9
-platform/packages/apps/PhoneCommon a952c9e18ad1a0118be3eb398a9bd1d99285c6e2
-platform/packages/apps/Protips 1e5d8a500dce6530a99cb952681889042dcfb63a
-platform/packages/apps/Provision 327d858736d39c11bd609e1f30d9c121c227158e
-platform/packages/apps/QuickSearchBox b12e08801ef5f720b7485248668953d9fbe991db
-platform/packages/apps/SafetyRegulatoryInfo 8a18edf034e8c615139eb2de97e23ce44bf70b1a
-platform/packages/apps/SecureElement 3baaa048af9b8abd35ecd87261b883ce6c50c918
-platform/packages/apps/Settings 889a8a375732d718260897608d00737d46013273
-platform/packages/apps/SettingsIntelligence 16fc826a4d69ed26d79e1070809a26dd558fe1c4
-platform/packages/apps/SoundRecorder 79c936f956f7f88fd184a41f4b514278cf54747a
-platform/packages/apps/SpareParts 07decfc6692957b753dea7cafd6203a7e36a78c2
-platform/packages/apps/Stk 2f32a87c91e812bed5ebdd9596baf3a3fdf25961
-platform/packages/apps/StorageManager 52ff6ad49110e739f929365542a6bb417ce6eb55
-platform/packages/apps/TV 44297f1efde250dc789eeceb090fe3b3dab87894
-platform/packages/apps/Tag e4d8ca287674b717ba8f8da117c100e8741473fe
-platform/packages/apps/Terminal 65b6be76303bab8fba6dd9aba447394d23ad82c1
-platform/packages/apps/Test/connectivity bf57693d997c27595452282a82c4035f93353731
-platform/packages/apps/TimeZoneData a11e5864bda7c05543b52c88e7c52116b53a0284
-platform/packages/apps/TimeZoneUpdater 6b53a195bf8e5b4528bebc9cc6b0fba962094464
-platform/packages/apps/Traceur 21ca6f877472f7978606f65985ad39cee25814b4
-platform/packages/apps/TvSettings 6a53427e0d5df081826cc84774ad8559b4dc0a6f
-platform/packages/apps/UnifiedEmail f493100c37cc943b27fafc17cad27533fbb16cf6
-platform/packages/apps/WallpaperPicker f147ac2fdb2018353bd9d21ca4e69e441a53c6a1
-platform/packages/experimental 51d31ef8d78c25758cc1f2a16db55dc92965697e
-platform/packages/inputmethods/LatinIME db2e4888f8fa1559b300d57ab98a8f9cc342439f
-platform/packages/inputmethods/OpenWnn ef90dbc922a99522410056d728563920a6467006
+platform/hardware/qcom/neuralnetworks/hvxservice f6b5fb4627c01ce153c2c223e459a63f1246608b
+platform/hardware/qcom/power a4ceddb5ceb072042dd7b385d97539e6adda0b5f
+platform/hardware/qcom/sdm710/data/ipacfg-mgr bca3dca0c7a8e0e2b943175df6134f43d7457b25
+platform/hardware/qcom/sdm710/display 5db9af6f1965c8b8eaecd3fd660dfa5e200bf8ec
+platform/hardware/qcom/sdm710/gps 72a449e92ca8a9965b40e1d09dbe5a6586f1ddb6
+platform/hardware/qcom/sdm710/media 95fc68cd2e0f8b37060518eb885044c239d08340
+platform/hardware/qcom/sdm710/thermal 3cc9ac6ceaa132ffacea35e9e2b5484e5ebefbf3
+platform/hardware/qcom/sdm710/vr 5f053ecd721599e4180c05a34bac4ef1328e2db7
+platform/hardware/qcom/sdm845/bt 9a88a6aa2c16b94f0f3be4d73f35c7c00f7baba9
+platform/hardware/qcom/sdm845/data/ipacfg-mgr 12333364172e23d509439dcd3d342e1edd31bb95
+platform/hardware/qcom/sdm845/display abd9d06fd9373f7046de0ae2f1b314aeb408e154
+platform/hardware/qcom/sdm845/gps 4d4799412ffcaae5e08c94f540bc2d759258c842
+platform/hardware/qcom/sdm845/media 01da16e501639a6dfb74bb40ab4bb8fe4b094584
+platform/hardware/qcom/sdm845/thermal ec9172540f62f501d543b986b65ea5b964f833e2
+platform/hardware/qcom/sdm845/vr 44952b4eec1f5ab4328d9412523c4576dda121f1
+platform/hardware/qcom/wlan 0b194449e212ad212a707d574340372ed82f3946
+platform/hardware/ril 06ae422afd799a9a0132d38816b569a12533d576
+platform/hardware/st/nfc b6c02595ef01526ea122d3b5894ca7c96b857a5a
+platform/hardware/st/secure_element ee4aaa683421bfc06a58dc60afd3dd0119532874
+platform/hardware/ti/am57x df2fecbf2a3df35abf4771802005baaa075041db
+platform/libcore caf1fc3efd9d7bf2602b95189f2d78cf604d270c
+platform/libnativehelper 11071717176dcd6ca3ee51b017873b411f663833
+platform/manifest 9a14d2aa50fd99969dc518bd43a18b2a5eac6090
+platform/packages/apps/BasicSmsReceiver e6ab5d11c11f4f4b62bc7ba7281e0954256f0923
+platform/packages/apps/Bluetooth 2a3d1420da7f0ca85a9f0b49fcbbc33b9ba693e0
+platform/packages/apps/Browser2 f7f85ef8c40c35c4128175f7f292fb4095e589bb
+platform/packages/apps/Calendar 985c16ab8b9e84a99cd802e9741ba9a70b50eadc
+platform/packages/apps/Camera2 3261a19a17970cc3d136f96c351500c62a3df26c
+platform/packages/apps/Car/Dialer 93f62fe7476814ae2a186be08d83de42ed131591
+platform/packages/apps/Car/Hvac 108564ebabc73f0be4f127df0a8059f9a855dde4
+platform/packages/apps/Car/LatinIME bf86e8a6305881cbbf067e338b6da16681aef495
+platform/packages/apps/Car/Launcher c3c855612341c4c88c2873f01743497c6c064dc3
+platform/packages/apps/Car/LensPicker b012fd84e8cb67928cde067529221e6a06d24f11
+platform/packages/apps/Car/LocalMediaPlayer 1db9ef3cc724c676f8c21d2cdedfa82551c58b94
+platform/packages/apps/Car/Media 8d006a8873a5e41ea1b513a92b4eb51f385e9130
+platform/packages/apps/Car/Messenger c949bcacef5615c13e2e75630247e03afa9c945d
+platform/packages/apps/Car/Notification 580bda9121adb2cea117e41f2756d9ff088de029
+platform/packages/apps/Car/Overview ef89bd021a031ee6877b7fbd0798226fc2d56c39
+platform/packages/apps/Car/Radio a89794e8a5f897e0cb4d799f5ff95ce952138889
+platform/packages/apps/Car/Settings b31b10b33d71a15f9c80ac0e6cfc3c51e2b7301b
+platform/packages/apps/Car/Stream 623ee8d86acdbcf04f4d78b2bed17a0c36b2a271
+platform/packages/apps/Car/SystemUpdater d7833bcca02a63e838d39017699e267e48b5cfbb
+platform/packages/apps/Car/libs fed801b18b50295f4708023c160929deafa0f7f4
+platform/packages/apps/CarrierConfig 99a462b3fd2fa59ff48f2c5a51d13524c505aa64
+platform/packages/apps/CellBroadcastReceiver bb13ac06b045a1e999cba3aa3f6309e53095ad7c
+platform/packages/apps/CertInstaller 542a366225110bcefa042caa35f34c7c562cb510
+platform/packages/apps/Contacts 07d0750264a2e93d39dbe131dfdfbb6765a79b7b
+platform/packages/apps/DeskClock c47ddffa53586ec13e12acc4a539a09513191fa2
+platform/packages/apps/DevCamera 80cdae550c4f898f92444b8f7583e97896153b9f
+platform/packages/apps/Dialer 798b99073a5077d527887124c618dd8aaf6e75bf
+platform/packages/apps/DocumentsUI f7c467f15d01689410d4e867f053191f9a60d466
+platform/packages/apps/Email f9bbd17972ca8ce9bf613f4fd70f6943a7d475f6
+platform/packages/apps/EmergencyInfo 5ae59f07216b6c6350bb28f45fee2eab77d57d95
+platform/packages/apps/Gallery 6f138e004f8912ef794c1bb9856f05cc775ab4df
+platform/packages/apps/Gallery2 54fb90ba4ee65f652ed2c1bae6f0d744a511bf82
+platform/packages/apps/HTMLViewer b22049403bdde84389564601ddc34276366653e9
+platform/packages/apps/KeyChain 8354ce70c815089e756fa0d80a2708ceb4186a29
+platform/packages/apps/Launcher2 45ac509e9c0276b825e7aba2ad2c2625dbb08d13
+platform/packages/apps/Launcher3 10ce6becf4375d34869f8286e81a4ff5991949d0
+platform/packages/apps/LegacyCamera e7ea8e0df41e500bb8791d80af491a90c7317cf3
+platform/packages/apps/ManagedProvisioning 821b10edf80c2a7f837dd9cd6d9d566df899504b
+platform/packages/apps/Messaging a7c35d04665692a0068ad4d3b583be3bb4142b63
+platform/packages/apps/Music 7ad96b6e9cf7572d3dc0a4fff9c0c9ef783b958d
+platform/packages/apps/MusicFX 08c88f68febf296c3cc2b89f524d4085dcc1bea1
+platform/packages/apps/Nfc 0d6451ad527be2931e9440ee1ca9b5eaf8900cd4
+platform/packages/apps/OneTimeInitializer 726476de1f465bcb4ec386b3b5a49261d5b8623d
+platform/packages/apps/PackageInstaller 9818b8be97f4002127179d1fd5f6a61966ddc027
+platform/packages/apps/PhoneCommon b898d0ed986cba10f593b649553f14093fc3e6ae
+platform/packages/apps/Protips aa9c6c1d3257d2b6d7ae6d0e8eaa69822ce0ba55
+platform/packages/apps/Provision b9437291f8fc918859a5195c78104b38ed6d49f3
+platform/packages/apps/QuickSearchBox 054b118c4893818a014cad4cf28d1b69f0c7e9b6
+platform/packages/apps/SafetyRegulatoryInfo ec05df81c739aa4752fff40ad21b3b2c34146daf
+platform/packages/apps/SecureElement 8a359559a0a1d44582bcfa2ab39f899e3f1f8874
+platform/packages/apps/Settings 626cd4448d24f395126a637e3a61058f96f8c698
+platform/packages/apps/SettingsIntelligence 312c7e60f9edbdda34b7648e70669be0c97b6e4b
+platform/packages/apps/SoundRecorder b72758c03a4d5ffbf9cc6e8409108111936c54e6
+platform/packages/apps/SpareParts b4a5cf67d0d90f14ae3ef2d0f88359aa7b0b32af
+platform/packages/apps/Stk 42237c4d97b74cca6410bb13bd0f7d1c6c97acbf
+platform/packages/apps/StorageManager afc069cb3d4ce48a2fa5bdee0b5b8c50b9a46791
+platform/packages/apps/TV 01c5fead6636e3e2ed654c297835be6f14ca09ee
+platform/packages/apps/Tag bf2b0b347ee4c2b6b67f68ceae318f332e848d9c
+platform/packages/apps/Terminal 74180be6cd21f3612d553d17461ffeb13e39c3e5
+platform/packages/apps/Test/connectivity b959b99372a74303edbf2a79d8c9aaaa75aab565
+platform/packages/apps/TimeZoneData d0b25661bfeb1ebbcb742440f6a0fad3f78cb5bb
+platform/packages/apps/TimeZoneUpdater 61da0e20e02e1d9542442127c10351e50a2f4ee8
+platform/packages/apps/Traceur 0f575f5a003923207e3e45b4c23b5cf16551ff50
+platform/packages/apps/TvSettings 00bbfa455a39247c622ba1f2cc0afb1eb953d66a
+platform/packages/apps/UnifiedEmail 651da7193b894f802deb39eab9edd2484eb39ef9
+platform/packages/apps/WallpaperPicker 9f7cb2fcff7c7721486e46aada59fecab9468059
+platform/packages/inputmethods/LatinIME 4475c4b338c65a3972c1a99536e97268509a1295
+platform/packages/modules/CaptivePortalLogin f59697441e74e3efd4aea935ccea563e4322d9cc
+platform/packages/modules/DnsResolver 3b6b92e63cc6a9c53c27d8c71382d2016162a11b
+platform/packages/modules/ExtServices 4728c14aeeaf5ef186758f62c430fe97827e40a0
+platform/packages/modules/ModuleMetadata 1c65c5b782125e20214fa888b919633b8b2ba380
+platform/packages/modules/NetworkPermissionConfig 8b88f9e84b9ab1d00ca98fb84327286873b1f19b
+platform/packages/modules/NetworkStack d34a81d78c418141c59b1f9b9fa6f6902dfa1969
 platform/packages/providers/ApplicationsProvider 33d26f5eedb3d3011762ce5b2de66e931bf64b35
-platform/packages/providers/BlockedNumberProvider 3f0b89985313d4e2ea4a3aff1b2146543f7191e1
-platform/packages/providers/BookmarkProvider 1e1b0fc17395167f3523633992827355968089e2
-platform/packages/providers/CalendarProvider abe740b6ee4849c2e62bcb803bc378d1a8103849
-platform/packages/providers/CallLogProvider baf1738747e5db125b0e3c8bf43c3101f80b5e25
-platform/packages/providers/ContactsProvider 559ec507e5f9ca3b14f2f7f3264570e25afcc01d
-platform/packages/providers/DownloadProvider 1c70b40dcd0bd08d418444a4ade08712def18abb
-platform/packages/providers/MediaProvider cbca3ba6ddcd9d693aa077251a683d4092a56c06
-platform/packages/providers/PartnerBookmarksProvider b8231336ae1fad7456714d510805eee94618b870
-platform/packages/providers/TelephonyProvider 5a5c2062f07556672d82b26e51575a95f3f143d4
-platform/packages/providers/TvProvider 942c5cf4cf477fe420fb278ec6df329311f06d56
-platform/packages/providers/UserDictionaryProvider 3ff9892780dfdd640760f69f63afe93e54ea2a5b
-platform/packages/screensavers/Basic aa20e8cc0f2fa5163231d087249ec83c4d71d07b
-platform/packages/screensavers/PhotoTable e772d7913b544c17465004115a467d083502d90f
-platform/packages/screensavers/WebView adf97342507b5495ad8bda4bc5a614ee093fbcff
-platform/packages/services/AlternativeNetworkAccess cee9fe96babf86570737b93e3ef47b6f7595051f
-platform/packages/services/BuiltInPrintService f273e0b9438c407f3517eecc1702d3639e5c8257
-platform/packages/services/Car 45e78cc5ee776b4b7d5e11dbffcdb2e35e7e0052
-platform/packages/services/Mms bf5d23fe7761ddc85b4d6ff8ee497c3bf83a1902
-platform/packages/services/NetworkRecommendation 228fddfc05a2cf055cfa1b0e5109e274f4e9a45f
-platform/packages/services/Telecomm 5a2f6feb2120bb44c083ab23b2acb139bca8bf66
-platform/packages/services/Telephony 4549a2a1dc02296fbc62343f192ff296a2e0b77d
-platform/packages/wallpapers/LivePicker c2d4abae315e42682688c00a3682dee68cecb556
-platform/pdk f33e0cd09e0dafd3de4231e8d0cc0dd691ce74d5
-platform/platform_testing d54f75d7dc5ab76b0f90e4ca79d94bbaf17a51d8
-platform/prebuilts/abi-dumps/ndk df54099ecaabf8f5e83f4e26d7ea18272c94b858
-platform/prebuilts/abi-dumps/vndk 6be6043b6163b3ad1219415823e925d7d8484217
-platform/prebuilts/android-emulator 03846ab903c56c79627a018d50bcc7c1407b7d4b
-platform/prebuilts/asuite 9875a67160161bc346ec72d8a8cfeaa07bfd5fdc
-platform/prebuilts/build-tools 7c0bd26ce3a2bb942c9c362326d581f89388b52e
-platform/prebuilts/bundletool 0cbef871dc39431ab74751483b7ebdf7edef8c36
-platform/prebuilts/checkcolor 88b97e1c98e415eace295a83cb2f3a99d94f2e86
-platform/prebuilts/checkstyle 1dab275b13943d7405852e69d19a45eb898d748c
-platform/prebuilts/clang-tools 23d14a64124a6f8464abb0315d6855d6310eede0
-platform/prebuilts/clang/host/darwin-x86 6b87f84771806daa8af74e3e0de213325621b056
-platform/prebuilts/clang/host/linux-x86 f95f58c3918c24322e3f301df953404ed8ffcc57
-platform/prebuilts/deqp e6f7e4caa419b9d25f3949b398206192d6c88219
-platform/prebuilts/devtools df0a7e9db2661694cb165c6ce1de2bfda3751908
-platform/prebuilts/fuchsia_sdk 851c5f69dd1cb66084a9617320da8e43c88c8a03
-platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9 f336828e13733256fdedb7c90df92033ba00588c
-platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9 84d62c6d15fb93917a2022d790176eed9cd721e3
+platform/packages/providers/BlockedNumberProvider 85bfaf2df50994d2cb862365b0b95195b5846b70
+platform/packages/providers/BookmarkProvider cba6b949f94a89471b6c98ac993798cf16bc40df
+platform/packages/providers/CalendarProvider be73cde5f818dce4779e43306b7544c0d721a2e5
+platform/packages/providers/CallLogProvider d4705c37a2cf8e903839170ee23c8df4457e7511
+platform/packages/providers/ContactsProvider dc9ee164743dbc882d2b8f4badeb0c4a303bd689
+platform/packages/providers/DownloadProvider 7bf82ed160212865e9055bd245fb0ee93589846b
+platform/packages/providers/MediaProvider 2da9b38159028f54d48e8e9a64d5a909783264ab
+platform/packages/providers/PartnerBookmarksProvider c710222f6ed3e3ec0739b0a9901cac7c7191df95
+platform/packages/providers/TelephonyProvider b303b2a76fa84583df2a855f10f33548cf8c9e90
+platform/packages/providers/TvProvider 30f54ea12762efd348189a3b54a0944d143379fe
+platform/packages/providers/UserDictionaryProvider 4625268eabe48f4df112f8bfeab0205c912c0825
+platform/packages/screensavers/Basic 3d7ebbf72aa91289e06e8a0921195eb15d9feedb
+platform/packages/screensavers/PhotoTable cd9b393fbfa9497e7c48a2098f89c8b96f18fbc7
+platform/packages/screensavers/WebView 316f1801d1e96d3e6d845db8da0ddf4b5703a50f
+platform/packages/services/AlternativeNetworkAccess 09b672b56616dce149bddb40d46aa507d678d220
+platform/packages/services/BuiltInPrintService 357e87fe4298f730a76c613d30130d246f399512
+platform/packages/services/Car 7f8ca1a91354ce7743786ed9536930fc7a3336cc
+platform/packages/services/Mms ba46a37457f641605df6dea5ca7a7e221ad44de8
+platform/packages/services/NetworkRecommendation ed682d71476263ac159911f5a371792adbb6977f
+platform/packages/services/Telecomm f5bb24aed2f698e4a6e2d17945a48428c4cc62dc
+platform/packages/services/Telephony 2e132abd4a76f7560348724494d7c140094dc147
+platform/packages/wallpapers/LivePicker 156bf2d82d1395e703633682389038a9a03ffdbc
+platform/pdk 3ab55d12375a929ffddbafb1473306235ee9afeb
+platform/platform_testing 89eab77a606e05dda25d98f3c75e9b13c05203c8
+platform/prebuilts/abi-dumps/ndk defffdac605433940ad70a5a199c35afc5995329
+platform/prebuilts/abi-dumps/platform 8051225355fef89762657071cb1610a816732de6
+platform/prebuilts/abi-dumps/vndk 04a2482b0661276d994576ebfaac6a9405548148
+platform/prebuilts/android-emulator 8e4032a7a3b77eb8002f1bc32a9144db05218f19
+platform/prebuilts/asuite aa3b22ec2e69a7f93a99476355631e70d1bc493c
+platform/prebuilts/build-tools 9bca2f4ad4b1821aa7c806f80752c2238960ad0c
+platform/prebuilts/bundletool 7d11788eb685c32f83defa62911b5130d243cc3e
+platform/prebuilts/checkcolor b4c98ed89a37499fa580445eab40a5efc77519b6
+platform/prebuilts/checkstyle b86c2b048b0f203ed8097cb30984570b4c31bf3f
+platform/prebuilts/clang-tools 3712a590edc7a2db67dba0b7e386f2e91cea7641
+platform/prebuilts/clang/host/darwin-x86 9388fc62aa3aa8e06b24c9e42a79b1593c6bdbf0
+platform/prebuilts/clang/host/linux-x86 465a76cd6608f4487d1750a474011052d6901e3d
+platform/prebuilts/deqp 55e2964c213ead822f8c840043415aec702e850c
+platform/prebuilts/devtools f1016ef790704553d03b3257f98955d5d9d37e5b
+platform/prebuilts/fuchsia_sdk e901948f06e27d938616ddc4a51a21a874d5b6c3
+platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9 f26ca76e4211874c8515c00369bccbaad9f599ce
+platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9 07b25a5af3a236640fa49f78fc61a173ed466420
 platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1 ec5aa66aaa4964c27564d0ec84dc1f18a2d72b7e
-platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9 d942564c9331f07026a8f78502d8571206eb7be4
-platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9 83acd7f249e652577b7fa3343e34fa5779b8f7c1
-platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 945630363f964b219c4b211bb635b61cc8547fc7
-platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9 5ad396f589bff4d4152bf95da7cfe2dfbb5addde
-platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8 5a7800f07447759cb2ce5d529d71e2eff6e6359a
-platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8 e64376b5c37d65e863a8057786142c1db6e9d3e7
-platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9 388fdc4995d374d76a0c4b292afabac91638e134
-platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9 df26981b1d00d4dd0cf35ed1d96344cf1dfb05b5
+platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9 57b865c1eed539ed0f956193796d87d1262fb29e
+platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9 7d9b053c69e2a965d9e6612cd24d451ab5baba18
+platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 e5d6c65b2f10bc136c200db0a6b5bf8e90910df4
+platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9 d8488104d0245ebc827fb2786190d67804b67ac0
+platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8 ca46f736f03adfa62003cb94392ed05ec6d8cc3f
+platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8 56592a3d4f46552c7001e99e720c9db5be8521ec
+platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9 d394198a1a0931ed30be6a7ea121e993f002b826
+platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9 4f70d1f7e34d6ea7383265f56198c280a6e542d2
 platform/prebuilts/gdb/darwin-x86 0a8c90248264a8b26970b4473770bcc3df8515fe
 platform/prebuilts/gdb/linux-x86 4adfde8bc82dd39f59e0445588c3e599ada477d2
-platform/prebuilts/go/darwin-x86 28437c29d829b8c753e7128090faf134181fdf19
-platform/prebuilts/go/linux-x86 394b8054fe2c7c143d15dd3236159971402b5a21
-platform/prebuilts/gradle-plugin 2cee90708c952bc779b0c67a00e202c9ba910d14
-platform/prebuilts/jdk/jdk8 aaa1e4d6fea9f97b32fe1bd97615b65b1c661f6e
-platform/prebuilts/jdk/jdk9 60eae91c05b7e653029024fbd37f7994afcb4288
-platform/prebuilts/ktlint 6550cab4ef65480db60b7b0d9973a8f354b10cf8
-platform/prebuilts/libs/libedit d32685dba4011664b590b94ad156bc734c2c9bb5
-platform/prebuilts/maven_repo/android 18142ab0a35da3bfb47f5af8ebcd27e232e9de8a
-platform/prebuilts/maven_repo/bumptech 94f47f5fb0a81da9d88af7d44803ecc135e043de
+platform/prebuilts/go/darwin-x86 ea5410f2f771b57189b5c1c3d092987f20795469
+platform/prebuilts/go/linux-x86 49819272adea34367b1feb7aee2b05598ad1671b
+platform/prebuilts/gradle-plugin 0dee4183b424858eb3bdd122867c12a5e8171645
+platform/prebuilts/jdk/jdk8 6941b9ea21ba32e52cca63fd71a92682fda07da8
+platform/prebuilts/jdk/jdk9 4d888dccbd817be9cf92f9edee09487fddf82fcb
+platform/prebuilts/ktlint 782b0efc4c90b86c1d9d456fafd3884149d954de
+platform/prebuilts/manifest-merger 8fdc0943f448fd67d746dcdbaf070d493908c134
+platform/prebuilts/maven_repo/android 000a58783687489ebbe5c55b95987f900395c60d
+platform/prebuilts/maven_repo/bumptech ab84bbd44dc2d3a38e7a77dd261d52ee9ea720f3
 platform/prebuilts/maven_repo/google-play-service-client-libraries-3p 427e6e2267fd43142ddbd1a87268e0112ddb9b11
-platform/prebuilts/misc c81ccfd6e9c0074ebd8b6cfee4b9f04390088a86
-platform/prebuilts/ndk da199e209925ed87d7f74be344e7b9922518b5ec
+platform/prebuilts/misc 227d8303ec28cee6563308500d902d4c5e3e8473
+platform/prebuilts/ndk 433d07f1026b7faa43a044d00f6bf21d7093bf5f
 platform/prebuilts/python/darwin-x86/2.7.5 0c5958b1636c47ed7c284f859c8e805fd06a0e63
-platform/prebuilts/python/linux-x86/2.7.5 cd921918ba92750211cdf505934df24ac6330245
-platform/prebuilts/qemu-kernel 63f888a1eb523bcac6b977ca15079e7a1b0757ed
-platform/prebuilts/r8 cce55572cba87ffec19be82895088cc4edaef250
-platform/prebuilts/sdk 663c43c5d8199f5407ed74a65d7fe12fe5f13df8
-platform/prebuilts/tools de0f0634c0cedc1cdc54b7a332d71fa6aafbd672
-platform/prebuilts/vndk/v27 bb116c61795f2ad2546c651628114bc9a0dc444e
-platform/prebuilts/vndk/v28 97bf66825a00bc3824fee030ca9ce93d6a886a80
-platform/sdk 1fc951b21c7c69764512ac32cd5b63a0c828b3e1
-platform/system/apex 21f3d9456976750de905a84df8a9d0774822bdb0
-platform/system/bpf fc3c7690fe6fb6777f6891e38eff55936a67665e
-platform/system/bpfprogs c5c05168c8831be3f6e6e10fd7586e703961f743
-platform/system/bt cab1ae11273e77feaadfde1e267da6c6d35a0900
-platform/system/ca-certificates baba0e07ebaf1c398cf8be48732e2d4e8b1915b8
-platform/system/chre 93b32e1c4ffa04711aad62afd9970359e107ba86
-platform/system/connectivity/wificond a83c257886ba13733f8c7814c295d73aad347fcb
-platform/system/connectivity/wifilogd b7037ae1b3bb92eee26376ed532c1b3e9adeff62
-platform/system/core 9a7a50aea0dfcb1a8c305f0b79e9a24d260db341
-platform/system/extras f8a943e3eec69d6238087b33ee8a6d051a4d21d5
-platform/system/gatekeeper 27748e24c1a1fbfb2919817333b6270ace62c16c
-platform/system/hardware/interfaces ba81fb29c4998647baf5fe0fa313a14d87b92eff
-platform/system/hwservicemanager 98db82953ecb61da7af890d3c8be215f41ae2e76
-platform/system/iorap 45229e411c27086b86787ff7aed2cd6828cd67a6
-platform/system/iot/attestation 4deae63f83ceea3353de18f2eda838fe4c828f30
-platform/system/keymaster bf1f16488d48634c5c9c6a9611ae1a409da53c93
-platform/system/libfmq 2cc8215a91173f11d4a97caef10b7b87aede5a98
-platform/system/libhidl ace631e16ab357e2628a54a7f8e4ba928f403777
-platform/system/libhwbinder e86755279b0616efa456599d8cd36b5f25d4df58
-platform/system/libsysprop 09332c2c14bbc14c51b5d88e022e53d9c0956529
-platform/system/libufdt f8f692c41cf84097412c22ea4820b3a11f81facc
-platform/system/libvintf f90ced7cce149b9f3e1137331e54359ad31f156b
-platform/system/media f68c60e2fa9c11ef1ee0ad1a026069197657efcd
-platform/system/netd e9c28e285f774efbb1241d15461a23727cf1ddd5
-platform/system/nfc fbec917983e05890a5fe46db1a7d7ee339d755e5
-platform/system/nvram 68f2afb006f2f1fe3743fffb2d43429bd7cbf238
-platform/system/security 6df27abdd0a932e21743054e0c7f1a2c70306bc7
-platform/system/sepolicy c2dbce06042133115e81377ac03fe211c9798b90
-platform/system/server_configurable_flags 0e3cf28b5b49679c49ae62ccc1bb816ae68334c8
-platform/system/testing/gtest_extras 237a0d91a5eed398b149b141159442f775c3d585
-platform/system/timezone 3160f43cb87f88cce38a8f29ce861aab85872468
-platform/system/tools/aidl f04d102e7220bc934dcd0d88c06c942580739998
-platform/system/tools/hidl fa333e774676692c43e96872473d51eeae6b3643
-platform/system/tools/sysprop b04d6197a74376e0bb1df5f5b5be92434ee43b1d
-platform/system/tools/xsdc effc699a0d56b52630c4bb98fc7d8443bc1279ec
-platform/system/ucontainer 86e2b4a784ab4e3b1b47517e1b45068e2751cdfa
-platform/system/update_engine 7328c9ffbcd628c339763d7b0dfd8f093920f518
-platform/system/vold 7adca74263e89d770e88cbc02b988beb99f2466b
-platform/test/framework 95997123038877a3933088aad124ad3dcd31bf18
-platform/test/mlts/benchmark ab62f602602b15d8e26353c82b492248f80e7d49
-platform/test/mlts/models b9608fe7263b91922e7e59fc0cfb0f5ac8a1a6b5
-platform/test/suite_harness 65f28a960738eeba95678963810a6ce3f3f56fae
+platform/prebuilts/python/linux-x86/2.7.5 fecb994c924df1aa7b6b06a51244dec1a5c073bd
+platform/prebuilts/qemu-kernel d34a2470ddc90651cc122c5a114d6aa2475235d0
+platform/prebuilts/r8 71b93828fc0a565ff1e5abcac14d49267bac612f
+platform/prebuilts/rust f7957e3231741d34945dc32791330d851f125ba8
+platform/prebuilts/sdk 7983b898fdf6f7e237d38fbcab60a6984e68aab1
+platform/prebuilts/tools 7e8db8b03dd9431a772b83f008d430f20aa31791
+platform/prebuilts/vndk/v27 2dca685a814ad0612343e31899f8b0ed2979d368
+platform/prebuilts/vndk/v28 3b3f358afaab5b4f635c57e841a49362c887398d
+platform/sdk c824a682897ace6bf4aaea2cb307ee11512b6397
+platform/system/apex e207cf6a164e3c72f8f20789b9fd345fa234753f
+platform/system/ashmemd a1c08fe13abe1ef1dcbed1a511f80600b4b7aad6
+platform/system/bpf 6524dececc60e663d7e290a81a9cbfaf4d5e8229
+platform/system/bpfprogs 7235e6e0f3c1ff780b01dd1d5d16aaea229aaee3
+platform/system/bt 990b46431fb7584c2ef94f4e925e1834c9d2b1a4
+platform/system/ca-certificates 836ee091331429b635ee58f6e12d34009d791a31
+platform/system/chre 7fa22fbc859a3ca4a9fb62d5ea94cbe9092ce7cf
+platform/system/connectivity/wificond d70c3c3e0b9afb5756c83abeb17db4389fc9d1b4
+platform/system/connectivity/wifilogd 8b01effbf158c87658f602328098b90d73aefd29
+platform/system/core a48152fb7fc50ace2222bb6002af87d0d64e662d
+platform/system/extras cccdf456b7f71b60ec5d7bec7bef7a5afd87fdb7
+platform/system/gatekeeper 192791ddac79cf35802cdcfd3b42894ad1760ad1
+platform/system/gsid ada28a4131fc5bba6bb6e1e75683fce292a33509
+platform/system/hardware/interfaces fea698820faab6c0a2127902195f51b47b69b783
+platform/system/hwservicemanager ad53407384e2a37be6286550d524c84d83f52388
+platform/system/iorap 2abdd3a8feea09e85eed119cd8c2ea4f53ae89eb
+platform/system/iot/attestation 53d69f64a4b5a8f59f514b4c337120d466da1349
+platform/system/keymaster 88bc8c377fb8a49b694700338c5f2e25e2158017
+platform/system/libfmq c03ea993f99c8fe4061a7f34a0bcd77bb69a12c4
+platform/system/libhidl 2c8b6846f36a84b9a46f9c176d958bfaed9375d1
+platform/system/libhwbinder 9364d6fb2f23aec5f84c3004538e9432442a6601
+platform/system/libsysprop 9283de549e9f09efdf224efcfb902c9032e64115
+platform/system/libufdt 7bcbd103dbc181c0c6082fefea56b5b72e09eba5
+platform/system/libvintf dc9211b42f8f031896eb5e35792221c98e46c226
+platform/system/linkerconfig f234440c98413f4c9dc735479370bbab42256fb6
+platform/system/media e896be5c3044f95dd64782527817f63e89b52b14
+platform/system/netd 20698093e44399c0e29bc5edd33873ebb251dff5
+platform/system/nfc c5c79500d9913f5c1e83024d67ad2f581fd2fbd6
+platform/system/nvram b37dac1f2de4608273a5dca9374dbbe0b7bb3b3e
+platform/system/security 86a58e4b3d9aa50ffa4b7ab625d32b1a234f4791
+platform/system/sepolicy 29425e3a302da76e25bc40f571a13096eef0b5f5
+platform/system/server_configurable_flags 2f193c7b9c0637e207501ca8b988b71aba8e856b
+platform/system/testing/gtest_extras ce77e1b8a5287dceeeda63a2f8f39a5a9cc856e0
+platform/system/timezone 83a80921be18985b39a4a27760490ef9050594ea
+platform/system/tools/aidl 1779866855da57b87b33777f4c0cbf6b417d971b
+platform/system/tools/hidl 2c272ae5aba32e53257a4394e5d5f500e938ca90
+platform/system/tools/mkbootimg 983425fe948027f60562088f270a80abbfb1018c
+platform/system/tools/sysprop 2f106a08a362cb04696b253d157716ad8e194707
+platform/system/tools/xsdc aa117444efbeddc5fa844012ffb899d7a923a662
+platform/system/ucontainer 55034d4045848b3cdb7c4a55dce4b5e216cddece
+platform/system/update_engine cf31bac300bc1aa4afaeb0c4728322e93364e2d2
+platform/system/vold 3ca773734cdb8a13fbd566c6ee2c278b60a33e47
+platform/test/framework 97070b0b323bde4f988e92e1154d2e84ba56d8d9
+platform/test/mlts/benchmark b3abd7ddecf98162e70cbe77df501e2e7e79eeb1
+platform/test/mlts/models 6844b59d5be85e36e5fcbd48e71e4a7c0b494e92
+platform/test/mts 020d89993700ea6e0f106201bbbcee3fe3af9a23
+platform/test/suite_harness f3280c39473c456cf6f2a6d555dfe1f4442c3f21
 platform/test/vti/alert 2270d160e38f0623d708cce36754fe14168dce64
-platform/test/vti/dashboard 31063431db0e84611c19f116a132eee9478ab9b5
-platform/test/vti/fuzz_test_serving e3773df668f1e06a54eda9cbc85e8fe95aad4af2
-platform/test/vti/test_serving cc1ed52758d6376de5d5563e1aa033f779502f69
-platform/test/vts 5a1a51e81bfac8f5d59da5b8c67fe826cd12ab62
-platform/test/vts-testcase/fuzz 97e4d305f9adcd82606749778fab889bc08208f4
-platform/test/vts-testcase/hal 676b4245bd16466230fe879929856e67e6b6c5f1
-platform/test/vts-testcase/hal-trace eb2ae993acc179013c8f52e6e39b7f6743e5b913
-platform/test/vts-testcase/kernel b3aff2cd754b03ce424055b2c3e51904e28e71bc
-platform/test/vts-testcase/nbu 7330df16d16dc980368af9e92c74de39bc8d5b8e
-platform/test/vts-testcase/performance 3aa2f08db11c602336154b646cdb3ff7068509c9
-platform/test/vts-testcase/security 36ecb76e7bc3ae8e2f55ba64f58fa9031c21a805
-platform/test/vts-testcase/vndk 7eb5ab3df5f31f005339f3bddaf4420e1632e8d9
-platform/tools/acloud 0a33a0762b8fdb968d21136e654183c132c0a97b
-platform/tools/adt/idea 1af0217323d9728d640eef43b3810c94f216e2f2
-platform/tools/apksig b510ca8c8ebd80ad0b823d38a32dc6445b083137
-platform/tools/apkzlib 29560e9fa98bbaa9d15520b1ec82ac09b30a1a5a
-platform/tools/asuite ebc49bc340374d6982f28e4fd5c0a51e58999894
-platform/tools/base 908b391a9c006af569dfaff08b37f8fdd6c4da89
-platform/tools/build 69c4b95102b4b9862bfba68b3eaf5b7537a705ee
-platform/tools/dexter 940c6774954dc34c34eaa85ca679a3772e73df1d
-platform/tools/external/fat32lib 445d40e55cbb432b5682a0df54e42b3d5285d57f
-platform/tools/external/gradle da1f8b241419474abd524910f457accf03218638
-platform/tools/external_updater 0f6b93dc282a0cbaf1c718b465717b67dd6f4556
+platform/test/vti/dashboard c3bfb1843a13e91fb74274c69072479e26be6a06
+platform/test/vti/fuzz_test_serving 6cf519a82baf307c8259f50acadd4b324b61425a
+platform/test/vti/test_serving 0c50f138e4cfbddb371adf2753227945144e00c8
+platform/test/vts 4c9453516bff9d362e13b04ed0db313cba1e674a
+platform/test/vts-testcase/fuzz 0894d765f639cfa68f925e45dae8a20ef4cbf70d
+platform/test/vts-testcase/hal d9d2bfa18bbe5c7c4a7392df34cf513527022ee2
+platform/test/vts-testcase/hal-trace b0183bd30a4fb5f838844f2b499809cd7b2dfe4b
+platform/test/vts-testcase/kernel e67601633867a269a2300a7b00a944e1b998ade5
+platform/test/vts-testcase/nbu 885545b381193c920be85fdf926607bff8d7b9d0
+platform/test/vts-testcase/performance 1fd8b9e1dc0319045ba53467b7a14359aa78dad3
+platform/test/vts-testcase/security ece818d67cb41740d3c30e6ecc6df8bcff4f9b3a
+platform/test/vts-testcase/vndk 8f05128127f3c3635ea3d3651de6423210048746
+platform/tools/acloud db865ba583a1f5c9ae070672860f0cff6c6c9b57
+platform/tools/adt/idea f32ccd8eb5775bdcf297aee84185440d35a2de41
+platform/tools/apksig de484cde6316107c9d6e76114836aa73efe1cf62
+platform/tools/apkzlib 56017e1e41731c127adfe73c6623c9051522e965
+platform/tools/asuite 1dc6870f1dc1123909e35121f2806768aa343935
+platform/tools/base dd1b8ee994421118019d6faabb4faa1eac88a59a
+platform/tools/build ea1d4adbbca405f8e12b91da9d9c7b261f562850
+platform/tools/currysrc b110cfcaa90c12810192f13108eb7ab942e81fdf
+platform/tools/dexter 8061b0722a7f8f2f41c46399456ea7260efc060a
+platform/tools/doc_generation 8f5ef51bfd1111ac29bab1fdf7bacb7ca6b03c7e
+platform/tools/external/fat32lib bfb20bd14658e50514b75da2c104ce0219928f68
+platform/tools/external/gradle a8873f98c59793cddd76755cebcef69f41778af9
+platform/tools/external_updater bc89ef9ab0ff4c93f8492cf5657e1c83ac486cfb
 platform/tools/idea 9b5d02ac8c92b1e71523cc15cb3d168d57fbd898
-platform/tools/loganalysis 4110660dc04cbb60a2f1339d2c03551c4210e4af
-platform/tools/metalava d89a15df3583273bccc43fceb35f307db17e0268
+platform/tools/loganalysis 2bbca3fbf4179f7dfb3381fb78ff04bcb3b345a2
+platform/tools/metalava 39a7a6c619b9eb58abeb9570d07ec2b8795a0a8b
 platform/tools/motodev 69989786cefbde82527960a1e100ec9afba46a98
 platform/tools/ndkports 74fefbc2160250129cbd157272fcfb3c9ac20f18
-platform/tools/repohooks ea3ae03ec941f2088543d49232a5f61bd294a741
-platform/tools/security fdda0f4c20431c4b40372e2a0080017f50f55218
+platform/tools/repohooks 7daa42dc56d8c158aae1361cce676e771382c362
+platform/tools/security 96eee30239573c26a41485b04e3499308e9b1478
 platform/tools/studio/cloud 58f06e77e051fff3903adabca7acdaa9dd12ec2d
 platform/tools/swt 8996e71047a2bd11efee46ef14e02435ab5fa07a
-platform/tools/test/connectivity 6b202c32f80160c4f2f9bc5b3b1e65db3ddbb4b4
-platform/tools/test/graphicsbenchmark 5dae30020d4036d4594172435d980941e433e1f9
-platform/tools/tradefederation 22d1e65e813a3830386e69a0c0ee690c1c88fabe
-platform/tools/tradefederation/contrib 6c84ad0b947e5f5339215f715d06cdca6288ed66
-platform/tools/trebuchet a85ff396e963e7afd544e6b053581541a5e7d23d
-toolchain/benchmark 00d3d7ee381092ff054a4d0fbb8aa36123c39038
-toolchain/pgo-profiles a7d38cd0a179be5053bc3e66955e99f0c724f9b0
+platform/tools/test/connectivity be6d1974af85abacb5595ddb00f7ea23e111f2e8
+platform/tools/test/graphicsbenchmark 5d0d75a89e31644dcc095a5e26ece29c6cfaed1d
+platform/tools/tradefederation ce8910f2479e980e623c78d91c54c9f1c746edde
+platform/tools/tradefederation/contrib 72e15ad1b660df97ce7cf191e05c04c154303283
+platform/tools/trebuchet a83b5dec9c2e6b4cca66091a355cc90c284f3d30
+toolchain/benchmark 268e4ff60085cbcca2c2f1c074386307711d4f44
+toolchain/pgo-profiles 93712411a89f63bc3413f3139a30a348ab66075b
+tools/platform-compat fdee6c55cbb28ec8fbd7fb8e6c5ad8bd12d1190a
diff --git a/report_html.py b/report_html.py
index 1a616fb..f229272 100755
--- a/report_html.py
+++ b/report_html.py
@@ -127,6 +127,20 @@
                              for thread in threads]
         return result
 
+    def merge_by_thread_name(self, process):
+        self.event_count += process.event_count
+        thread_list = list(self.threads.values()) + list(process.threads.values())
+        new_threads = {}  # map from thread name to ThreadScope
+        for thread in thread_list:
+            cur_thread = new_threads.get(thread.name)
+            if cur_thread is None:
+                new_threads[thread.name] = thread
+            else:
+                cur_thread.merge(thread)
+        self.threads = {}
+        for thread in new_threads.values():
+            self.threads[thread.tid] = thread
+
 
 class ThreadScope(object):
 
@@ -200,6 +214,18 @@
         result['rg'] = self.reverse_call_graph.gen_sample_info()
         return result
 
+    def merge(self, thread):
+        self.event_count += thread.event_count
+        self.sample_count += thread.sample_count
+        for lib_id, lib in thread.libs.items():
+            cur_lib = self.libs.get(lib_id)
+            if cur_lib is None:
+                self.libs[lib_id] = lib
+            else:
+                cur_lib.merge(lib)
+        self.call_graph.merge(thread.call_graph)
+        self.reverse_call_graph.merge(thread.reverse_call_graph)
+
 
 class LibScope(object):
 
@@ -222,6 +248,15 @@
                                for func in self.functions.values()]
         return result
 
+    def merge(self, lib):
+        self.event_count += lib.event_count
+        for func_id, function in lib.functions.items():
+            cur_function = self.functions.get(func_id)
+            if cur_function is None:
+                self.functions[func_id] = function
+            else:
+                cur_function.merge(function)
+
 
 class FunctionScope(object):
 
@@ -274,6 +309,28 @@
             result['a'] = items
         return result
 
+    def merge(self, function):
+        self.sample_count += function.sample_count
+        self.event_count += function.event_count
+        self.subtree_event_count += function.subtree_event_count
+        self.addr_hit_map = self.__merge_hit_map(self.addr_hit_map, function.addr_hit_map)
+        self.line_hit_map = self.__merge_hit_map(self.line_hit_map, function.line_hit_map)
+
+    @staticmethod
+    def __merge_hit_map(map1, map2):
+        if not map1:
+            return map2
+        if not map2:
+            return map1
+        for key, value2 in map2.items():
+            value1 = map1.get(key)
+            if value1 is None:
+                map1[key] = value2
+            else:
+                value1[0] += value2[0]
+                value1[1] += value2[1]
+        return map1
+
 
 class CallNode(object):
 
@@ -315,6 +372,16 @@
         result['c'] = [child.gen_sample_info() for child in self.children.values()]
         return result
 
+    def merge(self, node):
+        self.event_count += node.event_count
+        self.subtree_event_count += node.subtree_event_count
+        for key, child in node.children.items():
+            cur_child = self.children.get(key)
+            if cur_child is None:
+                self.children[key] = child
+            else:
+                cur_child.merge(child)
+
 
 class LibSet(object):
     """ Collection of shared libraries used in perf.data. """
@@ -558,10 +625,24 @@
             for thread in event.threads:
                 thread.update_subtree_event_count()
 
+    def aggregate_by_thread_name(self):
+        for event in self.events.values():
+            new_processes = {}  # from process name to ProcessScope
+            for process in event.processes.values():
+                cur_process = new_processes.get(process.name)
+                if cur_process is None:
+                    new_processes[process.name] = process
+                else:
+                    cur_process.merge_by_thread_name(process)
+            event.processes = {}
+            for process in new_processes.values():
+                event.processes[process.pid] = process
+
     def limit_percents(self, min_func_percent, min_callchain_percent):
         hit_func_ids = set()
         for event in self.events.values():
             min_limit = event.event_count * min_func_percent * 0.01
+            to_del_processes = []
             for process in event.processes.values():
                 to_del_threads = []
                 for thread in process.threads.values():
@@ -571,6 +652,10 @@
                         thread.limit_percents(min_limit, min_callchain_percent, hit_func_ids)
                 for thread in to_del_threads:
                     del process.threads[thread]
+                if not process.threads:
+                    to_del_processes.append(process.pid)
+            for process in to_del_processes:
+                del event.processes[process]
         self.functions.trim_functions(hit_func_ids)
 
     def _get_event(self, event_name):
@@ -833,6 +918,9 @@
     parser.add_argument('--no_browser', action='store_true', help="Don't open report in browser.")
     parser.add_argument('--show_art_frames', action='store_true',
                         help='Show frames of internal methods in the ART Java interpreter.')
+    parser.add_argument('--aggregate-by-thread-name', action='store_true', help="""aggregate
+                        samples by thread name instead of thread id. This is useful for
+                        showing multiple perf.data generated for the same app.""")
     args = parser.parse_args()
 
     # 1. Process args.
@@ -854,6 +942,8 @@
     record_data = RecordData(binary_cache_path, ndk_path, build_addr_hit_map)
     for record_file in args.record_file:
         record_data.load_record_file(record_file, args.show_art_frames)
+    if args.aggregate_by_thread_name:
+        record_data.aggregate_by_thread_name()
     record_data.limit_percents(args.min_func_percent, args.min_callchain_percent)
 
     def filter_lib(lib_name):
diff --git a/report_sample.py b/report_sample.py
index bbe9008..31a280f 100755
--- a/report_sample.py
+++ b/report_sample.py
@@ -46,9 +46,9 @@
 
         sec = sample.time / 1000000000
         usec = (sample.time - sec * 1000000000) / 1000
-        print('%s\t%d [%03d] %d.%d:\t\t%d %s:' % (sample.thread_comm,
-                                                  sample.tid, sample.cpu, sec,
-                                                  usec, sample.period, event.name))
+        print('%s\t%d [%03d] %d.%06d:\t\t%d %s:' % (sample.thread_comm,
+                                                    sample.tid, sample.cpu, sec,
+                                                    usec, sample.period, event.name))
         print('%16x\t%s (%s)' % (sample.ip, symbol.symbol_name, symbol.dso_name))
         for i in range(callchain.nr):
             entry = callchain.entries[i]
diff --git a/test.py b/test.py
index a3ef42f..e24f58f 100755
--- a/test.py
+++ b/test.py
@@ -36,9 +36,11 @@
 """
 from __future__ import print_function
 import argparse
+import collections
 import filecmp
 import fnmatch
 import inspect
+import json
 import os
 import re
 import shutil
@@ -54,7 +56,8 @@
 from simpleperf_report_lib import ReportLib
 from utils import log_exit, log_info, log_fatal
 from utils import AdbHelper, Addr2Nearestline, bytes_to_str, find_tool_path, get_script_dir
-from utils import is_python3, is_windows, Objdump, ReadElf, remove, SourceFileSearcher
+from utils import is_elf_file, is_python3, is_windows, Objdump, ReadElf, remove, SourceFileSearcher
+from utils import str_to_bytes
 
 try:
     # pylint: disable=unused-import
@@ -123,6 +126,21 @@
             return output_data
         return ''
 
+    def check_strings_in_file(self, filename, strings):
+        self.check_exist(filename=filename)
+        with open(filename, 'r') as fh:
+            self.check_strings_in_content(fh.read(), strings)
+
+    def check_exist(self, filename=None, dirname=None):
+        if filename:
+            self.assertTrue(os.path.isfile(filename), filename)
+        if dirname:
+            self.assertTrue(os.path.isdir(dirname), dirname)
+
+    def check_strings_in_content(self, content, strings):
+        for s in strings:
+            self.assertNotEqual(content.find(s), -1, "s: %s, content: %s" % (s, content))
+
 
 class TestExampleBase(TestBase):
     @classmethod
@@ -208,12 +226,6 @@
         if build_binary_cache:
             self.check_exist(dirname="binary_cache")
 
-    def check_exist(self, filename=None, dirname=None):
-        if filename:
-            self.assertTrue(os.path.isfile(filename), filename)
-        if dirname:
-            self.assertTrue(os.path.isdir(dirname), dirname)
-
     def check_file_under_dir(self, dirname, filename):
         self.check_exist(dirname=dirname)
         for _, _, files in os.walk(dirname):
@@ -222,16 +234,6 @@
                     return
         self.fail("Failed to call check_file_under_dir(dir=%s, file=%s)" % (dirname, filename))
 
-
-    def check_strings_in_file(self, filename, strings):
-        self.check_exist(filename=filename)
-        with open(filename, 'r') as fh:
-            self.check_strings_in_content(fh.read(), strings)
-
-    def check_strings_in_content(self, content, strings):
-        for s in strings:
-            self.assertNotEqual(content.find(s), -1, "s: %s, content: %s" % (s, content))
-
     def check_annotation_summary(self, summary_file, check_entries):
         """ check_entries is a list of (name, accumulated_period, period).
             This function checks for each entry, if the line containing [name]
@@ -648,7 +650,6 @@
         self.run_cmd(["report.py", "-g", "--comms", "BusyThread", "-o", "report.txt"])
         self.check_strings_in_file("report.txt", [
             "com.example.simpleperf.simpleperfexamplewithnative.MixActivity$1.run",
-            "com.example.simpleperf.simpleperfexamplewithnative.MixActivity.callFunction",
             "Java_com_example_simpleperf_simpleperfexamplewithnative_MixActivity_callFunction"])
         remove("annotated_files")
         self.run_cmd(["annotate.py", "-s", self.example_path, "--comm", "BusyThread"])
@@ -1187,17 +1188,31 @@
                         'simpleperf/simpleperfexampleofkotlin/MainActivity.kt'),
             searcher.get_real_path('MainActivity.kt'))
 
+    def test_is_elf_file(self):
+        self.assertTrue(is_elf_file(os.path.join(
+            'testdata', 'simpleperf_runtest_two_functions_arm')))
+        with open('not_elf', 'wb') as fh:
+            fh.write(b'\x90123')
+        try:
+            self.assertFalse(is_elf_file('not_elf'))
+        finally:
+            remove('not_elf')
+
 
 class TestNativeLibDownloader(unittest.TestCase):
-    def test_smoke(self):
-        adb = AdbHelper()
+    def setUp(self):
+        self.adb = AdbHelper()
+        self.adb.check_run(['shell', 'rm', '-rf', '/data/local/tmp/native_libs'])
 
+    def tearDown(self):
+        self.adb.check_run(['shell', 'rm', '-rf', '/data/local/tmp/native_libs'])
+
+    def test_smoke(self):
         def is_lib_on_device(path):
-            return adb.run(['shell', 'ls', path])
+            return self.adb.run(['shell', 'ls', path])
 
         # Sync all native libs on device.
-        adb.run(['shell', 'rm', '-rf', '/data/local/tmp/native_libs'])
-        downloader = NativeLibDownloader(None, 'arm64', adb)
+        downloader = NativeLibDownloader(None, 'arm64', self.adb)
         downloader.collect_native_libs_on_host(os.path.join(
             'testdata', 'SimpleperfExampleWithNative', 'app', 'build', 'intermediates', 'cmake',
             'profiling'))
@@ -1227,17 +1242,88 @@
                     self.assertTrue(build_id not in downloader.device_build_id_map)
                     self.assertFalse(is_lib_on_device(downloader.dir_on_device + name))
             if sync_count == 1:
-                adb.run(['pull', '/data/local/tmp/native_libs/build_id_list', 'build_id_list'])
+                self.adb.run(['pull', '/data/local/tmp/native_libs/build_id_list',
+                              'build_id_list'])
                 with open('build_id_list', 'rb') as fh:
                     self.assertEqual(bytes_to_str(fh.read()),
                                      '{}={}\n'.format(lib_list[0][0], lib_list[0][1].name))
                 remove('build_id_list')
-        adb.run(['shell', 'rm', '-rf', '/data/local/tmp/native_libs'])
+
+    def test_handle_wrong_build_id_list(self):
+        with open('build_id_list', 'wb') as fh:
+            fh.write(str_to_bytes('fake_build_id=binary_not_exist\n'))
+        self.adb.check_run(['shell', 'mkdir', '-p', '/data/local/tmp/native_libs'])
+        self.adb.check_run(['push', 'build_id_list', '/data/local/tmp/native_libs'])
+        remove('build_id_list')
+        downloader = NativeLibDownloader(None, 'arm64', self.adb)
+        downloader.collect_native_libs_on_device()
+        self.assertEqual(len(downloader.device_build_id_map), 0)
 
 
 class TestReportHtml(TestBase):
     def test_long_callchain(self):
-        self.run_cmd(['report_html.py', '-i', 'testdata/perf_with_long_callchain.data'])
+        self.run_cmd(['report_html.py', '-i',
+                      os.path.join('testdata', 'perf_with_long_callchain.data')])
+
+    def test_aggregated_by_thread_name(self):
+        # Calculate event_count for each thread name before aggregation.
+        event_count_for_thread_name = collections.defaultdict(lambda: 0)
+        # use "--min_func_percent 0" to avoid cutting any thread.
+        self.run_cmd(['report_html.py', '--min_func_percent', '0', '-i',
+                      os.path.join('testdata', 'aggregatable_perf1.data'),
+                      os.path.join('testdata', 'aggregatable_perf2.data')])
+        record_data = self._load_record_data_in_html('report.html')
+        event = record_data['sampleInfo'][0]
+        for process in event['processes']:
+            for thread in process['threads']:
+                thread_name = record_data['threadNames'][str(thread['tid'])]
+                event_count_for_thread_name[thread_name] += thread['eventCount']
+
+        # Check event count for each thread after aggregation.
+        self.run_cmd(['report_html.py', '--aggregate-by-thread-name',
+                      '--min_func_percent', '0', '-i',
+                      os.path.join('testdata', 'aggregatable_perf1.data'),
+                      os.path.join('testdata', 'aggregatable_perf2.data')])
+        record_data = self._load_record_data_in_html('report.html')
+        event = record_data['sampleInfo'][0]
+        hit_count = 0
+        for process in event['processes']:
+            for thread in process['threads']:
+                thread_name = record_data['threadNames'][str(thread['tid'])]
+                self.assertEqual(thread['eventCount'],
+                                 event_count_for_thread_name[thread_name])
+                hit_count += 1
+        self.assertEqual(hit_count, len(event_count_for_thread_name))
+
+    def test_no_empty_process(self):
+        """ Test not showing a process having no threads. """
+        perf_data = os.path.join('testdata', 'two_process_perf.data')
+        self.run_cmd(['report_html.py', '-i', perf_data])
+        record_data = self._load_record_data_in_html('report.html')
+        processes = record_data['sampleInfo'][0]['processes']
+        self.assertEqual(len(processes), 2)
+
+        # One process is removed because all its threads are removed for not
+        # reaching the min_func_percent limit.
+        self.run_cmd(['report_html.py', '-i', perf_data, '--min_func_percent', '20'])
+        record_data = self._load_record_data_in_html('report.html')
+        processes = record_data['sampleInfo'][0]['processes']
+        self.assertEqual(len(processes), 1)
+
+    def _load_record_data_in_html(self, html_file):
+        with open(html_file, 'r') as fh:
+            data = fh.read()
+        start_str = 'type="application/json"'
+        end_str = '</script>'
+        start_pos = data.find(start_str)
+        self.assertNotEqual(start_pos, -1)
+        start_pos = data.find('>', start_pos)
+        self.assertNotEqual(start_pos, -1)
+        start_pos += 1
+        end_pos = data.find(end_str, start_pos)
+        self.assertNotEqual(end_pos, -1)
+        json_data = data[start_pos:end_pos]
+        return json.loads(json_data)
 
 
 class TestBinaryCacheBuilder(TestBase):
@@ -1273,6 +1359,137 @@
         self.assertTrue(filecmp.cmp(target_file, source_file))
 
 
+class TestApiProfiler(TestBase):
+    def run_api_test(self, package_name, apk_name, expected_reports, min_android_version):
+        adb = AdbHelper()
+        if adb.get_android_version() < ord(min_android_version) - ord('L') + 5:
+            log_info('skip this test on Android < %s.' % min_android_version)
+            return
+        # step 1: Prepare profiling.
+        self.run_cmd(['api_profiler.py', 'prepare'])
+        # step 2: Install and run the app.
+        apk_path = os.path.join('testdata', apk_name)
+        adb.run(['uninstall', package_name])
+        adb.check_run(['install', '-t', apk_path])
+        adb.check_run(['shell', 'am', 'start', '-n', package_name + '/.MainActivity'])
+        # step 3: Wait until the app exits.
+        time.sleep(4)
+        while True:
+            result = adb.run(['shell', 'pidof', package_name])
+            if not result:
+                break
+            time.sleep(1)
+        # step 4: Collect recording data.
+        remove('simpleperf_data')
+        self.run_cmd(['api_profiler.py', 'collect', '-p', package_name, '-o', 'simpleperf_data'])
+        # step 5: Check recording data.
+        names = os.listdir('simpleperf_data')
+        self.assertGreater(len(names), 0)
+        for name in names:
+            path = os.path.join('simpleperf_data', name)
+            remove('report.txt')
+            self.run_cmd(['report.py', '-g', '-o', 'report.txt', '-i', path])
+            self.check_strings_in_file('report.txt', expected_reports)
+        # step 6: Clean up.
+        remove('report.txt')
+        remove('simpleperf_data')
+        adb.check_run(['uninstall', package_name])
+
+    def run_cpp_api_test(self, apk_name, min_android_version):
+        self.run_api_test('simpleperf.demo.cpp_api', apk_name, ['BusyThreadFunc'],
+                          min_android_version)
+
+    def test_cpp_api_on_a_debuggable_app_targeting_prev_q(self):
+        # The source code of the apk is in simpleperf/demo/CppApi (with a small change to exit
+        # after recording).
+        self.run_cpp_api_test('cpp_api-debug_prev_Q.apk', 'N')
+
+    def test_cpp_api_on_a_debuggable_app_targeting_q(self):
+        self.run_cpp_api_test('cpp_api-debug_Q.apk', 'N')
+
+    def test_cpp_api_on_a_profileable_app_targeting_prev_q(self):
+        # a release apk with <profileable android:shell="true" />
+        self.run_cpp_api_test('cpp_api-profile_prev_Q.apk', 'Q')
+
+    def test_cpp_api_on_a_profileable_app_targeting_q(self):
+        self.run_cpp_api_test('cpp_api-profile_Q.apk', 'Q')
+
+    def run_java_api_test(self, apk_name, min_android_version):
+        self.run_api_test('simpleperf.demo.java_api', apk_name,
+                          ['simpleperf.demo.java_api.MainActivity', 'java.lang.Thread.run'],
+                          min_android_version)
+
+    def test_java_api_on_a_debuggable_app_targeting_prev_q(self):
+        # The source code of the apk is in simpleperf/demo/JavaApi (with a small change to exit
+        # after recording).
+        self.run_java_api_test('java_api-debug_prev_Q.apk', 'P')
+
+    def test_java_api_on_a_debuggable_app_targeting_q(self):
+        self.run_java_api_test('java_api-debug_Q.apk', 'P')
+
+    def test_java_api_on_a_profileable_app_targeting_prev_q(self):
+        # a release apk with <profileable android:shell="true" />
+        self.run_java_api_test('java_api-profile_prev_Q.apk', 'Q')
+
+    def test_java_api_on_a_profileable_app_targeting_q(self):
+        self.run_java_api_test('java_api-profile_Q.apk', 'Q')
+
+
+class TestPprofProtoGenerator(TestBase):
+    def setUp(self):
+        if not HAS_GOOGLE_PROTOBUF:
+            raise unittest.SkipTest(
+                'Skip test for pprof_proto_generator because google.protobuf is missing')
+
+    def run_generator(self, options=None, testdata_file='perf_with_interpreter_frames.data'):
+        testdata_path = os.path.join('testdata', testdata_file)
+        options = options or []
+        self.run_cmd(['pprof_proto_generator.py', '-i', testdata_path] + options)
+        return self.run_cmd(['pprof_proto_generator.py', '--show'], return_output=True)
+
+    def test_show_art_frames(self):
+        art_frame_str = 'art::interpreter::DoCall'
+        # By default, don't show art frames.
+        self.assertNotIn(art_frame_str, self.run_generator())
+        # Use --show_art_frames to show art frames.
+        self.assertIn(art_frame_str, self.run_generator(['--show_art_frames']))
+
+    def test_pid_filter(self):
+        key = 'PlayScene::DoFrame()'  # function in process 10419
+        self.assertIn(key, self.run_generator())
+        self.assertIn(key, self.run_generator(['--pid', '10419']))
+        self.assertIn(key, self.run_generator(['--pid', '10419', '10416']))
+        self.assertNotIn(key, self.run_generator(['--pid', '10416']))
+
+    def test_tid_filter(self):
+        key1 = 'art::ProfileSaver::Run()'  # function in thread 10459
+        key2 = 'PlayScene::DoFrame()'  # function in thread 10463
+        for options in ([], ['--tid', '10459', '10463']):
+            output = self.run_generator(options)
+            self.assertIn(key1, output)
+            self.assertIn(key2, output)
+        output = self.run_generator(['--tid', '10459'])
+        self.assertIn(key1, output)
+        self.assertNotIn(key2, output)
+        output = self.run_generator(['--tid', '10463'])
+        self.assertNotIn(key1, output)
+        self.assertIn(key2, output)
+
+    def test_comm_filter(self):
+        key1 = 'art::ProfileSaver::Run()'  # function in thread 'Profile Saver'
+        key2 = 'PlayScene::DoFrame()'  # function in thread 'e.sample.tunnel'
+        for options in ([], ['--comm', 'Profile Saver', 'e.sample.tunnel']):
+            output = self.run_generator(options)
+            self.assertIn(key1, output)
+            self.assertIn(key2, output)
+        output = self.run_generator(['--comm', 'Profile Saver'])
+        self.assertIn(key1, output)
+        self.assertNotIn(key2, output)
+        output = self.run_generator(['--comm', 'e.sample.tunnel'])
+        self.assertNotIn(key1, output)
+        self.assertIn(key2, output)
+
+
 def get_all_tests():
     tests = []
     for name, value in globals().items():
@@ -1284,12 +1501,16 @@
     return sorted(tests)
 
 
-def run_tests(tests):
+def run_tests(tests, repeats):
     os.chdir(get_script_dir())
     build_testdata()
-    log_info('Run tests with python%d\n%s' % (3 if is_python3() else 2, '\n'.join(tests)))
     argv = [sys.argv[0]] + tests
-    unittest.main(argv=argv, failfast=True, verbosity=2, exit=False)
+    for repeat in range(repeats):
+        log_info('Run tests with python %d for %dth time\n%s' % (
+            3 if is_python3() else 2, repeat + 1, '\n'.join(tests)))
+        test_program = unittest.main(argv=argv, failfast=True, verbosity=2, exit=False)
+        if not test_program.result.wasSuccessful():
+            sys.exit(1)
 
 
 def main():
@@ -1298,6 +1519,7 @@
     parser.add_argument('--test-from', nargs=1, help='Run left tests from the selected test.')
     parser.add_argument('--python-version', choices=['2', '3', 'both'], default='both', help="""
                         Run tests on which python versions.""")
+    parser.add_argument('--repeat', type=int, nargs=1, default=[1], help='run test multiple times')
     parser.add_argument('pattern', nargs='*', help='Run tests matching the selected pattern.')
     args = parser.parse_args()
     tests = get_all_tests()
@@ -1338,7 +1560,7 @@
             argv += ['--python-version', str(version)]
             subprocess.check_call(argv)
         else:
-            run_tests(tests)
+            run_tests(tests, args.repeat[0])
 
 
 if __name__ == '__main__':
diff --git a/testdata/CppApi/app/src/main/cpp/native-lib.cpp b/testdata/CppApi/app/src/main/cpp/native-lib.cpp
new file mode 100644
index 0000000..bdf5f46
--- /dev/null
+++ b/testdata/CppApi/app/src/main/cpp/native-lib.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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 <android/log.h>
+#include <jni.h>
+#include <pthread.h>
+#include <simpleperf.h>
+#include <unistd.h>
+
+#include <atomic>
+#include <string>
+
+static void log(const char* msg) {
+  __android_log_print(ANDROID_LOG_INFO, "simpleperf", "%s", msg);
+}
+
+static std::atomic_bool profile_thread_exited(false);
+
+void* ProfileThreadFunc(void*) {
+  pthread_setname_np(pthread_self(), "ProfileThread");
+  simpleperf::RecordOptions options;
+  options.RecordDwarfCallGraph();
+  simpleperf::ProfileSession session;
+  log("start recording");
+  session.StartRecording(options);
+  for (int i = 0; i < 3; i++) {
+    sleep(1);
+    log("pause recording");
+    session.PauseRecording();
+    sleep(1);
+    log("resume recording");
+    session.ResumeRecording();
+  }
+  sleep(1);
+  log("stop recording");
+  session.StopRecording();
+  log("stop recording successfully");
+  profile_thread_exited = true;
+  return nullptr;
+};
+
+int CallFunction(int a) {
+  return a + 1;
+}
+
+static std::atomic_int64_t count;
+
+void* BusyThreadFunc(void*) {
+  pthread_setname_np(pthread_self(), "BusyThread");
+  count = 0;
+  volatile int i;
+  while (!profile_thread_exited) {
+    for (i = 0; i < 1000000; ) {
+      i = CallFunction(i);
+    }
+    timespec ts;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 1000000;
+    nanosleep(&ts, nullptr);
+    count++;
+  }
+  return nullptr;
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_simpleperf_demo_cpp_1api_MainActivity_runNativeCode(
+    JNIEnv *env,
+    jobject jobj) {
+  static bool threadsStarted = false;
+  if (!threadsStarted) {
+    pthread_t profile_thread;
+    if (pthread_create(&profile_thread, nullptr, ProfileThreadFunc, nullptr) != 0) {
+      log("failed to create profile thread");
+      return;
+    }
+    pthread_t busy_thread;
+    if (pthread_create(&busy_thread, nullptr, BusyThreadFunc, nullptr) != 0) {
+      log("failed to create busy thread");
+    }
+    threadsStarted = true;
+  }
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_simpleperf_demo_cpp_1api_MainActivity_getBusyThreadCount(
+    JNIEnv *env,
+    jobject jobj) {
+  return static_cast<jlong>(count);
+}
diff --git a/testdata/CppApi/app/src/main/java/simpleperf/demo/cpp_api/MainActivity.java b/testdata/CppApi/app/src/main/java/simpleperf/demo/cpp_api/MainActivity.java
new file mode 100644
index 0000000..6635529
--- /dev/null
+++ b/testdata/CppApi/app/src/main/java/simpleperf/demo/cpp_api/MainActivity.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package simpleperf.demo.cpp_api;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class MainActivity extends AppCompatActivity {
+
+    // Used to load the 'native-lib' library on application startup.
+    static {
+        System.loadLibrary("native-lib");
+    }
+
+    TextView textView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+        textView = findViewById(R.id.textView);
+        runNativeCode();
+
+        createUpdateViewThread();
+    }
+
+    void createUpdateViewThread() {
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException e) {}
+                    final long count = getBusyThreadCount();
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            textView.setText("Count: " + count);
+                        }
+                    });
+                }
+            }
+        }).start();
+    }
+
+    /**
+     * A native method that is implemented by the 'native-lib' native library,
+     * which is packaged with this application.
+     */
+    private native void runNativeCode();
+    private native long getBusyThreadCount();
+
+}
diff --git a/testdata/JavaApi/app/src/main/java/simpleperf/demo/java_api/MainActivity.java b/testdata/JavaApi/app/src/main/java/simpleperf/demo/java_api/MainActivity.java
new file mode 100644
index 0000000..9cb0c4a
--- /dev/null
+++ b/testdata/JavaApi/app/src/main/java/simpleperf/demo/java_api/MainActivity.java
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+package simpleperf.demo.java_api;
+
+import android.support.v7.app.AppCompatActivity;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.TextView;
+
+import com.android.simpleperf.ProfileSession;
+import com.android.simpleperf.RecordOptions;
+
+public class MainActivity extends AppCompatActivity {
+
+    TextView textView;
+
+    static boolean threadsStarted = false;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        textView = (TextView) findViewById(R.id.textView);
+
+        if (!threadsStarted) {
+            threadsStarted = true;
+            Thread profileThread = createProfileThread();
+            createBusyThread(profileThread);
+        }
+    }
+
+    Thread createProfileThread() {
+        Thread thread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                RecordOptions recordOptions = new RecordOptions();
+                recordOptions.recordDwarfCallGraph().setDuration(100);
+                ProfileSession profileSession = new ProfileSession();
+                try {
+                    Log.e("simpleperf", "startRecording");
+                    profileSession.startRecording(recordOptions);
+                    for (int i = 0; i < 3; i++) {
+                        Thread.sleep(1000);
+                        Log.e("simpleperf", "pauseRecording");
+                        profileSession.pauseRecording();
+                        Thread.sleep(1000);
+                        Log.e("simpleperf", "resumeRecording");
+                        profileSession.resumeRecording();
+                    }
+                    Thread.sleep(1000);
+                    Log.e("simpleperf", "stopRecording");
+                    profileSession.stopRecording();
+                    Log.e("simpleperf", "stopRecording successfully");
+                } catch (Exception e) {
+                    Log.e("simpleperf", "exception: " + e.getMessage());
+                }
+            }
+        }, "ProfileThread");
+        thread.start();
+        return thread;
+    }
+
+    void createBusyThread(final Thread profileThread) {
+        new Thread(new Runnable() {
+            volatile int i = 0;
+
+            @Override
+            public void run() {
+                long times = 0;
+                while (profileThread.isAlive()) {
+                    for (int i = 0; i < 1000000;) {
+                        i = callFunction(i);
+                    }
+                    try {
+                        Thread.sleep(1);
+                    } catch (InterruptedException e) {
+                    }
+                    times++;
+                    final long count = times;
+                    runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            textView.setText("count: " + count);
+                        }
+                    });
+                }
+            }
+
+            private int callFunction(int a) {
+                return a + 1;
+            }
+        }, "BusyThread").start();
+    }
+}
diff --git a/testdata/SimpleperfExamplePureJava/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplepurejava/ExampleInstrumentedTest.java b/testdata/SimpleperfExamplePureJava/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplepurejava/ExampleInstrumentedTest.java
index e4c2791..cb91806 100644
--- a/testdata/SimpleperfExamplePureJava/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplepurejava/ExampleInstrumentedTest.java
+++ b/testdata/SimpleperfExamplePureJava/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplepurejava/ExampleInstrumentedTest.java
@@ -1,14 +1,15 @@
 package com.example.simpleperf.simpleperfexamplepurejava;
 
+import static org.junit.Assert.*;
+
 import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.*;
-
 /**
  * Instrumentation test, which will execute on an Android device.
  *
diff --git a/testdata/SimpleperfExampleWithNative/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplewithnative/ExampleInstrumentedTest.java b/testdata/SimpleperfExampleWithNative/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplewithnative/ExampleInstrumentedTest.java
index 3b21b44..fffff66 100644
--- a/testdata/SimpleperfExampleWithNative/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplewithnative/ExampleInstrumentedTest.java
+++ b/testdata/SimpleperfExampleWithNative/app/src/androidTest/java/com/example/simpleperf/simpleperfexamplewithnative/ExampleInstrumentedTest.java
@@ -1,14 +1,15 @@
 package com.example.simpleperf.simpleperfexamplewithnative;
 
+import static org.junit.Assert.*;
+
 import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.*;
-
 /**
  * Instrumentation test, which will execute on an Android device.
  *
diff --git a/testdata/aggregatable_perf1.data b/testdata/aggregatable_perf1.data
new file mode 100644
index 0000000..61f5258
--- /dev/null
+++ b/testdata/aggregatable_perf1.data
Binary files differ
diff --git a/testdata/aggregatable_perf2.data b/testdata/aggregatable_perf2.data
new file mode 100644
index 0000000..7b8224e
--- /dev/null
+++ b/testdata/aggregatable_perf2.data
Binary files differ
diff --git a/testdata/cpp_api-debug_Q.apk b/testdata/cpp_api-debug_Q.apk
new file mode 100644
index 0000000..62591ad
--- /dev/null
+++ b/testdata/cpp_api-debug_Q.apk
Binary files differ
diff --git a/testdata/cpp_api-debug_prev_Q.apk b/testdata/cpp_api-debug_prev_Q.apk
new file mode 100644
index 0000000..2ebf32b
--- /dev/null
+++ b/testdata/cpp_api-debug_prev_Q.apk
Binary files differ
diff --git a/testdata/cpp_api-profile_Q.apk b/testdata/cpp_api-profile_Q.apk
new file mode 100644
index 0000000..b3f4e7d
--- /dev/null
+++ b/testdata/cpp_api-profile_Q.apk
Binary files differ
diff --git a/testdata/cpp_api-profile_prev_Q.apk b/testdata/cpp_api-profile_prev_Q.apk
new file mode 100644
index 0000000..33d7880
--- /dev/null
+++ b/testdata/cpp_api-profile_prev_Q.apk
Binary files differ
diff --git a/testdata/java_api-debug_Q.apk b/testdata/java_api-debug_Q.apk
new file mode 100644
index 0000000..4b141cd
--- /dev/null
+++ b/testdata/java_api-debug_Q.apk
Binary files differ
diff --git a/testdata/java_api-debug_prev_Q.apk b/testdata/java_api-debug_prev_Q.apk
new file mode 100644
index 0000000..0323aa2
--- /dev/null
+++ b/testdata/java_api-debug_prev_Q.apk
Binary files differ
diff --git a/testdata/java_api-profile_Q.apk b/testdata/java_api-profile_Q.apk
new file mode 100644
index 0000000..bb5f651
--- /dev/null
+++ b/testdata/java_api-profile_Q.apk
Binary files differ
diff --git a/testdata/java_api-profile_prev_Q.apk b/testdata/java_api-profile_prev_Q.apk
new file mode 100644
index 0000000..7a7fcb8
--- /dev/null
+++ b/testdata/java_api-profile_prev_Q.apk
Binary files differ
diff --git a/testdata/two_process_perf.data b/testdata/two_process_perf.data
new file mode 100644
index 0000000..c61d591
--- /dev/null
+++ b/testdata/two_process_perf.data
Binary files differ
diff --git a/utils.py b/utils.py
index ea708c6..9891e60 100644
--- a/utils.py
+++ b/utils.py
@@ -70,6 +70,17 @@
 def disable_debug_log():
     logging.getLogger().setLevel(logging.WARN)
 
+def set_log_level(level_name):
+    if level_name == 'debug':
+        level = logging.DEBUG
+    elif level_name == 'info':
+        level = logging.INFO
+    elif level_name == 'warning':
+        level = logging.WARNING
+    else:
+        log_fatal('unknown log level: %s' % level_name)
+    logging.getLogger().setLevel(level)
+
 def str_to_bytes(str_value):
     if not is_python3():
         return str_value
@@ -363,9 +374,7 @@
 def is_elf_file(path):
     if os.path.isfile(path):
         with open(path, 'rb') as fh:
-            data = fh.read(4)
-            if len(data) == 4 and bytes_to_str(data) == '\x7fELF':
-                return True
+            return fh.read(4) == b'\x7fELF'
     return False
 
 def find_real_dso_path(dso_path_in_record_file, binary_cache_path):