Slide 1

Slide 1 text

Introduction to Custom
 Android Browsers @DroidKaigi 2019 on 2019.02.08 Tomoya ASAI (CTO, WebDINO Japan)

Slide 2

Slide 2 text

about:me Tomoya ASAI - dynamis webdino.org CTO Tech Speaker dynamis @ Community Twitter: @dynamitter facebook.com/dynamis I LOVE Firefox = Red Panda = Petit Panda = Lesser Panda 2 @

Slide 3

Slide 3 text

about: WebDINO Japan Web, Browser, Open ( : ) (Chromium, Firefox ) ( : Gecko ) Web & Open Web IoT 2017 : Mozilla Japan WebDINO Japan https://www.webdino.org/ 3

Slide 4

Slide 4 text

about: WebDINO Japan Web, Browser, Open ( : ) (Chromium, Firefox ) ( : Gecko ) Web & Open Web IoT 2017 : Mozilla Japan WebDINO Japan https://www.webdino.org/ 4

Slide 5

Slide 5 text

Today's Topics Why Custom Browsers Firefox Building Firefox Customizing Firefox Chromium Building Chromium Customizing Chromium Conclusion 5

Slide 6

Slide 6 text

Questions

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Why Custom Browsers

Slide 12

Slide 12 text

Web AOSP Chrome Chrome #DroidKaigi 12

Slide 13

Slide 13 text

Building Firefox

Slide 14

Slide 14 text

Firefox for Android hg (mercurial) GitHub Artifact C 翻 UI OK mozcon g 14

Slide 15

Slide 15 text

Firefox for Android hg clone https://hg.mozilla.org/mozilla-central cd mozilla-central # mercurial をどうしても使いたくない場合は git ミラーから: # git clone https://github.com/mozilla/gecko- dev.git; cd gecko-dev # 開発環境のセットアップ ./mach bootstrap # ビルド、パッケージ作成、インストール、起動 ./mach build # artifact モードの場合は ./mach build mobile/android ./mach package ./mach install ./mach run https://developer.mozilla.org/docs/Mozilla/Developer_Guide/Build_Documentation/Simple_Firefox_for_Android_build 15

Slide 16

Slide 16 text

( ) mozcon g # Firefox for Android をビルドする: ac_add_options --enable-application=mobile/android ac_add_options --target=arm-linux-androideabi # Android SDK/NDK のパスをフルパスで設定: ac_add_options --with-android-sdk="/absolute/path/ to/.mozbuild/android-sdk" ac_add_options --with-android-ndk="/absolute/path/ to/.mozbuild/android-ndk-r11c" # ビルド結果の出⼒ディレクトリ: mk_add_options MOZ_OBJDIR=./objdir-droid https://developer.mozilla.org/docs/Mozilla/Developer_Guide/Build_Documentation/Simple_Firefox_for_Android_build 16

Slide 17

Slide 17 text

Artifact mozcon g # Firefox for Android をビルドする: ac_add_options --enable-application=mobile/android ac_add_options --target=arm-linux-androideabi # Android SDK のパスをフルパスで設定 (NDK 不要): ac_add_options --with-android-sdk="/absolute/path/ to/.mozbuild/android-sdk" # Artifact モードでのビルドを指定: ac_add_options --enable-artifact-builds # ビルド結果の出⼒ディレクトリ: mk_add_options MOZ_OBJDIR=./objdir-frontend https://developer.mozilla.org/docs/Mozilla/Developer_Guide/Build_Documentation/Simple_Firefox_for_Android_build 17

Slide 18

Slide 18 text

Slide 19

Slide 19 text

... en-US ( ) https://firefox-source-docs.mozilla.org/build/buildsystem/locales.html 19

Slide 20

Slide 20 text

( ) # まずは英語単⼀ロケールビルドを作成 ./mach build ./mach package # 各⾔語のファイルを⽣成 export MOZ_CHROME_MULTILOCALE="ja zh-TW" for AB_CD in $MOZ_CHROME_MULTILOCALE; do ./mach build chrome-$AB_CD done # マルチロケールビルドとしてリパッケージ AB_CD=multi ./mach package Firefox 52 20

