[gn] Make Android build work in standalone

This makes it possible to build for Android in Dawn standalone.
Previously it could only be done inside a Chromium checkout.

NOTE: No effort was made to see if the resulting binaries actually work,
only to make sure they're buildable.

Much of this configuration was copied from ANGLE, which is similar to
Dawn and already has a standalone Android build.

Note the revisions of various packages are not exactly the ones that
roll_chromium_deps.py will roll to, because those are hard to figure out
since chromium/src has moved past our DEPS version. They'll get in sync
with the next run.

Bug: 520153663
Change-Id: I1ad2ff2989d2177e3a2defb7bb35642ff99195c6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/315515
Reviewed-by: Brian Sheedy <bsheedy@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
diff --git a/.gitignore b/.gitignore
index 9a0c692..d300bea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,7 @@
 /testing
 /third_party/abseil-cpp/
 /third_party/agility-sdk/src
+/third_party/android_toolchain/ndk
 /third_party/angle
 /third_party/binutils
 /third_party/catapult
@@ -27,6 +28,7 @@
 /third_party/google_benchmark/src
 /third_party/googletest
 /third_party/gpuweb
+/third_party/jdk/current
 /third_party/jinja2
 /third_party/jsoncpp
 /third_party/EGL-Registry/src
diff --git a/.gitmodules b/.gitmodules
index 71073f9..73bd6f4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -217,3 +217,23 @@
 	path = third_party/litert-lm/src
 	url = https://chromium.googlesource.com/external/github.com/google-ai-edge/LiteRT-LM.git
 	gclient-condition = checkout_litert_lm
+[submodule "third_party/android_sdk"]
+	path = third_party/android_sdk
+	url = https://chromium.googlesource.com/chromium/src/third_party/android_sdk
+	gclient-condition = checkout_android and dawn_standalone
+[submodule "third_party/android_build_tools"]
+	path = third_party/android_build_tools
+	url = https://chromium.googlesource.com/chromium/src/third_party/android_build_tools
+	gclient-condition = checkout_android and dawn_standalone
+[submodule "third_party/cpu_features/src"]
+	path = third_party/cpu_features/src
+	url = https://chromium.googlesource.com/external/github.com/google/cpu_features.git
+	gclient-condition = checkout_android and dawn_standalone
+[submodule "third_party/ijar"]
+	path = third_party/ijar
+	url = https://chromium.googlesource.com/chromium/src/third_party/ijar
+	gclient-condition = checkout_android and dawn_standalone
+[submodule "third_party/libunwind/src"]
+	path = third_party/libunwind/src
+	url = https://chromium.googlesource.com/external/github.com/llvm/llvm-project/libunwind.git
+	gclient-condition = checkout_android and dawn_standalone
diff --git a/DEPS b/DEPS
index e5b6dc7..f9288dd 100644
--- a/DEPS
+++ b/DEPS
@@ -3,6 +3,7 @@
 gclient_gn_args_file = 'build/config/gclient_args.gni'
 
 gclient_gn_args = [
+  'android_ndk_version',
   'build_with_chromium',
   'dawn_node',
   'dawn_wasm',
@@ -91,6 +92,14 @@
   # Checkout LiteRT-LM and its data dependencies.
   # Not actually depended on by Dawn/Tint, only used to run benchmark tests on them.
   'checkout_litert_lm': False,
+
+  # Dependency versions for Android builds.
+  # These should be all rolled at once to match the values in Chromium.
+  'android_ndk_version': Str('2@30.0.14608247'),
+  'android_sdk_build-tools_version': 'febJrTgiK9s1ANoUlc4Orn3--zs9GjGCj2vQc8g7OaMC',
+  'android_sdk_emulator_version': '9lGp8nTUCRRWGMnI_96HcKfzjnxEJKUcfvfwmA3wXNkC',
+  'android_sdk_platform-tools_version': 'qTD9QdBlBf3dyHsN1lJ0RH6AhHxR42Hmg2Ih-Vj4zIEC',
+  'android_sdk_platforms_version': 'WhtP32Q46ZHdTmgCgdauM3ws_H9iPoGKEZ_cPggcQ6wC',
 }
 
 deps = {
@@ -666,6 +675,94 @@
     'condition': 'dawn_standalone',
   },
 
