Chromiumにシークレット"タブ"を追加する
今回の目標
Chromeを使っていて、閲覧履歴を残したくない、というときありますよね。
そんなときに活躍するのが「シークレットウィンドウ」なのですが、
普通のブラウザとシークレットモードのブラウザを分けて開かなくてはなりません。
...不便じゃないですか?不便ですよね。はい。
ということで今回はChromiumにシークレット"タブ"を追加してみようと思います。
まずはシークレットウィンドウに関連する部分を探す
いきなり変更を加えると言ってもChromiumのソースコードは膨大な量なのでどこから手を付けていいか見当も付きません。
まずは関係ありそうなところをChromium Code Searchで探ってみましょう。
シークレットモードは内部では"Incognito"と言うようなのでnewincognitowindowで検索してみると、
あった。(実は探すのめっちゃ苦労したけどそれは内緒)
見てみるとその下にはちょうどNewTabなんて関数も。
この2つを組み合わせればシークレットタブを作れちゃうのでは?
NewWindowとNewIncognitoWindowを見比べてみると、プリプロセッサ指令の違いはあるものの大きな違いは
GetOriginalProfile()かGetOffTheRecordProfile()かの違い。
これを踏まえてNewIncognitoTabを作ってみる。
コードを書き換えていく
タブを開くときにbrowserのprofileごと書き換えちゃおうという強引な発想。
ただbrowserのprofileは書き換えられないようconst定義がされていたのでそれを外しついでにセッターを定義。
またこのままだと続けて開くタブが全てシークレットモードになってしまうためNewTabにGetOriginalProfile()の処理を追加。
そしてチェックを一つ外す。
さて、なかなか強引だができたんじゃなかろうか...?
ということで試しにシークレットウィンドウを開くボタンをシークレットタブに割り当てて実行してみる。
とりあえずテスト
...こんな適当な変更で動いてしまった。
履歴もしっかり残らないしログイン情報も残らない。
今回はテスト的にシークレットウィンドウボタンに割り当てましたが
次回は"シークレットタブを開く"コマンドを追加して、見た目をそれっぽくしていきます。
Chromiumをgdbでデバッグする
Chromiumの動作を追う
以前Chromiumのソースコードを読み解くツールとしてChromium Code Searchを紹介しました。
しかし、名前に全く見当がつかなくて検索できない!ということもあると思います。
そんなときはデバッグで実際の動きを追ってやりましょう。
今回はgdbでChromiumをデバッグする際に有用なコマンドを紹介します。
プロセスを選んでデバッグする
まずはChromiumを起動した状態で、別のコンソールからその実行プロセスIDを調べてみましょう。
$ ps axf
すると現在実行されているプロセスがツリー状に表示されます。その中にさっき起動したChromiumもありましたね。
今回は新しいタブを開く動作を追うために、試しに赤枠で囲ったプロセスを追ってみましょう。
$ gdb -p 9089
このように"-p"オプションにプロセスIDを指定することで目的のプロセスをデバッグすることができる。
プロセスIDはps axfでいう一番左の列ですね。
子プロセスを追う
gdbでマルチプロセスのアプリケーションを追う場合、通常の設定では子プロセスが発生した場合でも、gdbはもとの親プロセスを追い続けてしまう。
子プロセスでの動作を追いたいときには
> set follow-fork-mode child
と指定することにより、プロセスが分かれた際に子プロセスに追従が移るようになります。
シングルプロセスでデバッグする
上のやり方ではプロセスIDを指定するためどのプロセスで目的の動作が行われているかわかっている必要があった。
しかしプロセスが大量でどのプロセスが何なのかわからない、ということもあると思います。
そんなとき有効なのがシングルプロセスモード。
Chromiumでは以下のオプションが公式でサポートされている...
> r --single-process
サポートされている...
[7117:7117:1024/155349.170354:ERROR:CONSOLE(1096)] "Uncaught TypeError: Cannot read property 'newTabPage' of undefined", source: chrome-search://local-ntp/local-ntp.js (1096)
されているはず...なんですが...サポートされていないオプションとして複数のエラーが発生する。。
アップデートで消えてしまったのでしょうか。
代わりに
> r -X
上のようなコマンドでシングルプロセスモードを指定することができます。
こちらはエラーもなくデバッグすることが可能。
これにより指定したブレークポイントを逃さず実行することができちゃいます。
最適な方法を
ここまで様々な方法を紹介しましたが、ときにより有効な手立ては違うでしょう。
最適なデバッグ方法を選べると良いですね。
Chromiumのコードを探る
Chromiumのソースを見てみたい
ソースコードになにか変更を加えてみたい!というとき、
まずはどこに何が書いてあるか調べなきゃいけないですよね。
でも自分で逐一ファイルを見ていくのは流石に手間がかかりすぎる。。
そんなときに役立つ便利な公式サイトを紹介します。
Chromium Code Search
こちらはChromiumのソースコードの中から自由に検索ができるサイト。
膨大なソースコードからすぐに検索を行うことができる強力な検索ツールです。
ソースコードを表示する画面では、
- クリックで関数の定義にジャンプ
- ファイル内検索
- 対象OSの変更
などなど様々な機能が用意されています。
気になる機能があるときはまず適当に検索にかけてみるのが発見への近道かも。
Design Document
こちらもChromium Project内で開発者向けに公開されているドキュメント。
主要な機能を司る部分の構造などが解説されています。
その部分がどのような意図に基づいて書かれているのか、などが解説されている場合が多いので
不可解に見える構造のコードでもデザインドキュメントに一度目を通してみると理解できるかも(?)
大規模だからこそ
Chromiumなどの大規模なソースコードを読み解くためには
まずデバッグするよりも検索ツールを利用したほうが有効だったりもするんですね。
ChromiumをGitでバージョン管理する
お馴染みのバージョン管理ツールGit
Chromiumをバージョン管理する上でもGitを使いたいところですが、Chromiumはcommitするにも一苦労。
Chromiumには先人のGit情報が
Chromiumをビルドするときにgclientのfetchを使ってソースをダウンロードしてきたのを覚えているでしょうか?
gclientはgitベースのツールですので、持ってきたディレクトリの中にはgit管理されていた名残がたくさん残っています。
gitは差分を記録する方式なので、このままcommitしようとすると、一部のファイルのみしかcommitされません。。
Chromiumをcommitするには
なのでcommitするには中のgit情報を削除する必要があります。
ディレクトリの各所に存在する.gitフォルダをすべて削除してしまいましょう。
検索して一つ一つ削除していってもいいですが、 、
$ find ./ -name ".git" -exec rm -rf {} \;
を実行してしまえばディレクトリ内すべての.gitを削除できます。
その後
$ git add . $ git commit -m "your comment" -a
でcommitすればchromiumソース全体をバージョン管理することができます。
変更を保存するときはぜひ利用しましょう。
ChromiumをWSL(Windows Subsystem for Linux)上でビルドしたい
お手軽WSL
April Updateで正式に追加されたbash on Windows改めWindows Subsystem for Linux、通称WSL。気軽にLinux環境が使えるということで期待が高まります。
Windows上でのビルドは時間がかかりすぎる...のでChromiumのビルドもWSL上でできたら時間も短縮できて良さそうですよね。
ということで試してみました。
WSLの導入方法に関しては過去の記事をを参考にしてください。
いよいよビルドしてみる
ビルドの詳しい手順に関しては以前の記事を参照してください。
さて、順調に手順をすすめていったところ...
$ gclient runhooks
Syncing projects: 100% (206/206), done. Running hooks: 5% ( 4/75) nacltools ________ running '/usr/bin/python src/build/download_nacl_toolchains.py --mode nacl_core_sdk sync --extract' in '/home/ybn/chromium' INFO: Extracting package (nacl_arm_glibc) to directory: /home/***/chromium/src/native_client/toolchain/linux_x86/nacl_arm_glibc INFO: Extracting binutils_arm_x86_64_linux.tgz (1/6) |------------------------------------------------| .................................................. INFO: Extracting gcc_arm_x86_64_linux.tgz (2/6) |------------------------------------------------| .................................................. INFO: Extracting gcc_libs_arm.tgz (3/6) |------------------------------------------------| ................................................. INFO: Extracting gdb_x86_64_linux.tgz (4/6) |------------------------------------------------| ................................................. INFO: Extracting glibc_arm.tgz (5/6) |------------------------------------------------| ................................................. Traceback (most recent call last): File "src/build/download_nacl_toolchains.py", line 59, in <module> sys.exit(Main(sys.argv[1:])) File "src/build/download_nacl_toolchains.py", line 55, in Main return package_version.main(args) File "/home/***/chromium/src/native_client/build/package_version/package_version.py", line 1289, in main return COMMANDS[arguments.command].do_cmd_func(arguments) File "/home/***/chromium/src/native_client/build/package_version/package_version.py", line 856, in _DoSyncCmd quiet=arguments.quiet) File "/home/***/chromium/src/native_client/build/package_version/package_version.py", line 562, in ExtractPackageTargets pynacl.file_tools.MoveAndMergeDirTree(temp_src_dir, destination_dir) File "/home/***/chromium/src/native_client/pynacl/file_tools.py", line 204, in MoveAndMergeDirTree MoveAndMergeDirTree(source_item, destination_item) File "/home/***/chromium/src/native_client/pynacl/file_tools.py", line 214, in MoveAndMergeDirTree Retry(os.rename, source_item, destination_item) File "/home/***/chromium/src/native_client/pynacl/file_tools.py", line 250, in Retry op(*args, **kwargs) OSError: [Errno 13] Permission denied Error: Command '/usr/bin/python src/build/download_nacl_toolchains.py --mode nacl_core_sdk sync --extract' returned non-zero exit status 1 in /home/***/chromium Hook '/usr/bin/python src/build/download_nacl_toolchains.py --mode nacl_core_sdk sync --extract' took **.** secs
以上のようなエラーが発生。何度やっても同じ場所でエラーが出てしまう。
chmodなども試しましたが解決しませんでした。。
実は...
このエラー、実は各所で報告されているエラーのようです。
まだWSLの日が浅いので報告数も少なく、いろいろ探し回りましたが今のところ有効な解決策も見つかっていません。
結論
つまり、WSL上でChromiumをビルドするのは諦めましょう。
Windows Subsystem for Linux(WSL)の導入方法
お手軽Linux
Linuxを使ってみたい!けどパーティション...?とかよくわかんないしデータを飛ばしたくない!
っていう人は多いと思います。そんな人におすすめなのがこのWindows Subsystem for Linux(通称WSL)!
簡単にWindows上でLinuxライクな環境を動かすことができます。
WSLとは
以前から限定的に利用されていたBash on Windowsが2018年のApril Updateによって正式にリリースされWSLとして生まれ変わり、Windows10なら誰でも利用できるようになりました。
UbuntuやDebianなど配信されている中から環境を選ぶこともできちゃうんです。すごいですね。
導入方法
ではさっそく導入していきましょう。
下準備
まずはWSLが利用できるように機能を有効化します。
コントロールパネルの「Windowsの機能の有効化または無効化」を開きます。
]
するとその中に「Windows Subsystem for Linux」の項目があると思いますのでチェックを有効にします。
再起動を求められたらそのまま再起動しましょう。
はい、準備完了です。
環境をインストール
好みの環境を入手しましょう。
Microsoft Storeを開き画像のように検索すると,,,
入手可能な環境が表示されるのであとはクリックしてインストールするだけ。
起動も入手してきたアプリを開けばOK。なんて簡単なんでしょう。
しかし問題点も
とってもお手軽にLinux環境を入手できて良いのですが、完全にLinuxと同じことができる、というわけでもなさそうです。
Windowsのユーザーの下に環境を作ることによって権限が与えられない箇所があるようで、 致命的なエラーにつながることもあるので、できないことがあっても手軽さに免じてまあ許してあげましょう。
Chromiumを自分でビルドしてみよう
自分でChromeの機能を作りたい
Chromeってとっても便利ですよね。
でも使っていると、「こんな機能ほしいな...」と思うことがたまにあります。
拡張機能を探してもそれらしいのが見つからない...。
よし、自分で作ってしまえばいいんだ。
ChromeとChromium
とはいってもChromeはGoogleの著作物なのでソースを勝手に書き換えちゃお~とかはできません。
そこで登場するのが「Chromium」。一言で言ってしまえばソースコードがすべて公開されてるChrome。
詳しく知りたい人は公式サイトを見てみるといいでしょう。 www.chromium.org
さっそくビルドしてみよう
- 用意するもの
- linux環境
- 時間
以上。初回ビルドにはとにかく時間がかかります。心してかかりましょう。
WindowsやMacでもできないことはないですが、おそらく30時間程かかります。
linux上でやることを強くオススメします。私はUbuntu16.04とUbuntu18.04で行っていました。
また、WSL(Windows Subsystem for Linux、旧bash on windows)は今のところ使えません。
ちなみに、ここに書いてあることはきっとすぐに古くなるでしょう。 もしうまく行かなかったら公式のドキュメントを確認してください。
Checking out and building Chromium on Linux
ビルド準備
必要なパッケージはだいたい同梱されているので、事前準備としてはpython, build-essential, git, vimがあればいいはず。
$ sudo apt-get install python build-essential git vim
depot_toolsの取得
まずはビルドに必要なツール「depot_tools」をcloneしてくる。depot_toolsにはgclientを始めChromiumを管理するツールがたくさん含まれています。
gclientの扱いなんかで困ったら公式サイトに使い方があるので見てみよう。
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
今後の操作はこの中のツールを使って行うので必ずpathを通しておく。
相対パスを用いるとdepot_toolsがうまく読み込まないので、絶対パスを使うか
$ export PATH="$PATH:/path/to/depot_tools"
$HOMEを使って
$ export PATH="$PATH:${HOME}/depot_tools"
直接実行したり.bashrcに追加したりしましょう。
ソースの取得
ソースを保存したいディレクトリに移動しdepot_tools内のfetchを使い、ソースを持ってくる。この際デフォルトではバージョン履歴がついてくるが無くすと時間を短縮できるので--no-historyオプションを推奨します。
$ fetch --nohooks --no-history chromium
これには早くても15分ほどはかかります。ソースコードのcheckoutが完了するとsrcができているので移動する。
$ cd src
続いてUbuntuの場合、依存性を解決してくれるシェルスクリプトが用意されているので実行する。
$ sudo build/install-build-deps.sh
hooksを実行する準備ができたのでパッケージを入手。
$gclient runhooks
これでビルド準備は完了です。
ninjaでビルド
depot_tools内のninjaツールを使ってビルドしていきます。
ninjaはC++ベースで作られているオープンソースのビルドツールで...詳細は公式サイト。
Ninja, a small build system with a focus on speed
まずビルドのためにディレクトリを作成します。
$ gn gen out/Default
Default
を任意に書き換えることでビルド環境を分けられる。
このままビルドすることもできるがいくつかビルドオプションを加えることでビルド時間を短縮できる。
$ gn args out/Default
実行するとvimが起動するのでオプションを改行区切りで記述する。
vimを普段使わない人向けに書くと、Insertで入力を始め、保存するときにはEscを押して入力を離脱したあと:wqと打ちEnterを押すと上書き保存&終了することができます。
その際の内容はout/Default/args.gnに保存されるのであとから変更したいときはそこを変更すればいい。
以下、おすすめするオプションをご紹介。
Jumbo build
use_jumbo_build=true
複数のソースファイルを一緒にコンパイルする。公式によるとChromiumはヘッダファイルが共通してるソースが多いから早くなるらしい。よくわからないけど実際早くなる。
Jumbo buildに関して詳しく知りたい人はこっち。
Jumbo / Unity builds
NaClの無効化
enable_nacl=false
多くの場合NaCl(Native Client)はなくても問題ない。無効化しちゃおう。
Welcome to Native Client - Google Chrome
他にデバッグシンボル系が多く存在するが今回はデバッグもしたいのでいじらない。
ビルドオプションに凝りたい人は公式サイトを読んでみよう。
www.chromium.org
ついにビルド
$ autoninja -C out/Default chrome
chromiumのビルドだけど名前はchromeなので間違えないようにね。
早くても2時間ほどはかかるので気長に待ちましょう。
とりあえず実行してみよう
$ out/Default/chrome
warningがたくさん出るかもしれないが無事に起動すればビルドは成功。