Slide 21

Slide 21 text

... Mozilla ... OS en-US Accept-Laguage ... ( ) : 翻 21

Slide 22

Slide 22 text

https://hg.mozilla.org/releases/mozilla-release/ ESR ( ) https://hg.mozilla.org/releases/mozilla-esr60/
 https://hg.mozilla.org/releases/mozilla-esr52/ ( branding ) 22

Slide 23

Slide 23 text

Mozilla mozharness 翻 10 / : https://treeherder.mozilla.org/ mozharness 翻 mozharness ( ) 翻 ... Mozilla 23

Slide 24

Slide 24 text

mozharness # 対象リリースブランチのファイルをクローンして mozconfig を⽤意 hg clone https://hg.mozilla.org/releases/mozilla-esr60/ mozilla-central # 対象リリースブランチの mozconfig と mozharness 設定テンプレを⼿元にコピー cp mozilla-central/mobile/android/config/mozconfigs/android-api-16/ l10n-nightly mozconfig cp mozilla-central/testing/mozharness/configs/developer_config.py config.py # 設定ファイルを編集。mozconfig は依存先にも注意。作りたいビルド設定を参考に書き換え: # mozharness/configs/multi_locale/mozilla-release_android.json nano mozconfig nano config.py # ⾔語リソースファイルを取得 mozilla-central/testing/mozharness/scripts/multil10n.py --cfg config.py --pull-build-source # ここでカスタマイズしたい内容に応じて各ファイルを編集 # ビルド (ビルド、英語版パッケージ、ロケール追加、マルチロケールビルド) を実⾏! mozilla-central/testing/mozharness/scripts/multil10n.py --cfg config.py 24

Slide 25

Slide 25 text

...

Slide 26

Slide 26 text

Customizing Firefox

Slide 27

Slide 27 text

Firefox (Yahoo, Yandex...) PC ( ...) FireTV UI Google FireTV YouTube YouTube Firefox ( Silk) Note: Android YouTube Google Firefox for FireTV: https://github.com/mozilla-mobile/firefox-tv 27

Slide 28

Slide 28 text

: Firefox OS VIERA Firefox OS "My Home Screen" Firefox OS Firefox UK "powered by Firefox OS" "OS" AOSP Panasonic FreeBSD FxOS "OS" https://medium.com/@bfrancis/the-legacy-of-firefox-os-c58ec32d94f0 28

Slide 29

Slide 29 text

Distribution Files DL 1. /data/data/org.mozilla. refox/distribution/ 2. /system/org.mozilla. refox/distribution/ 3. Google Play https://wiki.mozilla.org/Mobile/Distribution_Files 29

Slide 30

Slide 30 text

Distribution Files ( ) { "Preferences": { "general.useragent.device_string": "XXXXXX %DEVICEID% Build/ Xxxxxx%DEVICEID%", "general.useragent.use_device": true }, "ApplicationPreferences": { "newtab.load_homepage": true }, "AndroidPreferences": { "distribution.read_partner_bookmarks_provider": true, "distribution.read_partner_customizations_provider": true, "homepage": "http://home.att.com", "suggestedSites.hidden": "https://www.xxxxxx.xxx/", "distribution.set_as_homepage": true, "startpane_enabled": false } } preferences.json 30

Slide 31

Slide 31 text

: User Agent User Agent i-mode Firefox 41 OS ( Top100+ ) UA nger printing https://developer.mozilla.org/ja/docs/Web/HTTP/Gecko_user_agent_string_reference 31

Slide 32

Slide 32 text

Firefox Distribution Files UI Artifact Android mozharness 32

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

WebDINO Japan : https://www.webdino.org/contact/ 34

Slide 35

Slide 35 text

Building Chromium

Slide 36

Slide 36 text

Chromium for Android Firefox 4 5 200 300GB Firefox Artifact Google Corei7-4770 (3.9GHz 4core) 16GB HDD 駄 1 5 36

Slide 37

Slide 37 text