+  # For Android builds in standalone.
+  'third_party/android_sdk': {
+    'url': Var('chromium_git') + '/chromium/src/third_party/android_sdk@7a2315c1042afa89610bfd7ca6dd5d313dbbfc67',
+    'condition': 'checkout_android and dawn_standalone',
+  },
+  'third_party/android_sdk/public': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/android_sdk/public/build-tools/37.0.0',
+        'version': Var('android_sdk_build-tools_version'),
+      },
+      {
+        'package': 'chromium/third_party/android_sdk/public/emulator',
+        'version': Var('android_sdk_emulator_version'),
+      },
+      {
+        'package': 'chromium/third_party/android_sdk/public/platform-tools',
+        'version': Var('android_sdk_platform-tools_version'),
+      },
+      {
+        'package': 'chromium/third_party/android_sdk/public/platforms/android-37.0',
+        'version': Var('android_sdk_platforms_version'),
+      },
+      {
+        'package': 'chromium/third_party/android_sdk/public/cmdline-tools/linux',
+        'version': 'LZa8CWNVWS6UUQgQ7IJdFCqRV1Bmx2-alTNqEDJpJkcC',
+      },
+    ],
+    'condition': 'checkout_android and dawn_standalone',
+    'dep_type': 'cipd',
+  },
+  'third_party/android_toolchain/ndk': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/android_toolchain/android_toolchain',
+        'version': 'version:' + Var('android_ndk_version'),
+      },
+    ],
+    'condition': 'checkout_android and dawn_standalone',
+    'dep_type': 'cipd',
+  },
+  'third_party/jdk/current': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/jdk/linux-amd64',
+        'version': '2iiuF-nKDH3moTImx2op4WTRetbfhzKoZhH7Xo44zGsC',
+      },
+    ],
+    'condition': 'checkout_android and dawn_standalone and non_git_source',
+    'dep_type': 'cipd',
+  },
+  'third_party/android_build_tools': {
+    'url': Var('chromium_git') + '/chromium/src/third_party/android_build_tools@bf728906b86d63e57ef33a21215eaec7d1ad1991',
+    'condition': 'checkout_android and dawn_standalone',
+  },
+  'third_party/android_build_tools/aapt2/cipd': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/android_build_tools/aapt2',
+        'version': 'yfxf90-dNwgtoT5PFTDA5BUz9mvuYdTImnJF1K-jaeMC',
+      },
+    ],
+    'condition': 'checkout_android and dawn_standalone',
+    'dep_type': 'cipd',
+  },
+  'third_party/android_build_tools/manifest_merger/cipd': {
+    'packages': [
+      {
+        'package': 'chromium/third_party/android_build_tools/manifest_merger',
+        'version': '5t4XXJF0lLTEEcyB-6QtjaMd2_Q7I_ON2Y-RZOU7O-gC',
+      },
+    ],
+    'condition': 'checkout_android and dawn_standalone',
+    'dep_type': 'cipd',
+  },
+  'third_party/cpu_features/src': {
+    'url': Var('chromium_git') + '/external/github.com/google/cpu_features.git' + '@' + '81d13c49649f0714dd41fb56bb246398b6584085',
+    'condition': 'checkout_android and dawn_standalone',
+  },
+  'third_party/ijar': {
+    'url': Var('chromium_git') + '/chromium/src/third_party/ijar@94af60a05b33f9acb33477a8d969e48eb1c3029f',
+    'condition': 'checkout_android and dawn_standalone',
+  },
+  'third_party/libunwind/src': {
+    'url': Var('chromium_git') + '/external/github.com/llvm/llvm-project/libunwind.git@d6c7a21e978f0adaa43accaad53bc64f0b64f6ec',
+    'condition': 'checkout_android and dawn_standalone',
+  },
+
   # We never want to actually checkout Chromium, but we need a fake DEPS entry
   # in order for the Chromium -> Dawn DEPS autoroller to work. Note that this
   # only currently works due to an explicit exception in presubmit checks
diff --git a/OWNERS b/OWNERS
index b1bb03e..b091c0e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -26,10 +26,13 @@
 per-file buildtools=*
 per-file testing=*
 per-file third_party/abseil-cpp=*
+per-file third_party/android_build_tools=*
+per-file third_party/android_sdk=*
 per-file third_party/angle=*
 per-file third_party/catapult=*
 per-file third_party/chromium-tools-build/src=*
 per-file third_party/clang-format/script=*
