1*cc02d7e2SAndroid Build Coastguard Worker%YAML 1.2 2*cc02d7e2SAndroid Build Coastguard Worker--- | 3*cc02d7e2SAndroid Build Coastguard Worker <%! 4*cc02d7e2SAndroid Build Coastguard Worker def expand_symbol_list(symbol_list): 5*cc02d7e2SAndroid Build Coastguard Worker return ',\n '.join("'#define %s GRPC_SHADOW_%s'" % (symbol, symbol) for symbol in symbol_list) 6*cc02d7e2SAndroid Build Coastguard Worker 7*cc02d7e2SAndroid Build Coastguard Worker import subprocess 8*cc02d7e2SAndroid Build Coastguard Worker boringssl_commit = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd='third_party/boringssl-with-bazel').decode().strip() 9*cc02d7e2SAndroid Build Coastguard Worker 10*cc02d7e2SAndroid Build Coastguard Worker # Compress src/boringssl/boringssl_prefix_symbols.h with gzip then encode 11*cc02d7e2SAndroid Build Coastguard Worker # with Base64. The result is put in variable prefix_gz_b64. 12*cc02d7e2SAndroid Build Coastguard Worker # 13*cc02d7e2SAndroid Build Coastguard Worker # Note that gRPC's template parser is still using Python 2, whose gzip 14*cc02d7e2SAndroid Build Coastguard Worker # module does not support directly compressing bytes into bytes. Instead, 15*cc02d7e2SAndroid Build Coastguard Worker # we have to write the compressed bytes into a intermediate file 16*cc02d7e2SAndroid Build Coastguard Worker # (src/boringssl/boringssl_prefix_symbols.h.gz), read the compressed 17*cc02d7e2SAndroid Build Coastguard Worker # bytes from this file, then delete the intermediate file. 18*cc02d7e2SAndroid Build Coastguard Worker # 19*cc02d7e2SAndroid Build Coastguard Worker # TODO(mxyan): move to python3 style gzip compression when possible 20*cc02d7e2SAndroid Build Coastguard Worker def compress_and_encode_file(filepath): 21*cc02d7e2SAndroid Build Coastguard Worker gzip_filepath = filepath + '.gz' 22*cc02d7e2SAndroid Build Coastguard Worker import gzip, shutil, os, base64 23*cc02d7e2SAndroid Build Coastguard Worker with open(filepath, 'rb') as f_in, gzip.GzipFile(gzip_filepath, 'w', mtime=0.0) as f_out: 24*cc02d7e2SAndroid Build Coastguard Worker shutil.copyfileobj(f_in, f_out) 25*cc02d7e2SAndroid Build Coastguard Worker with open(gzip_filepath, 'rb') as f_in: 26*cc02d7e2SAndroid Build Coastguard Worker prefix_gz = f_in.read() 27*cc02d7e2SAndroid Build Coastguard Worker os.remove(gzip_filepath) 28*cc02d7e2SAndroid Build Coastguard Worker prefix_gz_b64 = base64.b64encode(prefix_gz) 29*cc02d7e2SAndroid Build Coastguard Worker WRAP_LENGTH=80 30*cc02d7e2SAndroid Build Coastguard Worker prefix_gz_b64_wrapped = [prefix_gz_b64[i:i+WRAP_LENGTH] for i in range(0, len(prefix_gz_b64), WRAP_LENGTH)] 31*cc02d7e2SAndroid Build Coastguard Worker return prefix_gz_b64_wrapped 32*cc02d7e2SAndroid Build Coastguard Worker %> 33*cc02d7e2SAndroid Build Coastguard Worker 34*cc02d7e2SAndroid Build Coastguard Worker # This file has been automatically generated from a template file. 35*cc02d7e2SAndroid Build Coastguard Worker # Please make modifications to 36*cc02d7e2SAndroid Build Coastguard Worker # `templates/src/objective-c/BoringSSL-GRPC.podspec.template` instead. This 37*cc02d7e2SAndroid Build Coastguard Worker # file can be regenerated from the template by running 38*cc02d7e2SAndroid Build Coastguard Worker # `tools/buildgen/generate_projects.sh`. 39*cc02d7e2SAndroid Build Coastguard Worker 40*cc02d7e2SAndroid Build Coastguard Worker # BoringSSL CocoaPods podspec 41*cc02d7e2SAndroid Build Coastguard Worker 42*cc02d7e2SAndroid Build Coastguard Worker # Copyright 2015, Google Inc. 43*cc02d7e2SAndroid Build Coastguard Worker # All rights reserved. 44*cc02d7e2SAndroid Build Coastguard Worker # 45*cc02d7e2SAndroid Build Coastguard Worker # Redistribution and use in source and binary forms, with or without 46*cc02d7e2SAndroid Build Coastguard Worker # modification, are permitted provided that the following conditions are 47*cc02d7e2SAndroid Build Coastguard Worker # met: 48*cc02d7e2SAndroid Build Coastguard Worker # 49*cc02d7e2SAndroid Build Coastguard Worker # * Redistributions of source code must retain the above copyright 50*cc02d7e2SAndroid Build Coastguard Worker # notice, this list of conditions and the following disclaimer. 51*cc02d7e2SAndroid Build Coastguard Worker # * Redistributions in binary form must reproduce the above 52*cc02d7e2SAndroid Build Coastguard Worker # copyright notice, this list of conditions and the following disclaimer 53*cc02d7e2SAndroid Build Coastguard Worker # in the documentation and/or other materials provided with the 54*cc02d7e2SAndroid Build Coastguard Worker # distribution. 55*cc02d7e2SAndroid Build Coastguard Worker # * Neither the name of Google Inc. nor the names of its 56*cc02d7e2SAndroid Build Coastguard Worker # contributors may be used to endorse or promote products derived from 57*cc02d7e2SAndroid Build Coastguard Worker # this software without specific prior written permission. 58*cc02d7e2SAndroid Build Coastguard Worker # 59*cc02d7e2SAndroid Build Coastguard Worker # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 60*cc02d7e2SAndroid Build Coastguard Worker # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 61*cc02d7e2SAndroid Build Coastguard Worker # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 62*cc02d7e2SAndroid Build Coastguard Worker # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 63*cc02d7e2SAndroid Build Coastguard Worker # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 64*cc02d7e2SAndroid Build Coastguard Worker # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 65*cc02d7e2SAndroid Build Coastguard Worker # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 66*cc02d7e2SAndroid Build Coastguard Worker # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 67*cc02d7e2SAndroid Build Coastguard Worker # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 68*cc02d7e2SAndroid Build Coastguard Worker # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 69*cc02d7e2SAndroid Build Coastguard Worker # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 70*cc02d7e2SAndroid Build Coastguard Worker 71*cc02d7e2SAndroid Build Coastguard Worker Pod::Spec.new do |s| 72*cc02d7e2SAndroid Build Coastguard Worker s.name = 'BoringSSL-GRPC' 73*cc02d7e2SAndroid Build Coastguard Worker version = '0.0.33' 74*cc02d7e2SAndroid Build Coastguard Worker s.version = version 75*cc02d7e2SAndroid Build Coastguard Worker s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google\'s needs.' 76*cc02d7e2SAndroid Build Coastguard Worker # Adapted from the homepage: 77*cc02d7e2SAndroid Build Coastguard Worker s.description = <<-DESC 78*cc02d7e2SAndroid Build Coastguard Worker BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. 79*cc02d7e2SAndroid Build Coastguard Worker 80*cc02d7e2SAndroid Build Coastguard Worker Although BoringSSL is an open source project, it is not intended for general use, as OpenSSL is. 81*cc02d7e2SAndroid Build Coastguard Worker We don't recommend that third parties depend upon it. Doing so is likely to be frustrating 82*cc02d7e2SAndroid Build Coastguard Worker because there are no guarantees of API stability. Only the latest version of this pod is 83*cc02d7e2SAndroid Build Coastguard Worker supported, and every new version is a new major version. 84*cc02d7e2SAndroid Build Coastguard Worker 85*cc02d7e2SAndroid Build Coastguard Worker We update Google libraries and programs that use BoringSSL as needed when deciding to make API 86*cc02d7e2SAndroid Build Coastguard Worker changes. This allows us to mostly avoid compromises in the name of compatibility. It works for 87*cc02d7e2SAndroid Build Coastguard Worker us, but it may not work for you. 88*cc02d7e2SAndroid Build Coastguard Worker 89*cc02d7e2SAndroid Build Coastguard Worker As a Cocoapods pod, it has the advantage over OpenSSL's pods that the library doesn't need to 90*cc02d7e2SAndroid Build Coastguard Worker be precompiled. This eliminates the 10 - 20 minutes of wait the first time a user does "pod 91*cc02d7e2SAndroid Build Coastguard Worker install", lets it be used as a dynamic framework (pending solution of Cocoapods' issue #4605), 92*cc02d7e2SAndroid Build Coastguard Worker and works with bitcode automatically. It's also thought to be smaller than OpenSSL (which takes 93*cc02d7e2SAndroid Build Coastguard Worker 1MB - 2MB per ARM architecture), but we don't have specific numbers yet. 94*cc02d7e2SAndroid Build Coastguard Worker 95*cc02d7e2SAndroid Build Coastguard Worker BoringSSL arose because Google used OpenSSL for many years in various ways and, over time, built 96*cc02d7e2SAndroid Build Coastguard Worker up a large number of patches that were maintained while tracking upstream OpenSSL. As Google's 97*cc02d7e2SAndroid Build Coastguard Worker product portfolio became more complex, more copies of OpenSSL sprung up and the effort involved 98*cc02d7e2SAndroid Build Coastguard Worker in maintaining all these patches in multiple places was growing steadily. 99*cc02d7e2SAndroid Build Coastguard Worker 100*cc02d7e2SAndroid Build Coastguard Worker Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's not part of the 101*cc02d7e2SAndroid Build Coastguard Worker NDK) and a number of other apps/programs. 102*cc02d7e2SAndroid Build Coastguard Worker DESC 103*cc02d7e2SAndroid Build Coastguard Worker s.homepage = 'https://github.com/google/boringssl' 104*cc02d7e2SAndroid Build Coastguard Worker s.license = { :type => 'Mixed', :file => 'LICENSE' } 105*cc02d7e2SAndroid Build Coastguard Worker # "The name and email addresses of the library maintainers, not the Podspec maintainer." 106*cc02d7e2SAndroid Build Coastguard Worker s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' 107*cc02d7e2SAndroid Build Coastguard Worker 108*cc02d7e2SAndroid Build Coastguard Worker s.source = { 109*cc02d7e2SAndroid Build Coastguard Worker :git => 'https://github.com/google/boringssl.git', 110*cc02d7e2SAndroid Build Coastguard Worker :commit => "${boringssl_commit}", 111*cc02d7e2SAndroid Build Coastguard Worker } 112*cc02d7e2SAndroid Build Coastguard Worker 113*cc02d7e2SAndroid Build Coastguard Worker s.ios.deployment_target = '10.0' 114*cc02d7e2SAndroid Build Coastguard Worker s.osx.deployment_target = '10.12' 115*cc02d7e2SAndroid Build Coastguard Worker s.tvos.deployment_target = '12.0' 116*cc02d7e2SAndroid Build Coastguard Worker s.watchos.deployment_target = '6.0' 117*cc02d7e2SAndroid Build Coastguard Worker 118*cc02d7e2SAndroid Build Coastguard Worker name = 'openssl_grpc' 119*cc02d7e2SAndroid Build Coastguard Worker 120*cc02d7e2SAndroid Build Coastguard Worker # When creating a dynamic framework, name it openssl.framework instead of BoringSSL.framework. 121*cc02d7e2SAndroid Build Coastguard Worker # This lets users write their includes like `#include <openssl/ssl.h>` as opposed to `#include 122*cc02d7e2SAndroid Build Coastguard Worker # <BoringSSL/ssl.h>`. 123*cc02d7e2SAndroid Build Coastguard Worker s.module_name = name 124*cc02d7e2SAndroid Build Coastguard Worker 125*cc02d7e2SAndroid Build Coastguard Worker # When creating a dynamic framework, copy the headers under `include/openssl/` into the root of 126*cc02d7e2SAndroid Build Coastguard Worker # the `Headers/` directory of the framework (i.e., not under `Headers/include/openssl`). 127*cc02d7e2SAndroid Build Coastguard Worker # 128*cc02d7e2SAndroid Build Coastguard Worker # TODO(jcanizales): Debug why this doesn't work on macOS. 129*cc02d7e2SAndroid Build Coastguard Worker s.header_mappings_dir = 'src/include/openssl' 130*cc02d7e2SAndroid Build Coastguard Worker 131*cc02d7e2SAndroid Build Coastguard Worker # The above has an undesired effect when creating a static library: It forces users to write 132*cc02d7e2SAndroid Build Coastguard Worker # includes like `#include <BoringSSL/ssl.h>`. `s.header_dir` adds a path prefix to that, and 133*cc02d7e2SAndroid Build Coastguard Worker # because Cocoapods lets omit the pod name when including headers of static libraries, the 134*cc02d7e2SAndroid Build Coastguard Worker # following lets users write `#include <openssl/ssl.h>`. 135*cc02d7e2SAndroid Build Coastguard Worker s.header_dir = name 136*cc02d7e2SAndroid Build Coastguard Worker 137*cc02d7e2SAndroid Build Coastguard Worker # We don't need to inhibit all warnings; only -Wno-shorten-64-to-32. But Cocoapods' linter doesn't 138*cc02d7e2SAndroid Build Coastguard Worker # want that for some reason. 139*cc02d7e2SAndroid Build Coastguard Worker s.compiler_flags = '-DOPENSSL_NO_ASM', '-GCC_WARN_INHIBIT_ALL_WARNINGS', '-w', '-DBORINGSSL_PREFIX=GRPC' 140*cc02d7e2SAndroid Build Coastguard Worker s.requires_arc = false 141*cc02d7e2SAndroid Build Coastguard Worker 142*cc02d7e2SAndroid Build Coastguard Worker # Like many other C libraries, BoringSSL has its public headers under `include/<libname>/` and its 143*cc02d7e2SAndroid Build Coastguard Worker # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't 144*cc02d7e2SAndroid Build Coastguard Worker # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in 145*cc02d7e2SAndroid Build Coastguard Worker # practice). Because we need our `header_mappings_dir` to be `include/openssl/` for the reason 146*cc02d7e2SAndroid Build Coastguard Worker # mentioned above, we work around the linter limitation by dividing the pod into two subspecs, one 147*cc02d7e2SAndroid Build Coastguard Worker # for public headers and the other for implementation. Each gets its own `header_mappings_dir`, 148*cc02d7e2SAndroid Build Coastguard Worker # making the linter happy. 149*cc02d7e2SAndroid Build Coastguard Worker s.subspec 'Interface' do |ss| 150*cc02d7e2SAndroid Build Coastguard Worker ss.header_mappings_dir = 'src/include/openssl' 151*cc02d7e2SAndroid Build Coastguard Worker ss.private_header_files = 'src/include/openssl/time.h' 152*cc02d7e2SAndroid Build Coastguard Worker ss.source_files = 'src/include/openssl/*.h' 153*cc02d7e2SAndroid Build Coastguard Worker end 154*cc02d7e2SAndroid Build Coastguard Worker s.subspec 'Implementation' do |ss| 155*cc02d7e2SAndroid Build Coastguard Worker ss.header_mappings_dir = 'src' 156*cc02d7e2SAndroid Build Coastguard Worker 157*cc02d7e2SAndroid Build Coastguard Worker ss.resource_bundles = { 158*cc02d7e2SAndroid Build Coastguard Worker s.module_name => 'src/PrivacyInfo.xcprivacy' 159*cc02d7e2SAndroid Build Coastguard Worker } 160*cc02d7e2SAndroid Build Coastguard Worker 161*cc02d7e2SAndroid Build Coastguard Worker ss.source_files = 'src/ssl/*.{h,c,cc}', 162*cc02d7e2SAndroid Build Coastguard Worker 'src/ssl/**/*.{h,c,cc}', 163*cc02d7e2SAndroid Build Coastguard Worker 'src/crypto/*.{h,c,cc}', 164*cc02d7e2SAndroid Build Coastguard Worker 'src/crypto/**/*.{h,c,cc}', 165*cc02d7e2SAndroid Build Coastguard Worker # We have to include fiat because spake25519 depends on it 166*cc02d7e2SAndroid Build Coastguard Worker 'src/third_party/fiat/*.{h,c,cc}', 167*cc02d7e2SAndroid Build Coastguard Worker # Include the err_data.c pre-generated in boringssl's master-with-bazel branch 168*cc02d7e2SAndroid Build Coastguard Worker 'err_data.c' 169*cc02d7e2SAndroid Build Coastguard Worker 170*cc02d7e2SAndroid Build Coastguard Worker ss.private_header_files = 'src/ssl/*.h', 171*cc02d7e2SAndroid Build Coastguard Worker 'src/ssl/**/*.h', 172*cc02d7e2SAndroid Build Coastguard Worker 'src/crypto/*.h', 173*cc02d7e2SAndroid Build Coastguard Worker 'src/crypto/**/*.h', 174*cc02d7e2SAndroid Build Coastguard Worker 'src/third_party/fiat/*.h' 175*cc02d7e2SAndroid Build Coastguard Worker # bcm.c includes other source files, creating duplicated symbols. Since it is not used, we 176*cc02d7e2SAndroid Build Coastguard Worker # explicitly exclude it from the pod. 177*cc02d7e2SAndroid Build Coastguard Worker # TODO (mxyan): Work with BoringSSL team to remove this hack. 178*cc02d7e2SAndroid Build Coastguard Worker ss.exclude_files = 'src/crypto/fipsmodule/bcm.c', 179*cc02d7e2SAndroid Build Coastguard Worker 'src/**/*_test.*', 180*cc02d7e2SAndroid Build Coastguard Worker 'src/**/test_*.*', 181*cc02d7e2SAndroid Build Coastguard Worker 'src/**/test/*.*' 182*cc02d7e2SAndroid Build Coastguard Worker 183*cc02d7e2SAndroid Build Coastguard Worker ss.dependency "#{s.name}/Interface", version 184*cc02d7e2SAndroid Build Coastguard Worker end 185*cc02d7e2SAndroid Build Coastguard Worker 186*cc02d7e2SAndroid Build Coastguard Worker s.pod_target_xcconfig = { 187*cc02d7e2SAndroid Build Coastguard Worker # Do not let src/include/openssl/time.h override system API 188*cc02d7e2SAndroid Build Coastguard Worker 'USE_HEADERMAP' => 'NO', 189*cc02d7e2SAndroid Build Coastguard Worker } 190*cc02d7e2SAndroid Build Coastguard Worker 191*cc02d7e2SAndroid Build Coastguard Worker s.prepare_command = <<-END_OF_COMMAND 192*cc02d7e2SAndroid Build Coastguard Worker set -e 193*cc02d7e2SAndroid Build Coastguard Worker 194*cc02d7e2SAndroid Build Coastguard Worker # To avoid symbol conflict with OpenSSL, gRPC needs to rename all the BoringSSL symbols with a 195*cc02d7e2SAndroid Build Coastguard Worker # prefix. This is done with BoringSSL's BORINGSSL_PREFIX mechanism 196*cc02d7e2SAndroid Build Coastguard Worker # (https://github.com/google/boringssl/blob/75148d7abf12bdd1797fec3c5da9a21963703516/BUILDING.md#building-with-prefixed-symbols). 197*cc02d7e2SAndroid Build Coastguard Worker # The required prefix header file boringssl_prefix_symbols.h is not part of BoringSSL repo at 198*cc02d7e2SAndroid Build Coastguard Worker # this moment. It has to be generated by BoringSSL's users and be injected to BoringSSL build. 199*cc02d7e2SAndroid Build Coastguard Worker # gRPC generates this file in script /tools/distrib/upgrade_boringssl_objc.sh. This script 200*cc02d7e2SAndroid Build Coastguard Worker # outputs a gzip+base64 encoded version of boringssl_prefix_symbols.h because of Cocoapods' 201*cc02d7e2SAndroid Build Coastguard Worker # limit on the 'prepare_command' field length. The encoded header is generated from 202*cc02d7e2SAndroid Build Coastguard Worker # /src/boringssl/boringssl_prefix_symbols.h. Here we decode the content and inject the header to 203*cc02d7e2SAndroid Build Coastguard Worker # the correct location in BoringSSL. 204*cc02d7e2SAndroid Build Coastguard Worker case "$(uname)" in 205*cc02d7e2SAndroid Build Coastguard Worker Darwin) opts="" ;; 206*cc02d7e2SAndroid Build Coastguard Worker *) opts="--ignore-garbage" ;; 207*cc02d7e2SAndroid Build Coastguard Worker esac 208*cc02d7e2SAndroid Build Coastguard Worker base64 --decode $opts <<EOF | gunzip > src/include/openssl/boringssl_prefix_symbols.h 209*cc02d7e2SAndroid Build Coastguard Worker % for line in compress_and_encode_file('src/boringssl/boringssl_prefix_symbols.h'): 210*cc02d7e2SAndroid Build Coastguard Worker ${line.decode('utf-8')} 211*cc02d7e2SAndroid Build Coastguard Worker % endfor 212*cc02d7e2SAndroid Build Coastguard Worker EOF 213*cc02d7e2SAndroid Build Coastguard Worker 214*cc02d7e2SAndroid Build Coastguard Worker # PrivacyInfo.xcprivacy is not part of BoringSSL repo, inject it during pod installation 215*cc02d7e2SAndroid Build Coastguard Worker base64 --decode $opts <<EOF | gunzip > src/PrivacyInfo.xcprivacy 216*cc02d7e2SAndroid Build Coastguard Worker % for line in compress_and_encode_file('src/objective-c/PrivacyInfo.xcprivacy'): 217*cc02d7e2SAndroid Build Coastguard Worker ${line.decode('utf-8')} 218*cc02d7e2SAndroid Build Coastguard Worker % endfor 219*cc02d7e2SAndroid Build Coastguard Worker EOF 220*cc02d7e2SAndroid Build Coastguard Worker 221*cc02d7e2SAndroid Build Coastguard Worker # We are renaming openssl to openssl_grpc so that there is no conflict with openssl if it exists 222*cc02d7e2SAndroid Build Coastguard Worker find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include <openssl/;#include <openssl_grpc/;g' 223*cc02d7e2SAndroid Build Coastguard Worker 224*cc02d7e2SAndroid Build Coastguard Worker # Include of boringssl_prefix_symbols.h does not follow Xcode import style. We add the package 225*cc02d7e2SAndroid Build Coastguard Worker # name here so that Xcode knows where to find it. 226*cc02d7e2SAndroid Build Coastguard Worker find . -type f \\( -path '*.h' -or -path '*.cc' -or -path '*.c' \\) -print0 | xargs -0 -L1 sed -E -i'.grpc_back' 's;#include <boringssl_prefix_symbols.h>;#include <openssl_grpc/boringssl_prefix_symbols.h>;g' 227*cc02d7e2SAndroid Build Coastguard Worker END_OF_COMMAND 228*cc02d7e2SAndroid Build Coastguard Worker end 229