Chromium Firefox CPU arch 1 (~2) API level 1 
 (arm64 ) Chromium CPU arch 2 API level 3 
 (x86 arch 3 ) 4-5 x 6 20-30 37

Slide 38

Slide 38 text

UI UI C 翻 ( ) unsigned 64bit md5 ID ... https://ftagada.wordpress.com/2011/01/08/chromium-translations-explained-part-1/ 38

Slide 39

Slide 39 text

Chromium #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" Item(IDS_PREFERENCES) Mac ( Android ... ) 39 設定... chrome/app/resources/generated_resources_ja.xtb chrome/browser/ui/cocoa/main_menu_builder.mm chrome/app/generated_resources.grd Preferences...

Slide 40

Slide 40 text

Chrome i18n GRIT GRIT https://www.chromium.org/developers/tools- we-use-in-chromium/grit https://cs.chromium.org/chromium/src/tools/ grit/ OSS console (server) Google https://ftagada.wordpress.com/2011/01/08/chromium-translations-explained-part-1/ 40

Slide 41

Slide 41 text

OSS

Slide 42

Slide 42 text

...

Slide 43

Slide 43 text

Chromium # まずはツールクローンしてパスを通す git clone https://chromium.googlesource.com/ chromium/tools/depot_tools.git export PATH="$PATH:/path/to/depot_tools" mkdir ~/chromium && cd ~/chromium fetch --nohooks android # gn は configure のようなもの gn gen --args='target_os="android" is_chromecast=true' out/Default # ninja は make のようなもので auto は並列数 -j 調整 autoninja -C out/Default chrome_public_apk https://chromium.googlesource.com/chromium/src/+/master/docs/android_build_instructions.md 43

Slide 44

Slide 44 text

# Make sure you are in 'src'. # This part should only need to be done once, but it won't # hurt to repeat it. (...以下略...何⾔ってんだこいつw) gclient sync --with_branch_heads --with_tags # You may have to explicitly 'git fetch origin' to pull branch-heads/ git fetch # Checkout the branch 'src' tree. git checkout -b branch_$BRANCH branch-heads/$BRANCH # Checkout all the submodules at their branch DEPS revisions. gclient sync --with_branch_heads --with_tags https://www.chromium.org/developers/how-tos/get-the-code/working-with-release-branches 44

Slide 45

Slide 45 text

Customizing Chromium

Slide 46

Slide 46 text

https://urls.jp/vm Android : https://urls.jp/vmdroid Chrome : https://urls.jp/vmext 46

Slide 47

Slide 47 text

: VideoMark Browser http://vm.webdino.org/ Paravi, TVer, YouTube Chromium API ( ) : https://github.com/videomark/videomark-browser 47 https://urls.jp/vm

Slide 48

Slide 48 text

VM 48 ֶज़ݚڀ༻σʔλ
 ΍ௐࠪ෼ੳ݁ՌΛ
 Ұൠެ։ ૹ৴ ʲΫϥΠΞϯτ৘ใʳ w ୺຤छผ
 1$PSϞόΠϧ w ϒϥ΢βόʔδϣϯ w 04όʔδϣϯ౳ ஫ࢯ໊ɾॅॴ౳ͷݸਓ ಛఆ৘ใ͸ؚ·ͳ͍
 6TFS"HFOU͔Β൑அ ʲωοτϫʔΫ৘ใʳ w ௨৴ࣄۀࣾɾ*41 w ஍Ҭ ౎ಓ෎ݝ ౳ ஫ૹ৴ݩ*1ΞυϨεΛ ಗ໊Խ ຤ඌΦΫςοτ ࡟আ ޙʹ(FP*1Ͱਪఆ ʲ࠶ੜ඼࣭ύϥϝʔλʳ w ಈը৘ใϏοτϨʔτɺ ղ૾౓ɺϑϨʔϜϨʔτ౳ w ࠶ੜ৘ใ࠶ੜͷதஅɺόο ϑΝϦϯά౳ w ૢ࡞৘ใಈըͷγʔΫɺ Ұ࣌ఀࢭɾ࠶։౳ 8FC7JEFP.BSL֦ுػೳ΍ϒϥ΢βʔͰࢹௌ৘ใΛऔಘ ࢹௌͨ͠ಈըͷ ମײ඼࣭ 2P& Λ dͷ਺஋ͱͯ͠ ϑΟʔυόοΫ ಈըαʔϏεͷ ਪఆମײ඼࣭஋ 2P& 2VBMJUZPG&YQFSJFODF ಈը഑৴αʔϏεɾ $%/αʔόʔ 8FC 7JEFP.BSL αʔόʔ ࢹௌ৘ใΛ෼ੳ ௨৴ࣄۀऀɾ*41 αʔϏεվળ༻ʹ ௐࠪσʔλΛఏڙ ར༻ऀͷ ϒϥ΢βʔ ʂ ಈըࢹௌ࣌ͷ 2P&Λ֬ೝ ϓϥΠόγʔอޢॲཧ ֶज़ݚڀ༻σʔλ࡞੒ ಈը഑৴αʔϏε΁ΞΫηε )5.-ɺಈըϑΝΠϧ౳Λड৴ ಗ໊Խॲཧ