+per-file third_party/cpu_features/src=*
 per-file third_party/depot_tools=*
 per-file third_party/directx-shader-compiler/src=*
 per-file third_party/directx-headers/src=*
@@ -39,6 +42,7 @@
 per-file third_party/google_benchmark/src=*
 per-file third_party/googletest=*
 per-file third_party/gpuweb=*
+per-file third_party/ijar=*
 per-file third_party/jinja2=*
 per-file third_party/jsoncpp=*
 per-file third_party/EGL-Registry/src=*
@@ -49,6 +53,7 @@
 per-file third_party/libdrm/src=*
 per-file third_party/libFuzzer/src=*
 per-file third_party/libprotobuf-mutator/src=*
+per-file third_party/libunwind/src=*
 per-file third_party/llvm-libc/src=*
 per-file third_party/markupsafe=*
 per-file third_party/node-addon-api=*
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
index fe4ae75..cfa391d 100644
--- a/build_overrides/build.gni
+++ b/build_overrides/build.gni
@@ -58,3 +58,8 @@
 } else if (host_os != "mac") {
   use_system_xcode = false
 }
+
+if (is_android) {
+  limit_android_deps = true
+  enable_java_templates = true
+}
diff --git a/docs/building.md b/docs/building.md
index 382354c..34d284d 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -165,6 +165,10 @@
 
 1.  Add your target OS to the `target_os` array in `.gclient`. Or, use
     `standalone-maximal.gclient` and follow the instructions in it.
+    This will enable downloading toolchains and any target-specific Dawn DEPS.
+    - Windows: ~16GB.
+    - Mac: ~4GB.
+    - Android: ~2.5GB.
 1.  `gclient sync`.
 1.  Create a new `out/*` directory for each target build with the relevant GN
     args. The following configurations have been tested:
@@ -175,16 +179,17 @@
           Use `autoninja --offline` (or `autoninja -k=0 ; autoninja --offline`
           to first compile everything possible with Siso, then compile the rest
           locally). See <https://crbug.com/446124900>.
