「Google Lensで画像を検索」機能の呼び出し過程を追う
PC版Chromeに搭載された「Google Lensで画像を検索」機能が気になっている
ブラウザの右パネルを活用し始めた傾向がみられ、このUIも気になるのでコードを読んでいく 
画像上でコンテキストメニューがクリックされた後、どういう流れを経て右パネルで検索結果が表示されるか
予想 
タブのスクリーンショットを撮る
画像の領域情報を保持する
スクリーンショットと領域情報がGoogle Lens APIに渡される
正解 (現時点での理解)
コンテキストメニューがクリックされた画像ノードを取得する
画像のビットマップからPNG形式のサムネイル画像をつくる
画像データそのものがGoogle Lens APIに渡される
未整理の調査メモ
「lens」で検索してみる
components/lens/lens_features.cc
おなじみのkで始まる定数の宣言
enable-side-panel
内部的にはregion-searchと呼ばれている?
components/lens/lens_entrypoints.cc
GetLensQueryParametersMap(lens::EntryPoint ep, bool is_side_panel_request)
エントリポイントとサイドパネルの有効化状況に応じてQueryParams Mapを組み立てる
kStartTimeQueryParameter: st
base::Time::Now().ToJavaTime();
kChromeSearchWithGoogleLensContextMenuItem: "ccm"
オプションを与えているだけで画像や領域情報は含まれていない
AppendOrReplaceQueryParametersForLensRequest内部で呼び出される
「AppendOrReplaceQueryParametersForLensRequest」で検索
気になる
chrome/browser/ui/views/lens/lens_side_panel_controller.cc
chrome/browser/ui/views/side_panel/lens/lens_unified_side_panel_view.cc
chrome/browser/ui/views/lens/lens_side_panel_controller.cc
void LensSidePanelController::LoadResultsInNewTab()
Open the latest URL visible on the side panel. This accounts for when the user uploads an image to Lens via drag and drop. This also allows any region selection changes to transfer to the new tab.
たぶんこのボタンが押されたときの挙動だ
今回深堀りしたい場所ではないので一旦撤退
コンテキストメニューから追っていく必要がある?
「で画像を検索」で検索
chrome/app/resources/generated_resources_ja.xtb
「VISUAL_SEAERCH_PROVIDER」
components/lens/lens_features.cc
Enables using
Google
as the visual search provider instead of Google Lens
. Google Lensの代わりにGoogleを使うオプション
関係ない
components/lens/lens_features.cc
chrome/browser/ui/tab_contents/core_tab_helper.cc
chrome/browser/ui/tab_contents/core_tab_helper.h
DoSearchByImageInNewTab (chrome/browser/ui/tab_contents/core_tab_helper.cc)
Handles the image thumbnail for the context node, composes a image search request based on the received thumbnail and opens the request in a new tab.
search_args.image_thumbnail_content に検索対象の画像データが格納されていそう
components/search_engines/template_url.h にもそれらしいコメントがある
search_args.image_thumbnail_content はどうやって作られる?
DoSearchByImageInNewTab関数の引数として const std::vector<uint8_t>& thumbnail_data が渡されている
この時点ですでに領域でのクロップは済んでいるはず?
PostContentToURL (chrome/browser/ui/tab_contents/core_tab_helper.cc)
Google Chrome Brandingの場合のみSidePanelにLensのリクエストを表示する
EdgeやBraveなどChrome以外のChromium製のブラウザでは使えない?
最終的にどちらかの下記の関数のどちらかでURLを開く
lens::OpenLensSidePanel(chrome::FindBrowserWithWebContents(web_contents()), open_url_params);
web_contents()->OpenURL(open_url_params);
修行が足りずこの2つの関数はどちらも全体像が見えてこない 
lens::OpenLensSidePanel
chrome/browser/ui/lens/lens_side_panel_helper.h
chrome/browser/ui/views/lens/lens_side_panel_helper.cc
OpenWithURL(url_params) も見ておくか
browser_view->lens_side_panel_controller()->OpenWithURL(url_params)
browser_view->lens_side_panel_controller()
chrome/browser/ui/views/lens/lens_side_panel_controller.h
chrome/browser/ui/views/lens/lens_side_panel_controller.cc
最後の LoadURLWithParams() も見る
side_panel_view_->GetWebContents()->GetController().LoadURLWithParams
content/browser/renderer_host/navigation_controller_impl.cc
→ NavigateWithoutEntry(params)
SearchWithLensInNewTab (chrome/browser/ui/tab_contents/core_tab_helper)
SearchByImageInNewTabImpl
→ thumbnail_capturer_proxy->RequestImageForContextNode を介して、DoSearchByImageInNewTabが実行されるぽい
BindOnceとは?
難しそう。Passing Parameters As A unique_ptrの例と近いことやっている?
RequestImageForContextNode (chrome/common/chrome_render_frame.mojom)
実装は chrome/renderer/chrome_render_frame_observer.cc ?
cc
void ChromeRenderFrameObserver::RequestImageForContextNode(
int32_t thumbnail_min_area_pixels,
const gfx::Size& thumbnail_max_size_pixels,
chrome::mojom::ImageFormat image_format,
RequestImageForContextNodeCallback callback) {
SkBitmapとか出てきているのでたぶんSKIA
完全にレンダリング層に来てしまった?
大雑把な流れ
WebNode context_node = render_frame()->GetWebFrame()->ContextMenuImageNode();
WebElement web_element = context_node.To<WebElement>();
web_element.ImageContents()
SkBitmap image = web_element.ImageContents();
必要に応じてこれをDownScaleしたものがSkBitmap thumbnail
ImageContents関数読みたいな 
SkBitmap bitmap;
thumbnailを元にしてあれこれ経て作られる
必要に応じて要求されたフォーマットに変換する
std::vector<unsigned char> data;
browserプロセスに返すimage_dataができあがる
std::move(callback).Run(image_data, original_size, image_extension);
最後の行でoriginalSizeとともにcallbackに渡す
chrome/browser/lens/region_search/lens_region_search_controller.h
Creates and runs the drag and capture flow. When run, the user enters into a screenshot capture mode with the ability to draw a rectagular region around the web contents. When finished with selection, the region is converted into a PNG and sent to Lens.
領域のスクリーンショットがPNG画像としてLensに渡されることは分かった
drag操作を待ち受けるっぽいのでこれも違う?
画像の上で右クリックしたときに、その画像のバイナリデータを送るのではなく、タブのスクリーンショットを撮ってその画像の領域 (で切り抜いた結果?) をLens APIに渡している?
違うっぽかった
普通にimageElmenentにアクセスできていた
components/lens/lens_entrypoints.h
CHROME_SEARCH_WITH_GOOGLE_LENS_CONTEXT_MENU_ITEM
LWDは何のことか分からない
chrome/browser/renderer_context_menu/render_view_context_menu.cc
chrome/browser/renderer_context_menu/render_view_context_menu.cc
脱線
tools/metrics/actions/actions.xml 面白い
機能ごとにowner (担当開発者) が列挙されている
commitをウォッチしておこう
Wire up Lens side panel. 2021/9/2
説明も用意されているのでこのファイルを眺めるだけで実験中の機能とかも把握できるのではないか
機能が実行されたことを記録している
chrome/browser/ui/browser_finder.cc
WebContent == タブ的なニュアンスなのかな
web_contents()->OpenURL()
実装はcontent/browser/web_contents/web_contents_impl.ccにある
web_contents()->OpenURL()
content/browser/web_contents/web_contents_impl.cc
→ LoadURLWithParams()
NavigationControllerImpl::NavigateWithoutEntry
content/browser/renderer_host/navigation_controller_impl.cc
長い
→ CreateNavigationRequestFromLoadParams
CreateNavigationRequestFromLoadParams
content/browser/renderer_host/navigation_controller_impl.cc
params.post_data
に格納されているPOSTしたいデータもここで渡されている またmojomだ