Slide 49

Slide 49 text

: Web VideoMark Android 49

Slide 50

Slide 50 text

: : Android PC or Android Chrome : ENABLE_EXTENSIONS 50 https://urls.jp/vm

Slide 51

Slide 51 text

# chrome/renderer/chrome_content_renderer_client.cc # ここで実⾏してください的なコードがあちこちにある: void ChromeContentRendererClient::RunScriptsAtDocumentEnd( content::RenderFrame* render_frame) { #if BUILDFLAG(ENABLE_EXTENSIONS) ChromeExtensionsRendererClient::GetInstance()- >RunScriptsAtDocumentEnd( render_frame); // |render_frame| might be dead by now. #endif # ここでコード挿⼊関数を呼び出そう! # InjectScript(render_frame) } https://cs.chromium.org/chromium/src/chrome/renderer/chrome_content_renderer_client.cc 51

Slide 52

Slide 52 text

( ) void InjectScript(content::RenderFrame* render_frame) { WebLocalFrame* frame = render_frame->GetWebFrame(); GURL url = GURL(frame->GetDocument().Url()); if (render_frame->IsMainFrame()) { base::StringPiece source_piece = ui::ResourceBundle::GetSharedInstance() .GetRawDataResource(IDR_CONTENT_JS); base::StringPiece injector = ui::ResourceBundle::GetSharedInstance() .GetRawDataResource(IDR_INJECT_JS); std::string source = base::ReplaceStringPlaceholders(injector, std::vector{source_piece.as_string()}, nullptr); blink::WebScriptSource source_in = blink::WebScriptSource(WebString::FromUTF8(source.data(), source.size())); frame->ExecuteScript(source_in); } } https://github.com/videomark/videomark-browser/blob/master/inject_sodium.diff 52

Slide 53

Slide 53 text

( ) // 先ほどの IDR_INJECT_JS の中⾝ let target = document.getElementsByTagName("body") [0]; let script = document.createElement("script"); script.setAttribute("type", "text/javascript"); // IDR_CONTENT_JS を script タグの中⾝に突っ込む script.innerText = "$1"; target.appendChild(script); // Web ページのコンテキストでコードを実⾏させる https://github.com/videomark/videomark-browser/blob/master/inject_sodium.diff 53

Slide 54

Slide 54 text

Chromium VideoMark Browser https://github.com/videomark/videomark-browser CopperheadOS Google https://github.com/CopperheadOS/ chromium_patches https://copperhead.co/android/docs/ building#chromium-and-webview 54

Slide 55

Slide 55 text

Conclusions

Slide 56

Slide 56 text

♥ Firefox ♥ 翻 ♥ Chromium ♥ API 56

Slide 57

Slide 57 text

: https://www.webdino.org/contact/ 57

Slide 58

Slide 58 text

Thank You! Any Questions? Feel free to contact me: dynamis webdino.org
 @dynamitter, facebook.com/dynamis Slide Upload: speakerdeck.com/dynamis by @4687koSourijun @