+    - `target_os = "android` `target_cpu = "arm64"` on Linux hosts (note below)
 
 For background, see also
 [this guide](https://chromium.googlesource.com/chromium/src/+/main/docs/win_cross.md).
 
 #### For Android targets (Linux hosts)
 
-Compiling Dawn binaries for Android is not supported in a Dawn standalone
-checkout; it must be checked out as a submodule of `chromium/src` (on a Linux
-host). If Chromium is configured to build for Android, then Dawn targets (like
-`dawn_unittests` will also be buildable.
+**Cross-compilation for Android as described above works to compile targets, but
+the resulting binaries have not been tested.** If you want to run them you *may*
+need to set up an Android Chromium build (which contains Dawn) and build Dawn
+targets (like `dawn_unittests`, `dawn_end2end_tests`) in the Chromium build.
 
 ### Using ccache for CMake builds
 
diff --git a/docs/development-tips.md b/docs/development-tips.md
index a9d022c..4d2aeac 100644
--- a/docs/development-tips.md
+++ b/docs/development-tips.md
@@ -1,7 +1,12 @@
 # Tips for developing Dawn code
 
+This doc is specifically for people working on Dawn itself (not just using it
+as a dependency).
+
 ## Build/run as much stuff as possible locally, to find bugs before they hit CQ
 
+Especially useful for any change or refactor that affects multiple backends.
+
 - Use `scripts/standalone-maximal.gclient` instead of `standalone.gclient`.
 - Set the `dawn_maximal = true` GN arg to default to building as many targets
   as possible given your host OS.
@@ -14,6 +19,9 @@
 
 ## Set up your IDE to use clangd
 
+Provides instant inline compilation errors in the editor. Significantly speeds
+up the development/iteration process, compared with recompiling the project.
+
 - Do the steps above, so that clangd will know how to build most files.
 - Do a full build in each build directory (to create generated files, etc.).
 - Set `"custom_vars": { "checkout_clangd": True }` in `.gclient`
@@ -21,8 +29,8 @@
 - Point your IDE to the binary at
   `third_party/llvm-build/Release+Asserts/bin/clangd`.
   - In VSCode: `clangd.path`
-- Configure clangd: Paste the relevant text into `.clangd` and then update the
-  `out/` paths in that file according to your needs.
+- Configure clangd: Paste the relevant text below into `.clangd` and then update
+  the `out/` paths in that file according to your needs.
   - Note the `PathMatch` paths aren't intended to be perfect, but please update
     this doc if you find platform-specific files that they miss.
   - If you have just one build directory, you can alternatively pass this as
@@ -31,6 +39,14 @@
   - For Chromium builds, take a look at
     [`chrome-remote-index`](https://github.com/clangd/chrome-remote-index/blob/main/docs/index.md).
 
+
+Other documentation that may be useful:
+
+- [Clangd docs on how to integrate clangd in various editors](https://clangd.llvm.org/installation.html#editor-plugins)
+- [Chromium docs on using clangd](https://chromium.googlesource.com/chromium/src/+/main/docs/clangd.md)
+
+### `.clangd`
+
 For Mac/Linux hosts:
 
 ```yml
@@ -46,6 +62,10 @@
     # `clangd/config.yml` (https://clangd.llvm.org/config#files). Suggestions:
     # - `--header-insertion=never` if you find yourself accidentally adding
     #   random headers when autocomplete goes sideways
+    # - `--background-index=false` if you only want support in the current file
+    #   (and includes), and don't want to index the whole project in the
+    #   background (for symbol search, find references, etc.). Saves battery
+    #   but otherwise isn't super necessary for Dawn since it's pretty small.
 ---
 If:
   PathMatch:
@@ -68,4 +88,12 @@
     - "src/.*_[Mm]etal.*"
 CompileFlags:
   CompilationDatabase: out/Debug-mac
+---
+If:
+  PathMatch:
+    - "src/.*[Aa]ndroid.*"
+    - "src/.*AHardwareBuffer.*"
+    - "src/.*AHB.*"
+CompileFlags:
+  CompilationDatabase: out/Debug-android
 ```
diff --git a/scripts/dawn_component.gni b/scripts/dawn_component.gni
index 781c5bf..1dd593a 100644
--- a/scripts/dawn_component.gni
+++ b/scripts/dawn_component.gni
@@ -133,7 +133,7 @@
     # all symbols except JNI ones. Remove this config so that our
     # shared_library symbols are visible. This matches what Chromium's
     # component template does.
-    if (build_with_chromium && is_android) {
+    if (is_android) {
       configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
     }
   }
diff --git a/scripts/dawn_features.gni b/scripts/dawn_features.gni
index 05e4290..16372e4 100644
--- a/scripts/dawn_features.gni
+++ b/scripts/dawn_features.gni
@@ -59,14 +59,19 @@
 dawn_is_winuwp = is_win && target_os == "winuwp"
 dawn_use_windows_ui = is_win
 
+if (is_android || is_ios) {
+  dawn_use_swiftshader = false
+} else {
+  declare_args() {
+    # Enables SwiftShader as the fallback adapter. Requires dawn_swiftshader_dir
+    # to be set to take effect.
+    dawn_use_swiftshader = true
+  }
+}
+
 declare_args() {
   dawn_tests_use_angle = true
 
-  # Enables SwiftShader as the fallback adapter. Requires dawn_swiftshader_dir
-  # to be set to take effect.
-  # TODO(dawn:1536): Enable SwiftShader for Android.
-  dawn_use_swiftshader = !is_android && !is_ios
-
   # Whether we allow building DXC.
   # DXC requires SM6.0+ which is blocklisted on x86.
   # See crbug.com/tint/1753.
@@ -79,8 +84,9 @@
   # Whether to build Dawn's NodeJS bindings. Default to the value from .gclient.
   dawn_build_node_bindings = dawn_standalone && dawn_node
 
-  # Whether to build Emdawnwebgpu. Default to the value from .gclient.
-  dawn_build_emdawnwebgpu = dawn_standalone && dawn_wasm
+  # Whether to build Emdawnwebgpu. Default to the value from .gclient, except
+  # don't enable this in Android builds.
+  dawn_build_emdawnwebgpu = dawn_standalone && dawn_wasm && !is_android
 
   # Whether Dawn uses the Agility SDK.
   dawn_use_agility_sdk = false
diff --git a/scripts/roll_chromium_deps.py b/scripts/roll_chromium_deps.py
index 85e35c4..7503a67 100755
--- a/scripts/roll_chromium_deps.py
+++ b/scripts/roll_chromium_deps.py
@@ -61,8 +61,13 @@
 DEFAULT_REVISION_CHARACTERS = 10
 
 # GN variables that need to be synced. A map from Dawn variable name to
-# Chromium variable name.
-SYNCED_VARIABLES = {}
+# Chromium variable name (if different).
+SYNCED_VARIABLES = {
+    # For Android builds in standalone.
+    # TODO(crbug.com/528413044): Replace this with a SYNCED_CIPD_DEPS entry on
+    # 'third_party/android_toolchain/ndk' instead to implicitly update this var.
+    'android_ndk_version': None,
+}
 
 # DEPS entries which have dep_type = cipd. In the Chromium DEPS file, these
 # will be prefixed with src/.
@@ -73,6 +78,12 @@
     'buildtools/win',
     'third_party/ninja',
     'third_party/siso/cipd',
+
+    # For Android builds in standalone.
+    'third_party/android_sdk/public',
+    'third_party/jdk/current',
+    'third_party/android_build_tools/aapt2/cipd',
+    'third_party/android_build_tools/manifest_merger/cipd',
 }
 
 # DEPS entries which have dep_type = gcs. In the Chromium DEPS file, these will
@@ -86,6 +97,13 @@
     'build/linux/debian_bullseye_amd64-sysroot',
 }
 
+# Files that are copied from Chromium directly. A map from Dawn file path to
+# Chromium file path (if different).
+SYNCED_TEXT_FILES = {
+    'third_party/cpu_features/BUILD.gn': None,
+    'third_party/jdk/BUILD.gn': None,
+}
+
 # Repos that are independently synced by Chromium and Dawn. A map from Dawn
 # names to Chromium names. None means that the names are identical. In the
 # Chromium DEPS file, these will be prefixed with src/.
@@ -126,11 +144,16 @@
     # third_party/webgpu-cts is technically used by both Chromium and Dawn, but
     # they are used for different purposes and the CTS roller needs to roll
     # Dawn's copy in order to update expectations.
+
+    # For Android builds in standalone.
+    'third_party/cpu_features/src': None,
+    'third_party/libunwind/src': None,
 }
 
 # Chromium directories that are exported as pseudo-repos in
 # chromium.googlesource.com under chromium/src/. Mapping of Dawn path to
 # Chromium src-relative path. None means that the names are identical.
+# NOTE: These are always rolled to top-of-tree - they ignore --revision.
 EXPORTED_CHROMIUM_REPOS = {
     'build': None,
     'buildtools': None,
@@ -148,6 +171,11 @@
     'tools/protoc_wrapper': None,
     'tools/valgrind': None,
     'tools/win': None,
+
+    # For Android builds in standalone.
+    'third_party/android_build_tools': None,
+    'third_party/android_sdk': None,
+    'third_party/ijar': None,
 }
 
 
@@ -546,6 +574,7 @@
     """
     changed_variables = []
     for dawn_var, chromium_var in SYNCED_VARIABLES.items():
+        chromium_var = chromium_var or dawn_var
         dawn_value = dawn_deps['vars'].get(dawn_var)
         chromium_value = chromium_deps['vars'].get(chromium_var)
         if not dawn_value:
@@ -1130,6 +1159,14 @@
     return updated_contents
 
 
+def _sync_text_files(new_revision):
+    for dawn_file, chromium_file in SYNCED_TEXT_FILES.items():
+        chromium_file = chromium_file or dawn_file
+        content = _read_remote_chromium_file(chromium_file, new_revision)
+        with open(dawn_file, 'w', encoding='utf-8') as outfile:
+            outfile.write(content)
+
+
 def _parse_args() -> argparse.Namespace:
     """Parses and returns command line arguments."""
     parser = argparse.ArgumentParser('Roll DEPS entries shared with Chromium.')
@@ -1203,6 +1240,7 @@
         _create_roll_branch()
 
     _apply_changed_deps(changed_entries)
+    _sync_text_files(revision_range.new_revision)
 
     if args.autoroll:
         _amend_commit(commit_message)
diff --git a/scripts/standalone-maximal.gclient b/scripts/standalone-maximal.gclient
index 0a4bc3c..a4e36e4 100644
--- a/scripts/standalone-maximal.gclient
+++ b/scripts/standalone-maximal.gclient
@@ -28,4 +28,4 @@
 # If cross compiling on Mac, uncomment this:
 #target_os += ['win']
 # If cross compiling on Linux, uncomment this:
-#target_os += ['win', 'mac']
\ No newline at end of file
+#target_os += ['win', 'mac', 'android']
diff --git a/src/dawn/native/BUILD.gn b/src/dawn/native/BUILD.gn
index ce32efe..74b5adc 100644
--- a/src/dawn/native/BUILD.gn
+++ b/src/dawn/native/BUILD.gn
@@ -1019,6 +1019,7 @@
         "vulkan/external_semaphore/SemaphoreServiceImplementationFD.h",
       ]
       if (is_android) {
+        libs += [ "android" ]
         sources += [
           "vulkan/external_memory/MemoryServiceImplementationAHardwareBuffer.cpp",
           "vulkan/external_memory/MemoryServiceImplementationAHardwareBuffer.h",
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryYCbCrAndroidTests.cpp b/src/dawn/tests/white_box/SharedTextureMemoryYCbCrAndroidTests.cpp
index efb1095..2237ae4 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryYCbCrAndroidTests.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryYCbCrAndroidTests.cpp
@@ -625,7 +625,9 @@
         auto ycbcr = math::Vec4f(cr / 255.0, y / 255.0, cb / 255.0, 1.0);
         auto rgb = math::Mul(ycbcrToRgb, ycbcr);
 
-        auto expected = utils::RGBA8(rgb[0] * 255, rgb[1] * 255, rgb[2] * 255, 255);
+        auto expected =
+            utils::RGBA8(static_cast<uint8_t>(rgb[0] * 255), static_cast<uint8_t>(rgb[1] * 255),
+                         static_cast<uint8_t>(rgb[2] * 255), 255);
         auto bottom = utils::RGBA8(expected.r - 1, expected.g - 1, expected.b - 1, 255);
         auto top = utils::RGBA8(expected.r + 1, expected.g + 1, expected.b + 1, 255);
 
diff --git a/third_party/android_build_tools b/third_party/android_build_tools
new file mode 160000
index 0000000..bf72890
--- /dev/null
+++ b/third_party/android_build_tools
@@ -0,0 +1 @@
+Subproject commit bf728906b86d63e57ef33a21215eaec7d1ad1991
diff --git a/third_party/android_sdk b/third_party/android_sdk
new file mode 160000
index 0000000..7a2315c
--- /dev/null
+++ b/third_party/android_sdk
@@ -0,0 +1 @@
+Subproject commit 7a2315c1042afa89610bfd7ca6dd5d313dbbfc67
diff --git a/third_party/cpu_features/BUILD.gn b/third_party/cpu_features/BUILD.gn
new file mode 100644
index 0000000..f077a01
--- /dev/null
+++ b/third_party/cpu_features/BUILD.gn
@@ -0,0 +1,69 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("cpu_features_config") {
+  cflags = [ "-Wno-unused-function" ]
+  defines = [
+    "STACK_LINE_READER_BUFFER_SIZE=1024",
+    "HAVE_STRONG_GETAUXVAL",
+  ]
+  include_dirs = [ "src/include" ]
+}
+
+config("ndk_compat_headers") {
+  include_dirs = [ "src/ndk_compat" ]
+}
+
+source_set("cpuinfo") {
+  sources = [
+    "src/src/copy.inl",
+    "src/src/define_introspection.inl",
+    "src/src/define_introspection_and_hwcaps.inl",
+    "src/src/equals.inl",
+    "src/src/filesystem.c",
+    "src/src/hwcaps.c",
+    "src/src/hwcaps_freebsd_or_openbsd.c",
+    "src/src/hwcaps_linux_or_android.c",
+    "src/src/stack_line_reader.c",
+    "src/src/string_view.c",
+  ]
+  if (current_cpu == "x86" || current_cpu == "x64") {
+    sources += [
+      "src/src/impl_x86__base_implementation.inl",
+      "src/src/impl_x86_freebsd.c",
+      "src/src/impl_x86_linux_or_android.c",
+      "src/src/impl_x86_macos.c",
+      "src/src/impl_x86_windows.c",
+    ]
+  } else if (current_cpu == "arm") {
+    sources += [ "src/src/impl_arm_linux_or_android.c" ]
+  } else if (current_cpu == "arm64") {
+    sources += [
+      "src/src/impl_aarch64_cpuid.c",
+      "src/src/impl_aarch64_freebsd_or_openbsd.c",
+      "src/src/impl_aarch64_linux_or_android.c",
+      "src/src/impl_aarch64_macos_or_iphone.c",
+      "src/src/impl_aarch64_windows.c",
+    ]
+  } else if (current_cpu == "mips") {
+    sources += [ "src/src/impl_mips_linux_or_android.c" ]
+  } else if (current_cpu == "ppc") {
+    sources += [ "src/src/impl_ppc_linux.c" ]
+  } else if (current_cpu == "riscv64") {
+    sources += [ "src/src/impl_riscv_linux.c" ]
+  } else {
+    error("Missing definition for architecture: $current_cpu")
+  }
+  configs += [ ":cpu_features_config" ]
+}
+
+source_set("ndk_compat") {
+  sources = [
+    "src/ndk_compat/cpu-features.c",
+    "src/ndk_compat/cpu-features.h",
+  ]
+  configs += [ ":cpu_features_config" ]
+  public_configs = [ ":ndk_compat_headers" ]
+  deps = [ ":cpuinfo" ]
+}
diff --git a/third_party/cpu_features/OWNERS b/third_party/cpu_features/OWNERS
new file mode 100644
index 0000000..361cf9f
--- /dev/null
+++ b/third_party/cpu_features/OWNERS
@@ -0,0 +1 @@
+per-file BUILD.gn=dawn-autoroll@skia-public.iam.gserviceaccount.com
diff --git a/third_party/cpu_features/README.md b/third_party/cpu_features/README.md
new file mode 100644
index 0000000..0f52ff7
--- /dev/null
+++ b/third_party/cpu_features/README.md
@@ -0,0 +1,2 @@
+`BUILD.gn` is copied directly from Chromium by `roll_chromium_deps.py`.
+Don't edit it directly or it'll be overwritten by the roll.
diff --git a/third_party/cpu_features/src b/third_party/cpu_features/src
new file mode 160000
index 0000000..81d13c4
--- /dev/null
+++ b/third_party/cpu_features/src
@@ -0,0 +1 @@
+Subproject commit 81d13c49649f0714dd41fb56bb246398b6584085
diff --git a/third_party/ijar b/third_party/ijar
new file mode 160000
index 0000000..94af60a
--- /dev/null
+++ b/third_party/ijar
@@ -0,0 +1 @@
+Subproject commit 94af60a05b33f9acb33477a8d969e48eb1c3029f
diff --git a/third_party/jdk/BUILD.gn b/third_party/jdk/BUILD.gn
new file mode 100644
index 0000000..e003eef
--- /dev/null
+++ b/third_party/jdk/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2019 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("jdk") {
+  include_dirs = [
+    "current/include",
+    "current/include/linux",
+  ]
+}
+
+group("java_data") {
+  data = [
+    "current/bin/java",
+    "current/bin/java.chromium",
+    "current/bin/jcmd",
+    "current/conf/",
+    "current/jmods/",
+    "current/lib/",
+  ]
+}
diff --git a/third_party/jdk/OWNERS b/third_party/jdk/OWNERS
new file mode 100644
index 0000000..361cf9f
--- /dev/null
+++ b/third_party/jdk/OWNERS
@@ -0,0 +1 @@
+per-file BUILD.gn=dawn-autoroll@skia-public.iam.gserviceaccount.com
diff --git a/third_party/jdk/README.md b/third_party/jdk/README.md
new file mode 100644
index 0000000..0f52ff7
--- /dev/null
+++ b/third_party/jdk/README.md
@@ -0,0 +1,2 @@
+`BUILD.gn` is copied directly from Chromium by `roll_chromium_deps.py`.
+Don't edit it directly or it'll be overwritten by the roll.
diff --git a/third_party/libunwind/src b/third_party/libunwind/src
new file mode 160000
index 0000000..d6c7a21
--- /dev/null
+++ b/third_party/libunwind/src
@@ -0,0 +1 @@
+Subproject commit d6c7a21e978f0adaa43accaad53bc64f0b64f6ec