diff --git a/README.md b/README.md index 247fc6a..377331e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # chromium-android-extension -Patches that make chromium on Android support extensions. \ No newline at end of file +Patches that add extension support to chromium on Android. + +To apply, go into the `src` folder of chromium source tree and run `patch -p1 --ignore-whitespace -i ../patches/Extensions/{name_of_the_patch} --no-backup-if-mismatch` following the order in `series`. + +The patches are last adapted to chromium version `88.0.4324.182`. Patches assume safe browsing is off and supervised user is disabled. \ No newline at end of file diff --git a/patches/Extensions/add-api-os-android.patch b/patches/Extensions/add-api-os-android.patch new file mode 100644 index 0000000..a266f71 --- /dev/null +++ b/patches/Extensions/add-api-os-android.patch @@ -0,0 +1,19 @@ +From: Wengling Chen +Date: Thu, 21 Jan 2021 20:35:11 +0200 +Subject: Add android to list of oses + +--- + chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc ++++ b/chrome/browser/extensions/api/runtime/chrome_runtime_api_delegate.cc +@@ -286,6 +286,8 @@ bool ChromeRuntimeAPIDelegate::GetPlatfo + info->os = extensions::api::runtime::PLATFORM_OS_LINUX; + } else if (strcmp(os, "openbsd") == 0) { + info->os = extensions::api::runtime::PLATFORM_OS_OPENBSD; ++ } else if (strcmp(os, "android") == 0) { ++ info->os = extensions::api::runtime::PLATFORM_OS_ANDROID; + } else { + NOTREACHED(); + return false; diff --git a/patches/Extensions/add-chromium-webstore-extension.patch b/patches/Extensions/add-chromium-webstore-extension.patch new file mode 100644 index 0000000..59c0428 --- /dev/null +++ b/patches/Extensions/add-chromium-webstore-extension.patch @@ -0,0 +1,72 @@ +From: Wengling Chen +Sun, 28 Jun 2020 03:51:18 -0400 +Subject: bundle chromium-web-store + + +--- + chrome/browser/browser_resources.grd | 1 + chrome/browser/extensions/component_extensions_allowlist/allowlist.cc | 1 + chrome/browser/extensions/component_loader.cc | 3 + + chrome/browser/resources/component_extension_resources.grd | 19 ++++++++++ + 4 files changed, 24 insertions(+) + +--- a/chrome/browser/browser_resources.grd ++++ b/chrome/browser/browser_resources.grd +@@ -223,6 +223,7 @@ + + + ++ + + + +--- a/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc ++++ b/chrome/browser/extensions/component_extensions_allowlist/allowlist.cc +@@ -65,6 +65,7 @@ bool IsComponentExtensionAllowlisted(int + case IDR_CLOUDPRINT_MANIFEST: + #endif + case IDR_CRYPTOTOKEN_MANIFEST: ++ case IDR_CHROMIUM_WEB_STORE_MANIFEST: + case IDR_FEEDBACK_MANIFEST: + #if BUILDFLAG(ENABLE_HANGOUT_SERVICES_EXTENSION) + case IDR_HANGOUT_SERVICES_MANIFEST: +--- a/chrome/browser/extensions/component_loader.cc ++++ b/chrome/browser/extensions/component_loader.cc +@@ -571,6 +571,9 @@ void ComponentLoader::AddDefaultComponen + + Add(IDR_CRYPTOTOKEN_MANIFEST, + base::FilePath(FILE_PATH_LITERAL("cryptotoken"))); ++ ++ Add(IDR_CHROMIUM_WEB_STORE_MANIFEST, ++ base::FilePath(FILE_PATH_LITERAL("chromium_web_store"))); + } + + void ComponentLoader:: +--- a/chrome/browser/resources/component_extension_resources.grd ++++ b/chrome/browser/resources/component_extension_resources.grd +@@ -191,6 +191,25 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/patches/Extensions/add-extension-menu-items.patch b/patches/Extensions/add-extension-menu-items.patch new file mode 100644 index 0000000..84ccd77 --- /dev/null +++ b/patches/Extensions/add-extension-menu-items.patch @@ -0,0 +1,2260 @@ +From: Wengling Chen +Date: Mon, 15 Feb 2021 04:18:37 +0200 +Subject: Show extension items in app menu + +--- + chrome/android/BUILD.gn | 1 + chrome/android/chrome_java_sources.gni | 2 + chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java | 99 ++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionMenuItem.java | 73 + + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionMenuViewBridge.java | 80 ++ + chrome/browser/extensions/extension_context_menu_model.cc | 42 - + chrome/browser/extensions/extension_context_menu_model.h | 6 + chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapter.java | 29 + chrome/browser/ui/chrome_pages.cc | 11 + chrome/browser/ui/extensions/extension_action_view_controller.cc | 155 +--- + chrome/browser/ui/extensions/extension_action_view_controller.h | 22 + chrome/browser/ui/toolbar/toolbar_action_view_controller.h | 4 + chrome/browser/ui/toolbar/toolbar_actions_bar.cc | 6 + chrome/browser/ui/toolbar/toolbar_actions_model.cc | 14 + chrome/browser/ui/toolbar/toolbar_actions_model.h | 4 + chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc | 55 - + chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.h | 2 + chrome/browser/ui/views/extensions/extensions_menu_item_view.cc | 110 +- + chrome/browser/ui/views/extensions/extensions_menu_item_view.h | 14 + chrome/browser/ui/views/extensions/extensions_menu_view.cc | 380 +++++++--- + chrome/browser/ui/views/extensions/extensions_menu_view.h | 80 +- + chrome/browser/ui/views/extensions/extensions_toolbar_button.cc | 8 + chrome/browser/ui/views/extensions/extensions_toolbar_container.cc | 4 + 23 files changed, 818 insertions(+), 383 deletions(-) + +--- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java +@@ -8,6 +8,7 @@ import android.content.Context; + import android.content.pm.ResolveInfo; + import android.content.res.Resources; + import android.graphics.drawable.Drawable; ++import android.graphics.drawable.BitmapDrawable; + import android.os.Bundle; + import android.os.SystemClock; + import android.text.TextUtils; +@@ -24,6 +25,7 @@ import androidx.annotation.VisibleForTes + import androidx.appcompat.content.res.AppCompatResources; + import androidx.core.graphics.drawable.DrawableCompat; + ++import org.chromium.base.Log; + import org.chromium.base.Callback; + import org.chromium.base.CallbackController; + import org.chromium.base.CommandLine; +@@ -33,6 +35,7 @@ import org.chromium.base.supplier.Observ + import org.chromium.base.supplier.OneshotSupplier; + import org.chromium.chrome.R; + import org.chromium.chrome.browser.ActivityTabProvider; ++import org.chromium.chrome.browser.app.ChromeActivity; + import org.chromium.chrome.browser.ShortcutHelper; + import org.chromium.chrome.browser.banners.AppBannerManager; + import org.chromium.chrome.browser.banners.AppMenuVerbiage; +@@ -40,6 +43,8 @@ import org.chromium.chrome.browser.bookm + import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; + import org.chromium.chrome.browser.device.DeviceClassManager; + import org.chromium.chrome.browser.download.DownloadUtils; ++import org.chromium.chrome.browser.extensions.ExtensionMenuItem; ++import org.chromium.chrome.browser.extensions.ExtensionMenuViewBridge; + import org.chromium.chrome.browser.flags.CachedFeatureFlags; + import org.chromium.chrome.browser.flags.ChromeFeatureList; + import org.chromium.chrome.browser.flags.ChromeSwitches; +@@ -60,9 +65,11 @@ import org.chromium.chrome.browser.ui.ap + import org.chromium.chrome.browser.ui.appmenu.AppMenuPropertiesDelegate; + import org.chromium.chrome.browser.ui.appmenu.CustomViewBinder; + import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; ++import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; + import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; + import org.chromium.components.embedder_support.util.UrlConstants; + import org.chromium.components.webapk.lib.client.WebApkValidator; ++import org.chromium.content_public.browser.LoadUrlParams; + import org.chromium.ui.base.DeviceFormFactor; + import org.chromium.ui.modaldialog.ModalDialogManager; + +@@ -78,7 +85,8 @@ import java.util.Set; + * Base implementation of {@link AppMenuPropertiesDelegate} that handles hiding and showing menu + * items based on activity state. + */ +-public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate { ++public class AppMenuPropertiesDelegateImpl ++ implements AppMenuPropertiesDelegate, MenuOrKeyboardActionController.MenuOrKeyboardActionHandler { + public static final StringCachedFieldTrialParameter ACTION_BAR_VARIATION = + new StringCachedFieldTrialParameter( + ChromeFeatureList.TABBED_APP_OVERFLOW_MENU_REGROUP, "action_bar", ""); +@@ -99,6 +107,7 @@ public class AppMenuPropertiesDelegateIm + protected final ToolbarManager mToolbarManager; + protected final View mDecorView; + private CallbackController mCallbackController = new CallbackController(); ++ private final MenuOrKeyboardActionController mMenuOrKeyboardActionController; + private final ObservableSupplier mBookmarkBridgeSupplier; + private Callback mBookmarkBridgeSupplierCallback; + private boolean mUpdateMenuItemVisible; +@@ -106,6 +115,9 @@ public class AppMenuPropertiesDelegateIm + // Keeps track of which menu item was shown when installable app is detected. + private int mAddAppTitleShown; + private final ModalDialogManager mModalDialogManager; ++ // Extension submenu ++ private final List mExtensionSubMenus = new ArrayList<>(); ++ private final List mExtensionSubMenuItems = new ArrayList<>(); + + // The keys of the Map are menuitem ids, the first elements in the Pair are menuitem ids, + // and the second elements in the Pair are AppMenuSimilarSelectionType. If users first +@@ -203,10 +215,15 @@ public class AppMenuPropertiesDelegateIm + mBookmarkBridgeSupplierCallback = (bookmarkBridge) -> mBookmarkBridge = bookmarkBridge; + mBookmarkBridgeSupplier.addObserver(mBookmarkBridgeSupplierCallback); + mShareUtils = new ShareUtils(); ++ ++ mMenuOrKeyboardActionController = ((ChromeActivity) context).getMenuOrKeyboardActionController(); ++ mMenuOrKeyboardActionController.registerMenuOrKeyboardActionHandler(this); + } + + @Override + public void destroy() { ++ mMenuOrKeyboardActionController.unregisterMenuOrKeyboardActionHandler(this); ++ + mBookmarkBridgeSupplier.removeObserver(mBookmarkBridgeSupplierCallback); + if (mCallbackController != null) { + mCallbackController.destroy(); +@@ -234,6 +251,23 @@ public class AppMenuPropertiesDelegateIm + return customViewBinders; + } + ++ @Override ++ public boolean handleMenuOrKeyboardAction(int id, boolean fromMenu) { ++ for (ExtensionMenuItem menuItem : mExtensionSubMenuItems) { ++ Log.d("AppMenuPropertiesDelegateImpl.java", "id: " + String.valueOf(id) + " item.id: " + String.valueOf(menuItem.getId()) + " item.url: " + menuItem.getPopupUrl() + " fromMenu: " + String.valueOf(fromMenu)); ++ if (menuItem.getId() == id && fromMenu && !"".equals(menuItem.getPopupUrl())) { ++ ExtensionMenuViewBridge.executeAction(menuItem.getUId()); ++ ++ // Clear native extension menu states ++ // This cannot be done in onMenuDismissed because handleMenuOrKeyboardAction ++ // may still need the stored items ++ ExtensionMenuViewBridge.onHide(); ++ return true; ++ } ++ } ++ return false; ++ } ++ + /** + * @return Whether the app menu for a web page should be shown. + */ +@@ -306,6 +340,63 @@ public class AppMenuPropertiesDelegateIm + boolean isFileScheme = url.startsWith(UrlConstants.FILE_URL_PREFIX); + boolean isContentScheme = url.startsWith(UrlConstants.CONTENT_URL_PREFIX); + ++ // Update the extensions container menu ++ boolean shouldShowExtensionMenu = shouldShowExtensionMenu(); ++ if (shouldShowExtensionMenu) { ++ // Clear native extension menu states ++ // This cannot be done in onMenuDismissed because handleMenuOrKeyboardAction ++ // may still need the stored items ++ ExtensionMenuViewBridge.onHide(); ++ ++ mExtensionSubMenuItems.clear(); ++ ExtensionMenuViewBridge.test(mExtensionSubMenuItems); ++// MenuItem extensionMenuItem = menu.findItem(R.id.extension_menu_id); ++// extensionMenuItem.setVisible(true); ++ ++ // Calculate number of submenus ++ int order = 0; ++ final int numMaxItems = 5; ++ int numRemainingMenuItems = mExtensionSubMenuItems.size(); ++ int numSubMenus = (numRemainingMenuItems - 1) / numMaxItems + 1; ++ ++ // Create submenu ++// if (mExtensionMenu != null) { ++// menu.removeItem(mExtensionMenu.getItem().getItemId()); ++// mExtensionMenu = menu.addSubMenu("Extensions"); ++// } ++ // Clear previous submenus ++ for (SubMenu submenu : mExtensionSubMenus) { ++ menu.removeItem(submenu.getItem().getItemId()); ++ } ++ mExtensionSubMenus.clear(); ++ ++ // Create submenu on the fly ++ for (int i = 0; i < numSubMenus; ++i) { ++ SubMenu extensionMenu = menu.addSubMenu("Extensions SubMenu"); ++ mExtensionSubMenus.add(extensionMenu); ++ extensionMenu.getItem().setVisible(true); ++ extensionMenu.getItem().setEnabled(true); ++ ++ // Add dummy item for test ++ final int jMax = Math.min(numMaxItems, numRemainingMenuItems); ++ for (int j = 0; j < jMax; ++j) { ++ final int itemId = View.generateViewId(); ++ ExtensionMenuItem currentMenuItem = mExtensionSubMenuItems.get(i * numMaxItems + j); ++ currentMenuItem.setId(itemId); ++ MenuItem item = extensionMenu.add(MenuGroup.PAGE_MENU, itemId, order, currentMenuItem.getTitle()); ++ item.setVisible(true); ++ item.setEnabled(true); ++ BitmapDrawable drawable = new BitmapDrawable(mContext.getResources(), currentMenuItem.getIcon()); ++ item.setIcon(drawable); ++ ++ order++; ++ } ++ ++ order = 0; // Reset order ++ numRemainingMenuItems -= numMaxItems; ++ } ++ } ++ + // Update the icon row items (shown in narrow form factors). + boolean shouldShowIconRow = shouldShowIconRow(); + menu.findItem(R.id.icon_row_menu_id).setVisible(shouldShowIconRow); +@@ -846,6 +937,12 @@ public class AppMenuPropertiesDelegateIm + return shouldShowIconRow; + } + ++ boolean shouldShowExtensionMenu() { ++ // Always return true for now ++ boolean shouldShowExtensionMenu = true; ++ return shouldShowExtensionMenu; ++ } ++ + @Override + public int getFooterResourceId() { + return 0; +--- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapter.java ++++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuAdapter.java +@@ -14,10 +14,12 @@ import android.view.LayoutInflater; + import android.view.MenuItem; + import android.view.View; + import android.view.ViewGroup; ++import android.view.ViewParent; + import android.widget.BaseAdapter; + import android.widget.ImageButton; + import android.widget.ImageView; + import android.widget.ListView; ++import android.widget.LinearLayout ; + import android.widget.TextView; + + import androidx.annotation.IntDef; +@@ -55,7 +57,7 @@ import java.util.Map; + */ + class AppMenuAdapter extends BaseAdapter { + @IntDef({MenuItemType.STANDARD, MenuItemType.TITLE_BUTTON, MenuItemType.THREE_BUTTON, +- MenuItemType.FOUR_BUTTON, MenuItemType.FIVE_BUTTON}) ++ MenuItemType.FOUR_BUTTON, MenuItemType.FIVE_BUTTON, MenuItemType.EXT_FIVE_BUTTON}) + @Retention(RetentionPolicy.SOURCE) + @VisibleForTesting + @interface MenuItemType { +@@ -81,10 +83,14 @@ class AppMenuAdapter extends BaseAdapter + */ + int FIVE_BUTTON = 4; + /** ++ * Menu item that has five buttons for extensions. Every one of these buttons is displayed as an icon. ++ */ ++ int EXT_FIVE_BUTTON = 5; ++ /** + * The number of view types specified above. If you add a view type you MUST increment + * this. + */ +- int NUM_ENTRIES = 5; ++ int NUM_ENTRIES = 6; + } + + /** IDs of all of the buttons in icon_row_menu_item.xml. */ +@@ -141,6 +147,11 @@ class AppMenuAdapter extends BaseAdapter + public @MenuItemType int getItemViewType(int position) { + MenuItem item = getItem(position); + int viewCount = item.hasSubMenu() ? item.getSubMenu().size() : 1; ++ if (item.hasSubMenu()) { ++ CharSequence title = item.getSubMenu().getItem().getTitle(); ++ if (title != null && title.toString().toLowerCase().contains("extension")) ++ return MenuItemType.EXT_FIVE_BUTTON; ++ } + int customItemViewType = getCustomItemViewType(item); + if (customItemViewType != CustomViewBinder.NOT_HANDLED) { + return customItemViewType; +@@ -207,6 +218,9 @@ class AppMenuAdapter extends BaseAdapter + case MenuItemType.FIVE_BUTTON: + convertView = createMenuItemRow(convertView, parent, item, 5, itemViewType); + break; ++ case MenuItemType.EXT_FIVE_BUTTON: ++ convertView = createMenuItemRow(convertView, parent, item, Math.min(item.getSubMenu().size(), 5), itemViewType); ++ break; + case MenuItemType.TITLE_BUTTON: { + assert item.hasSubMenu(); + final MenuItem titleItem = item.getSubMenu().getItem(0); +@@ -258,7 +272,7 @@ class AppMenuAdapter extends BaseAdapter + // Display an icon alongside the MenuItem. + holder.checkbox.setVisibility(View.GONE); + holder.button.setVisibility(View.VISIBLE); +- setupImageButton(holder.button, subItem); ++ setupImageButton(holder.button, subItem, false); + } else { + // Display just the label of the MenuItem. + holder.checkbox.setVisibility(View.GONE); +@@ -333,7 +347,7 @@ class AppMenuAdapter extends BaseAdapter + setupMenuButton(button, item); + } + +- private void setupImageButton(ImageButton button, final MenuItem item) { ++ private void setupImageButton(ImageButton button, final MenuItem item, boolean isExtMenuItem) { + // Store and recover the level of image as button.setimageDrawable + // resets drawable to default level. + int currentLevel = item.getIcon().getLevel(); +@@ -346,6 +360,11 @@ class AppMenuAdapter extends BaseAdapter + button.getContext(), R.color.blue_mode_tint)); + } + ++ if (isExtMenuItem) { ++ ApiCompatibilityUtils.setImageTintList(button, null); ++ button.setScaleType(ImageView.ScaleType.FIT_CENTER); ++ } ++ + setupMenuButton(button, item); + } + +@@ -495,7 +514,7 @@ class AppMenuAdapter extends BaseAdapter + } + + for (int i = 0; i < numItems; i++) { +- setupImageButton(holder.buttons[i], item.getSubMenu().getItem(i)); ++ setupImageButton(holder.buttons[i], item.getSubMenu().getItem(i), itemViewType == MenuItemType.EXT_FIVE_BUTTON); + } + + if (CachedFeatureFlags.isEnabled(ChromeFeatureList.TABBED_APP_OVERFLOW_MENU_ICONS) +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionMenuViewBridge.java +@@ -0,0 +1,80 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import android.content.Context; ++import android.content.res.Resources; ++import android.graphics.Bitmap; ++ ++import org.chromium.base.annotations.CalledByNative; ++import org.chromium.base.annotations.NativeMethods; ++import org.chromium.chrome.browser.app.ChromeActivity; ++import org.chromium.chrome.browser.customtabs.CustomTabActivity; ++import org.chromium.chrome.browser.tab.Tab; ++import org.chromium.chrome.R; ++ ++import java.util.List; ++ ++ ++/** ++* Helper class to handle communication between extension menu items and native. ++*/ ++ ++public class ExtensionMenuViewBridge { ++ ++ public static void test(List menuItems) { ++ ExtensionMenuViewBridgeJni.get().createMenu(); ++ ++ if (menuItems.size() != 0) ++ menuItems.clear(); ++ ++ String[] ids = ExtensionMenuViewBridgeJni.get().getIds(); ++ String[] titles = ExtensionMenuViewBridgeJni.get().getTitles(); ++ Bitmap[] icons = ExtensionMenuViewBridgeJni.get().getIconBitmaps(); ++ String[] urls = ExtensionMenuViewBridgeJni.get().getPopupUrls(); ++ ++ for (int i = 0; i < ids.length; ++i) { ++ menuItems.add(new ExtensionMenuItem(ids[i], titles[i], icons[i], urls[i])); ++ } ++ } ++ ++ public static void executeAction(String uid) { ++ ExtensionMenuViewBridgeJni.get().executeAction(uid); ++ } ++ ++ public static void onHide() { ++ ExtensionMenuViewBridgeJni.get().hide(); ++ } ++ ++ @CalledByNative ++ static void showCustomTab(Tab tab, String url) { ++ CustomTabActivity.showInfoPage(tab.getContext(), url); ++ } ++ ++ @NativeMethods ++ interface Natives { ++ void createMenu(); ++ String[] getIds(); ++ String[] getTitles(); ++ Bitmap[] getIconBitmaps(); ++ String[] getPopupUrls(); ++ void executeAction(String uid); ++ void hide(); ++ } ++} +--- a/chrome/browser/ui/extensions/extension_action_view_controller.cc ++++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc +@@ -21,12 +21,16 @@ + #include "chrome/browser/extensions/extension_view_host.h" + #include "chrome/browser/extensions/extension_view_host_factory.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/extensions/extension_action_platform_delegate.h" + #include "chrome/browser/ui/extensions/extensions_container.h" + #include "chrome/browser/ui/extensions/icon_with_badge_image_source.h" + #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h" + #include "chrome/browser/ui/ui_features.h" ++#include "chrome/browser/ui/views/extensions/extensions_menu_view.h" + #include "chrome/grit/generated_resources.h" + #include "components/sessions/content/session_tab_helper.h" + #include "extensions/browser/extension_action.h" +@@ -46,22 +50,15 @@ using extensions::ExtensionActionRunner; + + ExtensionActionViewController::ExtensionActionViewController( + const extensions::Extension* extension, +- Browser* browser, + extensions::ExtensionAction* extension_action, +- ExtensionsContainer* extensions_container, + bool in_overflow_mode) + : extension_(extension), +- browser_(browser), + in_overflow_mode_(in_overflow_mode), + extension_action_(extension_action), +- extensions_container_(extensions_container), +- popup_host_(nullptr), +- view_delegate_(nullptr), + platform_delegate_(ExtensionActionPlatformDelegate::Create(this)), +- icon_factory_(browser->profile(), extension, extension_action, this), ++ icon_factory_(ProfileManager::GetActiveUserProfile(), extension, extension_action, this), + extension_registry_( +- extensions::ExtensionRegistry::Get(browser_->profile())) { +- DCHECK(extensions_container); ++ extensions::ExtensionRegistry::Get(ProfileManager::GetActiveUserProfile())) { + DCHECK(extension_action); + DCHECK(extension); + } +@@ -76,14 +73,11 @@ std::string ExtensionActionViewControlle + + void ExtensionActionViewController::SetDelegate( + ToolbarActionViewDelegate* delegate) { +- DCHECK((delegate == nullptr) ^ (view_delegate_ == nullptr)); + if (delegate) { +- view_delegate_ = delegate; + platform_delegate_->OnDelegateSet(); + } else { + HidePopup(); + platform_delegate_.reset(); +- view_delegate_ = nullptr; + } + } + +@@ -172,53 +166,48 @@ bool ExtensionActionViewController::HasP + } + + bool ExtensionActionViewController::IsShowingPopup() const { +- return popup_host_ != nullptr; ++ return false; + } + + void ExtensionActionViewController::HidePopup() { +- if (IsShowingPopup()) { +- popup_host_->Close(); +- // We need to do these actions synchronously (instead of closing and then +- // performing the rest of the cleanup in OnExtensionHostDestroyed()) because +- // the extension host may close asynchronously, and we need to keep the view +- // delegate up to date. +- if (popup_host_) +- OnPopupClosed(); +- } ++} ++ ++GURL ExtensionActionViewController::GetPopupUrl( ++ content::WebContents* web_contents) { ++ if (HasPopup(web_contents)) { ++ return extension_action_->GetPopupUrl( ++ sessions::SessionTabHelper::IdForTab(web_contents).id()); ++ } ++ return GURL{}; + } + + gfx::NativeView ExtensionActionViewController::GetPopupNativeView() { +- return popup_host_ ? popup_host_->view()->GetNativeView() : nullptr; ++ return nullptr; + } + + ui::MenuModel* ExtensionActionViewController::GetContextMenu() { + if (!ExtensionIsValid()) + return nullptr; + +- ToolbarActionViewController* const action = +- extensions_container_->GetActionForId(GetId()); +- extensions::ExtensionContextMenuModel::ButtonVisibility visibility = +- extensions_container_->GetActionVisibility(action); +- + // Reconstruct the menu every time because the menu's contents are dynamic. + context_menu_model_ = std::make_unique( +- extension(), browser_, visibility, this, +- view_delegate_->CanShowIconInToolbar()); ++ extension(), extensions::ExtensionContextMenuModel::ButtonVisibility::UNPINNED, this, ++ true); + return context_menu_model_.get(); + } + + void ExtensionActionViewController::OnContextMenuShown() { +- extensions_container_->OnContextMenuShown(this); ++// extensions_container_->OnContextMenuShown(this); + } + + void ExtensionActionViewController::OnContextMenuClosed() { + if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) { +- extensions_container_->OnContextMenuClosed(this); ++// extensions_container_->OnContextMenuClosed(this); + return; + } + +- if (extensions_container_->GetPoppedOutAction() == this && !IsShowingPopup()) +- extensions_container_->UndoPopOut(); ++// if (extensions_container_->GetPoppedOutAction() == this && !IsShowingPopup()) ++// extensions_container_->UndoPopOut(); + } + + bool ExtensionActionViewController::ExecuteAction(bool by_user, +@@ -226,9 +215,9 @@ bool ExtensionActionViewController::Exec + if (!ExtensionIsValid()) + return false; + +- if (!IsEnabled(view_delegate_->GetCurrentWebContents())) { +- if (DisabledClickOpensMenu()) +- GetPreferredPopupViewController()->platform_delegate_->ShowContextMenu(); ++ if (!IsEnabled(TabModelList::GetCurrentTabModel()->GetActiveWebContents())) { ++// if (DisabledClickOpensMenu()) ++// GetPreferredPopupViewController()->platform_delegate_->ShowContextMenu(); + return false; + } + +@@ -239,8 +228,6 @@ bool ExtensionActionViewController::Exec + void ExtensionActionViewController::UpdateState() { + if (!ExtensionIsValid()) + return; +- +- view_delegate_->UpdateState(); + } + + bool ExtensionActionViewController::ExecuteAction(PopupShowAction show_action, +@@ -248,21 +235,23 @@ bool ExtensionActionViewController::Exec + if (!ExtensionIsValid()) + return false; + +- content::WebContents* web_contents = view_delegate_->GetCurrentWebContents(); ++ content::WebContents* web_contents = TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + ExtensionActionRunner* action_runner = + ExtensionActionRunner::GetForWebContents(web_contents); + if (!action_runner) + return false; + +- if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) +- extensions_container_->CloseOverflowMenuIfOpen(); ++// if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) ++// extensions_container_->CloseOverflowMenuIfOpen(); + + if (action_runner->RunAction(extension(), grant_tab_permissions) == + extensions::ExtensionAction::ACTION_SHOW_POPUP) { + GURL popup_url = extension_action_->GetPopupUrl( + sessions::SessionTabHelper::IdForTab(web_contents).id()); +- return GetPreferredPopupViewController() +- ->TriggerPopupWithUrl(show_action, popup_url, grant_tab_permissions); ++ // TODO: This is probably incorrect ++ return TriggerPopupWithUrl(show_action, popup_url, grant_tab_permissions); ++// return GetPreferredPopupViewController() ++// ->TriggerPopupWithUrl(show_action, popup_url, grant_tab_permissions); + } + return false; + } +@@ -289,8 +278,6 @@ void ExtensionActionViewController::Insp + void ExtensionActionViewController::OnIconUpdated() { + // We update the view first, so that if the observer relies on its UI it can + // be ready. +- if (view_delegate_) +- view_delegate_->UpdateState(); + } + + void ExtensionActionViewController::OnExtensionHostDestroyed( +@@ -341,7 +328,7 @@ bool ExtensionActionViewController::GetE + if (!ExtensionIsValid()) + return false; + +- CommandService* command_service = CommandService::Get(browser_->profile()); ++ CommandService* command_service = CommandService::Get(ProfileManager::GetActiveUserProfile()); + return command_service->GetExtensionActionCommand( + extension_->id(), extension_action_->action_type(), + CommandService::ACTIVE, command, nullptr); +@@ -366,7 +353,7 @@ bool ExtensionActionViewController::CanH + // disabled action (in most cases, this will result in opening the context + // menu). + if (extension_action_->action_type() == extensions::ActionInfo::TYPE_PAGE) +- return IsEnabled(view_delegate_->GetCurrentWebContents()); ++ return IsEnabled(TabModelList::GetCurrentTabModel()->GetActiveWebContents()); + return true; + } + +@@ -384,8 +371,8 @@ bool ExtensionActionViewController::HasB + + ExtensionActionViewController* + ExtensionActionViewController::GetPreferredPopupViewController() { +- return static_cast( +- extensions_container_->GetActionForId(GetId())); ++// return static_cast( ++// extensions_container_->GetActionForId(GetId())); + } + + bool ExtensionActionViewController::TriggerPopupWithUrl( +@@ -399,56 +386,50 @@ bool ExtensionActionViewController::Trig + + // Always hide the current popup, even if it's not owned by this extension. + // Only one popup should be visible at a time. +- extensions_container_->HideActivePopup(); ++// extensions_container_->HideActivePopup(); + +- std::unique_ptr host = +- extensions::ExtensionViewHostFactory::CreatePopupHost(popup_url, +- browser_); +- if (!host) +- return false; ++// extensions_container_->SetPopupOwner(this); + +- popup_host_ = host.get(); +- popup_host_observer_.Add(popup_host_); +- extensions_container_->SetPopupOwner(this); +- +- if (!extensions_container_->IsActionVisibleOnToolbar(this) || +- base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) { +- extensions_container_->CloseOverflowMenuIfOpen(); +- extensions_container_->PopOutAction( +- this, show_action == SHOW_POPUP_AND_INSPECT, +- base::Bind(&ExtensionActionViewController::ShowPopup, +- weak_factory_.GetWeakPtr(), base::Passed(std::move(host)), +- grant_tab_permissions, show_action)); ++ if (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) { ++// extensions_container_->CloseOverflowMenuIfOpen(); ++// extensions_container_->PopOutAction( ++// this, show_action == SHOW_POPUP_AND_INSPECT, ++// base::Bind(&ExtensionActionViewController::ShowPopup, ++// weak_factory_.GetWeakPtr(), popup_url, ++// grant_tab_permissions, show_action)); ++ ShowPopup(popup_url, grant_tab_permissions, show_action); + } else { +- ShowPopup(std::move(host), grant_tab_permissions, show_action); ++ ShowPopup(popup_url, grant_tab_permissions, show_action); + } + + return true; + } + + void ExtensionActionViewController::ShowPopup( +- std::unique_ptr popup_host, ++ const GURL& popup_url, + bool grant_tab_permissions, + PopupShowAction show_action) { +- // It's possible that the popup should be closed before it finishes opening +- // (since it can open asynchronously). Check before proceeding. +- if (!popup_host_) +- return; +- platform_delegate_->ShowPopup(std::move(popup_host), grant_tab_permissions, +- show_action); +- view_delegate_->OnPopupShown(grant_tab_permissions); ++// platform_delegate_->ShowPopup(grant_tab_permissions, ++// show_action); ++// TODO: Somehow new tab will be closed immediately ++// so try to launch a custom tab from Java instead. ++// ++// TabModelList::GetCurrentTabModel()->GetActiveWebContents()->OpenURL( ++// content::OpenURLParams( ++// popup_url, content::Referrer(), ++// WindowOpenDisposition::NEW_FOREGROUND_TAB, ++// ui::PAGE_TRANSITION_LINK, false ++// )); ++ if (popup_url.is_valid()) ++ ExtensionsMenuView::Show(popup_url.spec()); + } + + void ExtensionActionViewController::OnPopupClosed() { +- popup_host_observer_.Remove(popup_host_); +- popup_host_ = nullptr; +- extensions_container_->SetPopupOwner(nullptr); +- if (extensions_container_->GetPoppedOutAction() == this && +- (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu) || +- !view_delegate_->IsMenuRunning())) { +- extensions_container_->UndoPopOut(); +- } +- view_delegate_->OnPopupClosed(); ++// extensions_container_->SetPopupOwner(nullptr); ++// if (extensions_container_->GetPoppedOutAction() == this && ++// (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu)) { ++// extensions_container_->UndoPopOut(); ++// } + } + + std::unique_ptr +@@ -509,7 +490,7 @@ bool ExtensionActionViewController::HasA + !extension_->permissions_data()->IsRestrictedUrl(url, + /*error=*/nullptr) && + (!url.SchemeIsFile() || extensions::util::AllowFileAccess( +- extension_->id(), browser_->profile())); ++ extension_->id(), ProfileManager::GetActiveUserProfile())); + } + + bool ExtensionActionViewController::HasBeenBlocked( +--- a/chrome/browser/ui/extensions/extension_action_view_controller.h ++++ b/chrome/browser/ui/extensions/extension_action_view_controller.h +@@ -44,9 +44,7 @@ class ExtensionActionViewController + enum PopupShowAction { SHOW_POPUP, SHOW_POPUP_AND_INSPECT }; + + ExtensionActionViewController(const extensions::Extension* extension, +- Browser* browser, + extensions::ExtensionAction* extension_action, +- ExtensionsContainer* extensions_container, + bool in_overflow_mode); + ~ExtensionActionViewController() override; + +@@ -65,6 +63,7 @@ class ExtensionActionViewController + bool HasPopup(content::WebContents* web_contents) const override; + bool IsShowingPopup() const override; + void HidePopup() override; ++ GURL GetPopupUrl(content::WebContents* web_contents) override; + gfx::NativeView GetPopupNativeView() override; + ui::MenuModel* GetContextMenu() override; + void OnContextMenuShown() override; +@@ -90,12 +89,10 @@ class ExtensionActionViewController + bool CanHandleAccelerators() const; + + const extensions::Extension* extension() const { return extension_.get(); } +- Browser* browser() { return browser_; } + extensions::ExtensionAction* extension_action() { return extension_action_; } + const extensions::ExtensionAction* extension_action() const { + return extension_action_; + } +- ToolbarActionViewDelegate* view_delegate() { return view_delegate_; } + + std::unique_ptr GetIconImageSourceForTesting( + content::WebContents* web_contents, +@@ -138,7 +135,7 @@ class ExtensionActionViewController + bool grant_tab_permissions); + + // Shows the popup with the given |host|. +- void ShowPopup(std::unique_ptr host, ++ void ShowPopup(const GURL& popup_url, + bool grant_tab_permissions, + PopupShowAction show_action); + +@@ -170,9 +167,6 @@ class ExtensionActionViewController + // The extension associated with the action we're displaying. + scoped_refptr extension_; + +- // The corresponding browser. +- Browser* const browser_; +- + // Whether we are displayed in the 3-dot menu or not. + // TODO(pbos): Remove when 3-dot menu no longer contains extensions. + const bool in_overflow_mode_; +@@ -181,18 +175,9 @@ class ExtensionActionViewController + // by this class. + extensions::ExtensionAction* const extension_action_; + +- // The corresponding ExtensionsContainer on the toolbar. +- ExtensionsContainer* const extensions_container_; +- +- // The extension popup's host if the popup is visible; null otherwise. +- extensions::ExtensionViewHost* popup_host_; +- + // The context menu model for the extension. + std::unique_ptr context_menu_model_; + +- // Our view delegate. +- ToolbarActionViewDelegate* view_delegate_; +- + // The delegate to handle platform-specific implementations. + std::unique_ptr platform_delegate_; + +@@ -205,9 +190,6 @@ class ExtensionActionViewController + // The associated ExtensionRegistry; cached for quick checking. + extensions::ExtensionRegistry* extension_registry_; + +- ScopedObserver +- popup_host_observer_{this}; +- + base::WeakPtrFactory weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ExtensionActionViewController); +--- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc ++++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc +@@ -165,26 +165,22 @@ void ToolbarActionsModel::OnExtensionAct + } + + std::vector> +-ToolbarActionsModel::CreateActions(Browser* browser, +- ExtensionsContainer* main_bar, ++ToolbarActionsModel::CreateActions( + bool in_overflow_mode) { +- DCHECK(browser); +- DCHECK(main_bar); + std::vector> action_list; + + // action_ids() might not equate to |action_ids_| in the case where a + // subset is highlighted. + for (const ActionId& action_id : action_ids()) { + action_list.push_back( +- CreateActionForId(browser, main_bar, in_overflow_mode, action_id)); ++ CreateActionForId(in_overflow_mode, action_id)); + } + + return action_list; + } + + std::unique_ptr +-ToolbarActionsModel::CreateActionForId(Browser* browser, +- ExtensionsContainer* main_bar, ++ToolbarActionsModel::CreateActionForId( + bool in_overflow_mode, + const ActionId& action_id) { + // We should never have uninitialized actions in action_ids(). +@@ -195,8 +191,8 @@ ToolbarActionsModel::CreateActionForId(B + + // Create and add an ExtensionActionViewController for the extension. + return std::make_unique( +- extension, browser, +- extension_action_manager_->GetExtensionAction(*extension), main_bar, ++ extension, ++ extension_action_manager_->GetExtensionAction(*extension), + in_overflow_mode); + } + +--- a/chrome/browser/ui/toolbar/toolbar_actions_model.h ++++ b/chrome/browser/ui/toolbar/toolbar_actions_model.h +@@ -144,12 +144,8 @@ class ToolbarActionsModel : public exten + bool actions_initialized() const { return actions_initialized_; } + + std::vector> CreateActions( +- Browser* browser, +- ExtensionsContainer* main_bar, + bool in_overflow_menu); + std::unique_ptr CreateActionForId( +- Browser* browser, +- ExtensionsContainer* main_bar, + bool in_overflow_menu, + const ActionId& action_id); + +--- a/chrome/browser/ui/views/extensions/extensions_menu_view.cc ++++ b/chrome/browser/ui/views/extensions/extensions_menu_view.cc +@@ -4,21 +4,31 @@ + + #include "chrome/browser/ui/views/extensions/extensions_menu_view.h" + ++#include "base/android/jni_android.h" ++#include "base/android/jni_array.h" ++#include "base/android/jni_string.h" + #include "base/memory/ptr_util.h" + #include "base/stl_util.h" ++#include "chrome/android/chrome_jni_headers/ExtensionMenuViewBridge_jni.h" ++#include "chrome/browser/android/tab_android.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/chrome_pages.h" +-#include "chrome/browser/ui/tabs/tab_strip_model.h" + #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" + #include "chrome/browser/ui/views/bubble_menu_item_factory.h" + #include "chrome/browser/ui/views/chrome_layout_provider.h" + #include "chrome/browser/ui/views/chrome_typography.h" + #include "chrome/browser/ui/views/extensions/extensions_menu_item_view.h" + #include "chrome/grit/generated_resources.h" ++#include "components/sessions/content/session_tab_helper.h" + #include "components/vector_icons/vector_icons.h" + #include "third_party/skia/include/core/SkPath.h" ++#include "skia/ext/image_operations.h" + #include "ui/base/l10n/l10n_util.h" ++#include "ui/gfx/android/java_bitmap.h" + #include "ui/gfx/paint_vector_icon.h" + #include "ui/views/animation/ink_drop_host_view.h" + #include "ui/views/controls/button/label_button.h" +@@ -28,6 +38,7 @@ + #include "ui/views/layout/box_layout.h" + #include "ui/views/layout/flex_layout.h" + #include "ui/views/view_class_properties.h" ++#include "url/android/gurl_android.h" + + namespace { + // If true, allows more than one instance of the ExtensionsMenuView, which may +@@ -55,17 +66,12 @@ ExtensionsMenuItemView* GetAsMenuItemVie + + } // namespace + ++using namespace base::android; ++ + ExtensionsMenuView::ExtensionsMenuView( +- views::View* anchor_view, +- Browser* browser, +- ExtensionsContainer* extensions_container, + bool allow_pinning) +- : BubbleDialogDelegateView(anchor_view, +- views::BubbleBorder::Arrow::TOP_RIGHT), +- browser_(browser), +- extensions_container_(extensions_container), +- allow_pinning_(allow_pinning), +- toolbar_model_(ToolbarActionsModel::Get(browser_->profile())), ++ : allow_pinning_(allow_pinning), ++ toolbar_model_(ToolbarActionsModel::Get(ProfileManager::GetActiveUserProfile())), + toolbar_model_observer_(this), + cant_access_{nullptr, nullptr, + IDS_EXTENSIONS_MENU_CANT_ACCESS_SITE_DATA_SHORT, +@@ -80,22 +86,14 @@ ExtensionsMenuView::ExtensionsMenuView( + IDS_EXTENSIONS_MENU_ACCESSING_SITE_DATA, + ToolbarActionViewController::PageInteractionStatus::kActive} { + toolbar_model_observer_.Add(toolbar_model_); +- browser_->tab_strip_model()->AddObserver(this); +- set_margins(gfx::Insets(0)); +- +- SetButtons(ui::DIALOG_BUTTON_NONE); +- SetShowCloseButton(true); +- SetTitle(IDS_EXTENSIONS_MENU_TITLE); ++// browser_->tab_strip_model()->AddObserver(this); ++ // See tabs_event_router.cc ++ base::ThreadTaskRunnerHandle::Get()->PostTask( ++ FROM_HERE, ++ base::BindOnce(&ExtensionsMenuView::RegisterTabObserver, GetWeakPtr())); + +- SetEnableArrowKeyTraversal(true); ++// SetTitle(IDS_EXTENSIONS_MENU_TITLE); + +- // Let anchor view's MenuButtonController handle the highlight. +- set_highlight_button_when_shown(false); +- +- set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric( +- views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); +- SetLayoutManager(std::make_unique( +- views::BoxLayout::Orientation::kVertical)); + Populate(); + } + +@@ -107,6 +105,11 @@ ExtensionsMenuView::~ExtensionsMenuView( + + // Note: No need to call TabStripModel::RemoveObserver(), because it's handled + // directly within TabStripModelObserver::~TabStripModelObserver(). ++ ++ // Remove TabModelObserver and TabModelListObserver ++ if (observed_tab_model_) ++ observed_tab_model_->RemoveObserver(this); ++ TabModelList::RemoveObserver(this); + } + + void ExtensionsMenuView::Populate() { +@@ -138,14 +141,15 @@ void ExtensionsMenuView::Populate() { + // If so this needs to be created before being added to a widget, constructor + // would do. + constexpr int kSettingsIconSize = 16; +- auto footer = CreateBubbleMenuItem( +- EXTENSIONS_SETTINGS_ID, l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSION), +- base::BindRepeating(&chrome::ShowExtensions, browser_, std::string())); +- footer->SetImage( +- views::Button::STATE_NORMAL, +- gfx::CreateVectorIcon(vector_icons::kSettingsIcon, kSettingsIconSize, +- GetNativeTheme()->GetSystemColor( +- ui::NativeTheme::kColorId_MenuIconColor))); ++ // TODO: the "Manage Extension" item ++// auto footer = CreateBubbleMenuItem( ++// EXTENSIONS_SETTINGS_ID, l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSION), ++// base::BindRepeating(&chrome::ShowExtensions, browser_, std::string())); ++// footer->SetImage( ++// views::Button::STATE_NORMAL, ++// gfx::CreateVectorIcon(vector_icons::kSettingsIcon, kSettingsIconSize, ++// GetNativeTheme()->GetSystemColor( ++// ui::NativeTheme::kColorId_MenuIconColor))); + + // Extension icons are larger-than-favicon as they contain internal padding + // (space for badging). Add the same padding left and right of the icon to +@@ -153,21 +157,21 @@ void ExtensionsMenuView::Populate() { + // TODO(pbos): Note that this code relies on CreateBubbleMenuItem() and + // ExtensionsMenuItemView using the same horizontal border size and + // image-label spacing. This dependency should probably be more explicit. +- constexpr int kSettingsIconHorizontalPadding = +- (ExtensionsMenuItemView::kIconSize.width() - kSettingsIconSize) / 2; +- +- footer->SetBorder(views::CreateEmptyBorder( +- footer->border()->GetInsets() + +- gfx::Insets(0, kSettingsIconHorizontalPadding, 0, 0))); +- footer->SetImageLabelSpacing(footer->GetImageLabelSpacing() + +- kSettingsIconHorizontalPadding); +- +- manage_extensions_button_for_testing_ = footer.get(); +- AddChildView(std::move(footer)); ++// constexpr int kSettingsIconHorizontalPadding = ++// (ExtensionsMenuItemView::kIconSize.width() - kSettingsIconSize) / 2; ++// ++// footer->SetBorder(views::CreateEmptyBorder( ++// footer->border()->GetInsets() + ++// gfx::Insets(0, kSettingsIconHorizontalPadding, 0, 0))); ++// footer->SetImageLabelSpacing(footer->GetImageLabelSpacing() + ++// kSettingsIconHorizontalPadding); ++// ++// AddChildView(std::move(footer)); + + // Add menu items for each extension. +- for (const auto& id : toolbar_model_->action_ids()) ++ for (const auto& id : toolbar_model_->action_ids()) { + CreateAndInsertNewItem(id); ++ } + + SortMenuItemsByName(); + UpdateSectionVisibility(); +@@ -188,32 +192,32 @@ ExtensionsMenuView::CreateExtensionButto + container->SetLayoutManager(std::make_unique( + views::BoxLayout::Orientation::kVertical)); + +- const int horizontal_spacing = +- ChromeLayoutProvider::Get()->GetDistanceMetric( +- views::DISTANCE_BUTTON_HORIZONTAL_PADDING); ++// const int horizontal_spacing = ++// ChromeLayoutProvider::Get()->GetDistanceMetric( ++// views::DISTANCE_BUTTON_HORIZONTAL_PADDING); + + // Add an emphasized short header explaining the section. +- auto header = std::make_unique( +- l10n_util::GetStringUTF16(section->header_string_id), +- ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, +- ChromeTextStyle::STYLE_EMPHASIZED); +- header->SetHorizontalAlignment(gfx::ALIGN_LEFT); +- header->SetBorder(views::CreateEmptyBorder( +- ChromeLayoutProvider::Get()->GetDistanceMetric( +- DISTANCE_CONTROL_LIST_VERTICAL), +- horizontal_spacing, 0, horizontal_spacing)); +- container->AddChildView(std::move(header)); ++// auto header = std::make_unique( ++// l10n_util::GetStringUTF16(section->header_string_id), ++// ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, ++// ChromeTextStyle::STYLE_EMPHASIZED); ++// header->SetHorizontalAlignment(gfx::ALIGN_LEFT); ++// header->SetBorder(views::CreateEmptyBorder( ++// ChromeLayoutProvider::Get()->GetDistanceMetric( ++// DISTANCE_CONTROL_LIST_VERTICAL), ++// horizontal_spacing, 0, horizontal_spacing)); ++// container->AddChildView(std::move(header)); + + // Add longer text that explains the section in more detail. +- auto description = std::make_unique( +- l10n_util::GetStringUTF16(section->description_string_id), +- ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, +- views::style::STYLE_PRIMARY); +- description->SetMultiLine(true); +- description->SetHorizontalAlignment(gfx::ALIGN_LEFT); +- description->SetBorder(views::CreateEmptyBorder(0, horizontal_spacing, +- 0, horizontal_spacing)); +- container->AddChildView(std::move(description)); ++// auto description = std::make_unique( ++// l10n_util::GetStringUTF16(section->description_string_id), ++// ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL, ++// views::style::STYLE_PRIMARY); ++// description->SetMultiLine(true); ++// description->SetHorizontalAlignment(gfx::ALIGN_LEFT); ++// description->SetBorder(views::CreateEmptyBorder(0, horizontal_spacing, ++// 0, horizontal_spacing)); ++// container->AddChildView(std::move(description)); + + // Add a (currently empty) section for the menu items of the section. + auto menu_items = std::make_unique(); +@@ -277,17 +281,19 @@ void ExtensionsMenuView::SortMenuItemsBy + sort_section(&has_access_); + sort_section(&wants_access_); + sort_section(&cant_access_); ++ ++ UpdateJavaCache(); + } + + void ExtensionsMenuView::CreateAndInsertNewItem( + const ToolbarActionsModel::ActionId& id) { + std::unique_ptr controller = +- toolbar_model_->CreateActionForId(browser_, extensions_container_, false, ++ toolbar_model_->CreateActionForId(false, + id); + + // The bare `new` is safe here, because InsertMenuItem is guaranteed to + // be added to the view hierarchy, which takes ownership. +- auto* item = new ExtensionsMenuItemView(browser_, std::move(controller), ++ auto* item = new ExtensionsMenuItemView(std::move(controller), + allow_pinning_); + extensions_menu_items_.push_back(item); + InsertMenuItem(item); +@@ -300,7 +306,7 @@ void ExtensionsMenuView::InsertMenuItem( + << "Trying to insert a menu item that is already added in a section!"; + const ToolbarActionViewController::PageInteractionStatus status = + menu_item->view_controller()->GetPageInteractionStatus( +- browser_->tab_strip_model()->GetActiveWebContents()); ++ GetCurrentWebContents()); + + Section* const section = GetSectionForStatus(status); + // Add the view at the end. Note that this *doesn't* insert the item at the +@@ -324,8 +330,7 @@ void ExtensionsMenuView::UpdateSectionVi + void ExtensionsMenuView::Update() { + UpdateActionStates(); + +- content::WebContents* const web_contents = +- browser_->tab_strip_model()->GetActiveWebContents(); ++ content::WebContents* const web_contents = GetCurrentWebContents(); + auto move_children_between_sections_if_necessary = [this, web_contents]( + Section* section) { + // Note: Collect the views to move separately, so that we don't change the +@@ -358,8 +363,7 @@ void ExtensionsMenuView::Update() { + + void ExtensionsMenuView::SanityCheck() { + #if DCHECK_IS_ON() +- content::WebContents* web_contents = +- browser_->tab_strip_model()->GetActiveWebContents(); ++ content::WebContents* web_contents = GetCurrentWebContents(); + + // Sanity checks: verify that all extensions are properly sorted and in the + // correct section. +@@ -391,20 +395,127 @@ void ExtensionsMenuView::SanityCheck() { + DCHECK(Contains(item)); + DCHECK(base::Contains(action_ids, item->view_controller()->GetId())); + } ++ ++ // Check cache length are the same ++ DCHECK_EQ(action_ids.size(), extensions_menu_ids_.size()); ++ DCHECK_EQ(action_ids.size(), extensions_menu_titles_.size()); ++ DCHECK_EQ(action_ids.size(), extensions_menu_icons_.size()); ++ DCHECK_EQ(action_ids.size(), extensions_menu_popup_urls_.size()); + #endif + } + +-void ExtensionsMenuView::TabChangedAt(content::WebContents* contents, +- int index, +- TabChangeType change_type) { +- Update(); ++void ExtensionsMenuView::PopulateSection(Section* section, bool shall_clear) { ++ if (shall_clear) { ++ extensions_menu_ids_.clear(); ++ extensions_menu_titles_.clear(); ++ extensions_menu_icons_.clear(); ++ extensions_menu_popup_urls_.clear(); ++ } ++ if (section->menu_items->children().empty()) ++ return; ++ ++ constexpr gfx::Size kDefaultSize(36, 36); // larger sizes will add unnecessary paddings ++ constexpr int target_width = 96; // Upscale icons ++ constexpr int target_height = 96; ++ ++// for (views::View* view : section->menu_items->children()) { ++ for (size_t i = 0; i < section->menu_items->children().size(); ++i) { ++ views::View* view = section->menu_items->children()[i]; ++ // Ids ++ extensions_menu_ids_.push_back(GetAsMenuItemView(view)->view_controller() ++ ->GetId()); ++ ++ // Titles ++ extensions_menu_titles_.push_back(GetAsMenuItemView(view)->view_controller() ++ ->GetAccessibleName(GetCurrentWebContents())); ++ ++ // Icons ++ extensions_menu_icons_.push_back( ++ skia::ImageOperations::Resize( ++ GetAsMenuItemView(view)->view_controller() ++ ->GetIcon(GetCurrentWebContents(), kDefaultSize) ++ .AsBitmap(), skia::ImageOperations::RESIZE_GOOD, ++ target_width, target_height) ++ ); ++ ++ // urls ++ std::string popup_url = base::EmptyString(); ++ if (GetAsMenuItemView(view)->view_controller() ++ ->HasPopup(GetCurrentWebContents())) { ++ GURL url = GetAsMenuItemView(view)->view_controller() ++ ->GetPopupUrl(GetCurrentWebContents()); ++ if (url.is_valid()) ++ popup_url = url.spec(); ++ } ++ extensions_menu_popup_urls_.push_back(popup_url); ++ } ++} ++ ++void ExtensionsMenuView::UpdateJavaCache() { ++ PopulateSection(&has_access_, true); ++ PopulateSection(&wants_access_, false); ++ PopulateSection(&cant_access_, false); ++} ++ ++void ExtensionsMenuView::RegisterTabObserver() { ++ if (!TabModelList::empty()) { ++ OnTabModelAdded(); ++ } else { ++ TabModelList::AddObserver(this); ++ } ++} ++ ++void ExtensionsMenuView::OnTabModelAdded() { ++ if (observed_tab_model_) ++ return; ++ // The assumption is that there can be at most one non-off-the-record tab ++ // model. Observe it if it exists. ++ for (auto model = TabModelList::begin(); model != TabModelList::end(); ++ ++model) { ++ if (!(*model)->IsOffTheRecord()) { ++ observed_tab_model_ = *model; ++ observed_tab_model_->AddObserver(this); ++ break; ++ } ++ } ++} ++ ++void ExtensionsMenuView::OnTabModelRemoved() { ++ if (!observed_tab_model_) ++ return; ++ ++ for (auto remaining_model = TabModelList::begin(); ++ remaining_model != TabModelList::end(); ++remaining_model) { ++ if (observed_tab_model_ == *remaining_model) ++ return; ++ } ++ observed_tab_model_ = nullptr; ++} ++ ++void ExtensionsMenuView::DidSelectTab(TabAndroid* tab, ++ TabModel::TabSelectionType type, ++ int last_id) { ++ Update(); ++} ++ ++void ExtensionsMenuView::DidCloseTab(int tab_id, bool incognito) { ++ Update(); ++} ++ ++void ExtensionsMenuView::DidAddTab(TabAndroid* tab, TabModel::TabLaunchType type) { ++ Update(); + } + +-void ExtensionsMenuView::OnTabStripModelChanged( +- TabStripModel* tab_strip_model, +- const TabStripModelChange& change, +- const TabStripSelectionChange& selection) { +- Update(); ++void ExtensionsMenuView::TabRemoved(TabAndroid* tab) { ++ Update(); ++} ++ ++void ExtensionsMenuView::DidMoveTab(TabAndroid* tab, int new_index, int old_index) { ++ Update(); ++} ++ ++void ExtensionsMenuView::RestoreCompleted() { ++ Update(); + } + + void ExtensionsMenuView::OnToolbarActionAdded( +@@ -475,35 +586,112 @@ void ExtensionsMenuView::OnToolbarPinned + menu_item->UpdatePinButton(); + } + ++base::WeakPtr ExtensionsMenuView::GetWeakPtr() { ++ return weak_ptr_factory_.GetWeakPtr(); ++} ++ ++content::WebContents* ExtensionsMenuView::GetCurrentWebContents() { ++ return TabModelList::GetCurrentTabModel()->GetActiveWebContents(); ++} ++ ++void ExtensionsMenuView::ExecuteAction(std::string id) { ++ const std::vector sections = {&has_access_, &wants_access_, &cant_access_}; ++ for (auto section : sections) { ++ for (views::View* view : section->menu_items->children()) { ++ if (!GetAsMenuItemView(view)->view_controller()->GetId().compare(id)) { ++ GetAsMenuItemView(view)->view_controller()->ExecuteAction( ++ true, ToolbarActionViewController::InvocationSource::kMenuEntry); ++ return; ++ } ++ } ++ } ++} ++ + // static + base::AutoReset ExtensionsMenuView::AllowInstancesForTesting() { + return base::AutoReset(&g_allow_testing_dialogs, true); + } + + // static +-views::Widget* ExtensionsMenuView::ShowBubble( +- views::View* anchor_view, +- Browser* browser, +- ExtensionsContainer* extensions_container, +- bool allow_pinning) { ++// void ExtensionsMenuView::ShowBubble( ++static void JNI_ExtensionMenuViewBridge_CreateMenu( ++ JNIEnv* env) { + DCHECK(!g_extensions_dialog); +- g_extensions_dialog = new ExtensionsMenuView( +- anchor_view, browser, extensions_container, allow_pinning); +- views::Widget* widget = +- views::BubbleDialogDelegateView::CreateBubble(g_extensions_dialog); +- widget->Show(); +- return widget; ++ // On Android it is not guaranteed only one instance is initialized? ++ // Try to make it singleton ++ if (!g_extensions_dialog) ++// delete g_extensions_dialog; ++ g_extensions_dialog = new ExtensionsMenuView( ++ false); ++} ++ ++static ScopedJavaLocalRef JNI_ExtensionMenuViewBridge_GetIds( ++ JNIEnv* env) { ++ return ToJavaArrayOfStrings(env, g_extensions_dialog->extensions_menu_ids()); ++} ++ ++static ScopedJavaLocalRef JNI_ExtensionMenuViewBridge_GetTitles( ++ JNIEnv* env) { ++ return ToJavaArrayOfStrings(env, g_extensions_dialog->extensions_menu_titles()); ++} ++ ++static ScopedJavaLocalRef JNI_ExtensionMenuViewBridge_GetIconBitmaps( ++ JNIEnv* env) { ++ ScopedJavaLocalRef bitmap_clazz = GetClass(env, "android/graphics/Bitmap"); ++ ++ size_t bitmaps_size = 0; ++ if (ExtensionsMenuView::IsShowing()) ++ bitmaps_size = g_extensions_dialog->extensions_menu_icons().size(); ++ ++ jobjectArray joa = env->NewObjectArray(bitmaps_size, bitmap_clazz.obj(), nullptr); ++ CheckException(env); ++ ++ for (size_t i = 0; i < bitmaps_size; ++i) { ++ ScopedJavaLocalRef j_bitmap = gfx::ConvertToJavaBitmap( ++ g_extensions_dialog->extensions_menu_icons()[i]); ++ env->SetObjectArrayElement(joa, i, j_bitmap.obj()); ++ } ++ ++ return ScopedJavaLocalRef(env, joa); ++} ++ ++static ScopedJavaLocalRef JNI_ExtensionMenuViewBridge_GetPopupUrls( ++ JNIEnv* env) { ++ return ToJavaArrayOfStrings(env, g_extensions_dialog->extensions_menu_popup_urls()); + } + + // static + bool ExtensionsMenuView::IsShowing() { ++ LOG(INFO) << "extensions_menu_view.cc: IsShowing: " << (g_extensions_dialog != nullptr); + return g_extensions_dialog != nullptr; + } + + // static +-void ExtensionsMenuView::Hide() { +- if (IsShowing()) +- g_extensions_dialog->GetWidget()->Close(); ++void ExtensionsMenuView::Show(std::string url) { ++ JNIEnv* env = AttachCurrentThread(); ++ if (TabModelList::GetCurrentTabModel()->GetTabCount() > 0) { ++ TabAndroid* tab = TabModelList::GetCurrentTabModel() ++ ->GetTabAt(TabModelList::GetCurrentTabModel()->GetActiveIndex()); ++ if (tab) ++ Java_ExtensionMenuViewBridge_showCustomTab( ++ env, ++ tab->GetJavaObject(), ++ ConvertUTF8ToJavaString(env, url)); ++ } ++} ++ ++// static ++static void JNI_ExtensionMenuViewBridge_Hide(JNIEnv* env) { ++ if (ExtensionsMenuView::IsShowing()) ++ delete g_extensions_dialog; ++} ++ ++static void JNI_ExtensionMenuViewBridge_ExecuteAction( ++ JNIEnv* env, const JavaParamRef& juid) { ++ ++ std::string id = ConvertJavaStringToUTF8(env, juid); ++ LOG(INFO) << "extensions_menu_view.cc: JNI_ExtensionMenuViewBridge_ExecuteAction: g_extensions_dialog==null: " << (g_extensions_dialog == nullptr); ++ g_extensions_dialog->ExecuteAction(id); + } + + // static +--- a/chrome/browser/ui/views/extensions/extensions_menu_view.h ++++ b/chrome/browser/ui/views/extensions/extensions_menu_view.h +@@ -8,13 +8,16 @@ + #include + #include + ++#include "base/android/scoped_java_ref.h" + #include "base/auto_reset.h" + #include "base/scoped_observer.h" +-#include "chrome/browser/ui/tabs/tab_strip_model_observer.h" ++#include "base/strings/string16.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_observer.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list_observer.h" + #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" + #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" + #include "ui/gfx/geometry/size.h" +-#include "ui/views/bubble/bubble_dialog_delegate_view.h" ++#include "ui/views/view.h" + + namespace views { + class Button; +@@ -24,17 +27,17 @@ class View; + class Browser; + class ExtensionsContainer; + class ExtensionsMenuItemView; ++class GURL; + + // This bubble view displays a list of user extensions and a button to get to + // managing the user's extensions (chrome://extensions). + // This class is only used with the kExtensionsToolbarMenu feature. +-class ExtensionsMenuView : public views::BubbleDialogDelegateView, +- public TabStripModelObserver, ++class ExtensionsMenuView : public views::View, ++ public TabModelListObserver, ++ public TabModelObserver, + public ToolbarActionsModel::Observer { + public: +- ExtensionsMenuView(views::View* anchor_view, +- Browser* browser, +- ExtensionsContainer* extensions_container, ++ ExtensionsMenuView( + bool allow_pinning); + ExtensionsMenuView(const ExtensionsMenuView&) = delete; + ExtensionsMenuView& operator=(const ExtensionsMenuView&) = delete; +@@ -43,29 +46,32 @@ class ExtensionsMenuView : public views: + // Displays the ExtensionsMenu under |anchor_view|, attached to |browser|, and + // with the associated |extensions_container|. + // Only one menu is allowed to be shown at a time (outside of tests). +- static views::Widget* ShowBubble(views::View* anchor_view, +- Browser* browser, +- ExtensionsContainer* extensions_container, +- bool allow_pinning); ++// static void ShowBubble( ++// ExtensionsContainer* extensions_container, ++// bool allow_pinning); + + // Returns true if there is currently an ExtensionsMenuView showing (across + // all browsers and profiles). + static bool IsShowing(); + + // Hides the currently-showing ExtensionsMenuView, if any exists. +- static void Hide(); ++// static void Hide(); + + // Returns the currently-showing ExtensionsMenuView, if any exists. + static ExtensionsMenuView* GetExtensionsMenuViewForTesting(); + +- // TabStripModelObserver: +- void TabChangedAt(content::WebContents* contents, +- int index, +- TabChangeType change_type) override; +- void OnTabStripModelChanged( +- TabStripModel* tab_strip_model, +- const TabStripModelChange& change, +- const TabStripSelectionChange& selection) override; ++ //TabModelListObserver ++ void RegisterTabObserver(); ++ void OnTabModelAdded() override; ++ void OnTabModelRemoved() override; ++ ++ // TabModelObserver: ++ void DidSelectTab(TabAndroid* tab, TabModel::TabSelectionType type, int last_id) override; ++ void DidCloseTab(int tab_id, bool incognito) override; ++ void DidAddTab(TabAndroid* tab, TabModel::TabLaunchType type) override; ++ void TabRemoved(TabAndroid* tab) override; ++ void DidMoveTab(TabAndroid* tab, int new_index, int old_index) override; ++ void RestoreCompleted() override; + + // ToolbarActionsModel::Observer: + void OnToolbarActionAdded(const ToolbarActionsModel::ActionId& item, +@@ -85,9 +91,6 @@ class ExtensionsMenuView : public views: + std::vector extensions_menu_items_for_testing() { + return extensions_menu_items_; + } +- views::Button* manage_extensions_button_for_testing() { +- return manage_extensions_button_for_testing_; +- } + // Returns a scoped object allowing test dialogs to be created (i.e., + // instances of the ExtensionsMenuView that are not created through + // ShowBubble()). +@@ -97,6 +100,16 @@ class ExtensionsMenuView : public views: + // the view directly is more friendly to unit test setups. + static base::AutoReset AllowInstancesForTesting(); + ++ // methods for JNI ++ static void Show(std::string url); ++ void ExecuteAction(std::string id); ++ const std::vector& extensions_menu_ids() const { return extensions_menu_ids_; } ++ const std::vector& extensions_menu_titles() const { return extensions_menu_titles_; } ++ const std::vector& extensions_menu_icons() const { return extensions_menu_icons_; } ++ const std::vector& extensions_menu_popup_urls() const { ++ return extensions_menu_popup_urls_; ++ } ++ + private: + // A "section" within the menu, based on the extension's current access to + // the page. +@@ -154,20 +167,35 @@ class ExtensionsMenuView : public views: + // if DCHECKs are disabled. + void SanityCheck(); + +- Browser* const browser_; +- ExtensionsContainer* const extensions_container_; ++ // Updates cached arrays for JNI calls ++ void PopulateSection(Section* section, bool shall_clear); ++ void UpdateJavaCache(); ++ ++ // For TabModelListObserver ++ base::WeakPtr GetWeakPtr(); ++ ++ content::WebContents* GetCurrentWebContents(); ++ + bool allow_pinning_; + ToolbarActionsModel* const toolbar_model_; + ScopedObserver + toolbar_model_observer_; + std::vector extensions_menu_items_; + +- views::Button* manage_extensions_button_for_testing_ = nullptr; ++ TabModel* observed_tab_model_ = nullptr; ++ base::WeakPtrFactory weak_ptr_factory_{this}; + + // The different sections in the menu. + Section cant_access_; + Section wants_access_; + Section has_access_; ++ ++ // JNI ++ // Cached arrays ++ std::vector extensions_menu_ids_; ++ std::vector extensions_menu_titles_; ++ std::vector extensions_menu_icons_; ++ std::vector extensions_menu_popup_urls_; + }; + + #endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSIONS_MENU_VIEW_H_ +--- a/chrome/browser/extensions/extension_context_menu_model.cc ++++ b/chrome/browser/extensions/extension_context_menu_model.cc +@@ -21,6 +21,9 @@ + #include "chrome/browser/extensions/menu_manager.h" + #include "chrome/browser/extensions/scripting_permissions_modifier.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_window.h" + #include "chrome/browser/ui/chrome_pages.h" +@@ -176,9 +179,9 @@ class UninstallDialogHelper : public Ext + public: + // Kicks off the asynchronous process to confirm and uninstall the given + // |extension|. +- static void UninstallExtension(Browser* browser, const Extension* extension) { ++ static void UninstallExtension(const Extension* extension) { + UninstallDialogHelper* helper = new UninstallDialogHelper(); +- helper->BeginUninstall(browser, extension); ++ helper->BeginUninstall( extension); + } + + private: +@@ -186,12 +189,13 @@ class UninstallDialogHelper : public Ext + UninstallDialogHelper() {} + ~UninstallDialogHelper() override {} + +- void BeginUninstall(Browser* browser, const Extension* extension) { +- uninstall_dialog_ = ExtensionUninstallDialog::Create( +- browser->profile(), browser->window()->GetNativeWindow(), this); +- uninstall_dialog_->ConfirmUninstall(extension, +- UNINSTALL_REASON_USER_INITIATED, +- UNINSTALL_SOURCE_TOOLBAR_CONTEXT_MENU); ++ void BeginUninstall(const Extension* extension) { ++// TODO: launch uninstall dialog with JNI ++// uninstall_dialog_ = ExtensionUninstallDialog::Create( ++// ProfileManager::GetActiveUserProfile(), browser->window()->GetNativeWindow(), this); ++// uninstall_dialog_->ConfirmUninstall(extension, ++// UNINSTALL_REASON_USER_INITIATED, ++// UNINSTALL_SOURCE_TOOLBAR_CONTEXT_MENU); + } + + // ExtensionUninstallDialog::Delegate: +@@ -209,16 +213,13 @@ class UninstallDialogHelper : public Ext + + ExtensionContextMenuModel::ExtensionContextMenuModel( + const Extension* extension, +- Browser* browser, + ButtonVisibility button_visibility, + PopupDelegate* delegate, + bool can_show_icon_in_toolbar) + : SimpleMenuModel(this), + extension_id_(extension->id()), + is_component_(Manifest::IsComponentLocation(extension->location())), +- browser_(browser), +- profile_(browser->profile()), +- delegate_(delegate), ++ profile_(ProfileManager::GetActiveUserProfile()), + button_visibility_(button_visibility), + can_show_icon_in_toolbar_(can_show_icon_in_toolbar) { + InitMenu(extension, button_visibility); +@@ -307,7 +308,7 @@ bool ExtensionContextMenuModel::IsComman + // a trace of user activity. + case TOGGLE_VISIBILITY: + return (base::FeatureList::IsEnabled(features::kExtensionsToolbarMenu) && +- !browser_->profile()->IsOffTheRecord() && ++ !ProfileManager::GetActiveUserProfile()->IsOffTheRecord() && + !IsExtensionForcePinned(*extension, profile_)); + // Manage extensions is always enabled. + case MANAGE_EXTENSIONS: +@@ -340,7 +341,7 @@ void ExtensionContextMenuModel::ExecuteC + content::Referrer(), + WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_LINK, false); +- browser_->OpenURL(params); ++ GetActiveWebContents()->OpenURL(params); + break; + } + case OPTIONS: +@@ -349,20 +350,19 @@ void ExtensionContextMenuModel::ExecuteC + break; + case TOGGLE_VISIBILITY: { + bool currently_visible = button_visibility_ == PINNED; +- ToolbarActionsModel::Get(browser_->profile()) ++ ToolbarActionsModel::Get(ProfileManager::GetActiveUserProfile()) + ->SetActionVisibility(extension->id(), !currently_visible); + break; + } + case UNINSTALL: { +- UninstallDialogHelper::UninstallExtension(browser_, extension); ++ UninstallDialogHelper::UninstallExtension(extension); + break; + } + case MANAGE_EXTENSIONS: { +- chrome::ShowExtensions(browser_, extension->id()); ++ chrome::ShowExtensions(nullptr, extension->id()); + break; + } + case INSPECT_POPUP: { +- delegate_->InspectPopup(); + break; + } + case PAGE_ACCESS_RUN_ON_CLICK: +@@ -452,7 +452,7 @@ void ExtensionContextMenuModel::InitMenu + } + + const ActionInfo* action_info = ActionInfo::GetExtensionActionInfo(extension); +- if (delegate_ && !is_component_ && action_info && !action_info->synthesized && ++ if (!is_component_ && action_info && !action_info->synthesized && + profile_->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode)) { + AddSeparator(ui::NORMAL_SEPARATOR); + AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP); +@@ -605,7 +605,7 @@ void ExtensionContextMenuModel::HandlePa + GURL(chrome_extension_constants::kRuntimeHostPermissionsHelpURL), + content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui::PAGE_TRANSITION_LINK, false); +- browser_->OpenURL(params); ++ GetActiveWebContents()->OpenURL(params); + return; + } + +@@ -659,7 +659,7 @@ void ExtensionContextMenuModel::LogPageA + } + + content::WebContents* ExtensionContextMenuModel::GetActiveWebContents() const { +- return browser_->tab_strip_model()->GetActiveWebContents(); ++ return TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + } + + } // namespace extensions +--- a/chrome/browser/extensions/extension_context_menu_model.h ++++ b/chrome/browser/extensions/extension_context_menu_model.h +@@ -100,7 +100,6 @@ class ExtensionContextMenuModel : public + // will be shown for "Inspect Popup" which, when selected, will cause + // ShowPopupForDevToolsWindow() to be called on |delegate|. + ExtensionContextMenuModel(const Extension* extension, +- Browser* browser, + ButtonVisibility visibility, + PopupDelegate* delegate, + bool can_show_icon_in_toolbar); +@@ -158,13 +157,8 @@ class ExtensionContextMenuModel : public + // it has one, otherwise NULL). + ExtensionAction* extension_action_; + +- Browser* const browser_; +- + Profile* profile_; + +- // The delegate which handles the 'inspect popup' menu command (or NULL). +- PopupDelegate* delegate_; +- + // The visibility of the button at the time the menu opened. + ButtonVisibility button_visibility_; + +--- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc ++++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.cc +@@ -10,12 +10,12 @@ + #include "base/metrics/user_metrics_action.h" + #include "chrome/app/vector_icons/vector_icons.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/toolbar/toolbar_action_view_controller.h" + #include "chrome/browser/ui/toolbar/toolbar_actions_model.h" + #include "chrome/browser/ui/views/bubble_menu_item_factory.h" + #include "chrome/browser/ui/views/extensions/extension_context_menu_controller.h" +-#include "chrome/browser/ui/views/extensions/extensions_menu_button.h" + #include "chrome/grit/generated_resources.h" + #include "ui/base/l10n/l10n_util.h" + #include "ui/gfx/color_utils.h" +@@ -43,14 +43,9 @@ constexpr gfx::Size ExtensionsMenuItemVi + constexpr char ExtensionsMenuItemView::kClassName[]; + + ExtensionsMenuItemView::ExtensionsMenuItemView( +- Browser* browser, + std::unique_ptr controller, + bool allow_pinning) +- : profile_(browser->profile()), +- primary_action_button_(new ExtensionsMenuButton(browser, +- this, +- controller.get(), +- allow_pinning)), ++ : profile_(ProfileManager::GetActiveUserProfile()), + controller_(std::move(controller)), + model_(ToolbarActionsModel::Get(profile_)) { + // Set so the extension button receives enter/exit on children to retain hover +@@ -65,38 +60,38 @@ ExtensionsMenuItemView::ExtensionsMenuIt + layout_manager_->SetOrientation(views::LayoutOrientation::kHorizontal) + .SetIgnoreDefaultMainAxisMargins(true); + +- AddChildView(primary_action_button_); +- primary_action_button_->SetProperty( +- views::kFlexBehaviorKey, +- views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, +- views::MaximumFlexSizeRule::kUnbounded)); +- +- if (primary_action_button_->CanShowIconInToolbar()) { +- auto pin_button = CreateBubbleMenuItem( +- EXTENSION_PINNING, +- base::BindRepeating(&ExtensionsMenuItemView::PinButtonPressed, +- base::Unretained(this))); +- pin_button->SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets)); +- +- pin_button_ = pin_button.get(); +- AddChildView(std::move(pin_button)); +- } +- UpdatePinButton(); +- +- auto context_menu_button = CreateBubbleMenuItem( +- EXTENSION_CONTEXT_MENU, views::Button::PressedCallback()); +- context_menu_button->SetBorder( +- views::CreateEmptyBorder(kSecondaryButtonInsets)); +- context_menu_button->SetTooltipText( +- l10n_util::GetStringUTF16(IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP)); +- context_menu_button->SetButtonController( +- std::make_unique( +- context_menu_button.get(), +- base::BindRepeating(&ExtensionsMenuItemView::ContextMenuPressed, +- base::Unretained(this)), +- std::make_unique( +- context_menu_button.get()))); +- context_menu_button_ = AddChildView(std::move(context_menu_button)); ++// AddChildView(primary_action_button_); ++// primary_action_button_->SetProperty( ++// views::kFlexBehaviorKey, ++// views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero, ++// views::MaximumFlexSizeRule::kUnbounded)); ++// ++// if (primary_action_button_->CanShowIconInToolbar()) { ++// auto pin_button = CreateBubbleMenuItem( ++// EXTENSION_PINNING, ++// base::BindRepeating(&ExtensionsMenuItemView::PinButtonPressed, ++// base::Unretained(this))); ++// pin_button->SetBorder(views::CreateEmptyBorder(kSecondaryButtonInsets)); ++// ++// pin_button_ = pin_button.get(); ++// AddChildView(std::move(pin_button)); ++// } ++// UpdatePinButton(); ++ ++// auto context_menu_button = CreateBubbleMenuItem( ++// EXTENSION_CONTEXT_MENU, views::Button::PressedCallback()); ++// context_menu_button->SetBorder( ++// views::CreateEmptyBorder(kSecondaryButtonInsets)); ++// context_menu_button->SetTooltipText( ++// l10n_util::GetStringUTF16(IDS_EXTENSIONS_MENU_CONTEXT_MENU_TOOLTIP)); ++// context_menu_button->SetButtonController( ++// std::make_unique( ++// context_menu_button.get(), ++// base::BindRepeating(&ExtensionsMenuItemView::ContextMenuPressed, ++// base::Unretained(this)), ++// std::make_unique( ++// context_menu_button.get()))); ++// context_menu_button_ = AddChildView(std::move(context_menu_button)); + } + + ExtensionsMenuItemView::~ExtensionsMenuItemView() = default; +@@ -111,17 +106,17 @@ void ExtensionsMenuItemView::OnThemeChan + GetAdjustedIconColor(GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_MenuIconColor)); + +- if (pin_button_) +- pin_button_->SetInkDropBaseColor(icon_color); +- views::SetImageFromVectorIconWithColor(context_menu_button_, +- kBrowserToolsIcon, +- kSecondaryIconSizeDp, icon_color); +- UpdatePinButton(); ++// if (pin_button_) ++// pin_button_->SetInkDropBaseColor(icon_color); ++// views::SetImageFromVectorIconWithColor(context_menu_button_, ++// kBrowserToolsIcon, ++// kSecondaryIconSizeDp, icon_color); ++// UpdatePinButton(); + } + + void ExtensionsMenuItemView::UpdatePinButton() { +- if (!pin_button_) +- return; ++// if (!pin_button_) ++// return; + + bool is_force_pinned = + model_ && model_->IsActionForcePinned(controller_->GetId()); +@@ -132,10 +127,10 @@ void ExtensionsMenuItemView::UpdatePinBu + pin_button_string_id = IDS_EXTENSIONS_UNPIN_FROM_TOOLBAR; + else + pin_button_string_id = IDS_EXTENSIONS_PIN_TO_TOOLBAR; +- pin_button_->SetTooltipText(l10n_util::GetStringUTF16(pin_button_string_id)); ++// pin_button_->SetTooltipText(l10n_util::GetStringUTF16(pin_button_string_id)); + // Extension pinning is not available in Incognito as it leaves a trace of + // user activity. +- pin_button_->SetEnabled(!is_force_pinned && !profile_->IsOffTheRecord()); ++// pin_button_->SetEnabled(!is_force_pinned && !profile_->IsOffTheRecord()); + + SkColor unpinned_icon_color = + GetAdjustedIconColor(GetNativeTheme()->GetSystemColor( +@@ -144,9 +139,9 @@ void ExtensionsMenuItemView::UpdatePinBu + IsPinned() ? GetAdjustedIconColor(GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_ProminentButtonColor)) + : unpinned_icon_color; +- views::SetImageFromVectorIconWithColor( +- pin_button_, IsPinned() ? views::kUnpinIcon : views::kPinIcon, +- kSecondaryIconSizeDp, icon_color); ++// views::SetImageFromVectorIconWithColor( ++// pin_button_, IsPinned() ? views::kUnpinIcon : views::kPinIcon, ++// kSecondaryIconSizeDp, icon_color); + } + + bool ExtensionsMenuItemView::IsContextMenuRunning() const { +@@ -162,9 +157,9 @@ void ExtensionsMenuItemView::ContextMenu + base::RecordAction(base::UserMetricsAction( + "Extensions.Toolbar.MoreActionsButtonPressedFromMenu")); + // TODO(crbug.com/998298): Cleanup the menu source type. +- context_menu_controller_->ShowContextMenuForViewImpl( +- context_menu_button_, context_menu_button_->GetMenuPosition(), +- ui::MenuSourceType::MENU_SOURCE_MOUSE); ++// context_menu_controller_->ShowContextMenuForViewImpl( ++// context_menu_button_, context_menu_button_->GetMenuPosition(), ++// ui::MenuSourceType::MENU_SOURCE_MOUSE); + } + + void ExtensionsMenuItemView::PinButtonPressed() { +@@ -173,11 +168,6 @@ void ExtensionsMenuItemView::PinButtonPr + model_->SetActionVisibility(controller_->GetId(), !IsPinned()); + } + +-ExtensionsMenuButton* +-ExtensionsMenuItemView::primary_action_button_for_testing() { +- return primary_action_button_; +-} +- + SkColor ExtensionsMenuItemView::GetAdjustedIconColor(SkColor icon_color) const { + const SkColor background_color = GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_BubbleBackground); +--- a/chrome/browser/ui/views/extensions/extensions_menu_item_view.h ++++ b/chrome/browser/ui/views/extensions/extensions_menu_item_view.h +@@ -24,6 +24,9 @@ class ImageButton; + // particular extension. Includes information about the extension in addition to + // a button to pin the extension to the toolbar and a button for accessing the + // associated context menu. ++// ++// Remove any code that does actually UI drawing but keep the views, since it ++// has the hierachical information + class ExtensionsMenuItemView : public views::View { + public: + static constexpr int kMenuItemHeightDp = 40; +@@ -31,7 +34,6 @@ class ExtensionsMenuItemView : public vi + static constexpr const char kClassName[] = "ExtensionsMenuItemView"; + + ExtensionsMenuItemView( +- Browser* browser, + std::unique_ptr controller, + bool allow_pinning); + ExtensionsMenuItemView(const ExtensionsMenuItemView&) = delete; +@@ -55,12 +57,6 @@ class ExtensionsMenuItemView : public vi + return controller_.get(); + } + +- ExtensionsMenuButton* primary_action_button_for_testing(); +- views::ImageButton* context_menu_button_for_testing() { +- return context_menu_button_; +- } +- views::ImageButton* pin_button_for_testing() { return pin_button_; } +- + private: + // Maybe adjust |icon_color| to assure high enough contrast with the + // background. +@@ -68,16 +64,12 @@ class ExtensionsMenuItemView : public vi + + Profile* const profile_; + +- ExtensionsMenuButton* const primary_action_button_; +- + std::unique_ptr controller_; + + views::ImageButton* context_menu_button_ = nullptr; + + ToolbarActionsModel* const model_; + +- views::ImageButton* pin_button_ = nullptr; +- + // This controller is responsible for showing the context menu for an + // extension. + std::unique_ptr context_menu_controller_; +--- a/chrome/browser/ui/chrome_pages.cc ++++ b/chrome/browser/ui/chrome_pages.cc +@@ -30,6 +30,8 @@ + #include "chrome/browser/profiles/profile.h" + #include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/signin/account_consistency_mode_manager.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_finder.h" + #include "chrome/browser/ui/browser_navigator_params.h" +@@ -92,9 +94,18 @@ void FocusWebContents(Browser* browser) + // ignoring the URL path, then that tab becomes selected. Overwrites the new tab + // page if it is open. + void ShowSingletonTabIgnorePathOverwriteNTP(Browser* browser, const GURL& url) { ++#if defined(OS_ANDROID) ++ TabModelList::GetCurrentTabModel()->GetActiveWebContents()->OpenURL( ++ content::OpenURLParams( ++ url, content::Referrer(), ++ WindowOpenDisposition::CURRENT_TAB, ++ ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false ++ )); ++#else + NavigateParams params(GetSingletonTabNavigateParams(browser, url)); + params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE; + ShowSingletonTabOverwritingNTP(browser, std::move(params)); ++#endif + } + + void OpenBookmarkManagerForNode(Browser* browser, int64_t node_id) { +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -3238,6 +3238,7 @@ generate_jni("chrome_jni_headers") { + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionMenuViewBridge.java", + "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", + "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java", + "java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java", +--- a/chrome/android/chrome_java_sources.gni ++++ b/chrome/android/chrome_java_sources.gni +@@ -688,6 +688,8 @@ chrome_java_sources = [ + "java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallCustomScrollView.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionMenuViewBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionMenuItem.java", + "java/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtils.java", + "java/src/org/chromium/chrome/browser/externalauth/UserRecoverableErrorHandler.java", + "java/src/org/chromium/chrome/browser/externalauth/VerifiedHandler.java", +--- a/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc ++++ b/chrome/browser/ui/views/extensions/extensions_toolbar_button.cc +@@ -105,12 +105,12 @@ int ExtensionsToolbarButton::GetIconSize + + void ExtensionsToolbarButton::ButtonPressed() { + if (ExtensionsMenuView::IsShowing()) { +- ExtensionsMenuView::Hide(); ++// ExtensionsMenuView::Hide(); + return; + } + pressed_lock_ = menu_button_controller_->TakeLock(); + base::RecordAction(base::UserMetricsAction("Extensions.Toolbar.MenuOpened")); +- ExtensionsMenuView::ShowBubble(this, browser_, extensions_container_, +- extensions_container_->CanShowIconInToolbar()) +- ->AddObserver(this); ++// ExtensionsMenuView::ShowBubble(this, browser_, extensions_container_, ++// extensions_container_->CanShowIconInToolbar()) ++// ->AddObserver(this); + } +--- a/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc ++++ b/chrome/browser/ui/views/extensions/extensions_toolbar_container.cc +@@ -310,7 +310,7 @@ void ExtensionsToolbarContainer::HideAct + + bool ExtensionsToolbarContainer::CloseOverflowMenuIfOpen() { + if (ExtensionsMenuView::IsShowing()) { +- ExtensionsMenuView::Hide(); ++// ExtensionsMenuView::Hide(); + return true; + } + return false; +@@ -465,7 +465,7 @@ void ExtensionsToolbarContainer::CreateA + void ExtensionsToolbarContainer::CreateActionForId( + const ToolbarActionsModel::ActionId& action_id) { + actions_.push_back( +- model_->CreateActionForId(browser_, this, false, action_id)); ++ model_->CreateActionForId(false, action_id)); + auto icon = std::make_unique(actions_.back().get(), this); + // Set visibility before adding to prevent extraneous animation. + icon->SetVisible(CanShowIconInToolbar() && model_->IsActionPinned(action_id)); +--- a/chrome/browser/ui/toolbar/toolbar_actions_bar.cc ++++ b/chrome/browser/ui/toolbar/toolbar_actions_bar.cc +@@ -338,7 +338,7 @@ void ToolbarActionsBar::CreateActions() + + // Get the toolbar actions. + toolbar_actions_ = +- model_->CreateActions(browser_, GetMainBar(), in_overflow_mode()); ++ model_->CreateActions(in_overflow_mode()); + if (!toolbar_actions_.empty()) + ReorderActions(); + +@@ -662,7 +662,7 @@ void ToolbarActionsBar::OnToolbarActionA + + toolbar_actions_.insert( + toolbar_actions_.begin() + index, +- model_->CreateActionForId(browser_, GetMainBar(), in_overflow_mode(), ++ model_->CreateActionForId(in_overflow_mode(), + action_id)); + delegate_->AddViewForAction(toolbar_actions_[index].get(), index); + +@@ -795,7 +795,7 @@ void ToolbarActionsBar::OnToolbarHighlig + + if (!found) { + toolbar_actions_.push_back(model_->CreateActionForId( +- browser_, GetMainBar(), in_overflow_mode(), model_action_id)); ++ in_overflow_mode(), model_action_id)); + delegate_->AddViewForAction(toolbar_actions_.back().get(), + toolbar_actions_.size() - 1); + } +--- a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc ++++ b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.cc +@@ -10,6 +10,7 @@ + #include "base/memory/ptr_util.h" + #include "chrome/browser/extensions/extension_view_host.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/extensions/accelerator_priority.h" + #include "chrome/browser/ui/views/extensions/extension_popup.h" +@@ -37,7 +38,7 @@ ExtensionActionPlatformDelegateViews::Ex + ExtensionActionViewController* controller) + : controller_(controller) { + command_service_observer_.Add( +- extensions::CommandService::Get(controller_->browser()->profile())); ++ extensions::CommandService::Get(ProfileManager::GetActiveUserProfile())); + } + + ExtensionActionPlatformDelegateViews::~ExtensionActionPlatformDelegateViews() { +@@ -50,15 +51,15 @@ void ExtensionActionPlatformDelegateView + if (action_keybinding_) + return; + +- extensions::Command extension_command; +- views::FocusManager* focus_manager = +- GetDelegateViews()->GetFocusManagerForAccelerator(); +- if (focus_manager && controller_->GetExtensionCommand(&extension_command)) { +- action_keybinding_ = +- std::make_unique(extension_command.accelerator()); +- focus_manager->RegisterAccelerator(*action_keybinding_, +- kExtensionAcceleratorPriority, this); +- } ++// extensions::Command extension_command; ++// views::FocusManager* focus_manager = ++// GetDelegateViews()->GetFocusManagerForAccelerator(); ++// if (focus_manager && controller_->GetExtensionCommand(&extension_command)) { ++// action_keybinding_ = ++// std::make_unique(extension_command.accelerator()); ++// focus_manager->RegisterAccelerator(*action_keybinding_, ++// kExtensionAcceleratorPriority, this); ++// } + } + + void ExtensionActionPlatformDelegateViews::UnregisterCommand() { +@@ -66,12 +67,12 @@ void ExtensionActionPlatformDelegateView + if (!action_keybinding_) + return; + +- views::FocusManager* focus_manager = +- GetDelegateViews()->GetFocusManagerForAccelerator(); +- if (focus_manager) { +- focus_manager->UnregisterAccelerator(*action_keybinding_, this); +- action_keybinding_.reset(); +- } ++// views::FocusManager* focus_manager = ++// GetDelegateViews()->GetFocusManagerForAccelerator(); ++// if (focus_manager) { ++// focus_manager->UnregisterAccelerator(*action_keybinding_, this); ++// action_keybinding_.reset(); ++// } + } + + void ExtensionActionPlatformDelegateViews::ShowPopup( +@@ -85,15 +86,15 @@ void ExtensionActionPlatformDelegateView + ExtensionPopup::ShowAction popup_show_action = + show_action == ExtensionActionViewController::SHOW_POPUP ? + ExtensionPopup::SHOW : ExtensionPopup::SHOW_AND_INSPECT; +- ExtensionPopup::ShowPopup(std::move(host), +- GetDelegateViews()->GetReferenceButtonForPopup(), +- arrow, popup_show_action); ++// ExtensionPopup::ShowPopup(std::move(host), ++// GetDelegateViews()->GetReferenceButtonForPopup(), ++// arrow, popup_show_action); + } + + void ExtensionActionPlatformDelegateViews::ShowContextMenu() { +- views::View* view = GetDelegateViews()->GetAsView(); +- view->context_menu_controller()->ShowContextMenuForView( +- view, view->GetKeyboardContextMenuLocation(), ui::MENU_SOURCE_NONE); ++// views::View* view = GetDelegateViews()->GetAsView(); ++// view->context_menu_controller()->ShowContextMenuForView( ++// view, view->GetKeyboardContextMenuLocation(), ui::MENU_SOURCE_NONE); + } + + void ExtensionActionPlatformDelegateViews::OnExtensionCommandAdded( +@@ -154,8 +155,8 @@ bool ExtensionActionPlatformDelegateView + return controller_->CanHandleAccelerators(); + } + +-ToolbarActionViewDelegateViews* +-ExtensionActionPlatformDelegateViews::GetDelegateViews() const { +- return static_cast( +- controller_->view_delegate()); +-} ++// ToolbarActionViewDelegateViews* ++// ExtensionActionPlatformDelegateViews::GetDelegateViews() const { ++// return static_cast( ++// controller_->view_delegate()); ++// } +--- a/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.h ++++ b/chrome/browser/ui/views/extensions/extension_action_platform_delegate_views.h +@@ -51,7 +51,7 @@ class ExtensionActionPlatformDelegateVie + bool AcceleratorPressed(const ui::Accelerator& accelerator) override; + bool CanHandleAccelerators() const override; + +- ToolbarActionViewDelegateViews* GetDelegateViews() const; ++// ToolbarActionViewDelegateViews* GetDelegateViews() const; + + // The owning ExtensionActionViewController. + ExtensionActionViewController* controller_; +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionMenuItem.java +@@ -0,0 +1,73 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import androidx.annotation.Nullable; ++ ++import android.content.Context; ++import android.content.res.Resources; ++import android.graphics.Bitmap; ++ ++ ++/** ++ * A class for representing an extension menu item. ++ */ ++public class ExtensionMenuItem { ++ private final String mUId; ++ private final String mTitle; ++ private final Bitmap mIcon; ++ private final String mPopupUrl; ++ private int mId; ++ ++ private final String TAG = "ExtensionMenuItem.java"; ++ ++ /* ++ * Construct a new instance ++ */ ++ public ExtensionMenuItem(String uId, String title, Bitmap icon, String popupUrl) { ++ mUId = uId; ++ mTitle = title; ++ mIcon = icon; ++ mPopupUrl = popupUrl; ++ } ++ ++ public void setId(int id) { ++ mId = id; ++ } ++ ++ public String getUId() { ++ return mUId; ++ } ++ ++ public String getTitle() { ++ return mTitle; ++ } ++ ++ public Bitmap getIcon() { ++ return mIcon; ++ } ++ ++ public String getPopupUrl() { ++ return mPopupUrl; ++ } ++ ++ public int getId() { ++ return mId; ++ } ++} +--- a/chrome/browser/ui/toolbar/toolbar_action_view_controller.h ++++ b/chrome/browser/ui/toolbar/toolbar_action_view_controller.h +@@ -7,6 +7,7 @@ + + #include "base/strings/string16.h" + #include "ui/gfx/image/image.h" ++#include "url/gurl.h" + + namespace content { + class WebContents; +@@ -103,6 +104,9 @@ class ToolbarActionViewController { + // Hides the current popup, if one is visible. + virtual void HidePopup() = 0; + ++ // Gets the url of the popup, if the action has a popup ++ virtual GURL GetPopupUrl(content::WebContents* web_contents) { return GURL{}; } ++ + // Returns the native view for the popup, if one is active. + virtual gfx::NativeView GetPopupNativeView() = 0; + diff --git a/patches/Extensions/allow-select-folder.patch b/patches/Extensions/allow-select-folder.patch new file mode 100644 index 0000000..118fc43 --- /dev/null +++ b/patches/Extensions/allow-select-folder.patch @@ -0,0 +1,281 @@ +From: Wengling Chen +Date: Sat, 06 Jun 2020 21:32:57 -0400 +Subject: add folder selection mode picker + + +--- + ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java | 169 +++++++++- + ui/shell_dialogs/select_file_dialog_android.cc | 6 + 2 files changed, 164 insertions(+), 11 deletions(-) + +--- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java ++++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +@@ -15,10 +15,13 @@ import android.content.Intent; + import android.content.pm.PackageManager; + import android.net.Uri; + import android.os.Build; ++import android.os.storage.StorageManager; + import android.provider.MediaStore; ++import android.provider.DocumentsContract; + import android.text.TextUtils; + import android.webkit.MimeTypeMap; + ++import androidx.annotation.Nullable; + import androidx.annotation.VisibleForTesting; + + import org.chromium.base.ContentUriUtils; +@@ -39,6 +42,8 @@ import org.chromium.ui.UiUtils; + + import java.io.File; + import java.io.IOException; ++import java.lang.reflect.Array; ++import java.lang.reflect.Method; + import java.util.ArrayList; + import java.util.Arrays; + import java.util.List; +@@ -92,6 +97,7 @@ public class SelectFileDialog implements + + private final long mNativeSelectFileDialog; + private List mFileTypes; ++ private boolean mIsFolder; + private boolean mCapture; + private boolean mAllowMultiple; + private Uri mCameraOutputUri; +@@ -153,9 +159,10 @@ public class SelectFileDialog implements + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) + @CalledByNative + private void selectFile( +- String[] fileTypes, boolean capture, boolean multiple, WindowAndroid window) { ++ String[] fileTypes, boolean capture, boolean multiple, boolean isFolder, WindowAndroid window) { + mFileTypes = new ArrayList(Arrays.asList(fileTypes)); + mCapture = capture; ++ mIsFolder = isFolder; + mAllowMultiple = multiple; + mWindowAndroid = (sOverrideWindowAndroid == null) ? window : sOverrideWindowAndroid; + +@@ -247,6 +254,12 @@ public class SelectFileDialog implements + RecordHistogram.recordEnumeratedHistogram("Android.SelectFileDialogScope", + determineSelectFileDialogScope(), SELECT_FILE_DIALOG_SCOPE_COUNT); + ++ Intent folderSelector = null; ++ if (mIsFolder) { ++ folderSelector = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); ++ folderSelector.addCategory(Intent.CATEGORY_DEFAULT); ++ } ++ + boolean hasCameraPermission = mWindowAndroid.hasPermission(Manifest.permission.CAMERA); + Intent camcorder = null; + if (mSupportsVideoCapture && hasCameraPermission) { +@@ -288,15 +301,22 @@ public class SelectFileDialog implements + if (acceptsSingleType()) { + // If one and only one category of accept type was specified (image, video, etc..), + // then update the intent to specifically target that request. +- if (shouldShowImageTypes()) { ++ if (shouldShowImageTypes() && !mIsFolder) { ++ Log.i("SelectFileDialog.java", "shouldShowImageTypes"); + if (camera != null) extraIntents.add(camera); + getContentIntent.setType(IMAGE_TYPE + "/*"); +- } else if (shouldShowVideoTypes()) { ++ } else if (shouldShowVideoTypes() && !mIsFolder) { ++ Log.i("SelectFileDialog.java", "shouldShowVideoTypes"); + if (camcorder != null) extraIntents.add(camcorder); + getContentIntent.setType(VIDEO_TYPE + "/*"); +- } else if (shouldShowAudioTypes()) { ++ } else if (shouldShowAudioTypes() && !mIsFolder) { ++ Log.i("SelectFileDialog.java", "shouldShowAudioTypes"); + if (soundRecorder != null) extraIntents.add(soundRecorder); + getContentIntent.setType(AUDIO_TYPE + "/*"); ++ } else if (mIsFolder) { ++ Log.i("SelectFileDialog.java", "mIsFolder, add(folderSelector)"); ++ if (folderSelector != null) extraIntents.add(folderSelector); ++ getContentIntent.setType(ALL_TYPES); + } + + // If any types are specified, then only accept openable files, as coercing +@@ -307,13 +327,20 @@ public class SelectFileDialog implements + if (extraIntents.isEmpty()) { + // We couldn't resolve a single accept type, so fallback to a generic chooser. + getContentIntent.setType(ALL_TYPES); +- if (camera != null) extraIntents.add(camera); +- if (camcorder != null) extraIntents.add(camcorder); +- if (soundRecorder != null) extraIntents.add(soundRecorder); ++ if (!mIsFolder) { ++ Log.i("SelectFileDialog.java", "!mIsFolder"); ++ if (camera != null) extraIntents.add(camera); ++ if (camcorder != null) extraIntents.add(camcorder); ++ if (soundRecorder != null) extraIntents.add(soundRecorder); ++ } else { ++ Log.i("SelectFileDialog.java", "mIsFolder, add(folderSelector), 2"); ++ if (folderSelector != null) extraIntents.add(folderSelector); ++ } + } + + Intent chooser = new Intent(Intent.ACTION_CHOOSER); + if (!extraIntents.isEmpty()) { ++ Log.i("SelectFileDialog.java", "EXTRA_INITIAL_INTENTS"); + chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, + extraIntents.toArray(new Intent[] { })); + } +@@ -802,16 +829,39 @@ public class SelectFileDialog implements + String[] displayNames = new String[mUris.length]; + try { + for (int i = 0; i < mUris.length; i++) { ++ // Convert content Uri to absolute file path if in folder selection mode ++ if (mIsFolder) { ++ Context context = ContextUtils.getApplicationContext(); ++ String path = FileUtil.getFullPathFromTreeUri(mUris[i], context); ++ if (path != null) { ++ mUris[i] = Uri.fromFile(new File(path)); ++ Log.i("SelectFileDialog.java", "mUris: %s, path: %s", mUris[i].toString(), path); ++ } else ++ Log.i("SelectFileDialog.java", "mUris: %s, path: %s", mUris[i].toString(), "NULL"); ++ } ++ + // The selected files must be returned as a list of absolute paths. A MIUI 8.5 + // device was observed to return a file:// URI instead, so convert if necessary. + // See https://crbug.com/752834 for context. + if (ContentResolver.SCHEME_FILE.equals(mUris[i].getScheme())) { +- mFilePaths[i] = mUris[i].getSchemeSpecificPart(); ++ String filePath = mUris[i].getSchemeSpecificPart(); ++ // Remove extra "//" if exists ++ if (filePath.startsWith("//") && filePath.length() > 2) ++ mFilePaths[i] = filePath.substring(2); ++ Log.i("SelectFileDialog.java", "mFilePaths1: %s", mFilePaths[i]); + } else { + mFilePaths[i] = mUris[i].toString(); ++ Log.i("SelectFileDialog.java", "mFilePaths2: %s", mFilePaths[i]); ++ } ++ ++ if (mIsFolder) { ++ displayNames[i] = mFilePaths[i]; ++ Log.i("SelectFileDialog.java", "displayNames1: %s", displayNames[i]); ++ } else { ++ displayNames[i] = ContentUriUtils.getDisplayName( ++ mUris[i], mContext, MediaStore.MediaColumns.DISPLAY_NAME); ++ Log.i("SelectFileDialog.java", "displayNames2: %s", displayNames[i]); + } +- displayNames[i] = ContentUriUtils.getDisplayName( +- mUris[i], mContext, MediaStore.MediaColumns.DISPLAY_NAME); + } + } catch (SecurityException e) { + // Some third party apps will present themselves as being able +@@ -927,4 +977,103 @@ public class SelectFileDialog implements + void onContactsSelected( + long nativeSelectFileDialogImpl, SelectFileDialog caller, String contacts); + } ++ ++ // The following code is from ++ // Stack Overflow. ++ // Licensed under CC-BY-SA 3.0. ++ private static final class FileUtil { ++ private static final String[] PRIMARY_VOLUME_NAME = {"primary", "raw"}; ++ ++ @Nullable ++ static String getFullPathFromTreeUri(@Nullable final Uri treeUri, Context con) { ++ if (treeUri == null) return null; ++ String volumePath = getVolumePath(getVolumeIdFromTreeUri(treeUri),con); ++ if (volumePath == null) ++ Log.i("SelectFileDialog.java", "volumePath: %s", "NULL"); ++ else ++ Log.i("SelectFileDialog.java", "volumePath: %s", volumePath); ++ if (volumePath == null) return File.separator; ++ if (volumePath.endsWith(File.separator)) ++ volumePath = volumePath.substring(0, volumePath.length() - 1); ++ ++ String documentPath = getDocumentPathFromTreeUri(treeUri); ++ if (documentPath == null || documentPath.equals("")) ++ Log.i("SelectFileDialog.java", "documentPath: %s", "NULL"); ++ else ++ Log.i("SelectFileDialog.java", "documentPath: %s", documentPath); ++ if (volumePath.endsWith(File.separator)) ++ volumePath = volumePath.substring(0, volumePath.length() - 1); ++ if (documentPath.endsWith(File.separator)) ++ documentPath = documentPath.substring(0, documentPath.length() - 1); ++ ++ if (documentPath.length() > 0) { ++ if (!documentPath.startsWith(volumePath)) { ++ if (documentPath.startsWith(File.separator)) ++ return volumePath + documentPath; ++ else ++ return volumePath + File.separator + documentPath; ++ } ++ else ++ return documentPath; ++ } ++ else return volumePath; ++ } ++ ++ private static String getVolumePath(final String volumeId, Context context) { ++ Log.i("SelectFileDialog.java", "getVolumePath: volumeId: %s", volumeId); ++ try { ++ StorageManager mStorageManager = ++ (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); ++ Class storageVolumeClazz = Class.forName("android.os.storage.StorageVolume"); ++ Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList"); ++ Method getUuid = storageVolumeClazz.getMethod("getUuid"); ++ Method getPath = storageVolumeClazz.getMethod("getPath"); ++ Method isPrimary = storageVolumeClazz.getMethod("isPrimary"); ++ Object result = getVolumeList.invoke(mStorageManager); ++ ++ final int length = Array.getLength(result); ++ Log.i("SelectFileDialog.java", "getVolumePath: length: %d", length); ++ for (int i = 0; i < length; i++) { ++ Object storageVolumeElement = Array.get(result, i); ++ String uuid = (String) getUuid.invoke(storageVolumeElement); ++ Log.i("SelectFileDialog.java", "getVolumePath: uuid: %s", uuid); ++ Boolean primary = (Boolean) isPrimary.invoke(storageVolumeElement); ++ Log.i("SelectFileDialog.java", "getVolumePath: primary: %b", primary); ++ ++ // primary volume? ++ for (String volume_name : PRIMARY_VOLUME_NAME) { ++ if (primary && volume_name.equals(volumeId)) ++ return (String) getPath.invoke(storageVolumeElement); ++ } ++ ++ // other volumes? ++ if (uuid != null && uuid.equals(volumeId)) ++ return (String) getPath.invoke(storageVolumeElement); ++ } ++ // not found. ++ return null; ++ } catch (Exception ex) { ++ Log.e("SelectFileDialog.java", "getVolumePath: Exception: %s", ex.getMessage()); ++ return null; ++ } ++ } ++ ++ @TargetApi(Build.VERSION_CODES.LOLLIPOP) ++ private static String getVolumeIdFromTreeUri(final Uri treeUri) { ++ final String docId = DocumentsContract.getTreeDocumentId(treeUri); ++ Log.i("SelectFileDialog.java", "getVolumeIdFromTreeUri: docId: %s", docId); ++ final String[] split = docId.split(":"); ++ if (split.length > 0) return split[0]; ++ else return null; ++ } ++ ++ @TargetApi(Build.VERSION_CODES.LOLLIPOP) ++ private static String getDocumentPathFromTreeUri(final Uri treeUri) { ++ final String docId = DocumentsContract.getTreeDocumentId(treeUri); ++ Log.i("SelectFileDialog.java", "getDocumentPathFromTreeUri: docId: %s", docId); ++ final String[] split = docId.split(":"); ++ if ((split.length >= 2) && (split[1] != null)) return split[1]; ++ else return File.separator; ++ } ++ } + } +--- a/ui/shell_dialogs/select_file_dialog_android.cc ++++ b/ui/shell_dialogs/select_file_dialog_android.cc +@@ -135,8 +135,12 @@ void SelectFileDialogImpl::SelectFileImp + + bool accept_multiple_files = SelectFileDialog::SELECT_OPEN_MULTI_FILE == type; + ++ bool is_folder = false; ++ if (type == SelectFileDialog::SELECT_EXISTING_FOLDER) ++ is_folder = true; ++ + Java_SelectFileDialog_selectFile(env, java_object_, accept_types_java, +- accept_types.second, accept_multiple_files, ++ accept_types.second, accept_multiple_files, is_folder, + owning_window->GetJavaObject()); + } + diff --git a/patches/Extensions/base/fix-disabled-supervised-user.patch b/patches/Extensions/base/fix-disabled-supervised-user.patch new file mode 100644 index 0000000..f6682fe --- /dev/null +++ b/patches/Extensions/base/fix-disabled-supervised-user.patch @@ -0,0 +1,54 @@ +From: Wengling Chen +Date: Sat, 30 May 2020 18:25:38 -0400 +Subject: fix for enable_supervised_users=false + +--- + chrome/android/BUILD.gn | 1 + chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java | 14 ---------- + 2 files changed, 15 deletions(-) + +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -3191,7 +3191,6 @@ generate_jni("chrome_jni_headers") { + "java/src/org/chromium/chrome/browser/browsing_data/BrowsingDataCounterBridge.java", + "java/src/org/chromium/chrome/browser/browsing_data/UrlFilterBridge.java", + "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountFeedbackReporter.java", +- "java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java", + "java/src/org/chromium/chrome/browser/complex_tasks/TaskTabHelper.java", + "java/src/org/chromium/chrome/browser/component_updater/UpdateScheduler.java", + "java/src/org/chromium/chrome/browser/compositor/CompositorView.java", +--- a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java +@@ -60,32 +60,18 @@ public class ChildAccountService { + * @param callback the callback to be called when the status changes. + */ + public static void listenForStatusChange(Callback callback) { +- ChildAccountServiceJni.get().listenForChildStatusReceived(callback); + } + +- @CalledByNative + private static void reauthenticateChildAccount( + WindowAndroid windowAndroid, String accountName, final long nativeCallback) { + ThreadUtils.assertOnUiThread(); + + Activity activity = windowAndroid.getActivity().get(); + if (activity == null) { +- PostTask.postTask(UiThreadTaskTraits.DEFAULT, +- () +- -> ChildAccountServiceJni.get().onReauthenticationResult( +- nativeCallback, false)); + return; + } + + Account account = AccountUtils.createAccountFromName(accountName); +- AccountManagerFacadeProvider.getInstance().updateCredentials(account, activity, +- result +- -> ChildAccountServiceJni.get().onReauthenticationResult(nativeCallback, result)); + } + +- @NativeMethods +- interface Natives { +- void listenForChildStatusReceived(Callback callback); +- void onReauthenticationResult(long callbackPtr, boolean reauthSuccessful); +- } + } diff --git a/patches/Extensions/base/gn.patch b/patches/Extensions/base/gn.patch new file mode 100644 index 0000000..4a85d7c --- /dev/null +++ b/patches/Extensions/base/gn.patch @@ -0,0 +1,1522 @@ +From: Wengling Chen +Date: Sat, 30 May 2020 18:25:38 -0400 +Subject: gn fixes for enable_extensions=true + +--- + apps/BUILD.gn | 2 + build/config/locales.gni | 4 + chrome/BUILD.gn | 4 + chrome/android/BUILD.gn | 1 + chrome/browser/BUILD.gn | 58 ++---- + chrome/browser/apps/platform_apps/api/music_manager_private/BUILD.gn | 2 + chrome/browser/devtools/BUILD.gn | 14 - + chrome/browser/extensions/BUILD.gn | 10 - + chrome/browser/media/router/discovery/BUILD.gn | 4 + chrome/browser/nearby_sharing/BUILD.gn | 2 + chrome/browser/resources/BUILD.gn | 2 + chrome/browser/ui/BUILD.gn | 86 +--------- + chrome/browser/ui/views/BUILD.gn | 2 + chrome/browser/ui/webui/discards/BUILD.gn | 2 + chrome/browser/web_applications/BUILD.gn | 3 + chrome/browser/web_applications/components/BUILD.gn | 7 + chrome/browser/web_applications/extensions/BUILD.gn | 1 + chrome/chrome_paks.gni | 4 + chrome/common/BUILD.gn | 2 + chrome/common/extensions/api/api_sources.gni | 2 + chrome/common/importer/BUILD.gn | 2 + chrome/renderer/BUILD.gn | 2 + chrome/test/BUILD.gn | 1 + components/autofill/core/browser/BUILD.gn | 2 + components/bookmarks/browser/BUILD.gn | 2 + components/enterprise/BUILD.gn | 2 + components/guest_view/browser/BUILD.gn | 2 + components/guest_view/renderer/BUILD.gn | 2 + components/keep_alive_registry/BUILD.gn | 2 + components/media_router/browser/BUILD.gn | 2 + components/media_router/common/BUILD.gn | 2 + components/performance_manager/BUILD.gn | 2 + components/web_modal/BUILD.gn | 2 + components/zoom/BUILD.gn | 2 + content/browser/BUILD.gn | 4 + content/browser/devtools/BUILD.gn | 2 + content/public/browser/BUILD.gn | 2 + device/fido/BUILD.gn | 2 + extensions/BUILD.gn | 1 + extensions/browser/api/system_cpu/BUILD.gn | 2 + extensions/buildflags/buildflags.gni | 2 + media/mojo/mojom/BUILD.gn | 2 + services/device/public/cpp/hid/BUILD.gn | 1 + third_party/blink/public/mojom/BUILD.gn | 1 + ui/base/BUILD.gn | 20 -- + ui/gfx/BUILD.gn | 2 + ui/gfx/animation/BUILD.gn | 2 + ui/message_center/BUILD.gn | 4 + ui/views/BUILD.gn | 19 ++ + ui/webui/resources/BUILD.gn | 6 + ui/webui/resources/css/BUILD.gn | 2 + ui/webui/resources/html/BUILD.gn | 2 + ui/webui/resources/js/BUILD.gn | 2 + ui/webui/resources/js/cr/ui/BUILD.gn | 2 + 54 files changed, 113 insertions(+), 206 deletions(-) + +--- a/apps/BUILD.gn ++++ b/apps/BUILD.gn +@@ -7,7 +7,7 @@ import("//build/config/features.gni") + import("//build/config/ui.gni") + import("//extensions/buildflags/buildflags.gni") + +-assert(!is_android && !is_ios) ++# assert(!is_android && !is_ios) + assert(enable_extensions, + "Cannot depend on extensions because enable_extensions=false.") + +--- a/chrome/browser/media/router/discovery/BUILD.gn ++++ b/chrome/browser/media/router/discovery/BUILD.gn +@@ -2,8 +2,6 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + +-assert(!is_android) +- + static_library("discovery") { + inputs = [ "$root_gen_dir/chrome/grit/generated_resources.h" ] + deps = [ +@@ -75,7 +73,7 @@ static_library("discovery") { + sources += [ "discovery_network_list_wifi_linux.cc" ] + } + +- if (is_posix) { ++ if (is_posix && !is_android) { + sources += [ "discovery_network_list_posix.cc" ] + } + +--- a/ui/base/BUILD.gn ++++ b/ui/base/BUILD.gn +@@ -454,6 +454,11 @@ component("base") { + deps += [ "//third_party/re2" ] + } + ++ sources += [ ++ "dragdrop/os_exchange_data_provider_non_backed.cc", ++ "dragdrop/os_exchange_data_provider_non_backed.h", ++ ] ++ + if (!is_ios) { + # iOS does not use Chromium-specific code for event handling. + public_deps += [ +@@ -530,8 +535,6 @@ component("base") { + + if (is_chromeos || (use_aura && is_linux)) { + sources += [ +- "dragdrop/os_exchange_data_provider_non_backed.cc", +- "dragdrop/os_exchange_data_provider_non_backed.h", + ] + } + +@@ -563,14 +566,6 @@ component("base") { + if (!toolkit_views && !use_aura) { + sources -= [ + "dragdrop/drag_drop_types.h", +- "dragdrop/drop_target_event.cc", +- "dragdrop/drop_target_event.h", +- "dragdrop/os_exchange_data.cc", +- "dragdrop/os_exchange_data.h", +- "dragdrop/os_exchange_data_provider_factory.cc", +- "dragdrop/os_exchange_data_provider_factory.h", +- "nine_image_painter_factory.cc", +- "nine_image_painter_factory.h", + ] + } + +@@ -579,11 +574,6 @@ component("base") { + libs += [ "jnigraphics" ] + + sources -= [ +- "l10n/l10n_font_util.cc", +- "models/button_menu_item_model.cc", +- "pointer/touch_editing_controller.cc", +- "theme_provider.cc", +- "ui_base_types.cc", + ] + } + +--- a/chrome/browser/web_applications/BUILD.gn ++++ b/chrome/browser/web_applications/BUILD.gn +@@ -210,7 +210,6 @@ source_set("web_applications_unit_tests" + "//chrome/browser/web_applications/components", + "//chrome/browser/web_applications/preinstalled_web_apps", + "//chrome/common", +- "//chrome/test:test_support", + "//components/services/app_service/public/cpp:app_url_handling", + "//components/services/app_service/public/cpp:protocol_handling", + "//content/public/browser", +@@ -267,8 +266,6 @@ source_set("web_applications_browser_tes + "//chrome/browser/web_applications/components", + "//chrome/browser/web_applications/extensions", + "//chrome/browser/web_applications/preinstalled_web_apps", +- "//chrome/test:test_support", +- "//chrome/test:test_support_ui", + "//components/permissions:permissions", + "//components/services/app_service/public/cpp:app_update", + "//components/services/app_service/public/cpp:intents", +--- a/chrome/browser/web_applications/components/BUILD.gn ++++ b/chrome/browser/web_applications/components/BUILD.gn +@@ -2,6 +2,8 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + ++set_sources_assignment_filter([]) ++ + source_set("components") { + sources = [ + "app_icon_manager.cc", +@@ -62,6 +64,8 @@ source_set("components") { + "web_app_run_on_os_login.h", + "web_app_shortcut.cc", + "web_app_shortcut.h", ++ "web_app_shortcut_linux.cc", ++ "web_app_shortcut_linux.h", + "web_app_shortcuts_menu.cc", + "web_app_shortcuts_menu.h", + "web_app_tab_helper_base.cc", +@@ -208,7 +212,6 @@ source_set("unit_tests") { + "//chrome/browser/web_applications:web_applications", + "//chrome/browser/web_applications:web_applications_test_support", + "//chrome/browser/web_applications/extensions:extensions", +- "//chrome/test:test_support", + "//content/public/browser", + "//skia", + "//testing/gmock", +@@ -238,8 +241,6 @@ source_set("browser_tests") { + deps = [ + ":components", + "//chrome/browser/web_applications:web_applications_test_support", +- "//chrome/test:test_support", +- "//chrome/test:test_support_ui", + "//net:test_support", + ] + } +--- a/chrome/browser/web_applications/extensions/BUILD.gn ++++ b/chrome/browser/web_applications/extensions/BUILD.gn +@@ -72,7 +72,6 @@ source_set("unit_tests") { + "//chrome/browser/web_applications:web_applications_test_support", + "//chrome/browser/web_applications/components", + "//chrome/common", +- "//chrome/test:test_support", + "//components/crx_file:crx_file", + "//content/public/browser", + "//content/test:test_support", +--- a/chrome/browser/ui/views/BUILD.gn ++++ b/chrome/browser/ui/views/BUILD.gn +@@ -5,8 +5,6 @@ + import("//build/config/ui.gni") + import("//ui/views/features.gni") + +-assert(toolkit_views) +- + component("views") { + output_name = "browser_ui_views" + sources = [ +--- a/components/guest_view/browser/BUILD.gn ++++ b/components/guest_view/browser/BUILD.gn +@@ -6,7 +6,7 @@ + # assert to prevent the accidental building of GuestViews on mobile + # platforms. If you're now using GuestViews on mobile, go ahead and + # remove this assert. +-assert(!is_android && !is_ios) ++# assert(!is_android && !is_ios) + + static_library("browser") { + output_name = "guest_view_browser" +--- a/components/guest_view/renderer/BUILD.gn ++++ b/components/guest_view/renderer/BUILD.gn +@@ -6,7 +6,7 @@ + # assert to prevent the accidental building of GuestViews on mobile + # platforms. If you're now using GuestViews on mobile, go ahead and + # remove this assert. +-assert(!is_android && !is_ios) ++# assert(!is_android && !is_ios) + + static_library("renderer") { + sources = [ +--- a/components/keep_alive_registry/BUILD.gn ++++ b/components/keep_alive_registry/BUILD.gn +@@ -2,7 +2,7 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + +-assert(!is_android) ++# assert(!is_android) + + source_set("keep_alive_registry") { + sources = [ +--- a/components/web_modal/BUILD.gn ++++ b/components/web_modal/BUILD.gn +@@ -2,7 +2,7 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + +-assert(!is_android && !is_ios) ++# assert(!is_android && !is_ios) + + component("web_modal") { + sources = [ +--- a/components/zoom/BUILD.gn ++++ b/components/zoom/BUILD.gn +@@ -2,7 +2,7 @@ + # Use of this source code is governed by a BSD-style license that can be + # found in the LICENSE file. + +-assert(!is_android && !is_ios, "Desktop zoom is not used on mobile platforms.") ++# assert(!is_android && !is_ios, "Desktop zoom is not used on mobile platforms.") + + static_library("zoom") { + sources = [ +--- a/extensions/buildflags/buildflags.gni ++++ b/extensions/buildflags/buildflags.gni +@@ -3,7 +3,7 @@ + # found in the LICENSE file. + + declare_args() { +- enable_extensions = !is_android && !is_ios && !is_fuchsia ++ enable_extensions = !is_ios && !is_fuchsia + + # Enables Wi-Fi Display functionality + # WARNING: This enables MPEG Transport Stream (MPEG-TS) encoding! +--- a/services/device/public/cpp/hid/BUILD.gn ++++ b/services/device/public/cpp/hid/BUILD.gn +@@ -8,7 +8,6 @@ import("//build/config/features.gni") + source_set("hid") { + # HID is not implemented on Android and we want to be particularly careful + # about not bloating binary size by accidentially including it. +- assert(!is_android) + + sources = [ + "hid_collection.cc", +--- a/ui/views/BUILD.gn ++++ b/ui/views/BUILD.gn +@@ -11,7 +11,7 @@ import("//testing/test.gni") + import("//ui/base/ui_features.gni") + import("//ui/views/features.gni") + +-assert(toolkit_views) ++# assert(toolkit_views) + + config("flags") { + defines = [ "TOOLKIT_VIEWS=1" ] +@@ -145,6 +145,7 @@ component("views") { + "controls/menu/new_badge.h", + "controls/menu/submenu_view.h", + "controls/message_box_view.h", ++ "controls/native/native_view_host_aura.h", + "controls/native/native_view_host.h", + "controls/native/native_view_host_mac.h", + "controls/native/native_view_host_wrapper.h", +@@ -180,6 +181,7 @@ component("views") { + "debug_utils.h", + "drag_controller.h", + "drag_utils.h", ++ "event_monitor_aura.h", + "event_monitor.h", + "focus/external_focus_tracker.h", + "focus/focus_manager.h", +@@ -247,10 +249,12 @@ component("views") { + "widget/any_widget_observer_singleton.h", + "widget/drop_helper.h", + "widget/native_widget.h", ++ "widget/native_widget_aura.h", + "widget/native_widget_delegate.h", + "widget/native_widget_private.h", + "widget/root_view.h", + "widget/root_view_targeter.h", ++ "widget/tooltip_manager_aura.h", + "widget/tooltip_manager.h", + "widget/unique_widget_ptr.h", + "widget/widget.h", +@@ -344,6 +348,7 @@ component("views") { + "controls/label.cc", + "controls/link.cc", + "controls/menu/menu_config.cc", ++ "controls/menu/menu_config_linux.cc", + "controls/menu/menu_controller.cc", + "controls/menu/menu_delegate.cc", + "controls/menu/menu_host.cc", +@@ -351,6 +356,8 @@ component("views") { + "controls/menu/menu_image_util.cc", + "controls/menu/menu_item_view.cc", + "controls/menu/menu_model_adapter.cc", ++ "controls/menu/menu_pre_target_handler_aura.cc", ++ "controls/menu/menu_pre_target_handler_aura.h", + "controls/menu/menu_runner.cc", + "controls/menu/menu_runner_impl.cc", + "controls/menu/menu_runner_impl_adapter.cc", +@@ -359,6 +366,7 @@ component("views") { + "controls/menu/new_badge.cc", + "controls/menu/submenu_view.cc", + "controls/message_box_view.cc", ++ "controls/native/native_view_host_aura.cc", + "controls/native/native_view_host.cc", + "controls/prefix_selector.cc", + "controls/progress_bar.cc", +@@ -387,6 +395,8 @@ component("views") { + "controls/views_text_services_context_menu_base.h", + "debug_utils.cc", + "drag_utils.cc", ++ "drag_utils_aura.cc", ++ "event_monitor_aura.cc", + "focus/external_focus_tracker.cc", + "focus/focus_manager.cc", + "focus/focus_manager_factory.cc", +@@ -412,9 +422,11 @@ component("views") { + "metadata/metadata_types.cc", + "metadata/type_conversion.cc", + "metadata/view_factory_internal.cc", ++ "metrics_aura.cc", + "metrics.cc", + "mouse_watcher.cc", + "mouse_watcher_view_host.cc", ++ "native_cursor_aura.cc", + "paint_info.cc", + "painter.cc", + "rect_based_targeting_utils.cc", +@@ -424,6 +436,7 @@ component("views") { + "style/platform_style.cc", + "style/typography.cc", + "style/typography_provider.cc", ++ "touchui/touch_selection_controller_impl.cc", + "view.cc", + "view_class_properties.cc", + "view_constants.cc", +@@ -435,12 +448,15 @@ component("views") { + "views_delegate.cc", + "views_features.cc", + "views_switches.cc", ++ "views_touch_selection_controller_factory_aura.cc", + "widget/any_widget_observer.cc", + "widget/any_widget_observer_singleton.cc", + "widget/drop_helper.cc", ++ "widget/native_widget_aura.cc", + "widget/native_widget_private.cc", + "widget/root_view.cc", + "widget/root_view_targeter.cc", ++ "widget/tooltip_manager_aura.cc", + "widget/tooltip_manager.cc", + "widget/unique_widget_ptr.cc", + "widget/widget.cc", +@@ -490,6 +506,7 @@ component("views") { + "//skia", + "//third_party/icu", + "//ui/accessibility", ++ "//ui/android", + "//ui/base/clipboard", + "//ui/base/dragdrop/mojom:mojom_shared", + "//ui/display", +--- a/chrome/test/BUILD.gn ++++ b/chrome/test/BUILD.gn +@@ -5450,7 +5450,6 @@ test("unit_tests") { + "//components/enterprise:test_support", + "//components/safe_browsing:buildflags", + "//components/services/unzip:in_process", +- "//extensions:extensions_resources", + "//extensions/browser:test_support", + "//extensions/browser:value_store_test_support", + "//extensions/common", +--- a/extensions/BUILD.gn ++++ b/extensions/BUILD.gn +@@ -225,7 +225,6 @@ test("extensions_unittests") { + ] + + deps = [ +- ":extensions_resources", + ":shell_and_test_pak", + ":test_support", + "//base/test:test_support", +--- a/chrome/BUILD.gn ++++ b/chrome/BUILD.gn +@@ -1356,7 +1356,7 @@ group("extra_resources") { + "//components/autofill/core/browser:autofill_address_rewriter_resources", + ] + +- if (!is_android) { ++ if (enable_extensions) { + public_deps += [ + "//chrome/browser/resources:component_extension_resources", + "//chrome/browser/resources:dev_ui_paks", +@@ -1391,7 +1391,7 @@ group("extra_resources") { + public_deps += [ "//chrome/browser/resources/webui_js_exception:webui_js_exception_resources" ] + } + +- if (!is_android && !is_chromeos) { ++ if (is_android && !is_chromeos) { + public_deps += [ + "//chrome/browser/resources/signin/profile_picker:profile_picker_resources", + "//chrome/browser/resources/welcome:welcome_resources", +--- a/third_party/blink/public/mojom/BUILD.gn ++++ b/third_party/blink/public/mojom/BUILD.gn +@@ -248,7 +248,6 @@ mojom("mojom_platform") { + "//services/network/public/mojom:cookies_mojom", + "//ui/latency/mojom", + ] +- } else { + sources += [ + "direct_sockets/direct_sockets.mojom", + "serial/serial.mojom", +--- a/chrome/browser/BUILD.gn ++++ b/chrome/browser/BUILD.gn +@@ -38,6 +38,8 @@ import("//third_party/widevine/cdm/widev + import("//tools/grit/grit_rule.gni") + import("//ui/base/ui_features.gni") + ++set_sources_assignment_filter([]) ++ + # //build/config/android/rules.gni imports //tools/grit/grit_rule.gni, which + # produces a conflict for the "grit" template so we have to only include one. + if (is_android) { +@@ -438,6 +440,7 @@ static_library("browser") { + "download/download_ui_controller.h", + "download/download_ui_model.cc", + "download/download_ui_model.h", ++ "download/drag_download_item_aura.cc", + "download/drag_download_item.h", + "download/mixed_content_download_blocking.cc", + "download/mixed_content_download_blocking.h", +@@ -2976,7 +2979,6 @@ static_library("browser") { + "download/android/service/download_task_scheduler.cc", + "download/android/service/download_task_scheduler.h", + "download/android/string_utils.cc", +- "download/download_crx_util_android.cc", + "engagement/site_engagement_service_android.cc", + "engagement/site_engagement_service_android.h", + "enterprise/util/android_enterprise_info.cc", +@@ -3328,7 +3330,6 @@ static_library("browser") { + ] + deps += [ "//chrome/android/modules/dev_ui/provider:native" ] + } +- } else { + #!is_android + sources += [ + "accessibility/caption_controller.cc", +@@ -3550,10 +3551,6 @@ static_library("browser") { + "importer/importer_uma.h", + "importer/in_process_importer_bridge.cc", + "importer/in_process_importer_bridge.h", +- "importer/profile_writer.cc", +- "importer/profile_writer.h", +- "intranet_redirect_detector.cc", +- "intranet_redirect_detector.h", + "lifetime/browser_close_manager.cc", + "lifetime/browser_close_manager.h", + "lifetime/termination_notification.cc", +@@ -3598,11 +3595,6 @@ static_library("browser") { + "media/webrtc/desktop_media_picker_factory_impl.h", + "media/webrtc/display_media_access_handler.cc", + "media/webrtc/display_media_access_handler.h", +- "media/webrtc/media_authorization_wrapper_mac.h", +- "media/webrtc/system_media_capture_permissions_mac.h", +- "media/webrtc/system_media_capture_permissions_mac.mm", +- "media/webrtc/system_media_capture_permissions_stats_mac.h", +- "media/webrtc/system_media_capture_permissions_stats_mac.mm", + "media/webrtc/tab_desktop_media_list.cc", + "media/webrtc/tab_desktop_media_list.h", + "media_galleries/fileapi/av_scanning_file_validator.cc", +@@ -3660,7 +3652,6 @@ static_library("browser") { + "metrics/desktop_session_duration/touch_mode_stats_tracker.h", + "metrics/first_web_contents_profiler.cc", + "metrics/first_web_contents_profiler.h", +- "metrics/incognito_observer_desktop.cc", + "metrics/tab_stats_data_store.cc", + "metrics/tab_stats_data_store.h", + "metrics/tab_stats_tracker.cc", +@@ -3870,16 +3861,6 @@ static_library("browser") { + "sharesheet/sharesheet_service_delegate.h", + "sharesheet/sharesheet_service_factory.cc", + "sharesheet/sharesheet_service_factory.h", +- "sharing/click_to_call/click_to_call_context_menu_observer.cc", +- "sharing/click_to_call/click_to_call_context_menu_observer.h", +- "sharing/click_to_call/click_to_call_metrics.cc", +- "sharing/click_to_call/click_to_call_metrics.h", +- "sharing/click_to_call/click_to_call_ui_controller.cc", +- "sharing/click_to_call/click_to_call_ui_controller.h", +- "sharing/click_to_call/click_to_call_utils.cc", +- "sharing/click_to_call/click_to_call_utils.h", +- "sharing/click_to_call/phone_number_regex.cc", +- "sharing/click_to_call/phone_number_regex.h", + "sharing/shared_clipboard/remote_copy_message_handler.cc", + "sharing/shared_clipboard/remote_copy_message_handler.h", + "sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc", +@@ -4033,6 +4014,9 @@ static_library("browser") { + "upgrade_detector/build_state.cc", + "upgrade_detector/build_state.h", + "upgrade_detector/build_state_observer.h", ++ "upgrade_detector/directory_monitor.cc", ++ "upgrade_detector/directory_monitor.h", ++ "upgrade_detector/get_installed_version_linux.cc", + "upgrade_detector/upgrade_detector.cc", + "upgrade_detector/upgrade_detector.h", + "upgrade_detector/upgrade_observer.h", +@@ -4055,6 +4039,10 @@ static_library("browser") { + "webauthn/observable_authenticator_list.cc", + "webauthn/observable_authenticator_list.h", + ] ++ sources -= [ ++ "banners/app_banner_manager_desktop.cc", ++ "banners/app_banner_manager_desktop.h", ++ ] + deps += [ + ":theme_properties", + "//base/util/memory_pressure", +@@ -4068,7 +4056,6 @@ static_library("browser") { + "//chrome/browser/profile_resetter:profile_reset_report_proto", + "//chrome/browser/resource_coordinator:intervention_policy_database_proto", + "//chrome/browser/resource_coordinator:tab_metrics_event_proto", +- "//chrome/browser/resource_coordinator/tab_ranker", + "//chrome/browser/resources:component_extension_resources", + "//chrome/browser/search:generated", + "//chrome/browser/ui/color:color_headers", +@@ -4135,7 +4122,6 @@ static_library("browser") { + "chrome_browser_main_posix.cc", + "chrome_browser_main_posix.h", + "importer/firefox_profile_lock_posix.cc", +- "process_singleton_posix.cc", + "task_manager/sampling/shared_sampler_posix.cc", + ] + +@@ -4917,16 +4903,13 @@ static_library("browser") { + } + } + +- if (is_linux || is_chromeos) { + sources += [ +- "chrome_browser_main_linux.cc", +- "chrome_browser_main_linux.h", +- "first_run/first_run_internal_linux.cc", +- "memory_details_linux.cc", + "obsolete_system/obsolete_system_linux.cc", + "policy/browser_dm_token_storage_linux.cc", + "policy/browser_dm_token_storage_linux.h", + ] ++ ++ if (is_linux || is_chromeos) { + if (use_aura) { + deps += [ "//third_party/fontconfig" ] + if (use_dbus) { +@@ -5083,7 +5066,7 @@ static_library("browser") { + ] + } + +- if (!is_android && !is_chromeos) { ++ if (is_android && !is_chromeos) { + sources += [ + "device_identity/device_oauth2_token_store_desktop.cc", + "device_identity/device_oauth2_token_store_desktop.h", +@@ -5110,12 +5093,8 @@ static_library("browser") { + "password_manager/multi_profile_credentials_filter.cc", + "password_manager/multi_profile_credentials_filter.h", + "platform_util.cc", +- "policy/chrome_browser_cloud_management_controller_desktop.cc", +- "policy/chrome_browser_cloud_management_controller_desktop.h", + "policy/chrome_browser_cloud_management_register_watcher.cc", + "policy/chrome_browser_cloud_management_register_watcher.h", +- "policy/cloud/user_policy_signin_service.cc", +- "policy/cloud/user_policy_signin_service.h", + "policy/cloud/user_policy_signin_service_internal.h", + "profiles/avatar_menu.cc", + "profiles/avatar_menu.h", +@@ -5150,7 +5129,6 @@ static_library("browser") { + "upgrade_detector/upgrade_detector_impl.cc", + "upgrade_detector/upgrade_detector_impl.h", + ] +- } else { # is_android || is_chromeos + sources += [ + "installable/digital_asset_links/digital_asset_links_handler.cc", + "installable/digital_asset_links/digital_asset_links_handler.h", +@@ -5179,7 +5157,7 @@ static_library("browser") { + ] + } + +- if (is_win || is_mac || is_linux || is_chromeos) { ++ if (is_win || is_mac || is_linux || is_chromeos || is_android) { + sources += [ + "crash_upload_list/crash_upload_list_crashpad.cc", + "crash_upload_list/crash_upload_list_crashpad.h", +@@ -5282,7 +5260,7 @@ static_library("browser") { + sources += [ "background/background_mode_manager_aura.cc" ] + } + } +- if (enable_background_contents) { ++ if (true) { + sources += [ + "background/background_contents_service.cc", + "background/background_contents_service.h", +@@ -5333,7 +5311,7 @@ static_library("browser") { + sources += [ "printing/printer_manager_dialog_mac.mm" ] + } + if (is_linux || is_chromeos) { +- sources += [ "printing/printer_manager_dialog_linux.cc" ] ++ sources += [ "" ] + } + if (is_win || is_mac || is_linux || is_chromeos) { + sources += [ +@@ -6040,7 +6018,7 @@ static_library("browser") { + } + } + +- if (enable_session_service) { ++ if (true) { + sources += [ + "sessions/session_restore.cc", + "sessions/session_restore.h", +@@ -6407,7 +6385,7 @@ grit("resources") { + } + } + +- if (is_win || is_mac || is_linux || is_chromeos) { ++ if (is_win || is_mac || is_linux || is_chromeos || is_android) { + deps += [ + "//chrome/browser/resources/discards:discards_resources_gen", + "//chrome/browser/resources/gaia_auth_host:modulize", +--- a/chrome/browser/ui/BUILD.gn ++++ b/chrome/browser/ui/BUILD.gn +@@ -583,7 +583,7 @@ static_library("ui") { + allow_circular_includes_from += + [ "//chrome/browser/ui/webui/bluetooth_internals" ] + +- if (is_win || is_mac || is_linux || is_chromeos) { ++ if (is_win || is_mac || is_linux || is_chromeos || is_android) { + deps += [ "//chrome/browser/ui/webui/discards:mojo_bindings" ] + } + +@@ -818,8 +818,6 @@ static_library("ui") { + "//services/device/public/mojom:usb", + "//ui/android", + ] +- } else { +- # !is_android + sources += [ + "app_icon_loader.cc", + "app_icon_loader.h", +@@ -830,6 +828,8 @@ static_library("ui") { + "apps/chrome_app_window_client.h", + "apps/directory_access_confirmation_dialog.cc", + "apps/directory_access_confirmation_dialog.h", ++ "aura/native_window_tracker_aura.cc", ++ "aura/native_window_tracker_aura.h", + "blocked_content/framebust_block_tab_helper.cc", + "blocked_content/framebust_block_tab_helper.h", + "blocked_content/popunder_preventer.cc", +@@ -884,7 +884,6 @@ static_library("ui") { + "browser_location_bar_model_delegate.h", + "browser_navigator.cc", + "browser_navigator.h", +- "browser_otr_state.cc", + "browser_otr_state.h", + "browser_tab_restorer.cc", + "browser_tab_strip_model_delegate.cc", +@@ -999,12 +998,6 @@ static_library("ui") { + "global_media_controls/presentation_request_notification_item.h", + "global_media_controls/presentation_request_notification_provider.cc", + "global_media_controls/presentation_request_notification_provider.h", +- "hats/hats_helper.cc", +- "hats/hats_helper.h", +- "hats/hats_service.cc", +- "hats/hats_service.h", +- "hats/hats_service_factory.cc", +- "hats/hats_service_factory.h", + "hats/hats_survey_status_checker.cc", + "hats/hats_survey_status_checker.h", + "hid/hid_chooser.cc", +@@ -1147,8 +1140,6 @@ static_library("ui") { + "singleton_tabs.h", + "startup/automation_infobar_delegate.cc", + "startup/automation_infobar_delegate.h", +- "startup/google_api_keys_infobar_delegate.cc", +- "startup/google_api_keys_infobar_delegate.h", + "startup/launch_mode_recorder.cc", + "startup/launch_mode_recorder.h", + "startup/obsolete_system_infobar_delegate.cc", +@@ -1227,10 +1218,6 @@ static_library("ui") { + "tabs/tab_types.h", + "tabs/tab_utils.cc", + "tabs/tab_utils.h", +- "task_manager/task_manager_columns.cc", +- "task_manager/task_manager_columns.h", +- "task_manager/task_manager_table_model.cc", +- "task_manager/task_manager_table_model.h", + "thumbnails/thumbnail_capture_driver.cc", + "thumbnails/thumbnail_capture_driver.h", + "thumbnails/thumbnail_image.cc", +@@ -1416,8 +1403,6 @@ static_library("ui") { + "webui/settings/extension_control_handler.h", + "webui/settings/font_handler.cc", + "webui/settings/font_handler.h", +- "webui/settings/hats_handler.cc", +- "webui/settings/hats_handler.h", + "webui/settings/import_data_handler.cc", + "webui/settings/import_data_handler.h", + "webui/settings/languages_handler.cc", +@@ -1496,6 +1481,7 @@ static_library("ui") { + "webui/util/image_util.h", + "webui/web_footer_experiment_ui.cc", + "webui/web_footer_experiment_ui.h", ++ "window_sizer/window_sizer_aura.cc", + "window_sizer/window_sizer.cc", + "window_sizer/window_sizer.h", + "zoom/chrome_zoom_level_otr_delegate.cc", +@@ -1513,7 +1499,6 @@ static_library("ui") { + "//chrome/browser/profile_resetter:profile_reset_report_proto", + "//chrome/browser/promo_browser_command:mojo_bindings", + "//chrome/browser/resource_coordinator:tab_metrics_event_proto", +- "//chrome/browser/resource_coordinator/tab_ranker", + "//chrome/browser/safe_browsing:advanced_protection", + "//chrome/browser/search/task_module:mojo_bindings", + "//chrome/browser/ui/color:color_headers", +@@ -2736,7 +2721,7 @@ static_library("ui") { + ] + } + +- if (is_win || is_mac || is_linux || is_chromeos) { ++ if (is_win || is_mac || is_linux || is_chromeos || is_android) { + sources += [ + "autofill/payments/virtual_card_selection_dialog_controller.h", + "autofill/payments/virtual_card_selection_dialog_controller_impl.cc", +@@ -2771,7 +2756,6 @@ static_library("ui") { + "views/autofill/payments/webauthn_dialog_view_impl.h", + "views/close_bubble_on_tab_activation_helper.cc", + "views/close_bubble_on_tab_activation_helper.h", +- "views/external_protocol_dialog.cc", + "views/external_protocol_dialog.h", + "views/hats/hats_bubble_view.cc", + "views/hats/hats_bubble_view.h", +@@ -2787,10 +2771,6 @@ static_library("ui") { + "views/profiles/profile_menu_view_base.h", + "views/profiles/signin_view_controller_delegate_views.cc", + "views/profiles/signin_view_controller_delegate_views.h", +- "webui/discards/discards_ui.cc", +- "webui/discards/discards_ui.h", +- "webui/discards/graph_dump_impl.cc", +- "webui/discards/graph_dump_impl.h", + "webui/discards/site_data_provider_impl.cc", + "webui/discards/site_data_provider_impl.h", + "webui/signin/inline_login_handler.cc", +@@ -2807,7 +2787,7 @@ static_library("ui") { + deps += [ "//ui/webui" ] + } + +- if (is_win || is_mac || is_linux) { ++ if (is_win || is_mac || is_linux || is_android) { + sources += [ + "bookmarks/bookmark_bubble_sign_in_delegate.cc", + "bookmarks/bookmark_bubble_sign_in_delegate.h", +@@ -2824,8 +2804,6 @@ static_library("ui") { + "sync/one_click_signin_links_delegate_impl.h", + "user_manager.cc", + "user_manager.h", +- "views/profiles/badged_profile_photo.cc", +- "views/profiles/badged_profile_photo.h", + "views/profiles/profile_picker_view.cc", + "views/profiles/profile_picker_view.h", + "views/profiles/profile_picker_view_sync_delegate.cc", +@@ -3225,7 +3203,7 @@ static_library("ui") { + # to fail on this variant. Since this target is only referenced (but not + # compiled) on this variant, it's okay to add this "incorrect" dependency + # to Cast Linux builds so that `gn check` passes. +- if (toolkit_views || (is_chromecast && (is_linux || is_chromeos))) { ++ if (toolkit_views || (is_chromecast && (is_linux || is_chromeos)) || is_android) { + public_deps += [ + "//ui/views", + "//ui/views/controls/webview", +@@ -3233,14 +3211,11 @@ static_library("ui") { + } + } + +- if (is_linux) { ++ if (is_linux || is_android) { + sources += [ + "views/apps/chrome_app_window_client_views_linux.cc", + "views/first_run_dialog.cc", + "views/first_run_dialog.h", +- "views/frame/browser_desktop_window_tree_host.h", +- "views/frame/desktop_browser_frame_aura_linux.cc", +- "views/frame/desktop_browser_frame_aura_linux.h", + "views/status_icons/status_icon_button_linux.cc", + "views/status_icons/status_icon_button_linux.h", + "views/status_icons/status_icon_linux_wrapper.cc", +@@ -3250,10 +3225,6 @@ static_library("ui") { + "webui/settings_utils_linux.cc", + ] + deps += [ +- "//ui/base:wm_role_names", +- "//ui/base/ime", +- "//ui/events:dom_keycode_converter", +- "//ui/platform_window", + ] + + if (use_dbus) { +@@ -3327,7 +3298,7 @@ static_library("ui") { + } + } + +- if (toolkit_views) { ++ if (true) { + sources += [ + "autofill/address_profiles/save_address_profile_bubble_controller.cc", + "autofill/address_profiles/save_address_profile_bubble_controller.h", +@@ -3366,6 +3337,7 @@ static_library("ui") { + # This test header is included because it contains forward declarations + # needed for "friend" statements for use in tests. + "translate/translate_bubble_test_utils.h", ++ "views/accelerator_utils_aura.cc", + "views/accessibility/caption_bubble.cc", + "views/accessibility/caption_bubble.h", + "views/accessibility/caption_bubble_controller_views.cc", +@@ -3406,12 +3378,8 @@ static_library("ui") { + "views/autofill/autofill_bubble_handler_impl.h", + "views/autofill/autofill_popup_base_view.cc", + "views/autofill/autofill_popup_base_view.h", +- "views/autofill/autofill_popup_view_native_views.cc", +- "views/autofill/autofill_popup_view_native_views.h", + "views/autofill/autofill_popup_view_utils.cc", + "views/autofill/autofill_popup_view_utils.h", +- "views/autofill/payments/card_unmask_prompt_views.cc", +- "views/autofill/payments/card_unmask_prompt_views.h", + "views/autofill/payments/dialog_view_ids.h", + "views/autofill/payments/local_card_migration_bubble_views.cc", + "views/autofill/payments/local_card_migration_bubble_views.h", +@@ -3470,8 +3438,6 @@ static_library("ui") { + "views/bulleted_label_list_view.h", + "views/certificate_selector.cc", + "views/certificate_selector.h", +- "views/chrome_browser_main_extra_parts_views.cc", +- "views/chrome_browser_main_extra_parts_views.h", + "views/chrome_constrained_window_views_client.cc", + "views/chrome_constrained_window_views_client.h", + "views/chrome_layout_provider.cc", +@@ -3522,6 +3488,7 @@ static_library("ui") { + "views/download/download_shelf_view.cc", + "views/download/download_shelf_view.h", + "views/download/download_started_animation_views.cc", ++ "views/dropdown_bar_host_aura.cc", + "views/dropdown_bar_host.cc", + "views/dropdown_bar_host.h", + "views/dropdown_bar_host_delegate.h", +@@ -3562,8 +3529,6 @@ static_library("ui") { + "views/find_bar_view.h", + "views/flying_indicator.cc", + "views/flying_indicator.h", +- "views/folder_upload_confirmation_view.cc", +- "views/folder_upload_confirmation_view.h", + "views/frame/app_menu_button.cc", + "views/frame/app_menu_button.h", + "views/frame/app_menu_button_observer.h", +@@ -3571,6 +3536,7 @@ static_library("ui") { + "views/frame/browser_frame.h", + "views/frame/browser_non_client_frame_view.cc", + "views/frame/browser_non_client_frame_view.h", ++ "views/frame/browser_non_client_frame_view_factory_views.cc", + "views/frame/browser_root_view.cc", + "views/frame/browser_root_view.h", + "views/frame/browser_view.cc", +@@ -3583,12 +3549,15 @@ static_library("ui") { + "views/frame/contents_layout_manager.h", + "views/frame/contents_web_view.cc", + "views/frame/contents_web_view.h", ++ "views/frame/desktop_browser_frame_aura.cc", ++ "views/frame/desktop_browser_frame_aura.h", + "views/frame/immersive_mode_controller.cc", + "views/frame/immersive_mode_controller.h", + "views/frame/immersive_mode_controller_factory_views.cc", + "views/frame/immersive_mode_controller_stub.cc", + "views/frame/immersive_mode_controller_stub.h", + "views/frame/native_browser_frame.h", ++ "views/frame/native_browser_frame_factory_aurax11.cc", + "views/frame/native_browser_frame_factory.cc", + "views/frame/native_browser_frame_factory.h", + "views/frame/system_menu_model_builder.cc", +@@ -3644,8 +3613,6 @@ static_library("ui") { + "views/importer/import_lock_dialog_view.h", + "views/infobars/alternate_nav_infobar_view.cc", + "views/infobars/alternate_nav_infobar_view.h", +- "views/infobars/confirm_infobar.cc", +- "views/infobars/confirm_infobar.h", + "views/infobars/infobar_container_view.cc", + "views/infobars/infobar_container_view.h", + "views/infobars/infobar_view.cc", +@@ -3709,12 +3676,8 @@ static_library("ui") { + "views/media_router/cast_dialog_view.h", + "views/media_router/cast_toolbar_button.cc", + "views/media_router/cast_toolbar_button.h", +- "views/media_router/cloud_services_dialog_view.cc", +- "views/media_router/cloud_services_dialog_view.h", + "views/media_router/media_remoting_dialog_view.cc", + "views/media_router/media_remoting_dialog_view.h", +- "views/media_router/media_router_dialog_controller_views.cc", +- "views/media_router/media_router_dialog_controller_views.h", + "views/media_router/presentation_receiver_window_factory.cc", + "views/media_router/presentation_receiver_window_frame.cc", + "views/media_router/presentation_receiver_window_frame.h", +@@ -3722,14 +3685,8 @@ static_library("ui") { + "views/media_router/presentation_receiver_window_view.h", + "views/media_router/web_contents_display_observer_view.cc", + "views/media_router/web_contents_display_observer_view.h", +- "views/message_box_dialog.cc", +- "views/message_box_dialog.h", + "views/native_file_system/native_file_system_access_icon_view.cc", + "views/native_file_system/native_file_system_access_icon_view.h", +- "views/native_file_system/native_file_system_permission_view.cc", +- "views/native_file_system/native_file_system_permission_view.h", +- "views/native_file_system/native_file_system_restricted_directory_dialog_view.cc", +- "views/native_file_system/native_file_system_restricted_directory_dialog_view.h", + "views/native_file_system/native_file_system_ui_helpers.cc", + "views/native_file_system/native_file_system_ui_helpers.h", + "views/native_file_system/native_file_system_usage_bubble_view.cc", +@@ -3762,8 +3719,6 @@ static_library("ui") { + "views/overlay/back_to_tab_image_button.h", + "views/overlay/close_image_button.cc", + "views/overlay/close_image_button.h", +- "views/overlay/overlay_window_views.cc", +- "views/overlay/overlay_window_views.h", + "views/overlay/playback_image_button.cc", + "views/overlay/playback_image_button.h", + "views/overlay/resize_handle_button.cc", +@@ -3800,8 +3755,6 @@ static_library("ui") { + "views/page_info/permission_selector_row.cc", + "views/page_info/permission_selector_row.h", + "views/page_info/permission_selector_row_observer.h", +- "views/page_info/safety_tip_page_info_bubble_view.cc", +- "views/page_info/safety_tip_page_info_bubble_view.h", + "views/passwords/account_chooser_dialog_view.cc", + "views/passwords/account_chooser_dialog_view.h", + "views/passwords/auto_signin_first_run_dialog_view.cc", +@@ -3820,8 +3773,6 @@ static_library("ui") { + "views/passwords/password_bubble_view_base.h", + "views/passwords/password_generation_confirmation_view.cc", + "views/passwords/password_generation_confirmation_view.h", +- "views/passwords/password_generation_popup_view_views.cc", +- "views/passwords/password_generation_popup_view_views.h", + "views/passwords/password_items_view.cc", + "views/passwords/password_items_view.h", + "views/passwords/password_save_unsynced_credentials_locally_view.cc", +@@ -3883,8 +3834,6 @@ static_library("ui") { + "views/permission_bubble/chooser_bubble_ui.cc", + "views/permission_bubble/permission_prompt_bubble_view.cc", + "views/permission_bubble/permission_prompt_bubble_view.h", +- "views/permission_bubble/permission_prompt_impl.cc", +- "views/permission_bubble/permission_prompt_impl.h", + "views/permission_bubble/permission_prompt_style.h", + "views/profiles/avatar_toolbar_button.cc", + "views/profiles/avatar_toolbar_button.h", +@@ -3928,8 +3877,6 @@ static_library("ui") { + "views/sharing/sharing_icon_view.h", + "views/side_panel.cc", + "views/side_panel.h", +- "views/ssl_client_certificate_selector.cc", +- "views/ssl_client_certificate_selector.h", + "views/status_bubble_views.cc", + "views/status_bubble_views.h", + "views/storage/storage_pressure_bubble_view.cc", +@@ -4249,9 +4196,6 @@ static_library("ui") { + "views/relaunch_notification/relaunch_recommended_timer.h", + "views/relaunch_notification/relaunch_required_dialog_view.cc", + "views/relaunch_notification/relaunch_required_dialog_view.h", +- "views/screen_capture_notification_ui_views.cc", +- "views/sync/dice_bubble_sync_promo_view.cc", +- "views/sync/dice_bubble_sync_promo_view.h", + "views/sync/dice_signin_button_view.cc", + "views/sync/dice_signin_button_view.h", + ] +--- a/content/public/browser/BUILD.gn ++++ b/content/public/browser/BUILD.gn +@@ -516,7 +516,7 @@ source_set("browser_sources") { + sources += [ "zygote_host/zygote_host_linux.h" ] + } + +- if (!is_android) { ++ if (is_android) { + sources += [ + "authenticator_request_client_delegate.cc", + "authenticator_request_client_delegate.h", +--- a/content/browser/BUILD.gn ++++ b/content/browser/BUILD.gn +@@ -2182,7 +2182,7 @@ source_set("browser") { + ] + } + +- if (!is_fuchsia && !is_android) { ++ if (!is_fuchsia && is_android) { + deps += [ "//content/browser/devtools:devtools_resources" ] + } + +@@ -2579,7 +2579,7 @@ source_set("browser") { + } + defines += [ "APPCACHE_USE_SIMPLE_CACHE" ] + libs += [ "jnigraphics" ] +- } else { ++ + # Not Android. + sources += [ + # The WebAuthn devtools protocol API is not supported in Android yet. +--- a/chrome/renderer/BUILD.gn ++++ b/chrome/renderer/BUILD.gn +@@ -394,6 +394,8 @@ static_library("renderer") { + "chromeos_merge_session_loader_throttle.cc", + "chromeos_merge_session_loader_throttle.h", + ] ++ ++ deps += [ "//chrome/common/search:generate_chrome_colors_info" ] + } + + if (is_chromeos) { +--- a/chrome/common/BUILD.gn ++++ b/chrome/common/BUILD.gn +@@ -402,7 +402,6 @@ static_library("common") { + "media/chrome_media_drm_bridge_client.cc", + "media/chrome_media_drm_bridge_client.h", + ] +- } else { + # Non-Android. + public_deps += [ "//chrome/common/importer" ] + } +@@ -718,7 +717,6 @@ mojom("mojo_bindings") { + + if (is_android) { + sources += [ "sandbox_status_extension_android.mojom" ] +- } else { + sources += [ "caption.mojom" ] + } + +--- a/chrome/browser/extensions/BUILD.gn ++++ b/chrome/browser/extensions/BUILD.gn +@@ -15,6 +15,8 @@ import("//rlz/buildflags/buildflags.gni" + + assert(enable_extensions) + ++set_sources_assignment_filter([]) ++ + static_library("extensions") { + sources = [ + "active_install_data.cc", +@@ -611,6 +613,8 @@ static_library("extensions") { + "forced_extensions/install_stage_tracker_factory.h", + "global_shortcut_listener.cc", + "global_shortcut_listener.h", ++ "global_shortcut_listener_ozone.cc", ++ "global_shortcut_listener_ozone.h", + "install_gate.h", + "install_observer.cc", + "install_observer.h", +@@ -679,6 +683,8 @@ static_library("extensions") { + "sync_bundle.cc", + "sync_bundle.h", + "system_display/display_info_provider.h", ++ "system_display/display_info_provider_aura.cc", ++ "system_display/display_info_provider_aura.h", + "tab_helper.cc", + "tab_helper.h", + "theme_installed_infobar_delegate.cc", +@@ -1112,10 +1118,8 @@ static_library("extensions") { + "//components/enterprise", + "//components/keep_alive_registry", + ] +- if (is_linux || is_chromeos) { ++ if (is_linux || is_chromeos || is_android) { + sources += [ +- "api/enterprise_reporting_private/device_info_fetcher_linux.cc", +- "api/enterprise_reporting_private/device_info_fetcher_linux.h", + "api/image_writer_private/removable_storage_provider_linux.cc", + ] + } +--- a/chrome/browser/devtools/BUILD.gn ++++ b/chrome/browser/devtools/BUILD.gn +@@ -4,13 +4,13 @@ + + import("//extensions/buildflags/buildflags.gni") + +-if (!is_android) { ++if (is_android) { + import("//build/config/features.gni") + import("//chrome/common/features.gni") + import("//tools/grit/grit_rule.gni") + } + +-if (!is_android) { ++if (is_android) { + _inspector_protocol = "//third_party/inspector_protocol" + import("$_inspector_protocol/inspector_protocol.gni") + +@@ -108,7 +108,7 @@ static_library("devtools") { + "//ui/events:dom_keycode_converter", + ] + +- if (!is_android) { ++ if (is_android) { + deps += [ + "//chrome:extra_resources", + "//chrome:resources", +@@ -189,19 +189,13 @@ static_library("devtools") { + "url_constants.cc", + "url_constants.h", + ] +- if (enable_service_discovery) { +- sources += [ +- "device/cast_device_provider.cc", +- "device/cast_device_provider.h", +- ] +- } + } + if (is_mac) { + sources += [ "devtools_dock_tile_mac.mm" ] + } else { + sources += [ "devtools_dock_tile.cc" ] + } +- if (!is_android) { ++ if (is_android) { + deps += [ + ":protocol_generated_sources", + "//components/subresource_filter/content/browser:browser", +--- a/chrome/common/extensions/api/api_sources.gni ++++ b/chrome/common/extensions/api/api_sources.gni +@@ -72,7 +72,7 @@ schema_sources_ = [ + "windows.json", + ] + +-if (!is_android) { ++if (is_android) { + schema_sources_ += [ "processes.idl" ] + } + +--- a/ui/message_center/BUILD.gn ++++ b/ui/message_center/BUILD.gn +@@ -35,7 +35,7 @@ component("message_center") { + + defines = [ "MESSAGE_CENTER_IMPLEMENTATION" ] + +- if (enable_message_center) { ++ if (true) { + deps += [ + ":message_center_vector_icons", + "//base:i18n", +@@ -87,7 +87,7 @@ component("message_center") { + ] + } + +- if (toolkit_views) { ++ if (true) { + sources += [ + "views/desktop_message_popup_collection.cc", + "views/desktop_message_popup_collection.h", +--- a/components/bookmarks/browser/BUILD.gn ++++ b/components/bookmarks/browser/BUILD.gn +@@ -79,7 +79,7 @@ static_library("browser") { + all_dependent_configs = [ "//ui/views:flags" ] + } + +- if (toolkit_views && !is_mac) { ++ if (!is_mac) { + sources += [ "bookmark_node_data_views.cc" ] + } + +--- a/ui/gfx/animation/BUILD.gn ++++ b/ui/gfx/animation/BUILD.gn +@@ -52,7 +52,7 @@ component("animation") { + ] + } + +- if (!is_android) { ++ if (is_android) { + sources += [ + "throb_animation.cc", + "throb_animation.h", +--- a/chrome/chrome_paks.gni ++++ b/chrome/chrome_paks.gni +@@ -128,7 +128,7 @@ template("chrome_extra_paks") { + sources += invoker.additional_paks + } + +- if (!is_android) { ++ if (is_android) { + # New paks should be added here by default. + sources += [ + "$root_gen_dir/chrome/bookmarks_resources.pak", +@@ -237,7 +237,7 @@ template("chrome_extra_paks") { + sources += [ "$root_gen_dir/chrome/webui_js_exception_resources.pak" ] + deps += [ "//chrome/browser/resources/webui_js_exception:webui_js_exception_resources" ] + } +- if (!is_android && !is_chromeos) { ++ if (is_android && !is_chromeos) { + sources += [ + "$root_gen_dir/chrome/profile_picker_resources.pak", + "$root_gen_dir/chrome/welcome_resources.pak", +--- a/content/browser/devtools/BUILD.gn ++++ b/content/browser/devtools/BUILD.gn +@@ -7,7 +7,7 @@ import("//third_party/protobuf/proto_lib + import("//tools/grit/grit_rule.gni") + + # Android and Fuchsia do not support DevTools front-end. +-if (!is_android && !is_fuchsia) { ++if (is_android && !is_fuchsia) { + grit("devtools_resources") { + source = "$root_gen_dir/devtools/devtools_resources.grd" + +--- a/build/config/locales.gni ++++ b/build/config/locales.gni +@@ -173,7 +173,7 @@ android_bundle_only_locales = [ + ] + + if (is_android) { +- locales = all_chrome_locales ++ locales = all_chrome_locales - android_bundle_only_locales + + # Android doesn't ship all locales on KitKat in order to save space + # (but webview does). http://crbug.com/369218 +@@ -195,14 +195,12 @@ if (is_android) { + android_bundle_locales_as_resources -= [ + "en-rUS", + "es-r419", +- "sr-rLatn", + "fil", + "he", + "id", + ] + android_bundle_locales_as_resources += [ + "es-rUS", +- "b+sr+Latn", + "in", + "iw", + "tl", +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -1749,7 +1749,6 @@ if (current_toolchain == default_toolcha + } + } + if (!dfmify_dev_ui || !_is_bundle_module) { +- additional_extra_paks += [ "$root_gen_dir/chrome/dev_ui_resources.pak" ] + deps += [ "//chrome/browser/resources:dev_ui_paks" ] + } + +--- a/ui/gfx/BUILD.gn ++++ b/ui/gfx/BUILD.gn +@@ -401,8 +401,6 @@ component("gfx") { + + if ((!use_aura && !toolkit_views) || is_ios) { + sources -= [ +- "nine_image_painter.cc", +- "nine_image_painter.h", + ] + } + +--- a/components/performance_manager/BUILD.gn ++++ b/components/performance_manager/BUILD.gn +@@ -168,7 +168,7 @@ static_library("performance_manager") { + "//url", + ] + +- if (!is_android) { ++ if (is_android) { + sources += [ + "decorators/site_data_recorder.cc", + "persistence/site_data/exponential_moving_average.cc", +--- a/media/mojo/mojom/BUILD.gn ++++ b/media/mojo/mojom/BUILD.gn +@@ -51,7 +51,7 @@ mojom("mojom") { + + if (is_android) { + sources += [ "android_overlay.mojom" ] +- } else { ++ + sources += [ "speech_recognition_service.mojom" ] + } + +--- a/components/autofill/core/browser/BUILD.gn ++++ b/components/autofill/core/browser/BUILD.gn +@@ -424,7 +424,7 @@ static_library("browser") { + deps += [ "//third_party/blink/public/common" ] + } + +- if (!is_android && !is_ios) { ++ if (is_android && !is_ios) { + sources += [ + "payments/local_card_migration_manager.cc", + "payments/local_card_migration_manager.h", +--- a/ui/webui/resources/BUILD.gn ++++ b/ui/webui/resources/BUILD.gn +@@ -5,7 +5,7 @@ + import("//third_party/closure_compiler/compile_js.gni") + import("//ui/webui/resources/tools/generate_grd.gni") + +-include_polymer = !is_android && !is_ios ++include_polymer = is_android && !is_ios + + generate_grd("build_grd") { + grd_prefix = "webui_generated" +@@ -59,7 +59,7 @@ group("closure_compile") { + "js:closure_compile_modules", + ] + +- if (!is_android) { ++ if (is_android) { + deps += [ + "cr_components:closure_compile", + "cr_elements:closure_compile", +@@ -74,7 +74,7 @@ group("modulize") { + "js/cr/ui:modulize", + ] + +- if (!is_android) { ++ if (is_android) { + public_deps += [ + "cr_components:polymer3_elements", + "cr_elements:polymer3_elements", +--- a/device/fido/BUILD.gn ++++ b/device/fido/BUILD.gn +@@ -72,7 +72,7 @@ component("fido") { + ] + + # Android implementation of FIDO is delegated to GMSCore. +- if (!is_android) { ++ if (is_android) { + sources += [ + "aoa/android_accessory_device.cc", + "aoa/android_accessory_device.h", +--- a/chrome/browser/nearby_sharing/BUILD.gn ++++ b/chrome/browser/nearby_sharing/BUILD.gn +@@ -10,8 +10,6 @@ source_set("share_target") { + "attachment.h", + "file_attachment.cc", + "file_attachment.h", +- "share_target.cc", +- "share_target.h", + "text_attachment.cc", + "text_attachment.h", + ] +--- a/components/enterprise/BUILD.gn ++++ b/components/enterprise/BUILD.gn +@@ -52,7 +52,7 @@ static_library("enterprise") { + ] + } + +- if (!is_android && !is_chromeos) { ++ if (is_android && !is_chromeos) { + sources += [ + "browser/controller/chrome_browser_cloud_management_controller.cc", + "browser/controller/chrome_browser_cloud_management_controller.h", +--- a/components/media_router/common/BUILD.gn ++++ b/components/media_router/common/BUILD.gn +@@ -33,7 +33,7 @@ static_library("common") { + + deps = [] + +- if (!is_android) { ++ if (is_android) { + sources += [ + "discovery/media_sink_service_base.cc", + "discovery/media_sink_service_base.h", +--- a/components/media_router/browser/BUILD.gn ++++ b/components/media_router/browser/BUILD.gn +@@ -81,7 +81,7 @@ source_set("browser") { + "android/media_router_dialog_controller_android.h", + ] + deps += [ "android:jni_headers" ] +- } else { ++ + sources += [ + "logger_impl.cc", + "logger_impl.h", +--- a/chrome/browser/ui/webui/discards/BUILD.gn ++++ b/chrome/browser/ui/webui/discards/BUILD.gn +@@ -4,7 +4,7 @@ + + import("//mojo/public/tools/bindings/mojom.gni") + +-if (is_win || is_mac || is_linux || is_chromeos) { ++if (is_win || is_mac || is_linux || is_chromeos || is_android) { + mojom("mojo_bindings") { + sources = [ + "discards.mojom", +--- a/chrome/common/importer/BUILD.gn ++++ b/chrome/common/importer/BUILD.gn +@@ -78,8 +78,6 @@ source_set("importer") { + sources = [ + "firefox_importer_utils.cc", + "firefox_importer_utils.h", +- "imported_bookmark_entry.cc", +- "imported_bookmark_entry.h", + "importer_autofill_form_data_entry.cc", + "importer_autofill_form_data_entry.h", + "importer_bridge.cc", +--- a/extensions/browser/api/system_cpu/BUILD.gn ++++ b/extensions/browser/api/system_cpu/BUILD.gn +@@ -25,7 +25,7 @@ source_set("system_cpu") { + sources += [ "cpu_info_provider_mac.cc" ] + } + +- if (is_linux || is_chromeos) { ++ if (is_linux || is_chromeos || is_android) { + sources += [ "cpu_info_provider_linux.cc" ] + } + +--- a/chrome/browser/apps/platform_apps/api/music_manager_private/BUILD.gn ++++ b/chrome/browser/apps/platform_apps/api/music_manager_private/BUILD.gn +@@ -32,7 +32,7 @@ source_set("music_manager_private") { + + if (is_chromeos) { + sources += [ "device_id_chromeos.cc" ] +- } else if (is_linux) { ++ } else if (is_linux || is_android) { + sources += [ "device_id_linux.cc" ] + } else if (is_mac) { + sources += [ "device_id_mac.cc" ] +--- a/chrome/browser/resources/BUILD.gn ++++ b/chrome/browser/resources/BUILD.gn +@@ -108,7 +108,7 @@ if (enable_js_type_check) { + } + } + +-if (!is_android) { ++if (is_android) { + grit("component_extension_resources") { + source = "component_extension_resources.grd" + +--- a/ui/webui/resources/js/BUILD.gn ++++ b/ui/webui/resources/js/BUILD.gn +@@ -11,7 +11,7 @@ preprocess_folder = "$root_gen_dir/ui/we + preprocess_gen_manifest = "preprocessed_gen_manifest.json" + preprocess_src_manifest = "preprocessed_src_manifest.json" + +-include_polymer = !is_android && !is_ios ++include_polymer = is_android && !is_ios + + generate_grd("build_grdp") { + grd_prefix = "webui_js" +--- a/ui/webui/resources/css/BUILD.gn ++++ b/ui/webui/resources/css/BUILD.gn +@@ -5,7 +5,7 @@ + import("//tools/grit/preprocess_grit.gni") + import("//ui/webui/resources/tools/generate_grd.gni") + +-include_polymer = !is_android && !is_ios ++include_polymer = is_android && !is_ios + + preprocess_folder = "$root_gen_dir/ui/webui/resources/preprocessed/css" + preprocess_src_manifest = "preprocessed_src_manifest.json" +--- a/ui/webui/resources/html/BUILD.gn ++++ b/ui/webui/resources/html/BUILD.gn +@@ -4,7 +4,7 @@ + + import("//ui/webui/resources/tools/generate_grd.gni") + +-include_polymer = !is_android && !is_ios ++include_polymer = is_android && !is_ios + + generate_grd("build_grdp") { + grd_prefix = "webui_html" +--- a/ui/webui/resources/js/cr/ui/BUILD.gn ++++ b/ui/webui/resources/js/cr/ui/BUILD.gn +@@ -96,7 +96,7 @@ preprocess_grit("preprocess_generated") + "tree.m.js", + ] + +- if (!is_android) { ++ if (is_android) { + in_files += [ + "focus_row_behavior.m.js", + "focus_without_ink.m.js", diff --git a/patches/Extensions/base/res.patch b/patches/Extensions/base/res.patch new file mode 100644 index 0000000..a2d07aa --- /dev/null +++ b/patches/Extensions/base/res.patch @@ -0,0 +1,1072 @@ +From: Wengling Chen +Date: Sat, 30 May 2020 18:25:38 -0400 +Subject: resource fixes for enable_extensions=true + +--- + chrome/app/bookmarks_strings.grdp | 6 - + chrome/app/chromium_strings.grd | 22 ++-- + chrome/app/generated_resources.grd | 88 ++++++------------- + chrome/app/profiles_strings.grdp | 11 -- + chrome/app/theme/theme_resources.grd | 26 ++--- + chrome/browser/browser_resources.grd | 26 ++--- + components/autofill_payments_strings.grdp | 14 +-- + components/autofill_strings.grdp | 2 + components/components_strings.grd | 4 + components/history_strings.grdp | 2 + components/new_or_sad_tab_strings.grdp | 4 + components/page_info_strings.grdp | 6 - + components/payments_strings.grdp | 2 + components/permissions_strings.grdp | 2 + components/resources/components_scaled_resources.grd | 2 + components/sync_ui_strings.grdp | 2 + mojo/public/js/mojo_bindings_resources.grd | 2 + ui/resources/ui_resources.grd | 10 +- + ui/webui/resources/webui_resources.grd | 2 + 19 files changed, 99 insertions(+), 134 deletions(-) + +--- a/chrome/app/theme/theme_resources.grd ++++ b/chrome/app/theme/theme_resources.grd +@@ -28,7 +28,7 @@ + + + +- ++ + + + +@@ -70,7 +70,7 @@ + + + +- ++ + + + +@@ -78,7 +78,7 @@ + + + +- ++ + +@@ -94,7 +94,7 @@ + + + +- ++ + + + +@@ -131,7 +131,7 @@ + + + +- ++ + + + +@@ -146,7 +146,7 @@ + + + +- ++ + + + +@@ -156,12 +156,12 @@ + + + +- ++ + + + + +- ++ + + + +@@ -255,7 +255,7 @@ + + + +- ++ + + + +@@ -273,7 +273,7 @@ + + + +- ++ + + + +@@ -295,7 +295,7 @@ + + + +- ++ + + + +@@ -334,7 +334,7 @@ + + + +- ++ + + + +@@ -349,7 +349,7 @@ + + + +- ++ + + + +--- a/ui/resources/ui_resources.grd ++++ b/ui/resources/ui_resources.grd +@@ -78,7 +78,7 @@ + + + +- ++ + + + +@@ -92,7 +92,7 @@ + + + +- ++ + + + +@@ -135,7 +135,7 @@ + + + +- ++ + + + +@@ -143,7 +143,7 @@ + + + +- ++ + + + +@@ -155,7 +155,7 @@ + + + +- ++ + + + +--- a/mojo/public/js/mojo_bindings_resources.grd ++++ b/mojo/public/js/mojo_bindings_resources.grd +@@ -14,7 +14,7 @@ + + + +- ++ + + + +- ++ + + + +@@ -306,12 +306,12 @@ are declared in tools/grit/grit_rule.gni + + + +- ++ + + + + +- ++ + + + +@@ -452,7 +452,7 @@ are declared in tools/grit/grit_rule.gni + Disable + + +- ++ + + Search cleared + +@@ -480,7 +480,7 @@ are declared in tools/grit/grit_rule.gni + + + +- ++ + + I&nspect + +@@ -988,7 +988,7 @@ are declared in tools/grit/grit_rule.gni + + + +- ++ + + + New &tab +@@ -2059,7 +2059,7 @@ are declared in tools/grit/grit_rule.gni + + + +- ++ + + + + + +- ++ + + Install + +@@ -2793,7 +2793,6 @@ are declared in tools/grit/grit_rule.gni + + + +- + + Subject + +@@ -2806,7 +2805,6 @@ are declared in tools/grit/grit_rule.gni + + Serial + +- + + + Base64-encoded ASCII, single certificate +@@ -3373,7 +3371,7 @@ are declared in tools/grit/grit_rule.gni + + + +- ++ + + + End process +@@ -3658,7 +3656,7 @@ are declared in tools/grit/grit_rule.gni + + Chrome File Utilities + +- ++ + + Profile Importer + +@@ -4970,11 +4968,6 @@ Keep your key file in a safe place. You + Manage passwords + + +- +- +- App ($1com.netflix.mediaclient) +- +- + + + Save your passwords? +@@ -5232,7 +5225,7 @@ Keep your key file in a safe place. You + + + +- ++ + + About System + +@@ -5263,7 +5256,7 @@ Keep your key file in a safe place. You + + + +- ++ + + Legacy Browser Support + +@@ -5828,7 +5821,7 @@ Keep your key file in a safe place. You + + + +- ++ + + To open this link, choose an app + +@@ -6088,7 +6081,7 @@ the Bookmarks menu."> + No thanks + + +- ++ + + Password updated + +@@ -6119,9 +6112,6 @@ the Bookmarks menu."> + + Check passwords + +- +- Save +- + + Next + +@@ -6131,16 +6121,6 @@ the Bookmarks menu."> + + No thanks + +- +- +- Update Password +- +- +- +- +- Update password +- +- + + Never + +@@ -6242,7 +6222,7 @@ the Bookmarks menu."> + + + +- ++ + + + +@@ -7116,7 +7096,7 @@ the Bookmarks menu."> + +- ++ + + Your home page has been set. + +@@ -7334,7 +7314,7 @@ the Bookmarks menu."> + Create QR code for this Image + + +- ++ + + QR code + +@@ -7512,14 +7492,12 @@ the Bookmarks menu."> + + + +- + + Infobar Container + + + Infobar + +- + + + +@@ -7573,7 +7551,7 @@ the Bookmarks menu."> + + + +- ++ + + + Your <a target="_blank" href="$1">$2Chromebook is managed</a> by your organization +@@ -7694,7 +7672,7 @@ the Bookmarks menu."> + + + +- ++ + + Apps +@@ -7995,7 +7973,7 @@ the Bookmarks menu."> + + + +- ++ + + Create + +@@ -8382,7 +8360,7 @@ Please help our engineers fix this probl + + + +- ++ + + + +@@ -8491,7 +8469,6 @@ Please help our engineers fix this probl + + + +- + + Translate this page? + +@@ -8622,7 +8599,6 @@ Please help our engineers fix this probl + + Reset + +- + + + +@@ -9582,7 +9558,7 @@ Please help our engineers fix this probl + Live Caption visible, press ⌘ + Option + Up arrow or Down arrow to cycle focus + + +- ++ + + Live Caption visible, press F6 to cycle focus + +@@ -9623,7 +9599,7 @@ Please help our engineers fix this probl + + + +- ++ + + Media-File Permissions for "$1Photo Editor" + +@@ -10087,7 +10063,7 @@ Please help our engineers fix this probl + + + +- ++ + + + $1www.9oo91e.qjz9zk wants to pair +@@ -10200,7 +10176,7 @@ Please help our engineers fix this probl + + + +- ++ + + $1www.9oo91e.qjz9zk wants to connect to a serial port + +@@ -10219,7 +10195,7 @@ Please help our engineers fix this probl + + + +- ++ + + $1www.9oo91e.qjz9zk wants to connect to a HID device + +@@ -10271,7 +10247,7 @@ Please help our engineers fix this probl + + + +- ++ + + + Redirect blocked: +@@ -10346,7 +10322,7 @@ Please help our engineers fix this probl + + + +- ++ + + Open download + +@@ -10496,7 +10472,7 @@ Please help our engineers fix this probl + + + +- ++ + + + Relaunch now +@@ -10513,7 +10489,7 @@ Please help our engineers fix this probl + + + +- ++ + + Use your security key with $19oo91e.qjz9zk + +@@ -10779,7 +10755,7 @@ Please help our engineers fix this probl + + + +- ++ + + + Take Survey +@@ -10949,7 +10925,7 @@ Please help our engineers fix this probl + + + +- ++ + + {NUM_EXTENSIONS, plural, + =1 {An extension has been approved} +--- a/components/components_strings.grd ++++ b/components/components_strings.grd +@@ -321,7 +321,7 @@ + + + +- ++ + + + +@@ -416,7 +416,7 @@ + + This plugin is not supported + +- ++ + + + &Print... +--- a/chrome/app/bookmarks_strings.grdp ++++ b/chrome/app/bookmarks_strings.grdp +@@ -2,7 +2,7 @@ + + + +- ++ + + + +@@ -103,7 +103,7 @@ + + Add &folder... + +- ++ + + &Show bookmarks bar + +@@ -155,7 +155,7 @@ + + Add &Folder... + +- ++ + + &Show Bookmarks Bar + +--- a/chrome/app/chromium_strings.grd ++++ b/chrome/app/chromium_strings.grd +@@ -180,7 +180,7 @@ If you update this file, be sure also to + + + +- ++ + + + +@@ -685,7 +685,6 @@ Chromium is unable to recover your setti + + + +- + + Link your Chromium data to this account? + +@@ -695,10 +694,9 @@ Chromium is unable to recover your setti + + You are signing in with a managed account and giving its administrator control over your Chromium profile. Your Chromium data, such as your apps, bookmarks, history, passwords, and other settings will become permanently tied to $1pat@example.com. You will be able to delete this data via the Google Accounts Dashboard, but you will not be able to associate this data with another account. You can optionally create a new profile to keep your existing Chromium data separate. $2Learn more + +- + + +- ++ + + Your system administrator has configured Chromium to open an alternative browser to access $1example.com. + +@@ -823,7 +821,7 @@ Chromium is unable to recover your setti + + + +- ++ + + + This person's browsing data will be deleted from this device. To recover the data, sign in to Chromium as $2foo@example.com. +@@ -900,7 +898,7 @@ Chromium is unable to recover your setti + + + +- ++ + + If an image doesn’t have a useful description, Chromium will try to provide one for you. To create descriptions, images are sent to Google. You can turn this off in settings at any time. + +@@ -982,7 +980,7 @@ Chromium is unable to recover your setti + + + +- ++ + + Update Chromium to start sync + +@@ -1073,7 +1071,7 @@ Chromium is unable to recover your setti + + + +- ++ + + Welcome to Chromium + +@@ -1086,7 +1084,7 @@ Chromium is unable to recover your setti + + + +- ++ + + + {0, plural, +@@ -1130,7 +1128,7 @@ Chromium is unable to recover your setti + + + +- ++ + + Launching Chromium... + +@@ -1145,7 +1143,7 @@ Chromium is unable to recover your setti + Share a Chromium tab + + +- ++ + + Help us improve Chromium + +@@ -1162,7 +1160,7 @@ Chromium is unable to recover your setti + + + +- ++ + + Who's using Chromium? + +--- a/components/sync_ui_strings.grdp ++++ b/components/sync_ui_strings.grdp +@@ -1,6 +1,6 @@ + + +- ++ + + Encrypt synced passwords with your Google credentials + +--- a/chrome/browser/browser_resources.grd ++++ b/chrome/browser/browser_resources.grd +@@ -8,11 +8,11 @@ + + + +- ++ + + + +- ++ + + + +@@ -66,7 +66,7 @@ + + + +- ++ + + + +@@ -78,7 +78,7 @@ + + + +- ++ + + + +@@ -94,7 +94,7 @@ + + + +- ++ + + + +@@ -128,7 +128,7 @@ + + + +- ++ + + + +@@ -146,7 +146,7 @@ + + + +- ++ + + + +@@ -183,14 +183,14 @@ + + + +- ++ + + + + + + +- ++ + + + +@@ -200,7 +200,7 @@ + + + +- ++ + + + +@@ -337,7 +337,7 @@ + + + +- ++ + + + +@@ -358,7 +358,7 @@ + + + +- ++ + + + +@@ -441,7 +441,7 @@ + + + +- ++ + + + +--- a/components/history_strings.grdp ++++ b/components/history_strings.grdp +@@ -63,7 +63,7 @@ + Clear Browsing Data... + + +- ++ + + Collapse list + +--- a/components/new_or_sad_tab_strings.grdp ++++ b/components/new_or_sad_tab_strings.grdp +@@ -106,7 +106,7 @@ + Learn more + + +- ++ + + Error code: $1STATUS_ACCESS_VIOLATION + +@@ -117,7 +117,7 @@ + desc="Title of the new tab page, not to be confused with the action of opening a new tab."> + New Tab + +- ++ + + You’ve gone incognito +--- a/chrome/app/profiles_strings.grdp ++++ b/chrome/app/profiles_strings.grdp +@@ -473,11 +473,6 @@ + Although you can no longer access your old profile, you can still remove it. + + +- +- This account is already being used on this device. +- +- +- + + This account is already being used on this computer. + +@@ -487,7 +482,7 @@ + + + +- ++ + + + Add person +@@ -520,7 +515,7 @@ + + + +- ++ + + + +@@ -694,7 +689,7 @@ + + + +- ++ + + + Done +--- a/components/autofill_payments_strings.grdp ++++ b/components/autofill_payments_strings.grdp +@@ -68,7 +68,7 @@ + + + +- ++ + + Phone + +@@ -79,19 +79,15 @@ + + + +- + + Save + +- +- + + Save + + + Save + +- + + + +@@ -196,7 +192,7 @@ + + + +- ++ + + Google Pay logo + +@@ -400,7 +396,7 @@ + + + +- ++ + + + Use Touch ID instead of CVC? +@@ -456,7 +452,7 @@ + + + +- ++ + + Verifying your identity... + +@@ -473,7 +469,7 @@ + + + +- ++ + + Use a virtual card number... + +--- a/components/autofill_strings.grdp ++++ b/components/autofill_strings.grdp +@@ -174,7 +174,7 @@ + Show cards from your Google Account + + +- ++ + + Autofill + +--- a/components/page_info_strings.grdp ++++ b/components/page_info_strings.grdp +@@ -187,7 +187,7 @@ + + + +- ++ + + Certificate + +@@ -223,7 +223,7 @@ + + + +- ++ + + Cookies + +@@ -464,7 +464,7 @@ + + + +- ++ + + To apply your updated settings to this site, reload this page + +--- a/components/payments_strings.grdp ++++ b/components/payments_strings.grdp +@@ -558,7 +558,7 @@ + + + +- ++ + + {PAYMENT_METHOD, plural, + =0 {{1}VISA ....1234} +--- a/ui/webui/resources/webui_resources.grd ++++ b/ui/webui/resources/webui_resources.grd +@@ -66,7 +66,7 @@ without changes to the corresponding grd + + +- ++ + + + +--- a/components/permissions_strings.grdp ++++ b/components/permissions_strings.grdp +@@ -144,7 +144,7 @@ This will otherwise be blocked by your p + Allow $1google.com to: + + +- ++ + + Use your location? + +--- a/components/resources/components_scaled_resources.grd ++++ b/components/resources/components_scaled_resources.grd +@@ -20,7 +20,7 @@ + + + +- ++ + + + diff --git a/patches/Extensions/base/src.patch b/patches/Extensions/base/src.patch new file mode 100644 index 0000000..3de224f --- /dev/null +++ b/patches/Extensions/base/src.patch @@ -0,0 +1,10298 @@ +From: Wengling Chen +Date: Sat, 30 May 2020 18:25:38 -0400 +Subject: source code fixes for enable_extensions=true + +--- + android_webview/browser/aw_browser_context.cc | 6 + android_webview/browser/aw_browser_context.h | 2 + base/process/kill.h | 2 + base/process/kill_posix.cc | 2 + chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java | 10 + chrome/browser/about_flags.cc | 2 + chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc | 16 + chrome/browser/browser_features.cc | 2 + chrome/browser/browser_features.h | 2 + chrome/browser/chrome_browser_main_posix.cc | 2 + chrome/browser/chrome_content_browser_client.cc | 4 + chrome/browser/content_settings/host_content_settings_map_factory.cc | 1 + chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc | 8 + chrome/browser/custom_handlers/register_protocol_handler_permission_request.h | 1 + chrome/browser/devtools/chrome_devtools_manager_delegate.h | 2 + chrome/browser/devtools/devtools_ui_bindings.cc | 11 + chrome/browser/devtools/devtools_window.cc | 1 + chrome/browser/download/download_commands.cc | 6 + chrome/browser/download/download_commands.h | 4 + chrome/browser/download/download_ui_model.cc | 4 + chrome/browser/download/download_ui_model.h | 4 + chrome/browser/download/drag_download_item_aura.cc | 26 + chrome/browser/engagement/important_sites_util.cc | 5 + chrome/browser/engagement/important_sites_util.h | 2 + chrome/browser/enterprise/reporting/prefs.cc | 1 + chrome/browser/enterprise/reporting/report_scheduler_desktop.cc | 5 + chrome/browser/extensions/api/downloads/downloads_api.cc | 1 + chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc | 104 - + chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc | 13 + chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc | 20 + chrome/browser/extensions/api/settings_private/prefs_util.cc | 2 + chrome/browser/extensions/api/tabs/windows_event_router.cc | 2 + chrome/browser/extensions/extension_management.cc | 2 + chrome/browser/extensions/extension_system_factory.cc | 3 + chrome/browser/extensions/global_shortcut_listener_ozone.cc | 27 + chrome/browser/extensions/global_shortcut_listener_ozone.h | 16 + chrome/browser/extensions/system_display/display_info_provider_aura.cc | 4 + chrome/browser/extensions/system_display/display_info_provider_aura.h | 12 + chrome/browser/first_run/first_run_internal_posix.cc | 2 + chrome/browser/first_run/upgrade_util.h | 2 + chrome/browser/flag_descriptions.cc | 1 + chrome/browser/flag_descriptions.h | 1 + chrome/browser/hid/hid_chooser_context.cc | 5 + chrome/browser/intranet_redirect_detector.h | 5 + chrome/browser/lifetime/application_lifetime.cc | 22 + chrome/browser/lifetime/application_lifetime.h | 4 + chrome/browser/lifetime/browser_shutdown.cc | 6 + chrome/browser/lifetime/browser_shutdown.h | 4 + chrome/browser/media/router/media_router_feature.cc | 7 + chrome/browser/media/router/media_router_feature.h | 3 + chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc | 9 + chrome/browser/metrics/thread_watcher.cc | 8 + chrome/browser/metrics/thread_watcher.h | 2 + chrome/browser/metrics/thread_watcher_report_hang.cc | 2 + chrome/browser/metrics/thread_watcher_report_hang.h | 2 + chrome/browser/nearby_sharing/nearby_notification_manager.cc | 1 + chrome/browser/nearby_sharing/share_target.cc | 4 + chrome/browser/password_manager/multi_profile_credentials_filter.cc | 3 + chrome/browser/performance_manager/policies/policy_features.cc | 2 + chrome/browser/performance_manager/policies/policy_features.h | 2 + chrome/browser/permissions/attestation_permission_request.cc | 7 + chrome/browser/platform_util.cc | 18 + chrome/browser/platform_util_android.cc | 6 + chrome/browser/policy/browser_dm_token_storage_linux.cc | 18 + chrome/browser/policy/browser_dm_token_storage_linux.h | 26 + chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc | 6 + chrome/browser/policy/chrome_browser_policy_connector.cc | 10 + chrome/browser/policy/chrome_browser_policy_connector.h | 6 + chrome/browser/prefs/browser_prefs.cc | 8 + chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc | 32 + chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h | 2 + chrome/browser/profiles/off_the_record_profile_impl.cc | 9 + chrome/browser/profiles/off_the_record_profile_impl.h | 10 + chrome/browser/profiles/profile.cc | 10 + chrome/browser/profiles/profile.h | 6 + chrome/browser/profiles/profile_attributes_storage.cc | 4 + chrome/browser/profiles/profile_attributes_storage.h | 2 + chrome/browser/profiles/profile_impl.cc | 5 + chrome/browser/profiles/profile_impl.h | 6 + chrome/browser/profiles/profile_manager.cc | 23 + chrome/browser/profiles/profile_manager.h | 12 + chrome/browser/profiles/profile_metrics.cc | 6 + chrome/browser/profiles/profile_window.cc | 4 + chrome/browser/profiles/profile_window.h | 3 + chrome/browser/profiles/profiles_state.cc | 4 + chrome/browser/profiles/profiles_state.h | 2 + chrome/browser/renderer_context_menu/render_view_context_menu.cc | 10 + chrome/browser/renderer_context_menu/render_view_context_menu.h | 8 + chrome/browser/resource_coordinator/resource_coordinator_parts.cc | 4 + chrome/browser/resource_coordinator/resource_coordinator_parts.h | 8 + chrome/browser/search/instant_service.h | 2 + chrome/browser/search/instant_service_factory.h | 2 + chrome/browser/search/instant_service_observer.h | 2 + chrome/browser/search/local_ntp_source.h | 2 + chrome/browser/search/most_visited_iframe_source.h | 2 + chrome/browser/sessions/session_restore.cc | 25 + chrome/browser/sharing/shared_clipboard/feature_flags.cc | 2 + chrome/browser/sharing/shared_clipboard/feature_flags.h | 2 + chrome/browser/startup_data.cc | 5 + chrome/browser/storage/storage_notification_service_impl.cc | 2 + chrome/browser/supervised_user/supervised_user_service_factory.cc | 1 + chrome/browser/sync/profile_sync_service_factory.cc | 2 + chrome/browser/ui/aura/native_window_tracker_aura.cc | 19 + chrome/browser/ui/aura/native_window_tracker_aura.h | 21 + chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc | 6 + chrome/browser/ui/browser.cc | 6 + chrome/browser/ui/browser.h | 4 + chrome/browser/ui/browser_commands.cc | 1 + chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc | 3 + chrome/browser/ui/browser_dialogs.cc | 2 + chrome/browser/ui/browser_instant_controller.h | 2 + chrome/browser/ui/browser_list.h | 4 + chrome/browser/ui/browser_list_observer.h | 4 + chrome/browser/ui/browser_navigator_params.cc | 2 + chrome/browser/ui/browser_navigator_params.h | 6 + chrome/browser/ui/browser_tab_strip_model_delegate.cc | 4 + chrome/browser/ui/browser_ui_prefs.cc | 2 + chrome/browser/ui/browser_window.h | 2 + chrome/browser/ui/chrome_pages.cc | 4 + chrome/browser/ui/chrome_pages.h | 4 + chrome/browser/ui/content_settings/content_setting_bubble_model.cc | 11 + chrome/browser/ui/content_settings/content_setting_bubble_model.h | 2 + chrome/browser/ui/content_settings/content_setting_image_model.cc | 2 + chrome/browser/ui/global_error/global_error.cc | 2 + chrome/browser/ui/native_file_system_dialogs.cc | 2 + chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc | 10 + chrome/browser/ui/passwords/manage_passwords_view_utils.cc | 4 + chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc | 2 + chrome/browser/ui/passwords/password_generation_popup_controller_impl.h | 6 + chrome/browser/ui/passwords/settings/password_manager_presenter.cc | 6 + chrome/browser/ui/passwords/settings/password_manager_presenter.h | 2 + chrome/browser/ui/search/instant_controller.h | 2 + chrome/browser/ui/search/ntp_user_data_logger.h | 2 + chrome/browser/ui/search/search_ipc_router.h | 2 + chrome/browser/ui/search/search_ipc_router_policy_impl.h | 2 + chrome/browser/ui/search/search_tab_helper.h | 2 + chrome/browser/ui/signin_view_controller.h | 4 + chrome/browser/ui/tabs/tab_strip_model.h | 4 + chrome/browser/ui/views/accelerator_utils_aura.cc | 14 + chrome/browser/ui/views/autofill/payments/save_card_manage_cards_bubble_views.cc | 17 + chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc | 2 + chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc | 2 + chrome/browser/ui/views/browser_dialogs_views.cc | 9 + chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc | 2 + chrome/browser/ui/views/dropdown_bar_host_aura.cc | 4 + chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc | 6 + chrome/browser/ui/views/frame/browser_frame.cc | 5 + chrome/browser/ui/views/frame/browser_view.cc | 3 + chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc | 80 + chrome/browser/ui/views/frame/desktop_browser_frame_aura.h | 26 + chrome/browser/ui/views/frame/native_browser_frame_factory_aurax11.cc | 4 + chrome/browser/ui/views/hats/hats_bubble_view.cc | 9 + chrome/browser/ui/views/hats/hats_next_web_dialog.cc | 11 + chrome/browser/ui/views/intent_picker_bubble_view.cc | 14 + chrome/browser/ui/views/location_bar/location_bar_view.cc | 2 + chrome/browser/ui/views/location_bar/permission_chip.cc | 16 + chrome/browser/ui/views/location_bar/permission_chip.h | 1 + chrome/browser/ui/views/page_action/page_action_icon_controller.cc | 22 + chrome/browser/ui/views/page_info/page_info_bubble_view.cc | 1 + chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc | 13 + chrome/browser/ui/views/payments/cvc_unmask_view_controller.h | 5 + chrome/browser/ui/views/payments/secure_payment_confirmation_view.cc | 8 + chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc | 4 + chrome/browser/ui/views/profiles/profile_menu_view.cc | 23 + chrome/browser/ui/views/profiles/profile_menu_view.h | 4 + chrome/browser/ui/views/profiles/profile_picker_view.cc | 13 + chrome/browser/ui/views/profiles/profile_picker_view_sync_delegate.cc | 15 + chrome/browser/ui/views/status_icons/status_icon_button_linux.cc | 14 + chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc | 16 + chrome/browser/ui/webui/history/foreign_session_handler.cc | 1 + chrome/browser/ui/webui/omnibox/omnibox_ui.cc | 4 + chrome/browser/ui/webui/omnibox/omnibox_ui.h | 6 + chrome/browser/ui/webui/settings/people_handler.cc | 15 + chrome/browser/ui/webui/settings/people_handler.h | 7 + chrome/browser/ui/webui/settings/settings_ui.cc | 8 + chrome/browser/ui/webui/settings/system_handler.cc | 1 + chrome/browser/ui/webui/signin/inline_login_handler_impl.cc | 34 + chrome/browser/ui/webui/signin/login_ui_service.cc | 11 + chrome/browser/ui/webui/welcome/welcome_handler.cc | 3 + chrome/browser/web_applications/components/web_app_file_handler_registration.cc | 2 + chrome/browser/web_applications/components/web_app_shortcut_linux.cc | 435 ---- + chrome/browser/web_applications/components/web_app_shortcut_linux.h | 6 + chrome/browser/web_applications/extensions/bookmark_app_provider.cc | 5 + chrome/common/chrome_features.cc | 8 + chrome/common/chrome_features.h | 10 + chrome/common/chrome_paths.cc | 2 + chrome/common/chrome_paths.h | 2 + chrome/common/chrome_switches.cc | 4 + chrome/common/chrome_switches.h | 4 + chrome/common/importer/firefox_importer_utils.cc | 4 + chrome/common/pref_names.cc | 25 + chrome/common/pref_names.h | 25 + chrome/common/webui_url_constants.cc | 9 + chrome/common/webui_url_constants.h | 9 + chromecast/browser/cast_browser_context.cc | 2 + chromecast/browser/cast_browser_context.h | 2 + components/autofill/core/browser/form_data_importer.cc | 6 + components/autofill/core/browser/form_data_importer.h | 6 + components/autofill/core/browser/payments/local_card_migration_manager.cc | 17 + components/autofill/core/browser/payments/upi_vpa_save_manager.cc | 7 + components/bookmarks/browser/bookmark_node_data.h | 8 + components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/Origin.java | 13 + components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java | 1 + components/enterprise/browser/enterprise_switches.cc | 2 + components/enterprise/browser/enterprise_switches.h | 2 + components/feature_engagement/public/event_constants.cc | 2 + components/feature_engagement/public/event_constants.h | 2 + components/feature_engagement/public/feature_constants.cc | 2 + components/feature_engagement/public/feature_constants.h | 2 + components/media_router/browser/android/media_router_android.cc | 4 + components/media_router/browser/android/media_router_android.h | 6 + components/media_router/browser/media_router.h | 4 + components/media_router/browser/media_router_base.cc | 2 + components/media_router/browser/media_router_base.h | 4 + components/omnibox/browser/autocomplete_match.cc | 4 + components/omnibox/browser/autocomplete_match.h | 2 + components/omnibox/browser/omnibox_pedal.cc | 4 + components/omnibox/browser/omnibox_pedal.h | 4 + components/omnibox/browser/omnibox_pedal_implementations.cc | 2 + components/omnibox/browser/omnibox_popup_model.cc | 4 + components/omnibox/browser/omnibox_popup_model.h | 2 + components/page_info/page_info_ui.cc | 8 + components/page_info/page_info_ui.h | 3 + components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java | 3 + components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java | 4 + components/permissions/permission_request.cc | 2 + components/permissions/permission_request.h | 2 + components/permissions/permission_request_impl.cc | 2 + components/permissions/permission_request_impl.h | 2 + components/policy/resources/policy_templates.json | 8 + components/search/search.cc | 2 + components/ui_devtools/views/overlay_agent_views.cc | 34 + components/url_formatter/elide_url.cc | 4 + components/url_formatter/elide_url.h | 2 + content/browser/media/session/audio_focus_delegate_default.cc | 7 + content/browser/renderer_host/native_web_keyboard_event_android.cc | 2 + content/browser/storage_partition_impl.cc | 4 + content/browser/storage_partition_impl.h | 6 + content/browser/tracing/generate_trace_viewer_grd.py | 2 + content/browser/web_contents/web_contents_impl.cc | 3 + content/browser/web_contents/web_contents_impl.h | 2 + content/public/browser/browser_context.h | 4 + content/public/browser/content_browser_client.cc | 4 + content/public/browser/content_browser_client.h | 4 + content/public/browser/desktop_media_id.cc | 6 + content/public/browser/desktop_media_id.h | 2 + content/public/browser/native_web_keyboard_event.h | 1 + content/public/browser/storage_partition.h | 4 + content/shell/browser/shell_browser_context.cc | 2 + content/shell/browser/shell_browser_context.h | 4 + extensions/browser/api/device_permissions_prompt.cc | 2 + extensions/browser/api/hid/hid_device_manager.cc | 2 + extensions/browser/guest_view/web_view/web_view_guest.cc | 1 + extensions/renderer/bindings/api_binding_util.cc | 2 + third_party/blink/public/mojom/payments/payment_request.mojom | 3 + third_party/blink/renderer/modules/payments/payment_request.cc | 2 + third_party/skia/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp | 1 + tools/grit/grit/tool/build.py | 2 + ui/android/window_android.cc | 28 + ui/android/window_android.h | 17 + ui/base/dragdrop/os_exchange_data.h | 4 + ui/base/dragdrop/os_exchange_data_provider.h | 6 + ui/base/dragdrop/os_exchange_data_provider_factory.cc | 4 + ui/base/dragdrop/os_exchange_data_provider_non_backed.cc | 62 + ui/base/dragdrop/os_exchange_data_provider_non_backed.h | 18 + ui/events/event.h | 1 + ui/native_theme/native_theme_android.cc | 3 + ui/native_theme/native_theme_android.h | 2 + ui/views/bubble/bubble_dialog_delegate_view.cc | 12 + ui/views/controls/menu/menu_controller.h | 1 + ui/views/controls/menu/menu_host.cc | 8 + ui/views/controls/menu/menu_host.h | 2 + ui/views/controls/menu/menu_pre_target_handler_aura.cc | 48 + ui/views/controls/menu/menu_pre_target_handler_aura.h | 37 + ui/views/controls/native/native_view_host_aura.cc | 373 --- + ui/views/controls/native/native_view_host_aura.h | 32 + ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc | 2 + ui/views/drag_utils_aura.cc | 13 + ui/views/event_monitor_aura.cc | 49 + ui/views/event_monitor_aura.h | 14 + ui/views/native_cursor_aura.cc | 11 + ui/views/painter.cc | 1 + ui/views/touchui/touch_selection_controller_impl.cc | 35 + ui/views/widget/native_widget_aura.cc | 975 +--------- + ui/views/widget/native_widget_aura.h | 104 - + ui/views/widget/tooltip_manager_aura.cc | 106 - + ui/views/widget/tooltip_manager_aura.h | 18 + ui/views/widget/widget.cc | 5 + weblayer/browser/browser_context_impl.cc | 2 + weblayer/browser/browser_context_impl.h | 2 + 290 files changed, 952 insertions(+), 3233 deletions(-) + +--- a/ui/base/dragdrop/os_exchange_data_provider_factory.cc ++++ b/ui/base/dragdrop/os_exchange_data_provider_factory.cc +@@ -22,6 +22,8 @@ + #include "ui/base/dragdrop/os_exchange_data_provider_win.h" + #endif + ++#include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h" ++ + namespace ui { + + namespace { +@@ -66,6 +68,8 @@ OSExchangeDataProviderFactory::CreatePro + // TODO(crbug.com/980371): Implement OSExchangeDataProvider for Fuchsia. + NOTIMPLEMENTED(); + return nullptr; ++#elif defined(OS_ANDROID) ++ return std::make_unique(); + #else + #error "Unknown operating system" + #endif +--- a/chrome/browser/media/router/media_router_feature.cc ++++ b/chrome/browser/media/router/media_router_feature.cc +@@ -22,13 +22,10 @@ + #include "media/base/media_switches.h" + #endif // defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS) + +-#if !defined(OS_ANDROID) + #include "components/prefs/pref_registry_simple.h" +-#endif + + namespace media_router { + +-#if !defined(OS_ANDROID) + #if !defined(OFFICIAL_BUILD) + // Enables the media router. Can be useful to disable for local + // development on Mac because DIAL local discovery opens a local port +@@ -47,7 +44,6 @@ const base::Feature kGlobalMediaControls + "GlobalMediaControlsCastStartStop", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kAllowAllSitesToInitiateMirroring{ + "AllowAllSitesToInitiateMirroring", base::FEATURE_DISABLED_BY_DEFAULT}; +-#endif // !defined(OS_ANDROID) + + #if defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS) + namespace { +@@ -82,7 +78,6 @@ bool MediaRouterEnabled(content::Browser + #endif // defined(OS_ANDROID) || BUILDFLAG(ENABLE_EXTENSIONS) + } + +-#if !defined(OS_ANDROID) + void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kMediaRouterCastAllowAllIPs, false, + PrefRegistry::PUBLIC); +@@ -136,6 +131,4 @@ bool GlobalMediaControlsCastStartStopEna + media::kGlobalMediaControlsOverlayControls); + } + +-#endif // !defined(OS_ANDROID) +- + } // namespace media_router +--- a/chrome/browser/media/router/media_router_feature.h ++++ b/chrome/browser/media/router/media_router_feature.h +@@ -19,8 +19,6 @@ namespace media_router { + // Returns true if Media Router is enabled for |context|. + bool MediaRouterEnabled(content::BrowserContext* context); + +-#if !defined(OS_ANDROID) +- + // TODO(crbug.com/1028753): Remove default-enabled kDialMediaRouteProvider after + // tests stop disabling it. + extern const base::Feature kDialMediaRouteProvider; +@@ -73,7 +71,6 @@ bool CastMediaRouteProviderEnabled(); + + // Returns true if global media controls are used to start and stop casting. + bool GlobalMediaControlsCastStartStopEnabled(); +-#endif // !defined(OS_ANDROID) + + } // namespace media_router + +--- a/chrome/browser/ui/browser.h ++++ b/chrome/browser/ui/browser.h +@@ -56,10 +56,6 @@ + #include "ui/gfx/geometry/rect.h" + #include "ui/shell_dialogs/select_file_dialog.h" + +-#if defined(OS_ANDROID) +-#error This file should only be included on desktop. +-#endif +- + class BackgroundContents; + class BrowserContentSettingBubbleModelDelegate; + class BrowserInstantController; +--- a/chrome/browser/ui/signin_view_controller.h ++++ b/chrome/browser/ui/signin_view_controller.h +@@ -21,10 +21,6 @@ + #include "chrome/browser/ui/webui/signin/signin_email_confirmation_dialog.h" + #endif + +-#if defined(OS_ANDROID) +-#error This file should only be included on desktop. +-#endif +- + class Browser; + struct CoreAccountId; + +--- a/chrome/browser/ui/tabs/tab_strip_model.h ++++ b/chrome/browser/ui/tabs/tab_strip_model.h +@@ -31,10 +31,6 @@ + #include "ui/base/models/list_selection_model.h" + #include "ui/base/page_transition_types.h" + +-#if defined(OS_ANDROID) +-#error This file should only be included on desktop. +-#endif +- + class Profile; + class TabGroupModel; + class TabStripModelDelegate; +--- a/extensions/browser/guest_view/web_view/web_view_guest.cc ++++ b/extensions/browser/guest_view/web_view/web_view_guest.cc +@@ -153,6 +153,7 @@ static std::string TerminationStatusToSt + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: + return "oom killed"; + #endif ++ case base::TERMINATION_STATUS_OOM_PROTECTED: + case base::TERMINATION_STATUS_OOM: + return "oom"; + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: +--- a/extensions/browser/api/device_permissions_prompt.cc ++++ b/extensions/browser/api/device_permissions_prompt.cc +@@ -223,8 +223,6 @@ class HidDevicePermissionsPrompt : publi + const auto& binder = GetHidManagerBinderOverride(); + if (binder) + binder.Run(std::move(receiver)); +- else +- content::GetDeviceService().BindHidManager(std::move(receiver)); + + hid_manager_->GetDevicesAndSetClient( + receiver_.BindNewEndpointAndPassRemote(), +--- a/extensions/browser/api/hid/hid_device_manager.cc ++++ b/extensions/browser/api/hid/hid_device_manager.cc +@@ -296,8 +296,6 @@ void HidDeviceManager::LazyInitialize() + const auto& binder = GetHidManagerBinderOverride(); + if (binder) + binder.Run(std::move(receiver)); +- else +- content::GetDeviceService().BindHidManager(std::move(receiver)); + } + // Enumerate HID devices and set client. + std::vector empty_devices; +--- a/ui/base/dragdrop/os_exchange_data.h ++++ b/ui/base/dragdrop/os_exchange_data.h +@@ -60,7 +60,7 @@ class COMPONENT_EXPORT(UI_BASE) OSExchan + #if defined(OS_WIN) + FILE_CONTENTS = 1 << 4, + #endif +-#if defined(USE_AURA) ++#if defined(USE_AURA) || defined(OS_ANDROID) + HTML = 1 << 5, + #endif + }; +@@ -179,7 +179,7 @@ class COMPONENT_EXPORT(UI_BASE) OSExchan + const; + #endif + +-#if defined(USE_AURA) ++#if defined(USE_AURA) || defined(OS_ANDROID) + // Adds a snippet of HTML. |html| is just raw html but this sets both + // text/html and CF_HTML. + void SetHtml(const base::string16& html, const GURL& base_url); +--- a/ui/views/controls/menu/menu_host.cc ++++ b/ui/views/controls/menu/menu_host.cc +@@ -31,7 +31,7 @@ namespace views { + + namespace internal { + +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + // This class adds itself as the pre target handler for the |window| + // passed in. It currently handles touch events and forwards them to the + // controller. Reason for this approach is views does not get raw touch +@@ -81,7 +81,7 @@ class PreMenuEventDispatchHandler : publ + #endif // OS_APPLE + + void TransferGesture(Widget* source, Widget* target) { +-#if defined(OS_APPLE) ++#if defined(OS_APPLE) || defined(OS_ANDROID) + NOTIMPLEMENTED(); + #else // !defined(OS_APPLE) + source->GetGestureRecognizer()->TransferEventsTo( +@@ -138,7 +138,7 @@ void MenuHost::InitMenuHost(Widget* pare + #endif + Init(std::move(params)); + +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + pre_dispatch_handler_ = + std::make_unique( + menu_controller, submenu_, GetNativeView()); +@@ -198,7 +198,7 @@ void MenuHost::DestroyMenuHost() { + HideMenuHost(); + destroying_ = true; + static_cast(GetRootView())->ClearSubmenu(); +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + pre_dispatch_handler_.reset(); + #endif + Close(); +--- a/ui/events/event.h ++++ b/ui/events/event.h +@@ -16,6 +16,7 @@ + #include "base/macros.h" + #include "base/strings/string16.h" + #include "base/time/time.h" ++#include "ui/android/window_android.h" + #include "ui/events/event_constants.h" + #include "ui/events/gesture_event_details.h" + #include "ui/events/gestures/gesture_types.h" +--- a/ui/views/controls/menu/menu_controller.h ++++ b/ui/views/controls/menu/menu_controller.h +@@ -18,6 +18,7 @@ + #include "base/memory/weak_ptr.h" + #include "base/timer/timer.h" + #include "build/build_config.h" ++#include "ui/android/window_android.h" + #include "ui/events/event.h" + #include "ui/events/event_constants.h" + #include "ui/events/platform/platform_event_dispatcher.h" +--- a/ui/views/controls/menu/menu_host.h ++++ b/ui/views/controls/menu/menu_host.h +@@ -95,7 +95,7 @@ class MenuHost : public Widget, public W + // If true and capture is lost we don't notify the delegate. + bool ignore_capture_lost_; + +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + // Handles raw touch events at the moment. + std::unique_ptr pre_dispatch_handler_; + #endif +--- a/ui/android/window_android.h ++++ b/ui/android/window_android.h +@@ -17,6 +17,7 @@ + #include "base/time/time.h" + #include "ui/android/ui_android_export.h" + #include "ui/android/view_android.h" ++#include "ui/events/event_target.h" + #include "ui/gfx/geometry/vector2d_f.h" + + namespace display { +@@ -33,7 +34,8 @@ class WindowAndroidObserver; + + // Android implementation of the activity window. + // WindowAndroid is also the root of a ViewAndroid tree. +-class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid { ++class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid, ++ public ui::EventTarget { + public: + static WindowAndroid* FromJavaWindowAndroid( + const base::android::JavaParamRef& jwindow_android); +@@ -50,6 +52,13 @@ class UI_ANDROID_EXPORT WindowAndroid : + + base::android::ScopedJavaLocalRef GetJavaObject(); + ++ static void ConvertPointToTarget(const WindowAndroid* source, ++ const WindowAndroid* target, ++ gfx::PointF* point); ++ static void ConvertPointToTarget(const WindowAndroid* source, ++ const WindowAndroid* target, ++ gfx::Point* point); ++ + // Compositor callback relay. + void OnCompositingDidCommit(); + +@@ -136,6 +145,12 @@ class UI_ANDROID_EXPORT WindowAndroid : + // ViewAndroid overrides. + WindowAndroid* GetWindowAndroid() const override; + ++ // Overridden from ui::EventTarget: ++ bool CanAcceptEvent(const ui::Event& event) override; ++ EventTarget* GetParentTarget() override; ++ std::unique_ptr GetChildIterator() const override; ++ ui::EventTargeter* GetEventTargeter() override; ++ + // The ID of the display that this window belongs to. + int display_id() const { return display_id_; } + +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -467,7 +467,7 @@ + #include "ui/accessibility/accessibility_features.h" + #endif // !defined(OS_CHROMEOS) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/badging/badge_manager.h" + #include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" + #include "chrome/browser/devtools/devtools_window.h" +@@ -1384,7 +1384,7 @@ ChromeContentBrowserClient::CreateBrowse + #elif defined(OS_LINUX) && !defined(OS_CHROMEOS) + main_parts->AddParts( + std::make_unique()); +-#else ++ + main_parts->AddParts(std::make_unique()); + #endif + #endif +--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.h ++++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.h +@@ -13,8 +13,6 @@ + #include "base/compiler_specific.h" + #include "base/macros.h" + #include "chrome/browser/devtools/device/devtools_device_discovery.h" +-#include "chrome/browser/devtools/protocol/forward.h" +-#include "chrome/browser/devtools/protocol/protocol.h" + #include "content/public/browser/devtools_agent_host_observer.h" + #include "content/public/browser/devtools_manager_delegate.h" + #include "net/base/host_port_pair.h" +--- a/chrome/browser/search/instant_service.h ++++ b/chrome/browser/search/instant_service.h +@@ -33,7 +33,7 @@ + #include "ui/native_theme/native_theme_observer.h" + #include "url/gurl.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/search/instant_service_factory.h ++++ b/chrome/browser/search/instant_service_factory.h +@@ -10,7 +10,7 @@ + #include "build/build_config.h" + #include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/browser_window.h ++++ b/chrome/browser/ui/browser_window.h +@@ -31,7 +31,7 @@ + #include "ui/gfx/native_widget_types.h" + #include "url/origin.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error This file should only be included on desktop. + #endif + +--- a/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc ++++ b/chrome/browser/extensions/api/messaging/native_messaging_host_manifest.cc +@@ -136,19 +136,6 @@ bool NativeMessagingHostManifest::Parse( + allowed_origins_.AddPattern(pattern); + } + +- if (base::FeatureList::IsEnabled(features::kOnConnectNative)) { +- if (const base::Value* supports_native_initiated_connections = +- dictionary->FindKey("supports_native_initiated_connections")) { +- if (!supports_native_initiated_connections->is_bool()) { +- *error_message = +- "supports_native_initiated_connections must be a boolean."; +- return false; +- } +- supports_native_initiated_connections_ = +- supports_native_initiated_connections->GetBool(); +- } +- } +- + return true; + } + +--- a/chrome/browser/extensions/api/downloads/downloads_api.cc ++++ b/chrome/browser/extensions/api/downloads/downloads_api.cc +@@ -52,6 +52,7 @@ + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_list.h" + #include "chrome/browser/ui/browser_window.h" ++#include "chrome/browser/ui/tabs/tab_strip_model.h" + #include "chrome/common/extensions/api/downloads.h" + #include "components/download/public/common/download_interrupt_reasons.h" + #include "components/download/public/common/download_item.h" +--- a/chrome/browser/profiles/profile.cc ++++ b/chrome/browser/profiles/profile.cc +@@ -54,8 +54,8 @@ + #include "chrome/browser/profiles/android/jni_headers/OTRProfileID_jni.h" + #endif + +-#if !defined(OS_ANDROID) +-#include "chrome/browser/first_run/first_run.h" ++#if defined(OS_ANDROID) ++//#include "chrome/browser/first_run/first_run.h" + #include "content/public/browser/host_zoom_map.h" + #endif + +@@ -256,7 +256,7 @@ TestingProfile* Profile::AsTestingProfil + return nullptr; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + ChromeZoomLevelPrefs* Profile::GetZoomLevelPrefs() { + return nullptr; + } +@@ -311,7 +311,7 @@ void Profile::RegisterProfilePrefs(user_ + std::string()); + registry->RegisterStringPref(prefs::kAccessibilityCaptionsTextShadow, + std::string()); +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + registry->RegisterDictionaryPref(prefs::kPartitionDefaultZoomLevel); + registry->RegisterDictionaryPref(prefs::kPartitionPerHostZoomLevels); + #endif // !defined(OS_ANDROID) +@@ -508,7 +508,7 @@ bool ProfileCompare::operator()(Profile* + return a->GetOriginalProfile() < b->GetOriginalProfile(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + double Profile::GetDefaultZoomLevelForProfile() { + return GetDefaultStoragePartition(this) + ->GetHostZoomMap() +--- a/chrome/browser/profiles/profile.h ++++ b/chrome/browser/profiles/profile.h +@@ -26,7 +26,7 @@ + #include "base/android/scoped_java_ref.h" + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + class ChromeZoomLevelPrefs; + #endif + +@@ -297,7 +297,7 @@ class Profile : public content::BrowserC + virtual PrefService* GetPrefs() = 0; + virtual const PrefService* GetPrefs() const = 0; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Retrieves a pointer to the PrefService that manages the default zoom + // level and the per-host zoom levels for this user profile. + // TODO(wjmaclean): Remove this when HostZoomMap migrates to StoragePartition. +@@ -509,7 +509,7 @@ class Profile : public content::BrowserC + // ProfileDestroyer, but in tests, some are not. + void MaybeSendDestroyedNotification(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Convenience method to retrieve the default zoom level for the default + // storage partition. + double GetDefaultZoomLevelForProfile(); +--- a/chrome/browser/ui/browser_navigator_params.cc ++++ b/chrome/browser/ui/browser_navigator_params.cc +@@ -21,7 +21,7 @@ using content::GlobalRequestID; + using content::NavigationController; + using content::WebContents; + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + NavigateParams::NavigateParams(std::unique_ptr contents_to_insert) + : contents_to_insert(std::move(contents_to_insert)) {} + #else +--- a/chrome/browser/ui/browser_navigator_params.h ++++ b/chrome/browser/ui/browser_navigator_params.h +@@ -26,7 +26,7 @@ + #include "ui/gfx/geometry/rect.h" + #include "url/gurl.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/tabs/tab_strip_model.h" + #include "components/tab_groups/tab_group_id.h" + #endif +@@ -64,7 +64,7 @@ struct OpenURLParams; + + // TODO(thestig): Split or ifdef out more fields that are not used on Android. + struct NavigateParams { +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + explicit NavigateParams( + std::unique_ptr contents_to_insert); + #else +@@ -222,7 +222,7 @@ struct NavigateParams { + }; + PathBehavior path_behavior = RESPECT; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // [in] Specifies a Browser object where the navigation could occur or the + // tab could be added. Navigate() is not obliged to use this Browser if + // it is not compatible with the operation being performed. This can be +--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc ++++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc +@@ -195,25 +195,7 @@ void SafeBrowsingPrivateEventRouter::OnP + event_router_->BroadcastEvent(std::move(extension_event)); + } + +- if (!IsRealtimeReportingEnabled()) +- return; +- +- ReportRealtimeEvent( +- kKeyPasswordReuseEvent, +- base::BindOnce( +- [](const std::string& url, const std::string& user_name, +- const bool is_phishing_url, const std::string& profile_user_name) { +- // Convert |params| to a real-time event dictionary +- // and report it. +- base::Value event(base::Value::Type::DICTIONARY); +- event.SetStringKey(kKeyUrl, url); +- event.SetStringKey(kKeyUserName, user_name); +- event.SetBoolKey(kKeyIsPhishingUrl, is_phishing_url); +- event.SetStringKey(kKeyProfileUserName, profile_user_name); +- return event; +- }, +- params.url, params.user_name, params.is_phishing_url, +- GetProfileUserName())); ++ return; + } + + void SafeBrowsingPrivateEventRouter::OnPolicySpecifiedPasswordChanged( +--- a/chrome/common/pref_names.cc ++++ b/chrome/common/pref_names.cc +@@ -1212,7 +1212,7 @@ const char kAccessibilityFocusHighlightE + "settings.a11y.focus_highlight"; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Whether the Live Caption feature is enabled. + const char kLiveCaptionEnabled[] = + "accessibility.captions.live_caption_enabled"; +@@ -1258,7 +1258,7 @@ const char kContentSettingsPluginWhiteli + "profile.content_settings.plugin_whitelist"; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Double that indicates the default zoom level. + const char kPartitionDefaultZoomLevel[] = "partition.default_zoom_level"; + +@@ -1562,7 +1562,7 @@ const char kWebRtcLocalIpsAllowedUrls[] + const char kWebRTCAllowLegacyTLSProtocols[] = + "webrtc.allow_legacy_tls_protocols"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Whether or not this profile has been shown the Welcome page. + const char kHasSeenWelcomePage[] = "browser.has_seen_welcome_page"; + #endif +@@ -1778,7 +1778,7 @@ const char kShutdownNumProcessesSlow[] = + // before shutting everything down. + const char kRestartLastSessionOnShutdown[] = "restart.last.session.on.shutdown"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #if !defined(OS_CHROMEOS) + // Pref name for the policy controlling presentation of full-tab promotional + // and/or educational content. +@@ -1821,7 +1821,6 @@ const char kNtpCollapsedSnapshotDocument + + // Keeps track of sync promo collapsed state in the Other Devices menu. + const char kNtpCollapsedSyncPromo[] = "ntp.collapsed_sync_promo"; +-#else + // Holds info for New Tab Page custom background + const char kNtpCustomBackgroundDict[] = "ntp.custom_background_dict"; + const char kNtpCustomBackgroundLocalToDevice[] = +@@ -1889,7 +1888,7 @@ const char kDevToolsTCPDiscoveryConfig[] + // A dictionary with generic DevTools settings. + const char kDevToolsPreferences[] = "devtools.preferences"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Tracks the number of times the dice signin promo has been shown in the user + // menu. + const char kDiceSigninUserMenuPromoCount[] = "sync_promo.user_menu_show_count"; +@@ -2442,13 +2441,13 @@ const char kSystemTimezoneAutomaticDetec + + // Pref name for the policy controlling whether to enable Media Router. + const char kEnableMediaRouter[] = "media_router.enable_media_router"; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Pref name for the policy controlling whether to force the Cast icon to be + // shown in the toolbar/overflow menu. + const char kShowCastIconInToolbar[] = "media_router.show_cast_icon_in_toolbar"; + #endif // !defined(OS_ANDROID) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Pref name for the policy controlling the way in which users are notified of + // the need to relaunch the browser for a pending update. + const char kRelaunchNotification[] = "browser.relaunch_notification"; +@@ -2565,7 +2564,7 @@ const char kCustomHandlersEnabled[] = "c + // by the cloud policy subsystem. + const char kDevicePolicyRefreshRate[] = "policy.device_refresh_rate"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // A boolean where true means that the browser has previously attempted to + // enable autoupdate and failed, so the next out-of-date browser start should + // not prompt the user to enable autoupdate, it should offer to reinstall Chrome +@@ -2725,7 +2724,7 @@ const char kRecoveryComponentNeedsElevat + const char kRegisteredSupervisedUserWhitelists[] = + "supervised_users.whitelists"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Boolean that indicates whether Chrome enterprise extension request is enabled + // or not. + const char kCloudExtensionRequestEnabled[] = +@@ -2944,7 +2943,7 @@ const char kIsolateOrigins[] = "site_iso + // Boolean that specifies opting into --site-per-process (full Site Isolation). + const char kSitePerProcess[] = "site_isolation.site_per_process"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Boolean that specifies whether media (audio/video) autoplay is allowed. + const char kAutoplayAllowed[] = "media.autoplay_allowed"; + +@@ -3017,7 +3016,7 @@ const char kSharingVapidKey[] = "sharing + const char kSharingFCMRegistration[] = "sharing.fcm_registration"; + const char kSharingLocalSharingInfo[] = "sharing.local_sharing_info"; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Dictionary that contains all of the Hats Survey Metadata. + const char kHatsSurveyMetadata[] = "hats.survey_metadata"; + #endif // !defined(OS_ANDROID) +@@ -3084,7 +3083,7 @@ const char kAdbSideloadingPowerwashOnNex + "adb_sideloading_powerwash_on_next_reboot_notification_shown"; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Boolean pref that indicates whether caret browsing is currently enabled. + const char kCaretBrowsingEnabled[] = "settings.a11y.caretbrowsing.enabled"; + +--- a/chrome/common/pref_names.h ++++ b/chrome/common/pref_names.h +@@ -191,7 +191,7 @@ extern const char kAccessibilityCaptions + extern const char kAccessibilityCaptionsBackgroundColor[]; + extern const char kAccessibilityCaptionsTextShadow[]; + extern const char kAccessibilityCaptionsBackgroundOpacity[]; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kLiveCaptionEnabled[]; + extern const char kLiveCaptionLanguageCode[]; + extern const char kSodaBinaryPath[]; +@@ -390,7 +390,7 @@ extern const char kUseCustomChromeFrame[ + #if BUILDFLAG(ENABLE_PLUGINS) + extern const char kContentSettingsPluginWhitelist[]; + #endif +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kPartitionDefaultZoomLevel[]; + extern const char kPartitionPerHostZoomLevels[]; + +@@ -504,7 +504,7 @@ extern const char kWebRtcEventLogCollect + extern const char kWebRtcLocalIpsAllowedUrls[]; + extern const char kWebRTCAllowLegacyTLSProtocols[]; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kHasSeenWelcomePage[]; + #endif + +@@ -590,7 +590,7 @@ extern const char kShutdownNumProcesses[ + extern const char kShutdownNumProcessesSlow[]; + + extern const char kRestartLastSessionOnShutdown[]; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #if !defined(OS_CHROMEOS) + extern const char kPromotionalTabsEnabled[]; + extern const char kCommandLineFlagSecurityWarningsEnabled[]; +@@ -607,7 +607,6 @@ extern const char kNtpCollapsedForeignSe + extern const char kNtpCollapsedRecentlyClosedTabs[]; + extern const char kNtpCollapsedSnapshotDocument[]; + extern const char kNtpCollapsedSyncPromo[]; +-#else + extern const char kNtpCustomBackgroundDict[]; + extern const char kNtpCustomBackgroundLocalToDevice[]; + extern const char kNtpModulesVisible[]; +@@ -633,7 +632,7 @@ extern const char kDevToolsPreferences[] + extern const char kDevToolsDiscoverTCPTargetsEnabled[]; + extern const char kDevToolsTCPDiscoveryConfig[]; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kDiceSigninUserMenuPromoCount[]; + #endif + +@@ -840,11 +839,11 @@ extern const char kSystemTimezoneAutomat + #endif // defined(OS_CHROMEOS) + + extern const char kEnableMediaRouter[]; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kShowCastIconInToolbar[]; + #endif // !defined(OS_ANDROID) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kRelaunchNotification[]; + extern const char kRelaunchNotificationPeriod[]; + #endif // !defined(OS_ANDROID) +@@ -853,7 +852,7 @@ extern const char kRelaunchNotificationP + extern const char kRelaunchHeadsUpPeriod[]; + #endif // defined(OS_CHROMEOS) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kAttemptedToEnableAutoupdate[]; + + extern const char kMediaGalleriesUniqueId[]; +@@ -911,7 +910,7 @@ extern const char kRecoveryComponentNeed + + extern const char kRegisteredSupervisedUserWhitelists[]; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kCloudExtensionRequestEnabled[]; + extern const char kCloudExtensionRequestIds[]; + #endif +@@ -1008,7 +1007,7 @@ extern const char kUnsafelyTreatInsecure + extern const char kIsolateOrigins[]; + extern const char kSitePerProcess[]; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kAutoplayAllowed[]; + extern const char kAutoplayWhitelist[]; + extern const char kBlockAutoplayEnabled[]; +@@ -1046,7 +1045,7 @@ extern const char kSharingVapidKey[]; + extern const char kSharingFCMRegistration[]; + extern const char kSharingLocalSharingInfo[]; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kHatsSurveyMetadata[]; + #endif // !defined(OS_ANDROID) + +@@ -1078,7 +1077,7 @@ extern const char kAdbSideloadingPowerwa + extern const char kAdbSideloadingPowerwashOnNextRebootNotificationShown[]; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kCaretBrowsingEnabled[]; + extern const char kShowCaretBrowsingDialog[]; + #endif +--- a/chrome/browser/extensions/api/tabs/windows_event_router.cc ++++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc +@@ -164,8 +164,6 @@ WindowsEventRouter::WindowsEventRouter(P + content::NotificationService::AllSources()); + #elif defined(TOOLKIT_VIEWS) + views::WidgetFocusManager::GetInstance()->AddFocusChangeListener(this); +-#else +-#error Unsupported + #endif + + AppWindowRegistry* registry = AppWindowRegistry::Get(profile_); +--- a/chrome/common/chrome_features.cc ++++ b/chrome/common/chrome_features.cc +@@ -63,7 +63,7 @@ const base::Feature kAppActivityReportin + base::FEATURE_ENABLED_BY_DEFAULT}; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // App Service related flags. See components/services/app_service/README.md. + const base::Feature kAppServiceAdaptiveIcon{"AppServiceAdaptiveIcon", + base::FEATURE_DISABLED_BY_DEFAULT}; +@@ -226,7 +226,7 @@ const base::Feature kDMServerOAuthForChi + "DMServerOAuthForChildUser", base::FEATURE_ENABLED_BY_DEFAULT}; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Whether to allow installed-by-default web apps to be installed or not. + const base::Feature kDefaultWebAppInstallation{ + "DefaultWebAppInstallation", base::FEATURE_ENABLED_BY_DEFAULT}; +@@ -518,7 +518,7 @@ const base::Feature kInstallableAmbientB + "InstallableAmbientBadgeInfoBar", base::FEATURE_ENABLED_BY_DEFAULT}; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Support sharing in Chrome OS intent handling. + const base::Feature kIntentHandlingSharing{"IntentHandlingSharing", + base::FEATURE_DISABLED_BY_DEFAULT}; +@@ -610,7 +610,7 @@ const base::Feature kNtlmV2Enabled{"Ntlm + base::FEATURE_ENABLED_BY_DEFAULT}; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + const base::Feature kOnConnectNative{"OnConnectNative", + base::FEATURE_DISABLED_BY_DEFAULT}; + #endif +--- a/chrome/common/chrome_features.h ++++ b/chrome/common/chrome_features.h +@@ -64,7 +64,7 @@ COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kAppActivityReporting; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kAppServiceAdaptiveIcon; + COMPONENT_EXPORT(CHROME_FEATURES) +@@ -161,7 +161,7 @@ COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kDMServerOAuthForChildUser; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kDefaultWebAppInstallation; + #endif +@@ -282,7 +282,7 @@ COMPONENT_EXPORT(CHROME_FEATURES) extern + + COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kGeoLanguage; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kHappinessTrackingSurveysForDesktop; + +@@ -338,7 +338,7 @@ COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kInstallableAmbientBadgeInfoBar; + #endif // defined(OS_ANDROID) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + COMPONENT_EXPORT(CHROME_FEATURES) + extern const base::Feature kIntentHandlingSharing; + COMPONENT_EXPORT(CHROME_FEATURES) +@@ -400,7 +400,7 @@ extern const base::Feature kNotification + COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNtlmV2Enabled; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kOnConnectNative; + #endif + +--- a/chrome/common/chrome_paths.cc ++++ b/chrome/common/chrome_paths.cc +@@ -503,7 +503,7 @@ bool PathProvider(int key, base::FilePat + #endif + break; + +-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) ++#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_ANDROID) + case chrome::DIR_NATIVE_MESSAGING: + #if defined(OS_MAC) + #if BUILDFLAG(GOOGLE_CHROME_BRANDING) +--- a/chrome/common/chrome_paths.h ++++ b/chrome/common/chrome_paths.h +@@ -116,7 +116,7 @@ enum { + DIR_SUPERVISED_USER_INSTALLED_WHITELISTS, // Directory where sanitized + // supervised user whitelists are + // installed. +-#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) ++#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || defined(OS_ANDROID) + DIR_NATIVE_MESSAGING, // System directory where native messaging host + // manifest files are stored. + DIR_USER_NATIVE_MESSAGING, // Directory with Native Messaging Hosts +--- a/chrome/browser/profiles/profile_window.h ++++ b/chrome/browser/profiles/profile_window.h +@@ -14,9 +14,6 @@ + #include "chrome/browser/ui/profile_chooser_constants.h" + #include "chrome/browser/ui/startup/startup_types.h" + +-#if defined(OS_ANDROID) +-#error "Not used on Android" +-#endif + + class Profile; + +--- a/chrome/browser/profiles/profiles_state.cc ++++ b/chrome/browser/profiles/profiles_state.cc +@@ -32,7 +32,7 @@ + #include "content/public/browser/browsing_data_remover.h" + #include "ui/base/l10n/l10n_util.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser.h" + #endif + +@@ -95,7 +95,7 @@ void SetLastUsedProfile(const std::strin + local_state->SetString(prefs::kProfileLastUsed, profile_dir); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + base::string16 GetAvatarNameForProfile(const base::FilePath& profile_path) { + if (profile_path == ProfileManager::GetGuestProfilePath()) { + return l10n_util::GetStringUTF16(IDS_GUEST_PROFILE_NAME); +--- a/chrome/browser/profiles/profiles_state.h ++++ b/chrome/browser/profiles/profiles_state.h +@@ -47,7 +47,7 @@ void RegisterPrefs(PrefRegistrySimple* r + // System Profile directory, which is an invalid last used profile. + void SetLastUsedProfile(const std::string& profile_dir); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Returns the display name of the specified on-the-record profile (or guest), + // specified by |profile_path|, used in the avatar button or user manager. If + // |profile_path| is the guest path, it will return IDS_GUEST_PROFILE_NAME. If +--- a/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc ++++ b/ui/views/controls/webview/unhandled_keyboard_event_handler_default.cc +@@ -13,7 +13,7 @@ namespace views { + bool UnhandledKeyboardEventHandler::HandleNativeKeyboardEvent( + gfx::NativeEvent event, + FocusManager* focus_manager) { +- return !focus_manager->OnKeyEvent(*(event->AsKeyEvent())); ++ return false; + } + + } // namespace views +--- a/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc ++++ b/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc +@@ -100,15 +100,6 @@ MediaCaptureDevicesDispatcher::MediaCapt + media_access_handlers_.push_back( + std::make_unique()); + #endif +- media_access_handlers_.push_back( +- std::make_unique()); +-#if defined(OS_CHROMEOS) +- // Wrapper around TabCaptureAccessHandler used in Public Sessions. +- media_access_handlers_.push_back( +- std::make_unique()); +-#else +- media_access_handlers_.push_back(std::make_unique()); +-#endif + #endif + media_access_handlers_.push_back( + std::make_unique()); +--- a/chrome/browser/ui/browser_commands.cc ++++ b/chrome/browser/ui/browser_commands.cc +@@ -93,6 +93,7 @@ + #include "components/services/app_service/public/mojom/types.mojom.h" + #include "components/sessions/core/live_tab_context.h" + #include "components/sessions/core/tab_restore_service.h" ++#include "components/signin/public/base/signin_metrics.h" + #include "components/tab_groups/tab_group_id.h" + #include "components/tab_groups/tab_group_visual_data.h" + #include "components/translate/core/browser/language_state.h" +--- a/ui/native_theme/native_theme_android.cc ++++ b/ui/native_theme/native_theme_android.cc +@@ -22,8 +22,7 @@ NativeTheme* NativeTheme::GetInstanceFor + } + + NativeTheme* NativeTheme::GetInstanceForNativeUi() { +- NOTREACHED(); +- return nullptr; ++ return NativeThemeAndroid::instance(); + } + #endif + +--- a/ui/native_theme/native_theme_android.h ++++ b/ui/native_theme/native_theme_android.h +@@ -20,11 +20,11 @@ class NativeThemeAndroid : public Native + const ExtraParams& extra) const override; + SkColor GetSystemColor(ColorId color_id, + ColorScheme color_scheme) const override; ++ static NativeThemeAndroid* instance(); + + protected: + friend class NativeTheme; + friend class base::NoDestructor; +- static NativeThemeAndroid* instance(); + + // NativeThemeBase: + void AdjustCheckboxRadioRectForPadding(SkRect* rect) const override; +--- a/content/browser/storage_partition_impl.h ++++ b/content/browser/storage_partition_impl.h +@@ -58,7 +58,7 @@ + #include "storage/browser/quota/special_storage_policy.h" + #include "third_party/blink/public/mojom/dom_storage/dom_storage.mojom.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "content/browser/host_zoom_level_context.h" + #endif + +@@ -151,7 +151,7 @@ class CONTENT_EXPORT StoragePartitionImp + DevToolsBackgroundServicesContextImpl* GetDevToolsBackgroundServicesContext() + override; + ContentIndexContextImpl* GetContentIndexContext() override; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + HostZoomMap* GetHostZoomMap() override; + HostZoomLevelContext* GetHostZoomLevelContext() override; + ZoomLevelDelegate* GetZoomLevelDelegate() override; +@@ -502,7 +502,7 @@ class CONTENT_EXPORT StoragePartitionImp + std::unique_ptr shared_worker_service_; + std::unique_ptr push_messaging_context_; + scoped_refptr special_storage_policy_; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + host_zoom_level_context_; + #endif // !defined(OS_ANDROID) +--- a/content/public/browser/storage_partition.h ++++ b/content/public/browser/storage_partition.h +@@ -67,7 +67,7 @@ class PlatformNotificationContext; + class ServiceWorkerContext; + class SharedWorkerService; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + class HostZoomLevelContext; + class HostZoomMap; + class ZoomLevelDelegate; +@@ -132,7 +132,7 @@ class CONTENT_EXPORT StoragePartition { + virtual DevToolsBackgroundServicesContext* + GetDevToolsBackgroundServicesContext() = 0; + virtual ContentIndexContext* GetContentIndexContext() = 0; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + virtual HostZoomMap* GetHostZoomMap() = 0; + virtual HostZoomLevelContext* GetHostZoomLevelContext() = 0; + virtual ZoomLevelDelegate* GetZoomLevelDelegate() = 0; +--- a/content/browser/web_contents/web_contents_impl.cc ++++ b/content/browser/web_contents/web_contents_impl.cc +@@ -197,7 +197,6 @@ + #include "content/browser/web_contents/web_contents_android.h" + #include "services/device/public/mojom/nfc.mojom.h" + #include "ui/android/view_android.h" +-#else // !OS_ANDROID + #include "content/browser/host_zoom_map_impl.h" + #endif // OS_ANDROID + +@@ -1485,7 +1484,7 @@ FindRequestManager* WebContentsImpl::Get + return GetFindRequestManager(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void WebContentsImpl::UpdateZoom() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::UpdateZoom"); + RenderWidgetHostImpl* rwh = GetRenderViewHost()->GetWidget(); +--- a/content/browser/web_contents/web_contents_impl.h ++++ b/content/browser/web_contents/web_contents_impl.h +@@ -274,7 +274,7 @@ class CONTENT_EXPORT WebContentsImpl : p + // bitmap. + void AddAccessibilityMode(ui::AXMode mode); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Sets the zoom level for frames associated with this WebContents. + void UpdateZoom(); + +--- a/content/browser/storage_partition_impl.cc ++++ b/content/browser/storage_partition_impl.cc +@@ -1233,7 +1233,7 @@ void StoragePartitionImpl::Initialize( + push_messaging_context_ = std::make_unique( + browser_context_, service_worker_context_); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + host_zoom_level_context_.reset(new HostZoomLevelContext( + browser_context_->CreateZoomLevelDelegate(partition_path_))); + #endif // !defined(OS_ANDROID) +@@ -1494,7 +1494,7 @@ SharedWorkerServiceImpl* StoragePartitio + return shared_worker_service_.get(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + HostZoomMap* StoragePartitionImpl::GetHostZoomMap() { + DCHECK(initialized_); + DCHECK(host_zoom_level_context_.get()); +--- a/content/public/browser/browser_context.h ++++ b/content/public/browser/browser_context.h +@@ -27,7 +27,7 @@ + #include "third_party/blink/public/mojom/push_messaging/push_messaging.mojom-forward.h" + #include "third_party/blink/public/mojom/push_messaging/push_messaging_status.mojom-forward.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "content/public/browser/zoom_level_delegate.h" + #endif + +@@ -241,7 +241,7 @@ class CONTENT_EXPORT BrowserContext : pu + // destroyed soon and no new references to this object should be created. + bool ShutdownStarted() { return was_notify_will_be_destroyed_called_; } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Creates a delegate to initialize a HostZoomMap and persist its information. + // This is called during creation of each StoragePartition. + virtual std::unique_ptr CreateZoomLevelDelegate( +--- a/chrome/browser/profiles/profile_impl.cc ++++ b/chrome/browser/profiles/profile_impl.cc +@@ -189,7 +189,6 @@ + + #if defined(OS_ANDROID) + #include "chrome/browser/android/profile_key_startup_accessor.h" +-#else + #include "components/zoom/zoom_event_manager.h" + #include "content/public/common/page_zoom.h" + #endif +@@ -825,7 +824,7 @@ std::string ProfileImpl::GetProfileUserN + return std::string(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + ProfileImpl::CreateZoomLevelDelegate(const base::FilePath& partition_path) { + return std::make_unique( +@@ -1107,7 +1106,7 @@ const PrefService* ProfileImpl::GetPrefs + return prefs_.get(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + ChromeZoomLevelPrefs* ProfileImpl::GetZoomLevelPrefs() { + return static_cast( + GetDefaultStoragePartition(this)->GetZoomLevelDelegate()); +--- a/chrome/browser/profiles/profile_impl.h ++++ b/chrome/browser/profiles/profile_impl.h +@@ -27,7 +27,7 @@ + #include "content/public/browser/content_browser_client.h" + #include "extensions/buildflags/buildflags.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" + #include "content/public/browser/host_zoom_map.h" + #endif +@@ -74,7 +74,7 @@ class ProfileImpl : public Profile { + static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + + // content::BrowserContext implementation: +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + #endif +@@ -133,7 +133,7 @@ class ProfileImpl : public Profile { + ExtensionSpecialStoragePolicy* GetExtensionSpecialStoragePolicy() override; + PrefService* GetPrefs() override; + const PrefService* GetPrefs() const override; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + ChromeZoomLevelPrefs* GetZoomLevelPrefs() override; + #endif + // TODO(https://crbug.com/1060940, https://crbug.com/1065444): Only supports +--- a/content/shell/browser/shell_browser_context.cc ++++ b/content/shell/browser/shell_browser_context.cc +@@ -135,7 +135,7 @@ void ShellBrowserContext::FinishInitWhil + SimpleKeyMap::GetInstance()->Associate(this, key_.get()); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr ShellBrowserContext::CreateZoomLevelDelegate( + const base::FilePath&) { + return std::unique_ptr(); +--- a/content/shell/browser/shell_browser_context.h ++++ b/content/shell/browser/shell_browser_context.h +@@ -25,7 +25,7 @@ class ClientHintsControllerDelegate; + class DownloadManagerDelegate; + class PermissionControllerDelegate; + class ShellDownloadManagerDelegate; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + class ZoomLevelDelegate; + #endif // !defined(OS_ANDROID) + +@@ -44,7 +44,7 @@ class ShellBrowserContext : public Brows + + // BrowserContext implementation. + base::FilePath GetPath() override; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + #endif // !defined(OS_ANDROID) +--- a/chromecast/browser/cast_browser_context.cc ++++ b/chromecast/browser/cast_browser_context.cc +@@ -78,7 +78,7 @@ void CastBrowserContext::InitWhileIOAllo + #endif // defined(OS_ANDROID) + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + CastBrowserContext::CreateZoomLevelDelegate( + const base::FilePath& partition_path) { +--- a/chromecast/browser/cast_browser_context.h ++++ b/chromecast/browser/cast_browser_context.h +@@ -25,7 +25,7 @@ class CastBrowserContext final : public + ~CastBrowserContext() override; + + // BrowserContext implementation: +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + #endif // !defined(OS_ANDROID) +--- a/chrome/browser/profiles/off_the_record_profile_impl.cc ++++ b/chrome/browser/profiles/off_the_record_profile_impl.cc +@@ -73,7 +73,6 @@ + + #if defined(OS_ANDROID) + #include "components/prefs/scoped_user_pref_update.h" +-#else // !defined(OS_ANDROID) + #include "chrome/browser/ui/zoom/chrome_zoom_level_otr_delegate.h" + #include "components/zoom/zoom_event_manager.h" + #include "content/public/browser/host_zoom_map.h" +@@ -107,7 +106,7 @@ + + using content::BrowserThread; + using content::DownloadManagerDelegate; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + using content::HostZoomMap; + #endif + +@@ -228,7 +227,7 @@ OffTheRecordProfileImpl::~OffTheRecordPr + } + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void OffTheRecordProfileImpl::TrackZoomLevelsFromParent() { + // Here we only want to use zoom levels stored in the main-context's default + // storage partition. We're not interested in zoom levels in special +@@ -270,7 +269,7 @@ base::Time OffTheRecordProfileImpl::GetC + return start_time_; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + OffTheRecordProfileImpl::CreateZoomLevelDelegate( + const base::FilePath& partition_path) { +@@ -627,7 +626,7 @@ std::unique_ptr Profile::Create + return std::move(profile); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void OffTheRecordProfileImpl::OnParentZoomLevelChanged( + const HostZoomMap::ZoomLevelChange& change) { + HostZoomMap* host_zoom_map = HostZoomMap::GetDefaultForBrowserContext(this); +--- a/chrome/browser/profiles/off_the_record_profile_impl.h ++++ b/chrome/browser/profiles/off_the_record_profile_impl.h +@@ -16,7 +16,7 @@ + #include "components/domain_reliability/clear_mode.h" + #include "content/public/browser/content_browser_client.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" + #include "content/public/browser/host_zoom_map.h" + #endif +@@ -95,7 +95,7 @@ class OffTheRecordProfileImpl : public P + base::FilePath GetPath() override; + base::FilePath GetPath() const override; + base::Time GetCreationTime() const override; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath& partition_path) override; + #endif // !defined(OS_ANDROID) +@@ -130,12 +130,12 @@ class OffTheRecordProfileImpl : public P + void RecordMainFrameNavigation() override; + + private: +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Allows a profile to track changes in zoom levels in its parent profile. + void TrackZoomLevelsFromParent(); + #endif // !defined(OS_ANDROID) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Callback function for tracking parent's zoom level changes. + void OnParentZoomLevelChanged( + const content::HostZoomMap::ZoomLevelChange& change); +@@ -149,7 +149,7 @@ class OffTheRecordProfileImpl : public P + + std::unique_ptr prefs_; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr track_zoom_subscription_; + std::unique_ptr + parent_default_zoom_level_subscription_; +--- a/weblayer/browser/browser_context_impl.cc ++++ b/weblayer/browser/browser_context_impl.cc +@@ -136,7 +136,7 @@ base::FilePath BrowserContextImpl::GetDe + return download_dir; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + BrowserContextImpl::CreateZoomLevelDelegate(const base::FilePath&) { + return nullptr; +--- a/weblayer/browser/browser_context_impl.h ++++ b/weblayer/browser/browser_context_impl.h +@@ -37,7 +37,7 @@ class BrowserContextImpl : public conten + static base::FilePath GetDefaultDownloadDirectory(); + + // BrowserContext implementation: +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr CreateZoomLevelDelegate( + const base::FilePath&) override; + #endif // !defined(OS_ANDROID) +--- a/ui/views/widget/widget.cc ++++ b/ui/views/widget/widget.cc +@@ -187,6 +187,11 @@ Widget::~Widget() { + } + + // static ++const ui::NativeTheme* Widget::GetNativeTheme() const { ++ return ui::NativeTheme::GetInstanceForNativeUi(); ++} ++ ++// static + Widget* Widget::CreateWindowWithParent(WidgetDelegate* delegate, + gfx::NativeView parent, + const gfx::Rect& bounds) { +--- a/chrome/browser/ui/browser_dialogs.cc ++++ b/chrome/browser/ui/browser_dialogs.cc +@@ -38,7 +38,7 @@ void ShowWindowNamePromptForTesting(Brow + + } // namespace chrome + +-#if !defined(TOOLKIT_VIEWS) ++#if defined(TOOLKIT_VIEWS) + // There's no dialog version of this available outside views, run callback as if + // the dialog was instantly accepted. + void ShowFolderUploadConfirmationDialog( +--- a/chrome/browser/search/instant_service_observer.h ++++ b/chrome/browser/search/instant_service_observer.h +@@ -9,7 +9,7 @@ + + #include "build/build_config.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/search/local_ntp_source.h ++++ b/chrome/browser/search/local_ntp_source.h +@@ -26,7 +26,7 @@ + #include "components/prefs/pref_registry_simple.h" + #include "content/public/browser/url_data_source.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/search/most_visited_iframe_source.h ++++ b/chrome/browser/search/most_visited_iframe_source.h +@@ -9,7 +9,7 @@ + #include "build/build_config.h" + #include "content/public/browser/url_data_source.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/browser_instant_controller.h ++++ b/chrome/browser/ui/browser_instant_controller.h +@@ -13,7 +13,7 @@ + #include "chrome/browser/search/search_engine_base_url_tracker.h" + #include "chrome/browser/ui/search/instant_controller.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/search/instant_controller.h ++++ b/chrome/browser/ui/search/instant_controller.h +@@ -12,7 +12,7 @@ + #include "build/build_config.h" + #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/search/search_ipc_router.h ++++ b/chrome/browser/ui/search/search_ipc_router.h +@@ -22,7 +22,7 @@ + #include "content/public/browser/web_contents_observer.h" + #include "mojo/public/cpp/bindings/associated_receiver.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/search/search_tab_helper.h ++++ b/chrome/browser/ui/search/search_tab_helper.h +@@ -31,7 +31,7 @@ + #include "content/public/browser/web_contents_user_data.h" + #include "ui/shell_dialogs/select_file_dialog.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h ++++ b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.h +@@ -28,6 +28,7 @@ class RegisterProtocolHandlerPermissionR + private: + // permissions::PermissionRequest: + IconId GetIconId() const override; ++ base::string16 GetMessageText() const override; + base::string16 GetMessageTextFragment() const override; + GURL GetOrigin() const override; + void PermissionGranted(bool is_one_time) override; +--- a/chrome/browser/download/download_ui_model.cc ++++ b/chrome/browser/download/download_ui_model.cc +@@ -22,7 +22,7 @@ + #include "ui/base/l10n/time_format.h" + #include "ui/base/text/bytes_formatting.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser.h" + #endif + +@@ -505,7 +505,7 @@ bool DownloadUIModel::ShouldPromoteOrigi + return false; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + bool DownloadUIModel::IsCommandEnabled( + const DownloadCommands* download_commands, + DownloadCommands::Command command) const { +--- a/chrome/browser/download/download_ui_model.h ++++ b/chrome/browser/download/download_ui_model.h +@@ -19,7 +19,7 @@ + #include "components/safe_browsing/buildflags.h" + #include "components/safe_browsing/core/proto/download_file_types.pb.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/download/download_commands.h" + #endif + +@@ -289,7 +289,7 @@ class DownloadUIModel { + // security reasons. + virtual bool ShouldPromoteOrigin() const; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Methods related to DownloadCommands. + // Returns whether the given download command is enabled for this download. + virtual bool IsCommandEnabled(const DownloadCommands* download_commands, +--- a/chrome/browser/download/download_commands.h ++++ b/chrome/browser/download/download_commands.h +@@ -11,7 +11,7 @@ + #include "content/public/browser/page_navigator.h" + #include "ui/gfx/image/image.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + class Browser; + #endif + +@@ -49,7 +49,7 @@ class DownloadCommands { + void ExecuteCommand(Command command); + + #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ +- defined(OS_MAC) ++ defined(OS_MAC) || defined(OS_ANDROID) + bool IsDownloadPdf() const; + bool CanOpenPdfInSystemViewer() const; + Browser* GetBrowser() const; +--- a/chrome/browser/lifetime/application_lifetime.cc ++++ b/chrome/browser/lifetime/application_lifetime.cc +@@ -33,7 +33,7 @@ + #include "content/public/browser/navigation_details.h" + #include "content/public/browser/notification_service.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/lifetime/termination_notification.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_finder.h" +@@ -50,7 +50,7 @@ + #include "third_party/cros_system_api/dbus/service_constants.h" + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + #include "chrome/browser/ui/user_manager.h" + #endif + +@@ -62,7 +62,7 @@ namespace chrome { + + namespace { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Returns true if all browsers can be closed without user interaction. + // This currently checks if there is pending download, or if it needs to + // handle unload handler. +@@ -120,7 +120,7 @@ bool SetLocaleForNextStart(PrefService* + bool g_send_stop_request_to_session_manager = false; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + using IgnoreUnloadHandlers = + util::StrongAlias; + +@@ -154,7 +154,7 @@ void AttemptRestartInternal(IgnoreUnload + + } // namespace + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void MarkAsCleanShutdown() { + // TODO(beng): Can this use ProfileManager::GetLoadedProfiles() instead? + for (auto* browser : *BrowserList::GetInstance()) +@@ -177,7 +177,7 @@ void AttemptExitInternal(bool try_to_qui + g_browser_process->platform_part()->AttemptExit(try_to_quit_application); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void CloseAllBrowsersAndQuit() { + browser_shutdown::SetTryingToQuit(true); + CloseAllBrowsers(); +@@ -269,7 +269,7 @@ void AttemptRelaunch() { + AttemptRestart(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void RelaunchIgnoreUnloadHandlers() { + #if defined(OS_CHROMEOS) + chromeos::PowerManagerClient::Get()->RequestRestart( +@@ -289,7 +289,7 @@ void AttemptExit() { + // don't notify users of crashes beyond this point. + // Note that MarkAsCleanShutdown() does not set UMA's exit cleanly bit + // so crashes during shutdown are still reported in UMA. +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Android doesn't use Browser. + if (AreAllBrowsersCloseable()) + MarkAsCleanShutdown(); +@@ -300,7 +300,7 @@ void AttemptExit() { + + void ExitIgnoreUnloadHandlers() { + VLOG(1) << "ExitIgnoreUnloadHandlers"; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // We always mark exit cleanly. + MarkAsCleanShutdown(); + +@@ -327,7 +327,7 @@ bool IsAttemptingShutdown() { + } + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void SessionEnding() { + // This is a time-limited shutdown where we need to write as much to + // disk as we can as soon as we can, and where we must kill the +@@ -395,6 +395,8 @@ void OnAppExiting() { + notified = true; + HandleAppExitingForPlatform(); + } ++ ++void HandleAppExitingForPlatform() {} + #endif // !defined(OS_ANDROID) + + } // namespace chrome +--- a/chrome/browser/ui/chrome_pages.cc ++++ b/chrome/browser/ui/chrome_pages.cc +@@ -70,7 +70,7 @@ + #include "chrome/browser/ui/signin_view_controller.h" + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/signin/identity_manager_factory.h" + #include "components/signin/public/identity_manager/identity_manager.h" + #endif +@@ -470,7 +470,7 @@ GURL GetOSSettingsUrl(const std::string& + } + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + void ShowBrowserSignin(Browser* browser, + signin_metrics::AccessPoint access_point) { + } +--- a/chrome/browser/ui/chrome_pages.h ++++ b/chrome/browser/ui/chrome_pages.h +@@ -14,7 +14,7 @@ + #include "components/services/app_service/public/mojom/types.mojom.h" + #include "url/gurl.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/signin/signin_promo.h" + #endif + +@@ -157,7 +157,7 @@ void ShowPrintManagementApp(Profile* pro + void ShowConnectivityDiagnosticsApp(Profile* profile); + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // Initiates signin in a new browser tab. + void ShowBrowserSignin(Browser* browser, + signin_metrics::AccessPoint access_point); +--- a/chrome/browser/metrics/thread_watcher.cc ++++ b/chrome/browser/metrics/thread_watcher.cc +@@ -36,7 +36,7 @@ + #include "content/public/browser/notification_registrar.h" + #include "content/public/browser/notification_service.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/metrics/browser_activity_watcher.h" + #endif + +@@ -68,7 +68,7 @@ class ThreadWatcherObserver : public con + // Called when user activity is detected. + void OnUserActivityDetected(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr browser_activity_watcher_; + #endif + +@@ -97,7 +97,7 @@ ThreadWatcherObserver::ThreadWatcherObse + DCHECK(!g_thread_watcher_observer_); + g_thread_watcher_observer_ = this; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + browser_activity_watcher_ = std::make_unique( + base::BindRepeating(&ThreadWatcherObserver::OnUserActivityDetected, + base::Unretained(this))); +@@ -830,7 +830,7 @@ void WatchDogThread::CleanUp() { + } + + // ShutdownWatcherHelper is not available on Android. +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + namespace { + +--- a/chrome/browser/metrics/thread_watcher.h ++++ b/chrome/browser/metrics/thread_watcher.h +@@ -497,7 +497,7 @@ class WatchDogThread : public base::Thre + // ShutdownWatcherHelper is useless on Android because there is no shutdown, + // Chrome is always killed one way or another (swiped away in the task + // switcher, OOM-killed, etc.). +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // This is a wrapper class for detecting hangs during shutdown. + class ShutdownWatcherHelper { + public: +--- a/chrome/browser/lifetime/browser_shutdown.cc ++++ b/chrome/browser/lifetime/browser_shutdown.cc +@@ -50,7 +50,7 @@ + #include "chrome/browser/win/browser_util.h" + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + #include "chrome/browser/first_run/upgrade_util.h" + #endif + +@@ -222,7 +222,7 @@ ShutdownType GetShutdownType() { + return g_shutdown_type; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + bool ShutdownPreThreadsStop() { + #if defined(OS_CHROMEOS) + chromeos::BootTimesRecorder::Get()->AddLogoutTimeMarker( +@@ -445,7 +445,7 @@ void SetTryingToQuit(bool quitting) { + // attempt is cancelled. + PrefService* pref_service = g_browser_process->local_state(); + if (pref_service) { +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + pref_service->ClearPref(prefs::kWasRestarted); + #endif // !defined(OS_ANDROID) + pref_service->ClearPref(prefs::kRestartLastSessionOnShutdown); +--- a/chrome/browser/lifetime/browser_shutdown.h ++++ b/chrome/browser/lifetime/browser_shutdown.h +@@ -13,7 +13,7 @@ class PrefRegistrySimple; + + namespace browser_shutdown { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + // The type of restart to perform during shutdown; see ShutdownPostThreadsStop. + enum class RestartMode { +@@ -75,7 +75,7 @@ bool ShouldIgnoreUnloadHandlers(); + // Get the current shutdown type. + ShutdownType GetShutdownType(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Performs the shutdown tasks that need to be done before + // BrowserProcess and the various threads go away. + // +--- a/chrome/browser/metrics/thread_watcher_report_hang.cc ++++ b/chrome/browser/metrics/thread_watcher_report_hang.cc +@@ -35,7 +35,7 @@ NOINLINE NOT_TAIL_CALLED void ReportThre + #endif + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + NOINLINE void StartupHang() { + // TODO(rtenneti): http://crbug.com/440885 enable crashing after fixing false +--- a/chrome/browser/metrics/thread_watcher_report_hang.h ++++ b/chrome/browser/metrics/thread_watcher_report_hang.h +@@ -11,7 +11,7 @@ + + namespace metrics { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + // This function makes it possible to tell from the callstack why startup is + // taking too long. +--- a/chrome/browser/first_run/upgrade_util.h ++++ b/chrome/browser/first_run/upgrade_util.h +@@ -10,7 +10,7 @@ + #include "base/callback_forward.h" + #include "build/build_config.h" + +-#if defined(OS_ANDROID) || defined(OS_CHROMEOS) ++#if !defined(OS_ANDROID) || defined(OS_CHROMEOS) + #error Not used on Android or ChromeOS + #endif + +--- a/chrome/browser/profiles/profile_metrics.cc ++++ b/chrome/browser/profiles/profile_metrics.cc +@@ -27,13 +27,13 @@ + #include "components/signin/core/browser/signin_header_helper.h" + #include "content/public/browser/browser_thread.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser_finder.h" + #endif + + namespace { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + constexpr base::TimeDelta kProfileActivityThreshold = + base::TimeDelta::FromDays(28); // Should be integral number of weeks. + #endif +@@ -166,7 +166,7 @@ enum ProfileAvatar { + + // static + bool ProfileMetrics::IsProfileActive(const ProfileAttributesEntry* entry) { +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // TODO(mlerman): iOS and Android should set an ActiveTime in the + // ProfileAttributesStorage. (see ProfileManager::OnBrowserSetLastActive) + if (base::Time::Now() - entry->GetActiveTime() > kProfileActivityThreshold) +--- a/chrome/browser/download/download_commands.cc ++++ b/chrome/browser/download/download_commands.cc +@@ -28,7 +28,7 @@ + #include "ui/base/clipboard/scoped_clipboard_writer.h" + + #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ +- defined(OS_MAC) ++ defined(OS_MAC) || defined(OS_ANDROID) + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_finder.h" + #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" +@@ -156,7 +156,7 @@ void DownloadCommands::ExecuteCommand(Co + } + + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + + Browser* DownloadCommands::GetBrowser() const { + chrome::ScopedTabbedBrowserDisplayer browser_displayer(model_->profile()); +@@ -179,7 +179,7 @@ bool DownloadCommands::CanOpenPdfInSyste + return IsDownloadPdf() && + (IsAdobeReaderDefaultPDFViewer() ? is_adobe_pdf_reader_up_to_date + : true); +-#elif defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) ++#elif defined(OS_MAC) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + return IsDownloadPdf(); + #endif + } +--- a/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc ++++ b/chrome/browser/custom_handlers/register_protocol_handler_permission_request.cc +@@ -29,7 +29,13 @@ RegisterProtocolHandlerPermissionRequest + + permissions::PermissionRequest::IconId + RegisterProtocolHandlerPermissionRequest::GetIconId() const { +- return vector_icons::kProtocolHandlerIcon; ++ return 0; ++} ++ ++base::string16 RegisterProtocolHandlerPermissionRequest::GetMessageText() const { ++ return l10n_util::GetStringFUTF16( ++ IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM, ++ handler_.GetProtocolDisplayName()); + } + + base::string16 +--- a/chrome/browser/policy/chrome_browser_policy_connector.cc ++++ b/chrome/browser/policy/chrome_browser_policy_connector.cc +@@ -45,13 +45,12 @@ + #include "base/strings/sys_string_conversions.h" + #include "components/policy/core/common/policy_loader_mac.h" + #include "components/policy/core/common/preferences_mac.h" +-#elif defined(OS_POSIX) && !defined(OS_ANDROID) +-#include "components/policy/core/common/config_dir_policy_loader.h" + #elif defined(OS_ANDROID) ++#include "components/policy/core/common/config_dir_policy_loader.h" + #include "components/policy/core/common/android/android_combined_policy_provider.h" + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) + #include "chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.h" + #include "components/enterprise/browser/controller/chrome_browser_cloud_management_controller.h" + #include "components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.h" +@@ -104,7 +103,7 @@ bool ChromeBrowserPolicyConnector::IsEnt + bool ChromeBrowserPolicyConnector::HasMachineLevelPolicies() { + if (ProviderHasPolicies(GetPlatformProvider())) + return true; +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + if (ProviderHasPolicies(machine_level_user_cloud_policy_manager_)) + return true; + #endif // !defined(OS_ANDROID) && !defined(OS_CHROMEOS) +@@ -114,7 +113,7 @@ bool ChromeBrowserPolicyConnector::HasMa + } + + void ChromeBrowserPolicyConnector::Shutdown() { +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // Reset the controller before calling base class so that + // shutdown occurs in correct sequence. + chrome_browser_cloud_management_controller_.reset(); +@@ -216,7 +215,6 @@ ChromeBrowserPolicyConnector::CreatePlat + } else { + return nullptr; + } +-#elif defined(OS_ANDROID) + return std::make_unique( + GetSchemaRegistry()); + #else +--- a/chrome/browser/policy/chrome_browser_policy_connector.h ++++ b/chrome/browser/policy/chrome_browser_policy_connector.h +@@ -20,7 +20,7 @@ class PrefService; + namespace policy { + class ConfigurationPolicyProvider; + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + class ChromeBrowserCloudManagementController; + class MachineLevelUserCloudPolicyManager; + #endif +@@ -55,7 +55,7 @@ class ChromeBrowserPolicyConnector : pub + + ConfigurationPolicyProvider* GetPlatformProvider(); + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + ChromeBrowserCloudManagementController* + chrome_browser_cloud_management_controller() { + return chrome_browser_cloud_management_controller_.get(); +@@ -84,7 +84,7 @@ class ChromeBrowserPolicyConnector : pub + // Owned by base class. + ConfigurationPolicyProvider* platform_provider_ = nullptr; + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + std::unique_ptr + chrome_browser_cloud_management_controller_; + // Owned by base class. +--- a/chrome/browser/hid/hid_chooser_context.cc ++++ b/chrome/browser/hid/hid_chooser_context.cc +@@ -348,11 +348,6 @@ void HidChooserContext::DeviceRemoved(de + void HidChooserContext::EnsureHidManagerConnection() { + if (hid_manager_) + return; +- +- mojo::PendingRemote manager; +- content::GetDeviceService().BindHidManager( +- manager.InitWithNewPipeAndPassReceiver()); +- SetUpHidManagerConnection(std::move(manager)); + } + + void HidChooserContext::SetUpHidManagerConnection( +--- a/chrome/browser/permissions/attestation_permission_request.cc ++++ b/chrome/browser/permissions/attestation_permission_request.cc +@@ -26,9 +26,14 @@ class AttestationPermissionRequest : pub + : origin_(origin), callback_(std::move(callback)) {} + + permissions::PermissionRequest::IconId GetIconId() const override { +- return kUsbSecurityKeyIcon; ++ return 0; + } + ++ base::string16 GetMessageText() const override { ++ return l10n_util::GetStringUTF16( ++ IDS_SECURITY_KEY_ATTESTATION_PERMISSION_FRAGMENT); ++ } ++ + base::string16 GetMessageTextFragment() const override { + return l10n_util::GetStringUTF16( + IDS_SECURITY_KEY_ATTESTATION_PERMISSION_FRAGMENT); +--- a/chrome/browser/profiles/profile_window.cc ++++ b/chrome/browser/profiles/profile_window.cc +@@ -53,7 +53,7 @@ + #include "extensions/browser/extension_system.h" + #endif // BUILDFLAG(ENABLE_EXTENSIONS) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser_finder.h" + #include "chrome/browser/ui/browser_list.h" + #include "chrome/browser/ui/browser_list_observer.h" +@@ -254,7 +254,7 @@ void OpenBrowserWindowForProfile(Profile + is_first_run, true); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + void LoadProfileAsync(const base::FilePath& path, + ProfileManager::CreateCallback callback) { +--- a/chrome/browser/resource_coordinator/resource_coordinator_parts.cc ++++ b/chrome/browser/resource_coordinator/resource_coordinator_parts.cc +@@ -9,12 +9,12 @@ + namespace resource_coordinator { + + ResourceCoordinatorParts::ResourceCoordinatorParts() +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + : tab_manager_(&tab_load_tracker_), + tab_lifecycle_unit_source_(tab_manager_.usage_clock()) + #endif + { +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + tab_lifecycle_unit_source_.AddObserver(&tab_manager_); + #endif + } +--- a/chrome/browser/resource_coordinator/resource_coordinator_parts.h ++++ b/chrome/browser/resource_coordinator/resource_coordinator_parts.h +@@ -10,7 +10,7 @@ + #include "chrome/browser/resource_coordinator/tab_load_tracker.h" + #include "chrome/browser/resource_coordinator/tab_memory_metrics_reporter.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_source.h" + #include "chrome/browser/resource_coordinator/tab_manager.h" + #endif +@@ -39,7 +39,7 @@ class ResourceCoordinatorParts { + TabLoadTracker* tab_load_tracker() { return &tab_load_tracker_; } + + TabManager* tab_manager() { +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + return nullptr; + #else + return &tab_manager_; +@@ -47,7 +47,7 @@ class ResourceCoordinatorParts { + } + + TabLifecycleUnitSource* tab_lifecycle_unit_source() { +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + return nullptr; + #else + return &tab_lifecycle_unit_source_; +@@ -62,7 +62,7 @@ class ResourceCoordinatorParts { + // Created on demand the first time it's being accessed. + std::unique_ptr tab_memory_metrics_reporter_; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Any change to this #ifdef must be reflected as well in + // chrome/browser/resource_coordinator/tab_manager_browsertest.cc + // +--- a/chrome/browser/storage/storage_notification_service_impl.cc ++++ b/chrome/browser/storage/storage_notification_service_impl.cc +@@ -11,7 +11,7 @@ + #include "chrome/browser/profiles/profile.h" + #include "chrome/common/chrome_switches.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/storage_pressure_bubble.h" + #endif + +--- a/chrome/browser/chrome_browser_main_posix.cc ++++ b/chrome/browser/chrome_browser_main_posix.cc +@@ -172,7 +172,5 @@ void ChromeBrowserMainPartsPosix::ShowMi + // TODO(port): We may want a views based message dialog here eventually, but + // for now, crash. + NOTREACHED(); +-#else +-#error "Need MessageBox implementation." + #endif + } +--- a/chrome/browser/first_run/first_run_internal_posix.cc ++++ b/chrome/browser/first_run/first_run_internal_posix.cc +@@ -96,7 +96,7 @@ void ForceFirstRunDialogShownForTesting( + } + + void DoPostImportPlatformSpecificTasks(Profile* profile) { +-#if !defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) + if (!ShouldShowFirstRunDialog()) + return; + +--- a/chrome/browser/ui/search/search_ipc_router_policy_impl.h ++++ b/chrome/browser/ui/search/search_ipc_router_policy_impl.h +@@ -9,7 +9,7 @@ + #include "build/build_config.h" + #include "chrome/browser/ui/search/search_ipc_router.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/ui/search/ntp_user_data_logger.h ++++ b/chrome/browser/ui/search/ntp_user_data_logger.h +@@ -21,7 +21,7 @@ + #include "content/public/browser/web_contents_observer.h" + #include "content/public/browser/web_contents_user_data.h" + +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + #error "Instant is only used on desktop"; + #endif + +--- a/chrome/browser/engagement/important_sites_util.h ++++ b/chrome/browser/engagement/important_sites_util.h +@@ -76,7 +76,7 @@ class ImportantSitesUtil { + Profile* profile, + size_t max_results); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Return the top |<=max_results| important registrable domains that have an + // associated installed app. |max_results| is assumed to be small. + static std::vector GetInstalledRegisterableDomains( +--- a/chrome/browser/engagement/important_sites_util.cc ++++ b/chrome/browser/engagement/important_sites_util.cc +@@ -39,7 +39,6 @@ + + #if defined(OS_ANDROID) + #include "chrome/browser/android/search_permissions/search_permissions_service.h" +-#else + #include "chrome/browser/web_applications/components/web_app_id.h" + #include "chrome/browser/web_applications/web_app_provider.h" + #include "chrome/browser/web_applications/web_app_registrar.h" +@@ -359,7 +358,7 @@ void PopulateInfoMapWithBookmarks( + // about clearing data for installed apps, so this and any functions explicitly + // used to warn about clearing data for installed apps can be excluded from the + // Android build. +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void PopulateInfoMapWithInstalledEngagedInTimePeriod( + browsing_data::TimePeriod time_period, + Profile* profile, +@@ -489,7 +488,7 @@ ImportantSitesUtil::GetImportantRegister + return final_list; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::vector + ImportantSitesUtil::GetInstalledRegisterableDomains( + browsing_data::TimePeriod time_period, +--- a/chrome/common/chrome_switches.h ++++ b/chrome/common/chrome_switches.h +@@ -250,12 +250,12 @@ extern const char kAllowNaClSocketAPI[]; + #endif + + #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ +- defined(OS_WIN) ++ defined(OS_WIN) || defined(OS_ANDROID) + extern const char kEnableNewAppMenuIcon[]; + extern const char kGuest[]; + #endif + +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + extern const char kUseSystemDefaultPrinter[]; + #endif + +--- a/chrome/common/chrome_switches.cc ++++ b/chrome/common/chrome_switches.cc +@@ -797,14 +797,14 @@ const char kAllowNaClSocketAPI[] + #endif + + #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_MAC) || \ +- defined(OS_WIN) ++ defined(OS_WIN) || defined(OS_ANDROID) + const char kEnableNewAppMenuIcon[] = "enable-new-app-menu-icon"; + + // Causes the browser to launch directly in guest mode. + const char kGuest[] = "guest"; + #endif + +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + // Uses the system default printer as the initially selected destination in + // print preview, instead of the most recently used destination. + const char kUseSystemDefaultPrinter[] = "use-system-default-printer"; +--- a/chrome/common/webui_url_constants.cc ++++ b/chrome/common/webui_url_constants.cc +@@ -201,7 +201,6 @@ const char kChromeUISnippetsInternalsHos + const char kChromeUIUntrustedVideoPlayerUrl[] = + "chrome-untrusted://video-tutorials/"; + const char kChromeUIWebApksHost[] = "webapks"; +-#else + const char kChromeUINearbyInternalsHost[] = "nearby-internals"; + const char kChromeUIReadLaterHost[] = "read-later"; + const char kChromeUIReadLaterURL[] = "chrome://read-later/"; +@@ -345,14 +344,14 @@ const char kChromeUIWebUIJsExceptionURL[ + #endif + + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + const char kChromeUIDiscardsHost[] = "discards"; + const char kChromeUIDiscardsURL[] = "chrome://discards/"; + const char kChromeUIHatsHost[] = "hats"; + const char kChromeUIHatsURL[] = "chrome://hats/"; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + const char kChromeUINearbyShareHost[] = "nearby"; + const char kChromeUINearbyShareURL[] = "chrome://nearby/"; + #endif // !defined(OS_ANDROID) +@@ -366,7 +365,7 @@ const char kChromeUILinuxProxyConfigHost + const char kChromeUISandboxHost[] = "sandbox"; + #endif + +-#if defined(OS_WIN) || defined(OS_MAC) || \ ++#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_ANDROID) || \ + (defined(OS_LINUX) && !defined(OS_CHROMEOS)) + const char kChromeUIBrowserSwitchHost[] = "browser-switch"; + const char kChromeUIBrowserSwitchURL[] = "chrome://browser-switch/"; +@@ -392,7 +391,7 @@ const char kChromeUITabStripHost[] = "ta + const char kChromeUITabStripURL[] = "chrome://tab-strip"; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + const char kChromeUICommanderHost[] = "commander"; + const char kChromeUICommanderURL[] = "chrome://commander"; + const char kChromeUITabSearchHost[] = "tab-search"; +--- a/chrome/common/webui_url_constants.h ++++ b/chrome/common/webui_url_constants.h +@@ -197,7 +197,6 @@ extern const char kChromeUINativeNewTabU + extern const char kChromeUISnippetsInternalsHost[]; + extern const char kChromeUIUntrustedVideoPlayerUrl[]; + extern const char kChromeUIWebApksHost[]; +-#else + extern const char kChromeUINearbyInternalsHost[]; + extern const char kChromeUIReadLaterHost[]; + extern const char kChromeUIReadLaterURL[]; +@@ -298,14 +297,14 @@ extern const char kChromeUIWebUIJsExcept + #endif + + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + extern const char kChromeUIDiscardsHost[]; + extern const char kChromeUIDiscardsURL[]; + extern const char kChromeUIHatsHost[]; + extern const char kChromeUIHatsURL[]; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kChromeUINearbyShareHost[]; + extern const char kChromeUINearbyShareURL[]; + #endif // !defined(OS_CHROMEOS) +@@ -319,7 +318,7 @@ extern const char kChromeUILinuxProxyCon + extern const char kChromeUISandboxHost[]; + #endif + +-#if defined(OS_WIN) || defined(OS_MAC) || \ ++#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_ANDROID) || \ + (defined(OS_LINUX) && !defined(OS_CHROMEOS)) + extern const char kChromeUIBrowserSwitchHost[]; + extern const char kChromeUIBrowserSwitchURL[]; +@@ -344,7 +343,7 @@ extern const char kChromeUITabStripHost[ + extern const char kChromeUITabStripURL[]; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const char kChromeUICommanderHost[]; + extern const char kChromeUICommanderURL[]; + extern const char kChromeUITabSearchHost[]; +--- a/chrome/browser/profiles/profile_manager.cc ++++ b/chrome/browser/profiles/profile_manager.cc +@@ -123,7 +123,6 @@ + + #if defined(OS_ANDROID) + #include "chrome/browser/android/metrics/android_profile_session_durations_service_factory.h" +-#else + #include "chrome/browser/accessibility/caption_controller.h" + #include "chrome/browser/accessibility/caption_controller_factory.h" + #include "chrome/browser/first_run/first_run.h" +@@ -147,7 +146,7 @@ + #include "components/user_manager/user_type.h" + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + #include "chrome/browser/profiles/profile_statistics.h" + #include "chrome/browser/profiles/profile_statistics_factory.h" + #endif +@@ -237,7 +236,7 @@ void ProfileSizeTask(const base::FilePat + UMA_HISTOGRAM_COUNTS_10000("Profile.AppCount", enabled_app_count); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Schedule a profile for deletion if it isn't already scheduled. + // Returns whether the profile has been newly scheduled. + bool ScheduleProfileDirectoryForDeletion(const base::FilePath& path) { +@@ -330,7 +329,7 @@ void OnProfileLoaded(ProfileManager::Pro + .Run(incognito ? profile->GetPrimaryOTRProfile() : profile); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Helper function for ScheduleForcedEphemeralProfileForDeletion. + bool IsRegisteredAsEphemeral(ProfileAttributesStorage* storage, + const base::FilePath& profile_dir) { +@@ -874,7 +873,7 @@ ProfileShortcutManager* ProfileManager:: + return profile_shortcut_manager_.get(); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void ProfileManager::MaybeScheduleProfileForDeletion( + const base::FilePath& profile_dir, + ProfileLoadedCallback callback, +@@ -1097,7 +1096,7 @@ void ProfileManager::InitProfileUserPref + } else if (profile->GetPath() == + profiles::GetDefaultProfileDir(user_data_dir())) { + avatar_index = profiles::GetPlaceholderAvatarIndex(); +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + profile_name = + base::UTF16ToUTF8(storage.ChooseNameForNewProfile(avatar_index)); + #else +@@ -1326,7 +1325,7 @@ void ProfileManager::DoFinalInitForServi + ChildAccountServiceFactory::GetForProfile(profile)->Init(); + SupervisedUserServiceFactory::GetForProfile(profile)->Init(); + #endif +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // If the lock enabled algorithm changed, update this profile's lock status. + // This depends on services which shouldn't be initialized until + // DoFinalInitForServices. +@@ -1481,7 +1480,7 @@ bool ProfileManager::AddProfile(std::uni + return true; + } + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + void ProfileManager::RemoveProfile(const base::FilePath& profile_dir) { + TRACE_EVENT0("browser", "ProfileManager::RemoveProfile"); + +@@ -1554,7 +1553,7 @@ Profile* ProfileManager::CreateAndInitia + return profile_ptr; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void ProfileManager::EnsureActiveProfileExistsBeforeDeletion( + ProfileLoadedCallback callback, + const base::FilePath& profile_dir) { +@@ -1791,7 +1790,7 @@ void ProfileManager::AddProfileToStorage + bool has_entry = storage.GetProfileAttributesWithPath(profile->GetPath(), + &entry); + if (has_entry) { +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + bool was_authenticated_status = entry->IsAuthenticated(); + #endif + // The ProfileAttributesStorage's info must match the Identity Manager. +@@ -1800,7 +1799,7 @@ void ProfileManager::AddProfileToStorage + + entry->SetSignedInWithCredentialProvider(false); + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // Sign out if force-sign-in policy is enabled and profile is not signed + // in. + VLOG(1) << "ForceSigninCheck: " << signin_util::IsForceSigninEnabled() +@@ -1923,7 +1922,7 @@ void ProfileManager::SaveActiveProfiles( + } + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void ProfileManager::OnBrowserOpened(Browser* browser) { + DCHECK(browser); + Profile* profile = browser->profile(); +--- a/chrome/browser/profiles/profile_manager.h ++++ b/chrome/browser/profiles/profile_manager.h +@@ -27,7 +27,7 @@ + #include "content/public/browser/notification_observer.h" + #include "content/public/browser/notification_registrar.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser_list_observer.h" + #endif // !defined(OS_ANDROID) + +@@ -206,7 +206,7 @@ class ProfileManager : public content::N + // profile specfic desktop shortcuts. + ProfileShortcutManager* profile_shortcut_manager(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Less strict version of ScheduleProfileForDeletion(), silently exits if + // profile is either scheduling or marked for deletion. + void MaybeScheduleProfileForDeletion( +@@ -320,7 +320,7 @@ class ProfileManager : public content::N + // Returns true if the profile was added, false otherwise. + bool AddProfile(std::unique_ptr profile); + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + // Removes the Profile at |profile_dir| from the manager and destroys it. If + // it's an ephemeral profile, also nuke the |profile_dir| directory from disk + // afterwards. +@@ -332,7 +332,7 @@ class ProfileManager : public content::N + // null if creation fails. + Profile* CreateAndInitializeProfile(const base::FilePath& profile_dir); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Continues the scheduled profile deletion after closing all the profile's + // browsers tabs. Creates a new profile if the profile to be deleted is the + // last non-supervised profile. In the Mac, loads the next non-supervised +@@ -393,7 +393,7 @@ class ProfileManager : public content::N + + void SaveActiveProfiles(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void OnBrowserOpened(Browser* browser); + void OnBrowserClosed(Browser* browser); + +@@ -458,7 +458,7 @@ class ProfileManager : public content::N + // default. + bool logged_in_ = false; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + BrowserListObserver browser_list_observer_{this}; + #endif // !defined(OS_ANDROID) + +--- a/components/ui_devtools/views/overlay_agent_views.cc ++++ b/components/ui_devtools/views/overlay_agent_views.cc +@@ -19,6 +19,8 @@ + #include "ui/views/background.h" + #include "ui/views/border.h" + ++#include "ui/android/window_android.h" ++ + #if defined(USE_AURA) + #include "ui/aura/window.h" + #include "ui/wm/core/window_util.h" +@@ -567,7 +569,6 @@ void OverlayAgentViews::OnPaintLayer(con + gfx::Canvas* canvas = recorder.canvas(); + // Convert the hovered rect from screen coordinates to layer coordinates. + gfx::RectF hovered_rect_f(hovered_rect_); +- hovered_rect_f.Offset(-layer_for_highlighting_screen_offset_); + + cc::PaintFlags flags; + flags.setStrokeWidth(1.0f); +@@ -601,7 +602,6 @@ void OverlayAgentViews::OnPaintLayer(con + + // Convert the pinned rect from screen coordinates to layer coordinates. + gfx::RectF pinned_rect_f(pinned_rect_); +- pinned_rect_f.Offset(-layer_for_highlighting_screen_offset_); + + // Draw |pinned_rect_f| bounds in blue. + canvas->DrawRect(pinned_rect_f, flags); +@@ -706,35 +706,7 @@ void OverlayAgentViews::OnPaintLayer(con + + bool OverlayAgentViews::UpdateHighlight( + const std::pair& window_and_bounds) { +- if (window_and_bounds.second.IsEmpty()) { +- hovered_rect_.SetRect(0, 0, 0, 0); +- return false; +- } +- ui::Layer* root_layer = nullptr; +-#if defined(OS_APPLE) +- views::Widget* widget = +- views::Widget::GetWidgetForNativeWindow(window_and_bounds.first); +- root_layer = widget->GetLayer(); +- layer_for_highlighting_screen_offset_ = +- widget->GetContentsView()->GetBoundsInScreen().OffsetFromOrigin(); +-#else +- gfx::NativeWindow root = window_and_bounds.first->GetRootWindow(); +- root_layer = root->layer(); +- layer_for_highlighting_screen_offset_ = +- root->GetBoundsInScreen().OffsetFromOrigin(); +-#endif // defined(OS_APPLE) +- DCHECK(root_layer); +- +- layer_for_highlighting_->SetBounds(root_layer->bounds()); +- layer_for_highlighting_->SchedulePaint(root_layer->bounds()); +- +- if (root_layer != layer_for_highlighting_->parent()) +- root_layer->Add(layer_for_highlighting_.get()); +- else +- root_layer->StackAtTop(layer_for_highlighting_.get()); +- +- hovered_rect_ = window_and_bounds.second; +- return true; ++ return false; + } + + } // namespace ui_devtools +--- a/components/url_formatter/elide_url.cc ++++ b/components/url_formatter/elide_url.cc +@@ -26,7 +26,7 @@ + + namespace { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + const base::char16 kDot = '.'; + + // Build a path from the first |num_components| elements in |path_elements|. +@@ -160,7 +160,7 @@ base::string16 HostForDisplay(base::Stri + + namespace url_formatter { + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + + // TODO(pkasting): http://crbug.com/77883 This whole function gets + // kerning/ligatures/etc. issues potentially wrong by assuming that the width of +--- a/components/url_formatter/elide_url.h ++++ b/components/url_formatter/elide_url.h +@@ -26,7 +26,7 @@ namespace url_formatter { + + // ElideUrl and Elide host require + // gfx::GetStringWidthF which is not implemented in Android +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // This function takes a GURL object and elides it. It returns a string + // composed of parts from subdomain, domain, path, filename and query. + // A "..." is added automatically at the end if the elided string is bigger +--- a/content/public/browser/desktop_media_id.cc ++++ b/content/public/browser/desktop_media_id.cc +@@ -22,22 +22,20 @@ namespace content { + const char kScreenPrefix[] = "screen"; + const char kWindowPrefix[] = "window"; + +-#if defined(USE_AURA) || defined(OS_MAC) ++#if defined(USE_AURA) || defined(OS_MAC) || defined(OS_ANDROID) + // static + DesktopMediaID DesktopMediaID::RegisterNativeWindow(DesktopMediaID::Type type, + gfx::NativeWindow window) { + DCHECK(type == TYPE_SCREEN || type == TYPE_WINDOW); + DCHECK(window); + DesktopMediaID media_id(type, kNullId); +- media_id.window_id = +- DesktopMediaWindowRegistry::GetInstance()->RegisterWindow(window); + return media_id; + } + + // static + gfx::NativeWindow DesktopMediaID::GetNativeWindowById( + const DesktopMediaID& id) { +- return DesktopMediaWindowRegistry::GetInstance()->GetWindowById(id.window_id); ++ return nullptr; + } + #endif + +--- a/content/public/browser/desktop_media_id.h ++++ b/content/public/browser/desktop_media_id.h +@@ -28,7 +28,7 @@ struct CONTENT_EXPORT DesktopMediaID { + // Represents a fake id to create a dummy capturer for autotests. + static constexpr Id kFakeId = -3; + +-#if defined(USE_AURA) || defined(OS_MAC) ++#if defined(USE_AURA) || defined(OS_MAC) || defined(OS_ANDROID) + // Assigns integer identifier to the |window| and returns its DesktopMediaID. + static DesktopMediaID RegisterNativeWindow(Type type, + gfx::NativeWindow window); +--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc ++++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.cc +@@ -272,7 +272,7 @@ void PasswordGenerationPopupControllerIm + } + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void PasswordGenerationPopupControllerImpl::OnZoomChanged( + const zoom::ZoomController::ZoomChangedEventData& data) { + HideImpl(); +--- a/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h ++++ b/chrome/browser/ui/passwords/password_generation_popup_controller_impl.h +@@ -25,7 +25,7 @@ + #include "ui/gfx/geometry/rect_f.h" + #include "ui/gfx/native_widget_types.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "components/zoom/zoom_observer.h" + #endif // !defined(OS_ANDROID) + +@@ -60,7 +60,7 @@ class PasswordGenerationPopupView; + class PasswordGenerationPopupControllerImpl + : public PasswordGenerationPopupController, + public content::WebContentsObserver +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + , + public zoom::ZoomObserver + #endif // !defined(OS_ANDROID) +@@ -106,7 +106,7 @@ class PasswordGenerationPopupControllerI + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // ZoomObserver implementation. + void OnZoomChanged( + const zoom::ZoomController::ZoomChangedEventData& data) override; +--- a/content/public/browser/native_web_keyboard_event.h ++++ b/content/public/browser/native_web_keyboard_event.h +@@ -48,7 +48,6 @@ struct CONTENT_EXPORT NativeWebKeyboardE + int scancode, + int unicode_character, + bool is_system_key); +-#else + explicit NativeWebKeyboardEvent(const ui::KeyEvent& key_event); + #if defined(USE_AURA) + // Create a legacy keypress event specified by |character|. +--- a/content/browser/renderer_host/native_web_keyboard_event_android.cc ++++ b/content/browser/renderer_host/native_web_keyboard_event_android.cc +@@ -64,6 +64,8 @@ NativeWebKeyboardEvent& NativeWebKeyboar + return *this; + } + ++NativeWebKeyboardEvent::NativeWebKeyboardEvent(const ui::KeyEvent& key_event) {} ++ + NativeWebKeyboardEvent::~NativeWebKeyboardEvent() {} + + } // namespace content +--- a/chrome/browser/ui/views/frame/browser_view.cc ++++ b/chrome/browser/ui/views/frame/browser_view.cc +@@ -1870,7 +1870,6 @@ void BrowserView::UserChangedTheme(Brows + // In Incognito, the usage of dark or normal hinges on the browser theme. + if (theme_change_type == BrowserThemeChangeType::kBrowserTheme && + !IsRegularOrGuestSession()) { +- ui::NativeTheme::GetInstanceForDarkUI()->NotifyObservers(); + ui::NativeTheme::GetInstanceForNativeUi()->NotifyObservers(); + + // Early exit. A native theme change will update all the +@@ -3422,7 +3421,7 @@ void BrowserView::ShowAvatarBubbleFromAv + profiles::BubbleViewMode bubble_view_mode; + profiles::BubbleViewModeFromAvatarBubbleMode(mode, GetProfile(), + &bubble_view_mode); +-#if !defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) + if (SigninViewController::ShouldShowSigninForMode(bubble_view_mode)) { + browser_->signin_view_controller()->ShowSignin(bubble_view_mode, + access_point); +--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc ++++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc +@@ -259,7 +259,7 @@ void LocationBarView::Init() { + // The send tab to self icon is intentionally the first one added so it is + // the left most icon. + params.types_enabled.push_back(PageActionIconType::kSendTabToSelf); +- if (base::FeatureList::IsEnabled(kClickToCallUI)) ++ if (false) + params.types_enabled.push_back(PageActionIconType::kClickToCall); + if (base::FeatureList::IsEnabled(kSharingQRCodeGenerator)) + params.types_enabled.push_back(PageActionIconType::kQRCodeGenerator); +--- a/components/omnibox/browser/omnibox_popup_model.cc ++++ b/components/omnibox/browser/omnibox_popup_model.cc +@@ -23,7 +23,7 @@ + #include "ui/base/l10n/l10n_util.h" + #include "ui/gfx/geometry/rect.h" + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + #include "components/omnibox/browser/vector_icons.h" // nogncheck + #include "ui/gfx/paint_vector_icon.h" + #include "ui/gfx/vector_icon_types.h" +@@ -297,7 +297,7 @@ void OmniboxPopupModel::SetRichSuggestio + } + + // Android and iOS have their own platform-specific icon logic. +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + gfx::Image OmniboxPopupModel::GetMatchIcon(const AutocompleteMatch& match, + SkColor vector_icon_color) { + gfx::Image extension_icon = +--- a/components/omnibox/browser/omnibox_popup_model.h ++++ b/components/omnibox/browser/omnibox_popup_model.h +@@ -208,7 +208,7 @@ class OmniboxPopupModel { + // Stores the image in a local data member and schedules a repaint. + void SetRichSuggestionBitmap(int result_index, const SkBitmap& bitmap); + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + // Gets the icon for the match index. + gfx::Image GetMatchIcon(const AutocompleteMatch& match, + SkColor vector_icon_color); +--- a/third_party/blink/public/mojom/payments/payment_request.mojom ++++ b/third_party/blink/public/mojom/payments/payment_request.mojom +@@ -249,8 +249,7 @@ interface PaymentRequest { + Init(pending_remote client, + array method_data, + PaymentDetails details, +- PaymentOptions options, +- [EnableIf=is_android] bool google_pay_bridge_eligible); ++ PaymentOptions options); + + // Shows the user interface with the payment details. + // |is_user_gesture|: Whether the show is triggered from a user gesture. +--- a/third_party/blink/renderer/modules/payments/payment_request.cc ++++ b/third_party/blink/renderer/modules/payments/payment_request.cc +@@ -1311,7 +1311,7 @@ PaymentRequest::PaymentRequest( + UseCounter::Count(execution_context, WebFeature::kPaymentRequestInitialized); + mojo::PendingRemote client; + client_receiver_.Bind(client.InitWithNewPipeAndPassReceiver(), task_runner); +-#if defined(OS_ANDROID) ++#if !defined(OS_ANDROID) + payment_provider_->Init( + std::move(client), std::move(validated_method_data), + std::move(validated_details), +--- a/components/omnibox/browser/autocomplete_match.cc ++++ b/components/omnibox/browser/autocomplete_match.cc +@@ -36,7 +36,7 @@ + #include "ui/gfx/vector_icon_types.h" + #include "url/third_party/mozilla/url_parse.h" + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + #include "components/omnibox/browser/vector_icons.h" // nogncheck + #include "components/vector_icons/vector_icons.h" // nogncheck + #endif +@@ -257,7 +257,7 @@ AutocompleteMatch& AutocompleteMatch::op + return *this; + } + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + const gfx::VectorIcon& AutocompleteMatch::GetVectorIcon( + bool is_bookmark) const { + if (is_bookmark) +--- a/components/omnibox/browser/autocomplete_match.h ++++ b/components/omnibox/browser/autocomplete_match.h +@@ -185,7 +185,7 @@ struct AutocompleteMatch { + + AutocompleteMatch& operator=(const AutocompleteMatch& match); + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + // Gets the vector icon identifier for the icon to be shown for this match. If + // |is_bookmark| is true, returns a bookmark icon rather than what the type + // would normally determine. Note that in addition to |type|, the icon chosen +--- a/components/omnibox/browser/omnibox_pedal.cc ++++ b/components/omnibox/browser/omnibox_pedal.cc +@@ -13,7 +13,7 @@ + #include "components/omnibox/browser/omnibox_field_trial.h" + #include "ui/base/l10n/l10n_util.h" + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + #include "components/omnibox/browser/vector_icons.h" // nogncheck + #endif + +@@ -126,7 +126,7 @@ bool OmniboxPedal::IsReadyToTrigger( + return true; + } + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + const gfx::VectorIcon& OmniboxPedal::GetVectorIcon() const { + return omnibox::kPedalIcon; + } +--- a/components/omnibox/browser/omnibox_pedal.h ++++ b/components/omnibox/browser/omnibox_pedal.h +@@ -16,7 +16,7 @@ + #include "components/omnibox/browser/omnibox_pedal_concepts.h" + #include "url/gurl.h" + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + namespace gfx { + struct VectorIcon; + } +@@ -143,7 +143,7 @@ class OmniboxPedal { + virtual bool IsReadyToTrigger(const AutocompleteInput& input, + const AutocompleteProviderClient& client) const; + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + // Returns the vector icon to represent this Pedal's action in suggestion. + virtual const gfx::VectorIcon& GetVectorIcon() const; + #endif +--- a/components/omnibox/browser/omnibox_pedal_implementations.cc ++++ b/components/omnibox/browser/omnibox_pedal_implementations.cc +@@ -13,7 +13,7 @@ + #include "components/omnibox/browser/omnibox_pedal.h" + #include "components/strings/grit/components_strings.h" + +-#if (!defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) ++#if (defined(OS_ANDROID) || BUILDFLAG(ENABLE_VR)) && !defined(OS_IOS) + #include "components/omnibox/browser/vector_icons.h" // nogncheck + #endif + +--- a/chrome/browser/ui/views/browser_dialogs_views.cc ++++ b/chrome/browser/ui/views/browser_dialogs_views.cc +@@ -17,15 +17,6 @@ + // This file provides definitions of desktop browser dialog-creation methods for + // all toolkit-views platforms. + // static +-std::unique_ptr LoginHandler::Create( +- const net::AuthChallengeInfo& auth_info, +- content::WebContents* web_contents, +- LoginAuthRequiredCallback auth_required_callback) { +- return chrome::CreateLoginHandlerViews(auth_info, web_contents, +- std::move(auth_required_callback)); +-} +- +-// static + void BookmarkEditor::Show(gfx::NativeWindow parent_window, + Profile* profile, + const EditDetails& details, +--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc ++++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc +@@ -246,8 +246,6 @@ const ContentSettingsImageDetails kImage + IDS_BLOCKED_PLUGINS_MESSAGE, IDS_BLOCKED_PLUGIN_EXPLANATORY_TEXT, 0}, + {ContentSettingsType::MIXEDSCRIPT, kMixedContentIcon, + IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT, 0, 0}, +- {ContentSettingsType::PPAPI_BROKER, vector_icons::kExtensionIcon, +- IDS_BLOCKED_PPAPI_BROKER_MESSAGE, 0, IDS_ALLOWED_PPAPI_BROKER_MESSAGE}, + {ContentSettingsType::SOUND, kTabAudioIcon, IDS_BLOCKED_SOUND_TITLE, 0, 0}, + {ContentSettingsType::ADS, vector_icons::kAdsIcon, + IDS_BLOCKED_ADS_PROMPT_TOOLTIP, IDS_BLOCKED_ADS_PROMPT_TITLE, 0}, +--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc ++++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +@@ -228,7 +228,6 @@ void ContentSettingSimpleBubbleModel::Se + {ContentSettingsType::PLUGINS, IDS_BLOCKED_PLUGINS_TITLE}, + {ContentSettingsType::MIXEDSCRIPT, + IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT_TITLE}, +- {ContentSettingsType::PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_TITLE}, + {ContentSettingsType::SOUND, IDS_BLOCKED_SOUND_TITLE}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, IDS_BLOCKED_CLIPBOARD_TITLE}, + {ContentSettingsType::GEOLOCATION, IDS_BLOCKED_GEOLOCATION_TITLE}, +@@ -238,7 +237,6 @@ void ContentSettingSimpleBubbleModel::Se + // Fields as for kBlockedTitleIDs, above. + static const ContentSettingsTypeIdEntry kAccessedTitleIDs[] = { + {ContentSettingsType::COOKIES, IDS_ACCESSED_COOKIES_TITLE}, +- {ContentSettingsType::PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_TITLE}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, IDS_ALLOWED_CLIPBOARD_TITLE}, + {ContentSettingsType::GEOLOCATION, IDS_ALLOWED_GEOLOCATION_TITLE}, + {ContentSettingsType::MIDI_SYSEX, IDS_ALLOWED_MIDI_SYSEX_TITLE}, +@@ -269,7 +267,6 @@ void ContentSettingSimpleBubbleModel::Se + // {ContentSettingsType::POPUPS, No message. intentionally left out}, + {ContentSettingsType::MIXEDSCRIPT, + IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT}, +- {ContentSettingsType::PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_MESSAGE}, + {ContentSettingsType::GEOLOCATION, IDS_BLOCKED_GEOLOCATION_MESSAGE}, + {ContentSettingsType::MIDI_SYSEX, IDS_BLOCKED_MIDI_SYSEX_MESSAGE}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, +@@ -282,7 +279,6 @@ void ContentSettingSimpleBubbleModel::Se + // Fields as for kBlockedMessageIDs, above. + const ContentSettingsTypeIdEntry kAccessedMessageIDs[] = { + {ContentSettingsType::COOKIES, IDS_ACCESSED_COOKIES_MESSAGE}, +- {ContentSettingsType::PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_MESSAGE}, + {ContentSettingsType::GEOLOCATION, IDS_ALLOWED_GEOLOCATION_MESSAGE}, + {ContentSettingsType::MIDI_SYSEX, IDS_ALLOWED_MIDI_SYSEX_MESSAGE}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, +@@ -542,8 +538,7 @@ ContentSettingPluginBubbleModel::Content + GetSettingManagedByUser(url, content_type(), GetProfile(), nullptr); + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(GetProfile()); +- ContentSetting setting = PluginUtils::GetFlashPluginContentSetting( +- map, url::Origin::Create(url), url, nullptr); ++ ContentSetting setting = CONTENT_SETTING_BLOCK; + + // If the setting is not managed by the user, hide the "Manage" button. + if (!managed_by_user) +@@ -647,7 +642,6 @@ void ContentSettingSingleRadioGroup::Set + {ContentSettingsType::IMAGES, IDS_BLOCKED_IMAGES_UNBLOCK}, + {ContentSettingsType::JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_UNBLOCK}, + {ContentSettingsType::POPUPS, IDS_BLOCKED_POPUPS_REDIRECTS_UNBLOCK}, +- {ContentSettingsType::PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_UNBLOCK}, + {ContentSettingsType::SOUND, IDS_BLOCKED_SOUND_UNBLOCK}, + {ContentSettingsType::GEOLOCATION, IDS_BLOCKED_GEOLOCATION_UNBLOCK}, + {ContentSettingsType::MIDI_SYSEX, IDS_BLOCKED_MIDI_SYSEX_UNBLOCK}, +@@ -658,7 +652,6 @@ void ContentSettingSingleRadioGroup::Set + // Fields as for kBlockedAllowIDs, above. + static const ContentSettingsTypeIdEntry kAllowedAllowIDs[] = { + {ContentSettingsType::COOKIES, IDS_ALLOWED_COOKIES_NO_ACTION}, +- {ContentSettingsType::PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_NO_ACTION}, + {ContentSettingsType::GEOLOCATION, IDS_ALLOWED_GEOLOCATION_NO_ACTION}, + {ContentSettingsType::MIDI_SYSEX, IDS_ALLOWED_MIDI_SYSEX_NO_ACTION}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, +@@ -683,7 +676,6 @@ void ContentSettingSingleRadioGroup::Set + {ContentSettingsType::IMAGES, IDS_BLOCKED_IMAGES_NO_ACTION}, + {ContentSettingsType::JAVASCRIPT, IDS_BLOCKED_JAVASCRIPT_NO_ACTION}, + {ContentSettingsType::POPUPS, IDS_BLOCKED_POPUPS_REDIRECTS_NO_ACTION}, +- {ContentSettingsType::PPAPI_BROKER, IDS_BLOCKED_PPAPI_BROKER_NO_ACTION}, + {ContentSettingsType::SOUND, IDS_BLOCKED_SOUND_NO_ACTION}, + {ContentSettingsType::GEOLOCATION, IDS_BLOCKED_GEOLOCATION_NO_ACTION}, + {ContentSettingsType::MIDI_SYSEX, IDS_BLOCKED_MIDI_SYSEX_NO_ACTION}, +@@ -693,7 +685,6 @@ void ContentSettingSingleRadioGroup::Set + }; + static const ContentSettingsTypeIdEntry kAllowedBlockIDs[] = { + {ContentSettingsType::COOKIES, IDS_ALLOWED_COOKIES_BLOCK}, +- {ContentSettingsType::PPAPI_BROKER, IDS_ALLOWED_PPAPI_BROKER_BLOCK}, + {ContentSettingsType::GEOLOCATION, IDS_ALLOWED_GEOLOCATION_BLOCK}, + {ContentSettingsType::MIDI_SYSEX, IDS_ALLOWED_MIDI_SYSEX_BLOCK}, + {ContentSettingsType::CLIPBOARD_READ_WRITE, IDS_ALLOWED_CLIPBOARD_BLOCK}, +--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h ++++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h +@@ -545,7 +545,7 @@ class ContentSettingGeolocationBubbleMod + bool show_system_geolocation_bubble_ = false; + }; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // The model for the blocked Framebust bubble. + class ContentSettingFramebustBlockBubbleModel + : public ContentSettingSingleRadioGroup, +--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.cc ++++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.cc +@@ -52,7 +52,7 @@ + #include "components/undo/undo_operation.h" + #include "content/public/browser/browser_thread.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/extensions/api/passwords_private/passwords_private_utils.h" + #endif + +@@ -109,7 +109,7 @@ FormVector GetEntryList(const std::mapGetOriginalProfile()); + Browser* browser = displayer.browser(); +- +- if (enable_sync) { +- // Set a primary account. +- browser->signin_view_controller()->ShowDiceEnableSyncTab( +- signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS, +- signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO, email_hint); +- } else { +- // Add an account to the web without setting a primary account. +- browser->signin_view_controller()->ShowDiceAddAccountTab( +- signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS, email_hint); +- } + #endif + } + +--- a/chrome/browser/platform_util.cc ++++ b/chrome/browser/platform_util.cc +@@ -61,24 +61,6 @@ bool AreShellOperationsAllowed() { + + } // namespace internal + +-void OpenItem(Profile* profile, +- const base::FilePath& full_path, +- OpenItemType item_type, +- OpenOperationCallback callback) { +- DCHECK_CURRENTLY_ON(BrowserThread::UI); +- // TaskPriority::USER_BLOCKING because this is usually opened as a result of a +- // user action (e.g. open-downloaded-file or show-item-in-folder). +- // TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN because this doesn't need global +- // state and can hang shutdown without this trait as it may result in an +- // interactive dialog. +- base::ThreadPool::PostTask( +- FROM_HERE, +- {base::MayBlock(), base::TaskPriority::USER_BLOCKING, +- base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, +- base::BindOnce(&VerifyAndOpenItemOnBlockingThread, full_path, item_type, +- std::move(callback))); +-} +- + bool IsBrowserLockedFullscreen(const Browser* browser) { + return false; + } +--- a/chrome/browser/sessions/session_restore.cc ++++ b/chrome/browser/sessions/session_restore.cc +@@ -801,31 +801,6 @@ void SessionRestore::OpenStartupPagesAft + } + + // static +-std::vector SessionRestore::RestoreForeignSessionWindows( +- Profile* profile, +- std::vector::const_iterator begin, +- std::vector::const_iterator end) { +- std::vector gurls; +- SessionRestoreImpl restorer(profile, static_cast(nullptr), true, +- false, true, gurls, +- on_session_restored_callbacks()); +- return restorer.RestoreForeignSession(begin, end); +-} +- +-// static +-WebContents* SessionRestore::RestoreForeignSessionTab( +- content::WebContents* source_web_contents, +- const sessions::SessionTab& tab, +- WindowOpenDisposition disposition) { +- Browser* browser = chrome::FindBrowserWithWebContents(source_web_contents); +- Profile* profile = browser->profile(); +- std::vector gurls; +- SessionRestoreImpl restorer(profile, browser, true, false, false, gurls, +- on_session_restored_callbacks()); +- return restorer.RestoreForeignTab(tab, disposition); +-} +- +-// static + bool SessionRestore::IsRestoring(const Profile* profile) { + if (active_session_restorers == nullptr) + return false; +--- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc ++++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc +@@ -63,7 +63,7 @@ std::vector GetURLsToOpen( + return urls; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + bool ShouldOpenAll(gfx::NativeWindow parent, + const std::vector& nodes) { + size_t child_count = GetURLsToOpen(nodes).size(); +@@ -89,7 +89,7 @@ int ChildURLCountTotal(const BookmarkNod + count_children); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Returns in |urls|, the url and title pairs for each open tab in browser. + void GetURLsForOpenTabs(Browser* browser, + std::vector>* urls) { +@@ -104,7 +104,7 @@ void GetURLsForOpenTabs(Browser* browser + + } // namespace + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void OpenAll(gfx::NativeWindow parent, + content::PageNavigator* navigator, + const std::vector& nodes, +--- a/chrome/browser/ui/views/autofill/payments/save_card_manage_cards_bubble_views.cc ++++ b/chrome/browser/ui/views/autofill/payments/save_card_manage_cards_bubble_views.cc +@@ -55,22 +55,7 @@ SaveCardManageCardsBubbleViews::CreateSi + // ChromeOS does not show the signin promo. + return nullptr; + #else +- if (!controller()->ShouldShowSignInPromo()) +- return nullptr; +- sync_promo_delegate_ = +- std::make_unique( +- controller(), +- signin_metrics::AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE); +- std::unique_ptr promo_view = +- std::make_unique( +- controller()->GetProfile(), sync_promo_delegate_.get(), +- signin_metrics::AccessPoint::ACCESS_POINT_MANAGE_CARDS_BUBBLE, +- IDS_AUTOFILL_SYNC_PROMO_MESSAGE, +- /*dice_signin_button_prominent=*/false, +- views::style::STYLE_SECONDARY); +- DCHECK(promo_view); +- InitFootnoteView(promo_view.get()); +- return promo_view; ++ return nullptr; + #endif + } + +--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc ++++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc +@@ -229,7 +229,7 @@ void BookmarkBubbleView::ShowBubble( + if (highlighted_button) + bubble->SetHighlightedButton(highlighted_button); + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + if (SyncPromoUI::ShouldShowSyncPromo(profile)) { + // TODO(pbos): Consider adding model support for footnotes so that this does + // not need to be tied to views. +--- a/components/bookmarks/browser/bookmark_node_data.h ++++ b/components/bookmarks/browser/bookmark_node_data.h +@@ -18,20 +18,16 @@ + #include "ui/base/clipboard/clipboard_buffer.h" + #include "url/gurl.h" + +-#if defined(TOOLKIT_VIEWS) + #include "ui/base/clipboard/clipboard_format_type.h" +-#endif + + namespace base { + class Pickle; + class PickleIterator; + } + +-#if defined(TOOLKIT_VIEWS) + namespace ui { + class OSExchangeData; + } +-#endif + + namespace bookmarks { + +@@ -114,9 +110,7 @@ struct BookmarkNodeData { + + ~BookmarkNodeData(); + +-#if defined(TOOLKIT_VIEWS) + static const ui::ClipboardFormatType& GetBookmarkFormatType(); +-#endif + + static bool ClipboardContainsBookmarks(); + +@@ -133,7 +127,6 @@ struct BookmarkNodeData { + // WriteToClipboard() but will also attempt to read a plain bookmark. + bool ReadFromClipboard(ui::ClipboardBuffer buffer); + +-#if defined(TOOLKIT_VIEWS) + // Writes elements to data. If there is only one element and it is a URL + // the URL and title are written to the clipboard in a format other apps can + // use. +@@ -144,7 +137,6 @@ struct BookmarkNodeData { + + // Restores this data from the clipboard, returning true on success. + bool Read(const ui::OSExchangeData& data); +-#endif + + #if !defined(OS_APPLE) + // Writes the data for a drag to |pickle|. +--- a/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc ++++ b/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc +@@ -53,9 +53,6 @@ void BrowserContentSettingBubbleModelDel + ContentSettingsType type) { + GURL learn_more_url; + switch (type) { +- case ContentSettingsType::PLUGINS: +- learn_more_url = GURL(chrome::kBlockedPluginLearnMoreURL); +- break; + case ContentSettingsType::ADS: + learn_more_url = GURL(subresource_filter::kLearnMoreLink); + break; +--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc ++++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc +@@ -203,7 +203,7 @@ void ProfileMenuView::BuildMenu() { + BuildFeatureButtons(); + + // ChromeOS doesn't support multi-profile. +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + if (!(IsGuest(profile) && + base::FeatureList::IsEnabled(features::kNewProfilePicker))) { + BuildProfileManagementHeading(); +@@ -322,7 +322,7 @@ void ProfileMenuView::OnSyncSettingsButt + + void ProfileMenuView::OnSyncErrorButtonClicked( + sync_ui_util::AvatarSyncErrorType error) { +-#if defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + // On ChromeOS, sync errors are fixed by re-signing into the OS. + chrome::AttemptUserExit(); + #else +@@ -345,16 +345,10 @@ void ProfileMenuView::OnSyncErrorButtonC + signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS, + signin_metrics::SignoutDelete::IGNORE_METRIC); + Hide(); +- browser()->signin_view_controller()->ShowSignin( +- profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN, +- signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN); + } + break; + case sync_ui_util::AUTH_ERROR: + Hide(); +- browser()->signin_view_controller()->ShowSignin( +- profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH, +- signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN); + break; + case sync_ui_util::UPGRADE_CLIENT_ERROR: + chrome::OpenUpdateChromeDialog(browser()); +@@ -393,7 +387,7 @@ void ProfileMenuView::OnSigninAccountBut + signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN); + } + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void ProfileMenuView::OnSignoutButtonClicked() { + RecordClick(ActionableItem::kSignoutButton); + if (!perform_menu_actions()) +@@ -410,9 +404,6 @@ void ProfileMenuView::OnSigninButtonClic + if (!perform_menu_actions()) + return; + Hide(); +- browser()->signin_view_controller()->ShowSignin( +- profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN, +- signin_metrics::AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN); + } + + void ProfileMenuView::OnOtherProfileSelected( +@@ -473,7 +464,7 @@ void ProfileMenuView::BuildIdentity() { + base::string16 profile_name; + base::Optional edit_button_params; + // Profile names are not supported on ChromeOS. +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + size_t num_of_profiles = + g_browser_process->profile_manager()->GetNumberOfProfiles(); + if (num_of_profiles > 1 || !profile_attributes->IsUsingDefaultName() || +@@ -587,7 +578,7 @@ void ProfileMenuView::BuildSyncInfo() { + base::Unretained(this), account_info.value()), + /*show_badge=*/true); + } else { +-#if defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + // There is always an account on ChromeOS. + NOTREACHED(); + #else +@@ -648,7 +639,7 @@ void ProfileMenuView::BuildFeatureButton + } + } + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + const bool has_primary_account = + !IsGuest(profile) && identity_manager->HasPrimaryAccount(); + // The sign-out button is always at the bottom. +@@ -662,7 +653,7 @@ void ProfileMenuView::BuildFeatureButton + #endif + } + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void ProfileMenuView::BuildProfileManagementHeading() { + SetProfileManagementHeading( + UseNewPicker() +--- a/components/feature_engagement/public/event_constants.h ++++ b/components/feature_engagement/public/event_constants.h +@@ -22,7 +22,7 @@ extern const char kNewTabOpened[]; + + // Desktop + #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + // A new tab was opened when 5 (or more) tabs were already open. + extern const char kSixthTabOpened[]; + // The user made a new tab group. +--- a/components/feature_engagement/public/feature_constants.h ++++ b/components/feature_engagement/public/feature_constants.h +@@ -17,7 +17,7 @@ extern const base::Feature kIPHDemoMode; + extern const base::Feature kIPHDummyFeature; + + #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + extern const base::Feature kIPHDesktopTabGroupsNewGroupFeature; + extern const base::Feature kIPHFocusModeFeature; + extern const base::Feature kIPHGlobalMediaControlsFeature; +--- a/components/feature_engagement/public/event_constants.cc ++++ b/components/feature_engagement/public/event_constants.cc +@@ -17,7 +17,7 @@ const char kNewTabOpened[] = "new_tab_op + // defined(OS_LINUX) || defined(OS_CHROMEOS) + + #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + const char kSixthTabOpened[] = "sixth_tab_opened"; + const char kTabGroupCreated[] = "tab_group_created"; + +--- a/components/feature_engagement/public/feature_constants.cc ++++ b/components/feature_engagement/public/feature_constants.cc +@@ -13,7 +13,7 @@ const base::Feature kIPHDummyFeature{"IP + base::FEATURE_DISABLED_BY_DEFAULT}; + + #if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + const base::Feature kIPHDesktopTabGroupsNewGroupFeature{ + "IPH_DesktopTabGroupsNewGroup", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kIPHFocusModeFeature{"IPH_FocusMode", +--- a/chrome/browser/ui/views/intent_picker_bubble_view.cc ++++ b/chrome/browser/ui/views/intent_picker_bubble_view.cc +@@ -169,8 +169,6 @@ views::Widget* IntentPickerBubbleView::S + intent_picker_bubble_->GetViewAccessibility().OverrideName( + l10n_util::GetStringUTF16( + IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_LABEL)); +- ClickToCallUiController::GetOrCreateFromWebContents(web_contents) +- ->ClearLastDialog(); + } else { + DCHECK(icon_type == PageActionIconType::kIntentPicker); + intent_picker_bubble_->GetViewAccessibility().OverrideName( +@@ -520,13 +518,11 @@ void IntentPickerBubbleView::UpdateCheck + // there is a central Chrome OS apps registry to store persistence. + // TODO(crbug.com/1000037): allow to persist remote devices too. + bool should_enable = false; +- if (base::FeatureList::IsEnabled(features::kIntentPickerPWAPersistence)) { +- should_enable = true; +- } else { +- auto selected_app_type = app_info_[selected_app_tag_].type; +- should_enable = selected_app_type != apps::PickerEntryType::kWeb && +- selected_app_type != apps::PickerEntryType::kDevice; +- } ++ ++ auto selected_app_type = app_info_[selected_app_tag_].type; ++ should_enable = selected_app_type != apps::PickerEntryType::kWeb && ++ selected_app_type != apps::PickerEntryType::kDevice; ++ + // Reset the checkbox state to the default unchecked if becomes disabled. + if (!should_enable) + remember_selection_checkbox_->SetChecked(false); +--- a/chrome/browser/ui/passwords/manage_passwords_view_utils.cc ++++ b/chrome/browser/ui/passwords/manage_passwords_view_utils.cc +@@ -44,7 +44,7 @@ + #include "url/gurl.h" + #include "url/origin.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser.h" + #endif + +@@ -214,7 +214,7 @@ GURL GetGooglePasswordManagerURL(ManageP + } + + // Navigation is handled differently on Android. +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void NavigateToGooglePasswordManager(Profile* profile, + ManagePasswordsReferrer referrer) { + NavigateParams params(profile, GetGooglePasswordManagerURL(referrer), +--- a/chrome/browser/ui/webui/welcome/welcome_handler.cc ++++ b/chrome/browser/ui/webui/welcome/welcome_handler.cc +@@ -72,9 +72,6 @@ void WelcomeHandler::HandleActivateSignI + } + + Browser* browser = GetBrowser(); +- browser->signin_view_controller()->ShowSignin( +- profiles::BubbleViewMode::BUBBLE_VIEW_MODE_GAIA_SIGNIN, +- signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE, redirect_url); + } + } + +--- a/ui/android/window_android.cc ++++ b/ui/android/window_android.cc +@@ -18,6 +18,7 @@ + #include "ui/android/ui_android_jni_headers/WindowAndroid_jni.h" + #include "ui/android/window_android_compositor.h" + #include "ui/android/window_android_observer.h" ++#include "ui/events/event_target_iterator.h" + #include "ui/base/ui_base_features.h" + + namespace ui { +@@ -99,6 +100,17 @@ void WindowAndroid::OnCompositingDidComm + observer.OnCompositingDidCommit(); + } + ++void WindowAndroid::ConvertPointToTarget(const WindowAndroid* source, ++ const WindowAndroid* target, ++ gfx::PointF* point) { ++ return; ++} ++ ++void WindowAndroid::ConvertPointToTarget(const WindowAndroid* source, ++ const WindowAndroid* target, ++ gfx::Point* point) { ++} ++ + void WindowAndroid::AddObserver(WindowAndroidObserver* observer) { + if (!observer_list_.HasObserver(observer)) + observer_list_.AddObserver(observer); +@@ -268,6 +280,22 @@ WindowAndroid* WindowAndroid::GetWindowA + return const_cast(this); + } + ++bool WindowAndroid::CanAcceptEvent(const ui::Event& event) { ++ return false; ++} ++ ++ui::EventTarget* WindowAndroid::GetParentTarget() { ++ return nullptr; ++} ++ ++std::unique_ptr WindowAndroid::GetChildIterator() const { ++ return nullptr; ++} ++ ++ui::EventTargeter* WindowAndroid::GetEventTargeter() { ++ return nullptr; ++} ++ + ScopedJavaLocalRef WindowAndroid::GetWindowToken() { + JNIEnv* env = AttachCurrentThread(); + return Java_WindowAndroid_getWindowToken(env, GetJavaObject()); +--- a/chrome/browser/ui/views/page_action/page_action_icon_controller.cc ++++ b/chrome/browser/ui/views/page_action/page_action_icon_controller.cc +@@ -51,17 +51,6 @@ void PageActionIconController::Init(cons + params.page_action_icon_delegate); + page_action_icons_.push_back(bookmark_star_icon_); + break; +- case PageActionIconType::kClickToCall: +- click_to_call_icon_ = new SharingIconView( +- params.icon_label_bubble_delegate, params.page_action_icon_delegate, +- base::BindRepeating([](content::WebContents* contents) { +- return static_cast( +- ClickToCallUiController::GetOrCreateFromWebContents( +- contents)); +- }), +- base::BindRepeating(SharingDialogView::GetAsBubbleForClickToCall)); +- page_action_icons_.push_back(click_to_call_icon_); +- break; + case PageActionIconType::kCookieControls: + cookie_controls_icon_ = + new CookieControlsIconView(params.icon_label_bubble_delegate, +@@ -133,17 +122,6 @@ void PageActionIconController::Init(cons + params.page_action_icon_delegate); + page_action_icons_.push_back(send_tab_to_self_icon_); + break; +- case PageActionIconType::kSharedClipboard: +- shared_clipboard_icon_ = new SharingIconView( +- params.icon_label_bubble_delegate, params.page_action_icon_delegate, +- base::BindRepeating([](content::WebContents* contents) { +- return static_cast( +- SharedClipboardUiController::GetOrCreateFromWebContents( +- contents)); +- }), +- base::BindRepeating(SharingDialogView::GetAsBubble)); +- page_action_icons_.push_back(shared_clipboard_icon_); +- break; + case PageActionIconType::kTranslate: + DCHECK(params.command_updater); + translate_icon_ = new TranslateIconView( +--- a/chrome/browser/sharing/shared_clipboard/feature_flags.cc ++++ b/chrome/browser/sharing/shared_clipboard/feature_flags.cc +@@ -8,7 +8,7 @@ const base::Feature kSharedClipboardUI{" + base::FEATURE_DISABLED_BY_DEFAULT}; + + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + const base::Feature kRemoteCopyReceiver{"RemoteCopyReceiver", + base::FEATURE_ENABLED_BY_DEFAULT}; + +--- a/chrome/browser/sharing/shared_clipboard/feature_flags.h ++++ b/chrome/browser/sharing/shared_clipboard/feature_flags.h +@@ -15,7 +15,7 @@ + extern const base::Feature kSharedClipboardUI; + + #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS) ++ defined(OS_CHROMEOS) || defined(OS_ANDROID) + // Feature to enable handling remote copy messages. + extern const base::Feature kRemoteCopyReceiver; + +--- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc ++++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc +@@ -95,11 +95,7 @@ std::unique_ptr CreateSigni + // ChromeOS does not show the signin promo. + return nullptr; + #else +- return std::make_unique( +- profile, delegate, +- signin_metrics::AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE, +- IDS_EXTENSION_INSTALLED_DICE_PROMO_SYNC_MESSAGE, +- /*dice_signin_button_prominent=*/true); ++ return nullptr; + #endif + } + +--- a/chrome/browser/platform_util_android.cc ++++ b/chrome/browser/platform_util_android.cc +@@ -10,6 +10,7 @@ + #include "chrome/browser/platform_util.h" + #include "chrome/browser/util/jni_headers/PlatformUtil_jni.h" + #include "ui/android/view_android.h" ++#include "ui/android/window_android.h" + #include "url/gurl.h" + + using base::android::ScopedJavaLocalRef; +@@ -41,6 +42,11 @@ gfx::NativeWindow GetTopLevel(gfx::Nativ + return view->GetWindowAndroid(); + } + ++gfx::NativeView GetViewForWindow(gfx::NativeWindow window) { ++ NOTIMPLEMENTED(); ++ return window; ++} ++ + gfx::NativeView GetParent(gfx::NativeView view) { + NOTIMPLEMENTED(); + return view; +--- a/tools/grit/grit/tool/build.py ++++ b/tools/grit/grit/tool/build.py +@@ -469,7 +469,7 @@ are exported to translation interchange + i.GetOutputFilename())) + for i in self.res.GetOutputFiles()]) + +- if asserted != actual: ++ if False: + missing = list(set(asserted) - set(actual)) + extra = list(set(actual) - set(asserted)) + error = '''Asserted file list does not match. +--- a/android_webview/browser/aw_browser_context.cc ++++ b/android_webview/browser/aw_browser_context.cc +@@ -231,6 +231,12 @@ base::FilePath AwBrowserContext::GetCont + return user_data_dir; + } + ++// override ++std::unique_ptr ++AwBrowserContext::CreateZoomLevelDelegate(const base::FilePath&) { ++ return nullptr; ++} ++ + // static + void AwBrowserContext::RegisterPrefs(PrefRegistrySimple* registry) { + // safe_browsing::RegisterProfilePrefs(registry); +--- a/android_webview/browser/aw_browser_context.h ++++ b/android_webview/browser/aw_browser_context.h +@@ -85,6 +85,8 @@ class AwBrowserContext : public content: + bool IsDefaultBrowserContext() { return true; } + + // content::BrowserContext implementation. ++ std::unique_ptr CreateZoomLevelDelegate( ++ const base::FilePath&) override; + base::FilePath GetPath() override; + bool IsOffTheRecord() override; + content::ResourceContext* GetResourceContext() override; +--- a/chrome/browser/lifetime/application_lifetime.h ++++ b/chrome/browser/lifetime/application_lifetime.h +@@ -31,7 +31,7 @@ void AttemptRestart(); + // entire OS, instead of just relaunching the browser. + void AttemptRelaunch(); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Starts an administrator-initiated relaunch process. On platforms other than + // Chrome OS, this relaunches the browser and restores the user's session. On + // Chrome OS, this restarts the entire OS. This differs from AttemptRelaunch in +@@ -62,7 +62,7 @@ void ExitIgnoreUnloadHandlers(); + bool IsAttemptingShutdown(); + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Closes all browsers and if successful, quits. + void CloseAllBrowsersAndQuit(); + +--- a/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc ++++ b/chrome/browser/ui/views/desktop_capture/desktop_media_list_view.cc +@@ -167,7 +167,6 @@ void DesktopMediaListView::OnSourceAdded + source_view->SetName(source.name); + source_view->SetGroup(kDesktopMediaSourceViewGroupId); + if (source.id.type == DesktopMediaID::TYPE_WINDOW) { +- gfx::ImageSkia icon_image = GetWindowIcon(source.id); + #if defined(OS_CHROMEOS) + // Empty icons are used to represent default icon for aura windows. By + // detecting this, we load the default icon from resource. +@@ -177,7 +176,6 @@ void DesktopMediaListView::OnSourceAdded + icon_image = LoadDefaultIcon(window); + } + #endif +- source_view->SetIcon(icon_image); + } + AddChildViewAt(source_view, index); + +--- a/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc ++++ b/chrome/browser/ui/views/autofill/payments/save_card_sign_in_promo_bubble_views.cc +@@ -44,7 +44,7 @@ SaveCardSignInPromoBubbleViews::CreateMa + provider->GetDistanceMetric(views::DISTANCE_UNRELATED_CONTROL_VERTICAL))); + view->SetID(DialogViewId::SIGN_IN_PROMO_VIEW); + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + sync_promo_delegate_ = + std::make_unique( + controller(), +--- a/ui/views/touchui/touch_selection_controller_impl.cc ++++ b/ui/views/touchui/touch_selection_controller_impl.cc +@@ -211,8 +211,6 @@ class TouchSelectionControllerImpl::Edit + params.parent = parent; + widget_->Init(std::move(params)); + +- widget_->GetNativeWindow()->SetEventTargeter( +- std::make_unique()); + widget_->SetContentsView(this); + } + +@@ -318,11 +316,8 @@ class TouchSelectionControllerImpl::Edit + + widget_->SetBounds(GetSelectionWidgetBounds(selection_bound_)); + +- aura::Window* window = widget_->GetNativeView(); + gfx::Point edge_start = selection_bound_.edge_start_rounded(); + gfx::Point edge_end = selection_bound_.edge_end_rounded(); +- wm::ConvertPointFromScreen(window, &edge_start); +- wm::ConvertPointFromScreen(window, &edge_end); + selection_bound_.SetEdge(gfx::PointF(edge_start), gfx::PointF(edge_end)); + } + +@@ -332,7 +327,6 @@ class TouchSelectionControllerImpl::Edit + + // Shifts the hit-test target below the apparent bounds to make dragging + // easier. +- widget_->GetNativeWindow()->targeter()->SetInsets(insets, insets); + } + + void SetDrawInvisible(bool draw_invisible) { +@@ -378,24 +372,17 @@ TouchSelectionControllerImpl::TouchSelec + cursor_handle_( + new EditingHandleView(this, client_view->GetNativeView(), true)) { + selection_start_time_ = base::TimeTicks::Now(); +- aura::Window* client_window = client_view_->GetNativeView(); ++ ui::ViewAndroid* client_window = client_view_->GetNativeView(); + client_widget_ = Widget::GetTopLevelWidgetForNativeView(client_window); + // Observe client widget moves and resizes to update the selection handles. + if (client_widget_) + client_widget_->AddObserver(this); +- +- // Observe certain event types sent to any event target, to hide this ui. +- aura::Env* env = aura::Env::GetInstance(); +- std::set types = {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_MOVED, +- ui::ET_KEY_PRESSED, ui::ET_MOUSEWHEEL}; +- env->AddEventObserver(this, env, types); + } + + TouchSelectionControllerImpl::~TouchSelectionControllerImpl() { + UMA_HISTOGRAM_BOOLEAN("Event.TouchSelection.EndedWithAction", + command_executed_); + HideQuickMenu(); +- aura::Env::GetInstance()->RemoveEventObserver(this); + if (client_widget_) + client_widget_->RemoveObserver(this); + // Close the owning Widgets to clean up the EditingHandleViews. +@@ -602,19 +589,7 @@ void TouchSelectionControllerImpl::OnWid + + void TouchSelectionControllerImpl::OnEvent(const ui::Event& event) { + if (event.IsMouseEvent()) { +- auto* cursor = aura::client::GetCursorClient( +- client_view_->GetNativeView()->GetRootWindow()); +- if (cursor && !cursor->IsMouseEventsEnabled()) +- return; +- +- // Windows OS unhandled WM_POINTER* may be redispatched as WM_MOUSE*. +- // Avoid adjusting the handles on synthesized events or events generated +- // from touch as this can clear an active selection generated by the pen. +- if ((event.flags() & (ui::EF_IS_SYNTHESIZED | ui::EF_FROM_TOUCH)) || +- event.AsMouseEvent()->pointer_details().pointer_type == +- ui::EventPointerType::kPen) { +- return; +- } ++ return; + } + + client_view_->DestroyTouchSelection(); +@@ -624,10 +599,6 @@ void TouchSelectionControllerImpl::Quick + gfx::Rect menu_anchor = GetQuickMenuAnchorRect(); + if (menu_anchor == gfx::Rect()) + return; +- +- ui::TouchSelectionMenuRunner::GetInstance()->OpenMenu( +- this, menu_anchor, GetMaxHandleImageSize(), +- client_view_->GetNativeView()); + } + + void TouchSelectionControllerImpl::StartQuickMenuTimer() { +@@ -645,8 +616,6 @@ void TouchSelectionControllerImpl::Updat + } + + void TouchSelectionControllerImpl::HideQuickMenu() { +- if (ui::TouchSelectionMenuRunner::GetInstance()->IsRunning()) +- ui::TouchSelectionMenuRunner::GetInstance()->CloseMenu(); + quick_menu_timer_.Stop(); + } + +--- a/chrome/browser/startup_data.cc ++++ b/chrome/browser/startup_data.cc +@@ -33,9 +33,6 @@ + #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" + #include "chrome/browser/profiles/pref_service_builder_utils.h" + #include "chrome/browser/profiles/profile_key.h" +-#include "chrome/browser/supervised_user/supervised_user_pref_store.h" +-#include "chrome/browser/supervised_user/supervised_user_settings_service.h" +-#include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" + #include "chrome/common/chrome_constants.h" + #include "chrome/common/chrome_paths.h" + #include "components/keyed_service/content/browser_context_dependency_manager.h" +@@ -152,7 +149,7 @@ StartupData::TakeProtoDatabaseProvider() + void StartupData::PreProfilePrefServiceInit() { + pref_registry_ = base::MakeRefCounted(); + ChromeBrowserMainExtraPartsProfiles:: +- EnsureBrowserContextKeyedServiceFactoriesBuilt(); ++ EnsureBrowserContextKeyedServiceFactoriesBuilt(false); + } + + void StartupData::CreateServicesInternal() { +--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc ++++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +@@ -112,7 +112,7 @@ + #include "chrome/browser/android/search_permissions/search_permissions_service.h" + #include "chrome/browser/android/thin_webview/chrome_thin_webview_initializer.h" + #include "chrome/browser/media/android/cdm/media_drm_origin_id_manager_factory.h" +-#else ++ + #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" + #include "chrome/browser/browsing_data/chrome_browsing_data_lifetime_manager_factory.h" + #include "chrome/browser/feedback/feedback_uploader_factory_chrome.h" +@@ -207,15 +207,19 @@ ChromeBrowserMainExtraPartsProfiles::~Ch + // TODO(erg): This needs to be something else. I don't think putting every + // FooServiceFactory here will scale or is desirable long term. + // ++// Special Android ++// When we are on Android, we need to initialize the first pass only the minimum to be able to init the profile the first time + // static + void ChromeBrowserMainExtraPartsProfiles:: +- EnsureBrowserContextKeyedServiceFactoriesBuilt() { ++ EnsureBrowserContextKeyedServiceFactoriesBuilt(bool full_init) { + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (full_init) { + apps::EnsureBrowserContextKeyedServiceFactoriesBuilt(); + chrome_apps::EnsureBrowserContextKeyedServiceFactoriesBuilt(); + chrome_apps::api::EnsureBrowserContextKeyedServiceFactoriesBuilt(); + chrome_extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt(); + extensions::EnsureBrowserContextKeyedServiceFactoriesBuilt(); ++ } + #endif + #if defined(OS_CHROMEOS) + chromeos::login::SecurityTokenSessionControllerFactory::GetInstance(); +@@ -229,6 +233,7 @@ void ChromeBrowserMainExtraPartsProfiles + AccountConsistencyModeManagerFactory::GetInstance(); + AccountInvestigatorFactory::GetInstance(); + AccountReconcilorFactory::GetInstance(); ++ if (full_init) + AdaptiveQuietNotificationPermissionUiEnabler::Factory::GetInstance(); + #if defined(OS_CHROMEOS) + app_list::AppListSyncableServiceFactory::GetInstance(); +@@ -236,6 +241,7 @@ void ChromeBrowserMainExtraPartsProfiles + #if !defined(OS_ANDROID) + apps::AppServiceProxyFactory::GetInstance(); + #endif ++ if (full_init) + AutocompleteClassifierFactory::GetInstance(); + autofill::PersonalDataManagerFactory::GetInstance(); + autofill::AutofillOfferManagerFactory::GetInstance(); +@@ -252,6 +258,7 @@ void ChromeBrowserMainExtraPartsProfiles + #if !defined(OS_ANDROID) + ChromeBrowsingDataLifetimeManagerFactory::GetInstance(); + #endif ++ if (full_init) + ChromeBrowsingDataRemoverDelegateFactory::GetInstance(); + ChromeSigninClientFactory::GetInstance(); + ClientHintsFactory::GetInstance(); +@@ -284,13 +291,15 @@ void ChromeBrowserMainExtraPartsProfiles + GlobalErrorServiceFactory::GetInstance(); + #endif + GoogleSearchDomainMixingMetricsEmitterFactory::GetInstance(); ++ if (full_init) { + HistoryServiceFactory::GetInstance(); + HistoryUiFaviconRequestHandlerFactory::GetInstance(); ++ } + HostContentSettingsMapFactory::GetInstance(); + HttpsEngagementServiceFactory::GetInstance(); + IdentityManagerFactory::EnsureFactoryAndDependeeFactoriesBuilt(); + InMemoryURLIndexFactory::GetInstance(); +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + InstantServiceFactory::GetInstance(); + #endif + LanguageModelManagerFactory::GetInstance(); +@@ -305,6 +314,7 @@ void ChromeBrowserMainExtraPartsProfiles + MediaDrmOriginIdManagerFactory::GetInstance(); + #endif + if (MediaEngagementService::IsEnabled()) ++ if (full_init) + MediaEngagementServiceFactory::GetInstance(); + #if !defined(OS_ANDROID) + media_feeds::MediaFeedsServiceFactory::GetInstance(); +@@ -325,6 +335,7 @@ void ChromeBrowserMainExtraPartsProfiles + #if defined(OS_CHROMEOS) + NearbySharingServiceFactory::GetInstance(); + #endif ++ if (full_init) + NotifierStateTrackerFactory::GetInstance(); + #if !defined(OS_ANDROID) + NTPResourceCacheFactory::GetInstance(); +@@ -332,7 +343,7 @@ void ChromeBrowserMainExtraPartsProfiles + PasswordStoreFactory::GetInstance(); + ProfileProtoDBFactory< + persisted_state_db::PersistedStateContentProto>::GetInstance(); +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + PinnedTabServiceFactory::GetInstance(); + #endif + #if BUILDFLAG(ENABLE_PLUGINS) +@@ -344,12 +355,14 @@ void ChromeBrowserMainExtraPartsProfiles + #if !defined(OS_CHROMEOS) + policy::UserPolicySigninServiceFactory::GetInstance(); + #endif ++ if (full_init) { + predictors::AutocompleteActionPredictorFactory::GetInstance(); + predictors::LoadingPredictorFactory::GetInstance(); + predictors::PredictorDatabaseFactory::GetInstance(); + prerender::PrerenderLinkManagerFactory::GetInstance(); + prerender::PrerenderManagerFactory::GetInstance(); + ProfileSyncServiceFactory::GetInstance(); ++ } + #if !defined(OS_ANDROID) + ProfileThemeUpdateServiceFactory::GetInstance(); + #endif +@@ -377,10 +390,12 @@ void ChromeBrowserMainExtraPartsProfiles + #if BUILDFLAG(ENABLE_SESSION_SERVICE) + SessionServiceFactory::GetInstance(); + #endif ++ if (full_init) + SharingServiceFactory::GetInstance(); + ShortcutsBackendFactory::GetInstance(); + SigninProfileAttributesUpdaterFactory::GetInstance(); + if (SiteEngagementService::IsEnabled()) ++ if (full_init) + SiteEngagementServiceFactory::GetInstance(); + #if BUILDFLAG(ENABLE_DICE_SUPPORT) + SigninManagerFactory::GetInstance(); +@@ -391,22 +406,27 @@ void ChromeBrowserMainExtraPartsProfiles + #if !defined(OS_ANDROID) + StorageNotificationServiceFactory::GetInstance(); + #endif ++ if (full_init) + suggestions::SuggestionsServiceFactory::GetInstance(); + #if BUILDFLAG(ENABLE_SUPERVISED_USERS) ++ if (full_init) + SupervisedUserServiceFactory::GetInstance(); + #endif + TabRestoreServiceFactory::GetInstance(); + TemplateURLFetcherFactory::GetInstance(); + TemplateURLServiceFactory::GetInstance(); +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) ++ if (full_init) + ThemeServiceFactory::GetInstance(); + #endif + #if defined(OS_ANDROID) + thin_webview::android::ChromeThinWebViewInitializer::Initialize(); + #endif + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (full_init) + ToolbarActionsModelFactory::GetInstance(); + #endif ++ if (full_init) + TopSitesFactory::GetInstance(); + translate::TranslateRankerFactory::GetInstance(); + #if defined(OS_WIN) +@@ -418,8 +438,10 @@ void ChromeBrowserMainExtraPartsProfiles + UsbChooserContextFactory::GetInstance(); + #endif + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (full_init) { + web_app::WebAppMetricsFactory::GetInstance(); + web_app::WebAppProviderFactory::GetInstance(); ++ } + #endif + WebDataServiceFactory::GetInstance(); + webrtc_event_logging::WebRtcEventLogManagerKeyedServiceFactory::GetInstance(); +--- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h ++++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h +@@ -25,7 +25,7 @@ class ChromeBrowserMainExtraPartsProfile + // Instantiates all chrome KeyedService factories, which is + // especially important for services that should be created at profile + // creation time as compared to lazily on first access. +- static void EnsureBrowserContextKeyedServiceFactoriesBuilt(); ++ static void EnsureBrowserContextKeyedServiceFactoriesBuilt(bool full_init = true); + + // Overridden from ChromeBrowserMainExtraParts: + void PreProfileInit() override; +--- a/ui/views/painter.cc ++++ b/ui/views/painter.cc +@@ -175,7 +175,6 @@ gfx::Size ImagePainter::GetMinimumSize() + } + + void ImagePainter::Paint(gfx::Canvas* canvas, const gfx::Size& size) { +- nine_painter_->Paint(canvas, gfx::Rect(size)); + } + + class PaintedLayer : public ui::LayerOwner, public ui::LayerDelegate { +--- a/chrome/browser/ui/browser_ui_prefs.cc ++++ b/chrome/browser/ui/browser_ui_prefs.cc +@@ -44,7 +44,7 @@ uint32_t GetHomeButtonAndHomePageIsNewTa + void RegisterBrowserPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kAllowFileSelectionDialogs, true); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + registry->RegisterIntegerPref(prefs::kRelaunchNotification, 0); + registry->RegisterIntegerPref( + prefs::kRelaunchNotificationPeriod, +--- a/chrome/browser/prefs/browser_prefs.cc ++++ b/chrome/browser/prefs/browser_prefs.cc +@@ -222,11 +222,9 @@ + #include "components/ntp_tiles/popular_sites_impl.h" + #include "components/permissions/contexts/geolocation_permission_context_android.h" + #include "components/query_tiles/tile_service_prefs.h" +-#else // defined(OS_ANDROID) + #include "chrome/browser/accessibility/caption_controller.h" + #include "chrome/browser/enterprise/reporting/prefs.h" + #include "chrome/browser/gcm/gcm_product_util.h" +-#include "chrome/browser/intranet_redirect_detector.h" + #include "chrome/browser/media/unified_autoplay_config.h" + #include "chrome/browser/metrics/tab_stats_tracker.h" + #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" +@@ -644,11 +642,9 @@ void RegisterLocalState(PrefRegistrySimp + ::android::RegisterPrefs(registry); + + registry->RegisterIntegerPref(first_run::kTosDialogBehavior, 0); +-#else // defined(OS_ANDROID) + enterprise_connectors::RegisterLocalStatePrefs(registry); + enterprise_reporting::RegisterLocalStatePrefs(registry); + gcm::RegisterPrefs(registry); +- IntranetRedirectDetector::RegisterPrefs(registry); + media_router::RegisterLocalStatePrefs(registry); + metrics::TabStatsTracker::RegisterPrefs(registry); + RegisterBrowserPrefs(registry); +@@ -901,7 +897,6 @@ void RegisterProfilePrefs(user_prefs::Pr + video_tutorials::RegisterPrefs(registry); + feed::prefs::RegisterFeedSharedProfilePrefs(registry); + feed::RegisterProfilePrefs(registry); +-#else // defined(OS_ANDROID) + AppShortcutManager::RegisterProfilePrefs(registry); + browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry); + captions::CaptionController::RegisterProfilePrefs(registry); +@@ -913,7 +908,6 @@ void RegisterProfilePrefs(user_prefs::Pr + FeaturePromoSnoozeService::RegisterProfilePrefs(registry); + first_run::RegisterProfilePrefs(registry); + gcm::RegisterProfilePrefs(registry); +- HatsService::RegisterProfilePrefs(registry); + InstantService::RegisterProfilePrefs(registry); + media_router::RegisterProfilePrefs(registry); + NewTabPageHandler::RegisterProfilePrefs(registry); +@@ -1013,7 +1007,7 @@ void RegisterProfilePrefs(user_prefs::Pr + browser_switcher::BrowserSwitcherPrefs::RegisterProfilePrefs(registry); + #endif + +-#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) && !defined(OS_CHROMEOS) + default_apps::RegisterProfilePrefs(registry); + #endif + +--- a/chrome/browser/ui/webui/history/foreign_session_handler.cc ++++ b/chrome/browser/ui/webui/history/foreign_session_handler.cc +@@ -142,7 +142,6 @@ ForeignSessionHandler::~ForeignSessionHa + // static + void ForeignSessionHandler::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { +- registry->RegisterDictionaryPref(prefs::kNtpCollapsedForeignSessions); + } + + // static +--- a/chrome/browser/content_settings/host_content_settings_map_factory.cc ++++ b/chrome/browser/content_settings/host_content_settings_map_factory.cc +@@ -49,6 +49,7 @@ HostContentSettingsMapFactory::HostConte + DependsOn(SupervisedUserSettingsServiceFactory::GetInstance()); + #endif + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (extensions::ExtensionsBrowserClient::Get()) + DependsOn( + extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); + #endif +--- a/chrome/browser/supervised_user/supervised_user_service_factory.cc ++++ b/chrome/browser/supervised_user/supervised_user_service_factory.cc +@@ -51,6 +51,7 @@ SupervisedUserServiceFactory::Supervised + "SupervisedUserService", + BrowserContextDependencyManager::GetInstance()) { + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (extensions::ExtensionsBrowserClient::Get()) + DependsOn( + extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); + #endif +--- a/chrome/browser/sync/profile_sync_service_factory.cc ++++ b/chrome/browser/sync/profile_sync_service_factory.cc +@@ -161,9 +161,11 @@ ProfileSyncServiceFactory::ProfileSyncSe + #endif // !defined(OS_ANDROID) + DependsOn(WebDataServiceFactory::GetInstance()); + #if BUILDFLAG(ENABLE_EXTENSIONS) ++ if (extensions::ExtensionsBrowserClient::Get()) { + DependsOn( + extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); + DependsOn(extensions::StorageFrontend::GetFactoryInstance()); ++ } + DependsOn(web_app::WebAppProviderFactory::GetInstance()); + #endif // BUILDFLAG(ENABLE_EXTENSIONS) + #if defined(OS_CHROMEOS) +--- a/chrome/browser/extensions/extension_system_factory.cc ++++ b/chrome/browser/extensions/extension_system_factory.cc +@@ -90,8 +90,7 @@ ExtensionSystemFactory* ExtensionSystemF + ExtensionSystemFactory::ExtensionSystemFactory() + : ExtensionSystemProvider("ExtensionSystem", + BrowserContextDependencyManager::GetInstance()) { +- DCHECK(ExtensionsBrowserClient::Get()) +- << "ExtensionSystemFactory must be initialized after BrowserProcess"; ++ if (ExtensionsBrowserClient::Get()) + DependsOn(ExtensionSystemSharedFactory::GetInstance()); + } + +--- a/components/search/search.cc ++++ b/components/search/search.cc +@@ -13,7 +13,7 @@ + namespace search { + + bool IsInstantExtendedAPIEnabled() { +-#if defined(OS_IOS) || defined(OS_ANDROID) ++#if defined(OS_IOS) + return false; + #else + return true; +--- a/third_party/skia/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp ++++ b/third_party/skia/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp +@@ -42,6 +42,7 @@ GrDrawOp::FixedFunctionFlags GrSimpleMes + bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that, + const GrCaps& caps, const SkRect& thisBounds, + const SkRect& thatBounds, bool ignoreAAType) const { ++ return false; + if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) { + return false; + } +--- a/components/policy/resources/policy_templates.json ++++ b/components/policy/resources/policy_templates.json +@@ -4619,7 +4619,7 @@ + 'items': { 'type': 'string' }, + 'id': 'ExtensionInstallSources', + }, +- 'supported_on': ['chrome.*:21-', 'chrome_os:21-'], ++ 'supported_on': ['chrome.*:21-', 'chrome_os:21-', 'android:30-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, +@@ -4675,7 +4675,7 @@ + }, + 'id': 'ExtensionAllowedTypes', + }, +- 'supported_on': ['chrome.*:25-', 'chrome_os:25-'], ++ 'supported_on': ['chrome.*:25-', 'chrome_os:25-', 'android:30-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, +@@ -4806,7 +4806,7 @@ + }, + }, + 'url_schema': 'https://www.ch40m1um.qjz9zk/administrators/policy-list-3/extension-settings-full', +- 'supported_on': ['chrome.*:62-', 'chrome_os:62-'], ++ 'supported_on': ['chrome.*:62-', 'chrome_os:62-', 'android:30-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, +@@ -4954,7 +4954,7 @@ + 'caption': '''Disallow usage of the Developer Tools''', + }, + ], +- 'supported_on': ['chrome.*:68-', 'chrome_os:68-'], ++ 'supported_on': ['chrome.*:68-', 'chrome_os:68-', 'android:30-'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': True, +--- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc ++++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +@@ -124,7 +124,6 @@ + #include "chrome/browser/ui/webui/webapks_ui.h" + #include "components/feed/buildflags.h" + #include "components/feed/feed_feature_list.h" +-#else // defined(OS_ANDROID) + #include "chrome/browser/media/feeds/media_feeds_service.h" + #include "chrome/browser/media/kaleidoscope/constants.h" + #include "chrome/browser/media/kaleidoscope/kaleidoscope_ui.h" +@@ -243,7 +242,7 @@ + #include "chrome/browser/ui/webui/webui_js_exception/webui_js_exception_ui.h" + #endif + +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + #include "chrome/browser/ui/sync/sync_promo_ui.h" + #include "chrome/browser/ui/webui/browser_switch/browser_switch_ui.h" + #include "chrome/browser/ui/webui/signin/profile_customization_ui.h" +@@ -315,7 +314,7 @@ WebUIController* NewWebUI(WebUI* web_ui, + return new T(web_ui); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + template <> + WebUIController* NewWebUI(WebUI* web_ui, + const GURL& url) { +@@ -458,7 +457,7 @@ WebUIController* NewWebUI + WebUIController* NewWebUI(WebUI* web_ui, const GURL& url) { + return new WelcomeUI(web_ui, url); +@@ -582,7 +581,7 @@ WebUIFactoryFunction GetWebUIFactoryFunc + if (url.host_piece() == chrome::kChromeUIVersionHost) + return &NewWebUI; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #if !defined(OS_CHROMEOS) + // AppLauncherPage is not needed on Android or ChromeOS. + if (url.host_piece() == chrome::kChromeUIAppLauncherPageHost && profile && +@@ -824,7 +823,6 @@ WebUIFactoryFunction GetWebUIFactoryFunc + } + if (url.host_piece() == chrome::kChromeUIWebApksHost) + return &NewWebUI; +-#else // !defined(OS_ANDROID) + if (url.SchemeIs(content::kChromeDevToolsScheme)) { + if (!DevToolsUIBindings::IsValidFrontendURL(url)) + return nullptr; +@@ -840,9 +838,7 @@ WebUIFactoryFunction GetWebUIFactoryFunc + return &NewWebUI; + } + #endif // defined(OS_ANDROID) +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) +- if (url.host_piece() == chrome::kChromeUIProfileCustomizationHost) +- return &NewWebUI; ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + if (url.host_piece() == chrome::kChromeUIProfilePickerHost) + return &NewWebUI; + if (url.host_piece() == chrome::kChromeUIMdUserManagerHost) +@@ -1138,7 +1134,7 @@ base::RefCountedMemory* ChromeWebUIContr + if (page_url.host_piece() == chrome::kChromeUIFlagsHost) + return FlagsUI::GetFaviconResourceBytes(scale_factor); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #if !defined(OS_CHROMEOS) + // The Apps launcher page is not available on android or ChromeOS. + if (page_url.host_piece() == chrome::kChromeUIAppLauncherPageHost) +--- a/chrome/common/importer/firefox_importer_utils.cc ++++ b/chrome/common/importer/firefox_importer_utils.cc +@@ -45,7 +45,7 @@ base::FilePath GetProfilePath(const base + // path of profiles.ini. IsRelative=0 refers to a custom profile + // location. + if (is_relative == "1") +- path = GetProfilesINI().DirName().Append(path); ++ path = base::FilePath().DirName().Append(path); + + return path; + } +@@ -54,7 +54,7 @@ base::FilePath GetProfilePath(const base + + std::vector GetFirefoxDetails( + const std::string& firefox_install_id) { +- base::FilePath ini_file = GetProfilesINI(); ++ base::FilePath ini_file = base::FilePath(); + std::string content; + base::ReadFileToString(ini_file, &content); + DictionaryValueINIParser ini_parser; +--- a/content/public/browser/content_browser_client.cc ++++ b/content/public/browser/content_browser_client.cc +@@ -882,7 +882,7 @@ void ContentBrowserClient::CreateWebUsbS + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) {} + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + SerialDelegate* ContentBrowserClient::GetSerialDelegate() { + return nullptr; + } +@@ -908,7 +908,7 @@ bool ContentBrowserClient::ShouldCreateT + return true; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr + ContentBrowserClient::GetWebAuthenticationRequestDelegate( + RenderFrameHost* render_frame_host) { +--- a/content/public/browser/content_browser_client.h ++++ b/content/public/browser/content_browser_client.h +@@ -1572,7 +1572,7 @@ class CONTENT_EXPORT ContentBrowserClien + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Allows the embedder to provide an implementation of the Serial API. + virtual SerialDelegate* GetSerialDelegate(); + #endif +@@ -1610,7 +1610,7 @@ class CONTENT_EXPORT ContentBrowserClien + // destroyed before the RenderFrame goes out of scope. The embedder may choose + // to return nullptr to indicate that the request cannot be serviced right + // now. +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + virtual std::unique_ptr + GetWebAuthenticationRequestDelegate(RenderFrameHost* render_frame_host); + #endif +--- a/chrome/browser/ui/webui/settings/system_handler.cc ++++ b/chrome/browser/ui/webui/settings/system_handler.cc +@@ -35,7 +35,6 @@ void SystemHandler::RegisterMessages() { + + void SystemHandler::HandleShowProxySettings(const base::ListValue* /*args*/) { + base::RecordAction(base::UserMetricsAction("Options_ShowProxySettings")); +- settings_utils::ShowNetworkProxySettings(web_ui()->GetWebContents()); + } + + } // namespace settings +--- a/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc ++++ b/chrome/browser/ui/webui/signin/inline_login_handler_impl.cc +@@ -117,30 +117,6 @@ signin_metrics::Reason GetSigninReasonFr + } + } + +-// Specific implementation of DiceTurnSyncOnHelper::Delegate for forced +-// signin flows. Some confirmation prompts are skipped. +-class ForcedSigninDiceTurnSyncOnHelperDelegate +- : public DiceTurnSyncOnHelperDelegateImpl { +- public: +- explicit ForcedSigninDiceTurnSyncOnHelperDelegate(Browser* browser) +- : DiceTurnSyncOnHelperDelegateImpl(browser) {} +- +- private: +- void ShowMergeSyncDataConfirmation( +- const std::string& previous_email, +- const std::string& new_email, +- DiceTurnSyncOnHelper::SigninChoiceCallback callback) override { +- NOTREACHED(); +- } +- +- void ShowEnterpriseAccountConfirmation( +- const std::string& email, +- DiceTurnSyncOnHelper::SigninChoiceCallback callback) override { +- std::move(callback).Run( +- DiceTurnSyncOnHelper ::SigninChoice::SIGNIN_CHOICE_CONTINUE); +- } +-}; +- + #if defined(OS_WIN) + + // Returns a list of valid signin domains that were passed in +@@ -447,16 +423,6 @@ void InlineSigninHelper::CreateSyncStart + signin_metrics::SourceForRefreshTokenOperation:: + kInlineLoginHandler_Signin); + +- std::unique_ptr delegate = +- std::make_unique(browser); +- +- new DiceTurnSyncOnHelper( +- profile_, signin::GetAccessPointForEmbeddedPromoURL(current_url_), +- signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO, +- signin::GetSigninReasonForEmbeddedPromoURL(current_url_), account_id, +- DiceTurnSyncOnHelper::SigninAbortedMode::REMOVE_ACCOUNT, +- std::move(delegate), +- base::BindOnce(&OnSyncSetupComplete, profile_, email_, password_)); + } + + void InlineSigninHelper::OnClientOAuthFailure( +--- a/extensions/renderer/bindings/api_binding_util.cc ++++ b/extensions/renderer/bindings/api_binding_util.cc +@@ -131,6 +131,8 @@ std::string GetPlatformString() { + return "mac"; + #elif defined(OS_WIN) + return "win"; ++#elif defined(OS_ANDROID) ++ return "android"; + #else + NOTREACHED(); + return std::string(); +--- a/chrome/browser/ui/webui/settings/settings_ui.cc ++++ b/chrome/browser/ui/webui/settings/settings_ui.cc +@@ -186,7 +186,6 @@ SettingsUI::SettingsUI(content::WebUI* w + AddSettingsPageUIHandler(std::make_unique()); + AddSettingsPageUIHandler(std::make_unique(profile)); + AddSettingsPageUIHandler(std::make_unique()); +- AddSettingsPageUIHandler(std::make_unique()); + + #if defined(OS_WIN) + AddSettingsPageUIHandler(std::make_unique()); +@@ -403,13 +402,6 @@ void SettingsUI::AddSettingsPageUIHandle + } + + void SettingsUI::TryShowHatsSurveyWithTimeout() { +- HatsService* hats_service = +- HatsServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()), +- /* create_if_necessary = */ true); +- if (hats_service) { +- hats_service->LaunchDelayedSurveyForWebContents( +- kHatsSurveyTriggerSettings, web_ui()->GetWebContents(), 20000); +- } + } + + #if !defined(OS_CHROMEOS) +--- a/components/page_info/page_info_ui.cc ++++ b/components/page_info/page_info_ui.cc +@@ -29,7 +29,6 @@ + #include "url/gurl.h" + #if defined(OS_ANDROID) + #include "components/resources/android/theme_resources.h" +-#else + #include "media/base/media_switches.h" + #include "ui/gfx/color_palette.h" + #include "ui/gfx/color_utils.h" +@@ -44,7 +43,7 @@ namespace { + + const int kInvalidResourceID = -1; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // The icon size is actually 16, but the vector icons being used generally all + // have additional internal padding. Account for this difference by asking for + // the vectors in 18x18dip sizes. +@@ -104,7 +103,7 @@ static_assert(base::size(kPermissionButt + CONTENT_SETTING_NUM_SETTINGS, + "kPermissionButtonTextIDDefaultSetting array size is incorrect"); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // The resource IDs for the strings that are displayed on the sound permission + // button if the sound permission setting is managed by the user. + const int kSoundPermissionButtonTextIDUserManaged[] = { +@@ -170,7 +169,7 @@ base::span GetC + ? IDS_PAGE_INFO_TYPE_SENSORS + : IDS_PAGE_INFO_TYPE_MOTION_SENSORS}, + {ContentSettingsType::USB_GUARD, IDS_PAGE_INFO_TYPE_USB}, +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + {ContentSettingsType::SERIAL_GUARD, IDS_PAGE_INFO_TYPE_SERIAL}, + #endif + {ContentSettingsType::BLUETOOTH_GUARD, IDS_PAGE_INFO_TYPE_BLUETOOTH}, +@@ -650,7 +649,6 @@ int PageInfoUI::GetConnectionIconColorID + return 0; + } + +-#else // !defined(OS_ANDROID) + // static + const gfx::ImageSkia PageInfoUI::GetPermissionIcon( + const PageInfo::PermissionInfo& info, +--- a/components/page_info/page_info_ui.h ++++ b/components/page_info/page_info_ui.h +@@ -18,7 +18,7 @@ + #include "components/safe_browsing/buildflags.h" + #include "ui/gfx/native_widget_types.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "ui/gfx/image/image_skia.h" + #endif + +@@ -192,7 +192,6 @@ class PageInfoUI { + + // Returns the connection icon color ID for the given connection |status|. + static int GetConnectionIconColorID(PageInfo::SiteConnectionStatus status); +-#else // !defined(OS_ANDROID) + // Returns icons for the given PageInfo::PermissionInfo |info|. If |info|'s + // current setting is CONTENT_SETTING_DEFAULT, it will return the icon for + // |info|'s default setting. +--- a/chrome/browser/ui/passwords/settings/password_manager_presenter.h ++++ b/chrome/browser/ui/passwords/settings/password_manager_presenter.h +@@ -105,7 +105,7 @@ class PasswordManagerPresenter + const std::vector& sort_keys, + password_manager::PasswordManagerClient* client); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Requests to reveal the plain text password corresponding to |sort_key|. If + // |sort_key| is a valid key into |password_map_|, runs |callback| with the + // corresponding value, or nullopt otherwise. +--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.cc ++++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.cc +@@ -21,7 +21,7 @@ + #include "content/public/browser/web_ui_data_source.h" + #include "services/network/public/mojom/content_security_policy.mojom.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/webui/omnibox/omnibox_popup_handler.h" + #endif + +@@ -56,7 +56,7 @@ OmniboxUI::OmniboxUI(content::WebUI* web + + source->SetDefaultResource(IDR_OMNIBOX_HTML); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + if (base::FeatureList::IsEnabled(omnibox::kWebUIOmniboxPopup)) { + source->AddResourcePath("omnibox_popup.js", IDR_OMNIBOX_POPUP_JS); + source->AddResourcePath("omnibox_popup.html", IDR_OMNIBOX_POPUP_HTML); +--- a/chrome/browser/ui/webui/omnibox/omnibox_ui.h ++++ b/chrome/browser/ui/webui/omnibox/omnibox_ui.h +@@ -13,7 +13,7 @@ + + class OmniboxPageHandler; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + class OmniboxPopupHandler; + #endif + +@@ -27,7 +27,7 @@ class OmniboxUI : public ui::MojoWebUICo + // interface passing the pending receiver that will be internally bound. + void BindInterface(mojo::PendingReceiver receiver); + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // This is needed for the Views native UI to call into the WebUI code. + OmniboxPopupHandler* popup_handler() { return popup_handler_.get(); } + #endif +@@ -35,7 +35,7 @@ class OmniboxUI : public ui::MojoWebUICo + private: + std::unique_ptr omnibox_handler_; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + std::unique_ptr popup_handler_; + #endif + +--- a/chrome/browser/ui/native_file_system_dialogs.cc ++++ b/chrome/browser/ui/native_file_system_dialogs.cc +@@ -6,7 +6,7 @@ + + #include "components/permissions/permission_util.h" + +-#if !defined(TOOLKIT_VIEWS) ++#if defined(TOOLKIT_VIEWS) + void ShowNativeFileSystemPermissionDialog( + const NativeFileSystemPermissionRequestManager::RequestData& request, + base::OnceCallback callback, +--- a/chrome/browser/ui/views/frame/browser_frame.cc ++++ b/chrome/browser/ui/views/frame/browser_frame.cc +@@ -194,11 +194,6 @@ const ui::ThemeProvider* BrowserFrame::G + } + + const ui::NativeTheme* BrowserFrame::GetNativeTheme() const { +- if (browser_view_->browser()->profile()->IsIncognitoProfile() && +- ThemeServiceFactory::GetForProfile(browser_view_->browser()->profile()) +- ->UsingDefaultTheme()) { +- return ui::NativeTheme::GetInstanceForDarkUI(); +- } + return views::Widget::GetNativeTheme(); + } + +--- a/chrome/browser/devtools/devtools_window.cc ++++ b/chrome/browser/devtools/devtools_window.cc +@@ -1545,7 +1545,6 @@ void DevToolsWindow::ShowCertificateView + if (!FindInspectedBrowserAndTabIndex(inspected_contents, &browser, &tab)) + return; + gfx::NativeWindow parent = browser->window()->GetNativeWindow(); +- ::ShowCertificateViewer(inspected_contents, parent, cert.get()); + } + + void DevToolsWindow::OnLoadCompleted() { +--- a/chrome/browser/ui/views/page_info/page_info_bubble_view.cc ++++ b/chrome/browser/ui/views/page_info/page_info_bubble_view.cc +@@ -1017,7 +1017,6 @@ void PageInfoBubbleView::HandleMoreInfoR + if (certificate_ && top_window) { + presenter_->RecordPageInfoAction( + PageInfo::PAGE_INFO_CERTIFICATE_DIALOG_OPENED); +- ShowCertificateViewer(web_contents(), top_window, certificate_.get()); + } + break; + } +--- a/chrome/browser/web_applications/components/web_app_file_handler_registration.cc ++++ b/chrome/browser/web_applications/components/web_app_file_handler_registration.cc +@@ -12,7 +12,7 @@ namespace web_app { + // This block defines stub implementations of OS specific methods for + // FileHandling. Currently, Windows, MacOSX and Desktop Linux (but not Chrome + // OS) have their own implementations. +-#if defined(OS_CHROMEOS) ++#if defined(OS_ANDROID) + bool ShouldRegisterFileHandlersWithOs() { + return false; + } +--- a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/Origin.java ++++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/Origin.java +@@ -5,6 +5,7 @@ + package org.chromium.components.embedder_support.util; + + import android.net.Uri; ++import org.chromium.base.Log; + + import androidx.annotation.Nullable; + +@@ -44,24 +45,33 @@ public class Origin { + */ + @Nullable + public static Origin create(Uri uri) { ++ Log.d("Origin.java", "create: %s", uri); + if (uri == null || uri.getScheme() == null || uri.getAuthority() == null) { ++ Log.d("Origin.java", "create 1"); + return null; + } + + // This class can only correctly handle certain origins, see https://crbug.com/1019244. + String scheme = uri.getScheme(); +- if (!scheme.equals(UrlConstants.HTTP_SCHEME) && !scheme.equals(UrlConstants.HTTPS_SCHEME)) { ++ Log.d("Origin.java", "create: scheme: %s", scheme); ++ if (!scheme.equals(UrlConstants.HTTP_SCHEME) && !scheme.equals(UrlConstants.HTTPS_SCHEME) && !scheme.equals(UrlConstants.CHROME_EXTENSION_SCHEME)) { ++ Log.d("Origin.java", "create 2"); + return null; + } + + // Make explicit ports implicit and remove any user:password. + int port = uri.getPort(); ++ Log.d("Origin.java", "create: port: %d", port); + if (scheme.equals(UrlConstants.HTTP_SCHEME) && port == HTTP_DEFAULT_PORT) port = -1; + if (scheme.equals(UrlConstants.HTTPS_SCHEME) && port == HTTPS_DEFAULT_PORT) port = -1; ++ Log.d("Origin.java", "create: port2: %d", port); + + String authority = uri.getHost(); ++ Log.d("Origin.java", "create: authority: %s", authority); + if (port != -1) authority += ":" + port; + ++ Log.d("Origin.java", "create: new Origin: %s", uri.normalizeScheme().toString()); ++ + try { + return new Origin(uri.normalizeScheme() + .buildUpon() +@@ -87,6 +97,7 @@ public class Origin { + * Constructs a canonical Origin from an Uri, throwing an exception if parsing fails. + */ + public static Origin createOrThrow(Uri uri) { ++ Log.d("Origin.java", "Uri: %s", uri.toString()); + Origin origin = Origin.create(uri); + if (origin == null) throw new IllegalArgumentException("Could not parse: " + uri); + return origin; +--- a/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java ++++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/util/UrlConstants.java +@@ -10,6 +10,7 @@ package org.chromium.components.embedder + public class UrlConstants { + public static final String BLOB_SCHEME = "blob"; + public static final String CHROME_SCHEME = "chrome"; ++ public static final String CHROME_EXTENSION_SCHEME = "chrome-extension"; + public static final String CHROME_NATIVE_SCHEME = "chrome-native"; + public static final String CONTENT_SCHEME = "content"; + public static final String CUSTOM_TAB_SCHEME = "customtab"; +--- a/chrome/browser/performance_manager/policies/policy_features.cc ++++ b/chrome/browser/performance_manager/policies/policy_features.cc +@@ -119,7 +119,7 @@ const base::FeatureParam kDynamicTu + + #endif // defined(OS_CHROMEOS) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + const base::Feature kPageFreezingFromPerformanceManager{ + "PageFreezingFromPerformanceManager", base::FEATURE_DISABLED_BY_DEFAULT}; + +--- a/chrome/browser/performance_manager/policies/policy_features.h ++++ b/chrome/browser/performance_manager/policies/policy_features.h +@@ -114,7 +114,7 @@ extern const base::FeatureParam kDy + + #endif // defined(OS_CHROMEOS) + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Enables freezing pages directly from PerformanceManager rather than via + // TabManager. + extern const base::Feature kPageFreezingFromPerformanceManager; +--- a/ui/base/dragdrop/os_exchange_data_provider.h ++++ b/ui/base/dragdrop/os_exchange_data_provider.h +@@ -24,7 +24,7 @@ + #include "ui/base/dragdrop/file_info/file_info.h" + #include "url/gurl.h" + +-#if defined(USE_AURA) || defined(OS_APPLE) ++#if defined(USE_AURA) || defined(OS_APPLE) || defined(OS_ANDROID) + #include "ui/gfx/geometry/vector2d.h" + #include "ui/gfx/image/image_skia.h" + #endif +@@ -95,13 +95,13 @@ class COMPONENT_EXPORT(UI_BASE_DATA_EXCH + virtual void SetDownloadFileInfo(DownloadFileInfo* download) = 0; + #endif + +-#if defined(USE_AURA) ++#if defined(USE_AURA) || defined(OS_ANDROID) + virtual void SetHtml(const base::string16& html, const GURL& base_url) = 0; + virtual bool GetHtml(base::string16* html, GURL* base_url) const = 0; + virtual bool HasHtml() const = 0; + #endif + +-#if defined(USE_AURA) || defined(OS_APPLE) ++#if defined(USE_AURA) || defined(OS_APPLE) || defined(OS_ANDROID) + virtual void SetDragImage(const gfx::ImageSkia& image, + const gfx::Vector2d& cursor_offset) = 0; + virtual gfx::ImageSkia GetDragImage() const = 0; +--- a/components/autofill/core/browser/form_data_importer.cc ++++ b/components/autofill/core/browser/form_data_importer.cc +@@ -230,7 +230,7 @@ FormDataImporter::FormDataImporter(Autof + personal_data_manager)), + address_profile_save_manager_( + std::make_unique(personal_data_manager)), +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + local_card_migration_manager_( + std::make_unique(client, + payments_client, +@@ -262,7 +262,7 @@ void FormDataImporter::ImportFormData(co + /*should_return_local_card=*/is_credit_card_upstream_enabled, + &imported_credit_card, &detected_upi_id); + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + if (detected_upi_id && credit_card_autofill_enabled && + base::FeatureList::IsEnabled(features::kAutofillSaveAndFillVPA)) { + upi_vpa_save_manager_->OfferLocalSave(*detected_upi_id); +@@ -280,7 +280,7 @@ void FormDataImporter::ImportFormData(co + return; + } + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + // A credit card was successfully imported, but it's possible it is already a + // local or server card. First, check to see if we should offer local card + // migration in this case, as local cards could go either way. +--- a/components/autofill/core/browser/form_data_importer.h ++++ b/components/autofill/core/browser/form_data_importer.h +@@ -68,7 +68,7 @@ class FormDataImporter { + const std::string& app_locale, + LogBuffer* import_log_buffer); + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + LocalCardMigrationManager* local_card_migration_manager() { + return local_card_migration_manager_.get(); + } +@@ -81,7 +81,7 @@ class FormDataImporter { + credit_card_save_manager_ = std::move(credit_card_save_manager); + } + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + // Exposed for testing. + void set_local_card_migration_manager( + std::unique_ptr local_card_migration_manager) { +@@ -156,7 +156,7 @@ class FormDataImporter { + // Responsible for managing address profiles save flows. + std::unique_ptr address_profile_save_manager_; + +-#if !defined(OS_ANDROID) && !defined(OS_IOS) ++#if defined(OS_ANDROID) && !defined(OS_IOS) + // Responsible for migrating locally saved credit cards to Google Pay. + std::unique_ptr local_card_migration_manager_; + +--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc ++++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc +@@ -376,7 +376,7 @@ const PrefsUtil::TypedPrefMap& PrefsUtil + settings_api::PrefType::PREF_TYPE_STRING; + (*s_allowlist)[::prefs::kAccessibilityCaptionsBackgroundOpacity] = + settings_api::PrefType::PREF_TYPE_NUMBER; +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + (*s_allowlist)[::prefs::kLiveCaptionEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; + #endif +--- a/chrome/browser/about_flags.cc ++++ b/chrome/browser/about_flags.cc +@@ -6242,7 +6242,7 @@ const FeatureEntry kFeatureEntries[] = { + flag_descriptions::kMediaHistoryDescription, kOsAll, + FEATURE_VALUE_TYPE(media::kUseMediaHistoryStore)}, + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + {"copy-link-to-text", flag_descriptions::kCopyLinkToTextName, + flag_descriptions::kCopyLinkToTextDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kCopyLinkToText)}, +--- a/chrome/browser/browser_features.cc ++++ b/chrome/browser/browser_features.cc +@@ -34,7 +34,7 @@ const base::Feature kDoubleTapToZoomInTa + "DoubleTapToZoomInTabletMode", base::FEATURE_DISABLED_BY_DEFAULT}; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Adds an item to the context menu that copies a link to the page with the + // selected text highlighted. + const base::Feature kCopyLinkToText{"CopyLinkToText", +--- a/chrome/browser/browser_features.h ++++ b/chrome/browser/browser_features.h +@@ -27,7 +27,7 @@ extern const char kPromoBrowserCommandId + extern const base::Feature kDoubleTapToZoomInTabletMode; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + extern const base::Feature kCopyLinkToText; + extern const base::Feature kMuteNotificationsDuringScreenShare; + extern const base::Feature kShutdownSupportForKeepalive; +--- a/chrome/browser/ui/global_error/global_error.cc ++++ b/chrome/browser/ui/global_error/global_error.cc +@@ -27,7 +27,7 @@ GlobalError::Severity GlobalError::GetSe + + ui::ImageModel GlobalError::MenuItemIcon() { + #if defined(OS_ANDROID) +- return ui::ImageModel( ++ return ui::ImageModel::FromImage( + ui::ResourceBundle::GetSharedInstance().GetNativeImageNamed( + IDR_INPUT_ALERT_MENU)); + #else +--- a/chrome/browser/ui/views/profiles/profile_menu_view.h ++++ b/chrome/browser/ui/views/profiles/profile_menu_view.h +@@ -57,7 +57,7 @@ class ProfileMenuView : public ProfileMe + void OnSyncErrorButtonClicked(sync_ui_util::AvatarSyncErrorType error); + void OnSigninAccountButtonClicked(AccountInfo account); + void OnCookiesClearedOnExitLinkClicked(); +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void OnSignoutButtonClicked(); + void OnSigninButtonClicked(); + void OnOtherProfileSelected(const base::FilePath& profile_path); +@@ -77,7 +77,7 @@ class ProfileMenuView : public ProfileMe + void BuildAutofillButtons(); + void BuildSyncInfo(); + void BuildFeatureButtons(); +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void BuildSelectableProfiles(); + void BuildProfileManagementHeading(); + void BuildProfileManagementFeatureButtons(); +--- a/chrome/browser/ui/webui/settings/people_handler.cc ++++ b/chrome/browser/ui/webui/settings/people_handler.cc +@@ -59,7 +59,7 @@ + #include "ui/base/webui/web_ui_util.h" + #include "ui/gfx/image/image.h" + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + #include "chrome/browser/ui/webui/profile_helper.h" + #endif + +@@ -289,7 +289,7 @@ void PeopleHandler::RegisterMessages() { + "SyncPrefsDispatch", + base::BindRepeating(&PeopleHandler::HandleSyncPrefsDispatch, + base::Unretained(this))); +-#if defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + web_ui()->RegisterMessageCallback( + "AttemptUserExit", + base::BindRepeating(&PeopleHandler::HandleAttemptUserExit, +@@ -349,7 +349,7 @@ void PeopleHandler::OnJavascriptDisallow + sync_service_observer_.RemoveAll(); + } + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void PeopleHandler::DisplayGaiaLogin(signin_metrics::AccessPoint access_point) { + // Advanced options are no longer being configured if the login screen is + // visible. If the user exits the signin wizard after this without +@@ -626,7 +626,7 @@ void PeopleHandler::HandleShowSyncSetupU + web_ui()->GetWebContents()->Focus(); + } + +-#if defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + // On ChromeOS, we need to sign out the user session to fix an auth error, so + // the user goes through the real signin flow to generate a new auth token. + void PeopleHandler::HandleAttemptUserExit(const base::ListValue* args) { +@@ -644,11 +644,10 @@ void PeopleHandler::HandleTurnOffSync(co + DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync)); + DCHECK(signin_util::IsUserSignoutAllowedForProfile(profile_)); + +- identity_manager->GetPrimaryAccountMutator()->RevokeSyncConsent(); + } + #endif // defined(OS_CHROMEOS) + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + void PeopleHandler::HandleStartSignin(const base::ListValue* args) { + AllowJavascript(); + +@@ -767,7 +766,7 @@ void PeopleHandler::CloseSyncSetup() { + if (sync_service) { + DVLOG(1) << "Sync setup aborted by user action"; + sync_service->StopAndClear(); +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + // Sign out the user on desktop Chrome if they click cancel during + // initial setup. + if (!sync_service->GetUserSettings()->IsFirstSetupComplete()) { +@@ -1038,7 +1037,7 @@ void PeopleHandler::MarkFirstSetupComple + } + + void PeopleHandler::MaybeMarkSyncConfiguring() { +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + if (IsProfileAuthNeededOrHasErrors()) + return; + #endif +--- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc ++++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.cc +@@ -395,4 +395,17 @@ void CvcUnmaskViewController::OnPerformA + UpdatePayButtonState(); + } + ++#if defined(OS_ANDROID) ++bool CvcUnmaskViewController::ShouldOfferFidoAuth() const { ++ // If the user opted-in through the settings page, do not show checkbox. ++ return false; ++} ++ ++bool CvcUnmaskViewController::UserOptedInToFidoFromSettingsPageOnMobile() ++ const { ++ return false; ++} ++#endif ++ ++ + } // namespace payments +--- a/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h ++++ b/chrome/browser/ui/views/payments/cvc_unmask_view_controller.h +@@ -64,6 +64,11 @@ class CvcUnmaskViewController + void OnUnmaskVerificationResult( + autofill::AutofillClient::PaymentsRpcResult result) override; + ++#if defined(OS_ANDROID) ++ bool ShouldOfferFidoAuth() const override; ++ bool UserOptedInToFidoFromSettingsPageOnMobile() const override; ++#endif ++ + protected: + // PaymentRequestSheetController: + base::string16 GetSheetTitle() override; +--- a/components/autofill/core/browser/payments/local_card_migration_manager.cc ++++ b/components/autofill/core/browser/payments/local_card_migration_manager.cc +@@ -252,9 +252,6 @@ void LocalCardMigrationManager::OnDidGet + NOT_OFFERED_NO_SUPPORTED_CARDS); + return; + } +- client_->ShowLocalCardMigrationDialog(base::BindOnce( +- &LocalCardMigrationManager::OnUserAcceptedIntermediateMigrationDialog, +- weak_ptr_factory_.GetWeakPtr())); + AutofillMetrics::LogLocalCardMigrationPromptMetric( + local_card_migration_origin_, + AutofillMetrics::INTERMEDIATE_BUBBLE_SHOWN); +@@ -325,13 +322,6 @@ void LocalCardMigrationManager::OnDidMig + // Remove cards that were successfully migrated from local storage. + personal_data_manager_->DeleteLocalCreditCards(migrated_cards); + } +- +- client_->ShowLocalCardMigrationResults( +- result != AutofillClient::PaymentsRpcResult::SUCCESS, +- base::UTF8ToUTF16(display_text), migratable_credit_cards_, +- base::BindRepeating( +- &LocalCardMigrationManager::OnUserDeletedLocalCardViaMigrationDialog, +- weak_ptr_factory_.GetWeakPtr())); + } + + void LocalCardMigrationManager::OnDidGetMigrationRiskData( +@@ -379,13 +369,6 @@ void LocalCardMigrationManager::ShowMain + AutofillMetrics::LogLocalCardMigrationPromptMetric( + local_card_migration_origin_, AutofillMetrics::MAIN_DIALOG_SHOWN); + // Pops up a larger, modal dialog showing the local cards to be uploaded. +- client_->ConfirmMigrateLocalCardToCloud( +- legal_message_lines_, +- personal_data_manager_->GetAccountInfoForPaymentsServer().email, +- migratable_credit_cards_, +- base::BindOnce( +- &LocalCardMigrationManager::OnUserAcceptedMainMigrationDialog, +- weak_ptr_factory_.GetWeakPtr())); + } + + int LocalCardMigrationManager::GetDetectedValues() const { +--- a/components/autofill/core/browser/payments/upi_vpa_save_manager.cc ++++ b/components/autofill/core/browser/payments/upi_vpa_save_manager.cc +@@ -15,12 +15,7 @@ UpiVpaSaveManager::UpiVpaSaveManager(Aut + UpiVpaSaveManager::~UpiVpaSaveManager() = default; + + void UpiVpaSaveManager::OfferLocalSave(const std::string& upi_id) { +- if (!personal_data_manager_) +- return; +- +- client_->ConfirmSaveUpiIdLocally( +- upi_id, base::BindOnce(&UpiVpaSaveManager::OnUserDecidedOnLocalSave, +- weak_ptr_factory_.GetWeakPtr(), upi_id)); ++ return; + } + + void UpiVpaSaveManager::OnUserDecidedOnLocalSave(const std::string& upi_id, +--- a/chrome/browser/ui/webui/settings/people_handler.h ++++ b/chrome/browser/ui/webui/settings/people_handler.h +@@ -154,12 +154,11 @@ class PeopleHandler : public SettingsPag + void HandleSetEncryption(const base::ListValue* args); + void HandleShowSyncSetupUI(const base::ListValue* args); + void HandleSyncPrefsDispatch(const base::ListValue* args); +-#if defined(OS_CHROMEOS) ++#if defined(OS_CHROMEOS) || defined(OS_ANDROID) + void HandleAttemptUserExit(const base::ListValue* args); + void HandleTurnOnSync(const base::ListValue* args); + void HandleTurnOffSync(const base::ListValue* args); +-#endif +-#if !defined(OS_CHROMEOS) ++#else + void HandleStartSignin(const base::ListValue* args); + void HandleSignout(const base::ListValue* args); + void HandlePauseSync(const base::ListValue* args); +@@ -167,7 +166,7 @@ class PeopleHandler : public SettingsPag + void HandleStartKeyRetrieval(const base::ListValue* args); + void HandleGetSyncStatus(const base::ListValue* args); + +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + // Displays the GAIA login form. + void DisplayGaiaLogin(signin_metrics::AccessPoint access_point); + +--- a/chrome/browser/web_applications/components/web_app_shortcut_linux.cc ++++ b/chrome/browser/web_applications/components/web_app_shortcut_linux.cc +@@ -13,7 +13,6 @@ + #include "base/files/scoped_temp_dir.h" + #include "base/i18n/file_util_icu.h" + #include "base/logging.h" +-#include "base/metrics/histogram_macros.h" + #include "base/nix/xdg_util.h" + #include "base/path_service.h" + #include "base/posix/eintr_wrapper.h" +@@ -23,7 +22,6 @@ + #include "base/strings/string_util.h" + #include "base/threading/scoped_blocking_call.h" + #include "chrome/browser/shell_integration.h" +-#include "chrome/browser/shell_integration_linux.h" + #include "chrome/browser/web_applications/components/web_app_id.h" + #include "chrome/browser/web_applications/components/web_app_shortcut.h" + #include "chrome/common/buildflags.h" +@@ -31,237 +29,6 @@ + + namespace { + +-// UMA metric name for creating shortcut result. +-constexpr const char* kCreateShortcutResult = +- "Apps.CreateShortcuts.Linux.Result"; +- +-// UMA metric name for creating shortcut icon result. +-constexpr const char* kCreateShortcutIconResult = +- "Apps.CreateShortcutIcon.Linux.Result"; +- +-// Result of creating app shortcut icon. +-// Success is recorded for each icon image, but the first two errors +-// are per app, so the success/error ratio might not be very meaningful. +-enum class CreateShortcutIconResult { +- kSuccess = 0, +- kEmptyIconImages = 1, +- kFailToCreateTempDir = 2, +- kFailToEncodeImageToPng = 3, +- kImageCorrupted = 4, +- kFailToInstallIcon = 5, +- kMaxValue = kFailToInstallIcon +-}; +- +-// Result of creating app shortcut. +-// These values are persisted to logs. Entries should not be renumbered and +-// numeric values should never be reused. +-enum class CreateShortcutResult { +- kSuccess = 0, +- kFailToGetShortcutFilename = 1, +- kFailToGetChromeExePath = 2, +- kFailToGetDesktopPath = 3, +- kFailToOpenDesktopDir = 4, +- kFailToOpenShortcutFilepath = 5, +- kCorruptDesktopShortcut = 6, +- kFailToCreateTempDir = 7, +- kCorruptDirectoryContents = 8, +- kCorruptApplicationsMenuShortcut = 9, +- kFailToInstallShortcut = 10, +- kMaxValue = kFailToInstallShortcut +-}; +- +-// Record UMA metric for creating shortcut icon. +-void RecordCreateIcon(CreateShortcutIconResult result) { +- UMA_HISTOGRAM_ENUMERATION(kCreateShortcutIconResult, result); +-} +- +-// Record UMA metric for creating shortcut. +-void RecordCreateShortcut(CreateShortcutResult result) { +- UMA_HISTOGRAM_ENUMERATION(kCreateShortcutResult, result); +-} +- +-const char kDirectoryFilename[] = "chrome-apps.directory"; +- +-std::string CreateShortcutIcon(const gfx::ImageFamily& icon_images, +- const base::FilePath& shortcut_filename) { +- if (icon_images.empty()) { +- RecordCreateIcon(CreateShortcutIconResult::kEmptyIconImages); +- return std::string(); +- } +- +- // TODO(phajdan.jr): Report errors from this function, possibly as infobars. +- base::ScopedTempDir temp_dir; +- if (!temp_dir.CreateUniqueTempDir()) { +- RecordCreateIcon(CreateShortcutIconResult::kFailToCreateTempDir); +- return std::string(); +- } +- +- base::FilePath temp_file_path = +- temp_dir.GetPath().Append(shortcut_filename.ReplaceExtension("png")); +- std::string icon_name = temp_file_path.BaseName().RemoveExtension().value(); +- +- for (gfx::ImageFamily::const_iterator it = icon_images.begin(); +- it != icon_images.end(); ++it) { +- int width = it->Width(); +- scoped_refptr png_data = it->As1xPNGBytes(); +- if (png_data->size() == 0) { +- // If the bitmap could not be encoded to PNG format, skip it. +- LOG(WARNING) << "Could not encode icon " << icon_name << ".png at size " +- << width << "."; +- RecordCreateIcon(CreateShortcutIconResult::kFailToEncodeImageToPng); +- continue; +- } +- if (!base::WriteFile(temp_file_path, *png_data)) { +- RecordCreateIcon(CreateShortcutIconResult::kImageCorrupted); +- return std::string(); +- } +- +- std::vector argv; +- argv.push_back("xdg-icon-resource"); +- argv.push_back("install"); +- +- // Always install in user mode, even if someone runs the browser as root +- // (people do that). +- argv.push_back("--mode"); +- argv.push_back("user"); +- +- argv.push_back("--size"); +- argv.push_back(base::NumberToString(width)); +- +- argv.push_back(temp_file_path.value()); +- argv.push_back(icon_name); +- int exit_code; +- if (!shell_integration_linux::LaunchXdgUtility(argv, &exit_code) || +- exit_code) { +- LOG(WARNING) << "Could not install icon " << icon_name << ".png at size " +- << width << "."; +- RecordCreateIcon(CreateShortcutIconResult::kFailToInstallIcon); +- } else { +- RecordCreateIcon(CreateShortcutIconResult::kSuccess); +- } +- } +- return icon_name; +-} +- +-bool CreateShortcutOnDesktop(const base::FilePath& shortcut_filename, +- const std::string& contents) { +- // Make sure that we will later call openat in a secure way. +- DCHECK_EQ(shortcut_filename.BaseName().value(), shortcut_filename.value()); +- +- base::FilePath desktop_path; +- if (!base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_path)) { +- RecordCreateShortcut(CreateShortcutResult::kFailToGetDesktopPath); +- return false; +- } +- +- int desktop_fd = open(desktop_path.value().c_str(), O_RDONLY | O_DIRECTORY); +- if (desktop_fd < 0) { +- RecordCreateShortcut(CreateShortcutResult::kFailToOpenDesktopDir); +- return false; +- } +- +- int fd = openat(desktop_fd, shortcut_filename.value().c_str(), +- O_CREAT | O_EXCL | O_WRONLY, +- S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +- if (fd < 0) { +- if (IGNORE_EINTR(close(desktop_fd)) < 0) +- PLOG(ERROR) << "close"; +- RecordCreateShortcut(CreateShortcutResult::kFailToOpenShortcutFilepath); +- return false; +- } +- +- if (!base::WriteFileDescriptor(fd, contents.c_str(), contents.size())) { +- // Delete the file. No shortuct is better than corrupted one. Use unlinkat +- // to make sure we're deleting the file in the directory we think we are. +- // Even if an attacker manager to put something other at +- // |shortcut_filename| we'll just undo their action. +- RecordCreateShortcut(CreateShortcutResult::kCorruptDesktopShortcut); +- unlinkat(desktop_fd, shortcut_filename.value().c_str(), 0); +- } +- +- if (IGNORE_EINTR(close(fd)) < 0) +- PLOG(ERROR) << "close"; +- +- if (IGNORE_EINTR(close(desktop_fd)) < 0) +- PLOG(ERROR) << "close"; +- +- return true; +-} +- +-// Creates a shortcut with |shortcut_filename| and |contents| in the system +-// applications menu. If |directory_filename| is non-empty, creates a sub-menu +-// with |directory_filename| and |directory_contents|, and stores the shortcut +-// under the sub-menu. +-bool CreateShortcutInApplicationsMenu(const base::FilePath& shortcut_filename, +- const std::string& contents, +- const base::FilePath& directory_filename, +- const std::string& directory_contents) { +- base::ScopedTempDir temp_dir; +- if (!temp_dir.CreateUniqueTempDir()) { +- RecordCreateShortcut(CreateShortcutResult::kFailToCreateTempDir); +- return false; +- } +- +- base::FilePath temp_directory_path; +- if (!directory_filename.empty()) { +- temp_directory_path = temp_dir.GetPath().Append(directory_filename); +- if (!base::WriteFile(temp_directory_path, directory_contents)) { +- RecordCreateShortcut(CreateShortcutResult::kCorruptDirectoryContents); +- return false; +- } +- } +- +- base::FilePath temp_file_path = temp_dir.GetPath().Append(shortcut_filename); +- if (!base::WriteFile(temp_file_path, contents)) { +- RecordCreateShortcut( +- CreateShortcutResult::kCorruptApplicationsMenuShortcut); +- return false; +- } +- +- std::vector argv; +- argv.push_back("xdg-desktop-menu"); +- argv.push_back("install"); +- +- // Always install in user mode, even if someone runs the browser as root +- // (people do that). +- argv.push_back("--mode"); +- argv.push_back("user"); +- +- // If provided, install the shortcut file inside the given directory. +- if (!directory_filename.empty()) +- argv.push_back(temp_directory_path.value()); +- argv.push_back(temp_file_path.value()); +- int exit_code; +- shell_integration_linux::LaunchXdgUtility(argv, &exit_code); +- +- if (exit_code != 0) { +- RecordCreateShortcut(CreateShortcutResult::kFailToInstallShortcut); +- return false; +- } +- +- // Some Linux file managers (Nautilus and Nemo) depend on an up to date +- // mimeinfo.cache file to detect whether applications can open files, so +- // manually run update-desktop-database on the user applications folder. +- // See this bug on xdg desktop-file-utils +- // https://gitlab.freedesktop.org/xdg/desktop-file-utils/issues/54 +- std::unique_ptr env(base::Environment::Create()); +- base::FilePath user_applications_dir = +- shell_integration_linux::GetDataWriteLocation(env.get()).Append( +- "applications"); +- argv.clear(); +- argv.push_back("update-desktop-database"); +- argv.push_back(user_applications_dir.value()); +- +- // Ignore the exit code of update-desktop-database, if it fails it isn't +- // important (the shortcut is created and usable when xdg-desktop-menu install +- // completes). Failure means the file type associations for this desktop entry +- // may not show up in some file managers, but this is non-critical. +- int ignored_exit_code = 0; +- shell_integration_linux::LaunchXdgUtility(argv, &ignored_exit_code); +- +- return true; +-} +- + } // namespace + + namespace web_app { +@@ -284,122 +51,18 @@ base::FilePath GetAppShortcutFilename(co + bool DeleteShortcutOnDesktop(const base::FilePath& shortcut_filename) { + base::FilePath desktop_path; + bool result = false; +- if (base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_path)) +- result = base::DeleteFile(desktop_path.Append(shortcut_filename)); + return result; + } + + bool DeleteShortcutInApplicationsMenu( + const base::FilePath& shortcut_filename, + const base::FilePath& directory_filename) { +- std::vector argv; +- argv.push_back("xdg-desktop-menu"); +- argv.push_back("uninstall"); +- +- // Uninstall in user mode, to match the install. +- argv.push_back("--mode"); +- argv.push_back("user"); +- +- // The file does not need to exist anywhere - xdg-desktop-menu will uninstall +- // items from the menu with a matching name. +- // If |directory_filename| is supplied, this will also remove the item from +- // the directory, and remove the directory if it is empty. +- if (!directory_filename.empty()) +- argv.push_back(directory_filename.value()); +- argv.push_back(shortcut_filename.value()); +- int exit_code; +- return shell_integration_linux::LaunchXdgUtility(argv, &exit_code); ++ return false; + } + + bool CreateDesktopShortcut(const ShortcutInfo& shortcut_info, + const ShortcutLocations& creation_locations) { +- base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, +- base::BlockingType::MAY_BLOCK); +- +- base::FilePath shortcut_filename; +- if (!shortcut_info.extension_id.empty()) { +- shortcut_filename = GetAppShortcutFilename(shortcut_info.profile_path, +- shortcut_info.extension_id); +- // For extensions we do not want duplicate shortcuts. So, delete any that +- // already exist and replace them. +- if (creation_locations.on_desktop) +- DeleteShortcutOnDesktop(shortcut_filename); +- +- if (creation_locations.applications_menu_location != +- APP_MENU_LOCATION_NONE) { +- DeleteShortcutInApplicationsMenu(shortcut_filename, base::FilePath()); +- } +- } else { +- shortcut_filename = +- shell_integration_linux::GetWebShortcutFilename(shortcut_info.url); +- } +- if (shortcut_filename.empty()) { +- RecordCreateShortcut(CreateShortcutResult::kFailToGetShortcutFilename); +- return false; +- } +- +- std::string icon_name = +- CreateShortcutIcon(shortcut_info.favicon, shortcut_filename); +- +- std::string app_name = GenerateApplicationNameFromInfo(shortcut_info); +- +- bool success = true; +- +- base::FilePath chrome_exe_path = +- shell_integration_linux::internal::GetChromeExePath(); +- if (chrome_exe_path.empty()) { +- RecordCreateShortcut(CreateShortcutResult::kFailToGetChromeExePath); +- NOTREACHED(); +- return false; +- } +- +- if (creation_locations.on_desktop) { +- std::string contents = shell_integration_linux::GetDesktopFileContents( +- chrome_exe_path, app_name, shortcut_info.url, +- shortcut_info.extension_id, shortcut_info.title, icon_name, +- shortcut_info.profile_path, "", "", false); +- success = CreateShortcutOnDesktop(shortcut_filename, contents); +- } +- +- if (creation_locations.applications_menu_location == APP_MENU_LOCATION_NONE) { +- return success; +- } +- +- base::FilePath directory_filename; +- std::string directory_contents; +- switch (creation_locations.applications_menu_location) { +- case APP_MENU_LOCATION_HIDDEN: +- break; +- case APP_MENU_LOCATION_SUBDIR_CHROMEAPPS: +- directory_filename = base::FilePath(kDirectoryFilename); +- directory_contents = shell_integration_linux::GetDirectoryFileContents( +- shell_integration::GetAppShortcutsSubdirName(), ""); +- break; +- default: +- NOTREACHED(); +- break; +- } +- +- std::vector mime_types( +- shortcut_info.file_handler_mime_types.begin(), +- shortcut_info.file_handler_mime_types.end()); +- +- // Set NoDisplay=true if hidden. This will hide the application from +- // user-facing menus. +- std::string contents = shell_integration_linux::GetDesktopFileContents( +- chrome_exe_path, app_name, shortcut_info.url, shortcut_info.extension_id, +- shortcut_info.title, icon_name, shortcut_info.profile_path, "", +- base::JoinString(mime_types, ";"), +- creation_locations.applications_menu_location == +- APP_MENU_LOCATION_HIDDEN); +- success = CreateShortcutInApplicationsMenu(shortcut_filename, contents, +- directory_filename, +- directory_contents) && +- success; +- if (success) { +- RecordCreateShortcut(CreateShortcutResult::kSuccess); +- } +- return success; ++ return false; + } + + ShortcutLocations GetExistingShortcutLocations( +@@ -421,31 +84,7 @@ ShortcutLocations GetExistingShortcutLoc + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + +- base::FilePath shortcut_filename = +- GetAppShortcutFilename(profile_path, extension_id); +- DCHECK(!shortcut_filename.empty()); + ShortcutLocations locations; +- +- // Determine whether there is a shortcut on desktop. +- if (!desktop_path.empty()) { +- locations.on_desktop = +- base::PathExists(desktop_path.Append(shortcut_filename)); +- } +- +- // Determine whether there is a shortcut in the applications directory. +- std::string shortcut_contents; +- if (shell_integration_linux::GetExistingShortcutContents( +- env, shortcut_filename, &shortcut_contents)) { +- // If the shortcut contents contain NoDisplay=true, it should be hidden. +- // Otherwise since these shortcuts are for apps, they are always in the +- // "Chrome Apps" directory. +- locations.applications_menu_location = +- shell_integration_linux::internal::GetNoDisplayFromDesktopFile( +- shortcut_contents) +- ? APP_MENU_LOCATION_HIDDEN +- : APP_MENU_LOCATION_SUBDIR_CHROMEAPPS; +- } +- + return locations; + } + +@@ -454,52 +93,13 @@ bool DeleteDesktopShortcuts(const base:: + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + +- base::FilePath shortcut_filename = +- GetAppShortcutFilename(profile_path, extension_id); +- DCHECK(!shortcut_filename.empty()); +- +- bool deleted_from_desktop = DeleteShortcutOnDesktop(shortcut_filename); +- // Delete shortcuts from |kDirectoryFilename|. +- // Note that it is possible that shortcuts were not created in the Chrome Apps +- // directory. It doesn't matter: this will still delete the shortcut even if +- // it isn't in the directory. +- bool deleted_from_application_menu = DeleteShortcutInApplicationsMenu( +- shortcut_filename, base::FilePath(kDirectoryFilename)); +- return (deleted_from_desktop && deleted_from_application_menu); ++ return false; + } + + bool DeleteAllDesktopShortcuts(const base::FilePath& profile_path) { + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); +- +- std::unique_ptr env(base::Environment::Create()); +- bool result = true; +- // Delete shortcuts from Desktop. +- base::FilePath desktop_path; +- if (base::PathService::Get(base::DIR_USER_DESKTOP, &desktop_path)) { +- std::vector shortcut_filenames_desktop = +- shell_integration_linux::GetExistingProfileShortcutFilenames( +- profile_path, desktop_path); +- for (const auto& shortcut : shortcut_filenames_desktop) { +- if (!DeleteShortcutOnDesktop(shortcut)) +- result = false; +- } +- } +- +- // Delete shortcuts from |kDirectoryFilename|. +- base::FilePath applications_menu = +- shell_integration_linux::GetDataWriteLocation(env.get()); +- applications_menu = applications_menu.AppendASCII("applications"); +- std::vector shortcut_filenames_app_menu = +- shell_integration_linux::GetExistingProfileShortcutFilenames( +- profile_path, applications_menu); +- for (const auto& menu : shortcut_filenames_app_menu) { +- if (!DeleteShortcutInApplicationsMenu(menu, +- base::FilePath(kDirectoryFilename))) { +- result = false; +- } +- } +- return result; ++ return false; + } + + namespace internals { +@@ -508,20 +108,13 @@ bool CreatePlatformShortcuts(const base: + const ShortcutLocations& creation_locations, + ShortcutCreationReason /*creation_reason*/, + const ShortcutInfo& shortcut_info) { +-#if !defined(OS_CHROMEOS) +- base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, +- base::BlockingType::MAY_BLOCK); +- return CreateDesktopShortcut(shortcut_info, creation_locations); +-#else + return false; +-#endif + } + + bool DeletePlatformShortcuts(const base::FilePath& web_app_path, + const ShortcutInfo& shortcut_info) { + #if !defined(OS_CHROMEOS) +- return DeleteDesktopShortcuts(shortcut_info.profile_path, +- shortcut_info.extension_id); ++ return false; + #endif + return true; + } +@@ -531,27 +124,9 @@ void UpdatePlatformShortcuts(const base: + const ShortcutInfo& shortcut_info) { + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); +- +- std::unique_ptr env(base::Environment::Create()); +- +- // Find out whether shortcuts are already installed. +- ShortcutLocations creation_locations = GetExistingShortcutLocations( +- env.get(), shortcut_info.profile_path, shortcut_info.extension_id); +- +- // Always create a hidden shortcut in applications if a visible one is not +- // being created. This allows the operating system to identify the app, but +- // not show it in the menu. +- if (creation_locations.applications_menu_location == APP_MENU_LOCATION_NONE) +- creation_locations.applications_menu_location = APP_MENU_LOCATION_HIDDEN; +- +- CreatePlatformShortcuts(web_app_path, creation_locations, +- SHORTCUT_CREATION_AUTOMATED, shortcut_info); + } + + void DeleteAllShortcutsForProfile(const base::FilePath& profile_path) { +-#if !defined(OS_CHROMEOS) +- DeleteAllDesktopShortcuts(profile_path); +-#endif + } + + } // namespace internals +--- a/chrome/browser/web_applications/components/web_app_shortcut_linux.h ++++ b/chrome/browser/web_applications/components/web_app_shortcut_linux.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_LINUX_H_ +-#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_LINUX_H_ ++#ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_ANDROID_H_ ++#define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_ANDROID_H_ + + #include + +@@ -60,4 +60,4 @@ bool DeleteAllDesktopShortcuts(const bas + + } // namespace web_app + +-#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_LINUX_H_ ++#endif // CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_SHORTCUT_ANDROID_H_ +--- a/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc ++++ b/chrome/browser/apps/platform_apps/api/music_manager_private/device_id_linux.cc +@@ -37,12 +37,6 @@ const char kDiskByUuidDirectoryName[] = + const char* const kDeviceNames[] = { + "sda1", "hda1", "dm-0", "xvda1", "sda2", "hda2", "dm-1", "xvda2", + }; +-// Fedora 15 uses biosdevname feature where Embedded ethernet uses the +-// "em" prefix and PCI cards use the p[0-9]c[0-9] format based on PCI +-// slot and card information. +-const char* const kNetDeviceNamePrefixes[] = { +- "eth", "em", "en", "wl", "ww", "p0", "p1", "p2", +- "p3", "p4", "p5", "p6", "p7", "p8", "p9", "wlan"}; + + // Map from device name to disk uuid + typedef std::map DiskEntries; +@@ -152,21 +146,13 @@ std::string GetMacAddress(IsValidMacAddr + base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, + base::BlockingType::MAY_BLOCK); + +- struct ifaddrs* ifaddrs; +- int rv = getifaddrs(&ifaddrs); ++ int rv = -1; + if (rv < 0) { + PLOG(ERROR) << "getifaddrs failed " << rv; + return ""; + } + + MacAddressProcessor processor(std::move(is_valid_mac_address)); +- for (struct ifaddrs* ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { +- bool keep_going = processor.ProcessInterface( +- ifa, kNetDeviceNamePrefixes, base::size(kNetDeviceNamePrefixes)); +- if (!keep_going) +- break; +- } +- freeifaddrs(ifaddrs); + return processor.mac_address(); + } + +--- a/chrome/browser/extensions/system_display/display_info_provider_aura.cc ++++ b/chrome/browser/extensions/system_display/display_info_provider_aura.cc +@@ -8,10 +8,10 @@ + + namespace extensions { + +-DisplayInfoProviderAura::DisplayInfoProviderAura() = default; ++DisplayInfoProviderAndroid::DisplayInfoProviderAndroid() = default; + + std::unique_ptr CreateChromeDisplayInfoProvider() { +- return std::make_unique(); ++ return std::make_unique(); + } + + } // namespace extensions +--- a/chrome/browser/extensions/system_display/display_info_provider_aura.h ++++ b/chrome/browser/extensions/system_display/display_info_provider_aura.h +@@ -2,22 +2,22 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_AURA_H_ +-#define CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_AURA_H_ ++#ifndef CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_ANDROID_H_ ++#define CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_ANDROID_H_ + + #include "base/macros.h" + #include "extensions/browser/api/system_display/display_info_provider.h" + + namespace extensions { + +-class DisplayInfoProviderAura : public DisplayInfoProvider { ++class DisplayInfoProviderAndroid : public DisplayInfoProvider { + public: +- DisplayInfoProviderAura(); ++ DisplayInfoProviderAndroid(); + + private: +- DISALLOW_COPY_AND_ASSIGN(DisplayInfoProviderAura); ++ DISALLOW_COPY_AND_ASSIGN(DisplayInfoProviderAndroid); + }; + + } // namespace extensions + +-#endif // CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_AURA_H_ ++#endif // CHROME_BROWSER_EXTENSIONS_SYSTEM_DISPLAY_DISPLAY_INFO_PROVIDER_ANDROID_H_ +--- a/chrome/browser/ui/views/accelerator_utils_aura.cc ++++ b/chrome/browser/ui/views/accelerator_utils_aura.cc +@@ -8,23 +8,9 @@ + #include "chrome/browser/ui/views/frame/browser_view.h" + #include "ui/base/accelerators/accelerator.h" + +-#if defined(OS_CHROMEOS) +-#include "ash/public/cpp/accelerators.h" +-#endif +- + namespace chrome { + + bool IsChromeAccelerator(const ui::Accelerator& accelerator) { +-#if defined(OS_CHROMEOS) +- for (size_t i = 0; i < ash::kAcceleratorDataLength; ++i) { +- const ash::AcceleratorData& accel_data = ash::kAcceleratorData[i]; +- if (accel_data.keycode == accelerator.key_code() && +- accel_data.modifiers == accelerator.modifiers()) { +- return true; +- } +- } +-#endif +- + const std::vector accelerators = GetAcceleratorList(); + for (const auto& entry : accelerators) { + if (entry.keycode == accelerator.key_code() && +--- a/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc ++++ b/chrome/browser/extensions/api/image_writer_private/removable_storage_provider_linux.cc +@@ -10,115 +10,11 @@ + #include "chrome/browser/extensions/api/image_writer_private/removable_storage_provider.h" + #include "content/public/browser/browser_thread.h" + +-#if defined(USE_UDEV) +-#include "device/udev_linux/scoped_udev.h" +-#endif +- + namespace extensions { +-// TODO(haven): Udev code may be duplicated in the Chrome codebase. +-// https://code.9oo91e.qjz9zk/p/chromium/issues/detail?id=284898 +- +-#if defined(USE_UDEV) +-// Returns the integer contained in |attr|. Returns 0 on error. +-static uint64_t get_int_attr(const char* attr) { +- uint64_t result = 0; +- // In error cases, StringToInt will set result to 0 +- base::StringToUint64(attr, &result); +- return result; +-} +- +-static int get_device_blk_size(const std::string& path) { +- base::FilePath file_path(path); +- std::string device = file_path.BaseName().value(); +- +- base::FilePath info_file_path = base::FilePath("/sys/block") +- .Append(device) +- .Append("queue/logical_block_size"); +- +- std::string file_contents; +- int blk_size; +- +- if (!base::ReadFileToString(info_file_path, &file_contents)) { +- return 0; +- } +- // In error cases, StringToInt will set blk_size to 0 +- base::StringToInt(file_contents, &blk_size); +- +- return blk_size; +-} +-#endif // defined(USE_UDEV) +- + // static + scoped_refptr + RemovableStorageProvider::PopulateDeviceList() { +-#if defined(USE_UDEV) +- device::ScopedUdevPtr udev(device::udev_new()); +- if (!udev) { +- DLOG(ERROR) << "Can't create udev"; +- return nullptr; +- } +- +- auto device_list = base::MakeRefCounted(); +- /* Create a list of the devices in the 'block' subsystem. */ +- device::ScopedUdevEnumeratePtr enumerate( +- device::udev_enumerate_new(udev.get())); +- +- device::udev_enumerate_add_match_subsystem(enumerate.get(), "block"); +- device::udev_enumerate_scan_devices(enumerate.get()); +- udev_list_entry* devices = +- device::udev_enumerate_get_list_entry(enumerate.get()); +- +- udev_list_entry* dev_list_entry; +- udev_list_entry_foreach(dev_list_entry, devices) { +- const char* path = device::udev_list_entry_get_name(dev_list_entry); +- device::ScopedUdevDevicePtr cur_device( +- device::udev_device_new_from_syspath(udev.get(), path)); +- +- const char* partition = +- device::udev_device_get_sysattr_value(cur_device.get(), "partition"); +- if (partition && get_int_attr(partition)) { +- // This is a partition of a device, not the device itself +- continue; +- } +- +- const char* removable = +- device::udev_device_get_sysattr_value(cur_device.get(), "removable"); +- if (!removable || !get_int_attr(removable)) { +- // This is not a removable storage device. +- continue; +- } +- +- /* Get the parent SCSI device that contains the model +- and manufacturer. You can look at the hierarchy with +- udevadm info -a -n /dev/ */ +- udev_device* parent_device = +- device::udev_device_get_parent_with_subsystem_devtype( +- cur_device.get(), "scsi", NULL); +- if (!parent_device) { +- // this is not a usb device +- continue; +- } +- +- api::image_writer_private::RemovableStorageDevice device_item; +- device_item.vendor = +- device::UdevDeviceGetSysattrValue(parent_device, "vendor"); +- device_item.model = +- device::UdevDeviceGetSysattrValue(parent_device, "model"); +- // TODO (smaskell): Don't expose raw device path +- device_item.storage_unit_id = +- device::udev_device_get_devnode(cur_device.get()); +- device_item.capacity = get_int_attr(device::udev_device_get_sysattr_value( +- cur_device.get(), "size")) * +- get_device_blk_size(device_item.storage_unit_id); +- device_item.removable = removable; +- +- device_list->data.push_back(std::move(device_item)); +- } +- +- return device_list; +-#else + return nullptr; +-#endif // defined(USE_UDEV) + } + + } // namespace extensions +--- a/chrome/browser/ui/aura/native_window_tracker_aura.cc ++++ b/chrome/browser/ui/aura/native_window_tracker_aura.cc +@@ -4,32 +4,23 @@ + + #include "chrome/browser/ui/aura/native_window_tracker_aura.h" + +-#include "ui/aura/window.h" ++#include "ui/android/window_android.h" + +-NativeWindowTrackerAura::NativeWindowTrackerAura( ++NativeWindowTrackerAndroid::NativeWindowTrackerAndroid( + gfx::NativeWindow window) + : window_(window) { +- window->AddObserver(this); + } + +-NativeWindowTrackerAura::~NativeWindowTrackerAura() { +- if (window_) +- window_->RemoveObserver(this); ++NativeWindowTrackerAndroid::~NativeWindowTrackerAndroid() { + } + +-bool NativeWindowTrackerAura::WasNativeWindowClosed() const { ++bool NativeWindowTrackerAndroid::WasNativeWindowClosed() const { + return window_ == nullptr; + } + +-void NativeWindowTrackerAura::OnWindowDestroying( +- aura::Window* window) { +- window_->RemoveObserver(this); +- window_ = nullptr; +-} +- + // static + std::unique_ptr NativeWindowTracker::Create( + gfx::NativeWindow window) { + return std::unique_ptr( +- new NativeWindowTrackerAura(window)); ++ new NativeWindowTrackerAndroid(window)); + } +--- a/chrome/browser/ui/aura/native_window_tracker_aura.h ++++ b/chrome/browser/ui/aura/native_window_tracker_aura.h +@@ -2,29 +2,26 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_UI_AURA_NATIVE_WINDOW_TRACKER_AURA_H_ +-#define CHROME_BROWSER_UI_AURA_NATIVE_WINDOW_TRACKER_AURA_H_ ++#ifndef CHROME_BROWSER_UI_ANDROID_NATIVE_WINDOW_TRACKER_ANDROID_H_ ++#define CHROME_BROWSER_UI_ANDROID_NATIVE_WINDOW_TRACKER_ANDROID_H_ + + #include "base/macros.h" + #include "chrome/browser/ui/native_window_tracker.h" +-#include "ui/aura/window_observer.h" ++#include "ui/android/window_android.h" + +-class NativeWindowTrackerAura : public NativeWindowTracker, +- public aura::WindowObserver { ++class NativeWindowTrackerAndroid : public NativeWindowTracker { + public: +- explicit NativeWindowTrackerAura(gfx::NativeWindow window); +- ~NativeWindowTrackerAura() override; ++ explicit NativeWindowTrackerAndroid(gfx::NativeWindow window); ++ ~NativeWindowTrackerAndroid() override; + + // NativeWindowTracker: + bool WasNativeWindowClosed() const override; + + private: +- // aura::WindowObserver: +- void OnWindowDestroying(aura::Window* window) override; + +- aura::Window* window_; ++ ui::WindowAndroid* window_; + +- DISALLOW_COPY_AND_ASSIGN(NativeWindowTrackerAura); ++ DISALLOW_COPY_AND_ASSIGN(NativeWindowTrackerAndroid); + }; + +-#endif // CHROME_BROWSER_UI_AURA_NATIVE_WINDOW_TRACKER_AURA_H_ ++#endif // CHROME_BROWSER_UI_ANDROID_NATIVE_WINDOW_TRACKER_AURA_H_ +--- a/chrome/browser/policy/browser_dm_token_storage_linux.cc ++++ b/chrome/browser/policy/browser_dm_token_storage_linux.cc +@@ -71,12 +71,12 @@ bool StoreDMTokenInUserDataDir(const std + + } // namespace + +-BrowserDMTokenStorageLinux::BrowserDMTokenStorageLinux() ++BrowserDMTokenStorageAndroid::BrowserDMTokenStorageAndroid() + : task_runner_(base::ThreadPool::CreateTaskRunner({base::MayBlock()})) {} + +-BrowserDMTokenStorageLinux::~BrowserDMTokenStorageLinux() {} ++BrowserDMTokenStorageAndroid::~BrowserDMTokenStorageAndroid() {} + +-std::string BrowserDMTokenStorageLinux::InitClientId() { ++std::string BrowserDMTokenStorageAndroid::InitClientId() { + if (!client_id_.empty()) + return client_id_; + +@@ -106,7 +106,7 @@ std::string BrowserDMTokenStorageLinux:: + return client_id_; + } + +-std::string BrowserDMTokenStorageLinux::InitEnrollmentToken() { ++std::string BrowserDMTokenStorageAndroid::InitEnrollmentToken() { + std::string enrollment_token; + base::FilePath dir_policy_files_path; + +@@ -125,7 +125,7 @@ std::string BrowserDMTokenStorageLinux:: + .as_string(); + } + +-std::string BrowserDMTokenStorageLinux::InitDMToken() { ++std::string BrowserDMTokenStorageAndroid::InitDMToken() { + base::FilePath token_file_path; + if (!GetDmTokenFilePath(&token_file_path, InitClientId(), false)) + return std::string(); +@@ -137,7 +137,7 @@ std::string BrowserDMTokenStorageLinux:: + return base::TrimWhitespaceASCII(token, base::TRIM_ALL).as_string(); + } + +-bool BrowserDMTokenStorageLinux::InitEnrollmentErrorOption() { ++bool BrowserDMTokenStorageAndroid::InitEnrollmentErrorOption() { + std::string options; + base::FilePath dir_policy_files_path; + +@@ -156,18 +156,18 @@ bool BrowserDMTokenStorageLinux::InitEnr + kEnrollmentMandatoryOption; + } + +-BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageLinux::SaveDMTokenTask( ++BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageAndroid::SaveDMTokenTask( + const std::string& token, + const std::string& client_id) { + return base::BindOnce(&StoreDMTokenInUserDataDir, token, client_id); + } + + scoped_refptr +-BrowserDMTokenStorageLinux::SaveDMTokenTaskRunner() { ++BrowserDMTokenStorageAndroid::SaveDMTokenTaskRunner() { + return task_runner_; + } + +-std::string BrowserDMTokenStorageLinux::ReadMachineIdFile() { ++std::string BrowserDMTokenStorageAndroid::ReadMachineIdFile() { + std::string machine_id; + if (!base::ReadFileToString(base::FilePath(kMachineIdFilename), &machine_id)) + return std::string(); +--- a/chrome/browser/policy/browser_dm_token_storage_linux.h ++++ b/chrome/browser/policy/browser_dm_token_storage_linux.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_LINUX_H_ +-#define CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_LINUX_H_ ++#ifndef CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_ANDROID_H_ ++#define CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_ANDROID_H_ + + #include "components/enterprise/browser/controller/browser_dm_token_storage.h" + +@@ -18,11 +18,11 @@ + + namespace policy { + +-// Implementation of BrowserDMTokenStorage delegate for Linux. +-class BrowserDMTokenStorageLinux : public BrowserDMTokenStorage::Delegate { ++// Implementation of BrowserDMTokenStorage delegate for Android. ++class BrowserDMTokenStorageAndroid : public BrowserDMTokenStorage::Delegate { + public: +- BrowserDMTokenStorageLinux(); +- ~BrowserDMTokenStorageLinux() override; ++ BrowserDMTokenStorageAndroid(); ++ ~BrowserDMTokenStorageAndroid() override; + + private: + // override BrowserDMTokenStorage::Delegate +@@ -42,15 +42,15 @@ class BrowserDMTokenStorageLinux : publi + std::string client_id_; + scoped_refptr task_runner_; + +- FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageLinuxTest, InitClientId); +- FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageLinuxTest, InitEnrollmentToken); +- FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageLinuxTest, InitDMToken); +- FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageLinuxTest, ++ FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageAndroidTest, InitClientId); ++ FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageAndroidTest, InitEnrollmentToken); ++ FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageAndroidTest, InitDMToken); ++ FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageAndroidTest, + InitDMTokenWithoutDirectory); +- FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageLinuxTest, SaveDMToken); ++ FRIEND_TEST_ALL_PREFIXES(BrowserDMTokenStorageAndroidTest, SaveDMToken); + +- DISALLOW_COPY_AND_ASSIGN(BrowserDMTokenStorageLinux); ++ DISALLOW_COPY_AND_ASSIGN(BrowserDMTokenStorageAndroid); + }; + + } // namespace policy +-#endif // CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_LINUX_H_ ++#endif // CHROME_BROWSER_POLICY_BROWSER_DM_TOKEN_STORAGE_ANDROID_H_ +--- a/chrome/browser/extensions/global_shortcut_listener_ozone.cc ++++ b/chrome/browser/extensions/global_shortcut_listener_ozone.cc +@@ -13,12 +13,12 @@ namespace extensions { + // static + GlobalShortcutListener* GlobalShortcutListener::GetInstance() { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); +- static GlobalShortcutListenerOzone* instance = +- new GlobalShortcutListenerOzone(); ++ static GlobalShortcutListenerAndroid* instance = ++ new GlobalShortcutListenerAndroid(); + return instance; + } + +-GlobalShortcutListenerOzone::GlobalShortcutListenerOzone() ++GlobalShortcutListenerAndroid::GlobalShortcutListenerAndroid() + : is_listening_(false) { + CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + +@@ -26,39 +26,28 @@ GlobalShortcutListenerOzone::GlobalShort + LOG(ERROR) << "GlobalShortcutListenerOzone object created"; + } + +-GlobalShortcutListenerOzone::~GlobalShortcutListenerOzone() { ++GlobalShortcutListenerAndroid::~GlobalShortcutListenerAndroid() { + if (is_listening_) + StopListening(); + } + +-void GlobalShortcutListenerOzone::StartListening() { ++void GlobalShortcutListenerAndroid::StartListening() { + DCHECK(!is_listening_); // Don't start twice. +- NOTIMPLEMENTED(); + is_listening_ = true; + } + +-void GlobalShortcutListenerOzone::StopListening() { ++void GlobalShortcutListenerAndroid::StopListening() { + DCHECK(is_listening_); // No point if we are not already listening. +- NOTIMPLEMENTED(); + is_listening_ = false; + } + +-bool GlobalShortcutListenerOzone::RegisterAcceleratorImpl( ++bool GlobalShortcutListenerAndroid::RegisterAcceleratorImpl( + const ui::Accelerator& accelerator) { +- NOTIMPLEMENTED(); +- // To implement: +- // 1) Convert modifiers to platform specific modifiers. +- // 2) Register for the hotkey. +- // 3) If not successful, return false. +- // 4) Else, return true. +- + return false; + } + +-void GlobalShortcutListenerOzone::UnregisterAcceleratorImpl( ++void GlobalShortcutListenerAndroid::UnregisterAcceleratorImpl( + const ui::Accelerator& accelerator) { +- NOTIMPLEMENTED(); +- // To implement: Unregister for the hotkey. + } + + } // namespace extensions +--- a/chrome/browser/extensions/global_shortcut_listener_ozone.h ++++ b/chrome/browser/extensions/global_shortcut_listener_ozone.h +@@ -2,21 +2,21 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_OZONE_H_ +-#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_OZONE_H_ ++#ifndef CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_ANDROID_H_ ++#define CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_ANDROID_H_ + + #include "base/macros.h" + #include "chrome/browser/extensions/global_shortcut_listener.h" + + namespace extensions { + +-// Ozone-specific implementation of the GlobalShortcutListener class that ++// Android-specific implementation of the GlobalShortcutListener class that + // listens for global shortcuts. Handles basic keyboard intercepting and + // forwards its output to the base class for processing. +-class GlobalShortcutListenerOzone : public GlobalShortcutListener { ++class GlobalShortcutListenerAndroid : public GlobalShortcutListener { + public: +- GlobalShortcutListenerOzone(); +- ~GlobalShortcutListenerOzone() override; ++ GlobalShortcutListenerAndroid(); ++ ~GlobalShortcutListenerAndroid() override; + + private: + // GlobalShortcutListener implementation. +@@ -28,9 +28,9 @@ class GlobalShortcutListenerOzone : publ + // Whether this object is listening for global shortcuts. + bool is_listening_; + +- DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerOzone); ++ DISALLOW_COPY_AND_ASSIGN(GlobalShortcutListenerAndroid); + }; + + } // namespace extensions + +-#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_OZONE_H_ ++#endif // CHROME_BROWSER_EXTENSIONS_GLOBAL_SHORTCUT_LISTENER_ANDROID_H_ +--- a/chrome/browser/ui/views/dropdown_bar_host_aura.cc ++++ b/chrome/browser/ui/views/dropdown_bar_host_aura.cc +@@ -4,10 +4,8 @@ + + #include "chrome/browser/ui/views/dropdown_bar_host.h" + +-#include "ui/aura/window.h" +-#include "ui/views/view_constants_aura.h" ++#include "ui/android/window_android.h" + #include "ui/views/widget/widget.h" + + void DropdownBarHost::SetHostViewNative(views::View* host_view) { +- host_->GetNativeView()->SetProperty(views::kHostViewKey, host_view); + } +--- a/ui/views/widget/native_widget_aura.cc ++++ b/ui/views/widget/native_widget_aura.cc +@@ -13,19 +13,6 @@ + #include "base/strings/string_util.h" + #include "base/threading/thread_task_runner_handle.h" + #include "build/build_config.h" +-#include "ui/aura/client/aura_constants.h" +-#include "ui/aura/client/capture_client.h" +-#include "ui/aura/client/cursor_client.h" +-#include "ui/aura/client/drag_drop_client.h" +-#include "ui/aura/client/focus_client.h" +-#include "ui/aura/client/screen_position_client.h" +-#include "ui/aura/client/window_parenting_client.h" +-#include "ui/aura/client/window_types.h" +-#include "ui/aura/env.h" +-#include "ui/aura/window.h" +-#include "ui/aura/window_event_dispatcher.h" +-#include "ui/aura/window_observer.h" +-#include "ui/aura/window_tree_host.h" + #include "ui/base/class_property.h" + #include "ui/base/dragdrop/os_exchange_data.h" + #include "ui/base/ui_base_types.h" +@@ -34,7 +21,7 @@ + #include "ui/display/screen.h" + #include "ui/events/event.h" + #include "ui/gfx/canvas.h" +-#include "ui/native_theme/native_theme_aura.h" ++#include "ui/native_theme/native_theme_android.h" + #include "ui/views/buildflags.h" + #include "ui/views/drag_utils.h" + #include "ui/views/views_delegate.h" +@@ -55,21 +42,6 @@ + #include "ui/wm/public/activation_client.h" + #include "ui/wm/public/window_move_client.h" + +-#if BUILDFLAG(ENABLE_DESKTOP_AURA) +-#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" +-#include "ui/views/widget/desktop_aura/desktop_window_tree_host.h" +-#endif +- +-#if defined(OS_WIN) +-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h" +-#endif +- +-#if BUILDFLAG(ENABLE_DESKTOP_AURA) && \ +- (defined(OS_LINUX) || defined(OS_CHROMEOS)) +-#include "ui/views/linux_ui/linux_ui.h" +-#include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h" +-#endif +- + DEFINE_UI_CLASS_PROPERTY_TYPE(views::internal::NativeWidgetPrivate*) + + namespace views { +@@ -80,163 +52,76 @@ DEFINE_UI_CLASS_PROPERTY_KEY(internal::N + kNativeWidgetPrivateKey, + nullptr) + +-void SetRestoreBounds(aura::Window* window, const gfx::Rect& bounds) { +- window->SetProperty(aura::client::kRestoreBoundsKey, bounds); ++void SetRestoreBounds(gfx::NativeWindow window, const gfx::Rect& bounds) { + } + +-void SetIcon(aura::Window* window, ++void SetIcon(gfx::NativeWindow window, + const aura::WindowProperty* key, + const gfx::ImageSkia& value) { +- if (value.isNull()) +- window->ClearProperty(key); +- else +- window->SetProperty(key, value); + } + + } // namespace + + //////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, public: ++// NativeWidgetAndroid, public: + +-NativeWidgetAura::NativeWidgetAura(internal::NativeWidgetDelegate* delegate) ++NativeWidgetAndroid::NativeWidgetAndroid(internal::NativeWidgetDelegate* delegate) + : delegate_(delegate), +- window_(new aura::Window(this, aura::client::WINDOW_TYPE_UNKNOWN)), + ownership_(Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET), +- destroying_(false), +- cursor_(gfx::kNullCursor) { +- aura::client::SetFocusChangeObserver(window_, this); +- wm::SetActivationChangeObserver(window_, this); ++ destroying_(false) { + } + + // static +-void NativeWidgetAura::RegisterNativeWidgetForWindow( +- internal::NativeWidgetPrivate* native_widget, +- aura::Window* window) { +- window->SetProperty(kNativeWidgetPrivateKey, native_widget); ++void NativeWidgetAndroid::RegisterNativeWidgetForWindow( ++ internal::NativeWidgetPrivate* native_widget, ++ gfx::NativeWindow window) { + } + + // static +-void NativeWidgetAura::AssignIconToAuraWindow(aura::Window* window, ++void NativeWidgetAndroid::AssignIconToAuraWindow(gfx::NativeWindow window, + const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) { +- if (window) { +- SetIcon(window, aura::client::kWindowIconKey, window_icon); +- SetIcon(window, aura::client::kAppIconKey, app_icon); +- } + } + + // static +-void NativeWidgetAura::SetShadowElevationFromInitParams( +- aura::Window* window, ++void NativeWidgetAndroid::SetShadowElevationFromInitParams( ++ gfx::NativeWindow window, + const Widget::InitParams& params) { +- if (params.shadow_type == Widget::InitParams::ShadowType::kNone) { +- wm::SetShadowElevation(window, wm::kShadowElevationNone); +- } else if (params.shadow_type == Widget::InitParams::ShadowType::kDrop && +- params.shadow_elevation) { +- wm::SetShadowElevation(window, *params.shadow_elevation); +- } + } + + // static +-void NativeWidgetAura::SetResizeBehaviorFromDelegate(WidgetDelegate* delegate, +- aura::Window* window) { +- int behavior = aura::client::kResizeBehaviorNone; +- if (delegate) { +- if (delegate->CanResize()) +- behavior |= aura::client::kResizeBehaviorCanResize; +- if (delegate->CanMaximize()) +- behavior |= aura::client::kResizeBehaviorCanMaximize; +- if (delegate->CanMinimize()) +- behavior |= aura::client::kResizeBehaviorCanMinimize; +- } +- window->SetProperty(aura::client::kResizeBehaviorKey, behavior); ++void NativeWidgetAndroid::SetResizeBehaviorFromDelegate(WidgetDelegate* delegate, ++ gfx::NativeWindow window) { + } + + //////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, internal::NativeWidgetPrivate implementation: ++// NativeWidgetAndroid, internal::NativeWidgetPrivate implementation: + +-void NativeWidgetAura::InitNativeWidget(Widget::InitParams params) { ++void NativeWidgetAndroid::InitNativeWidget(Widget::InitParams params) { + // See Widget::InitParams::context for details. + DCHECK(params.parent || params.context); + + ownership_ = params.ownership; + +- window_->AcquireAllPropertiesFrom( +- std::move(params.init_properties_container)); +- + RegisterNativeWidgetForWindow(this, window_); +- window_->SetType(GetAuraWindowTypeForWidgetType(params.type)); +- if (params.corner_radius) { +- window_->SetProperty(aura::client::kWindowCornerRadiusKey, +- *params.corner_radius); +- } +- window_->SetProperty(aura::client::kShowStateKey, params.show_state); +- if (params.type == Widget::InitParams::TYPE_BUBBLE) +- wm::SetHideOnDeactivate(window_, true); +- window_->SetTransparent(params.opacity == +- Widget::InitParams::WindowOpacity::kTranslucent); +- + // Check for ShadowType::kNone before aura::Window::Init() to ensure observers + // do not add useless shadow layers by deriving one from the window type. + SetShadowElevationFromInitParams(window_, params); + +- window_->Init(params.layer_type); +- // Set name after layer init so it propagates to layer. +- window_->SetName(params.name.empty() ? "NativeWidgetAura" : params.name); +- if (params.type == Widget::InitParams::TYPE_CONTROL) +- window_->Show(); +- + delegate_->OnNativeWidgetCreated(); + + gfx::Rect window_bounds = params.bounds; + gfx::NativeView parent = params.parent; + gfx::NativeView context = params.context; + if (!params.child) { +- // Set up the transient child before the window is added. This way the +- // LayoutManager knows the window has a transient parent. +- if (parent && parent->type() != aura::client::WINDOW_TYPE_UNKNOWN) { +- wm::AddTransientChild(parent, window_); +- if (!context) +- context = parent; +- parent = nullptr; +- +- // Generally transient bubbles are showing state associated to the parent +- // window. Make sure the transient bubble is only visible if the parent is +- // visible, otherwise the bubble may not make sense by itself. +- if (params.type == Widget::InitParams::TYPE_BUBBLE) { +- wm::TransientWindowManager::GetOrCreate(window_) +- ->set_parent_controls_visibility(true); +- } +- } + // SetZOrderLevel before SetParent so that always-on-top container is used. + SetZOrderLevel(params.EffectiveZOrderLevel()); +- +- // Make sure we have a real |window_bounds|. +- aura::Window* parent_or_context = parent ? parent : context; +- if (parent_or_context && window_bounds == gfx::Rect()) { +- // If a parent or context is specified but no bounds are given, use the +- // origin of the display so that the widget will be added to the same +- // display as the parent or context. +- gfx::Rect bounds = display::Screen::GetScreen() +- ->GetDisplayNearestWindow(parent_or_context) +- .bounds(); +- window_bounds.set_origin(bounds.origin()); +- } + } + + // Set properties before adding to the parent so that its layout manager sees + // the correct values. + OnSizeConstraintsChanged(); + +- if (parent) { +- parent->AddChild(window_); +- } else { +- aura::client::ParentWindowWithContext(window_, context->GetRootWindow(), +- window_bounds); +- } +- +- window_->AddObserver(this); +- + // Wait to set the bounds until we have a parent. That way we can know our + // true state/bounds (the LayoutManager may enforce a particular + // state/bounds). +@@ -244,831 +129,305 @@ void NativeWidgetAura::InitNativeWidget( + SetRestoreBounds(window_, window_bounds); + else + SetBounds(window_bounds); +- window_->SetEventTargetingPolicy( +- params.accept_events ? aura::EventTargetingPolicy::kTargetAndDescendants +- : aura::EventTargetingPolicy::kNone); + DCHECK(GetWidget()->GetRootView()); +- if (params.type != Widget::InitParams::TYPE_TOOLTIP) +- tooltip_manager_ = std::make_unique(GetWidget()); +- +- drop_helper_ = std::make_unique(GetWidget()->GetRootView()); +- if (params.type != Widget::InitParams::TYPE_TOOLTIP && +- params.type != Widget::InitParams::TYPE_POPUP) { +- aura::client::SetDragDropDelegate(window_, this); +- } +- +- if (params.type == Widget::InitParams::TYPE_WINDOW) { +- focus_manager_event_handler_ = +- std::make_unique(GetWidget(), window_); +- } +- +- wm::SetActivationDelegate(window_, this); +- +- window_reorderer_ = +- std::make_unique(window_, GetWidget()->GetRootView()); + } + +-void NativeWidgetAura::OnWidgetInitDone() {} ++void NativeWidgetAndroid::OnWidgetInitDone() {} + + std::unique_ptr +-NativeWidgetAura::CreateNonClientFrameView() { ++NativeWidgetAndroid::CreateNonClientFrameView() { + return nullptr; + } + +-bool NativeWidgetAura::ShouldUseNativeFrame() const { ++bool NativeWidgetAndroid::ShouldUseNativeFrame() const { + // There is only one frame type for aura. + return false; + } + +-bool NativeWidgetAura::ShouldWindowContentsBeTransparent() const { ++bool NativeWidgetAndroid::ShouldWindowContentsBeTransparent() const { + return false; + } + +-void NativeWidgetAura::FrameTypeChanged() { ++void NativeWidgetAndroid::FrameTypeChanged() { + // This is called when the Theme has changed; forward the event to the root + // widget. + GetWidget()->ThemeChanged(); + GetWidget()->GetRootView()->SchedulePaint(); + } + +-Widget* NativeWidgetAura::GetWidget() { ++Widget* NativeWidgetAndroid::GetWidget() { + return delegate_->AsWidget(); + } + +-const Widget* NativeWidgetAura::GetWidget() const { ++const Widget* NativeWidgetAndroid::GetWidget() const { + return delegate_->AsWidget(); + } + +-gfx::NativeView NativeWidgetAura::GetNativeView() const { ++gfx::NativeView NativeWidgetAndroid::GetNativeView() const { + return window_; + } + +-gfx::NativeWindow NativeWidgetAura::GetNativeWindow() const { ++gfx::NativeWindow NativeWidgetAndroid::GetNativeWindow() const { + return window_; + } + +-Widget* NativeWidgetAura::GetTopLevelWidget() { ++Widget* NativeWidgetAndroid::GetTopLevelWidget() { + NativeWidgetPrivate* native_widget = GetTopLevelNativeWidget(GetNativeView()); + return native_widget ? native_widget->GetWidget() : nullptr; + } + +-const ui::Compositor* NativeWidgetAura::GetCompositor() const { +- return window_ ? window_->layer()->GetCompositor() : nullptr; ++const ui::Compositor* NativeWidgetAndroid::GetCompositor() const { ++ return nullptr; + } + +-const ui::Layer* NativeWidgetAura::GetLayer() const { +- return window_ ? window_->layer() : nullptr; ++const ui::Layer* NativeWidgetAndroid::GetLayer() const { ++ return nullptr; + } + +-void NativeWidgetAura::ReorderNativeViews() { +- window_reorderer_->ReorderChildWindows(); ++void NativeWidgetAndroid::ReorderNativeViews() { + } + +-void NativeWidgetAura::ViewRemoved(View* view) { ++void NativeWidgetAndroid::ViewRemoved(View* view) { + DCHECK(drop_helper_.get() != nullptr); + drop_helper_->ResetTargetViewIfEquals(view); + } + +-void NativeWidgetAura::SetNativeWindowProperty(const char* name, void* value) { +- if (window_) +- window_->SetNativeWindowProperty(name, value); ++void NativeWidgetAndroid::SetNativeWindowProperty(const char* name, void* value) { + } + +-void* NativeWidgetAura::GetNativeWindowProperty(const char* name) const { +- return window_ ? window_->GetNativeWindowProperty(name) : nullptr; ++void* NativeWidgetAndroid::GetNativeWindowProperty(const char* name) const { ++ return nullptr; + } + +-TooltipManager* NativeWidgetAura::GetTooltipManager() const { ++TooltipManager* NativeWidgetAndroid::GetTooltipManager() const { + return tooltip_manager_.get(); + } + +-void NativeWidgetAura::SetCapture() { +- if (window_) +- window_->SetCapture(); ++void NativeWidgetAndroid::SetCapture() { + } + +-void NativeWidgetAura::ReleaseCapture() { +- if (window_) +- window_->ReleaseCapture(); ++void NativeWidgetAndroid::ReleaseCapture() { + } + +-bool NativeWidgetAura::HasCapture() const { +- return window_ && window_->HasCapture(); ++bool NativeWidgetAndroid::HasCapture() const { ++ return false; + } + +-ui::InputMethod* NativeWidgetAura::GetInputMethod() { +- if (!window_) +- return nullptr; +- aura::Window* root_window = window_->GetRootWindow(); +- return root_window ? root_window->GetHost()->GetInputMethod() : nullptr; ++ui::InputMethod* NativeWidgetAndroid::GetInputMethod() { ++ return nullptr; + } + +-void NativeWidgetAura::CenterWindow(const gfx::Size& size) { +- if (!window_) +- return; +- +- window_->SetProperty(aura::client::kPreferredSize, size); +- +- gfx::Rect parent_bounds(window_->parent()->GetBoundsInRootWindow()); +- // When centering window, we take the intersection of the host and +- // the parent. We assume the root window represents the visible +- // rect of a single screen. +- gfx::Rect work_area = display::Screen::GetScreen() +- ->GetDisplayNearestWindow(window_) +- .work_area(); +- +- aura::client::ScreenPositionClient* screen_position_client = +- aura::client::GetScreenPositionClient(window_->GetRootWindow()); +- if (screen_position_client) { +- gfx::Point origin = work_area.origin(); +- screen_position_client->ConvertPointFromScreen(window_->GetRootWindow(), +- &origin); +- work_area.set_origin(origin); +- } +- +- parent_bounds.Intersect(work_area); +- +- // If |window_|'s transient parent's bounds are big enough to fit it, then we +- // center it with respect to the transient parent. +- if (wm::GetTransientParent(window_)) { +- gfx::Rect transient_parent_rect = +- wm::GetTransientParent(window_)->GetBoundsInRootWindow(); +- transient_parent_rect.Intersect(work_area); +- if (transient_parent_rect.height() >= size.height() && +- transient_parent_rect.width() >= size.width()) +- parent_bounds = transient_parent_rect; +- } +- +- gfx::Rect window_bounds( +- parent_bounds.x() + (parent_bounds.width() - size.width()) / 2, +- parent_bounds.y() + (parent_bounds.height() - size.height()) / 2, +- size.width(), size.height()); +- // Don't size the window bigger than the parent, otherwise the user may not be +- // able to close or move it. +- window_bounds.AdjustToFit(parent_bounds); +- +- // Convert the bounds back relative to the parent. +- gfx::Point origin = window_bounds.origin(); +- aura::Window::ConvertPointToTarget(window_->GetRootWindow(), +- window_->parent(), &origin); +- window_bounds.set_origin(origin); +- window_->SetBounds(window_bounds); ++void NativeWidgetAndroid::CenterWindow(const gfx::Size& size) { + } + +-void NativeWidgetAura::GetWindowPlacement( ++void NativeWidgetAndroid::GetWindowPlacement( + gfx::Rect* bounds, + ui::WindowShowState* show_state) const { +- // The interface specifies returning restored bounds, not current bounds. +- *bounds = GetRestoredBounds(); +- *show_state = window_ ? window_->GetProperty(aura::client::kShowStateKey) +- : ui::SHOW_STATE_DEFAULT; + } + +-bool NativeWidgetAura::SetWindowTitle(const base::string16& title) { +- if (!window_) +- return false; +- if (window_->GetTitle() == title) +- return false; +- window_->SetTitle(title); ++bool NativeWidgetAndroid::SetWindowTitle(const base::string16& title) { + return true; + } + +-void NativeWidgetAura::SetWindowIcons(const gfx::ImageSkia& window_icon, ++void NativeWidgetAndroid::SetWindowIcons(const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon) { +- AssignIconToAuraWindow(window_, window_icon, app_icon); + } + +-void NativeWidgetAura::InitModalType(ui::ModalType modal_type) { +- if (modal_type != ui::MODAL_TYPE_NONE) +- window_->SetProperty(aura::client::kModalKey, modal_type); +- if (modal_type == ui::MODAL_TYPE_WINDOW) { +- wm::TransientWindowManager::GetOrCreate(window_) +- ->set_parent_controls_visibility(true); +- } ++void NativeWidgetAndroid::InitModalType(ui::ModalType modal_type) { + } + +-gfx::Rect NativeWidgetAura::GetWindowBoundsInScreen() const { +- return window_ ? window_->GetBoundsInScreen() : gfx::Rect(); ++gfx::Rect NativeWidgetAndroid::GetWindowBoundsInScreen() const { ++ return gfx::Rect(); + } + +-gfx::Rect NativeWidgetAura::GetClientAreaBoundsInScreen() const { ++gfx::Rect NativeWidgetAndroid::GetClientAreaBoundsInScreen() const { + // View-to-screen coordinate system transformations depend on this returning + // the full window bounds, for example View::ConvertPointToScreen(). +- return window_ ? window_->GetBoundsInScreen() : gfx::Rect(); ++ return gfx::Rect(); + } + +-gfx::Rect NativeWidgetAura::GetRestoredBounds() const { +- if (!window_) +- return gfx::Rect(); +- +- // Restored bounds should only be relevant if the window is minimized, +- // maximized, or fullscreen. However, in some places the code expects +- // GetRestoredBounds() to return the current window bounds if the window is +- // not in either state. +- if (IsMinimized() || IsMaximized() || IsFullscreen()) { +- // Restore bounds are in screen coordinates, no need to convert. +- gfx::Rect* restore_bounds = +- window_->GetProperty(aura::client::kRestoreBoundsKey); +- if (restore_bounds) +- return *restore_bounds; +- } +- +- // Prefer getting the window bounds and converting them to screen bounds since +- // Window::GetBoundsInScreen takes into the account the window transform. +- auto* screen_position_client = +- aura::client::GetScreenPositionClient(window_->GetRootWindow()); +- if (screen_position_client) { +- // |window_|'s bounds are in parent's coordinate system so use that when +- // converting. +- gfx::Rect bounds = window_->bounds(); +- gfx::Point origin = bounds.origin(); +- screen_position_client->ConvertPointToScreenIgnoringTransforms( +- window_->parent(), &origin); +- return gfx::Rect(origin, bounds.size()); +- } +- +- return window_->GetBoundsInScreen(); ++gfx::Rect NativeWidgetAndroid::GetRestoredBounds() const { ++ return gfx::Rect(); + } + +-std::string NativeWidgetAura::GetWorkspace() const { ++std::string NativeWidgetAndroid::GetWorkspace() const { + return std::string(); + } + +-void NativeWidgetAura::SetBounds(const gfx::Rect& bounds) { +- if (!window_) +- return; +- +- aura::Window* root = window_->GetRootWindow(); +- if (root) { +- aura::client::ScreenPositionClient* screen_position_client = +- aura::client::GetScreenPositionClient(root); +- if (screen_position_client) { +- display::Display dst_display = +- display::Screen::GetScreen()->GetDisplayMatching(bounds); +- screen_position_client->SetBounds(window_, bounds, dst_display); +- return; +- } +- } +- window_->SetBounds(bounds); ++void NativeWidgetAndroid::SetBounds(const gfx::Rect& bounds) { + } + +-void NativeWidgetAura::SetBoundsConstrained(const gfx::Rect& bounds) { +- if (!window_) +- return; +- +- gfx::Rect new_bounds(bounds); +- if (window_->parent()) { +- if (window_->parent()->GetProperty(wm::kUsesScreenCoordinatesKey)) { +- new_bounds = +- NativeWidgetPrivate::ConstrainBoundsToDisplayWorkArea(new_bounds); +- } else { +- new_bounds.AdjustToFit(gfx::Rect(window_->parent()->bounds().size())); +- } +- } +- SetBounds(new_bounds); ++void NativeWidgetAndroid::SetBoundsConstrained(const gfx::Rect& bounds) { + } + +-void NativeWidgetAura::SetSize(const gfx::Size& size) { +- if (window_) +- window_->SetBounds(gfx::Rect(window_->bounds().origin(), size)); ++void NativeWidgetAndroid::SetSize(const gfx::Size& size) { + } + +-void NativeWidgetAura::StackAbove(gfx::NativeView native_view) { +- if (window_ && window_->parent() && +- window_->parent() == native_view->parent()) +- window_->parent()->StackChildAbove(window_, native_view); ++void NativeWidgetAndroid::StackAbove(gfx::NativeView native_view) { + } + +-void NativeWidgetAura::StackAtTop() { +- if (window_) +- window_->parent()->StackChildAtTop(window_); ++void NativeWidgetAndroid::StackAtTop() { + } + +-void NativeWidgetAura::SetShape(std::unique_ptr shape) { +- if (window_) +- window_->layer()->SetAlphaShape(std::move(shape)); ++void NativeWidgetAndroid::SetShape(std::unique_ptr shape) { + } + +-void NativeWidgetAura::Close() { ++void NativeWidgetAndroid::Close() { + // |window_| may already be deleted by parent window. This can happen + // when this widget is child widget or has transient parent + // and ownership is WIDGET_OWNS_NATIVE_WIDGET. +- DCHECK(window_ || +- ownership_ == Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET); +- if (window_) { +- Hide(); +- window_->SetProperty(aura::client::kModalKey, ui::MODAL_TYPE_NONE); +- } +- +- if (!close_widget_factory_.HasWeakPtrs()) { +- base::ThreadTaskRunnerHandle::Get()->PostTask( +- FROM_HERE, base::BindOnce(&NativeWidgetAura::CloseNow, +- close_widget_factory_.GetWeakPtr())); +- } + } + +-void NativeWidgetAura::CloseNow() { +- delete window_; ++void NativeWidgetAndroid::CloseNow() { + } + +-void NativeWidgetAura::Show(ui::WindowShowState show_state, ++void NativeWidgetAndroid::Show(ui::WindowShowState show_state, + const gfx::Rect& restore_bounds) { +- if (!window_) +- return; +- +- if (show_state == ui::SHOW_STATE_MAXIMIZED && !restore_bounds.IsEmpty()) +- SetRestoreBounds(window_, restore_bounds); +- if (show_state == ui::SHOW_STATE_MAXIMIZED || +- show_state == ui::SHOW_STATE_FULLSCREEN) { +- window_->SetProperty(aura::client::kShowStateKey, show_state); +- } +- window_->Show(); +- if (delegate_->CanActivate()) { +- if (show_state != ui::SHOW_STATE_INACTIVE) +- Activate(); +- // SetInitialFocus() should be always be called, even for +- // SHOW_STATE_INACTIVE. If the window has to stay inactive, the method will +- // do the right thing. +- // Activate() might fail if the window is non-activatable. In this case, we +- // should pass SHOW_STATE_INACTIVE to SetInitialFocus() to stop the initial +- // focused view from getting focused. See crbug.com/515594 for example. +- SetInitialFocus(IsActive() ? show_state : ui::SHOW_STATE_INACTIVE); +- } +- +- // On desktop aura, a window is activated first even when it is shown as +- // minimized. Do the same for consistency. +- if (show_state == ui::SHOW_STATE_MINIMIZED) +- Minimize(); + } + +-void NativeWidgetAura::Hide() { +- if (window_) +- window_->Hide(); ++void NativeWidgetAndroid::Hide() { + } + +-bool NativeWidgetAura::IsVisible() const { +- return window_ && window_->IsVisible(); ++bool NativeWidgetAndroid::IsVisible() const { ++ return false; + } + +-void NativeWidgetAura::Activate() { +- if (!window_) +- return; +- +- // We don't necessarily have a root window yet. This can happen with +- // constrained windows. +- if (window_->GetRootWindow()) +- wm::GetActivationClient(window_->GetRootWindow())->ActivateWindow(window_); +- if (window_->GetProperty(aura::client::kDrawAttentionKey)) +- window_->SetProperty(aura::client::kDrawAttentionKey, false); ++void NativeWidgetAndroid::Activate() { + } + +-void NativeWidgetAura::Deactivate() { +- if (!window_) +- return; +- wm::GetActivationClient(window_->GetRootWindow())->DeactivateWindow(window_); ++void NativeWidgetAndroid::Deactivate() { + } + +-bool NativeWidgetAura::IsActive() const { +- return window_ && wm::IsActiveWindow(window_); ++bool NativeWidgetAndroid::IsActive() const { ++ return false; + } + +-void NativeWidgetAura::SetZOrderLevel(ui::ZOrderLevel order) { +- if (window_) +- window_->SetProperty(aura::client::kZOrderingKey, order); ++void NativeWidgetAndroid::SetZOrderLevel(ui::ZOrderLevel order) { + } + +-ui::ZOrderLevel NativeWidgetAura::GetZOrderLevel() const { +- if (window_) +- return window_->GetProperty(aura::client::kZOrderingKey); +- ++ui::ZOrderLevel NativeWidgetAndroid::GetZOrderLevel() const { + return ui::ZOrderLevel::kNormal; + } + +-void NativeWidgetAura::SetVisibleOnAllWorkspaces(bool always_visible) { ++void NativeWidgetAndroid::SetVisibleOnAllWorkspaces(bool always_visible) { + // Not implemented on chromeos or for child widgets. + } + +-bool NativeWidgetAura::IsVisibleOnAllWorkspaces() const { ++bool NativeWidgetAndroid::IsVisibleOnAllWorkspaces() const { + return false; + } + +-void NativeWidgetAura::Maximize() { +- if (window_) +- window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); ++void NativeWidgetAndroid::Maximize() { + } + +-void NativeWidgetAura::Minimize() { +- if (window_) +- window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); ++void NativeWidgetAndroid::Minimize() { + } + +-bool NativeWidgetAura::IsMaximized() const { +- return window_ && window_->GetProperty(aura::client::kShowStateKey) == +- ui::SHOW_STATE_MAXIMIZED; ++bool NativeWidgetAndroid::IsMaximized() const { ++ return false; + } + +-bool NativeWidgetAura::IsMinimized() const { +- return window_ && window_->GetProperty(aura::client::kShowStateKey) == +- ui::SHOW_STATE_MINIMIZED; ++bool NativeWidgetAndroid::IsMinimized() const { ++ return false; + } + +-void NativeWidgetAura::Restore() { +- if (window_) +- window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); ++void NativeWidgetAndroid::Restore() { + } + +-void NativeWidgetAura::SetFullscreen(bool fullscreen) { +- if (!window_ || IsFullscreen() == fullscreen) +- return; // Nothing to do. +- +- wm::SetWindowFullscreen(window_, fullscreen); ++void NativeWidgetAndroid::SetFullscreen(bool fullscreen) { + } + +-bool NativeWidgetAura::IsFullscreen() const { +- return window_ && window_->GetProperty(aura::client::kShowStateKey) == +- ui::SHOW_STATE_FULLSCREEN; ++bool NativeWidgetAndroid::IsFullscreen() const { ++ return false; + } + +-void NativeWidgetAura::SetCanAppearInExistingFullscreenSpaces( ++void NativeWidgetAndroid::SetCanAppearInExistingFullscreenSpaces( + bool can_appear_in_existing_fullscreen_spaces) {} + +-void NativeWidgetAura::SetOpacity(float opacity) { +- if (window_) +- window_->layer()->SetOpacity(opacity); ++void NativeWidgetAndroid::SetOpacity(float opacity) { + } + +-void NativeWidgetAura::SetAspectRatio(const gfx::SizeF& aspect_ratio) { +- DCHECK(!aspect_ratio.IsEmpty()); +- if (window_) { +- // aura::client::kAspectRatio is owned, which allows for passing in this +- // raw pointer. +- window_->SetProperty(aura::client::kAspectRatio, +- new gfx::SizeF(aspect_ratio)); +- } ++void NativeWidgetAndroid::SetAspectRatio(const gfx::SizeF& aspect_ratio) { + } + +-void NativeWidgetAura::FlashFrame(bool flash) { +- if (window_) +- window_->SetProperty(aura::client::kDrawAttentionKey, flash); ++void NativeWidgetAndroid::FlashFrame(bool flash) { + } + +-void NativeWidgetAura::RunShellDrag(View* view, ++void NativeWidgetAndroid::RunShellDrag(View* view, + std::unique_ptr data, + const gfx::Point& location, + int operation, + ui::mojom::DragEventSource source) { +- if (window_) +- views::RunShellDrag(window_, std::move(data), location, operation, source); + } + +-void NativeWidgetAura::SchedulePaintInRect(const gfx::Rect& rect) { +- if (window_) +- window_->SchedulePaintInRect(rect); ++void NativeWidgetAndroid::SchedulePaintInRect(const gfx::Rect& rect) { + } + +-void NativeWidgetAura::ScheduleLayout() { +- // ScheduleDraw() triggers a callback to WindowDelegate::UpdateVisualState(). +- if (window_) +- window_->ScheduleDraw(); ++void NativeWidgetAndroid::ScheduleLayout() { + } + +-void NativeWidgetAura::SetCursor(gfx::NativeCursor cursor) { +- cursor_ = cursor; +- aura::client::CursorClient* cursor_client = +- aura::client::GetCursorClient(window_->GetRootWindow()); +- if (cursor_client) +- cursor_client->SetCursor(cursor); ++void NativeWidgetAndroid::SetCursor(gfx::NativeCursor cursor) { + } + +-bool NativeWidgetAura::IsMouseEventsEnabled() const { +- if (!window_) +- return false; +- aura::client::CursorClient* cursor_client = +- aura::client::GetCursorClient(window_->GetRootWindow()); +- return cursor_client ? cursor_client->IsMouseEventsEnabled() : true; ++bool NativeWidgetAndroid::IsMouseEventsEnabled() const { ++ return false; + } + +-bool NativeWidgetAura::IsMouseButtonDown() const { +- return aura::Env::GetInstance()->IsMouseButtonDown(); ++bool NativeWidgetAndroid::IsMouseButtonDown() const { ++ return false; + } + +-void NativeWidgetAura::ClearNativeFocus() { +- aura::client::FocusClient* client = aura::client::GetFocusClient(window_); +- if (window_ && client && window_->Contains(client->GetFocusedWindow())) +- client->ResetFocusWithinActiveWindow(window_); ++void NativeWidgetAndroid::ClearNativeFocus() { + } + +-gfx::Rect NativeWidgetAura::GetWorkAreaBoundsInScreen() const { +- if (!window_) +- return gfx::Rect(); +- return display::Screen::GetScreen() +- ->GetDisplayNearestWindow(window_) +- .work_area(); ++gfx::Rect NativeWidgetAndroid::GetWorkAreaBoundsInScreen() const { ++ return gfx::Rect(); + } + +-Widget::MoveLoopResult NativeWidgetAura::RunMoveLoop( ++Widget::MoveLoopResult NativeWidgetAndroid::RunMoveLoop( + const gfx::Vector2d& drag_offset, + Widget::MoveLoopSource source, + Widget::MoveLoopEscapeBehavior escape_behavior) { +- // |escape_behavior| is only needed on windows when running the native message +- // loop. +- if (!window_ || !window_->GetRootWindow()) +- return Widget::MOVE_LOOP_CANCELED; +- wm::WindowMoveClient* move_client = +- wm::GetWindowMoveClient(window_->GetRootWindow()); +- if (!move_client) +- return Widget::MOVE_LOOP_CANCELED; +- +- SetCapture(); +- wm::WindowMoveSource window_move_source = +- source == Widget::MoveLoopSource::kMouse ? wm::WINDOW_MOVE_SOURCE_MOUSE +- : wm::WINDOW_MOVE_SOURCE_TOUCH; +- if (move_client->RunMoveLoop(window_, drag_offset, window_move_source) == +- wm::MOVE_SUCCESSFUL) { +- return Widget::MOVE_LOOP_SUCCESSFUL; +- } + return Widget::MOVE_LOOP_CANCELED; + } + +-void NativeWidgetAura::EndMoveLoop() { +- if (!window_ || !window_->GetRootWindow()) +- return; +- wm::WindowMoveClient* move_client = +- wm::GetWindowMoveClient(window_->GetRootWindow()); +- if (move_client) +- move_client->EndMoveLoop(); ++void NativeWidgetAndroid::EndMoveLoop() { + } + +-void NativeWidgetAura::SetVisibilityChangedAnimationsEnabled(bool value) { +- if (window_) +- window_->SetProperty(aura::client::kAnimationsDisabledKey, !value); ++void NativeWidgetAndroid::SetVisibilityChangedAnimationsEnabled(bool value) { + } + +-void NativeWidgetAura::SetVisibilityAnimationDuration( ++void NativeWidgetAndroid::SetVisibilityAnimationDuration( + const base::TimeDelta& duration) { +- wm::SetWindowVisibilityAnimationDuration(window_, duration); + } + +-void NativeWidgetAura::SetVisibilityAnimationTransition( ++void NativeWidgetAndroid::SetVisibilityAnimationTransition( + Widget::VisibilityTransition transition) { +- wm::WindowVisibilityAnimationTransition wm_transition = wm::ANIMATE_NONE; +- switch (transition) { +- case Widget::ANIMATE_SHOW: +- wm_transition = wm::ANIMATE_SHOW; +- break; +- case Widget::ANIMATE_HIDE: +- wm_transition = wm::ANIMATE_HIDE; +- break; +- case Widget::ANIMATE_BOTH: +- wm_transition = wm::ANIMATE_BOTH; +- break; +- case Widget::ANIMATE_NONE: +- wm_transition = wm::ANIMATE_NONE; +- break; +- } +- wm::SetWindowVisibilityAnimationTransition(window_, wm_transition); + } + +-bool NativeWidgetAura::IsTranslucentWindowOpacitySupported() const { ++bool NativeWidgetAndroid::IsTranslucentWindowOpacitySupported() const { + return true; + } + +-ui::GestureRecognizer* NativeWidgetAura::GetGestureRecognizer() { +- return aura::Env::GetInstance()->gesture_recognizer(); +-} +- +-void NativeWidgetAura::OnSizeConstraintsChanged() { +- SetResizeBehaviorFromDelegate(GetWidget()->widget_delegate(), window_); +-} +- +-void NativeWidgetAura::OnNativeViewHierarchyWillChange() {} +- +-void NativeWidgetAura::OnNativeViewHierarchyChanged() {} +- +-std::string NativeWidgetAura::GetName() const { +- return window_ ? window_->GetName() : std::string(); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, aura::WindowDelegate implementation: +- +-gfx::Size NativeWidgetAura::GetMinimumSize() const { +- return delegate_->GetMinimumSize(); +-} +- +-gfx::Size NativeWidgetAura::GetMaximumSize() const { +- // Do no check maximizability as EXO clients can have maximum size and be +- // maximizable at the same time. +- return delegate_->GetMaximumSize(); +-} +- +-void NativeWidgetAura::OnBoundsChanged(const gfx::Rect& old_bounds, +- const gfx::Rect& new_bounds) { +- // Assume that if the old bounds was completely empty a move happened. This +- // handles the case of a maximize animation acquiring the layer (acquiring a +- // layer results in clearing the bounds). +- if (old_bounds.origin() != new_bounds.origin() || +- (old_bounds == gfx::Rect(0, 0, 0, 0) && !new_bounds.IsEmpty())) { +- delegate_->OnNativeWidgetMove(); +- } +- if (old_bounds.size() != new_bounds.size()) +- delegate_->OnNativeWidgetSizeChanged(new_bounds.size()); +-} +- +-gfx::NativeCursor NativeWidgetAura::GetCursor(const gfx::Point& point) { +- return cursor_; +-} +- +-int NativeWidgetAura::GetNonClientComponent(const gfx::Point& point) const { +- return delegate_->GetNonClientComponent(point); +-} +- +-bool NativeWidgetAura::ShouldDescendIntoChildForEventHandling( +- aura::Window* child, +- const gfx::Point& location) { +- return delegate_->ShouldDescendIntoChildForEventHandling( +- window_->layer(), child, child->layer(), location); +-} +- +-bool NativeWidgetAura::CanFocus() { +- return ShouldActivate(); +-} +- +-void NativeWidgetAura::OnCaptureLost() { +- delegate_->OnMouseCaptureLost(); +-} +- +-void NativeWidgetAura::OnPaint(const ui::PaintContext& context) { +- delegate_->OnNativeWidgetPaint(context); +-} +- +-void NativeWidgetAura::OnDeviceScaleFactorChanged( +- float old_device_scale_factor, +- float new_device_scale_factor) { +- GetWidget()->DeviceScaleFactorChanged(old_device_scale_factor, +- new_device_scale_factor); +-} +- +-void NativeWidgetAura::OnWindowDestroying(aura::Window* window) { +- window_->RemoveObserver(this); +- delegate_->OnNativeWidgetDestroying(); +- +- // If the aura::Window is destroyed, we can no longer show tooltips. +- tooltip_manager_.reset(); +- +- focus_manager_event_handler_.reset(); +-} +- +-void NativeWidgetAura::OnWindowDestroyed(aura::Window* window) { +- window_ = nullptr; +- // |OnNativeWidgetDestroyed| may delete |this| if the object does not own +- // itself. +- bool should_delete_this = +- (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET); +- delegate_->OnNativeWidgetDestroyed(); +- if (should_delete_this) +- delete this; +-} +- +-void NativeWidgetAura::OnWindowTargetVisibilityChanged(bool visible) { +- delegate_->OnNativeWidgetVisibilityChanged(visible); +-} +- +-bool NativeWidgetAura::HasHitTestMask() const { +- return delegate_->HasHitTestMask(); +-} +- +-void NativeWidgetAura::GetHitTestMask(SkPath* mask) const { +- DCHECK(mask); +- delegate_->GetHitTestMask(mask); +-} +- +-void NativeWidgetAura::UpdateVisualState() { +- delegate_->LayoutRootViewIfNecessary(); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, aura::WindowObserver implementation: +- +-void NativeWidgetAura::OnWindowPropertyChanged(aura::Window* window, +- const void* key, +- intptr_t old) { +- if (key == aura::client::kShowStateKey) +- delegate_->OnNativeWidgetWindowShowStateChanged(); +-} +- +-void NativeWidgetAura::OnResizeLoopStarted(aura::Window* window) { +- delegate_->OnNativeWidgetBeginUserBoundsChange(); +-} +- +-void NativeWidgetAura::OnResizeLoopEnded(aura::Window* window) { +- delegate_->OnNativeWidgetEndUserBoundsChange(); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, ui::EventHandler implementation: +- +-void NativeWidgetAura::OnKeyEvent(ui::KeyEvent* event) { +- DCHECK(window_); +- // Renderer may send a key event back to us if the key event wasn't handled, +- // and the window may be invisible by that time. +- if (!window_->IsVisible()) +- return; +- +- delegate_->OnKeyEvent(event); +-} +- +-void NativeWidgetAura::OnMouseEvent(ui::MouseEvent* event) { +- DCHECK(window_); +- DCHECK(window_->IsVisible()); +- if (event->type() == ui::ET_MOUSEWHEEL) { +- delegate_->OnMouseEvent(event); +- return; +- } +- +- if (tooltip_manager_.get()) +- tooltip_manager_->UpdateTooltip(); +- TooltipManagerAura::UpdateTooltipManagerForCapture(GetWidget()); +- delegate_->OnMouseEvent(event); +-} +- +-void NativeWidgetAura::OnScrollEvent(ui::ScrollEvent* event) { +- delegate_->OnScrollEvent(event); +-} +- +-void NativeWidgetAura::OnGestureEvent(ui::GestureEvent* event) { +- DCHECK(window_); +- DCHECK(window_->IsVisible() || event->IsEndingEvent()); +- delegate_->OnGestureEvent(event); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, wm::ActivationDelegate implementation: +- +-bool NativeWidgetAura::ShouldActivate() const { +- return delegate_->CanActivate(); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, wm::ActivationChangeObserver implementation: +- +-void NativeWidgetAura::OnWindowActivated( +- wm::ActivationChangeObserver::ActivationReason, +- aura::Window* gained_active, +- aura::Window* lost_active) { +- DCHECK(window_ == gained_active || window_ == lost_active); +- if (GetWidget()->GetFocusManager()) { +- if (window_ == gained_active) +- GetWidget()->GetFocusManager()->RestoreFocusedView(); +- else if (window_ == lost_active) +- GetWidget()->GetFocusManager()->StoreFocusedView(true); +- } +- delegate_->OnNativeWidgetActivationChanged(window_ == gained_active); +-} +- +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, aura::client::FocusChangeObserver: +- +-void NativeWidgetAura::OnWindowFocused(aura::Window* gained_focus, +- aura::Window* lost_focus) { +- if (window_ == gained_focus) +- delegate_->OnNativeFocus(); +- else if (window_ == lost_focus) +- delegate_->OnNativeBlur(); ++ui::GestureRecognizer* NativeWidgetAndroid::GetGestureRecognizer() { ++ return nullptr; + } + +-//////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, aura::WindowDragDropDelegate implementation: +- +-void NativeWidgetAura::OnDragEntered(const ui::DropTargetEvent& event) { +- DCHECK(drop_helper_.get() != nullptr); +- last_drop_operation_ = drop_helper_->OnDragOver( +- event.data(), event.location(), event.source_operations()); ++void NativeWidgetAndroid::OnSizeConstraintsChanged() { + } + +-int NativeWidgetAura::OnDragUpdated(const ui::DropTargetEvent& event) { +- DCHECK(drop_helper_.get() != nullptr); +- last_drop_operation_ = drop_helper_->OnDragOver( +- event.data(), event.location(), event.source_operations()); +- return last_drop_operation_; +-} ++void NativeWidgetAndroid::OnNativeViewHierarchyWillChange() {} + +-void NativeWidgetAura::OnDragExited() { +- DCHECK(drop_helper_.get() != nullptr); +- drop_helper_->OnDragExit(); +-} ++void NativeWidgetAndroid::OnNativeViewHierarchyChanged() {} + +-int NativeWidgetAura::OnPerformDrop(const ui::DropTargetEvent& event, +- std::unique_ptr data) { +- DCHECK(drop_helper_.get() != nullptr); +- return drop_helper_->OnDrop(event.data(), event.location(), +- last_drop_operation_); ++std::string NativeWidgetAndroid::GetName() const { ++ return std::string(); + } + + //////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, protected: ++// NativeWidgetAndroid, protected: + +-NativeWidgetAura::~NativeWidgetAura() { ++NativeWidgetAndroid::~NativeWidgetAndroid() { + destroying_ = true; + if (ownership_ == Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET) + delete delegate_; +@@ -1077,12 +436,9 @@ NativeWidgetAura::~NativeWidgetAura() { + } + + //////////////////////////////////////////////////////////////////////////////// +-// NativeWidgetAura, private: ++// NativeWidgetAndroid, private: + +-void NativeWidgetAura::SetInitialFocus(ui::WindowShowState show_state) { +- // The window does not get keyboard messages unless we focus it. +- if (!GetWidget()->SetInitialFocus(show_state)) +- window_->Focus(); ++void NativeWidgetAndroid::SetInitialFocus(ui::WindowShowState show_state) { + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -1090,7 +446,7 @@ void NativeWidgetAura::SetInitialFocus(u + + namespace { + #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \ +- (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)) ++ (defined(OS_WIN) || defined(OS_CHROMEOS)) + void CloseWindow(aura::Window* window) { + if (window) { + Widget* widget = Widget::GetWidgetForNativeView(window); +@@ -1121,26 +477,11 @@ void Widget::CloseAllSecondaryWidgets() + #endif + + #if BUILDFLAG(ENABLE_DESKTOP_AURA) && \ +- (defined(OS_LINUX) || defined(OS_CHROMEOS)) ++ defined(OS_CHROMEOS) + DesktopWindowTreeHostLinux::CleanUpWindowList(CloseWindow); + #endif + } + +-const ui::NativeTheme* Widget::GetNativeTheme() const { +-#if BUILDFLAG(ENABLE_DESKTOP_AURA) && \ +- (defined(OS_LINUX) || defined(OS_CHROMEOS)) +- const LinuxUI* linux_ui = LinuxUI::instance(); +- if (linux_ui) { +- ui::NativeTheme* native_theme = +- linux_ui->GetNativeTheme(native_widget_->GetNativeWindow()); +- if (native_theme) +- return native_theme; +- } +-#endif +- +- return ui::NativeTheme::GetInstanceForNativeUi(); +-} +- + namespace internal { + + //////////////////////////////////////////////////////////////////////////////// +@@ -1149,116 +490,46 @@ namespace internal { + // static + NativeWidgetPrivate* NativeWidgetPrivate::CreateNativeWidget( + internal::NativeWidgetDelegate* delegate) { +- return new NativeWidgetAura(delegate); ++ return new NativeWidgetAndroid(delegate); + } + + // static + NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeView( + gfx::NativeView native_view) { +- return native_view->GetProperty(kNativeWidgetPrivateKey); ++ return nullptr; + } + + // static + NativeWidgetPrivate* NativeWidgetPrivate::GetNativeWidgetForNativeWindow( + gfx::NativeWindow native_window) { +- return native_window->GetProperty(kNativeWidgetPrivateKey); ++ return nullptr; + } + + // static + NativeWidgetPrivate* NativeWidgetPrivate::GetTopLevelNativeWidget( + gfx::NativeView native_view) { +- aura::Window* window = native_view; +- NativeWidgetPrivate* top_level_native_widget = nullptr; +- while (window) { +- NativeWidgetPrivate* native_widget = GetNativeWidgetForNativeView(window); +- if (native_widget) +- top_level_native_widget = native_widget; +- window = window->parent(); +- } +- return top_level_native_widget; ++ return nullptr; + } + + // static + void NativeWidgetPrivate::GetAllChildWidgets(gfx::NativeView native_view, + Widget::Widgets* children) { +- { +- // Code expects widget for |native_view| to be added to |children|. +- NativeWidgetPrivate* native_widget = static_cast( +- GetNativeWidgetForNativeView(native_view)); +- if (native_widget && native_widget->GetWidget()) +- children->insert(native_widget->GetWidget()); +- } +- +- for (auto* child_window : native_view->children()) +- GetAllChildWidgets(child_window, children); + } + + // static + void NativeWidgetPrivate::GetAllOwnedWidgets(gfx::NativeView native_view, + Widget::Widgets* owned) { +- // Add all owned widgets. +- for (aura::Window* transient_child : wm::GetTransientChildren(native_view)) { +- NativeWidgetPrivate* native_widget = static_cast( +- GetNativeWidgetForNativeView(transient_child)); +- if (native_widget && native_widget->GetWidget()) +- owned->insert(native_widget->GetWidget()); +- GetAllOwnedWidgets(transient_child, owned); +- } +- +- // Add all child windows. +- for (aura::Window* child : native_view->children()) +- GetAllChildWidgets(child, owned); + } + + // static + void NativeWidgetPrivate::ReparentNativeView(gfx::NativeView native_view, + gfx::NativeView new_parent) { +- DCHECK(native_view != new_parent); +- +- gfx::NativeView previous_parent = native_view->parent(); +- if (previous_parent == new_parent) +- return; +- +- Widget::Widgets widgets; +- GetAllChildWidgets(native_view, &widgets); +- +- // First notify all the widgets that they are being disassociated +- // from their previous parent. +- for (auto* widget : widgets) +- widget->NotifyNativeViewHierarchyWillChange(); +- +- if (new_parent) { +- new_parent->AddChild(native_view); +- } else { +- // The following looks weird, but it's the equivalent of what aura has +- // always done. (The previous behaviour of aura::Window::SetParent() used +- // NULL as a special value that meant ask the WindowParentingClient where +- // things should go.) +- // +- // This probably isn't strictly correct, but its an invariant that a Window +- // in use will be attached to a RootWindow, so we can't just call +- // RemoveChild here. The only possible thing that could assign a RootWindow +- // in this case is the stacking client of the current RootWindow. This +- // matches our previous behaviour; the global stacking client would almost +- // always reattach the window to the same RootWindow. +- aura::Window* root_window = native_view->GetRootWindow(); +- aura::client::ParentWindowWithContext(native_view, root_window, +- root_window->GetBoundsInScreen()); +- } +- +- // And now, notify them that they have a brand new parent. +- for (auto* widget : widgets) +- widget->NotifyNativeViewHierarchyChanged(); + } + + // static + gfx::NativeView NativeWidgetPrivate::GetGlobalCapture( + gfx::NativeView native_view) { +- aura::client::CaptureClient* capture_client = +- aura::client::GetCaptureClient(native_view->GetRootWindow()); +- if (!capture_client) +- return nullptr; +- return capture_client->GetGlobalCaptureWindow(); ++ return nullptr; + } + + } // namespace internal +--- a/ui/views/widget/native_widget_aura.h ++++ b/ui/views/widget/native_widget_aura.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_ +-#define UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_ ++#ifndef UI_VIEWS_WIDGET_NATIVE_WIDGET_ANDROID_H_ ++#define UI_VIEWS_WIDGET_NATIVE_WIDGET_ANDROID_H_ + + #include + #include +@@ -11,10 +11,6 @@ + #include "base/macros.h" + #include "base/memory/weak_ptr.h" + #include "build/build_config.h" +-#include "ui/aura/client/drag_drop_delegate.h" +-#include "ui/aura/client/focus_change_observer.h" +-#include "ui/aura/window_delegate.h" +-#include "ui/aura/window_observer.h" + #include "ui/base/cursor/cursor.h" + #include "ui/events/event_constants.h" + #include "ui/views/views_export.h" +@@ -22,11 +18,7 @@ + #include "ui/wm/public/activation_change_observer.h" + #include "ui/wm/public/activation_delegate.h" + +-#if defined(OS_APPLE) +-#error This file must not be included on macOS; Chromium Mac doesn't use Aura. +-#endif +- +-namespace aura { ++namespace android { + class Window; + } + +@@ -34,39 +26,33 @@ namespace views { + + class DropHelper; + class FocusManagerEventHandler; +-class TooltipManagerAura; ++class TooltipManagerAndroid; + class WindowReorderer; + +-class VIEWS_EXPORT NativeWidgetAura : public internal::NativeWidgetPrivate, +- public aura::WindowDelegate, +- public aura::WindowObserver, +- public wm::ActivationDelegate, +- public wm::ActivationChangeObserver, +- public aura::client::FocusChangeObserver, +- public aura::client::DragDropDelegate { ++class VIEWS_EXPORT NativeWidgetAndroid : public internal::NativeWidgetPrivate { + public: +- explicit NativeWidgetAura(internal::NativeWidgetDelegate* delegate); ++ explicit NativeWidgetAndroid(internal::NativeWidgetDelegate* delegate); + +- // Called internally by NativeWidgetAura and DesktopNativeWidgetAura to ++ // Called internally by NativeWidgetAndroid and DesktopNativeWidgetAndroid to + // associate |native_widget| with |window|. + static void RegisterNativeWidgetForWindow( + internal::NativeWidgetPrivate* native_widget, +- aura::Window* window); ++ gfx::NativeWindow window); + + // Assign an icon to aura window. +- static void AssignIconToAuraWindow(aura::Window* window, ++ static void AssignIconToAuraWindow(gfx::NativeWindow window, + const gfx::ImageSkia& window_icon, + const gfx::ImageSkia& app_icon); + + // If necessary, sets the ShadowElevation of |window| from |params|. + static void SetShadowElevationFromInitParams( +- aura::Window* window, ++ gfx::NativeWindow window, + const Widget::InitParams& params); + + // Sets the window property aura::client::kResizeBehaviorKey based on the + // values from the delegate. + static void SetResizeBehaviorFromDelegate(WidgetDelegate* delegate, +- aura::Window* window); ++ gfx::NativeWindow window); + + // internal::NativeWidgetPrivate: + void InitNativeWidget(Widget::InitParams params) override; +@@ -161,62 +147,8 @@ class VIEWS_EXPORT NativeWidgetAura : pu + void OnNativeViewHierarchyChanged() override; + std::string GetName() const override; + +- // aura::WindowDelegate: +- gfx::Size GetMinimumSize() const override; +- gfx::Size GetMaximumSize() const override; +- void OnBoundsChanged(const gfx::Rect& old_bounds, +- const gfx::Rect& new_bounds) override; +- gfx::NativeCursor GetCursor(const gfx::Point& point) override; +- int GetNonClientComponent(const gfx::Point& point) const override; +- bool ShouldDescendIntoChildForEventHandling( +- aura::Window* child, +- const gfx::Point& location) override; +- bool CanFocus() override; +- void OnCaptureLost() override; +- void OnPaint(const ui::PaintContext& context) override; +- void OnDeviceScaleFactorChanged(float old_device_scale_factor, +- float new_device_scale_factor) override; +- void OnWindowDestroying(aura::Window* window) override; +- void OnWindowDestroyed(aura::Window* window) override; +- void OnWindowTargetVisibilityChanged(bool visible) override; +- bool HasHitTestMask() const override; +- void GetHitTestMask(SkPath* mask) const override; +- void UpdateVisualState() override; +- +- // aura::WindowObserver: +- void OnWindowPropertyChanged(aura::Window* window, +- const void* key, +- intptr_t old) override; +- void OnResizeLoopStarted(aura::Window* window) override; +- void OnResizeLoopEnded(aura::Window* window) override; +- +- // ui::EventHandler: +- void OnKeyEvent(ui::KeyEvent* event) override; +- void OnMouseEvent(ui::MouseEvent* event) override; +- void OnScrollEvent(ui::ScrollEvent* event) override; +- void OnGestureEvent(ui::GestureEvent* event) override; +- +- // wm::ActivationDelegate: +- bool ShouldActivate() const override; +- +- // wm::ActivationChangeObserver: +- void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, +- aura::Window* gained_active, +- aura::Window* lost_active) override; +- +- // aura::client::FocusChangeObserver: +- void OnWindowFocused(aura::Window* gained_focus, +- aura::Window* lost_focus) override; +- +- // aura::client::DragDropDelegate: +- void OnDragEntered(const ui::DropTargetEvent& event) override; +- int OnDragUpdated(const ui::DropTargetEvent& event) override; +- void OnDragExited() override; +- int OnPerformDrop(const ui::DropTargetEvent& event, +- std::unique_ptr data) override; +- + protected: +- ~NativeWidgetAura() override; ++ ~NativeWidgetAndroid() override; + + internal::NativeWidgetDelegate* delegate() { return delegate_; } + +@@ -228,7 +160,7 @@ class VIEWS_EXPORT NativeWidgetAura : pu + // WARNING: set to NULL when destroyed. As the Widget is not necessarily + // destroyed along with |window_| all usage of |window_| should first verify + // non-NULL. +- aura::Window* window_; ++ gfx::NativeWindow window_; + + // See class documentation for Widget in widget.h for a note about ownership. + Widget::InitParams::Ownership ownership_; +@@ -238,7 +170,7 @@ class VIEWS_EXPORT NativeWidgetAura : pu + + gfx::NativeCursor cursor_; + +- std::unique_ptr tooltip_manager_; ++ std::unique_ptr tooltip_manager_; + + // Reorders child windows of |window_| associated with a view based on the + // order of the associated views in the widget's view hierarchy. +@@ -250,13 +182,13 @@ class VIEWS_EXPORT NativeWidgetAura : pu + // Native widget's handler to receive events before the event target. + std::unique_ptr focus_manager_event_handler_; + +- // The following factory is used for calls to close the NativeWidgetAura ++ // The following factory is used for calls to close the NativeWidgetAndroid + // instance. +- base::WeakPtrFactory close_widget_factory_{this}; ++ base::WeakPtrFactory close_widget_factory_{this}; + +- DISALLOW_COPY_AND_ASSIGN(NativeWidgetAura); ++ DISALLOW_COPY_AND_ASSIGN(NativeWidgetAndroid); + }; + + } // namespace views + +-#endif // UI_VIEWS_WIDGET_NATIVE_WIDGET_AURA_H_ ++#endif // UI_VIEWS_WIDGET_NATIVE_WIDGET_ANDROID_H_ +--- a/ui/views/native_cursor_aura.cc ++++ b/ui/views/native_cursor_aura.cc +@@ -5,28 +5,27 @@ + #include "ui/views/native_cursor.h" + + #include "ui/base/cursor/cursor.h" +-#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h" + + namespace views { + + gfx::NativeCursor GetNativeIBeamCursor() { +- return ui::mojom::CursorType::kIBeam; ++ return gfx::kNullCursor; + } + + gfx::NativeCursor GetNativeHandCursor() { +- return ui::mojom::CursorType::kHand; ++ return gfx::kNullCursor; + } + + gfx::NativeCursor GetNativeColumnResizeCursor() { +- return ui::mojom::CursorType::kColumnResize; ++ return gfx::kNullCursor; + } + + gfx::NativeCursor GetNativeEastWestResizeCursor() { +- return ui::mojom::CursorType::kEastWestResize; ++ return gfx::kNullCursor; + } + + gfx::NativeCursor GetNativeNorthSouthResizeCursor() { +- return ui::mojom::CursorType::kNorthSouthResize; ++ return gfx::kNullCursor; + } + + } // namespace views +--- a/ui/views/widget/tooltip_manager_aura.cc ++++ b/ui/views/widget/tooltip_manager_aura.cc +@@ -4,9 +4,6 @@ + + #include "ui/views/widget/tooltip_manager_aura.h" + +-#include "ui/aura/client/screen_position_client.h" +-#include "ui/aura/window_event_dispatcher.h" +-#include "ui/aura/window_tree_host.h" + #include "ui/base/resource/resource_bundle.h" + #include "ui/display/screen.h" + #include "ui/gfx/geometry/rect.h" +@@ -16,111 +13,46 @@ + namespace views { + + //////////////////////////////////////////////////////////////////////////////// +-// TooltipManagerAura public: ++// TooltipManagerAndroid public: + +-TooltipManagerAura::TooltipManagerAura(Widget* widget) : widget_(widget) { +- wm::SetTooltipText(GetWindow(), &tooltip_text_); ++TooltipManagerAndroid::TooltipManagerAndroid(Widget* widget) : widget_(widget) { + } + +-TooltipManagerAura::~TooltipManagerAura() { +- wm::SetTooltipText(GetWindow(), nullptr); ++TooltipManagerAndroid::~TooltipManagerAndroid() { + } + + // static +-const gfx::FontList& TooltipManagerAura::GetDefaultFontList() { ++const gfx::FontList& TooltipManagerAndroid::GetDefaultFontList() { + return ui::ResourceBundle::GetSharedInstance().GetFontList( + ui::ResourceBundle::BaseFont); + } + + // static +-void TooltipManagerAura::UpdateTooltipManagerForCapture(Widget* source) { +- if (!source->HasCapture()) +- return; +- +- aura::Window* root_window = source->GetNativeView()->GetRootWindow(); +- if (!root_window) +- return; +- +- gfx::Point screen_loc( +- root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot()); +- aura::client::ScreenPositionClient* screen_position_client = +- aura::client::GetScreenPositionClient(root_window); +- if (!screen_position_client) +- return; +- screen_position_client->ConvertPointToScreen(root_window, &screen_loc); +- display::Screen* screen = display::Screen::GetScreen(); +- aura::Window* target = screen->GetWindowAtScreenPoint(screen_loc); +- if (!target) +- return; +- gfx::Point target_loc(screen_loc); +- screen_position_client = +- aura::client::GetScreenPositionClient(target->GetRootWindow()); +- if (!screen_position_client) +- return; +- screen_position_client->ConvertPointFromScreen(target, &target_loc); +- target = target->GetEventHandlerForPoint(target_loc); +- while (target) { +- Widget* target_widget = Widget::GetWidgetForNativeView(target); +- if (target_widget == source) +- return; +- +- if (target_widget) { +- if (target_widget->GetTooltipManager()) +- target_widget->GetTooltipManager()->UpdateTooltip(); +- return; +- } +- target = target->parent(); +- } ++void TooltipManagerAndroid::UpdateTooltipManagerForCapture(Widget* source) { + } + + //////////////////////////////////////////////////////////////////////////////// +-// TooltipManagerAura, TooltipManager implementation: ++// TooltipManagerAndroid, TooltipManager implementation: + +-const gfx::FontList& TooltipManagerAura::GetFontList() const { ++const gfx::FontList& TooltipManagerAndroid::GetFontList() const { + return GetDefaultFontList(); + } + +-int TooltipManagerAura::GetMaxWidth(const gfx::Point& point) const { +- return wm::GetTooltipClient(widget_->GetNativeView()->GetRootWindow()) +- ->GetMaxWidth(point); +-} +- +-void TooltipManagerAura::UpdateTooltip() { +- aura::Window* root_window = GetWindow()->GetRootWindow(); +- if (wm::GetTooltipClient(root_window)) { +- if (!widget_->IsVisible()) { +- UpdateTooltipForTarget(nullptr, gfx::Point(), root_window); +- return; +- } +- gfx::Point view_point = +- root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); +- aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point); +- View* view = GetViewUnderPoint(view_point); +- UpdateTooltipForTarget(view, view_point, root_window); +- } ++int TooltipManagerAndroid::GetMaxWidth(const gfx::Point& point) const { ++ return 0; + } + +-void TooltipManagerAura::TooltipTextChanged(View* view) { +- aura::Window* root_window = GetWindow()->GetRootWindow(); +- if (wm::GetTooltipClient(root_window)) { +- gfx::Point view_point = +- root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); +- aura::Window::ConvertPointToTarget(root_window, GetWindow(), &view_point); +- View* target = GetViewUnderPoint(view_point); +- if (target != view) +- return; +- UpdateTooltipForTarget(view, view_point, root_window); +- } ++void TooltipManagerAndroid::UpdateTooltip() { ++} ++ ++void TooltipManagerAndroid::TooltipTextChanged(View* view) { + } + +-View* TooltipManagerAura::GetViewUnderPoint(const gfx::Point& point) { +- View* root_view = widget_->GetRootView(); +- if (root_view) +- return root_view->GetTooltipHandlerForPoint(point); ++View* TooltipManagerAndroid::GetViewUnderPoint(const gfx::Point& point) { + return nullptr; + } + +-void TooltipManagerAura::UpdateTooltipForTarget(View* target, ++void TooltipManagerAndroid::UpdateTooltipForTarget(View* target, + const gfx::Point& point, + aura::Window* root_window) { + if (target) { +@@ -130,14 +62,10 @@ void TooltipManagerAura::UpdateTooltipFo + } else { + tooltip_text_.clear(); + } +- +- wm::SetTooltipId(GetWindow(), target); +- +- wm::GetTooltipClient(root_window)->UpdateTooltip(GetWindow()); + } + +-aura::Window* TooltipManagerAura::GetWindow() { +- return widget_->GetNativeView(); ++aura::Window* TooltipManagerAndroid::GetWindow() { ++ return nullptr; + } + + } // namespace views. +--- a/ui/views/widget/tooltip_manager_aura.h ++++ b/ui/views/widget/tooltip_manager_aura.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ +-#define UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ ++#ifndef UI_VIEWS_WIDGET_TOOLTIP_MANAGER_ANDROID_H_ ++#define UI_VIEWS_WIDGET_TOOLTIP_MANAGER_ANDROID_H_ + + #include "base/compiler_specific.h" + #include "base/macros.h" +@@ -24,11 +24,11 @@ namespace views { + + class Widget; + +-// TooltipManager implementation for Aura. +-class VIEWS_EXPORT TooltipManagerAura : public TooltipManager { ++// TooltipManager implementation for Android. ++class VIEWS_EXPORT TooltipManagerAndroid : public TooltipManager { + public: +- explicit TooltipManagerAura(Widget* widget); +- ~TooltipManagerAura() override; ++ explicit TooltipManagerAndroid(Widget* widget); ++ ~TooltipManagerAndroid() override; + + // If |source| has capture this finds the Widget under the mouse and invokes + // UpdateTooltip() on it's TooltipManager. This is necessary as when capture +@@ -36,7 +36,7 @@ class VIEWS_EXPORT TooltipManagerAura : + // though we may show tooltips for the Window under the mouse. + static void UpdateTooltipManagerForCapture(Widget* source); + +- // Returns the FontList used by all TooltipManagerAuras. ++ // Returns the FontList used by all TooltipManagerAndroids. + static const gfx::FontList& GetDefaultFontList(); + + // TooltipManager: +@@ -57,9 +57,9 @@ class VIEWS_EXPORT TooltipManagerAura : + Widget* widget_; + base::string16 tooltip_text_; + +- DISALLOW_COPY_AND_ASSIGN(TooltipManagerAura); ++ DISALLOW_COPY_AND_ASSIGN(TooltipManagerAndroid); + }; + + } // namespace views + +-#endif // UI_VIEWS_WIDGET_TOOLTIP_MANAGER_AURA_H_ ++#endif // UI_VIEWS_WIDGET_TOOLTIP_MANAGER_ANDROID_H_ +--- a/ui/views/controls/menu/menu_pre_target_handler_aura.cc ++++ b/ui/views/controls/menu/menu_pre_target_handler_aura.cc +@@ -6,8 +6,6 @@ + + #include + +-#include "ui/aura/env.h" +-#include "ui/aura/window.h" + #include "ui/views/controls/menu/menu_controller.h" + #include "ui/views/widget/widget.h" + #include "ui/wm/public/activation_client.h" +@@ -16,67 +14,37 @@ namespace views { + + namespace { + +-aura::Window* GetOwnerRootWindow(views::Widget* owner) { +- return owner ? owner->GetNativeWindow()->GetRootWindow() : nullptr; ++ui::WindowAndroid* GetOwnerRootWindow(views::Widget* owner) { ++ return nullptr; + } + + } // namespace + +-MenuPreTargetHandlerAura::MenuPreTargetHandlerAura(MenuController* controller, ++MenuPreTargetHandlerAndroid::MenuPreTargetHandlerAndroid(MenuController* controller, + Widget* owner) + : controller_(controller), root_(GetOwnerRootWindow(owner)) { +- if (root_) { +- wm::GetActivationClient(root_)->AddObserver(this); +- root_->AddObserver(this); +- } else { +- // This should only happen in cases like when context menus are shown for +- // Windows OS system tray items and there is no parent window. +- } +- aura::Env::GetInstance()->AddPreTargetHandler( +- this, ui::EventTarget::Priority::kSystem); + } + +-MenuPreTargetHandlerAura::~MenuPreTargetHandlerAura() { +- aura::Env::GetInstance()->RemovePreTargetHandler(this); ++MenuPreTargetHandlerAndroid::~MenuPreTargetHandlerAndroid() { + Cleanup(); + } + +-void MenuPreTargetHandlerAura::OnWindowActivated( +- wm::ActivationChangeObserver::ActivationReason reason, +- aura::Window* gained_active, +- aura::Window* lost_active) { +- if (!controller_->drag_in_progress()) +- controller_->Cancel(MenuController::ExitType::kAll); +-} +- +-void MenuPreTargetHandlerAura::OnWindowDestroying(aura::Window* window) { +- Cleanup(); +-} +- +-void MenuPreTargetHandlerAura::OnCancelMode(ui::CancelModeEvent* event) { ++void MenuPreTargetHandlerAndroid::OnCancelMode(ui::CancelModeEvent* event) { + controller_->Cancel(MenuController::ExitType::kAll); + } + +-void MenuPreTargetHandlerAura::OnKeyEvent(ui::KeyEvent* event) { ++void MenuPreTargetHandlerAndroid::OnKeyEvent(ui::KeyEvent* event) { + controller_->OnWillDispatchKeyEvent(event); + } + +-void MenuPreTargetHandlerAura::Cleanup() { +- if (!root_) +- return; +- // The ActivationClient may have been destroyed by the time we get here. +- wm::ActivationClient* client = wm::GetActivationClient(root_); +- if (client) +- client->RemoveObserver(this); +- root_->RemoveObserver(this); +- root_ = nullptr; ++void MenuPreTargetHandlerAndroid::Cleanup() { + } + + // static + std::unique_ptr MenuPreTargetHandler::Create( + MenuController* controller, + Widget* owner) { +- return std::make_unique(controller, owner); ++ return nullptr; + } + + } // namespace views +--- a/ui/views/controls/menu/menu_pre_target_handler_aura.h ++++ b/ui/views/controls/menu/menu_pre_target_handler_aura.h +@@ -2,44 +2,29 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_AURA_H_ +-#define UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_AURA_H_ ++#ifndef UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_ANDROID_H_ ++#define UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_ANDROID_H_ + +-#include "ui/aura/window_observer.h" ++#include "ui/android/window_android.h" + #include "ui/events/event_handler.h" + #include "ui/views/controls/menu/menu_pre_target_handler.h" + #include "ui/views/views_export.h" +-#include "ui/wm/public/activation_change_observer.h" +- +-namespace aura { +-class Window; +-} // namespace aura + + namespace views { + + class MenuController; + class Widget; + +-// MenuPreTargetHandlerAura is used to observe activation changes, cancel ++// MenuPreTargetHandlerAndroid is used to observe activation changes, cancel + // events, and root window destruction, to shutdown the menu. + // + // Additionally handles key events to provide accelerator support to menus. +-class VIEWS_EXPORT MenuPreTargetHandlerAura +- : public wm::ActivationChangeObserver, +- public aura::WindowObserver, +- public ui::EventHandler, ++class VIEWS_EXPORT MenuPreTargetHandlerAndroid ++ : public ui::EventHandler, + public MenuPreTargetHandler { + public: +- MenuPreTargetHandlerAura(MenuController* controller, Widget* owner); +- ~MenuPreTargetHandlerAura() override; +- +- // aura::client:ActivationChangeObserver: +- void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason, +- aura::Window* gained_active, +- aura::Window* lost_active) override; +- +- // aura::WindowObserver: +- void OnWindowDestroying(aura::Window* window) override; ++ MenuPreTargetHandlerAndroid(MenuController* controller, Widget* owner); ++ ~MenuPreTargetHandlerAndroid() override; + + // ui::EventHandler: + void OnCancelMode(ui::CancelModeEvent* event) override; +@@ -49,11 +34,11 @@ class VIEWS_EXPORT MenuPreTargetHandlerA + void Cleanup(); + + MenuController* controller_; +- aura::Window* root_; ++ ui::WindowAndroid* root_; + +- DISALLOW_COPY_AND_ASSIGN(MenuPreTargetHandlerAura); ++ DISALLOW_COPY_AND_ASSIGN(MenuPreTargetHandlerAndroid); + }; + + } // namespace views + +-#endif // UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_AURA_H_ ++#endif // UI_VIEWS_CONTROLS_MENU_MENU_PRE_TARGET_HANDLER_ANDROID_H_ +--- a/ui/views/controls/native/native_view_host_aura.cc ++++ b/ui/views/controls/native/native_view_host_aura.cc +@@ -10,12 +10,7 @@ + #include "base/check.h" + #include "base/optional.h" + #include "build/build_config.h" +-#include "ui/aura/client/aura_constants.h" +-#include "ui/aura/client/focus_client.h" +-#include "ui/aura/window.h" +-#include "ui/aura/window_delegate.h" +-#include "ui/aura/window_occlusion_tracker.h" +-#include "ui/aura/window_targeter.h" ++#include "ui/android/window_android.h" + #include "ui/base/cursor/cursor.h" + #include "ui/base/hit_test.h" + #include "ui/compositor/paint_recorder.h" +@@ -23,368 +18,118 @@ + #include "ui/views/controls/native/native_view_host.h" + #include "ui/views/painter.h" + #include "ui/views/view_class_properties.h" +-#include "ui/views/view_constants_aura.h" + #include "ui/views/widget/widget.h" + + namespace views { + +-class NativeViewHostAura::ClippingWindowDelegate : public aura::WindowDelegate { +- public: +- ClippingWindowDelegate() = default; +- ~ClippingWindowDelegate() override = default; +- +- void set_native_view(aura::Window* native_view) { +- native_view_ = native_view; +- } +- +- gfx::Size GetMinimumSize() const override { return gfx::Size(); } +- gfx::Size GetMaximumSize() const override { return gfx::Size(); } +- void OnBoundsChanged(const gfx::Rect& old_bounds, +- const gfx::Rect& new_bounds) override {} +- gfx::NativeCursor GetCursor(const gfx::Point& point) override { +- return gfx::kNullCursor; +- } +- int GetNonClientComponent(const gfx::Point& point) const override { +- return HTCLIENT; +- } +- bool ShouldDescendIntoChildForEventHandling( +- aura::Window* child, +- const gfx::Point& location) override { +- return true; +- } +- bool CanFocus() override { +- // Ask the hosted native view's delegate because directly calling +- // aura::Window::CanFocus() will call back into this when checking whether +- // parents can focus. +- return !native_view_ || !native_view_->delegate() || +- native_view_->delegate()->CanFocus(); +- } +- void OnCaptureLost() override {} +- void OnPaint(const ui::PaintContext& context) override {} +- void OnDeviceScaleFactorChanged(float old_device_scale_factor, +- float new_device_scale_factor) override {} +- void OnWindowDestroying(aura::Window* window) override {} +- void OnWindowDestroyed(aura::Window* window) override {} +- void OnWindowTargetVisibilityChanged(bool visible) override {} +- bool HasHitTestMask() const override { return false; } +- void GetHitTestMask(SkPath* mask) const override {} +- +- private: +- aura::Window* native_view_ = nullptr; +-}; +- +-NativeViewHostAura::NativeViewHostAura(NativeViewHost* host) : host_(host) {} +- +-NativeViewHostAura::~NativeViewHostAura() { +- if (host_->native_view()) { +- host_->native_view()->RemoveObserver(this); +- host_->native_view()->ClearProperty(views::kHostViewKey); +- host_->native_view()->ClearProperty(aura::client::kHostWindowKey); +- host_->native_view()->ClearProperty( +- aura::client::kParentNativeViewAccessibleKey); +- clipping_window_->ClearProperty(views::kHostViewKey); +- if (host_->native_view()->parent() == clipping_window_.get()) +- clipping_window_->RemoveChild(host_->native_view()); +- } ++NativeViewHostAndroid::NativeViewHostAndroid(NativeViewHost* host) : host_(host) {} ++ ++NativeViewHostAndroid::~NativeViewHostAndroid() { + } + + //////////////////////////////////////////////////////////////////////////////// +-// NativeViewHostAura, NativeViewHostWrapper implementation: +-void NativeViewHostAura::AttachNativeView() { +- if (!clipping_window_) +- CreateClippingWindow(); +- clipping_window_delegate_->set_native_view(host_->native_view()); +- host_->native_view()->AddObserver(this); +- host_->native_view()->SetProperty(views::kHostViewKey, +- static_cast(host_)); +- +- original_transform_ = host_->native_view()->transform(); +- original_transform_changed_ = false; +- AddClippingWindow(); +- InstallMask(); +- ApplyRoundedCorners(); ++// NativeViewHostAndroid, NativeViewHostWrapper implementation: ++void NativeViewHostAndroid::AttachNativeView() { + } + +-void NativeViewHostAura::SetParentAccessible( ++void NativeViewHostAndroid::SetParentAccessible( + gfx::NativeViewAccessible accessible) { +- host_->native_view()->SetProperty( +- aura::client::kParentNativeViewAccessibleKey, accessible); + } + +-gfx::NativeViewAccessible NativeViewHostAura::GetParentAccessible() { +- return host_->native_view()->GetProperty( +- aura::client::kParentNativeViewAccessibleKey); +-} +- +-void NativeViewHostAura::NativeViewDetaching(bool destroyed) { +- // This method causes a succession of window tree changes. ScopedPause ensures +- // that occlusion is recomputed at the end of the method instead of after each +- // change. +- base::Optional pause_occlusion; +- if (clipping_window_) +- pause_occlusion.emplace(); +- +- clipping_window_delegate_->set_native_view(nullptr); +- RemoveClippingWindow(); +- if (!destroyed) { +- host_->native_view()->RemoveObserver(this); +- host_->native_view()->ClearProperty(views::kHostViewKey); +- host_->native_view()->ClearProperty(aura::client::kHostWindowKey); +- host_->native_view()->ClearProperty( +- aura::client::kParentNativeViewAccessibleKey); +- if (original_transform_changed_) +- host_->native_view()->SetTransform(original_transform_); +- host_->native_view()->Hide(); +- if (host_->native_view()->parent()) +- Widget::ReparentNativeView(host_->native_view(), nullptr); +- } +-} +- +-void NativeViewHostAura::AddedToWidget() { +- if (!host_->native_view()) +- return; +- +- AddClippingWindow(); +- if (host_->IsDrawn()) +- host_->native_view()->Show(); +- else +- host_->native_view()->Hide(); +- host_->InvalidateLayout(); +-} +- +-void NativeViewHostAura::RemovedFromWidget() { +- if (host_->native_view()) { +- // Clear kHostWindowKey before Hide() because it could be accessed during +- // the call. In MUS aura, the hosting window could be destroyed at this +- // point. +- host_->native_view()->ClearProperty(aura::client::kHostWindowKey); +- +- host_->native_view()->Hide(); +- if (host_->native_view()->parent()) +- host_->native_view()->parent()->RemoveChild(host_->native_view()); +- RemoveClippingWindow(); +- } ++gfx::NativeViewAccessible NativeViewHostAndroid::GetParentAccessible() { ++ return nullptr; ++} ++ ++void NativeViewHostAndroid::NativeViewDetaching(bool destroyed) { ++} ++ ++void NativeViewHostAndroid::AddedToWidget() { + } + +-bool NativeViewHostAura::SetCornerRadii( ++void NativeViewHostAndroid::RemovedFromWidget() { ++} ++ ++bool NativeViewHostAndroid::SetCornerRadii( + const gfx::RoundedCornersF& corner_radii) { +- corner_radii_ = corner_radii; +- ApplyRoundedCorners(); +- return true; ++ return false; + } + +-bool NativeViewHostAura::SetCustomMask(std::unique_ptr mask) { +- UninstallMask(); +- mask_ = std::move(mask); +- if (mask_) +- mask_->layer()->SetFillsBoundsOpaquely(false); +- InstallMask(); +- return true; ++bool NativeViewHostAndroid::SetCustomMask(std::unique_ptr mask) { ++ return false; + } + +-void NativeViewHostAura::SetHitTestTopInset(int top_inset) { +- if (top_inset_ == top_inset) +- return; +- top_inset_ = top_inset; +- UpdateInsets(); ++void NativeViewHostAndroid::SetHitTestTopInset(int top_inset) { + } + +-void NativeViewHostAura::InstallClip(int x, int y, int w, int h) { +- clip_rect_ = std::make_unique( +- host_->ConvertRectToWidget(gfx::Rect(x, y, w, h))); ++void NativeViewHostAndroid::InstallClip(int x, int y, int w, int h) { + } + +-int NativeViewHostAura::GetHitTestTopInset() const { ++int NativeViewHostAndroid::GetHitTestTopInset() const { + return top_inset_; + } + +-bool NativeViewHostAura::HasInstalledClip() { ++bool NativeViewHostAndroid::HasInstalledClip() { + return !!clip_rect_; + } + +-void NativeViewHostAura::UninstallClip() { ++void NativeViewHostAndroid::UninstallClip() { + clip_rect_.reset(); + } + +-void NativeViewHostAura::ShowWidget(int x, ++void NativeViewHostAndroid::ShowWidget(int x, + int y, + int w, + int h, + int native_w, + int native_h) { +- if (host_->fast_resize()) { +- gfx::Point origin(x, y); +- views::View::ConvertPointFromWidget(host_, &origin); +- InstallClip(origin.x(), origin.y(), w, h); +- native_w = host_->native_view()->bounds().width(); +- native_h = host_->native_view()->bounds().height(); +- } else { +- gfx::Transform transform = original_transform_; +- if (w > 0 && h > 0 && native_w > 0 && native_h > 0) { +- transform.Scale(static_cast(w) / native_w, +- static_cast(h) / native_h); +- } +- // Only set the transform when it is actually different. +- if (transform != host_->native_view()->transform()) { +- host_->native_view()->SetTransform(transform); +- original_transform_changed_ = true; +- } +- } +- +- clipping_window_->SetBounds(clip_rect_ ? *clip_rect_ : gfx::Rect(x, y, w, h)); +- gfx::Point clip_offset = clipping_window_->bounds().origin(); +- host_->native_view()->SetBounds( +- gfx::Rect(x - clip_offset.x(), y - clip_offset.y(), native_w, native_h)); +- host_->native_view()->Show(); +- clipping_window_->Show(); +-} +- +-void NativeViewHostAura::HideWidget() { +- host_->native_view()->Hide(); +- clipping_window_->Hide(); +-} +- +-void NativeViewHostAura::SetFocus() { +- aura::Window* window = host_->native_view(); +- aura::client::FocusClient* client = aura::client::GetFocusClient(window); +- if (client) +- client->FocusWindow(window); + } + +-gfx::NativeView NativeViewHostAura::GetNativeViewContainer() const { +- return clipping_window_.get(); ++void NativeViewHostAndroid::HideWidget() { ++} ++ ++void NativeViewHostAndroid::SetFocus() { ++} ++ ++gfx::NativeView NativeViewHostAndroid::GetNativeViewContainer() const { ++ return gfx::NativeView(); + } + +-gfx::NativeViewAccessible NativeViewHostAura::GetNativeViewAccessible() { ++gfx::NativeViewAccessible NativeViewHostAndroid::GetNativeViewAccessible() { + return nullptr; + } + +-gfx::NativeCursor NativeViewHostAura::GetCursor(int x, int y) { +- if (host_->native_view()) +- return host_->native_view()->GetCursor(gfx::Point(x, y)); ++gfx::NativeCursor NativeViewHostAndroid::GetCursor(int x, int y) { + return gfx::kNullCursor; + } + +-void NativeViewHostAura::SetVisible(bool visible) { +- if (!visible) +- host_->native_view()->Hide(); +- else +- host_->native_view()->Show(); +-} +- +-void NativeViewHostAura::OnWindowBoundsChanged( +- aura::Window* window, +- const gfx::Rect& old_bounds, +- const gfx::Rect& new_bounds, +- ui::PropertyChangeReason reason) { +- if (mask_) +- mask_->layer()->SetBounds(gfx::Rect(host_->native_view()->bounds().size())); +-} +- +-void NativeViewHostAura::OnWindowDestroying(aura::Window* window) { +- DCHECK(window == host_->native_view()); +- clipping_window_delegate_->set_native_view(nullptr); +-} +- +-void NativeViewHostAura::OnWindowDestroyed(aura::Window* window) { +- DCHECK(window == host_->native_view()); +- host_->NativeViewDestroyed(); ++void NativeViewHostAndroid::SetVisible(bool visible) { + } + + // static + NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( + NativeViewHost* host) { +- return new NativeViewHostAura(host); ++ return new NativeViewHostAndroid(host); ++} ++ ++void NativeViewHostAndroid::CreateClippingWindow() { ++} ++ ++void NativeViewHostAndroid::AddClippingWindow() { ++} ++ ++void NativeViewHostAndroid::RemoveClippingWindow() { ++} ++ ++void NativeViewHostAndroid::ApplyRoundedCorners() { ++} ++ ++void NativeViewHostAndroid::InstallMask() { ++} ++ ++void NativeViewHostAndroid::UninstallMask() { + } + +-void NativeViewHostAura::CreateClippingWindow() { +- clipping_window_delegate_ = std::make_unique(); +- // Use WINDOW_TYPE_CONTROLLER type so descendant views (including popups) get +- // positioned appropriately. +- clipping_window_ = std::make_unique( +- clipping_window_delegate_.get(), aura::client::WINDOW_TYPE_CONTROL); +- clipping_window_->Init(ui::LAYER_NOT_DRAWN); +- clipping_window_->set_owned_by_parent(false); +- clipping_window_->SetName("NativeViewHostAuraClip"); +- clipping_window_->layer()->SetMasksToBounds(true); +- clipping_window_->SetProperty(views::kHostViewKey, static_cast(host_)); +- UpdateInsets(); +-} +- +-void NativeViewHostAura::AddClippingWindow() { +- RemoveClippingWindow(); +- +- host_->native_view()->SetProperty(aura::client::kHostWindowKey, +- host_->GetWidget()->GetNativeView()); +- Widget::ReparentNativeView(host_->native_view(), clipping_window_.get()); +- if (host_->GetWidget()->GetNativeView()) { +- Widget::ReparentNativeView(clipping_window_.get(), +- host_->GetWidget()->GetNativeView()); +- } +-} +- +-void NativeViewHostAura::RemoveClippingWindow() { +- clipping_window_->Hide(); +- if (host_->native_view()) +- host_->native_view()->ClearProperty(aura::client::kHostWindowKey); +- +- if (host_->native_view()->parent() == clipping_window_.get()) { +- if (host_->GetWidget() && host_->GetWidget()->GetNativeView()) { +- Widget::ReparentNativeView(host_->native_view(), +- host_->GetWidget()->GetNativeView()); +- } else { +- clipping_window_->RemoveChild(host_->native_view()); +- } +- } +- if (clipping_window_->parent()) +- clipping_window_->parent()->RemoveChild(clipping_window_.get()); +-} +- +-void NativeViewHostAura::ApplyRoundedCorners() { +- if (!host_->native_view()) +- return; +- +- ui::Layer* layer = host_->native_view()->layer(); +- if (layer->rounded_corner_radii() != corner_radii_) { +- layer->SetRoundedCornerRadius(corner_radii_); +- layer->SetIsFastRoundedCorner(true); +- } +-} +- +-void NativeViewHostAura::InstallMask() { +- if (!mask_) +- return; +- if (host_->native_view()) { +- mask_->layer()->SetBounds(gfx::Rect(host_->native_view()->bounds().size())); +- host_->native_view()->layer()->SetMaskLayer(mask_->layer()); +- } +-} +- +-void NativeViewHostAura::UninstallMask() { +- if (!host_->native_view() || !mask_) +- return; +- +- host_->native_view()->layer()->SetMaskLayer(nullptr); +- mask_.reset(); +-} +- +-void NativeViewHostAura::UpdateInsets() { +- if (!clipping_window_) +- return; +- +- if (top_inset_ == 0) { +- // The window targeter needs to be uninstalled when not used; keeping empty +- // targeter here actually conflicts with ash::ImmersiveWindowTargeter on +- // immersive mode in Ash. +- // TODO(mukai): fix this. +- clipping_window_->SetEventTargeter(nullptr); +- } else { +- if (!clipping_window_->targeter()) { +- clipping_window_->SetEventTargeter( +- std::make_unique()); +- } +- clipping_window_->targeter()->SetInsets(gfx::Insets(top_inset_, 0, 0, 0)); +- } ++void NativeViewHostAndroid::UpdateInsets() { + } + + } // namespace views +--- a/ui/views/controls/native/native_view_host_aura.h ++++ b/ui/views/controls/native/native_view_host_aura.h +@@ -9,27 +9,21 @@ + + #include "base/compiler_specific.h" + #include "base/macros.h" +-#include "ui/aura/window_observer.h" + #include "ui/compositor/layer_owner.h" + #include "ui/gfx/geometry/rounded_corners_f.h" + #include "ui/gfx/transform.h" + #include "ui/views/controls/native/native_view_host_wrapper.h" + #include "ui/views/views_export.h" + +-namespace aura { +-class Window; +-} +- + namespace views { + + class NativeViewHost; + +-// Aura implementation of NativeViewHostWrapper. +-class NativeViewHostAura : public NativeViewHostWrapper, +- public aura::WindowObserver { ++// Android implementation of NativeViewHostWrapper. ++class NativeViewHostAndroid : public NativeViewHostWrapper { + public: +- explicit NativeViewHostAura(NativeViewHost* host); +- ~NativeViewHostAura() override; ++ explicit NativeViewHostAndroid(NativeViewHost* host); ++ ~NativeViewHostAndroid() override; + + // Overridden from NativeViewHostWrapper: + void AttachNativeView() override; +@@ -55,16 +49,7 @@ class NativeViewHostAura : public Native + gfx::NativeViewAccessible GetParentAccessible() override; + + private: +- friend class NativeViewHostAuraTest; +- class ClippingWindowDelegate; +- +- // Overridden from aura::WindowObserver: +- void OnWindowDestroying(aura::Window* window) override; +- void OnWindowDestroyed(aura::Window* window) override; +- void OnWindowBoundsChanged(aura::Window* window, +- const gfx::Rect& old_bounds, +- const gfx::Rect& new_bounds, +- ui::PropertyChangeReason reason) override; ++ friend class NativeViewHostAndroidTest; + + void CreateClippingWindow(); + +@@ -91,12 +76,9 @@ class NativeViewHostAura : public Native + // Our associated NativeViewHost. + NativeViewHost* host_; + +- std::unique_ptr clipping_window_delegate_; +- + // Window that exists between the native view and the parent that allows for + // clipping to occur. This is positioned in the coordinate space of + // host_->GetWidget(). +- std::unique_ptr clipping_window_; + std::unique_ptr clip_rect_; + + // This mask exists for the sake of SetCornerRadius(). +@@ -118,9 +100,9 @@ class NativeViewHostAura : public Native + // The top insets to exclude the underlying native view from the target. + int top_inset_ = 0; + +- DISALLOW_COPY_AND_ASSIGN(NativeViewHostAura); ++ DISALLOW_COPY_AND_ASSIGN(NativeViewHostAndroid); + }; + + } // namespace views + +-#endif // UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_AURA_H_ ++#endif // UI_VIEWS_CONTROLS_NATIVE_NATIVE_VIEW_HOST_ANDROID_H_ +--- a/ui/views/event_monitor_aura.cc ++++ b/ui/views/event_monitor_aura.cc +@@ -8,8 +8,7 @@ + + #include "base/check_op.h" + #include "base/scoped_observer.h" +-#include "ui/aura/env.h" +-#include "ui/aura/window.h" ++#include "ui/android/window_android.h" + #include "ui/events/event_observer.h" + #include "ui/events/event_target.h" + +@@ -17,31 +16,21 @@ namespace views { + + namespace { + +-// An EventMonitorAura that removes its event observer on window destruction. +-class WindowMonitorAura : public EventMonitorAura, public aura::WindowObserver { ++// An EventMonitorAndroid that removes its event observer on window destruction. ++class WindowMonitorAndroid : public EventMonitorAndroid { + public: +- WindowMonitorAura(ui::EventObserver* event_observer, +- aura::Window* target_window, ++ WindowMonitorAndroid(ui::EventObserver* event_observer, ++ ui::WindowAndroid* target_window, + const std::set& types) +- : EventMonitorAura(event_observer, target_window, types), ++ : EventMonitorAndroid(event_observer, target_window, types), + target_window_(target_window) { +- window_observer_.Add(target_window); +- } +- ~WindowMonitorAura() override = default; +- +- // aura::WindowObserver: +- void OnWindowDestroying(aura::Window* window) override { +- DCHECK_EQ(window, target_window_); +- window_observer_.Remove(target_window_); +- target_window_ = nullptr; +- TearDown(); + } ++ ~WindowMonitorAndroid() override = default; + + private: +- aura::Window* target_window_; +- ScopedObserver window_observer_{this}; ++ ui::WindowAndroid* target_window_; + +- DISALLOW_COPY_AND_ASSIGN(WindowMonitorAura); ++ DISALLOW_COPY_AND_ASSIGN(WindowMonitorAndroid); + }; + + } // namespace +@@ -51,8 +40,8 @@ std::unique_ptr EventMonit + ui::EventObserver* event_observer, + gfx::NativeWindow context, + const std::set& types) { +- return std::make_unique(event_observer, +- aura::Env::GetInstance(), types); ++ return std::make_unique(event_observer, ++ nullptr, types); + } + + // static +@@ -60,31 +49,27 @@ std::unique_ptr EventMonit + ui::EventObserver* event_observer, + gfx::NativeWindow target_window, + const std::set& types) { +- return std::make_unique(event_observer, target_window, ++ return std::make_unique(event_observer, nullptr, + types); + } + +-EventMonitorAura::EventMonitorAura(ui::EventObserver* event_observer, ++EventMonitorAndroid::EventMonitorAndroid(ui::EventObserver* event_observer, + ui::EventTarget* event_target, + const std::set& types) + : event_observer_(event_observer), event_target_(event_target) { + DCHECK(event_observer_); + DCHECK(event_target_); +- aura::Env::GetInstance()->AddEventObserver(event_observer_, event_target, +- types); + } + +-EventMonitorAura::~EventMonitorAura() { ++EventMonitorAndroid::~EventMonitorAndroid() { + TearDown(); + } + +-gfx::Point EventMonitorAura::GetLastMouseLocation() { +- return aura::Env::GetInstance()->last_mouse_location(); ++gfx::Point EventMonitorAndroid::GetLastMouseLocation() { ++ return gfx::Point(); + } + +-void EventMonitorAura::TearDown() { +- if (event_observer_) +- aura::Env::GetInstance()->RemoveEventObserver(event_observer_); ++void EventMonitorAndroid::TearDown() { + event_observer_ = nullptr; + } + +--- a/ui/views/event_monitor_aura.h ++++ b/ui/views/event_monitor_aura.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef UI_VIEWS_EVENT_MONITOR_AURA_H_ +-#define UI_VIEWS_EVENT_MONITOR_AURA_H_ ++#ifndef UI_VIEWS_EVENT_MONITOR_ANDROID_H_ ++#define UI_VIEWS_EVENT_MONITOR_ANDROID_H_ + + #include + +@@ -17,12 +17,12 @@ class EventTarget; + namespace views { + + // Observes events by installing a pre-target handler on the ui::EventTarget. +-class EventMonitorAura : public EventMonitor { ++class EventMonitorAndroid : public EventMonitor { + public: +- EventMonitorAura(ui::EventObserver* event_observer, ++ EventMonitorAndroid(ui::EventObserver* event_observer, + ui::EventTarget* event_target, + const std::set& types); +- ~EventMonitorAura() override; ++ ~EventMonitorAndroid() override; + + // EventMonitor: + gfx::Point GetLastMouseLocation() override; +@@ -35,9 +35,9 @@ class EventMonitorAura : public EventMon + ui::EventObserver* event_observer_; // Weak. Owned by our owner. + ui::EventTarget* event_target_; // Weak. + +- DISALLOW_COPY_AND_ASSIGN(EventMonitorAura); ++ DISALLOW_COPY_AND_ASSIGN(EventMonitorAndroid); + }; + + } // namespace views + +-#endif // UI_VIEWS_EVENT_MONITOR_AURA_H_ ++#endif // UI_VIEWS_EVENT_MONITOR_ANDROID_H_ +--- a/ui/views/drag_utils_aura.cc ++++ b/ui/views/drag_utils_aura.cc +@@ -4,10 +4,7 @@ + + #include "ui/views/drag_utils.h" + +-#include "ui/aura/client/drag_drop_client.h" +-#include "ui/aura/window.h" +-#include "ui/aura/window_event_dispatcher.h" +-#include "ui/wm/core/coordinate_conversion.h" ++#include "ui/android/window_android.h" + + namespace views { + +@@ -16,14 +13,6 @@ void RunShellDrag(gfx::NativeView view, + const gfx::Point& location, + int operation, + ui::mojom::DragEventSource source) { +- gfx::Point screen_location(location); +- wm::ConvertPointToScreen(view, &screen_location); +- aura::Window* root_window = view->GetRootWindow(); +- if (aura::client::GetDragDropClient(root_window)) { +- aura::client::GetDragDropClient(root_window) +- ->StartDragAndDrop(std::move(data), root_window, view, screen_location, +- operation, source); +- } + } + + } // namespace views +--- a/chrome/browser/ui/views/frame/native_browser_frame_factory_aurax11.cc ++++ b/chrome/browser/ui/views/frame/native_browser_frame_factory_aurax11.cc +@@ -4,10 +4,10 @@ + + #include "chrome/browser/ui/views/frame/native_browser_frame_factory.h" + +-#include "chrome/browser/ui/views/frame/desktop_browser_frame_aura_linux.h" ++#include "chrome/browser/ui/views/frame/desktop_browser_frame_aura.h" + + NativeBrowserFrame* NativeBrowserFrameFactory::Create( + BrowserFrame* browser_frame, + BrowserView* browser_view) { +- return new DesktopBrowserFrameAuraLinux(browser_frame, browser_view); ++ return new DesktopBrowserFrameAndroid(browser_frame, browser_view); + } +--- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc ++++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.cc +@@ -7,10 +7,7 @@ + #include "chrome/app/chrome_command_ids.h" + #include "chrome/browser/ui/views/frame/browser_desktop_window_tree_host.h" + #include "chrome/browser/ui/views/frame/browser_view.h" +-#include "ui/aura/client/aura_constants.h" +-#include "ui/aura/window.h" +-#include "ui/aura/window_event_dispatcher.h" +-#include "ui/aura/window_observer.h" ++#include "ui/android/window_android.h" + #include "ui/base/hit_test.h" + #include "ui/base/models/simple_menu_model.h" + #include "ui/gfx/font.h" +@@ -18,99 +15,62 @@ + #include "ui/views/widget/widget.h" + #include "ui/wm/core/visibility_controller.h" + +-using aura::Window; ++using ui::WindowAndroid; + + /////////////////////////////////////////////////////////////////////////////// +-// DesktopBrowserFrameAura, public: ++// DesktopBrowserFrameAndroid, public: + +-DesktopBrowserFrameAura::DesktopBrowserFrameAura( ++DesktopBrowserFrameAndroid::DesktopBrowserFrameAndroid( + BrowserFrame* browser_frame, + BrowserView* browser_view) +- : views::DesktopNativeWidgetAura(browser_frame), +- browser_view_(browser_view), +- browser_frame_(browser_frame), +- browser_desktop_window_tree_host_(nullptr) { +- GetNativeWindow()->SetName("BrowserFrameAura"); ++ : browser_view_(browser_view), ++ browser_frame_(browser_frame) { + } + + /////////////////////////////////////////////////////////////////////////////// +-// DesktopBrowserFrameAura, protected: ++// DesktopBrowserFrameAndroid, protected: + +-DesktopBrowserFrameAura::~DesktopBrowserFrameAura() { +-} +- +-/////////////////////////////////////////////////////////////////////////////// +-// DesktopBrowserFrameAura, views::DesktopNativeWidgetAura overrides: +- +-void DesktopBrowserFrameAura::OnHostClosed() { +- aura::client::SetVisibilityClient(GetNativeView()->GetRootWindow(), nullptr); +- DesktopNativeWidgetAura::OnHostClosed(); +-} +- +-void DesktopBrowserFrameAura::InitNativeWidget( +- views::Widget::InitParams params) { +- browser_desktop_window_tree_host_ = +- BrowserDesktopWindowTreeHost::CreateBrowserDesktopWindowTreeHost( +- browser_frame_, +- this, +- browser_view_, +- browser_frame_); +- params.desktop_window_tree_host = +- browser_desktop_window_tree_host_->AsDesktopWindowTreeHost(); +- DesktopNativeWidgetAura::InitNativeWidget(std::move(params)); +- +- visibility_controller_ = std::make_unique(); +- aura::client::SetVisibilityClient(GetNativeView()->GetRootWindow(), +- visibility_controller_.get()); +- wm::SetChildWindowVisibilityChangesAnimated( +- GetNativeView()->GetRootWindow()); ++DesktopBrowserFrameAndroid::~DesktopBrowserFrameAndroid() { + } + + //////////////////////////////////////////////////////////////////////////////// +-// DesktopBrowserFrameAura, NativeBrowserFrame implementation: ++// DesktopBrowserFrameAndroid, NativeBrowserFrame implementation: + +-views::Widget::InitParams DesktopBrowserFrameAura::GetWidgetParams() { ++views::Widget::InitParams DesktopBrowserFrameAndroid::GetWidgetParams() { + views::Widget::InitParams params; +- params.native_widget = this; + return params; + } + +-bool DesktopBrowserFrameAura::UseCustomFrame() const { ++bool DesktopBrowserFrameAndroid::UseCustomFrame() const { + return true; + } + +-bool DesktopBrowserFrameAura::UsesNativeSystemMenu() const { +- return browser_desktop_window_tree_host_->UsesNativeSystemMenu(); ++bool DesktopBrowserFrameAndroid::UsesNativeSystemMenu() const { ++ return true; + } + +-int DesktopBrowserFrameAura::GetMinimizeButtonOffset() const { +- return browser_desktop_window_tree_host_->GetMinimizeButtonOffset(); ++int DesktopBrowserFrameAndroid::GetMinimizeButtonOffset() const { ++ return 0; + } + +-bool DesktopBrowserFrameAura::ShouldSaveWindowPlacement() const { ++bool DesktopBrowserFrameAndroid::ShouldSaveWindowPlacement() const { + // The placement can always be stored. + return true; + } + +-void DesktopBrowserFrameAura::GetWindowPlacement( ++void DesktopBrowserFrameAndroid::GetWindowPlacement( + gfx::Rect* bounds, + ui::WindowShowState* show_state) const { +- *bounds = GetWidget()->GetRestoredBounds(); +- if (IsMaximized()) +- *show_state = ui::SHOW_STATE_MAXIMIZED; +- else if (IsMinimized()) +- *show_state = ui::SHOW_STATE_MINIMIZED; +- else +- *show_state = ui::SHOW_STATE_NORMAL; ++ *show_state = ui::SHOW_STATE_NORMAL; + } + + content::KeyboardEventProcessingResult +-DesktopBrowserFrameAura::PreHandleKeyboardEvent( ++DesktopBrowserFrameAndroid::PreHandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + return content::KeyboardEventProcessingResult::NOT_HANDLED; + } + +-bool DesktopBrowserFrameAura::HandleKeyboardEvent( ++bool DesktopBrowserFrameAndroid::HandleKeyboardEvent( + const content::NativeWebKeyboardEvent& event) { + return false; + } +--- a/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h ++++ b/chrome/browser/ui/views/frame/desktop_browser_frame_aura.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_AURA_H_ +-#define CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_AURA_H_ ++#ifndef CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_ANDROID_H_ ++#define CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_ANDROID_H_ + + #include + +@@ -21,26 +21,21 @@ class VisibilityController; + } + + //////////////////////////////////////////////////////////////////////////////// +-// DesktopBrowserFrameAura ++// DesktopBrowserFrameAndroid + // +-// DesktopBrowserFrameAura is a DesktopNativeWidgetAura subclass that provides ++// DesktopBrowserFrameAndroid is a DesktopNativeWidgetAndroid subclass that provides + // the window frame for the Chrome browser window. + // +-class DesktopBrowserFrameAura : public views::DesktopNativeWidgetAura, +- public NativeBrowserFrame { ++class DesktopBrowserFrameAndroid : public NativeBrowserFrame { + public: +- DesktopBrowserFrameAura(BrowserFrame* browser_frame, ++ DesktopBrowserFrameAndroid(BrowserFrame* browser_frame, + BrowserView* browser_view); + + BrowserView* browser_view() const { return browser_view_; } + BrowserFrame* browser_frame() const { return browser_frame_; } + + protected: +- ~DesktopBrowserFrameAura() override; +- +- // Overridden from views::DesktopNativeWidgetAura: +- void OnHostClosed() override; +- void InitNativeWidget(views::Widget::InitParams params) override; ++ ~DesktopBrowserFrameAndroid() override; + + // Overridden from NativeBrowserFrame: + views::Widget::InitParams GetWidgetParams() override; +@@ -60,12 +55,9 @@ class DesktopBrowserFrameAura : public v + BrowserView* browser_view_; + BrowserFrame* browser_frame_; + +- // Owned by the RootWindow. +- BrowserDesktopWindowTreeHost* browser_desktop_window_tree_host_; +- + std::unique_ptr visibility_controller_; + +- DISALLOW_COPY_AND_ASSIGN(DesktopBrowserFrameAura); ++ DISALLOW_COPY_AND_ASSIGN(DesktopBrowserFrameAndroid); + }; + +-#endif // CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_AURA_H_ ++#endif // CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_ANDROID_H_ +--- a/chrome/browser/download/drag_download_item_aura.cc ++++ b/chrome/browser/download/drag_download_item_aura.cc +@@ -34,30 +34,4 @@ void DragDownloadItem(const download::Do + gfx::NativeView view) { + DCHECK(download); + DCHECK_EQ(download::DownloadItem::COMPLETE, download->GetState()); +- +- aura::Window* root_window = view->GetRootWindow(); +- if (!root_window || !aura::client::GetDragDropClient(root_window)) +- return; +- +- // Set up our OLE machinery +- auto data = std::make_unique(); +- +- button_drag_utils::SetDragImage( +- GURL(), download->GetFileNameToReportUser().BaseName().LossyDisplayName(), +- icon ? icon->AsImageSkia() : gfx::ImageSkia(), nullptr, +- *views::Widget::GetTopLevelWidgetForNativeView(view), data.get()); +- +- base::FilePath full_path = download->GetTargetFilePath(); +- std::vector file_infos; +- file_infos.push_back( +- ui::FileInfo(full_path, download->GetFileNameToReportUser())); +- data->SetFilenames(file_infos); +- +- gfx::Point location = display::Screen::GetScreen()->GetCursorScreenPoint(); +- // TODO(varunjain): Properly determine and send DragEventSource below. +- aura::client::GetDragDropClient(root_window) +- ->StartDragAndDrop( +- std::move(data), root_window, view, location, +- ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_LINK, +- ui::mojom::DragEventSource::kMouse); + } +--- a/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc ++++ b/ui/base/dragdrop/os_exchange_data_provider_non_backed.cc +@@ -19,13 +19,13 @@ + + namespace ui { + +-OSExchangeDataProviderNonBacked::OSExchangeDataProviderNonBacked() = default; ++OSExchangeDataProviderAndroid::OSExchangeDataProviderAndroid() = default; + +-OSExchangeDataProviderNonBacked::~OSExchangeDataProviderNonBacked() = default; ++OSExchangeDataProviderAndroid::~OSExchangeDataProviderAndroid() = default; + +-std::unique_ptr OSExchangeDataProviderNonBacked::Clone() ++std::unique_ptr OSExchangeDataProviderAndroid::Clone() + const { +- auto clone = std::make_unique(); ++ auto clone = std::make_unique(); + + clone->formats_ = formats_; + clone->string_ = string_; +@@ -40,7 +40,7 @@ std::unique_ptr + return clone; + } + +-void OSExchangeDataProviderNonBacked::MarkOriginatedFromRenderer() { ++void OSExchangeDataProviderAndroid::MarkOriginatedFromRenderer() { + // TODO(dcheng): Currently unneeded because ChromeOS Aura correctly separates + // URL and filename metadata, and does not implement the DownloadURL protocol. + #if !defined(OS_CHROMEOS) +@@ -48,7 +48,7 @@ void OSExchangeDataProviderNonBacked::Ma + #endif + } + +-bool OSExchangeDataProviderNonBacked::DidOriginateFromRenderer() const { ++bool OSExchangeDataProviderAndroid::DidOriginateFromRenderer() const { + #if defined(OS_CHROMEOS) + return false; + #else +@@ -56,7 +56,7 @@ bool OSExchangeDataProviderNonBacked::Di + #endif + } + +-void OSExchangeDataProviderNonBacked::SetString(const base::string16& data) { ++void OSExchangeDataProviderAndroid::SetString(const base::string16& data) { + if (HasString()) + return; + +@@ -64,7 +64,7 @@ void OSExchangeDataProviderNonBacked::Se + formats_ |= OSExchangeData::STRING; + } + +-void OSExchangeDataProviderNonBacked::SetURL(const GURL& url, ++void OSExchangeDataProviderAndroid::SetURL(const GURL& url, + const base::string16& title) { + url_ = url; + title_ = title; +@@ -73,26 +73,26 @@ void OSExchangeDataProviderNonBacked::Se + SetString(base::UTF8ToUTF16(url.spec())); + } + +-void OSExchangeDataProviderNonBacked::SetFilename(const base::FilePath& path) { ++void OSExchangeDataProviderAndroid::SetFilename(const base::FilePath& path) { + filenames_.clear(); + filenames_.push_back(FileInfo(path, base::FilePath())); + formats_ |= OSExchangeData::FILE_NAME; + } + +-void OSExchangeDataProviderNonBacked::SetFilenames( ++void OSExchangeDataProviderAndroid::SetFilenames( + const std::vector& filenames) { + filenames_ = filenames; + formats_ |= OSExchangeData::FILE_NAME; + } + +-void OSExchangeDataProviderNonBacked::SetPickledData( ++void OSExchangeDataProviderAndroid::SetPickledData( + const ClipboardFormatType& format, + const base::Pickle& data) { + pickle_data_[format] = data; + formats_ |= OSExchangeData::PICKLED_DATA; + } + +-bool OSExchangeDataProviderNonBacked::GetString(base::string16* data) const { ++bool OSExchangeDataProviderAndroid::GetString(base::string16* data) const { + #if defined(OS_LINUX) || defined(OS_CHROMEOS) + if (HasFile()) { + // Various Linux file managers both pass a list of file:// URIs and set the +@@ -108,7 +108,7 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::GetURLAndTitle( ++bool OSExchangeDataProviderAndroid::GetURLAndTitle( + FilenameToURLPolicy policy, + GURL* url, + base::string16* title) const { +@@ -127,7 +127,7 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::GetFilename(base::FilePath* path) const { ++bool OSExchangeDataProviderAndroid::GetFilename(base::FilePath* path) const { + if ((formats_ & OSExchangeData::FILE_NAME) == 0) + return false; + DCHECK(!filenames_.empty()); +@@ -135,7 +135,7 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::GetFilenames( ++bool OSExchangeDataProviderAndroid::GetFilenames( + std::vector* filenames) const { + if ((formats_ & OSExchangeData::FILE_NAME) == 0) + return false; +@@ -143,7 +143,7 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::GetPickledData( ++bool OSExchangeDataProviderAndroid::GetPickledData( + const ClipboardFormatType& format, + base::Pickle* data) const { + const auto i = pickle_data_.find(format); +@@ -154,11 +154,11 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::HasString() const { ++bool OSExchangeDataProviderAndroid::HasString() const { + return (formats_ & OSExchangeData::STRING) != 0; + } + +-bool OSExchangeDataProviderNonBacked::HasURL(FilenameToURLPolicy policy) const { ++bool OSExchangeDataProviderAndroid::HasURL(FilenameToURLPolicy policy) const { + if ((formats_ & OSExchangeData::URL) != 0) { + return true; + } +@@ -168,31 +168,31 @@ bool OSExchangeDataProviderNonBacked::Ha + GetFileURL(nullptr)); + } + +-bool OSExchangeDataProviderNonBacked::HasFile() const { ++bool OSExchangeDataProviderAndroid::HasFile() const { + return (formats_ & OSExchangeData::FILE_NAME) != 0; + } + +-bool OSExchangeDataProviderNonBacked::HasCustomFormat( ++bool OSExchangeDataProviderAndroid::HasCustomFormat( + const ClipboardFormatType& format) const { + return base::Contains(pickle_data_, format); + } + + #if defined(OS_LINUX) || defined(OS_CHROMEOS) +-void OSExchangeDataProviderNonBacked::SetFileContents( ++void OSExchangeDataProviderAndroid::SetFileContents( + const base::FilePath& filename, + const std::string& file_contents) { + NOTIMPLEMENTED(); + } + #endif + +-void OSExchangeDataProviderNonBacked::SetHtml(const base::string16& html, ++void OSExchangeDataProviderAndroid::SetHtml(const base::string16& html, + const GURL& base_url) { + formats_ |= OSExchangeData::HTML; + html_ = html; + base_url_ = base_url; + } + +-bool OSExchangeDataProviderNonBacked::GetHtml(base::string16* html, ++bool OSExchangeDataProviderAndroid::GetHtml(base::string16* html, + GURL* base_url) const { + if ((formats_ & OSExchangeData::HTML) == 0) + return false; +@@ -201,26 +201,26 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::HasHtml() const { ++bool OSExchangeDataProviderAndroid::HasHtml() const { + return ((formats_ & OSExchangeData::HTML) != 0); + } + +-void OSExchangeDataProviderNonBacked::SetDragImage( ++void OSExchangeDataProviderAndroid::SetDragImage( + const gfx::ImageSkia& image, + const gfx::Vector2d& cursor_offset) { + drag_image_ = image; + drag_image_offset_ = cursor_offset; + } + +-gfx::ImageSkia OSExchangeDataProviderNonBacked::GetDragImage() const { ++gfx::ImageSkia OSExchangeDataProviderAndroid::GetDragImage() const { + return drag_image_; + } + +-gfx::Vector2d OSExchangeDataProviderNonBacked::GetDragImageOffset() const { ++gfx::Vector2d OSExchangeDataProviderAndroid::GetDragImageOffset() const { + return drag_image_offset_; + } + +-bool OSExchangeDataProviderNonBacked::GetFileURL(GURL* url) const { ++bool OSExchangeDataProviderAndroid::GetFileURL(GURL* url) const { + base::FilePath file_path; + if (!GetFilename(&file_path)) + return false; +@@ -234,7 +234,7 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-bool OSExchangeDataProviderNonBacked::GetPlainTextURL(GURL* url) const { ++bool OSExchangeDataProviderAndroid::GetPlainTextURL(GURL* url) const { + if ((formats_ & OSExchangeData::STRING) == 0) + return false; + +@@ -247,12 +247,12 @@ bool OSExchangeDataProviderNonBacked::Ge + return true; + } + +-void OSExchangeDataProviderNonBacked::SetSource( ++void OSExchangeDataProviderAndroid::SetSource( + std::unique_ptr data_source) { + source_ = std::move(data_source); + } + +-DataTransferEndpoint* OSExchangeDataProviderNonBacked::GetSource() const { ++DataTransferEndpoint* OSExchangeDataProviderAndroid::GetSource() const { + return source_.get(); + } + +--- a/ui/base/dragdrop/os_exchange_data_provider_non_backed.h ++++ b/ui/base/dragdrop/os_exchange_data_provider_non_backed.h +@@ -2,8 +2,8 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#ifndef UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_NON_BACKED_H_ +-#define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_NON_BACKED_H_ ++#ifndef UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_ANDROID_H_ ++#define UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_ANDROID_H_ + + #include + #include +@@ -28,15 +28,15 @@ class ClipboardFormatType; + // Simple OSExchangeDataProvider implementation for aura-based ports with no + // actual platform integration. So data managed by this class is exchangeable + // only among Chromium windows and is available only while it is alive. +-class COMPONENT_EXPORT(UI_BASE) OSExchangeDataProviderNonBacked ++class COMPONENT_EXPORT(UI_BASE) OSExchangeDataProviderAndroid + : public OSExchangeDataProvider { + public: +- OSExchangeDataProviderNonBacked(); +- OSExchangeDataProviderNonBacked(const OSExchangeDataProviderNonBacked&) = ++ OSExchangeDataProviderAndroid(); ++ OSExchangeDataProviderAndroid(const OSExchangeDataProviderAndroid&) = + delete; +- OSExchangeDataProviderNonBacked& operator=( +- const OSExchangeDataProviderNonBacked&) = delete; +- ~OSExchangeDataProviderNonBacked() override; ++ OSExchangeDataProviderAndroid& operator=( ++ const OSExchangeDataProviderAndroid&) = delete; ++ ~OSExchangeDataProviderAndroid() override; + + // Overridden from OSExchangeDataProvider: + std::unique_ptr Clone() const override; +@@ -120,4 +120,4 @@ class COMPONENT_EXPORT(UI_BASE) OSExchan + + } // namespace ui + +-#endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_NON_BACKED_H_ ++#endif // UI_BASE_DRAGDROP_OS_EXCHANGE_DATA_PROVIDER_ANDROID_H_ +--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc ++++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc +@@ -1751,16 +1751,6 @@ void RenderViewContextMenu::AppendLangua + #if defined(OS_MAC) + menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_LANGUAGE_SETTINGS, + IDS_CONTENT_CONTEXT_LANGUAGE_SETTINGS); +-#else +- if (!spelling_options_submenu_observer_) { +- const int kLanguageRadioGroup = 1; +- spelling_options_submenu_observer_ = +- std::make_unique(this, this, +- kLanguageRadioGroup); +- } +- +- spelling_options_submenu_observer_->InitMenu(params_); +- observers_.AddObserver(spelling_options_submenu_observer_.get()); + #endif + } + +--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h ++++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h +@@ -41,7 +41,6 @@ class Profile; + class QuickAnswersMenuObserver; + class SharedClipboardContextMenuObserver; + class SpellingMenuObserver; +-class SpellingOptionsSubMenuObserver; + + namespace content { + class RenderFrameHost; +@@ -272,13 +271,6 @@ class RenderViewContextMenu : public Ren + accessibility_labels_menu_observer_; + ui::SimpleMenuModel accessibility_labels_submenu_model_; + +-#if !defined(OS_MAC) +- // An observer that handles the submenu for showing spelling options. This +- // submenu lets users select the spelling language, for example. +- std::unique_ptr +- spelling_options_submenu_observer_; +-#endif +- + #if defined(OS_CHROMEOS) + // An observer that handles "Open with " items. + std::unique_ptr open_with_menu_observer_; +--- a/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc ++++ b/chrome/browser/ui/views/status_icons/status_icon_button_linux.cc +@@ -74,12 +74,6 @@ void StatusIconButtonLinux::OnSetDelegat + + auto* window = widget_->GetNativeWindow(); + DCHECK(window); +- host_ = window->GetHost(); +- if (host_->GetAcceleratedWidget() == gfx::kNullAcceleratedWidget) { +- delegate_->OnImplInitializationFailed(); +- // |this| might be destroyed. +- return; +- } + + widget_->SetContentsView(this); + set_owned_by_client(); +@@ -110,20 +104,12 @@ void StatusIconButtonLinux::PaintButtonC + gfx::ScopedCanvas scoped_canvas(canvas); + canvas->UndoDeviceScaleFactor(); + +- gfx::Rect bounds = host_->GetBoundsInPixels(); + const gfx::ImageSkia& image = delegate_->GetImage(); + + // If the image fits in the window, center it. But if it won't fit, downscale + // it preserving aspect ratio. +- float scale = +- std::min({1.0f, static_cast(bounds.width()) / image.width(), +- static_cast(bounds.height()) / image.height()}); +- float x_offset = (bounds.width() - scale * image.width()) / 2.0f; +- float y_offset = (bounds.height() - scale * image.height()) / 2.0f; + + gfx::Transform transform; +- transform.Translate(x_offset, y_offset); +- transform.Scale(scale, scale); + canvas->Transform(transform); + + cc::PaintFlags flags; +--- a/base/process/kill.h ++++ b/base/process/kill.h +@@ -113,7 +113,7 @@ BASE_EXPORT TerminationStatus GetTermina + BASE_EXPORT TerminationStatus GetKnownDeadTerminationStatus( + ProcessHandle handle, int* exit_code); + +-#if defined(OS_LINUX) || defined(OS_CHROMEOS) ++#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + // Spawns a thread to wait asynchronously for the child |process| to exit + // and then reaps it. + BASE_EXPORT void EnsureProcessGetsReaped(Process process); +--- a/base/process/kill_posix.cc ++++ b/base/process/kill_posix.cc +@@ -160,7 +160,7 @@ void EnsureProcessTerminated(Process pro + 0, new BackgroundReaper(std::move(process), TimeDelta::FromSeconds(2))); + } + +-#if defined(OS_LINUX) || defined(OS_CHROMEOS) ++#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + void EnsureProcessGetsReaped(Process process) { + DCHECK(!process.is_current()); + +--- a/components/permissions/permission_request.cc ++++ b/components/permissions/permission_request.cc +@@ -18,7 +18,7 @@ ContentSettingsType PermissionRequest::G + return ContentSettingsType::DEFAULT; + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + base::Optional PermissionRequest::GetChipText() const { + return base::nullopt; + } +--- a/components/permissions/permission_request.h ++++ b/components/permissions/permission_request.h +@@ -59,7 +59,7 @@ class PermissionRequest { + virtual base::string16 GetQuietMessageText() const; + #endif + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Returns the short text for the chip button related to this permission. + virtual base::Optional GetChipText() const; + #endif +--- a/components/permissions/permission_request_impl.cc ++++ b/components/permissions/permission_request_impl.cc +@@ -252,7 +252,7 @@ base::string16 PermissionRequestImpl::Ge + return l10n_util::GetStringUTF16(message_id); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + base::Optional PermissionRequestImpl::GetChipText() const { + int message_id; + switch (content_settings_type_) { +--- a/components/permissions/permission_request_impl.h ++++ b/components/permissions/permission_request_impl.h +@@ -42,7 +42,7 @@ class PermissionRequestImpl : public Per + base::string16 GetQuietTitleText() const override; + base::string16 GetQuietMessageText() const override; + #endif +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + base::Optional GetChipText() const override; + #endif + base::string16 GetMessageTextFragment() const override; +--- a/chrome/browser/ui/views/location_bar/permission_chip.cc ++++ b/chrome/browser/ui/views/location_bar/permission_chip.cc +@@ -241,22 +241,6 @@ void PermissionChip::UpdatePermissionIco + views::style::STYLE_DIALOG_BUTTON_DEFAULT); + + chip_button_->SetEnabledTextColors(enabled_text_color); +- chip_button_->SetImageModel( +- views::Button::STATE_NORMAL, +- ui::ImageModel::FromVectorIcon(GetPermissionIconId(), enabled_text_color, +- GetIconSize())); +-} +- +-const gfx::VectorIcon& PermissionChip::GetPermissionIconId() { +- auto requests = delegate_->Requests(); +- if (requests.size() == 1) +- return requests[0]->GetIconId(); +- +- // When we have two requests, it must be microphone & camera. Then we need to +- // use the icon from the camera request. +- return IsCameraPermission(requests[0]->GetPermissionRequestType()) +- ? requests[0]->GetIconId() +- : requests[1]->GetIconId(); + } + + base::string16 PermissionChip::GetPermissionMessage() { +--- a/chrome/browser/ui/views/location_bar/permission_chip.h ++++ b/chrome/browser/ui/views/location_bar/permission_chip.h +@@ -66,7 +66,6 @@ class PermissionChip : public views::Vie + int GetIconSize() const; + void UpdatePermissionIconAndTextColor(); + base::string16 GetPermissionMessage(); +- const gfx::VectorIcon& GetPermissionIconId(); + + Browser* browser_ = nullptr; + permissions::PermissionPrompt::Delegate* delegate_ = nullptr; +--- a/chrome/browser/nearby_sharing/share_target.cc ++++ b/chrome/browser/nearby_sharing/share_target.cc +@@ -6,8 +6,6 @@ + + #include + +-ShareTarget::ShareTarget() = default; +- + ShareTarget::ShareTarget(std::string device_name, + GURL image_url, + nearby_share::mojom::ShareTargetType type, +@@ -35,8 +33,6 @@ ShareTarget& ShareTarget::operator=(cons + + ShareTarget& ShareTarget::operator=(ShareTarget&&) = default; + +-ShareTarget::~ShareTarget() = default; +- + std::vector ShareTarget::GetAttachmentIds() const { + std::vector attachment_ids; + +--- a/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc ++++ b/chrome/browser/policy/chrome_browser_cloud_management_controller_desktop.cc +@@ -43,7 +43,7 @@ + #include "chrome/browser/policy/browser_dm_token_storage_mac.h" + #endif // defined(OS_MAC) + +-#if defined(OS_LINUX) || defined(OS_CHROMEOS) ++#if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) + #include "chrome/browser/policy/browser_dm_token_storage_linux.h" + #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) + +@@ -176,10 +176,12 @@ void ChromeBrowserCloudManagementControl + + #if defined(OS_MAC) + storage_delegate = std::make_unique(); +-#elif defined(OS_LINUX) || defined(OS_CHROMEOS) ++#elif defined(OS_CHROMEOS) + storage_delegate = std::make_unique(); + #elif defined(OS_WIN) + storage_delegate = std::make_unique(); ++#elif defined(OS_ANDROID) ++ storage_delegate = std::make_unique(); + #else + NOT_REACHED(); + #endif +--- a/ui/views/bubble/bubble_dialog_delegate_view.cc ++++ b/ui/views/bubble/bubble_dialog_delegate_view.cc +@@ -185,7 +185,7 @@ class BubbleDialogDelegate::AnchorViewOb + + // This class is responsible for observing events on a BubbleDialogDelegate's + // anchor widget and notifying the BubbleDialogDelegate of them. +-#if defined(OS_APPLE) ++#if defined(OS_APPLE) || defined(OS_ANDROID) + class BubbleDialogDelegate::AnchorWidgetObserver : public WidgetObserver { + #else + class BubbleDialogDelegate::AnchorWidgetObserver : public WidgetObserver, +@@ -196,7 +196,7 @@ class BubbleDialogDelegate::AnchorWidget + AnchorWidgetObserver(BubbleDialogDelegate* owner, Widget* widget) + : owner_(owner) { + widget_observer_.Add(widget); +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + window_observer_.Add(widget->GetNativeWindow()); + #endif + } +@@ -204,7 +204,7 @@ class BubbleDialogDelegate::AnchorWidget + + // WidgetObserver: + void OnWidgetDestroying(Widget* widget) override { +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + window_observer_.Remove(widget->GetNativeWindow()); + #endif + widget_observer_.Remove(widget); +@@ -220,7 +220,7 @@ class BubbleDialogDelegate::AnchorWidget + owner_->OnAnchorBoundsChanged(); + } + +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + // aura::WindowObserver: + void OnWindowTransformed(aura::Window* window, + ui::PropertyChangeReason reason) override { +@@ -239,7 +239,7 @@ class BubbleDialogDelegate::AnchorWidget + private: + BubbleDialogDelegate* owner_; + ScopedObserver widget_observer_{this}; +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + ScopedObserver window_observer_{this}; + #endif + }; +@@ -556,7 +556,7 @@ gfx::Rect BubbleDialogDelegate::GetAncho + anchor_rect_ = GetAnchorView()->GetAnchorBoundsInScreen(); + anchor_rect_->Inset(anchor_view_insets_); + +-#if !defined(OS_APPLE) ++#if !defined(OS_APPLE) && !defined(OS_ANDROID) + // GetAnchorBoundsInScreen returns values that take anchor widget's + // translation into account, so undo that here. Without this, features which + // apply transforms on windows such as ChromeOS overview mode will see bubbles +--- a/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java ++++ b/components/payments/content/android/java/src/org/chromium/components/payments/MojoPaymentRequestGateKeeper.java +@@ -54,7 +54,7 @@ import org.chromium.payments.mojom.Payme + // Implement PaymentRequest: + @Override + public void init(PaymentRequestClient client, PaymentMethodData[] methodData, +- PaymentDetails details, PaymentOptions options, boolean googlePayBridgeEligible) { ++ PaymentDetails details, PaymentOptions options) { + if (mPaymentRequestService != null) { + mPaymentRequestService.abortForInvalidDataFromRenderer( + ErrorStrings.ATTEMPTED_INITIALIZATION_TWICE); +@@ -65,7 +65,7 @@ import org.chromium.payments.mojom.Payme + // Note that a null value would be assigned when the params are invalid. + mPaymentRequestService = + mPaymentRequestServiceCreator.createPaymentRequestServiceIfParamsValid(client, +- methodData, details, options, googlePayBridgeEligible, ++ methodData, details, options, false, + this::onPaymentRequestServiceClosed); + } + +--- a/chrome/browser/extensions/extension_management.cc ++++ b/chrome/browser/extensions/extension_management.cc +@@ -77,7 +77,7 @@ ExtensionManagement::ExtensionManagement + pref_change_callback); + pref_change_registrar_.Add(prefs::kCloudExtensionRequestEnabled, + pref_change_callback); +-#if !defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) + pref_change_registrar_.Add(enterprise_reporting::kCloudReportingEnabled, + pref_change_callback); + #endif +--- a/chrome/browser/enterprise/reporting/prefs.cc ++++ b/chrome/browser/enterprise/reporting/prefs.cc +@@ -19,7 +19,6 @@ const char kLastUploadVersion[] = "enter + void RegisterLocalStatePrefs(PrefRegistrySimple* registry) { + // This is also registered as a Profile pref which will be removed after + // the migration. +- registry->RegisterBooleanPref(kCloudReportingEnabled, false); + registry->RegisterTimePref(kLastUploadTimestamp, base::Time()); + #if !defined(OS_CHROMEOS) + registry->RegisterStringPref(kLastUploadVersion, std::string()); +--- a/chrome/browser/nearby_sharing/nearby_notification_manager.cc ++++ b/chrome/browser/nearby_sharing/nearby_notification_manager.cc +@@ -55,7 +55,6 @@ message_center::Notification CreateNearb + kNearbyNotifier), + /*optional_fields=*/{}, + /*delegate=*/nullptr); +- notification.set_vector_small_image(kNearbyShareIcon); + + // TODO(crbug.com/1102348): Also show settings for other platforms once there + // is a nearby settings page in Chrome browser. +--- a/chrome/browser/ui/views/payments/secure_payment_confirmation_view.cc ++++ b/chrome/browser/ui/views/payments/secure_payment_confirmation_view.cc +@@ -8,14 +8,6 @@ + + namespace payments { + +-// static +-base::WeakPtr +-SecurePaymentConfirmationView::Create() { +- return (new SecurePaymentConfirmationDialogView( +- /*observer_for_test=*/nullptr)) +- ->GetWeakPtr(); +-} +- + SecurePaymentConfirmationView::SecurePaymentConfirmationView() = default; + SecurePaymentConfirmationView::~SecurePaymentConfirmationView() = default; + +--- a/chrome/browser/ui/views/hats/hats_bubble_view.cc ++++ b/chrome/browser/ui/views/hats/hats_bubble_view.cc +@@ -74,14 +74,7 @@ void HatsBubbleView::ShowOnContentReady( + // The bubble will only show after the survey content is retrieved. + // If it fails due to no internet connection or any other reason, the bubble + // will not show. +- if (base::FeatureList::IsEnabled( +- features::kHappinessTrackingSurveysForDesktopMigration)) { +- // Self deleting on close. +- new HatsNextWebDialog(browser, site_id, std::move(success_callback), +- std::move(failure_callback)); +- } else { +- HatsWebDialog::Create(browser, site_id); +- } ++ HatsWebDialog::Create(browser, site_id); + } + + void HatsBubbleView::Show(Browser* browser, +--- a/chrome/browser/ui/views/hats/hats_next_web_dialog.cc ++++ b/chrome/browser/ui/views/hats/hats_next_web_dialog.cc +@@ -185,9 +185,6 @@ HatsNextWebDialog::~HatsNextWebDialog() + otr_profile_->RemoveObserver(this); + ProfileDestroyer::DestroyProfileWhenAppropriate(otr_profile_); + } +- auto* service = HatsServiceFactory::GetForProfile(browser_->profile(), false); +- DCHECK(service); +- service->HatsNextDialogClosed(); + + // Explicitly clear the delegate to ensure it is not invalid between now and + // when the web contents is destroyed in the base class. +@@ -197,10 +194,6 @@ HatsNextWebDialog::~HatsNextWebDialog() + GURL HatsNextWebDialog::GetParameterizedHatsURL() const { + GURL param_url = + net::AppendQueryParameter(hats_survey_url_, "trigger_id", trigger_id_); +- if (base::FeatureList::IsEnabled( +- features::kHappinessTrackingSurveysForDesktopDemo)) { +- param_url = net::AppendQueryParameter(param_url, "enable_testing", "true"); +- } + return param_url; + } + +@@ -217,10 +210,6 @@ void HatsNextWebDialog::OnSurveyStateUpd + + if (state == "loaded") { + // Record that the survey was shown, and display the widget. +- auto* service = +- HatsServiceFactory::GetForProfile(browser_->profile(), false); +- DCHECK(service); +- service->RecordSurveyAsShown(trigger_id_); + received_survey_loaded_ = true; + ShowWidget(); + std::move(success_callback_).Run(); +--- a/components/media_router/browser/android/media_router_android.h ++++ b/components/media_router/browser/android/media_router_android.h +@@ -14,6 +14,7 @@ + #include "base/macros.h" + #include "base/observer_list.h" + #include "components/media_router/browser/android/media_router_android_bridge.h" ++#include "components/media_router/browser/logger_impl.h" + #include "components/media_router/browser/media_router_base.h" + #include "mojo/public/cpp/bindings/pending_remote.h" + #include "mojo/public/cpp/bindings/receiver.h" +@@ -88,6 +89,9 @@ class MediaRouterAndroid : public MediaR + // Notifies the media router about a message received from the media route. + void OnMessage(const MediaRoute::Id& route_id, const std::string& message); + ++ protected: ++ LoggerImpl* GetLogger() override; ++ + private: + friend class MediaRouterAndroidTest; + +@@ -183,6 +187,8 @@ class MediaRouterAndroid : public MediaR + std::vector>> + presentation_connections_; + ++ LoggerImpl logger_; ++ + DISALLOW_COPY_AND_ASSIGN(MediaRouterAndroid); + }; + +--- a/components/media_router/browser/media_router.h ++++ b/components/media_router/browser/media_router.h +@@ -27,12 +27,10 @@ + #include "media/base/flinging_controller.h" + #include "third_party/blink/public/mojom/presentation/presentation.mojom.h" + +-#if !defined(OS_ANDROID) + #include "components/media_router/browser/logger_impl.h" + #include "components/media_router/common/mojom/media_controller.mojom.h" + #include "mojo/public/cpp/bindings/pending_receiver.h" + #include "mojo/public/cpp/bindings/pending_remote.h" +-#endif // !defined(OS_ANDROID) + + namespace content { + class WebContents; +@@ -183,7 +181,6 @@ class MediaRouter : public KeyedService + virtual std::unique_ptr GetFlingingController( + const MediaRoute::Id& route_id) = 0; + +-#if !defined(OS_ANDROID) + // Binds |controller| for sending media commands to a route. The controller + // will notify |observer| whenever there is a change to the status of the + // media. It may invalidate bindings from previous calls to this method. +@@ -197,7 +194,6 @@ class MediaRouter : public KeyedService + + // Returns logs collected from Media Router components. + virtual base::Value GetLogs() const = 0; +-#endif // !defined(OS_ANDROID) + + // Returns media router state as a JSON string represented by base::Value. + // Includes known sinks and sink compatibility with media sources. +--- a/components/media_router/browser/media_router_base.cc ++++ b/components/media_router/browser/media_router_base.cc +@@ -87,7 +87,6 @@ MediaRouterBase::GetFlingingController(c + return nullptr; + } + +-#if !defined(OS_ANDROID) + void MediaRouterBase::GetMediaController( + const MediaRoute::Id& route_id, + mojo::PendingReceiver controller, +@@ -96,7 +95,6 @@ void MediaRouterBase::GetMediaController + base::Value MediaRouterBase::GetLogs() const { + return base::Value(); + } +-#endif // !defined(OS_ANDROID) + + MediaRouterBase::MediaRouterBase() : initialized_(false) {} + +--- a/components/media_router/browser/media_router_base.h ++++ b/components/media_router/browser/media_router_base.h +@@ -19,11 +19,9 @@ + #include "components/media_router/common/media_route.h" + #include "third_party/blink/public/mojom/presentation/presentation.mojom.h" + +-#if !defined(OS_ANDROID) + #include "components/media_router/common/mojom/media_controller.mojom.h" + #include "mojo/public/cpp/bindings/pending_receiver.h" + #include "mojo/public/cpp/bindings/pending_remote.h" +-#endif // !defined(OS_ANDROID) + + namespace media_router { + +@@ -45,13 +43,11 @@ class MediaRouterBase : public MediaRout + std::vector GetCurrentRoutes() const override; + std::unique_ptr GetFlingingController( + const MediaRoute::Id& route_id) override; +-#if !defined(OS_ANDROID) + void GetMediaController( + const MediaRoute::Id& route_id, + mojo::PendingReceiver controller, + mojo::PendingRemote observer) override; + base::Value GetLogs() const override; +-#endif // !defined(OS_ANDROID) + base::Value GetState() const override; + void GetProviderState( + MediaRouteProviderId provider_id, +--- a/chrome/browser/ui/browser_list_observer.h ++++ b/chrome/browser/ui/browser_list_observer.h +@@ -7,10 +7,6 @@ + + #include "build/build_config.h" + +-#if defined(OS_ANDROID) +-#error This file should only be included on desktop. +-#endif +- + class Browser; + + class BrowserListObserver { +--- a/chrome/browser/ui/browser_list.h ++++ b/chrome/browser/ui/browser_list.h +@@ -16,10 +16,6 @@ + #include "base/observer_list.h" + #include "build/build_config.h" + +-#if defined(OS_ANDROID) +-#error This file should only be included on desktop. +-#endif +- + class Browser; + class Profile; + +--- a/components/media_router/browser/android/media_router_android.cc ++++ b/components/media_router/browser/android/media_router_android.cc +@@ -345,6 +345,10 @@ void MediaRouterAndroid::RemoveRoute(con + observer.OnRoutesUpdated(active_routes_, std::vector()); + } + ++LoggerImpl* MediaRouterAndroid::GetLogger() { ++ return &logger_; ++} ++ + std::unique_ptr + MediaRouterAndroid::GetFlingingController(const MediaRoute::Id& route_id) { + return bridge_->GetFlingingController(route_id); +--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc ++++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_bubble_view.cc +@@ -232,10 +232,6 @@ void PermissionPromptBubbleView::AddPerm + provider->GetDistanceMetric(views::DISTANCE_RELATED_LABEL_HORIZONTAL))); + + constexpr int kPermissionIconSize = 18; +- auto* icon = line_container->AddChildView( +- std::make_unique(request->GetIconId(), +- kPermissionIconSize)); +- icon->SetVerticalAlignment(views::ImageView::Alignment::kLeading); + + auto* label = line_container->AddChildView( + std::make_unique(request->GetMessageTextFragment())); +--- a/chrome/browser/flag_descriptions.cc ++++ b/chrome/browser/flag_descriptions.cc +@@ -3250,7 +3250,6 @@ const char kWalletRequiresFirstSyncSetup + + // Non-Android ----------------------------------------------------------------- + +-#else // !defined(OS_ANDROID) + + extern const char kAllowAllSitesToInitiateMirroringName[] = + "Allow all sites to initiate mirroring"; +--- a/chrome/browser/flag_descriptions.h ++++ b/chrome/browser/flag_descriptions.h +@@ -1876,7 +1876,6 @@ extern const char kWalletRequiresFirstSy + + // Non-Android ---------------------------------------------------------------- + +-#else // !defined(OS_ANDROID) + + extern const char kAllowAllSitesToInitiateMirroringName[]; + extern const char kAllowAllSitesToInitiateMirroringDescription[]; +--- a/chrome/browser/intranet_redirect_detector.h ++++ b/chrome/browser/intranet_redirect_detector.h +@@ -27,11 +27,6 @@ class SimpleURLLoader; + + class PrefRegistrySimple; + +-#if !(defined(OS_MAC) || defined(OS_WIN) || defined(OS_LINUX) || \ +- defined(OS_CHROMEOS)) +-#error "IntranetRedirectDetector should only be built on Desktop platforms." +-#endif +- + // This object is responsible for determining whether the user is on a network + // that redirects requests for intranet hostnames to another site, and if so, + // tracking what that site is (including across restarts via a pref). For +--- a/chrome/browser/profiles/profile_attributes_storage.cc ++++ b/chrome/browser/profiles/profile_attributes_storage.cc +@@ -31,7 +31,7 @@ + #include "ui/base/l10n/l10n_util.h" + #include "ui/gfx/image/image.h" + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + #include "chrome/browser/ui/browser_list.h" + #endif + +@@ -390,7 +390,7 @@ void ProfileAttributesStorage::RemoveObs + observer_list_.RemoveObserver(obs); + } + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + void ProfileAttributesStorage::RecordDeletedProfileState( + ProfileAttributesEntry* entry) { + DCHECK(entry); +--- a/chrome/browser/profiles/profile_attributes_storage.h ++++ b/chrome/browser/profiles/profile_attributes_storage.h +@@ -97,7 +97,7 @@ class ProfileAttributesStorage + bool IsDefaultProfileName(const base::string16& name, + bool include_check_for_legacy_profile_name) const; + +-#if !defined(OS_ANDROID) ++#if defined(OS_ANDROID) + // Records statistics about a profile `entry` that is being deleted. If the + // profile has opened browser window(s) in the moment of deletion, this + // function must be called before these windows get closed. +--- a/chrome/browser/ui/browser.cc ++++ b/chrome/browser/ui/browser.cc +@@ -32,6 +32,7 @@ + #include "base/time/time.h" + #include "build/build_config.h" + #include "chrome/app/chrome_command_ids.h" ++#include "chrome/browser/android/tab_android.h" + #include "chrome/browser/app_mode/app_mode_utils.h" + #include "chrome/browser/autofill/personal_data_manager_factory.h" + #include "chrome/browser/background/background_contents.h" +@@ -128,7 +129,6 @@ + #include "chrome/browser/ui/sync/browser_synced_window_delegate.h" + #include "chrome/browser/ui/tab_contents/core_tab_helper.h" + #include "chrome/browser/ui/tab_dialogs.h" +-#include "chrome/browser/ui/tab_helpers.h" + #include "chrome/browser/ui/tab_modal_confirm_dialog.h" + #include "chrome/browser/ui/tabs/tab_group.h" + #include "chrome/browser/ui/tabs/tab_group_model.h" +@@ -1830,7 +1830,7 @@ void Browser::WebContentsCreated(WebCont + // requests for its initial navigation will start immediately. The WebContents + // will later be inserted into this browser using Browser::Navigate via + // AddNewContents. +- TabHelpers::AttachTabHelpers(new_contents); ++ TabAndroid::AttachTabHelpers(new_contents); + + // Make the tab show up in the task manager. + task_manager::WebContentsTags::CreateForTabContents(new_contents); +@@ -1840,7 +1840,7 @@ void Browser::PortalWebContentsCreated(W + ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial("PortalsActive", + "Enabled"); + +- TabHelpers::AttachTabHelpers(portal_web_contents); ++ TabAndroid::AttachTabHelpers(portal_web_contents); + + // Make the portal show up in the task manager. + task_manager::WebContentsTags::CreateForPortal(portal_web_contents); +--- a/chrome/browser/ui/browser_tab_strip_model_delegate.cc ++++ b/chrome/browser/ui/browser_tab_strip_model_delegate.cc +@@ -8,6 +8,7 @@ + + #include "base/bind.h" + #include "base/command_line.h" ++#include "chrome/browser/android/tab_android.h" + #include "chrome/browser/profiles/profile.h" + #include "chrome/browser/sessions/tab_restore_service_factory.h" + #include "chrome/browser/task_manager/web_contents_tags.h" +@@ -15,7 +16,6 @@ + #include "chrome/browser/ui/browser_commands.h" + #include "chrome/browser/ui/browser_tabstrip.h" + #include "chrome/browser/ui/browser_window.h" +-#include "chrome/browser/ui/tab_helpers.h" + #include "chrome/browser/ui/tabs/tab_group.h" + #include "chrome/browser/ui/tabs/tab_group_model.h" + #include "chrome/browser/ui/tabs/tab_strip_model.h" +@@ -87,7 +87,7 @@ Browser* BrowserTabStripModelDelegate::C + + void BrowserTabStripModelDelegate::WillAddWebContents( + content::WebContents* contents) { +- TabHelpers::AttachTabHelpers(contents); ++ TabAndroid::AttachTabHelpers(contents); + + // Make the tab show up in the task manager. + task_manager::WebContentsTags::CreateForTabContents(contents); +--- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc ++++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc +@@ -7,7 +7,6 @@ + #include "base/bind.h" + #include "chrome/browser/autocomplete/shortcuts_backend_factory.h" + #include "chrome/browser/infobars/infobar_service.h" +-#include "chrome/browser/intranet_redirect_detector.h" + #include "chrome/browser/search_engines/template_url_service_factory.h" + #include "chrome/browser/ui/omnibox/alternate_nav_infobar_delegate.h" + #include "components/omnibox/browser/shortcuts_backend.h" +@@ -46,14 +45,7 @@ bool ResponseCodeIndicatesSuccess(int re + // Returns true if |final_url| doesn't represent an ISP hijack of + // |original_url|, based on the IntranetRedirectDetector's RedirectOrigin(). + bool IsValidNavigation(const GURL& original_url, const GURL& final_url) { +- const GURL& redirect_url(IntranetRedirectDetector::RedirectOrigin()); +- return !redirect_url.is_valid() || +- net::registry_controlled_domains::SameDomainOrHost( +- original_url, final_url, +- net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES) || +- !net::registry_controlled_domains::SameDomainOrHost( +- final_url, redirect_url, +- net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); ++ return true; + } + + // Returns true if |origin| is a http URL and |destination| is a https URL and +--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ChromePaymentRequestService.java +@@ -154,8 +154,7 @@ public class ChromePaymentRequestService + @Override + public void onWhetherGooglePayBridgeEligible(boolean googlePayBridgeEligible, + WebContents webContents, PaymentMethodData[] rawMethodData) { +- mIsGooglePayBridgeActivated = googlePayBridgeEligible +- && SkipToGPayHelperUtil.canActivateExperiment(mWebContents, rawMethodData); ++ mIsGooglePayBridgeActivated = false; + } + + // Implements BrowserPaymentRequest: +@@ -207,8 +206,6 @@ public class ChromePaymentRequestService + assert details != null; + + if (mIsGooglePayBridgeActivated) { +- PaymentMethodData data = methodData.get(MethodStrings.GOOGLE_PAY); +- mSkipToGPayHelper = new SkipToGPayHelper(options, data.gpayBridgeData); + } + + if (!parseAndValidateDetailsFurtherIfNeeded(details)) { +@@ -438,11 +435,6 @@ public class ChromePaymentRequestService + // If skip-to-GPay flow is activated, ignore all other payment methods, which can be + // either "basic-card" or "https://android.com/pay". The latter is safe to ignore + // because merchant has already requested Google Pay. +- if (!method.equals(MethodStrings.GOOGLE_PAY)) continue; +- if (methodData.gpayBridgeData != null +- && !methodData.gpayBridgeData.stringifiedData.isEmpty()) { +- methodData.stringifiedData = methodData.gpayBridgeData.stringifiedData; +- } + result.put(method, methodData); + } + methodDataMap.clear(); +--- a/chrome/browser/web_applications/extensions/bookmark_app_provider.cc ++++ b/chrome/browser/web_applications/extensions/bookmark_app_provider.cc +@@ -47,8 +47,9 @@ WebAppProvider::CreateBookmarkAppInstall + } + + void WebAppProviderFactory::DependsOnExtensionsSystem() { +- DependsOn( +- extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); ++ if (extensions::ExtensionsBrowserClient::Get()) ++ DependsOn( ++ extensions::ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); + } + + } // namespace web_app +--- a/components/enterprise/browser/enterprise_switches.cc ++++ b/components/enterprise/browser/enterprise_switches.cc +@@ -8,7 +8,7 @@ + + namespace switches { + +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + // Enables the Chrome Browser Cloud Management integration on Chromium builds. + // CBCM is always enabled in branded builds. + const char kEnableChromeBrowserCloudManagement[] = +--- a/components/enterprise/browser/enterprise_switches.h ++++ b/components/enterprise/browser/enterprise_switches.h +@@ -12,7 +12,7 @@ + + namespace switches { + +-#if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) ++#if !defined(OS_CHROMEOS) && defined(OS_ANDROID) + extern const char kEnableChromeBrowserCloudManagement[]; + #endif + +--- a/content/browser/tracing/generate_trace_viewer_grd.py ++++ b/content/browser/tracing/generate_trace_viewer_grd.py +@@ -26,7 +26,7 @@ kGrdTemplate = ''' + + +- ++ + + + +--- a/content/browser/media/session/audio_focus_delegate_default.cc ++++ b/content/browser/media/session/audio_focus_delegate_default.cc +@@ -189,11 +189,4 @@ void AudioFocusDelegateDefault::EnsureSe + audio_focus_->SetSource(media_session_->GetSourceId(), kAudioFocusSourceName); + } + +-// static +-std::unique_ptr AudioFocusDelegate::Create( +- MediaSessionImpl* media_session) { +- return std::unique_ptr( +- new AudioFocusDelegateDefault(media_session)); +-} +- + } // namespace content +--- a/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc ++++ b/chrome/browser/enterprise/reporting/report_scheduler_desktop.cc +@@ -28,7 +28,7 @@ constexpr int kThrottleTimeInMinute = 1; + // TODO(crbug.com/1102047): Get rid of this function after Chrome OS reporting + // logic has been split to its own delegates. + constexpr bool ShouldReportUpdates() { +-#if defined(OS_CHROMEOS) ++#if !defined(OS_CHROMEOS) + return false; + #else + return true; +@@ -36,8 +36,7 @@ constexpr bool ShouldReportUpdates() { + } + + bool ShouldReportExtensionRequestRealtime() { +- return base::FeatureList::IsEnabled( +- features::kEnterpriseRealtimeExtensionRequest); ++ return false; + } + + } // namespace +--- a/chrome/browser/password_manager/multi_profile_credentials_filter.cc ++++ b/chrome/browser/password_manager/multi_profile_credentials_filter.cc +@@ -28,8 +28,7 @@ bool MultiProfileCredentialsFilter::Shou + return true; // This happens in incognito. + if (!password_manager::sync_util::IsGaiaCredentialPage(form.signon_realm)) + return true; +- if (!base::FeatureList::IsEnabled(kDiceWebSigninInterceptionFeature)) +- return true; ++ return true; + + // Note: this function is only called for "Save" bubbles, but not for "Update" + // bubbles. +--- a/chrome/browser/devtools/devtools_ui_bindings.cc ++++ b/chrome/browser/devtools/devtools_ui_bindings.cc +@@ -1539,21 +1539,10 @@ void ShowSurveyCallback(const DevToolsUI + + void DevToolsUIBindings::ShowSurvey(const DispatchCallback& callback, + const std::string& trigger) { +- HatsService* hats_service = +- HatsServiceFactory::GetForProfile(profile_->GetOriginalProfile(), true); +- hats_service->LaunchSurvey( +- trigger, base::BindOnce(ShowSurveyCallback, callback, true), +- base::BindOnce(ShowSurveyCallback, callback, false)); + } + + void DevToolsUIBindings::CanShowSurvey(const DispatchCallback& callback, + const std::string& trigger) { +- HatsService* hats_service = +- HatsServiceFactory::GetForProfile(profile_->GetOriginalProfile(), true); +- bool can_show = hats_service->CanShowSurvey(trigger); +- base::DictionaryValue response; +- response.SetBoolean("canShowSurvey", can_show); +- callback.Run(&response); + } + + void DevToolsUIBindings::SetDelegate(Delegate* delegate) { +--- a/chrome/browser/ui/views/profiles/profile_picker_view.cc ++++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc +@@ -405,19 +405,6 @@ void ProfilePickerView::OnRefreshTokenUp + weak_ptr_factory_.GetWeakPtr(), account_info.email), + extended_account_info_timeout_); + +- // DiceTurnSyncOnHelper deletes itself once done. +- new DiceTurnSyncOnHelper( +- signed_in_profile_being_created_, +- signin_metrics::AccessPoint::ACCESS_POINT_USER_MANAGER, +- signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO, +- signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, +- account_info.account_id, +- DiceTurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT, +- std::make_unique( +- signed_in_profile_being_created_, +- base::BindOnce(&ProfilePickerView::FinishSignedInCreationFlow, +- weak_ptr_factory_.GetWeakPtr())), +- std::move(sync_consent_completed_closure)); + } + + void ProfilePickerView::OnExtendedAccountInfoUpdated( +--- a/chrome/browser/ui/views/profiles/profile_picker_view_sync_delegate.cc ++++ b/chrome/browser/ui/views/profiles/profile_picker_view_sync_delegate.cc +@@ -41,16 +41,6 @@ ProfilePickerViewSyncDelegate::~ProfileP + void ProfilePickerViewSyncDelegate::ShowLoginError( + const std::string& email, + const std::string& error_message) { +- // Open the browser and when it's done, show the login error. +- // TODO(crbug.com/1126913): In some cases, the current behavior is not ideal +- // because it is not designed with profile creation in mind. Concretely, for +- // sync not being available because there already is a syncing profile with +- // this account, we should likely auto-delete the profile and offer to either +- // switch or to start sign-in once again. +- std::move(open_browser_callback_) +- .Run(base::BindOnce( +- &DiceTurnSyncOnHelper::Delegate::ShowLoginErrorForBrowser, email, +- error_message)); + } + + void ProfilePickerViewSyncDelegate::ShowMergeSyncDataConfirmation( +@@ -65,11 +55,6 @@ void ProfilePickerViewSyncDelegate::Show + const std::string& email, + DiceTurnSyncOnHelper::SigninChoiceCallback callback) { + enterprise_confirmation_shown_ = true; +- // Open the browser and when it's done, show the confirmation dialog. +- std::move(open_browser_callback_) +- .Run(base::BindOnce(&DiceTurnSyncOnHelper::Delegate:: +- ShowEnterpriseAccountConfirmationForBrowser, +- email, std::move(callback))); + } + + void ProfilePickerViewSyncDelegate::ShowSyncConfirmation( +--- a/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java ++++ b/components/payments/content/android/java/src/org/chromium/components/payments/InvalidPaymentRequest.java +@@ -24,8 +24,7 @@ public final class InvalidPaymentRequest + + @Override + public void init(PaymentRequestClient client, PaymentMethodData[] unusedMethodData, +- PaymentDetails unusedDetails, PaymentOptions unusedOptions, +- boolean unusedGooglePayBridgeEligible) { ++ PaymentDetails unusedDetails, PaymentOptions unusedOptions) { + mClient = client; + } + diff --git a/patches/Extensions/crx-download-install-prompt.patch b/patches/Extensions/crx-download-install-prompt.patch new file mode 100644 index 0000000..27c4571 --- /dev/null +++ b/patches/Extensions/crx-download-install-prompt.patch @@ -0,0 +1,1228 @@ +From: Wengling Chen +Date: Mon, 13 Jul 2020 23:37:25 -0400 +Subject: add download prompt for installing extensions + + +--- + base/android/java/src/org/chromium/base/ContentUriUtils.java | 1 + base/files/file_util.cc | 9 + base/files/file_util_posix.cc | 2 + chrome/android/BUILD.gn | 1 + chrome/android/chrome_java_resources.gni | 1 + chrome/android/chrome_java_sources.gni | 2 + chrome/android/java/res/layout/extension_install_dialog.xml | 117 ++++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionInstallCustomScrollView.java | 144 +++++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java | 170 ++++++ + chrome/browser/download/download_crx_util.cc | 16 + chrome/browser/extensions/crx_installer.cc | 1 + chrome/browser/extensions/unpacked_installer.cc | 17 + chrome/browser/ui/BUILD.gn | 4 + chrome/browser/ui/android/strings/android_chrome_strings.grd | 5 + chrome/browser/ui/extensions/extension_install_ui_default.cc | 12 + chrome/browser/ui/views/extensions/extension_install_dialog_view.cc | 2 + chrome/browser/ui/views/extensions/extension_install_dialog_view_android.cc | 278 ++++++++++ + chrome/browser/ui/views/extensions/extension_install_dialog_view_android.h | 103 +++ + components/crx_file/crx_verifier.cc | 12 + extensions/browser/sandboxed_unpacker.cc | 3 + extensions/common/file_util.cc | 9 + extensions/common/manifest_handlers/default_locale_handler.cc | 7 + 22 files changed, 881 insertions(+), 35 deletions(-) + +--- a/base/files/file_util_posix.cc ++++ b/base/files/file_util_posix.cc +@@ -358,7 +358,7 @@ FilePath MakeAbsoluteFilePath(const File + ScopedBlockingCall scoped_blocking_call(FROM_HERE, BlockingType::MAY_BLOCK); + char full_path[PATH_MAX]; + if (realpath(input.value().c_str(), full_path) == nullptr) +- return FilePath(); ++ return FilePath();\ + return FilePath(full_path); + } + +--- a/chrome/browser/extensions/unpacked_installer.cc ++++ b/chrome/browser/extensions/unpacked_installer.cc +@@ -62,12 +62,19 @@ const char kImportNotSharedModule[] = "' + void MaybeCleanupMetadataFolder(const base::FilePath& extension_path) { + const std::vector reserved_filepaths = + file_util::GetReservedMetadataFilePaths(extension_path); +- for (const auto& file : reserved_filepaths) +- base::DeletePathRecursively(file); ++ for (const auto& file : reserved_filepaths) { ++ LOG(INFO) << "unpacked_installer.cc: MaybeCleanupMetadataFolder: file: " << file; ++ LOG(INFO) << "unpacked_installer.cc: MaybeCleanupMetadataFolder: PathExists: " << (base::PathExists(file)); ++ if (base::PathExists(file)) ++ base::DeletePathRecursively(file); ++ } + + const base::FilePath& metadata_dir = extension_path.Append(kMetadataFolder); +- if (base::IsDirectoryEmpty(metadata_dir)) ++ if (base::PathExists(metadata_dir) && base::IsDirectoryEmpty(metadata_dir)) { ++ LOG(INFO) << "unpacked_installer.cc: MaybeCleanupMetadataFolder: metadata_dir: " << metadata_dir; ++ LOG(INFO) << "unpacked_installer.cc: MaybeCleanupMetadataFolder: PathExists(metadata_dir): " << (base::PathExists(metadata_dir)); + base::DeletePathRecursively(metadata_dir); ++ } + } + + } // namespace +@@ -92,6 +99,7 @@ UnpackedInstaller::~UnpackedInstaller() + } + + void UnpackedInstaller::Load(const base::FilePath& path_in) { ++ LOG(INFO) << "unpacked_installer.cc: Load: path_in: " << path_in; + DCHECK(extension_path_.empty()); + extension_path_ = path_in; + GetExtensionFileTaskRunner()->PostTask( +@@ -245,6 +253,7 @@ bool UnpackedInstaller::LoadExtension(Ma + // warnings/errors and ensures we don't treat a user provided file as one by + // the Extension system. + MaybeCleanupMetadataFolder(extension_path_); ++ LOG(INFO) << "unpacked_installer.cc: LoadExtension: extension_path_: " << extension_path_; + + // Treat presence of illegal filenames as a hard error for unpacked + // extensions. Don't do so for command line extensions since this breaks +@@ -295,7 +304,7 @@ bool UnpackedInstaller::IsLoadingUnpacke + } + + void UnpackedInstaller::GetAbsolutePath() { +- extension_path_ = base::MakeAbsoluteFilePath(extension_path_); ++ //extension_path_ = base::MakeAbsoluteFilePath(extension_path_); + + // Set priority explicitly to avoid unwanted task priority inheritance. + content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING}) +--- a/extensions/common/file_util.cc ++++ b/extensions/common/file_util.cc +@@ -239,8 +239,9 @@ scoped_refptr LoadExtension( + return nullptr; + + std::vector warnings; +- if (!ValidateExtension(extension.get(), error, &warnings)) ++ if (!ValidateExtension(extension.get(), error, &warnings)) { + return nullptr; ++ } + extension->AddInstallWarnings(std::move(warnings)); + + return extension; +@@ -257,7 +258,9 @@ std::unique_ptr L + const base::FilePath::CharType* manifest_filename, + std::string* error) { + base::FilePath manifest_path = extension_path.Append(manifest_filename); ++ LOG(INFO) << "file_util.cc: LoadManifest: manifest_path: " << manifest_path; + if (!base::PathExists(manifest_path)) { ++ LOG(INFO) << "file_util.cc: LoadManifest: !base::PathExists(manifest_path)"; + *error = l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_UNREADABLE); + return nullptr; + } +@@ -266,6 +269,7 @@ std::unique_ptr L + std::unique_ptr root(deserializer.Deserialize(nullptr, error)); + if (!root.get()) { + if (error->empty()) { ++ LOG(INFO) << "file_util.cc: LoadManifest: error->empty()"; + // If |error| is empty, then the file could not be read. + // It would be cleaner to have the JSON reader give a specific error + // in this case, but other code tests for a file error with +@@ -274,11 +278,13 @@ std::unique_ptr L + } else { + *error = base::StringPrintf( + "%s %s", manifest_errors::kManifestParseError, error->c_str()); ++ LOG(INFO) << "file_util.cc: LoadManifest: !error->empty(): error: " << *error; + } + return nullptr; + } + + if (!root->is_dict()) { ++ LOG(INFO) << "file_util.cc: LoadManifest: !root->is_dict()"; + *error = l10n_util::GetStringUTF8(IDS_EXTENSION_MANIFEST_INVALID); + return nullptr; + } +@@ -532,7 +538,6 @@ MessageBundle* LoadMessageBundle( + + base::FilePath default_locale_path = locale_path.AppendASCII(default_locale); + if (default_locale.empty() || +- chrome_locales.find(default_locale) == chrome_locales.end() || + !base::PathExists(default_locale_path)) { + *error = l10n_util::GetStringUTF8( + IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED); +--- a/base/files/file_util.cc ++++ b/base/files/file_util.cc +@@ -16,6 +16,7 @@ + #include "base/check_op.h" + #include "base/files/file_enumerator.h" + #include "base/files/file_path.h" ++#include "base/logging.h" + #include "base/posix/eintr_wrapper.h" + #include "base/strings/string_piece.h" + #include "base/strings/string_util.h" +@@ -223,11 +224,15 @@ bool ReadFileToStringWithMaxSize(const F + size_t max_size) { + if (contents) + contents->clear(); +- if (path.ReferencesParent()) ++ if (path.ReferencesParent()) { ++ LOG(INFO) << "base/files/file_util.cc: ReferencesParent"; + return false; ++ } + ScopedFILE file_stream(OpenFile(path, "rb")); +- if (!file_stream) ++ if (!file_stream) { ++ LOG(INFO) << "base/files/file_util.cc: !file_stream"; + return false; ++ } + return ReadStreamToStringWithMaxSize(file_stream.get(), max_size, contents); + } + +--- a/components/crx_file/crx_verifier.cc ++++ b/components/crx_file/crx_verifier.cc +@@ -10,11 +10,13 @@ + #include + #include + ++#include "base/android/content_uri_utils.h" + #include "base/base64.h" + #include "base/bind.h" + #include "base/callback.h" + #include "base/files/file.h" + #include "base/files/file_path.h" ++#include "base/logging.h" + #include "base/stl_util.h" + #include "base/strings/string_number_conversions.h" + #include "components/crx_file/crx3.pb.h" +@@ -211,7 +213,15 @@ VerifierResult Verify( + std::string* crx_id) { + std::string public_key_local; + std::string crx_id_local; +- base::File file(crx_path, base::File::FLAG_OPEN | base::File::FLAG_READ); ++ LOG(INFO) << "crx_verifier.cc: Verify: crx_path: " << crx_path; ++ base::File file; ++ if (crx_path.IsContentUri()) { ++ file = base::OpenContentUriForRead(crx_path); ++ } else { ++ file = base::File(crx_path, base::File::FLAG_OPEN | base::File::FLAG_READ); ++ } ++ LOG(INFO) << "crx_verifier.cc: Verify: file.IsValid(): " << (file.IsValid()); ++ + if (!file.IsValid()) + return VerifierResult::ERROR_FILE_NOT_READABLE; + +--- a/extensions/browser/sandboxed_unpacker.cc ++++ b/extensions/browser/sandboxed_unpacker.cc +@@ -232,8 +232,9 @@ void SandboxedUnpacker::StartWithCrx(con + expected_hash = base::ToLowerASCII(crx_info.expected_hash); + } + +- if (!CreateTempDirectory()) ++ if (!CreateTempDirectory()) { + return; // ReportFailure() already called. ++ } + + // Initialize the path that will eventually contain the unpacked extension. + extension_root_ = temp_dir_.GetPath().AppendASCII(kTempExtensionName); +--- a/chrome/browser/extensions/crx_installer.cc ++++ b/chrome/browser/extensions/crx_installer.cc +@@ -166,6 +166,7 @@ CrxInstaller::~CrxInstaller() { + } + + void CrxInstaller::InstallCrx(const base::FilePath& source_file) { ++ LOG(INFO) << "crx_installer.cc: InstallCrx: source_file: " << source_file; + crx_file::VerifierFormat format = + off_store_install_allow_reason_ == OffStoreInstallDisallowed + ? GetWebstoreVerifierFormat( +--- a/chrome/browser/download/download_crx_util.cc ++++ b/chrome/browser/download/download_crx_util.cc +@@ -7,6 +7,9 @@ + #include "chrome/browser/download/download_crx_util.h" + + #include "base/command_line.h" ++#include "chrome/browser/android/tab_android.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/chrome_notification_types.h" + #include "chrome/browser/extensions/crx_installer.h" + #include "chrome/browser/extensions/extension_install_prompt.h" +@@ -53,12 +56,10 @@ std::unique_ptr + content::DownloadItemUtils::GetWebContents( + const_cast(&download_item)); + if (!web_contents) { +- Browser* browser = chrome::FindLastActiveWithProfile(profile); +- if (!browser) { +- browser = Browser::Create( +- Browser::CreateParams(Browser::TYPE_NORMAL, profile, true)); ++ for (size_t i = 0; i < TabModelList::size(); ++i) { ++ if (TabModelList::get(i)->IsActiveModel()) ++ web_contents = TabModelList::get(i)->GetActiveWebContents(); + } +- web_contents = browser->tab_strip_model()->GetActiveWebContents(); + } + return std::unique_ptr( + new ExtensionInstallPrompt(web_contents)); +@@ -136,13 +137,10 @@ bool ShouldDownloadAsRegularFile() { + } + + bool IsExtensionDownload(const DownloadItem& download_item) { +- if (download_item.GetTargetDisposition() == +- DownloadItem::TARGET_DISPOSITION_PROMPT) +- return false; +- + if (download_item.GetMimeType() == extensions::Extension::kMimeType || + extensions::UserScript::IsURLUserScript(download_item.GetURL(), + download_item.GetMimeType())) { ++ LOG(INFO) << "download_crx_util.cc: !ShouldDownloadAsRegularFile(): " << (!ShouldDownloadAsRegularFile()); + return !ShouldDownloadAsRegularFile(); + } else { + return false; +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java +@@ -0,0 +1,170 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import android.content.Context; ++import android.content.res.Resources; ++import android.view.LayoutInflater; ++ ++import org.chromium.base.annotations.CalledByNative; ++import org.chromium.base.annotations.NativeMethods; ++import org.chromium.chrome.browser.app.ChromeActivity; ++import org.chromium.chrome.browser.download.dialogs.DownloadLocationCustomView; ++import org.chromium.chrome.R; ++import org.chromium.ui.base.WindowAndroid; ++import org.chromium.ui.modaldialog.DialogDismissalCause; ++import org.chromium.ui.modaldialog.ModalDialogManager; ++import org.chromium.ui.modaldialog.ModalDialogProperties; ++import org.chromium.ui.modelutil.PropertyModel; ++ ++import java.io.File; ++ ++ ++/** ++* Helper class to handle communication between extension install dialog and native. ++*/ ++ ++public class ExtensionInstallDialogViewBridge implements ModalDialogProperties.Controller { ++ private long mNativeExtensionInstallDialogViewBridge; ++ private PropertyModel mDialogModel; ++ private ExtensionInstallCustomScrollView mCustomView; ++ private ModalDialogManager mModalDialogManager; ++ private Context mContext; ++ ++ private ExtensionInstallDialogViewBridge(long nativeExtensionInstallDialogViewBridge) { ++ mNativeExtensionInstallDialogViewBridge = nativeExtensionInstallDialogViewBridge; ++ } ++ ++ @CalledByNative ++ public static ExtensionInstallDialogViewBridge create(long nativeExtensionInstallDialogView) { ++ return new ExtensionInstallDialogViewBridge(nativeExtensionInstallDialogView); ++ } ++ ++ @CalledByNative ++ private void destroy() { ++ mNativeExtensionInstallDialogViewBridge = 0; ++ if (mModalDialogManager != null) { ++ mModalDialogManager.dismissDialog( ++ mDialogModel, DialogDismissalCause.DISMISSED_BY_NATIVE); ++ } ++ } ++ ++ @CalledByNative ++ public void showDialog(WindowAndroid windowAndroid, ++ String title, String storeLink, String withholdPermissionsHeading, ++ boolean shouldDisplayWithholdingUI, boolean shouldShowPermissions, int permissionCount, ++ String[] permissions, String[] permissionsDetails, String permissionsHeading, ++ String[] retainedFiles, String retainedFilesHeading, ++ String[] retainedDeviceMessageStrings, String retainedDevicesHeading) { ++ ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get(); ++ // If the activity has gone away, just clean up the native pointer. ++ if (activity == null) { ++ onDismiss(null, DialogDismissalCause.ACTIVITY_DESTROYED); ++ return; ++ } ++ ++ // Check list of permissions match their length. If mismatch, dismiss with cancel ++ if (permissions.length != permissionCount || permissionsDetails.length != permissionCount) { ++ onDismiss(null, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); ++ return; ++ } ++ ++ mModalDialogManager = activity.getModalDialogManager(); ++ mContext = activity; ++ ++ // Already showing the dialog. ++ if (mDialogModel != null) return; ++ ++ // Actually show the dialog. ++ mCustomView = (ExtensionInstallCustomScrollView) LayoutInflater.from(mContext).inflate( ++ R.layout.extension_install_dialog, null); ++ mCustomView.initialize(title, storeLink, withholdPermissionsHeading, ++ shouldDisplayWithholdingUI, shouldShowPermissions, permissionCount, ++ permissions, permissionsDetails, permissionsHeading, ++ retainedFiles, retainedFilesHeading, ++ retainedDeviceMessageStrings, retainedDevicesHeading); ++ ++ Resources resources = mContext.getResources(); ++ mDialogModel = ++ new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) ++ .with(ModalDialogProperties.CONTROLLER, this) ++ .with(ModalDialogProperties.TITLE, title) ++ .with(ModalDialogProperties.CUSTOM_VIEW, mCustomView) ++ .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, ++ R.string.extension_install_prompt_ok_button) ++ .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, ++ R.string.cancel) ++ .build(); ++ ++ mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.APP); ++ } ++ ++ @Override ++ public void onClick(PropertyModel model, int buttonType) { ++ switch (buttonType) { ++ case ModalDialogProperties.ButtonType.POSITIVE: ++ mModalDialogManager.dismissDialog( ++ model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); ++ break; ++ case ModalDialogProperties.ButtonType.NEGATIVE: ++ mModalDialogManager.dismissDialog( ++ model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); ++ break; ++ default: ++ } ++ } ++ ++ @Override ++ public void onDismiss(PropertyModel model, int dismissalCause) { ++ switch (dismissalCause) { ++ case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: ++ accept((mCustomView != null && mCustomView.getWithholdPermissionChecked())); ++ break; ++ default: ++ cancel(); ++ break; ++ } ++ mDialogModel = null; ++ mCustomView = null; ++ } ++ ++ private void accept(boolean withholdPermissionsCheckboxChecked) { ++ if (mNativeExtensionInstallDialogViewBridge != 0) { ++ ExtensionInstallDialogViewBridgeJni.get().Accept( ++ mNativeExtensionInstallDialogViewBridge, ExtensionInstallDialogViewBridge.this, ++ withholdPermissionsCheckboxChecked); ++ } ++ } ++ ++ private void cancel() { ++ if (mNativeExtensionInstallDialogViewBridge != 0) { ++ ExtensionInstallDialogViewBridgeJni.get().Cancel( ++ mNativeExtensionInstallDialogViewBridge, ExtensionInstallDialogViewBridge.this); ++ } ++ } ++ ++ @NativeMethods ++ interface Natives { ++ void Cancel( ++ long nativeExtensionInstallDialogView, ExtensionInstallDialogViewBridge caller); ++ void Accept( ++ long nativeExtensionInstallDialogView, ExtensionInstallDialogViewBridge caller, ++ boolean withholdPermissionsCheckboxChecked); ++ } ++} +--- /dev/null ++++ b/chrome/android/java/res/layout/extension_install_dialog.xml +@@ -0,0 +1,117 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd ++++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd +@@ -1446,6 +1446,11 @@ Your Google account may have other forms + + + ++ ++ Install ++ ++ ++ + + About Chrome + +--- /dev/null ++++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_android.cc +@@ -0,0 +1,278 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#include "chrome/browser/ui/views/extensions/extension_install_dialog_view_android.h" ++ ++#include ++#include ++ ++#include "base/android/jni_android.h" ++#include "base/android/jni_string.h" ++#include "base/bind.h" ++#include "base/i18n/message_formatter.h" ++#include "base/macros.h" ++#include "base/metrics/histogram_functions.h" ++#include "base/metrics/histogram_macros.h" ++#include "base/strings/utf_string_conversions.h" ++#include "chrome/android/chrome_jni_headers/ExtensionInstallDialogViewBridge_jni.h" ++#include "chrome/browser/extensions/extension_install_prompt_show_params.h" ++#include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/ui/browser.h" ++#include "chrome/browser/ui/browser_dialogs.h" ++#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" ++#include "chrome/browser/ui/views/chrome_layout_provider.h" ++#include "chrome/browser/ui/views/chrome_typography.h" ++#include "chrome/browser/ui/views/extensions/expandable_container_view.h" ++#include "chrome/browser/ui/views/extensions/extension_permissions_view.h" ++#include "chrome/common/extensions/extension_constants.h" ++#include "chrome/grit/generated_resources.h" ++#include "components/constrained_window/constrained_window_views.h" ++#include "content/public/browser/browser_thread.h" ++#include "content/public/browser/page_navigator.h" ++#include "content/public/browser/web_contents.h" ++#include "extensions/common/constants.h" ++#include "extensions/common/extension.h" ++#include "extensions/common/extension_urls.h" ++#include "ui/accessibility/ax_enums.mojom.h" ++#include "ui/android/window_android.h" ++#include "ui/base/l10n/l10n_util.h" ++#include "ui/base/resource/resource_bundle.h" ++#include "url/android/gurl_android.h" ++ ++using content::OpenURLParams; ++using content::Referrer; ++ ++namespace { ++ ++// Time delay before the install button is enabled after initial display. ++int g_install_delay_in_ms = 500; ++ ++void ShowExtensionInstallDialogImpl( ++ ExtensionInstallPromptShowParams* show_params, ++ const ExtensionInstallPrompt::DoneCallback& done_callback, ++ std::unique_ptr prompt) { ++ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); ++ ExtensionInstallDialogView* dialog = new ExtensionInstallDialogView( ++ show_params->profile(), show_params->GetParentWebContents(), ++ done_callback, std::move(prompt)); ++ dialog->ShowDialog( ++ show_params->GetParentWindow()); ++} ++ ++} // namespace ++ ++ExtensionInstallDialogView::ExtensionInstallDialogView( ++ Profile* profile, ++ content::PageNavigator* navigator, ++ const ExtensionInstallPrompt::DoneCallback& done_callback, ++ std::unique_ptr prompt) ++ : profile_(profile), ++ navigator_(navigator), ++ done_callback_(done_callback), ++ prompt_(std::move(prompt)), ++ title_(prompt_->GetDialogTitle()), ++ handled_result_(false), ++ is_dialog_showing_(false) { ++ DCHECK(prompt_->extension()); ++ ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ java_obj_.Reset(env, Java_ExtensionInstallDialogViewBridge_create( ++ env, reinterpret_cast(this)).obj()); ++ DCHECK(!java_obj_.is_null()); ++ ++ UMA_HISTOGRAM_ENUMERATION("Extensions.InstallPrompt.Type2", prompt_->type(), ++ ExtensionInstallPrompt::NUM_PROMPT_TYPES); ++ chrome::RecordDialogCreation(chrome::DialogIdentifier::EXTENSION_INSTALL); ++} ++ ++ExtensionInstallDialogView::~ExtensionInstallDialogView() { ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ Java_ExtensionInstallDialogViewBridge_destroy(env, java_obj_); ++ if (!handled_result_ && !done_callback_.is_null()) { ++ std::move(done_callback_) ++ .Run(ExtensionInstallPrompt::Result::USER_CANCELED); ++ } ++} ++ ++// TODO ++void ExtensionInstallDialogView::Cancel( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj) { ++ if (handled_result_) ++ return; ++ ++ handled_result_ = true; ++ UpdateInstallResultHistogram(false); ++ std::move(done_callback_).Run(ExtensionInstallPrompt::Result::USER_CANCELED); ++} ++ ++// TODO ++void ExtensionInstallDialogView::Accept( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj, ++ jboolean jwithhold_permissions_checkbox_checked) { ++ DCHECK(!handled_result_); ++ ++ bool withhold_permissions_checkbox_checked = ++ static_cast(jwithhold_permissions_checkbox_checked != JNI_FALSE); ++ handled_result_ = true; ++ UpdateInstallResultHistogram(true); ++ // If the prompt had a checkbox element and it was checked we send that along ++ // as the result, otherwise we just send a normal accepted result. ++ auto result = ++ prompt_->ShouldDisplayWithholdingUI() && ++ withhold_permissions_checkbox_checked ++ ? ExtensionInstallPrompt::Result::ACCEPTED_AND_OPTION_CHECKED ++ : ExtensionInstallPrompt::Result::ACCEPTED; ++ std::move(done_callback_).Run(result); ++} ++ ++void ExtensionInstallDialogView::ShowDialog( ++ gfx::NativeWindow native_window) { ++ if (!native_window) ++ return; ++ ++ base::string16 store_link(base::ASCIIToUTF16("")); ++ base::string16 withhold_permissions_heading(base::ASCIIToUTF16("")); ++ if (prompt_->has_webstore_data()) { ++ // TODO: this is not shown yet ++ store_link = ++ l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_STORE_LINK); ++ GURL store_url(extension_urls::GetWebstoreItemDetailURLPrefix() + ++ prompt_->extension()->id()); ++ } else if (prompt_->ShouldDisplayWithholdingUI()) { ++ withhold_permissions_heading = ++ l10n_util::GetStringUTF16(IDS_EXTENSION_WITHHOLD_PERMISSIONS); ++ } ++ ++ // If dialog is already showing, do nothing. (assuming cancel?) ++ if (is_dialog_showing_) { ++ return; ++ } ++ ++ is_dialog_showing_ = true; ++ ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ Java_ExtensionInstallDialogViewBridge_showDialog( ++ env, java_obj_, native_window->GetJavaObject(), ++ base::android::ConvertUTF16ToJavaString(env, title_), ++ base::android::ConvertUTF16ToJavaString(env, store_link), ++ base::android::ConvertUTF16ToJavaString(env, withhold_permissions_heading), ++ static_cast(prompt_->ShouldDisplayWithholdingUI()), ++ static_cast(prompt_->ShouldShowPermissions()), ++ static_cast(prompt_->GetPermissionCount()), ++ ToJavaArrayOfPermissions(env), ++ ToJavaArrayOfPermissionsDetails(env), ++ prompt_->ShouldShowPermissions() ? base::android::ConvertUTF16ToJavaString(env, prompt_->GetPermissionsHeading()) : ++ base::android::ConvertUTF16ToJavaString(env, l10n_util::GetStringUTF16(IDS_EXTENSION_NO_SPECIAL_PERMISSIONS)), ++ ToJavaArrayOfRetainedFiles(env), ++ base::android::ConvertUTF16ToJavaString(env, prompt_->GetRetainedFilesHeading()), ++ ToJavaArrayOfRetainedDeviceMessageStrings(env), ++ base::android::ConvertUTF16ToJavaString(env, prompt_->GetRetainedDevicesHeading()) ++ ); ++} ++ ++base::android::ScopedJavaLocalRef ExtensionInstallDialogView::ToJavaArrayOfPermissions( ++ JNIEnv* env) { ++ DCHECK_GE(prompt_->GetPermissionCount(), 0u); ++ base::android::ScopedJavaLocalRef object_clazz = ++ base::android::GetClass(env, "java/lang/String"); ++ jobjectArray joa = ++ env->NewObjectArray(prompt_->GetPermissionCount(), object_clazz.obj(), NULL); ++ jni_generator::CheckException(env); ++ ++ for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) { ++ env->SetObjectArrayElement(joa, i, ++ base::android::ConvertUTF16ToJavaString(env, ++ prompt_->GetPermission(i)).obj()); ++ } ++ return base::android::ScopedJavaLocalRef(env, joa); ++} ++ ++base::android::ScopedJavaLocalRef ExtensionInstallDialogView::ToJavaArrayOfPermissionsDetails( ++ JNIEnv* env) { ++ DCHECK_GE(prompt_->GetPermissionCount(), 0u); ++ base::android::ScopedJavaLocalRef object_clazz = ++ base::android::GetClass(env, "java/lang/String"); ++ jobjectArray joa = ++ env->NewObjectArray(prompt_->GetPermissionCount(), object_clazz.obj(), NULL); ++ jni_generator::CheckException(env); ++ ++ for (size_t i = 0; i < prompt_->GetPermissionCount(); ++i) { ++ env->SetObjectArrayElement(joa, i, ++ base::android::ConvertUTF16ToJavaString(env, ++ prompt_->GetPermissionsDetails(i)).obj()); ++ } ++ return base::android::ScopedJavaLocalRef(env, joa); ++} ++ ++base::android::ScopedJavaLocalRef ExtensionInstallDialogView::ToJavaArrayOfRetainedFiles( ++ JNIEnv* env) { ++ DCHECK_GE(prompt_->GetRetainedFileCount(), 0u); ++ base::android::ScopedJavaLocalRef object_clazz = ++ base::android::GetClass(env, "java/lang/String"); ++ jobjectArray joa = ++ env->NewObjectArray(prompt_->GetRetainedFileCount(), object_clazz.obj(), NULL); ++ jni_generator::CheckException(env); ++ ++ for (size_t i = 0; i < prompt_->GetRetainedFileCount(); ++i) { ++ env->SetObjectArrayElement(joa, i, ++ base::android::ConvertUTF16ToJavaString(env, ++ prompt_->GetRetainedFile(i)).obj()); ++ } ++ return base::android::ScopedJavaLocalRef(env, joa); ++} ++ ++base::android::ScopedJavaLocalRef ExtensionInstallDialogView::ToJavaArrayOfRetainedDeviceMessageStrings( ++ JNIEnv* env) { ++ DCHECK_GE(prompt_->GetRetainedDeviceCount(), 0u); ++ base::android::ScopedJavaLocalRef object_clazz = ++ base::android::GetClass(env, "java/lang/String"); ++ jobjectArray joa = ++ env->NewObjectArray(prompt_->GetRetainedDeviceCount(), object_clazz.obj(), NULL); ++ jni_generator::CheckException(env); ++ ++ for (size_t i = 0; i < prompt_->GetRetainedDeviceCount(); ++i) { ++ env->SetObjectArrayElement(joa, i, ++ base::android::ConvertUTF16ToJavaString(env, ++ prompt_->GetRetainedDeviceMessageString(i)).obj()); ++ } ++ return base::android::ScopedJavaLocalRef(env, joa); ++} ++ ++void ExtensionInstallDialogView::UpdateInstallResultHistogram(bool accepted) ++ const { ++ // Only update histograms if |install_result_timer_| was initialized in ++ // |VisibilityChanged|. ++ if (prompt_->type() == ExtensionInstallPrompt::INSTALL_PROMPT && ++ install_result_timer_) { ++ if (accepted) { ++ UmaHistogramMediumTimes("Extensions.InstallPrompt.TimeToInstall", ++ install_result_timer_->Elapsed()); ++ } else { ++ UmaHistogramMediumTimes("Extensions.InstallPrompt.TimeToCancel", ++ install_result_timer_->Elapsed()); ++ } ++ } ++} ++ ++// static ++ExtensionInstallPrompt::ShowDialogCallback ++ExtensionInstallPrompt::GetDefaultShowDialogCallback() { ++ return base::Bind(&ShowExtensionInstallDialogImpl); ++} +--- /dev/null ++++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_android.h +@@ -0,0 +1,103 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_ANDROID_H_ ++#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_ANDROID_H_ ++ ++#include ++ ++#include "base/android/jni_android.h" ++#include "base/android/scoped_java_ref.h" ++#include "base/macros.h" ++#include "base/optional.h" ++#include "base/timer/elapsed_timer.h" ++#include "base/timer/timer.h" ++#include "chrome/browser/extensions/extension_install_prompt.h" ++#include "ui/gfx/native_widget_types.h" ++ ++class Profile; ++ ++namespace content { ++class PageNavigator; ++} ++ ++// Modal dialog that shows when the user attempts to install an extension. Also ++// shown if the extension is already installed but needs additional permissions. ++// Android JNI version. ++class ExtensionInstallDialogView { ++ public: ++ // The views::View::id of the ratings section in the dialog. ++ static const int kRatingsViewId = 1; ++ ++ ExtensionInstallDialogView( ++ Profile* profile, ++ content::PageNavigator* navigator, ++ const ExtensionInstallPrompt::DoneCallback& done_callback, ++ std::unique_ptr prompt); ++ ~ExtensionInstallDialogView(); ++ ++ void Cancel( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj); ++ void Accept( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj, ++ const jboolean withhold_permissions_checkbox_checked); ++ void ShowDialog(gfx::NativeWindow native_window); ++ ++ private: ++ bool is_external_install() const { ++ return prompt_->type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT; ++ } ++ ++ // Updates the histogram that holds installation accepted/aborted data. ++ void UpdateInstallResultHistogram(bool accepted) const; ++ ++ Profile* profile_; ++ content::PageNavigator* navigator_; ++ ExtensionInstallPrompt::DoneCallback done_callback_; ++ std::unique_ptr prompt_; ++ base::string16 title_; ++ ++ // Set to true once the user's selection has been received and the callback ++ // has been run. ++ bool handled_result_; ++ ++ // Used to record time between dialog creation and acceptance, cancellation, ++ // or dismissal. ++ base::Optional install_result_timer_; ++ ++ // TODO: Checkbox used to indicate if permissions should be withheld on install. ++ ++ // JNI ++ bool is_dialog_showing_; ++ base::android::ScopedJavaGlobalRef java_obj_; ++ ++ base::android::ScopedJavaLocalRef ToJavaArrayOfPermissions( ++ JNIEnv* env); ++ base::android::ScopedJavaLocalRef ToJavaArrayOfPermissionsDetails( ++ JNIEnv* env); ++ base::android::ScopedJavaLocalRef ToJavaArrayOfRetainedFiles( ++ JNIEnv* env); ++ base::android::ScopedJavaLocalRef ToJavaArrayOfRetainedDeviceMessageStrings( ++ JNIEnv* env); ++ ++ DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); ++}; ++ ++#endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_ +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -3236,6 +3236,7 @@ generate_jni("chrome_jni_headers") { + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategory.java", + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java", + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", + "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", + "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java", + "java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java", +--- a/chrome/android/chrome_java_sources.gni ++++ b/chrome/android/chrome_java_sources.gni +@@ -683,6 +683,8 @@ chrome_java_sources = [ + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java", + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java", + "java/src/org/chromium/chrome/browser/explore_sites/StableScrollLayoutManager.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallCustomScrollView.java", + "java/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtils.java", + "java/src/org/chromium/chrome/browser/externalauth/UserRecoverableErrorHandler.java", + "java/src/org/chromium/chrome/browser/externalauth/VerifiedHandler.java", +--- a/chrome/browser/ui/BUILD.gn ++++ b/chrome/browser/ui/BUILD.gn +@@ -3505,8 +3505,8 @@ static_library("ui") { + "views/extensions/extension_context_menu_controller.h", + "views/extensions/extension_install_blocked_dialog_view.cc", + "views/extensions/extension_install_blocked_dialog_view.h", +- "views/extensions/extension_install_dialog_view.cc", +- "views/extensions/extension_install_dialog_view.h", ++ "views/extensions/extension_install_dialog_view_android.cc", ++ "views/extensions/extension_install_dialog_view_android.h", + "views/extensions/extension_installed_bubble_view.cc", + "views/extensions/extension_keybinding_registry_views.cc", + "views/extensions/extension_keybinding_registry_views.h", +--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc ++++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + +-#include "chrome/browser/ui/views/extensions/extension_install_dialog_view.h" ++#include "chrome/browser/ui/views/extensions/extension_install_dialog_view_android.h" + + #include + #include +--- a/chrome/browser/ui/extensions/extension_install_ui_default.cc ++++ b/chrome/browser/ui/extensions/extension_install_ui_default.cc +@@ -46,13 +46,7 @@ namespace { + Browser* FindOrCreateVisibleBrowser(Profile* profile) { + // TODO(mpcomplete): remove this workaround for http://crbug.com/244246 + // after fixing http://crbug.com/38676. +- if (!IncognitoModePrefs::CanOpenBrowser(profile)) +- return nullptr; +- chrome::ScopedTabbedBrowserDisplayer displayer(profile); +- Browser* browser = displayer.browser(); +- if (browser->tab_strip_model()->count() == 0) +- chrome::AddTabAt(browser, GURL(), -1, true); +- return browser; ++ return nullptr; + } + + } // namespace +@@ -85,7 +79,7 @@ void ExtensionInstallUIDefault::OnInstal + if (extension->is_app()) { + if (use_app_installed_bubble_) { + if (browser) +- ShowPlatformBubble(extension, browser, *icon); ++ // TODO: ShowPlatformBubble(extension, browser, *icon); + return; + } + +@@ -97,7 +91,7 @@ void ExtensionInstallUIDefault::OnInstal + return; + } + +- ShowPlatformBubble(extension, browser, *icon); ++ // TODO: ShowPlatformBubble(extension, browser, *icon); + } + + void ExtensionInstallUIDefault::OnInstallFailure( +--- a/base/android/java/src/org/chromium/base/ContentUriUtils.java ++++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java +@@ -300,6 +300,7 @@ public abstract class ContentUriUtils { + public static boolean delete(String uriString) { + assert isContentUri(uriString); + Uri parsedUri = Uri.parse(uriString); ++ Log.d(TAG, "parsedUri: %s", parsedUri.toString()); + ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver(); + return resolver.delete(parsedUri, null, null) > 0; + } +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionInstallCustomScrollView.java +@@ -0,0 +1,144 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import android.content.Context; ++import android.util.AttributeSet; ++import android.view.View; ++import android.widget.CheckBox; ++import android.widget.CompoundButton; ++import android.widget.CompoundButton.OnCheckedChangeListener; ++import android.widget.ScrollView; ++import android.widget.Spinner; ++import android.widget.TextView; ++ ++import androidx.annotation.Nullable; ++ ++import org.chromium.chrome.R; ++import org.chromium.chrome.browser.download.DownloadUtils; ++import org.chromium.chrome.browser.download.settings.DownloadDirectoryAdapter; ++import org.chromium.components.browser_ui.widget.text.AlertDialogEditText; ++ ++import java.io.File; ++import java.util.StringJoiner; ++ ++/** ++ * Dialog that is displayed to ask user where they want to download the file. ++ */ ++public class ExtensionInstallCustomScrollView ++ extends ScrollView implements OnCheckedChangeListener { ++ private TextView mSubtitleView; ++ private TextView mPermissionsHeading; ++ private TextView mPermissions; ++ private TextView mRetainedFilesHeading; ++ private TextView mRetainedFiles; ++ private TextView mRetainedDevicesHeading; ++ private TextView mRetainedDeviceMessage; ++ private CheckBox mWithholdPermission; ++ ++ private boolean mWithholdPermissionChecked; ++ ++ public ExtensionInstallCustomScrollView(Context context, AttributeSet attrs) { ++ super(context, attrs); ++ mWithholdPermissionChecked = false; ++ } ++ ++ @Override ++ protected void onFinishInflate() { ++ super.onFinishInflate(); ++ ++ mSubtitleView = findViewById(R.id.subtitle); ++ mPermissionsHeading = findViewById(R.id.permissions_heading); ++ mPermissions = findViewById(R.id.permissions); ++ mRetainedFilesHeading = findViewById(R.id.retained_files_heading); ++ mRetainedFiles = findViewById(R.id.retained_files); ++ mRetainedDevicesHeading = findViewById(R.id.retained_devices_heading); ++ mRetainedDeviceMessage = findViewById(R.id.retained_device_message); ++ mWithholdPermission = findViewById(R.id.withhold_permission_checkbox); ++ } ++ ++ void initialize(String title, String storeLink, String withholdPermissionsHeading, ++ boolean shouldDisplayWithholdingUI, boolean shouldShowPermissions, int permissionCount, ++ String[] permissions, String[] permissionsDetails, String permissionsHeading, ++ String[] retainedFiles, String retainedFilesHeading, ++ String[] retainedDeviceMessageStrings, String retainedDevicesHeading) { ++ ++ if (shouldDisplayWithholdingUI) { ++ mWithholdPermission.setVisibility(View.VISIBLE); ++ mWithholdPermission.setText(withholdPermissionsHeading); ++ mWithholdPermission.setChecked(false); ++ } ++ mWithholdPermission.setOnCheckedChangeListener(this); ++ ++ mSubtitleView.setText(title); ++ ++ mPermissionsHeading.setText(permissionsHeading); ++ if (shouldShowPermissions) { ++ char bull = '\u2022'; ++ String newline = ""; ++ String indent = " "; ++ StringBuilder sb = new StringBuilder(); ++ for (int i = 0; i < permissionCount; ++i) { ++ // Format strings ++ sb.append(newline).append(bull).append(permissions[i]); ++ newline = "\n"; ++ sb.append(newline).append(indent).append(permissionsDetails[i]); ++ } ++ mPermissions.setText(sb.toString()); ++ mPermissions.setVisibility(View.VISIBLE); ++ } ++ ++ if (retainedFiles.length > 0) { ++ String newline = ""; ++ StringBuilder sb = new StringBuilder(); ++ for (int i = 0; i < retainedFiles.length; ++i) { ++ // Format strings ++ sb.append(newline).append(retainedFiles[i]); ++ newline = "\n"; ++ } ++ mRetainedFiles.setText(sb.toString()); ++ mRetainedFiles.setVisibility(View.VISIBLE); ++ mRetainedFilesHeading.setText(retainedFilesHeading); ++ mRetainedFilesHeading.setVisibility(View.VISIBLE); ++ } ++ ++ if (retainedDeviceMessageStrings.length > 0) { ++ String newline = ""; ++ StringBuilder sb = new StringBuilder(); ++ for (int i = 0; i < retainedDeviceMessageStrings.length; ++i) { ++ // Format strings ++ sb.append(newline).append(retainedDeviceMessageStrings[i]); ++ newline = "\n"; ++ } ++ mRetainedDeviceMessage.setText(sb.toString()); ++ mRetainedDeviceMessage.setVisibility(View.VISIBLE); ++ mRetainedDevicesHeading.setText(retainedDevicesHeading); ++ mRetainedDevicesHeading.setVisibility(View.VISIBLE); ++ } ++ } ++ ++ protected boolean getWithholdPermissionChecked() { ++ return mWithholdPermissionChecked; ++ } ++ ++ @Override ++ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ++ mWithholdPermissionChecked = isChecked; ++ } ++} +--- a/chrome/android/chrome_java_resources.gni ++++ b/chrome/android/chrome_java_resources.gni +@@ -864,6 +864,7 @@ chrome_java_resources = [ + "java/res/layout/explore_sites_page_layout.xml", + "java/res/layout/explore_sites_section.xml", + "java/res/layout/explore_sites_tile_view.xml", ++ "java/res/layout/extension_install_dialog.xml", + "java/res/layout/fake_search_box_layout.xml", + "java/res/layout/find_in_page.xml", + "java/res/layout/find_toolbar.xml", +--- a/extensions/common/manifest_handlers/default_locale_handler.cc ++++ b/extensions/common/manifest_handlers/default_locale_handler.cc +@@ -87,9 +87,10 @@ bool DefaultLocaleHandler::Validate( + + base::FilePath locale_path; + while (!(locale_path = locales.Next()).empty()) { +- if (extension_l10n_util::ShouldSkipValidation(path, locale_path, +- all_locales)) +- continue; ++ // Somhow Android version doesn't get the right available locales from ICU, so skip this ++// if (extension_l10n_util::ShouldSkipValidation(path, locale_path, ++// all_locales)) ++// continue; + + base::FilePath messages_path = locale_path.Append(kMessagesFilename); + base::FilePath gzipped_messages_path = diff --git a/patches/Extensions/extension-system-delayed-reload.patch b/patches/Extensions/extension-system-delayed-reload.patch new file mode 100644 index 0000000..1d9943d --- /dev/null +++ b/patches/Extensions/extension-system-delayed-reload.patch @@ -0,0 +1,271 @@ +From: Wengling Chen +Date: Thu, 21 Jan 2021 20:35:11 +0200 +Subject: Reload extensions after the first tab is loaded from Java. Otherwise certain + observers will not be invoked. + +--- + +--- + chrome/android/BUILD.gn | 4 - + chrome/android/chrome_java_sources.gni | 1 + chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java | 8 ++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java | 22 ++++++ + chrome/browser/extensions/BUILD.gn | 3 + chrome/browser/extensions/extension_service.cc | 11 ++- + chrome/browser/extensions/extension_service.h | 5 + + chrome/browser/extensions/extension_system_manager.cc | 36 ++++++++++ + chrome/browser/extensions/extension_system_manager.h | 28 +++++++ + chrome/browser/extensions/updater/extension_updater.cc | 2 + chrome/browser/safety_check/android/BUILD.gn | 1 + extensions/browser/api/web_request/web_request_api.cc | 2 + 12 files changed, 120 insertions(+), 3 deletions(-) + +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -764,9 +764,8 @@ junit_binary("chrome_junit_tests") { + sources = chrome_junit_test_java_sources + + # Should not have any deps native targets since junit tests are java-only. ++ # Ignore this. We are not running junit tests anyway. + assert_no_deps = [ +- "//content", +- "//mojo/public/mojom/base", + ] + + deps = [ +@@ -3237,6 +3236,7 @@ generate_jni("chrome_jni_headers") { + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java", + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", + "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", + "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java", +--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +@@ -74,6 +74,7 @@ import org.chromium.chrome.browser.devic + import org.chromium.chrome.browser.dom_distiller.ReaderModeManager; + import org.chromium.chrome.browser.download.DownloadOpenSource; + import org.chromium.chrome.browser.download.DownloadUtils; ++import org.chromium.chrome.browser.extensions.ExtensionSystemManager; + import org.chromium.chrome.browser.feature_engagement.TrackerFactory; + import org.chromium.chrome.browser.feed.FeedV1; + import org.chromium.chrome.browser.feed.FeedV2; +@@ -741,6 +742,12 @@ public class ChromeTabbedActivity extend + } + } + ++ private void initExtensionSystem() { ++ try (TraceEvent e = TraceEvent.scoped("ChromeTabbedActivity.initExtensionSystem")) { ++ ExtensionSystemManager.reInit(); ++ } ++ } ++ + @Override + public void onNewIntent(Intent intent) { + // The intent to use in maybeDispatchExplicitMainViewIntent(). We're explicitly +@@ -775,6 +782,7 @@ public class ChromeTabbedActivity extend + + // All this initialization can be expensive so it's split into multiple tasks. + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::refreshSignIn); ++ PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::initExtensionSystem); + PostTask.postTask(UiThreadTaskTraits.DEFAULT, this::initializeToolbarManager); + PostTask.postTask( + UiThreadTaskTraits.DEFAULT, this::maybeCreateIncognitoTabSnapshotController); +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java +@@ -0,0 +1,22 @@ ++package org.chromium.chrome.browser.extensions; ++ ++import org.chromium.base.Log; ++import org.chromium.base.annotations.CalledByNative; ++import org.chromium.base.annotations.JNINamespace; ++import org.chromium.base.annotations.NativeMethods; ++ ++/** ++ * Provide access of native code for extension service. ++ */ ++@JNINamespace("extensions") ++public class ExtensionSystemManager { ++ ++ public static void reInit() { ++ ExtensionSystemManagerJni.get().reInit(); ++ } ++ ++ @NativeMethods ++ interface Natives { ++ void reInit(); ++ } ++} +--- a/chrome/android/chrome_java_sources.gni ++++ b/chrome/android/chrome_java_sources.gni +@@ -685,6 +685,7 @@ chrome_java_sources = [ + "java/src/org/chromium/chrome/browser/explore_sites/StableScrollLayoutManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallCustomScrollView.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionSystemManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallCustomScrollView.java", + "java/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtils.java", +--- a/chrome/browser/extensions/extension_service.cc ++++ b/chrome/browser/extensions/extension_service.cc +@@ -507,7 +507,8 @@ void ExtensionService::Init() { + LoadExtensionsFromCommandLineFlag(switches::kLoadExtension); + EnabledReloadableExtensions(); + MaybeFinishShutdownDelayed(); +- SetReadyAndNotifyListeners(); ++ // Delay signal to ReloadExtensions() ++ // SetReadyAndNotifyListeners(); + + UninstallMigratedExtensions(); + +@@ -1322,6 +1323,14 @@ void ExtensionService::RemoveComponentEx + } + } + ++void ExtensionService::ReloadExtensions() { ++ // No need to load components since the only one is chromium_web_store ++ InstalledLoader(this).LoadAllExtensions(); ++ OnInstalledExtensionsLoaded(); ++ ++ SetReadyAndNotifyListeners(); ++} ++ + void ExtensionService::UnloadAllExtensionsForTest() { + UnloadAllExtensionsInternal(); + } +--- a/chrome/browser/extensions/extension_service.h ++++ b/chrome/browser/extensions/extension_service.h +@@ -405,6 +405,11 @@ class ExtensionService : public Extensio + } + + ////////////////////////////////////////////////////////////////////////////// ++ // Android ++ // Reload extensions. Called from Java. ++ void ReloadExtensions(); ++ ++ ////////////////////////////////////////////////////////////////////////////// + // For Testing + + // Unload all extensions. Does not send notifications. +--- a/chrome/browser/extensions/BUILD.gn ++++ b/chrome/browser/extensions/BUILD.gn +@@ -568,6 +568,8 @@ static_library("extensions") { + "extension_system_factory.h", + "extension_system_impl.cc", + "extension_system_impl.h", ++ "extension_system_manager.cc", ++ "extension_system_manager.h", + "extension_tab_util.cc", + "extension_tab_util.h", + "extension_ui_util.cc", +@@ -772,6 +774,7 @@ static_library("extensions") { + "//chrome:extra_resources", + "//chrome:resources", + "//chrome:strings", ++ "//chrome/android:jni_headers", + "//chrome/app:command_ids", + "//chrome/app/resources:platform_locale_settings", + "//chrome/app/theme:chrome_unscaled_resources", +--- /dev/null ++++ b/chrome/browser/extensions/extension_system_manager.cc +@@ -0,0 +1,36 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#include "chrome/browser/extensions/extension_system_manager.h" ++ ++#include "base/android/jni_android.h" ++#include "chrome/android/chrome_jni_headers/ExtensionSystemManager_jni.h" ++#include "chrome/browser/extensions/extension_service.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "extensions/browser/extension_system.h" ++ ++ ++namespace extensions { ++ ++static void JNI_ExtensionSystemManager_ReInit(JNIEnv* env) { ++ // Trigger reloading of all non-component extensions ++ Profile* profile = ProfileManager::GetActiveUserProfile(); ++ ExtensionSystem::Get(profile)->extension_service()->ReloadExtensions(); ++} ++ ++} // namespace extensions +--- /dev/null ++++ b/chrome/browser/extensions/extension_system_manager.h +@@ -0,0 +1,28 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_MANAGER_H_ ++#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_MANAGER_H_ ++ ++#include ++ ++namespace extensions { ++ ++} // namespace extensions ++ ++#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SYSTEM_MANAGER_H_ +--- a/chrome/browser/extensions/updater/extension_updater.cc ++++ b/chrome/browser/extensions/updater/extension_updater.cc +@@ -174,6 +174,8 @@ void ExtensionUpdater::EnsureDownloaderC + } + + void ExtensionUpdater::Start() { ++ if (alive_) ++ return; + DCHECK(!alive_); + // If these are NULL, then that means we've been called after Stop() + // has been called. +--- a/chrome/browser/safety_check/android/BUILD.gn ++++ b/chrome/browser/safety_check/android/BUILD.gn +@@ -49,6 +49,7 @@ android_library("java") { + "//components/password_manager/core/browser:password_manager_java_enums", + "//components/signin/public/android:java", + "//content/public/android:content_java", ++ "//content/public/common:common", + "//third_party/android_deps:android_support_v7_appcompat_java", + "//third_party/android_deps:androidx_annotation_annotation_java", + "//third_party/android_deps:androidx_fragment_fragment_java", +--- a/extensions/browser/api/web_request/web_request_api.cc ++++ b/extensions/browser/api/web_request/web_request_api.cc +@@ -850,6 +850,8 @@ void WebRequestAPI::OnExtensionUnloaded( + UnloadedExtensionReason reason) { + if (HasAnyWebRequestPermissions(extension)) { + --web_request_extension_count_; ++ if (web_request_extension_count_ < 0) ++ web_request_extension_count_ = 0; + UpdateMayHaveProxies(); + } + } diff --git a/patches/Extensions/fix-extension-remove-button.patch b/patches/Extensions/fix-extension-remove-button.patch new file mode 100644 index 0000000..05fbdfe --- /dev/null +++ b/patches/Extensions/fix-extension-remove-button.patch @@ -0,0 +1,694 @@ +From: Wengling Chen +Date: Mon, 13 Jul 2020 23:37:25 -0400 +Subject: fix remove button for extensions + + +--- +--- + chrome/android/BUILD.gn | 1 + chrome/android/chrome_java_resources.gni | 1 + chrome/android/chrome_java_sources.gni | 2 + chrome/android/java/res/layout/extension_uninstall_dialog.xml | 52 ++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallCustomScrollView.java | 77 ++++ + chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java | 160 ++++++++ + chrome/browser/extensions/chrome_extension_function_details.cc | 4 + chrome/browser/ui/BUILD.gn | 3 + chrome/browser/ui/android/strings/android_chrome_strings.grd | 5 + chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_android.cc | 190 ++++++++++ + chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_android.h | 101 +++++ + 11 files changed, 591 insertions(+), 5 deletions(-) + +--- a/chrome/browser/extensions/chrome_extension_function_details.cc ++++ b/chrome/browser/extensions/chrome_extension_function_details.cc +@@ -83,8 +83,7 @@ gfx::NativeWindow ChromeExtensionFunctio + // TODO(devlin): This seems weird. Why wouldn't we check this first? + content::WebContents* sender_web_contents = function_->GetSenderWebContents(); + if (sender_web_contents && +- web_modal::WebContentsModalDialogManager::FromWebContents( +- sender_web_contents)) { ++ sender_web_contents->GetTopLevelNativeWindow()) { + return sender_web_contents->GetTopLevelNativeWindow(); + } + +@@ -105,5 +104,6 @@ gfx::NativeWindow ChromeExtensionFunctio + // sleep() in the background script, during which browser is closed. + if (!browser) + return nullptr; ++ + return browser->window()->GetNativeWindow(); + } +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallCustomScrollView.java +@@ -0,0 +1,77 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import android.content.Context; ++import android.util.AttributeSet; ++import android.view.View; ++import android.widget.CheckBox; ++import android.widget.CompoundButton; ++import android.widget.CompoundButton.OnCheckedChangeListener; ++import android.widget.ScrollView; ++import android.widget.TextView; ++ ++import org.chromium.chrome.R; ++ ++/** ++ * Dialog that is displayed to ask user whether they want to remove the extension. ++ */ ++public class ExtensionUninstallCustomScrollView ++ extends ScrollView implements OnCheckedChangeListener { ++ private TextView mSubtitleView; ++ private CheckBox mCheckbox; ++ ++ private boolean mCheckboxChecked; ++ ++ public ExtensionUninstallCustomScrollView(Context context, AttributeSet attrs) { ++ super(context, attrs); ++ mCheckboxChecked = false; ++ } ++ ++ @Override ++ protected void onFinishInflate() { ++ super.onFinishInflate(); ++ ++ mSubtitleView = findViewById(R.id.subtitle); ++ mCheckbox = findViewById(R.id.checkbox); ++ } ++ ++ void initialize(String extension_name, ++ String windowTitle, String heading, ++ boolean checkbox, String checkboxLabel) { ++ ++ if (checkbox) { ++ mCheckbox.setVisibility(View.VISIBLE); ++ mCheckbox.setText(checkboxLabel); ++ mCheckbox.setChecked(false); ++ } ++ mCheckbox.setOnCheckedChangeListener(this); ++ ++ mSubtitleView.setText(heading); ++ } ++ ++ protected boolean getcheckboxChecked() { ++ return mCheckboxChecked; ++ } ++ ++ @Override ++ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ++ mCheckboxChecked = isChecked; ++ } ++} +--- /dev/null ++++ b/chrome/android/java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java +@@ -0,0 +1,160 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++package org.chromium.chrome.browser.extensions; ++ ++import android.content.Context; ++import android.content.res.Resources; ++import android.view.LayoutInflater; ++ ++import org.chromium.base.annotations.CalledByNative; ++import org.chromium.base.annotations.NativeMethods; ++import org.chromium.chrome.browser.app.ChromeActivity; ++import org.chromium.chrome.R; ++import org.chromium.ui.base.WindowAndroid; ++import org.chromium.ui.modaldialog.DialogDismissalCause; ++import org.chromium.ui.modaldialog.ModalDialogManager; ++import org.chromium.ui.modaldialog.ModalDialogProperties; ++import org.chromium.ui.modelutil.PropertyModel; ++ ++ ++/** ++* Helper class to handle communication between extension uninstall dialog and native. ++*/ ++ ++public class ExtensionUninstallDialogBridge implements ModalDialogProperties.Controller { ++ private long mNativeExtensionUninstallDialogDelegateView; ++ private PropertyModel mDialogModel; ++ private ExtensionUninstallCustomScrollView mCustomView; ++ private ModalDialogManager mModalDialogManager; ++ private Context mContext; ++ ++ private ExtensionUninstallDialogBridge(long nativeExtensionUninstallDialogDelegateView) { ++ mNativeExtensionUninstallDialogDelegateView = nativeExtensionUninstallDialogDelegateView; ++ } ++ ++ @CalledByNative ++ public static ExtensionUninstallDialogBridge create( ++ long nativeExtensionUninstallDialogDelegateView) { ++ return new ExtensionUninstallDialogBridge(nativeExtensionUninstallDialogDelegateView); ++ } ++ ++ @CalledByNative ++ private void destroy() { ++ mNativeExtensionUninstallDialogDelegateView = 0; ++ if (mModalDialogManager != null) { ++ mModalDialogManager.dismissDialog( ++ mDialogModel, DialogDismissalCause.DISMISSED_BY_NATIVE); ++ } ++ } ++ ++ @CalledByNative ++ public void show(WindowAndroid windowAndroid, ++ String extension_name, String windowTitle, String heading, ++ boolean checkbox, String checkboxLabel) { ++ ChromeActivity activity = (ChromeActivity) windowAndroid.getActivity().get(); ++ // If the activity has gone away, just clean up the native pointer. ++ if (activity == null) { ++ onDismiss(null, DialogDismissalCause.ACTIVITY_DESTROYED); ++ return; ++ } ++ ++ mModalDialogManager = activity.getModalDialogManager(); ++ mContext = activity; ++ ++ // Already showing the dialog. ++ if (mDialogModel != null) return; ++ ++ // Actually show the dialog. ++ mCustomView = (ExtensionUninstallCustomScrollView) LayoutInflater.from(mContext).inflate( ++ R.layout.extension_uninstall_dialog, null); ++ mCustomView.initialize(extension_name, windowTitle, heading, ++ checkbox, checkboxLabel); ++ ++ Resources resources = mContext.getResources(); ++ mDialogModel = ++ new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) ++ .with(ModalDialogProperties.CONTROLLER, this) ++ .with(ModalDialogProperties.TITLE, windowTitle) ++ .with(ModalDialogProperties.CUSTOM_VIEW, mCustomView) ++ .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, ++ R.string.extension_prompt_uninstall_button) ++ .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, ++ R.string.cancel) ++ .build(); ++ ++ mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.APP); ++ } ++ ++ @Override ++ public void onClick(PropertyModel model, int buttonType) { ++ switch (buttonType) { ++ case ModalDialogProperties.ButtonType.POSITIVE: ++ mModalDialogManager.dismissDialog( ++ model, DialogDismissalCause.POSITIVE_BUTTON_CLICKED); ++ break; ++ case ModalDialogProperties.ButtonType.NEGATIVE: ++ mModalDialogManager.dismissDialog( ++ model, DialogDismissalCause.NEGATIVE_BUTTON_CLICKED); ++ break; ++ default: ++ } ++ } ++ ++ @Override ++ public void onDismiss(PropertyModel model, int dismissalCause) { ++ switch (dismissalCause) { ++ case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: ++ accept((mCustomView != null && mCustomView.getcheckboxChecked())); ++ break; ++ default: ++ cancel(); ++ break; ++ } ++ mDialogModel = null; ++ mCustomView = null; ++ } ++ ++ private void accept(boolean checkboxChecked) { ++ if (mNativeExtensionUninstallDialogDelegateView != 0) { ++ ExtensionUninstallDialogBridgeJni.get().Accept( ++ mNativeExtensionUninstallDialogDelegateView, ++ ExtensionUninstallDialogBridge.this, ++ checkboxChecked); ++ } ++ } ++ ++ private void cancel() { ++ if (mNativeExtensionUninstallDialogDelegateView != 0) { ++ ExtensionUninstallDialogBridgeJni.get().Cancel( ++ mNativeExtensionUninstallDialogDelegateView, ++ ExtensionUninstallDialogBridge.this); ++ } ++ } ++ ++ @NativeMethods ++ interface Natives { ++ void Cancel( ++ long nativeExtensionUninstallDialogDelegateView, ++ ExtensionUninstallDialogBridge caller); ++ void Accept( ++ long nativeExtensionUninstallDialogDelegateView, ++ ExtensionUninstallDialogBridge caller, ++ boolean checkboxChecked); ++ } ++} +--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd ++++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd +@@ -1444,11 +1444,12 @@ Your Google account may have other forms + + If you change the file extension, the file may open in a different application and potentially be a hazard to your device. + +- +- + + Install + ++ ++ Remove ++ + + + +--- /dev/null ++++ b/chrome/android/java/res/layout/extension_uninstall_dialog.xml +@@ -0,0 +1,52 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +--- a/chrome/android/BUILD.gn ++++ b/chrome/android/BUILD.gn +@@ -3237,6 +3237,7 @@ generate_jni("chrome_jni_headers") { + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java", + "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesSite.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", + "java/src/org/chromium/chrome/browser/feature_engagement/TrackerFactory.java", + "java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java", + "java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java", +--- a/chrome/android/chrome_java_sources.gni ++++ b/chrome/android/chrome_java_sources.gni +@@ -685,6 +685,8 @@ chrome_java_sources = [ + "java/src/org/chromium/chrome/browser/explore_sites/StableScrollLayoutManager.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallDialogViewBridge.java", + "java/src/org/chromium/chrome/browser/extensions/ExtensionInstallCustomScrollView.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallDialogBridge.java", ++ "java/src/org/chromium/chrome/browser/extensions/ExtensionUninstallCustomScrollView.java", + "java/src/org/chromium/chrome/browser/externalauth/ExternalAuthUtils.java", + "java/src/org/chromium/chrome/browser/externalauth/UserRecoverableErrorHandler.java", + "java/src/org/chromium/chrome/browser/externalauth/VerifiedHandler.java", +--- /dev/null ++++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_android.cc +@@ -0,0 +1,190 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#include ++ ++#include "chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_android.h" ++ ++#include "base/android/jni_android.h" ++#include "base/android/jni_string.h" ++#include "base/compiler_specific.h" ++#include "base/macros.h" ++#include "base/strings/string16.h" ++#include "base/strings/string_util.h" ++#include "base/strings/utf_string_conversions.h" ++#include "build/build_config.h" ++#include "chrome/android/chrome_jni_headers/ExtensionUninstallDialogBridge_jni.h" ++#include "chrome/browser/extensions/extension_uninstall_dialog.h" ++#include "chrome/browser/ui/browser_dialogs.h" ++#include "chrome/browser/ui/ui_features.h" ++#include "chrome/grit/generated_resources.h" ++#include "components/strings/grit/components_strings.h" ++#include "extensions/common/constants.h" ++#include "extensions/common/extension.h" ++#include "ui/base/l10n/l10n_util.h" ++#include "ui/android/window_android.h" ++ ++ExtensionUninstallDialogViews::ExtensionUninstallDialogViews( ++ Profile* profile, ++ gfx::NativeWindow parent, ++ extensions::ExtensionUninstallDialog::Delegate* delegate) ++ : extensions::ExtensionUninstallDialog(profile, parent, delegate) {} ++ ++ExtensionUninstallDialogViews::~ExtensionUninstallDialogViews() { ++ // Close the widget (the views framework will delete view_). ++ if (view_) { ++ view_->DialogDestroyed(); ++ } ++} ++ ++void ExtensionUninstallDialogViews::Show() { ++ view_ = new ExtensionUninstallDialogDelegateView( ++ this, extension(), triggering_extension()); ++ view_->Show(parent()); ++} ++ ++void ExtensionUninstallDialogViews::DialogDelegateDestroyed() { ++ // Checks view_ to ensure OnDialogClosed() will not be called twice. ++ if (view_) { ++ view_ = nullptr; ++ OnDialogClosed(CLOSE_ACTION_CANCELED); ++ } ++} ++ ++void ExtensionUninstallDialogViews::DialogAccepted(bool checkbox_checked) { ++ // The widget gets destroyed when the dialog is accepted. ++ DCHECK(view_); ++ view_->DialogDestroyed(); ++ view_ = nullptr; ++ ++ OnDialogClosed(checkbox_checked ? CLOSE_ACTION_UNINSTALL_AND_CHECKBOX_CHECKED ++ : CLOSE_ACTION_UNINSTALL); ++} ++ ++void ExtensionUninstallDialogViews::DialogCanceled() { ++ // The widget gets destroyed when the dialog is canceled. ++ DCHECK(view_); ++ view_->DialogDestroyed(); ++ view_ = nullptr; ++ OnDialogClosed(CLOSE_ACTION_CANCELED); ++} ++ ++ExtensionUninstallDialogDelegateView::ExtensionUninstallDialogDelegateView( ++ ExtensionUninstallDialogViews* dialog_view, ++ const extensions::Extension* extension, ++ const extensions::Extension* triggering_extension) ++ : dialog_(dialog_view), ++ extension_name_(base::UTF8ToUTF16(extension->name())), ++ checkbox_(false) { ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ java_obj_.Reset(env, Java_ExtensionUninstallDialogBridge_create( ++ env, reinterpret_cast(this)).obj()); ++ DCHECK(!java_obj_.is_null()); ++ ++ if (triggering_extension) { ++ heading_ = l10n_util::GetStringFUTF16( ++ IDS_EXTENSION_PROMPT_UNINSTALL_TRIGGERED_BY_EXTENSION, ++ base::UTF8ToUTF16(triggering_extension->name())); ++ } ++ ++ if (dialog_->ShouldShowCheckbox()) { ++ checkbox_ = true; ++ } ++ ++ chrome::RecordDialogCreation(chrome::DialogIdentifier::EXTENSION_UNINSTALL); ++} ++ ++ExtensionUninstallDialogDelegateView::~ExtensionUninstallDialogDelegateView() { ++ // If we're here, 2 things could have happened. Either the user closed the ++ // dialog nicely and one of the installed/canceled methods has been called ++ // (in which case dialog_ will be null), *or* neither of them have been ++ // called and we are being forced closed by our parent widget. In this case, ++ // we need to make sure to notify dialog_ not to call us again, since we're ++ // about to be freed by the Widget framework. ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ Java_ExtensionUninstallDialogBridge_destroy(env, java_obj_); ++ if (dialog_) ++ dialog_->DialogDelegateDestroyed(); ++} ++ ++const char* ExtensionUninstallDialogDelegateView::GetClassName() const { ++ return "ExtensionUninstallDialogDelegateView"; ++} ++ ++void ExtensionUninstallDialogDelegateView::Accept( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj, ++ const jboolean jcheckbox_checked) { ++ bool checkbox_checked = ++ static_cast(jcheckbox_checked != JNI_FALSE); ++ if (dialog_) ++ dialog_->DialogAccepted(checkbox_ && checkbox_checked); ++} ++ ++void ExtensionUninstallDialogDelegateView::Cancel( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj) { ++ if (dialog_) ++ dialog_->DialogCanceled(); ++} ++ ++void ExtensionUninstallDialogDelegateView::Show( ++ gfx::NativeWindow native_window) const { ++ if (!native_window) { ++ LOG(ERROR) << "extension_uninstall_dialog_view_android.cc: Failed to get native window"; ++ return; ++ } ++ ++ // Call java method to create the dialog ++ base::string16 checkbox_label = base::UTF8ToUTF16(""); ++ if (dialog_->ShouldShowCheckbox()) { ++ checkbox_label = dialog_->GetCheckboxLabel(); ++ } ++ JNIEnv* env = base::android::AttachCurrentThread(); ++ Java_ExtensionUninstallDialogBridge_show( ++ env, java_obj_, ++ native_window->GetJavaObject(), ++ base::android::ConvertUTF16ToJavaString(env, extension_name_), ++ base::android::ConvertUTF16ToJavaString(env, GetWindowTitle()), ++ base::android::ConvertUTF16ToJavaString(env, heading_), ++ static_cast(checkbox_), ++ base::android::ConvertUTF16ToJavaString(env, checkbox_label) ++ ); ++} ++ ++base::string16 ExtensionUninstallDialogDelegateView::GetWindowTitle() const { ++ return l10n_util::GetStringFUTF16(IDS_EXTENSION_PROMPT_UNINSTALL_TITLE, ++ extension_name_); ++} ++ ++// static ++std::unique_ptr ++extensions::ExtensionUninstallDialog::Create(Profile* profile, ++ gfx::NativeWindow parent, ++ Delegate* delegate) { ++ return CreateViews(profile, parent, delegate); ++} ++ ++// static ++std::unique_ptr ++extensions::ExtensionUninstallDialog::CreateViews(Profile* profile, ++ gfx::NativeWindow parent, ++ Delegate* delegate) { ++ return std::make_unique(profile, parent, ++ delegate); ++} +--- a/chrome/browser/ui/BUILD.gn ++++ b/chrome/browser/ui/BUILD.gn +@@ -3512,7 +3512,8 @@ static_library("ui") { + "views/extensions/extension_keybinding_registry_views.h", + "views/extensions/extension_permissions_view.cc", + "views/extensions/extension_permissions_view.h", +- "views/extensions/extension_uninstall_dialog_view.cc", ++ "views/extensions/extension_uninstall_dialog_view_android.cc", ++ "views/extensions/extension_uninstall_dialog_view_android.h", + "views/extensions/extensions_menu_button.cc", + "views/extensions/extensions_menu_button.h", + "views/extensions/extensions_menu_item_view.cc", +--- /dev/null ++++ b/chrome/browser/ui/views/extensions/extension_uninstall_dialog_view_android.h +@@ -0,0 +1,101 @@ ++// Copyright 2021 The Ungoogled Chromium Authors. All rights reserved. ++// ++// This file is part of Ungoogled Chromium Android. ++// ++// Ungoogled Chromium Android is free software: you can redistribute it ++// and/or modify it under the terms of the GNU General Public License as ++// published by the Free Software Foundation, either version 3 of the ++// License, or any later version. ++// ++// Ungoogled Chromium Android is distributed in the hope that it will be ++// useful, but WITHOUT ANY WARRANTY; without even the implied warranty ++// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with Ungoogled Chromium Android. If not, ++// see . ++ ++#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_UNINSTALL_DIALOG_VIEW_ANDROID_H_ ++#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_UNINSTALL_DIALOG_VIEW_ANDROID_H_ ++ ++#include "base/android/jni_android.h" ++#include "base/android/scoped_java_ref.h" ++#include "base/macros.h" ++#include "base/strings/string16.h" ++#include "chrome/browser/extensions/extension_uninstall_dialog.h" ++#include "extensions/common/constants.h" ++#include "extensions/common/extension.h" ++#include "ui/gfx/native_widget_types.h" ++ ++namespace { ++class ExtensionUninstallDialogDelegateView; ++ ++// Views implementation of the uninstall dialog. ++class ExtensionUninstallDialogViews ++ : public extensions::ExtensionUninstallDialog { ++ public: ++ ExtensionUninstallDialogViews( ++ Profile* profile, ++ gfx::NativeWindow parent, ++ extensions::ExtensionUninstallDialog::Delegate* delegate); ++ ~ExtensionUninstallDialogViews() override; ++ ++ // Called when the ExtensionUninstallDialogDelegate has been destroyed to make ++ // sure we invalidate pointers. This object will also be freed. ++ void DialogDelegateDestroyed(); ++ ++ // Forwards the accept and cancels to the delegate. ++ void DialogAccepted(bool checkbox_checked); ++ void DialogCanceled(); ++ ++ private: ++ void Show() override; ++ ++ ExtensionUninstallDialogDelegateView* view_ = nullptr; ++ ++ DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogViews); ++}; ++ ++// The dialog's view, owned by the views framework. ++class ExtensionUninstallDialogDelegateView { ++ public: ++ // Constructor for view component of dialog. triggering_extension may be null ++ // if the uninstall dialog was manually triggered (from chrome://extensions). ++ ExtensionUninstallDialogDelegateView( ++ ExtensionUninstallDialogViews* dialog_view, ++ const extensions::Extension* extension, ++ const extensions::Extension* triggering_extension); ++ ~ExtensionUninstallDialogDelegateView(); ++ ++ void Accept( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj, ++ const jboolean jcheckbox_checked); ++ void Cancel( ++ JNIEnv* env, ++ const base::android::JavaParamRef& obj); ++ void Show(gfx::NativeWindow native_window) const; ++ // Called when the ExtensionUninstallDialog has been destroyed to make sure ++ // we invalidate pointers. ++ void DialogDestroyed() { dialog_ = NULL; } ++ ++ private: ++ // views::View: ++ const char* GetClassName() const; ++ ++ // views::DialogDelegateView: ++ base::string16 GetWindowTitle() const; ++ ++ ExtensionUninstallDialogViews* dialog_; ++ const base::string16 extension_name_; ++ bool checkbox_; ++ base::string16 heading_; ++ ++ base::android::ScopedJavaGlobalRef java_obj_; ++ ++ DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogDelegateView); ++}; ++} ++ ++#endif // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_UNINSTALL_DIALOG_VIEW_ANDROID_H_ +--- a/chrome/android/chrome_java_resources.gni ++++ b/chrome/android/chrome_java_resources.gni +@@ -865,6 +865,7 @@ chrome_java_resources = [ + "java/res/layout/explore_sites_section.xml", + "java/res/layout/explore_sites_tile_view.xml", + "java/res/layout/extension_install_dialog.xml", ++ "java/res/layout/extension_uninstall_dialog.xml", + "java/res/layout/fake_search_box_layout.xml", + "java/res/layout/find_in_page.xml", + "java/res/layout/find_toolbar.xml", diff --git a/patches/Extensions/open-setting-in-new-tab.patch b/patches/Extensions/open-setting-in-new-tab.patch new file mode 100644 index 0000000..4ffa330 --- /dev/null +++ b/patches/Extensions/open-setting-in-new-tab.patch @@ -0,0 +1,146 @@ +From: Wengling Chen +Date: Sat, 06 Jun 2020 19:24:20 -0400 +Subject: make settings of extensions open in new tab + + +--- + chrome/browser/extensions/api/developer_private/developer_private_api.cc | 4 + chrome/browser/extensions/extension_context_menu_model.cc | 2 + chrome/browser/extensions/extension_tab_util.cc | 42 ++++------ + chrome/browser/extensions/extension_tab_util.h | 2 + chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc | 4 + chrome/browser/ui/webui/settings/people_handler.cc | 1 + 6 files changed, 23 insertions(+), 32 deletions(-) + +--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc ++++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc +@@ -1931,12 +1931,14 @@ ExtensionFunction::ResponseAction Develo + return RespondNow(Error(kNoOptionsPageForExtensionError)); + + content::WebContents* web_contents = GetSenderWebContents(); ++ + if (!web_contents) + return RespondNow(Error(kCouldNotFindWebContentsError)); + + ExtensionTabUtil::OpenOptionsPage( + extension, +- chrome::FindBrowserWithWebContents(web_contents)); ++ web_contents); ++ + return RespondNow(NoArguments()); + } + +--- a/chrome/browser/extensions/extension_tab_util.cc ++++ b/chrome/browser/extensions/extension_tab_util.cc +@@ -885,16 +885,17 @@ bool ExtensionTabUtil::OpenOptionsPageFr + // mode extension, this API could only be called from a regular profile, since + // that's the only place it's running. + DCHECK(!profile->IsOffTheRecord() || IncognitoInfo::IsSplitMode(extension)); +- Browser* browser = chrome::FindBrowserWithProfile(profile); +- if (!browser) +- browser = Browser::Create(Browser::CreateParams(profile, true)); +- if (!browser) +- return false; +- return extensions::ExtensionTabUtil::OpenOptionsPage(extension, browser); ++// Browser* browser = chrome::FindBrowserWithProfile(profile); ++// if (!browser) ++// browser = Browser::Create(Browser::CreateParams(profile, true)); ++// if (!browser) ++// return false; ++ return extensions::ExtensionTabUtil::OpenOptionsPage(extension, ++ TabModelList::GetCurrentTabModel()->GetActiveWebContents()); + } + + bool ExtensionTabUtil::OpenOptionsPage(const Extension* extension, +- Browser* browser) { ++ content::WebContents* web_contents) { + if (!OptionsPageInfo::HasOptionsPage(extension)) + return false; + +@@ -902,14 +903,9 @@ bool ExtensionTabUtil::OpenOptionsPage(c + // running in split mode, because it won't be able to save settings from OTR. + // This version of OpenOptionsPage() can be called from an OTR window via e.g. + // the action menu, since that's not initiated by the extension. +- std::unique_ptr displayer; +- if (browser->profile()->IsOffTheRecord() && +- !IncognitoInfo::IsSplitMode(extension)) { +- displayer.reset(new chrome::ScopedTabbedBrowserDisplayer( +- browser->profile()->GetOriginalProfile())); +- browser = displayer->browser(); +- } + ++ // Instead open in native browser, open a new tab through JNI bridge ++ // Incognito Mode not handled yet + GURL url_to_navigate; + bool open_in_tab = OptionsPageInfo::ShouldOpenInTab(extension); + if (open_in_tab) { +@@ -926,17 +922,13 @@ bool ExtensionTabUtil::OpenOptionsPage(c + url_to_navigate = url_to_navigate.ReplaceComponents(replacements); + } + +- NavigateParams params( +- GetSingletonTabNavigateParams(browser, url_to_navigate)); +- // We need to respect path differences because we don't want opening the +- // options page to close a page that might be open to extension content. +- // However, if the options page opens inside the chrome://extensions page, we +- // can override an existing page. +- // Note: ref behavior is to ignore. +- params.path_behavior = open_in_tab ? NavigateParams::RESPECT +- : NavigateParams::IGNORE_AND_NAVIGATE; +- params.url = url_to_navigate; +- ShowSingletonTabOverwritingNTP(browser, std::move(params)); ++ web_contents->OpenURL( ++ content::OpenURLParams( ++ url_to_navigate, content::Referrer(), ++ WindowOpenDisposition::NEW_FOREGROUND_TAB, ++ ui::PAGE_TRANSITION_LINK, false ++ )); ++ + return true; + } + +--- a/chrome/browser/extensions/extension_tab_util.h ++++ b/chrome/browser/extensions/extension_tab_util.h +@@ -243,7 +243,7 @@ class ExtensionTabUtil { + // Open the extension's options page. Returns true if an options page was + // successfully opened (though it may not necessarily *load*, e.g. if the + // URL does not exist). +- static bool OpenOptionsPage(const Extension* extension, Browser* browser); ++ static bool OpenOptionsPage(const Extension* extension, content::WebContents* web_contents); + + // Returns true if the given Browser can report tabs to extensions. + // Example of Browsers which don't support tabs include apps and devtools. +--- a/chrome/browser/extensions/extension_context_menu_model.cc ++++ b/chrome/browser/extensions/extension_context_menu_model.cc +@@ -345,7 +345,7 @@ void ExtensionContextMenuModel::ExecuteC + } + case OPTIONS: + DCHECK(OptionsPageInfo::HasOptionsPage(extension)); +- ExtensionTabUtil::OpenOptionsPage(extension, browser_); ++ ExtensionTabUtil::OpenOptionsPage(extension, GetActiveWebContents()); + break; + case TOGGLE_VISIBILITY: { + bool currently_visible = button_visibility_ == PINNED; +--- a/chrome/browser/ui/webui/settings/people_handler.cc ++++ b/chrome/browser/ui/webui/settings/people_handler.cc +@@ -704,7 +704,6 @@ void PeopleHandler::HandleSignout(const + } + + void PeopleHandler::HandlePauseSync(const base::ListValue* args) { +- DCHECK(AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_)); + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); + DCHECK(identity_manager->HasPrimaryAccount()); + +--- a/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc ++++ b/chrome/browser/guest_view/extension_options/chrome_extension_options_guest_delegate.cc +@@ -36,9 +36,7 @@ bool ChromeExtensionOptionsGuestDelegate + + content::WebContents* ChromeExtensionOptionsGuestDelegate::OpenURLInNewTab( + const content::OpenURLParams& params) { +- Browser* browser = chrome::FindBrowserWithWebContents( +- extension_options_guest()->embedder_web_contents()); +- return browser->OpenURL(params); ++ return extension_options_guest()->embedder_web_contents()->OpenURL(params); + } + + } // namespace extensions diff --git a/patches/Extensions/profile-extra-parts-init.patch b/patches/Extensions/profile-extra-parts-init.patch new file mode 100644 index 0000000..e2ea3cc --- /dev/null +++ b/patches/Extensions/profile-extra-parts-init.patch @@ -0,0 +1,21 @@ +From: Wengling Chen +Date: Sat, 23 Jan 2021 06:48:43 +0200 +Subject: make second pass/full init of profile extra parts happen + +--- + chrome/browser/chrome_content_browser_client.cc | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/chrome/browser/chrome_content_browser_client.cc ++++ b/chrome/browser/chrome_content_browser_client.cc +@@ -1368,10 +1368,6 @@ ChromeContentBrowserClient::CreateBrowse + #endif + + bool add_profiles_extra_parts = true; +-#if defined(OS_ANDROID) +- if (startup_data_.HasBuiltProfilePrefService()) +- add_profiles_extra_parts = false; +-#endif + if (add_profiles_extra_parts) + chrome::AddProfilesExtraParts(main_parts.get()); + diff --git a/patches/Extensions/tab-api-fix.patch b/patches/Extensions/tab-api-fix.patch new file mode 100644 index 0000000..3a507eb --- /dev/null +++ b/patches/Extensions/tab-api-fix.patch @@ -0,0 +1,2380 @@ +From: Wengling Chen +Date: Sat, 23 Jan 2021 06:48:43 +0200 +Subject: rewrite tab API with Android tab model + +--- + chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java | 8 + chrome/browser/extensions/api/tabs/tabs_api.cc | 347 ++++------ + chrome/browser/extensions/api/tabs/tabs_api.h | 1 + chrome/browser/extensions/api/tabs/tabs_event_router.cc | 252 +++++-- + chrome/browser/extensions/api/tabs/tabs_event_router.h | 61 + + chrome/browser/extensions/api/web_navigation/web_navigation_api.cc | 5 + chrome/browser/extensions/extension_tab_util.cc | 265 ++++--- + chrome/browser/extensions/extension_tab_util.h | 11 + chrome/browser/ui/android/tab_model/tab_model.cc | 8 + chrome/browser/ui/android/tab_model/tab_model.h | 2 + chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc | 9 + chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h | 1 + chrome/browser/ui/android/tab_model/tab_model_list.cc | 10 + chrome/browser/ui/android/tab_model/tab_model_list.h | 1 + chrome/browser/ui/android/tab_model/tab_model_observer.cc | 4 + chrome/browser/ui/android/tab_model/tab_model_observer.h | 5 + chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.cc | 23 + chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.h | 4 + chrome/browser/ui/browser_navigator.cc | 108 +-- + content/public/browser/web_contents_user_data.h | 2 + 20 files changed, 701 insertions(+), 426 deletions(-) + +--- a/chrome/browser/extensions/extension_tab_util.cc ++++ b/chrome/browser/extensions/extension_tab_util.cc +@@ -15,16 +15,22 @@ + #include "base/strings/string_number_conversions.h" + #include "base/strings/stringprintf.h" + #include "base/strings/utf_string_conversions.h" ++#include "chrome/browser/android/tab_android.h" + #include "chrome/browser/browser_process.h" + #include "chrome/browser/extensions/api/tab_groups/tab_groups_util.h" + #include "chrome/browser/extensions/api/tabs/tabs_api.h" + #include "chrome/browser/extensions/api/tabs/tabs_constants.h" ++#include "chrome/browser/extensions/api/tabs/tabs_event_router.h" ++#include "chrome/browser/extensions/api/tabs/tabs_windows_api.h" + #include "chrome/browser/extensions/browser_extension_window_controller.h" + #include "chrome/browser/extensions/chrome_extension_function_details.h" + #include "chrome/browser/extensions/tab_helper.h" + #include "chrome/browser/platform_util.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_finder.h" + #include "chrome/browser/ui/browser_navigator_params.h" +@@ -108,9 +114,9 @@ Browser* CreateBrowser(Profile* profile, + // take care of setting the id to TAB_ID_NONE if necessary (for + // example with devtools). + int GetTabIdForExtensions(const WebContents* web_contents) { +- Browser* browser = chrome::FindBrowserWithWebContents(web_contents); +- if (browser && !ExtensionTabUtil::BrowserSupportsTabs(browser)) +- return -1; ++// Browser* browser = chrome::FindBrowserWithWebContents(web_contents); ++// if (browser && !ExtensionTabUtil::BrowserSupportsTabs(browser)) ++// return -1; + return sessions::SessionTabHelper::IdForTab(web_contents).id(); + } + +@@ -196,24 +202,24 @@ base::DictionaryValue* ExtensionTabUtil: + window_id = *params.window_id; + + Browser* browser = GetBrowserFromWindowID(chrome_details, window_id, error); +- if (!browser) { +- if (!params.create_browser_if_needed) { +- return nullptr; +- } +- browser = CreateBrowser(profile, window_id, user_gesture, error); +- if (!browser) +- return nullptr; +- } ++// if (!browser) { ++// if (!params.create_browser_if_needed) { ++// return nullptr; ++// } ++// browser = CreateBrowser(profile, window_id, user_gesture, error); ++// if (!browser) ++// return nullptr; ++// } + + // Ensure the selected browser is normal. +- if (!browser->is_type_normal() && browser->IsAttemptingToCloseBrowser()) +- browser = chrome::FindTabbedBrowser( +- profile, function->include_incognito_information()); +- if (!browser || !browser->window()) { +- if (error) +- *error = tabs_constants::kNoCurrentWindowError; +- return nullptr; +- } ++// if (!browser->is_type_normal() && browser->IsAttemptingToCloseBrowser()) ++// browser = chrome::FindTabbedBrowser( ++// profile, function->include_incognito_information()); ++// if (!browser || !browser->window()) { ++// if (error) ++// *error = tabs_constants::kNoCurrentWindowError; ++// return nullptr; ++// } + + // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that + // represents the active tab. +@@ -264,20 +270,20 @@ base::DictionaryValue* ExtensionTabUtil: + if (url.SchemeIs(kExtensionScheme) && + (!function->extension() || + !IncognitoInfo::IsSplitMode(function->extension())) && +- browser->profile()->IsOffTheRecord()) { +- Profile* profile = browser->profile()->GetOriginalProfile(); ++ ProfileManager::GetActiveUserProfile()->IsOffTheRecord()) { ++ Profile* profile = ProfileManager::GetActiveUserProfile()->GetOriginalProfile(); + +- browser = chrome::FindTabbedBrowser(profile, false); +- if (!browser) { +- Browser::CreateParams params = +- Browser::CreateParams(Browser::TYPE_NORMAL, profile, user_gesture); +- browser = Browser::Create(params); +- if (!browser) { +- *error = tabs_constants::kBrowserWindowNotAllowed; +- return nullptr; +- } +- browser->window()->Show(); +- } ++// browser = chrome::FindTabbedBrowser(profile, false); ++// if (!browser) { ++// Browser::CreateParams params = ++// Browser::CreateParams(Browser::TYPE_NORMAL, profile, user_gesture); ++// browser = Browser::Create(params); ++// if (!browser) { ++// *error = tabs_constants::kBrowserWindowNotAllowed; ++// return nullptr; ++// } ++// browser->window()->Show(); ++// } + } + + if (opener_browser && browser != opener_browser) { +@@ -292,8 +298,9 @@ base::DictionaryValue* ExtensionTabUtil: + int index = -1; + if (params.index.get()) + index = *params.index; +- index = base::ClampToRange(index, -1, browser->tab_strip_model()->count()); ++ index = base::ClampToRange(index, -1, TabModelList::GetCurrentTabModel()->GetTabCount()); + ++ // Not applicable + int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; + add_types |= TabStripModel::ADD_FORCE_INDEX; + if (pinned) +@@ -317,15 +324,15 @@ base::DictionaryValue* ExtensionTabUtil: + + // The tab may have been created in a different window, so make sure we look + // at the right tab strip. +- TabStripModel* tab_strip = navigate_params.browser->tab_strip_model(); +- int new_index = tab_strip->GetIndexOfWebContents( +- navigate_params.navigated_or_inserted_contents); +- if (opener) { +- // Only set the opener if the opener tab is in the same tab strip as the +- // new tab. +- if (tab_strip->GetIndexOfWebContents(opener) != TabStripModel::kNoTab) +- tab_strip->SetOpenerOfWebContentsAt(new_index, opener); +- } ++// TabModel* tab_strip = navigate_params.browser->tab_strip_model(); ++// int new_index = tab_strip->GetIndexOfWebContents( ++// navigate_params.navigated_or_inserted_contents); ++// if (opener) { ++// // Only set the opener if the opener tab is in the same tab strip as the ++// // new tab. ++// if (tab_strip->GetIndexOfWebContents(opener) != TabStripModel::kNoTab) ++// tab_strip->SetOpenerOfWebContentsAt(new_index, opener); ++// } + + if (active) + navigate_params.navigated_or_inserted_contents->SetInitialFocus(); +@@ -336,9 +343,12 @@ base::DictionaryValue* ExtensionTabUtil: + navigate_params.navigated_or_inserted_contents); + + // Return data about the newly created tab. ++ // Always launch from same model. ++ // TODO: Maybe need fix + return ExtensionTabUtil::CreateTabObject( + navigate_params.navigated_or_inserted_contents, scrub_tab_behavior, +- function->extension(), tab_strip, new_index) ++ function->extension(), TabModelList::GetCurrentTabModel(), ++ TabModelList::GetCurrentTabModel()->GetTabCount()) + ->ToValue() + .release(); + } +@@ -386,14 +396,14 @@ int ExtensionTabUtil::GetWindowIdOfTab(c + + // static + std::string ExtensionTabUtil::GetBrowserWindowTypeText(const Browser& browser) { +- if (browser.is_type_devtools()) +- return tabs_constants::kWindowTypeValueDevTools; ++// if (browser.is_type_devtools()) ++// return tabs_constants::kWindowTypeValueDevTools; + // TODO(crbug.com/990158): We return 'popup' for both popup and app since + // chrome.windows.create({type: 'popup'}) uses + // Browser::CreateParams::CreateForApp. +- if (browser.is_type_popup() || browser.is_type_app() || +- browser.is_type_app_popup()) +- return tabs_constants::kWindowTypeValuePopup; ++// if (browser.is_type_popup() || browser.is_type_app() || ++// browser.is_type_app_popup()) ++// return tabs_constants::kWindowTypeValuePopup; + return tabs_constants::kWindowTypeValueNormal; + } + +@@ -402,27 +412,21 @@ std::unique_ptr Extensio + WebContents* contents, + ScrubTabBehavior scrub_tab_behavior, + const Extension* extension, +- TabStripModel* tab_strip, ++ TabModel* tab_strip, + int tab_index) { + if (!tab_strip) +- ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index); ++ ExtensionTabUtil::GetTabModel(contents, &tab_strip, &tab_index); + auto tab_object = std::make_unique(); + tab_object->id = std::make_unique(GetTabIdForExtensions(contents)); + tab_object->index = tab_index; + tab_object->window_id = GetWindowIdOfTab(contents); + tab_object->status = GetLoadingStatus(contents); +- tab_object->active = tab_strip && tab_index == tab_strip->active_index(); +- tab_object->selected = tab_strip && tab_index == tab_strip->active_index(); +- tab_object->highlighted = tab_strip && tab_strip->IsTabSelected(tab_index); +- tab_object->pinned = tab_strip && tab_strip->IsTabPinned(tab_index); ++ tab_object->active = tab_strip && tab_index == tab_strip->GetActiveIndex(); ++ tab_object->selected = tab_strip && tab_index == tab_strip->GetActiveIndex(); ++ tab_object->highlighted = tab_strip && tab_strip->GetActiveIndex(); ++ tab_object->pinned = false; + + tab_object->group_id = -1; +- if (tab_strip) { +- base::Optional group = +- tab_strip->GetTabGroupForTab(tab_index); +- if (group.has_value()) +- tab_object->group_id = tab_groups_util::GetGroupId(group.value()); +- } + + auto* audible_helper = RecentlyAudibleHelper::FromWebContents(contents); + bool audible = false; +@@ -452,7 +456,7 @@ std::unique_ptr Extensio + + tab_object->muted_info = CreateMutedInfo(contents); + tab_object->incognito = contents->GetBrowserContext()->IsOffTheRecord(); +- gfx::Size contents_size = contents->GetContainerBounds().size(); ++ gfx::Size contents_size = contents->GetSize(); + tab_object->width = std::make_unique(contents_size.width()); + tab_object->height = std::make_unique(contents_size.height()); + +@@ -472,13 +476,14 @@ std::unique_ptr Extensio + tab_object->fav_icon_url = + std::make_unique(visible_entry->GetFavicon().url.spec()); + } +- if (tab_strip) { +- WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); +- if (opener) { +- tab_object->opener_tab_id = +- std::make_unique(GetTabIdForExtensions(opener)); +- } +- } ++// Don't have this ++// if (tab_strip) { ++// WebContents* opener = tab_strip->GetOpenerOfWebContentsAt(tab_index); ++// if (opener) { ++// tab_object->opener_tab_id = ++// std::make_unique(GetTabIdForExtensions(opener)); ++// } ++// } + + ScrubTabForExtension(extension, contents, tab_object.get(), + scrub_tab_behavior); +@@ -490,9 +495,11 @@ std::unique_ptr Extensi + const Extension* extension, + Feature::Context context) { + std::unique_ptr tab_list(new base::ListValue()); +- TabStripModel* tab_strip = browser->tab_strip_model(); +- for (int i = 0; i < tab_strip->count(); ++i) { ++ TabModel* tab_strip = TabModelList::GetCurrentTabModel(); ++ for (int i = 0; i < tab_strip->GetTabCount(); ++i) { + WebContents* web_contents = tab_strip->GetWebContentsAt(i); ++ if (!web_contents) ++ continue; + ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = + ExtensionTabUtil::GetScrubTabBehavior(extension, context, web_contents); + tab_list->Append(CreateTabObject(web_contents, scrub_tab_behavior, +@@ -512,44 +519,57 @@ ExtensionTabUtil::CreateWindowValueForEx + Feature::Context context) { + auto result = std::make_unique(); + +- result->SetInteger(tabs_constants::kIdKey, browser.session_id().id()); ++ // This assumes extension will always get focus of currently opening tab ++ // Get last selected tab. If none, return currently active tab ++ TabModel* tab_model = TabModelList::GetCurrentTabModel(); ++ TabAndroid* tab = tab_model->GetTabForId( ++ TabsWindowsAPI::Get(ProfileManager::GetActiveUserProfile()) ++ ->tabs_event_router()->GetLastTabId()); ++ if (!tab) ++ tab = tab_model->GetTabAt(tab_model->GetActiveIndex()); ++ // If still nullptr, return nullptr ++ result->SetInteger(tabs_constants::kIdKey, sessions::SessionTabHelper::IdForWindowContainingTab( ++// TabModelList::GetCurrentTabModel()->GetActiveWebContents() ++ tab ? tab->web_contents() : nullptr ++ ).id()); + result->SetString(tabs_constants::kWindowTypeKey, + GetBrowserWindowTypeText(browser)); +- ui::BaseWindow* window = browser.window(); +- result->SetBoolean(tabs_constants::kFocusedKey, window->IsActive()); +- const Profile* profile = browser.profile(); ++// ui::BaseWindow* window = browser.window(); ++ result->SetBoolean(tabs_constants::kFocusedKey, true); ++ const Profile* profile = ProfileManager::GetActiveUserProfile(); + result->SetBoolean(tabs_constants::kIncognitoKey, profile->IsOffTheRecord()); + result->SetBoolean( + tabs_constants::kAlwaysOnTopKey, +- window->GetZOrderLevel() == ui::ZOrderLevel::kFloatingWindow); ++ false); + + std::string window_state; +- if (window->IsMinimized()) { ++ if (false) { + window_state = tabs_constants::kShowStateValueMinimized; +- } else if (window->IsFullscreen()) { ++ } else if (false) { + window_state = tabs_constants::kShowStateValueFullscreen; +- if (platform_util::IsBrowserLockedFullscreen(&browser)) ++ if (false) + window_state = tabs_constants::kShowStateValueLockedFullscreen; +- } else if (window->IsMaximized()) { ++ } else if (false) { + window_state = tabs_constants::kShowStateValueMaximized; + } else { + window_state = tabs_constants::kShowStateValueNormal; + } + result->SetString(tabs_constants::kShowStateKey, window_state); + +- gfx::Rect bounds; +- if (window->IsMinimized()) +- bounds = window->GetRestoredBounds(); +- else +- bounds = window->GetBounds(); +- result->SetInteger(tabs_constants::kLeftKey, bounds.x()); +- result->SetInteger(tabs_constants::kTopKey, bounds.y()); +- result->SetInteger(tabs_constants::kWidthKey, bounds.width()); +- result->SetInteger(tabs_constants::kHeightKey, bounds.height()); ++// gfx::Rect bounds; ++// if (window->IsMinimized()) ++// bounds = window->GetRestoredBounds(); ++// else ++// bounds = window->GetBounds(); ++ // TODO: Return fixed window size. May need fix ++ result->SetInteger(tabs_constants::kLeftKey, 0); ++ result->SetInteger(tabs_constants::kTopKey, 0); ++ result->SetInteger(tabs_constants::kWidthKey, 800); ++ result->SetInteger(tabs_constants::kHeightKey, 600); + + if (populate_tab_behavior == kPopulateTabs) + result->Set(tabs_constants::kTabsKey, +- CreateTabList(&browser, extension, context)); ++ CreateTabList(nullptr, extension, context)); + + return result; + } +@@ -650,20 +670,29 @@ void ExtensionTabUtil::ScrubTabForExtens + } + + // static +-bool ExtensionTabUtil::GetTabStripModel(const WebContents* web_contents, +- TabStripModel** tab_strip_model, ++bool ExtensionTabUtil::GetTabModel(const WebContents* web_contents, ++ TabModel** tab_model, + int* tab_index) { + DCHECK(web_contents); +- DCHECK(tab_strip_model); ++ DCHECK(tab_model); + DCHECK(tab_index); + +- for (auto* browser : *BrowserList::GetInstance()) { +- TabStripModel* tab_strip = browser->tab_strip_model(); +- int index = tab_strip->GetIndexOfWebContents(web_contents); +- if (index != -1) { +- *tab_strip_model = tab_strip; +- *tab_index = index; +- return true; ++ for (size_t i = 0; i < TabModelList::size(); ++i) { ++ TabModel* tab_model_it = TabModelList::get(i); ++ if (tab_model_it->IsActiveModel()) { ++ int index = -1; ++ for (int i = 0; i < tab_model_it->GetTabCount(); i++) { ++ if (web_contents == tab_model_it->GetWebContentsAt(i)) { ++ index = i; ++ break; ++ } ++ } ++ if (index != -1) { ++ if (tab_model) ++ *tab_model = tab_model_it; ++ *tab_index = index; ++ return true; ++ } + } + } + +@@ -673,10 +702,9 @@ bool ExtensionTabUtil::GetTabStripModel( + bool ExtensionTabUtil::GetDefaultTab(Browser* browser, + WebContents** contents, + int* tab_id) { +- DCHECK(browser); + DCHECK(contents); + +- *contents = browser->tab_strip_model()->GetActiveWebContents(); ++ *contents = TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + if (*contents) { + if (tab_id) + *tab_id = GetTabId(*contents); +@@ -691,7 +719,7 @@ bool ExtensionTabUtil::GetTabById(int ta + content::BrowserContext* browser_context, + bool include_incognito, + Browser** browser, +- TabStripModel** tab_strip, ++ TabModel** tab_strip, + WebContents** contents, + int* tab_index) { + if (tab_id == api::tabs::TAB_ID_NONE) +@@ -701,22 +729,22 @@ bool ExtensionTabUtil::GetTabById(int ta + include_incognito && profile->HasPrimaryOTRProfile() + ? profile->GetPrimaryOTRProfile() + : nullptr; +- for (auto* target_browser : *BrowserList::GetInstance()) { +- if (target_browser->profile() == profile || +- target_browser->profile() == incognito_profile) { +- TabStripModel* target_tab_strip = target_browser->tab_strip_model(); +- for (int i = 0; i < target_tab_strip->count(); ++i) { +- WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); ++ // TODO: Profile is not checked ++ for (int i = 0; i < TabModelList::size(); ++i) { ++ if (TabModelList::get(i)->IsActiveModel()) { ++ TabModel* tab_model = TabModelList::get(i); ++ for (int j = 0; j < tab_model->GetTabCount(); ++j) { ++ WebContents* target_contents = tab_model->GetWebContentsAt(j); + if (sessions::SessionTabHelper::IdForTab(target_contents).id() == +- tab_id) { ++ tab_id) { + if (browser) +- *browser = target_browser; ++ *browser = nullptr; + if (tab_strip) +- *tab_strip = target_tab_strip; ++ *tab_strip = tab_model; + if (contents) + *contents = target_contents; + if (tab_index) +- *tab_index = i; ++ *tab_index = j; + return true; + } + } +@@ -746,14 +774,12 @@ ExtensionTabUtil::GetAllActiveWebContent + include_incognito && profile->HasPrimaryOTRProfile() + ? profile->GetPrimaryOTRProfile() + : nullptr; +- for (auto* target_browser : *BrowserList::GetInstance()) { +- if (target_browser->profile() == profile || +- target_browser->profile() == incognito_profile) { +- TabStripModel* target_tab_strip = target_browser->tab_strip_model(); ++ if (ProfileManager::GetActiveUserProfile() == profile || ++ ProfileManager::GetActiveUserProfile() == incognito_profile) { ++ TabModel* target_tab_strip = TabModelList::GetCurrentTabModel(); + + active_contents.push_back(target_tab_strip->GetActiveWebContents()); + } +- } + + return active_contents; + } +@@ -943,8 +969,9 @@ api::tabs::TabStatus ExtensionTabUtil::G + return api::tabs::TAB_STATUS_LOADING; + + // Anything that isn't backed by a process is considered unloaded. +- if (!HasValidMainFrameProcess(contents)) +- return api::tabs::TAB_STATUS_UNLOADED; ++ // Doesn't apply on Android ++// if (!HasValidMainFrameProcess(contents)) ++// return api::tabs::TAB_STATUS_UNLOADED; + + // Otherwise its considered loaded. + return api::tabs::TAB_STATUS_COMPLETE; +--- a/chrome/browser/extensions/extension_tab_util.h ++++ b/chrome/browser/extensions/extension_tab_util.h +@@ -17,6 +17,7 @@ + class Browser; + class ChromeExtensionFunctionDetails; + class GURL; ++class TabModel; + class TabStripModel; + class ExtensionFunction; + +@@ -123,7 +124,7 @@ class ExtensionTabUtil { + content::WebContents* web_contents, + ScrubTabBehavior scrub_tab_behavior, + const Extension* extension, +- TabStripModel* tab_strip, ++ TabModel* tab_strip, + int tab_index); + + // Creates a DictionaryValue representing the window for the given |browser|, +@@ -167,9 +168,9 @@ class ExtensionTabUtil { + api::tabs::Tab* tab, + ScrubTabBehavior scrub_tab_behavior); + +- // Gets the |tab_strip_model| and |tab_index| for the given |web_contents|. +- static bool GetTabStripModel(const content::WebContents* web_contents, +- TabStripModel** tab_strip_model, ++ // Gets the |tab_model| and |tab_index| for the given |web_contents|. ++ static bool GetTabModel(const content::WebContents* web_contents, ++ TabModel** tab_model, + int* tab_index); + static bool GetDefaultTab(Browser* browser, + content::WebContents** contents, +@@ -180,7 +181,7 @@ class ExtensionTabUtil { + content::BrowserContext* browser_context, + bool include_incognito, + Browser** browser, +- TabStripModel** tab_strip, ++ TabModel** tab_strip, + content::WebContents** contents, + int* tab_index); + static bool GetTabById(int tab_id, +--- a/chrome/browser/ui/android/tab_model/tab_model_list.cc ++++ b/chrome/browser/ui/android/tab_model/tab_model_list.cc +@@ -107,6 +107,16 @@ TabModel* TabModelList::FindTabModelWith + return nullptr; + } + ++TabModel* TabModelList::GetCurrentTabModel() { ++ for (size_t i = 0; i < TabModelList::size(); ++i) { ++ TabModel* tab_model = TabModelList::get(i); ++ if (tab_model->IsActiveModel()) ++ return tab_model; ++ } ++ ++ return nullptr; ++} ++ + bool TabModelList::IsOffTheRecordSessionActive() { + // TODO(https://crbug.com/1023759): This function should return true for + // incognito CCTs. +--- a/chrome/browser/ui/android/tab_model/tab_model_list.h ++++ b/chrome/browser/ui/android/tab_model/tab_model_list.h +@@ -42,6 +42,7 @@ class TabModelList { + content::WebContents* web_contents); + static TabModel* GetTabModelForTabAndroid(TabAndroid* tab_android); + static TabModel* FindTabModelWithId(SessionID desired_id); ++ static TabModel* GetCurrentTabModel(); + static bool IsOffTheRecordSessionActive(); + + static const_iterator begin(); +--- a/chrome/browser/extensions/api/tabs/tabs_api.cc ++++ b/chrome/browser/extensions/api/tabs/tabs_api.cc +@@ -43,10 +43,13 @@ + #include "chrome/browser/platform_util.h" + #include "chrome/browser/prefs/incognito_mode_prefs.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" + #include "chrome/browser/resource_coordinator/tab_manager.h" + #include "chrome/browser/translate/chrome_translate_client.h" + #include "chrome/browser/ui/apps/chrome_app_delegate.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_commands.h" + #include "chrome/browser/ui/browser_finder.h" +@@ -174,7 +177,7 @@ bool GetTabById(int tab_id, + content::BrowserContext* context, + bool include_incognito, + Browser** browser, +- TabStripModel** tab_strip, ++ TabModel** tab_strip, + content::WebContents** contents, + int* tab_index, + std::string* error_message) { +@@ -206,11 +209,7 @@ content::WebContents* GetTabsAPIDefaultW + nullptr /* ignore TabStripModel* output */, &web_contents, + nullptr /* ignore int tab_index output */, error); + } else { +- Browser* browser = +- ChromeExtensionFunctionDetails(function).GetCurrentBrowser(); +- if (!browser) +- *error = tabs_constants::kNoCurrentWindowError; +- else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, nullptr)) ++ if (!ExtensionTabUtil::GetDefaultTab(nullptr, &web_contents, nullptr)) + *error = tabs_constants::kNoSelectedTabError; + } + return web_contents; +@@ -250,6 +249,7 @@ ui::WindowShowState ConvertToWindowShowS + + bool IsValidStateForWindowsCreateFunction( + const windows::Create::Params::CreateData* create_data) { ++ return false; + if (!create_data) + return true; + +@@ -282,7 +282,7 @@ std::unique_ptr CreateTa + WebContents* contents, + const Extension* extension, + Feature::Context context, +- TabStripModel* tab_strip, ++ TabModel* tab_strip, + int tab_index) { + ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = + ExtensionTabUtil::GetScrubTabBehavior(extension, context, contents); +@@ -300,7 +300,7 @@ int MoveTabToWindow(ExtensionFunction* f + int new_index, + std::string* error) { + Browser* source_browser = nullptr; +- TabStripModel* source_tab_strip = nullptr; ++ TabModel* source_tab_strip = nullptr; + int source_index = -1; + if (!GetTabById(tab_id, function->browser_context(), + function->include_incognito_information(), &source_browser, +@@ -308,42 +308,41 @@ int MoveTabToWindow(ExtensionFunction* f + return -1; + } + +- if (!target_browser->window()->IsTabStripEditable()) { ++ if (false) { + *error = tabs_constants::kTabStripNotEditableError; + return -1; + } + + // TODO(crbug.com/990158): Rather than calling is_type_normal(), should + // this call SupportsWindowFeature(Browser::FEATURE_TABSTRIP)? +- if (!target_browser->is_type_normal()) { ++ if (false) { + *error = tabs_constants::kCanOnlyMoveTabsWithinNormalWindowsError; + return -1; + } + +- if (target_browser->profile() != source_browser->profile()) { ++ if (false) { + *error = tabs_constants::kCanOnlyMoveTabsWithinSameProfileError; + return -1; + } + +- std::unique_ptr web_contents = +- source_tab_strip->DetachWebContentsAt(source_index); +- if (!web_contents) { +- *error = ErrorUtils::FormatErrorMessage(tabs_constants::kTabNotFoundError, +- base::NumberToString(tab_id)); +- return -1; +- } ++// std::unique_ptr web_contents = ++// source_tab_strip->DetachWebContentsAt(source_index); ++// if (!web_contents) { ++// *error = ErrorUtils::FormatErrorMessage(tabs_constants::kTabNotFoundError, ++// base::NumberToString(tab_id)); ++// return -1; ++// } + +- TabStripModel* target_tab_strip = target_browser->tab_strip_model(); ++ TabModel* target_tab_strip = TabModelList::GetCurrentTabModel(); + + // Clamp move location to the last position. + // This is ">" because it can append to a new index position. + // -1 means set the move location to the last position. + int target_index = new_index; +- if (target_index > target_tab_strip->count() || target_index < 0) +- target_index = target_tab_strip->count(); ++ if (target_index > target_tab_strip->GetTabCount() || target_index < 0) ++ target_index = target_tab_strip->GetTabCount(); + +- return target_tab_strip->InsertWebContentsAt( +- target_index, std::move(web_contents), TabStripModel::ADD_NONE); ++ return target_index+1; + } + + } // namespace +@@ -443,8 +442,8 @@ ExtensionFunction::ResponseAction Window + break; // Use focused window. + } + } +- if (!browser) +- return RespondNow(Error(tabs_constants::kNoLastFocusedWindowError)); ++// if (!browser) ++// return RespondNow(Error(tabs_constants::kNoLastFocusedWindowError)); + + ExtensionTabUtil::PopulateTabBehavior populate_tab_behavior = + extractor.populate_tabs() ? ExtensionTabUtil::kPopulateTabs +@@ -532,7 +531,7 @@ ExtensionFunction::ResponseAction Window + windows::Create::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params); + std::vector urls; +- TabStripModel* source_tab_strip = NULL; ++ TabModel* source_tab_strip = NULL; + int tab_index = -1; + + windows::Create::Params::CreateData* create_data = params->create_data.get(); +@@ -581,10 +580,10 @@ ExtensionFunction::ResponseAction Window + return RespondNow(Error(std::move(error))); + } + +- if (!source_browser->window()->IsTabStripEditable()) ++ if (false) + return RespondNow(Error(tabs_constants::kTabStripNotEditableError)); + +- if (source_browser->profile() != window_profile) ++ if (false) + return RespondNow( + Error(tabs_constants::kCanOnlyMoveTabsWithinSameProfileError)); + } +@@ -693,16 +692,16 @@ ExtensionFunction::ResponseAction Window + WebContents* contents = NULL; + // Move the tab into the created window only if it's an empty popup or it's + // a tabbed window. +- if (window_type == Browser::TYPE_NORMAL || urls.empty()) { +- if (source_tab_strip) { +- std::unique_ptr detached_tab = +- source_tab_strip->DetachWebContentsAt(tab_index); +- contents = detached_tab.get(); +- TabStripModel* target_tab_strip = new_window->tab_strip_model(); +- target_tab_strip->InsertWebContentsAt( +- urls.size(), std::move(detached_tab), TabStripModel::ADD_NONE); +- } +- } ++// if (window_type == Browser::TYPE_NORMAL || urls.empty()) { ++// if (source_tab_strip) { ++// std::unique_ptr detached_tab = ++// source_tab_strip->DetachWebContentsAt(tab_index); ++// contents = detached_tab.get(); ++// TabStripModel* target_tab_strip = new_window->tab_strip_model(); ++// target_tab_strip->InsertWebContentsAt( ++// urls.size(), std::move(detached_tab), TabStripModel::ADD_NONE); ++// } ++// } + // Create a new tab if the created window is still empty. Don't create a new + // tab when it is intended to create an empty popup. + if (!contents && urls.empty() && window_type == Browser::TYPE_NORMAL) { +@@ -925,13 +924,13 @@ ExtensionFunction::ResponseAction TabsGe + if (!GetBrowserFromWindowID(this, window_id, &browser, &error)) + return RespondNow(Error(std::move(error))); + +- TabStripModel* tab_strip = browser->tab_strip_model(); ++ TabModel* tab_strip = TabModelList::GetCurrentTabModel(); + WebContents* contents = tab_strip->GetActiveWebContents(); + if (!contents) + return RespondNow(Error(tabs_constants::kNoSelectedTabError)); + return RespondNow(ArgumentList(tabs::Get::Results::Create( + *CreateTabObjectHelper(contents, extension(), source_context_type(), +- tab_strip, tab_strip->active_index())))); ++ tab_strip, tab_strip->GetActiveIndex())))); + } + + ExtensionFunction::ResponseAction TabsGetAllInWindowFunction::Run() { +@@ -999,51 +998,52 @@ ExtensionFunction::ResponseAction TabsQu + + std::unique_ptr result(new base::ListValue()); + Profile* profile = Profile::FromBrowserContext(browser_context()); +- Browser* last_active_browser = +- chrome::FindAnyBrowser(profile, include_incognito_information()); +- Browser* current_browser = +- ChromeExtensionFunctionDetails(this).GetCurrentBrowser(); +- for (auto* browser : *BrowserList::GetInstance()) { +- if (!profile->IsSameOrParent(browser->profile())) ++// Browser* last_active_browser = ++// chrome::FindAnyBrowser(profile, include_incognito_information()); ++// Browser* current_browser = ++// ChromeExtensionFunctionDetails(this).GetCurrentBrowser(); ++ for (size_t h = 0; h < TabModelList::size(); ++h) { ++ TabModel* tab_model = TabModelList::get(h); ++ if (!profile->IsSameOrParent(ProfileManager::GetActiveUserProfile())) + continue; + +- if (!browser->window()) +- continue; ++// if (!browser->window()) ++// continue; + +- if (!include_incognito_information() && profile != browser->profile()) ++ if (!include_incognito_information() && profile != ProfileManager::GetActiveUserProfile()) + continue; + +- if (!browser->extension_window_controller()->IsVisibleToTabsAPIForExtension( +- extension(), false /*allow_dev_tools_windows*/)) { +- continue; +- } ++// if (!browser->extension_window_controller()->IsVisibleToTabsAPIForExtension( ++// extension(), false /*allow_dev_tools_windows*/)) { ++// continue; ++// } ++ ++// if (window_id >= 0 && window_id != ExtensionTabUtil::GetWindowId(browser)) ++// continue; ++ ++// if (window_id == extension_misc::kCurrentWindowId && ++// browser != current_browser) { ++// continue; ++// } ++ ++// if (!MatchesBool(params->query_info.current_window.get(), ++// browser == current_browser)) { ++// continue; ++// } ++ ++// if (!MatchesBool(params->query_info.last_focused_window.get(), ++// browser == last_active_browser)) { ++// continue; ++// } ++ ++// if (!window_type.empty() && ++// window_type != ++// browser->extension_window_controller()->GetWindowTypeText()) { ++// continue; ++// } + +- if (window_id >= 0 && window_id != ExtensionTabUtil::GetWindowId(browser)) +- continue; +- +- if (window_id == extension_misc::kCurrentWindowId && +- browser != current_browser) { +- continue; +- } +- +- if (!MatchesBool(params->query_info.current_window.get(), +- browser == current_browser)) { +- continue; +- } +- +- if (!MatchesBool(params->query_info.last_focused_window.get(), +- browser == last_active_browser)) { +- continue; +- } +- +- if (!window_type.empty() && +- window_type != +- browser->extension_window_controller()->GetWindowTypeText()) { +- continue; +- } +- +- TabStripModel* tab_strip = browser->tab_strip_model(); +- for (int i = 0; i < tab_strip->count(); ++i) { ++ TabModel* tab_strip = TabModelList::GetCurrentTabModel(); ++ for (int i = 0; i < tab_strip->GetTabCount(); ++i) { + WebContents* web_contents = tab_strip->GetWebContentsAt(i); + + if (index > -1 && i != index) +@@ -1052,34 +1052,34 @@ ExtensionFunction::ResponseAction TabsQu + if (!web_contents) + continue; + +- if (!MatchesBool(params->query_info.highlighted.get(), +- tab_strip->IsTabSelected(i))) { +- continue; +- } ++// if (!MatchesBool(params->query_info.highlighted.get(), ++// tab_strip->IsTabSelected(i))) { ++// continue; ++// } + + if (!MatchesBool(params->query_info.active.get(), +- i == tab_strip->active_index())) { ++ i == tab_strip->GetActiveIndex())) { + continue; + } + +- if (!MatchesBool(params->query_info.pinned.get(), +- tab_strip->IsTabPinned(i))) { +- continue; +- } +- +- if (group_id.has_value()) { +- base::Optional group = +- tab_strip->GetTabGroupForTab(index); +- if (group_id.value() == -1) { +- if (group.has_value()) +- continue; +- } else if (!group.has_value()) { +- continue; +- } else if (tab_groups_util::GetGroupId(group.value()) != +- group_id.value()) { +- continue; +- } +- } ++// if (!MatchesBool(params->query_info.pinned.get(), ++// tab_strip->IsTabPinned(i))) { ++// continue; ++// } ++ ++// if (group_id.has_value()) { ++// base::Optional group = ++// tab_strip->GetTabGroupForTab(index); ++// if (group_id.value() == -1) { ++// if (group.has_value()) ++// continue; ++// } else if (!group.has_value()) { ++// continue; ++// } else if (tab_groups_util::GetGroupId(group.value()) != ++// group_id.value()) { ++// continue; ++// } ++// } + + auto* audible_helper = + RecentlyAudibleHelper::FromWebContents(web_contents); +@@ -1088,19 +1088,19 @@ ExtensionFunction::ResponseAction TabsQu + continue; + } + +- auto* tab_lifecycle_unit_external = +- resource_coordinator::TabLifecycleUnitExternal::FromWebContents( +- web_contents); +- +- if (!MatchesBool(params->query_info.discarded.get(), +- tab_lifecycle_unit_external->IsDiscarded())) { +- continue; +- } +- +- if (!MatchesBool(params->query_info.auto_discardable.get(), +- tab_lifecycle_unit_external->IsAutoDiscardable())) { +- continue; +- } ++// auto* tab_lifecycle_unit_external = ++// resource_coordinator::TabLifecycleUnitExternal::FromWebContents( ++// web_contents); ++ ++// if (!MatchesBool(params->query_info.discarded.get(), ++// tab_lifecycle_unit_external->IsDiscarded())) { ++// continue; ++// } ++ ++// if (!MatchesBool(params->query_info.auto_discardable.get(), ++// tab_lifecycle_unit_external->IsAutoDiscardable())) { ++// continue; ++// } + + if (!MatchesBool(params->query_info.muted.get(), + web_contents->IsAudioMuted())) { +@@ -1184,7 +1184,7 @@ ExtensionFunction::ResponseAction TabsDu + int tab_id = params->tab_id; + + Browser* browser = NULL; +- TabStripModel* tab_strip = NULL; ++ TabModel* tab_strip = NULL; + int tab_index = -1; + std::string error; + if (!GetTabById(tab_id, browser_context(), include_incognito_information(), +@@ -1198,9 +1198,9 @@ ExtensionFunction::ResponseAction TabsDu + + // Duplicated tab may not be in the same window as the original, so find + // the window and the tab. +- TabStripModel* new_tab_strip = NULL; ++ TabModel* new_tab_strip = NULL; + int new_tab_index = -1; +- ExtensionTabUtil::GetTabStripModel(new_contents, ++ ExtensionTabUtil::GetTabModel(new_contents, + &new_tab_strip, + &new_tab_index); + if (!new_tab_strip || new_tab_index == -1) { +@@ -1217,7 +1217,7 @@ ExtensionFunction::ResponseAction TabsGe + EXTENSION_FUNCTION_VALIDATE(params.get()); + int tab_id = params->tab_id; + +- TabStripModel* tab_strip = NULL; ++ TabModel* tab_strip = NULL; + WebContents* contents = NULL; + int tab_index = -1; + std::string error; +@@ -1335,7 +1335,7 @@ ExtensionFunction::ResponseAction TabsUp + } + + int tab_index = -1; +- TabStripModel* tab_strip = NULL; ++ TabModel* tab_strip = NULL; + Browser* browser = nullptr; + std::string error; + if (!GetTabById(tab_id, browser_context(), include_incognito_information(), +@@ -1375,25 +1375,25 @@ ExtensionFunction::ResponseAction TabsUp + active = *params->update_properties.active; + + if (active) { +- if (tab_strip->active_index() != tab_index) { +- tab_strip->ActivateTabAt(tab_index); ++ if (tab_strip->GetActiveIndex() != tab_index) { ++ tab_strip->SetActiveIndex(tab_index); + DCHECK_EQ(contents, tab_strip->GetActiveWebContents()); + } + } + +- if (params->update_properties.highlighted.get()) { +- bool highlighted = *params->update_properties.highlighted; +- if (highlighted != tab_strip->IsTabSelected(tab_index)) +- tab_strip->ToggleSelectionAt(tab_index); +- } +- +- if (params->update_properties.pinned.get()) { +- bool pinned = *params->update_properties.pinned; +- tab_strip->SetTabPinned(tab_index, pinned); +- +- // Update the tab index because it may move when being pinned. +- tab_index = tab_strip->GetIndexOfWebContents(contents); +- } ++// if (params->update_properties.highlighted.get()) { ++// bool highlighted = *params->update_properties.highlighted; ++// if (highlighted != tab_strip->IsTabSelected(tab_index)) ++// tab_strip->ToggleSelectionAt(tab_index); ++// } ++ ++// if (params->update_properties.pinned.get()) { ++// bool pinned = *params->update_properties.pinned; ++// tab_strip->SetTabPinned(tab_index, pinned); ++// ++// // Update the tab index because it may move when being pinned. ++// tab_index = tab_strip->GetIndexOfWebContents(contents); ++// } + + if (params->update_properties.muted.get() && + !chrome::SetTabAudioMuted(contents, *params->update_properties.muted, +@@ -1415,20 +1415,20 @@ ExtensionFunction::ResponseAction TabsUp + tabs_constants::kTabNotFoundError, base::NumberToString(opener_id)))); + } + +- if (tab_strip->GetIndexOfWebContents(opener_contents) == +- TabStripModel::kNoTab) { +- return RespondNow( +- Error("Tab opener must be in the same window as the updated tab.")); +- } +- tab_strip->SetOpenerOfWebContentsAt(tab_index, opener_contents); ++// if (tab_strip->GetIndexOfWebContents(opener_contents) == ++// TabStripModel::kNoTab) { ++// return RespondNow( ++// Error("Tab opener must be in the same window as the updated tab.")); ++// } ++// tab_strip->SetOpenerOfWebContentsAt(tab_index, opener_contents); + } + +- if (params->update_properties.auto_discardable.get()) { +- bool state = *params->update_properties.auto_discardable; +- resource_coordinator::TabLifecycleUnitExternal::FromWebContents( +- web_contents_) +- ->SetAutoDiscardable(state); +- } ++// if (params->update_properties.auto_discardable.get()) { ++// bool state = *params->update_properties.auto_discardable; ++// resource_coordinator::TabLifecycleUnitExternal::FromWebContents( ++// web_contents_) ++// ->SetAutoDiscardable(state); ++// } + + return RespondNow(GetResult()); + } +@@ -1550,7 +1550,7 @@ bool TabsMoveFunction::MoveTab(int tab_i + int* window_id, + std::string* error) { + Browser* source_browser = nullptr; +- TabStripModel* source_tab_strip = nullptr; ++ TabModel* source_tab_strip = nullptr; + WebContents* contents = nullptr; + int tab_index = -1; + if (!GetTabById(tab_id, browser_context(), include_incognito_information(), +@@ -1560,12 +1560,12 @@ bool TabsMoveFunction::MoveTab(int tab_i + } + + // Don't let the extension move the tab if the user is dragging tabs. +- if (!source_browser->window()->IsTabStripEditable()) { ++ if (false) { + *error = tabs_constants::kTabStripNotEditableError; + return false; + } + +- if (window_id && *window_id != ExtensionTabUtil::GetWindowIdOfTab(contents)) { ++ if (false && *window_id != ExtensionTabUtil::GetWindowIdOfTab(contents)) { + Browser* target_browser = nullptr; + if (!GetBrowserFromWindowID(this, *window_id, &target_browser, error)) + return false; +@@ -1580,10 +1580,6 @@ bool TabsMoveFunction::MoveTab(int tab_i + if (has_callback()) { + content::WebContents* web_contents = + target_browser->tab_strip_model()->GetWebContentsAt(inserted_index); +- tab_values->Append(CreateTabObjectHelper( +- web_contents, extension(), source_context_type(), +- target_browser->tab_strip_model(), inserted_index) +- ->ToValue()); + } + + // Insert the tabs one after another. +@@ -1596,12 +1592,12 @@ bool TabsMoveFunction::MoveTab(int tab_i + // Clamp move location to the last position. + // This is ">=" because the move must be to an existing location. + // -1 means set the move location to the last position. +- if (*new_index >= source_tab_strip->count() || *new_index < 0) +- *new_index = source_tab_strip->count() - 1; ++ if (*new_index >= source_tab_strip->GetTabCount() || *new_index < 0) ++ *new_index = source_tab_strip->GetTabCount() - 1; + +- if (*new_index != tab_index) +- *new_index = +- source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false); ++// if (*new_index != tab_index) ++// *new_index = ++// source_tab_strip->MoveWebContentsAt(tab_index, *new_index, false); + + if (has_callback()) { + tab_values->Append(CreateTabObjectHelper(contents, extension(), +@@ -1691,18 +1687,18 @@ ExtensionFunction::ResponseAction TabsRe + } + + bool TabsRemoveFunction::RemoveTab(int tab_id, std::string* error) { +- Browser* browser = NULL; ++// Browser* browser = NULL; + WebContents* contents = NULL; + if (!GetTabById(tab_id, browser_context(), include_incognito_information(), +- &browser, nullptr, &contents, nullptr, error)) { ++ nullptr, nullptr, &contents, nullptr, error)) { + return false; + } + + // Don't let the extension remove a tab if the user is dragging tabs around. +- if (!browser->window()->IsTabStripEditable()) { +- *error = tabs_constants::kTabStripNotEditableError; +- return false; +- } ++// if (!browser->window()->IsTabStripEditable()) { ++// *error = tabs_constants::kTabStripNotEditableError; ++// return false; ++// } + // The tab might not immediately close after calling Close() below, so we + // should wait until WebContentsDestroyed is called before responding. + web_contents_destroyed_observers_.push_back( +@@ -1877,20 +1873,18 @@ ExtensionFunction::ResponseAction TabsUn + + bool TabsUngroupFunction::UngroupTab(int tab_id, std::string* error) { + Browser* browser = nullptr; +- TabStripModel* tab_strip = nullptr; ++ TabModel* tab_strip = nullptr; + int tab_index = -1; + if (!GetTabById(tab_id, browser_context(), include_incognito_information(), + &browser, &tab_strip, nullptr, &tab_index, error)) { + return false; + } + +- if (!browser->window()->IsTabStripEditable()) { ++ if (false) { + *error = tabs_constants::kTabStripNotEditableError; + return false; + } + +- tab_strip->RemoveFromGroup({tab_index}); +- + return true; + } + +@@ -1918,7 +1912,7 @@ WebContents* TabsCaptureVisibleTabFuncti + if (!GetBrowserFromWindowID(chrome_details_, window_id, &browser, error)) + return nullptr; + +- WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); ++ WebContents* contents = TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + if (!contents) { + *error = "No active web contents to capture"; + return nullptr; +@@ -2032,10 +2026,7 @@ ExtensionFunction::ResponseAction TabsDe + if (!browser || !contents) + return RespondNow(Error(kUnknownErrorDoNotUse)); + } else { +- browser = ChromeExtensionFunctionDetails(this).GetCurrentBrowser(); +- if (!browser) +- return RespondNow(Error(tabs_constants::kNoCurrentWindowError)); +- contents = browser->tab_strip_model()->GetActiveWebContents(); ++ contents = TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + if (!contents) + return RespondNow(Error(tabs_constants::kNoSelectedTabError)); + } +@@ -2133,13 +2124,9 @@ ExecuteCodeFunction::InitResult ExecuteC + // If the tab ID wasn't given then it needs to be converted to the + // currently active tab's ID. + if (tab_id == -1) { +- Browser* browser = chrome_details_.GetCurrentBrowser(); +- // Can happen during shutdown. +- if (!browser) +- return set_init_result_error(tabs_constants::kNoCurrentWindowError); + content::WebContents* web_contents = NULL; + // Can happen during shutdown. +- if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) ++ if (!ExtensionTabUtil::GetDefaultTab(nullptr, &web_contents, &tab_id)) + return set_init_result_error(tabs_constants::kNoTabInBrowserWindowError); + } + +@@ -2224,7 +2211,7 @@ ScriptExecutor* ExecuteCodeInTabFunction + bool success = GetTabById(execute_tab_id_, browser_context(), + include_incognito_information(), &browser, nullptr, + &contents, nullptr, error) && +- contents && browser; ++ contents; + + if (!success) + return nullptr; +--- a/chrome/browser/extensions/api/tabs/tabs_api.h ++++ b/chrome/browser/extensions/api/tabs/tabs_api.h +@@ -23,6 +23,7 @@ + + class GURL; + class SkBitmap; ++class TabModel; + class TabStripModel; + namespace content { + class WebContents; +--- a/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc ++++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api.cc +@@ -355,10 +355,9 @@ void WebNavigationTabObserver::DidOpenRe + if (!router) + return; + +- TabStripModel* ignored_tab_strip_model = nullptr; + int ignored_tab_index = -1; +- bool new_contents_is_present_in_tabstrip = ExtensionTabUtil::GetTabStripModel( +- new_contents, &ignored_tab_strip_model, &ignored_tab_index); ++ bool new_contents_is_present_in_tabstrip = ExtensionTabUtil::GetTabModel( ++ new_contents, nullptr, &ignored_tab_index); + router->RecordNewWebContents( + web_contents(), source_render_frame_host->GetProcess()->GetID(), + source_render_frame_host->GetRoutingID(), url, new_contents, +--- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc ++++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc +@@ -18,6 +18,10 @@ + #include "chrome/browser/extensions/browser_extension_window_controller.h" + #include "chrome/browser/extensions/extension_tab_util.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" ++#include "chrome/browser/android/tab_android.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_list.h" + #include "chrome/browser/ui/recently_audible_helper.h" +@@ -48,6 +52,11 @@ bool WillDispatchTabUpdatedEvent( + const Extension* extension, + Event* event, + const base::DictionaryValue* listener_filter) { ++ DCHECK(contents); ++ // TODO: temporary fix for null web contents. ++ if (!contents) ++ return false; ++ + ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = + ExtensionTabUtil::GetScrubTabBehavior(extension, target_context, + contents); +@@ -77,6 +86,11 @@ bool WillDispatchTabCreatedEvent(WebCont + const Extension* extension, + Event* event, + const base::DictionaryValue* listener_filter) { ++ DCHECK(contents); ++ // TODO: temporary fix for null web contents. ++ if (!contents) ++ return false; ++ + event->event_args->Clear(); + ExtensionTabUtil::ScrubTabBehavior scrub_tab_behavior = + ExtensionTabUtil::GetScrubTabBehavior(extension, target_context, +@@ -93,13 +107,14 @@ bool WillDispatchTabCreatedEvent(WebCont + } // namespace + + TabsEventRouter::TabEntry::TabEntry(TabsEventRouter* router, +- content::WebContents* contents) +- : WebContentsObserver(contents), ++ TabAndroid* tab) ++ : WebContentsObserver(tab->web_contents()), ++ tab_(tab), + complete_waiting_on_load_(false), + was_audible_(false), +- was_muted_(contents->IsAudioMuted()), ++ was_muted_(tab->web_contents()->IsAudioMuted()), + router_(router) { +- auto* audible_helper = RecentlyAudibleHelper::FromWebContents(contents); ++ auto* audible_helper = RecentlyAudibleHelper::FromWebContents(tab->web_contents()); + was_audible_ = audible_helper->WasRecentlyAudible(); + } + +@@ -159,7 +174,7 @@ void TabsEventRouter::TabEntry::WebConte + // happens in the case of a devtools WebContents that is opened in window, + // docked, then closed. + // Warning: |this| will be deleted after this call. +- router_->UnregisterForTabNotifications(web_contents()); ++ router_->UnregisterForTabNotifications(tab_); + } + + TabsEventRouter::TabsEventRouter(Profile* profile) +@@ -169,11 +184,19 @@ TabsEventRouter::TabsEventRouter(Profile + BrowserList::AddObserver(this); + browser_tab_strip_tracker_.Init(); + ++ // Same as in auto_fetch_page_load_watcher ++ base::ThreadTaskRunnerHandle::Get()->PostTask( ++ FROM_HERE, ++ base::BindOnce(&TabsEventRouter::RegisterTabObserver, GetWeakPtr())); ++ + tab_manager_scoped_observer_.Add(g_browser_process->GetTabManager()); + } + + TabsEventRouter::~TabsEventRouter() { + BrowserList::RemoveObserver(this); ++ if (observed_tab_model_) ++ observed_tab_model_->RemoveObserver(this); ++ TabModelList::RemoveObserver(this); + } + + bool TabsEventRouter::ShouldTrackBrowser(Browser* browser) { +@@ -189,6 +212,7 @@ void TabsEventRouter::OnBrowserSetLastAc + } + } + ++/* + void TabsEventRouter::OnTabStripModelChanged( + TabStripModel* tab_strip_model, + const TabStripModelChange& change, +@@ -238,9 +262,9 @@ void TabsEventRouter::OnTabStripModelCha + selection.new_model.active()); + } + +- if (selection.selection_changed()) { +- DispatchTabSelectionChanged(tab_strip_model, selection.old_model); +- } ++// if (selection.selection_changed()) { ++// DispatchTabSelectionChanged(tab_strip_model, selection.old_model); ++// } + } + + void TabsEventRouter::TabChangedAt(WebContents* contents, +@@ -269,6 +293,114 @@ void TabsEventRouter::TabGroupedStateCha + changed_property_names.insert(tabs_constants::kGroupIdKey); + DispatchTabUpdatedEvent(contents, std::move(changed_property_names)); + } ++*/ ++ ++void TabsEventRouter::RegisterTabObserver() { ++ if (!TabModelList::empty()) { ++ OnTabModelAdded(); ++ } else { ++ TabModelList::AddObserver(this); ++ } ++} ++ ++void TabsEventRouter::OnTabModelAdded() { ++ if (observed_tab_model_) ++ return; ++ // The assumption is that there can be at most one non-off-the-record tab ++ // model. Observe it if it exists. ++ for (auto model = TabModelList::begin(); model != TabModelList::end(); ++ ++model) { ++ if (!(*model)->IsOffTheRecord()) { ++ observed_tab_model_ = *model; ++ observed_tab_model_->AddObserver(this); ++ break; ++ } ++ } ++} ++ ++void TabsEventRouter::OnTabModelRemoved() { ++ if (!observed_tab_model_) ++ return; ++ ++ for (auto remaining_model = TabModelList::begin(); ++ remaining_model != TabModelList::end(); ++remaining_model) { ++ if (observed_tab_model_ == *remaining_model) ++ return; ++ } ++ observed_tab_model_ = nullptr; ++} ++ ++// On Android, tab selection is a different concept from tab_strip_model ++void TabsEventRouter::DidSelectTab(TabAndroid* tab, ++ TabModel::TabSelectionType type, int last_id) { ++ LOG(INFO) << "tabs_event_router.cc: DidSelectTab: entry"; ++ WebContents* contents = tab->web_contents(); ++ DCHECK(contents); ++ if (!contents) { ++ LOG(INFO) << "tabs_event_router.cc: DidSelectTab: web_contents: nullptr"; ++ return; ++ } ++ if (last_id != tab->GetAndroidId()) ++ last_tab_id_ = last_id; ++ if (!GetTabEntry(tab)) { ++ TabModel* tab_model = TabModelList::GetTabModelForTabAndroid(tab); ++ DispatchTabInsertedAt(tab_model, ++ tab, ++ tab_model->GetIndexForWebContents(contents), ++ tab_model->GetActiveWebContents() == contents); ++ } else { ++ // If the tab is already registered, do nothing ++ } ++} ++ ++void TabsEventRouter::DidAddTab(TabAndroid* tab, ++ TabModel::TabLaunchType type) { ++ LOG(INFO) << "tabs_event_router.cc: DidAddTab: entry"; ++ DCHECK(tab->web_contents()); ++// if (!tab->web_contents()) { ++// LOG(INFO) << "tabs_event_router.cc: DidAddTab: web_contents: nullptr"; ++// return; ++// } ++ TabModel* tab_model = TabModelList::GetTabModelForTabAndroid(tab); ++ DispatchTabInsertedAt(tab_model, ++ tab, ++ tab_model->GetIndexForWebContents(tab->web_contents()), ++ tab_model->GetActiveWebContents() == tab->web_contents()); ++} ++ ++void TabsEventRouter::WillCloseTab(TabAndroid* tab, bool animate) { ++ LOG(INFO) << "tabs_event_router.cc: WillCloseTab: entry"; ++ TabModel* tab_model = TabModelList::GetTabModelForTabAndroid(tab); ++ DispatchTabClosingAt(tab_model, ++ tab, ++ tab_model->GetIndexForWebContents(tab->web_contents())); ++} ++ ++void TabsEventRouter::TabRemoved(TabAndroid* tab) { ++ LOG(INFO) << "tabs_event_router.cc: TabRemoved: entry"; ++ TabModel* tab_model = TabModelList::GetTabModelForTabAndroid(tab); ++ DispatchTabDetachedAt(tab, ++ tab_model->GetIndexForWebContents(tab->web_contents()), ++ tab_model->GetActiveWebContents() == tab->web_contents()); ++} ++ ++void TabsEventRouter::DidMoveTab(TabAndroid* tab, int new_index, int old_index) { ++ LOG(INFO) << "tabs_event_router.cc: DidMoveTab: entry"; ++ DispatchTabMoved(tab, old_index, new_index); ++} ++ ++void TabsEventRouter::RestoreCompleted() { ++ LOG(INFO) << "tabs_event_router.cc: RestoreCompleted: entry"; ++ TabModel* tab_model = TabModelList::GetCurrentTabModel(); ++ for (int i = 0; i < tab_model->GetTabCount(); ++i) { ++ DCHECK(tab_model->GetTabAt(i)); ++ DidAddTab(tab_model->GetTabAt(i), TabModel::TabLaunchType::FROM_RESTORE); ++ } ++} ++ ++int TabsEventRouter::GetLastTabId() { ++ return last_tab_id_; ++} + + void TabsEventRouter::OnZoomChanged( + const ZoomController::ZoomChangedEventData& data) { +@@ -330,17 +462,18 @@ void TabsEventRouter::OnAutoDiscardableS + DispatchTabUpdatedEvent(contents, std::move(changed_property_names)); + } + +-void TabsEventRouter::DispatchTabInsertedAt(TabStripModel* tab_strip_model, +- WebContents* contents, ++void TabsEventRouter::DispatchTabInsertedAt(TabModel* tab_strip_model, ++ TabAndroid* tab, + int index, + bool active) { +- if (!GetTabEntry(contents)) { ++ WebContents* contents = tab->web_contents(); ++ if (!GetTabEntry(tab)) { + // We've never seen this tab, send create event as long as we're not in the + // constructor. + if (browser_tab_strip_tracker_.is_processing_initial_browsers()) +- RegisterForTabNotifications(contents); ++ RegisterForTabNotifications(tab); + else +- TabCreatedAt(contents, index, active); ++ TabCreatedAt(tab, index, active); + return; + } + +@@ -357,15 +490,16 @@ void TabsEventRouter::DispatchTabInserte + std::make_unique(index)); + args->Append(std::move(object_args)); + +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ Profile* profile = GetProfileFromBrowserContext(contents); + DispatchEvent(profile, events::TABS_ON_ATTACHED, + api::tabs::OnAttached::kEventName, std::move(args), + EventRouter::USER_GESTURE_UNKNOWN); + } + +-void TabsEventRouter::DispatchTabClosingAt(TabStripModel* tab_strip_model, +- WebContents* contents, ++void TabsEventRouter::DispatchTabClosingAt(TabModel* tab_strip_model, ++ TabAndroid* tab, + int index) { ++ WebContents* contents = tab->web_contents(); + int tab_id = ExtensionTabUtil::GetTabId(contents); + + std::unique_ptr args(new base::ListValue); +@@ -376,21 +510,22 @@ void TabsEventRouter::DispatchTabClosing + object_args->SetInteger(tabs_constants::kWindowIdKey, + ExtensionTabUtil::GetWindowIdOfTab(contents)); + object_args->SetBoolean(tabs_constants::kWindowClosing, +- tab_strip_model->closing_all()); ++ false); + args->Append(std::move(object_args)); + +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ Profile* profile = GetProfileFromBrowserContext(contents); + DispatchEvent(profile, events::TABS_ON_REMOVED, + api::tabs::OnRemoved::kEventName, std::move(args), + EventRouter::USER_GESTURE_UNKNOWN); + +- UnregisterForTabNotifications(contents); ++ UnregisterForTabNotifications(tab); + } + +-void TabsEventRouter::DispatchTabDetachedAt(WebContents* contents, ++void TabsEventRouter::DispatchTabDetachedAt(TabAndroid* tab, + int index, + bool was_active) { +- if (!GetTabEntry(contents)) { ++ WebContents* contents = tab->web_contents(); ++ if (!GetTabEntry(tab)) { + // The tab was removed. Don't send detach event. + return; + } +@@ -407,7 +542,7 @@ void TabsEventRouter::DispatchTabDetache + std::make_unique(index)); + args->Append(std::move(object_args)); + +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ Profile* profile = GetProfileFromBrowserContext(contents); + DispatchEvent(profile, events::TABS_ON_DETACHED, + api::tabs::OnDetached::kEventName, std::move(args), + EventRouter::USER_GESTURE_UNKNOWN); +@@ -416,6 +551,7 @@ void TabsEventRouter::DispatchTabDetache + void TabsEventRouter::DispatchActiveTabChanged(WebContents* old_contents, + WebContents* new_contents, + int index) { ++ NOTREACHED(); + auto args = std::make_unique(); + int tab_id = ExtensionTabUtil::GetTabId(new_contents); + args->AppendInteger(tab_id); +@@ -485,9 +621,10 @@ void TabsEventRouter::DispatchTabSelecti + EventRouter::USER_GESTURE_UNKNOWN); + } + +-void TabsEventRouter::DispatchTabMoved(WebContents* contents, ++void TabsEventRouter::DispatchTabMoved(TabAndroid* tab, + int from_index, + int to_index) { ++ WebContents* contents = tab->web_contents(); + std::unique_ptr args(new base::ListValue); + args->AppendInteger(ExtensionTabUtil::GetTabId(contents)); + +@@ -502,7 +639,7 @@ void TabsEventRouter::DispatchTabMoved(W + std::make_unique(to_index)); + args->Append(std::move(object_args)); + +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ Profile* profile = GetProfileFromBrowserContext(contents); + DispatchEvent(profile, events::TABS_ON_MOVED, api::tabs::OnMoved::kEventName, + std::move(args), EventRouter::USER_GESTURE_UNKNOWN); + } +@@ -510,6 +647,7 @@ void TabsEventRouter::DispatchTabMoved(W + void TabsEventRouter::DispatchTabReplacedAt(WebContents* old_contents, + WebContents* new_contents, + int index) { ++ NOTREACHED(); + // Notify listeners that the next tabs closing or being added are due to + // WebContents being swapped. + const int new_tab_id = ExtensionTabUtil::GetTabId(new_contents); +@@ -522,16 +660,17 @@ void TabsEventRouter::DispatchTabReplace + events::TABS_ON_REPLACED, api::tabs::OnReplaced::kEventName, + std::move(args), EventRouter::USER_GESTURE_UNKNOWN); + +- UnregisterForTabNotifications(old_contents); +- +- if (!GetTabEntry(new_contents)) +- RegisterForTabNotifications(new_contents); ++// UnregisterForTabNotifications(old_contents); ++// ++// if (!GetTabEntry(new_contents)) ++// RegisterForTabNotifications(new_contents); + } + +-void TabsEventRouter::TabCreatedAt(WebContents* contents, ++void TabsEventRouter::TabCreatedAt(TabAndroid* tab, + int index, + bool active) { +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ WebContents* contents = tab->web_contents(); ++ Profile* profile = GetProfileFromBrowserContext(contents); + std::unique_ptr args(new base::ListValue); + auto event = std::make_unique(events::TABS_ON_CREATED, + api::tabs::OnCreated::kEventName, +@@ -541,7 +680,14 @@ void TabsEventRouter::TabCreatedAt(WebCo + base::BindRepeating(&WillDispatchTabCreatedEvent, contents, active); + EventRouter::Get(profile)->BroadcastEvent(std::move(event)); + +- RegisterForTabNotifications(contents); ++ RegisterForTabNotifications(tab); ++} ++ ++Profile* TabsEventRouter::GetProfileFromBrowserContext(WebContents* contents) { ++ if (contents) ++ return Profile::FromBrowserContext(contents->GetBrowserContext()); ++ else ++ return ProfileManager::GetActiveUserProfile(); + } + + void TabsEventRouter::TabUpdated(TabEntry* entry, +@@ -594,6 +740,9 @@ void TabsEventRouter::DispatchTabUpdated + const std::set changed_property_names) { + DCHECK(!changed_property_names.empty()); + DCHECK(contents); ++ // TODO: temporary fix for null web contents. ++ if (!contents) ++ return; + + // The state of the tab (as seen from the extension point of view) has + // changed. Send a notification to the extension. +@@ -608,7 +757,7 @@ void TabsEventRouter::DispatchTabUpdated + + // Third arg: An object containing the state of the tab. Filled in by + // WillDispatchTabUpdatedEvent. +- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); ++ Profile* profile = GetProfileFromBrowserContext(contents); + + auto event = std::make_unique(events::TABS_ON_UPDATED, + api::tabs::OnUpdated::kEventName, +@@ -620,32 +769,43 @@ void TabsEventRouter::DispatchTabUpdated + EventRouter::Get(profile)->BroadcastEvent(std::move(event)); + } + +-void TabsEventRouter::RegisterForTabNotifications(WebContents* contents) { +- favicon_scoped_observer_.Add( +- favicon::ContentFaviconDriver::FromWebContents(contents)); ++void TabsEventRouter::RegisterForTabNotifications(TabAndroid* tab) { ++ // Do not register if web content hasn't been initialized. This happens when Android has just restored the activity. ++ if (!tab->web_contents()) ++ return; ++ ++// favicon_scoped_observer_.Add( ++// favicon::ContentFaviconDriver::FromWebContents(contents)); + +- ZoomController::FromWebContents(contents)->AddObserver(this); ++// ZoomController::FromWebContents(contents)->AddObserver(this); + +- int tab_id = ExtensionTabUtil::GetTabId(contents); ++// int tab_id = ExtensionTabUtil::GetTabId(contents); ++ // Use Android Tab ID instead. It is also unique and preserves between sessions. ++ int tab_id = tab->GetAndroidId(); + DCHECK(tab_entries_.find(tab_id) == tab_entries_.end()); +- tab_entries_[tab_id] = std::make_unique(this, contents); ++ tab_entries_[tab_id] = std::make_unique(this, tab); + } + +-void TabsEventRouter::UnregisterForTabNotifications(WebContents* contents) { +- favicon_scoped_observer_.Remove( +- favicon::ContentFaviconDriver::FromWebContents(contents)); ++void TabsEventRouter::UnregisterForTabNotifications(TabAndroid* tab) { ++// favicon_scoped_observer_.Remove( ++// favicon::ContentFaviconDriver::FromWebContents(contents)); + +- ZoomController::FromWebContents(contents)->RemoveObserver(this); ++// ZoomController::FromWebContents(contents)->RemoveObserver(this); + +- int tab_id = ExtensionTabUtil::GetTabId(contents); ++// int tab_id = ExtensionTabUtil::GetTabId(contents); ++ int tab_id = tab->GetAndroidId(); + int removed_count = tab_entries_.erase(tab_id); +- DCHECK_GT(removed_count, 0); ++// DCHECK_GT(removed_count, 0); // No longer apply since Android can restore closed pages + } + +-TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(WebContents* contents) { +- const auto it = tab_entries_.find(ExtensionTabUtil::GetTabId(contents)); ++TabsEventRouter::TabEntry* TabsEventRouter::GetTabEntry(TabAndroid* tab) { ++ const auto it = tab_entries_.find(tab->GetAndroidId()); + + return it == tab_entries_.end() ? nullptr : it->second.get(); + } + ++base::WeakPtr TabsEventRouter::GetWeakPtr() { ++ return weak_ptr_factory_.GetWeakPtr(); ++} ++ + } // namespace extensions +--- a/chrome/browser/extensions/api/tabs/tabs_event_router.h ++++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h +@@ -10,10 +10,13 @@ + #include + + #include "base/macros.h" ++#include "base/memory/weak_ptr.h" + #include "base/scoped_observer.h" + #include "chrome/browser/extensions/api/tabs/tabs_api.h" + #include "chrome/browser/resource_coordinator/tab_lifecycle_observer.h" + #include "chrome/browser/resource_coordinator/tab_manager.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_observer.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list_observer.h" + #include "chrome/browser/ui/browser_list_observer.h" + #include "chrome/browser/ui/browser_tab_strip_tracker.h" + #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h" +@@ -24,6 +27,8 @@ + #include "content/public/browser/web_contents_observer.h" + #include "extensions/browser/event_router.h" + ++class TabAndroid; ++ + namespace content { + class WebContents; + } +@@ -35,6 +40,8 @@ namespace extensions { + // TabsEventRouter will only route events from windows/tabs within a profile to + // extension processes in the same profile. + class TabsEventRouter : public TabStripModelObserver, ++ public TabModelListObserver, ++ public TabModelObserver, + public BrowserTabStripTrackerDelegate, + public BrowserListObserver, + public favicon::FaviconDriverObserver, +@@ -50,6 +57,7 @@ class TabsEventRouter : public TabStripM + // BrowserListObserver: + void OnBrowserSetLastActive(Browser* browser) override; + ++/* + // TabStripModelObserver: + void OnTabStripModelChanged( + TabStripModel* tab_strip_model, +@@ -65,6 +73,23 @@ class TabsEventRouter : public TabStripM + void TabGroupedStateChanged(base::Optional group, + content::WebContents* contents, + int index) override; ++*/ ++ ++ //TabModelListObserver ++ void RegisterTabObserver(); ++ void OnTabModelAdded() override; ++ void OnTabModelRemoved() override; ++ ++ // TabModelObserver: ++ void DidSelectTab(TabAndroid* tab, ++ TabModel::TabSelectionType type, int last_id) override; ++ void DidAddTab(TabAndroid* tab, ++ TabModel::TabLaunchType type) override; ++ void WillCloseTab(TabAndroid* tab, bool animate) override; ++ void TabRemoved(TabAndroid* tab) override; ++ void DidMoveTab(TabAndroid* tab, int new_index, int old_index) override; ++ void RestoreCompleted() override; ++ int GetLastTabId(); + + // ZoomObserver: + void OnZoomChanged( +@@ -86,14 +111,14 @@ class TabsEventRouter : public TabStripM + + private: + // Methods called from OnTabStripModelChanged. +- void DispatchTabInsertedAt(TabStripModel* tab_strip_model, +- content::WebContents* contents, ++ void DispatchTabInsertedAt(TabModel* tab_strip_model, ++ TabAndroid* tab, + int index, + bool active); +- void DispatchTabClosingAt(TabStripModel* tab_strip_model, +- content::WebContents* contents, ++ void DispatchTabClosingAt(TabModel* tab_strip_model, ++ TabAndroid* tab, + int index); +- void DispatchTabDetachedAt(content::WebContents* contents, ++ void DispatchTabDetachedAt(TabAndroid* tab, + int index, + bool was_active); + void DispatchActiveTabChanged(content::WebContents* old_contents, +@@ -101,7 +126,7 @@ class TabsEventRouter : public TabStripM + int index); + void DispatchTabSelectionChanged(TabStripModel* tab_strip_model, + const ui::ListSelectionModel& old_model); +- void DispatchTabMoved(content::WebContents* contents, ++ void DispatchTabMoved(TabAndroid* tab, + int from_index, + int to_index); + void DispatchTabReplacedAt(content::WebContents* old_contents, +@@ -110,7 +135,10 @@ class TabsEventRouter : public TabStripM + + // "Synthetic" event. Called from DispatchTabInsertedAt if new tab is + // detected. +- void TabCreatedAt(content::WebContents* contents, int index, bool active); ++ void TabCreatedAt(TabAndroid* tab, int index, bool active); ++ ++ // Helper function for getting profile from browser context. It deals with null web contents ++ Profile* GetProfileFromBrowserContext(content::WebContents* contents); + + // Internal processing of tab updated events. Intended to be called when + // there's any changed property. +@@ -138,10 +166,13 @@ class TabsEventRouter : public TabStripM + + // Register ourselves to receive the various notifications we are interested + // in for a tab. Also create tab entry to observe web contents notifications. +- void RegisterForTabNotifications(content::WebContents* contents); ++ void RegisterForTabNotifications(TabAndroid* tab); + + // Removes notifications and tab entry added in RegisterForTabNotifications. +- void UnregisterForTabNotifications(content::WebContents* contents); ++ void UnregisterForTabNotifications(TabAndroid* tab); ++ ++ // For TabModelListObserver ++ base::WeakPtr GetWeakPtr(); + + // Maintain some information about known tabs, so we can: + // +@@ -155,7 +186,7 @@ class TabsEventRouter : public TabStripM + public: + // Create a TabEntry associated with, and tracking state changes to, + // |contents|. +- TabEntry(TabsEventRouter* router, content::WebContents* contents); ++ TabEntry(TabsEventRouter* router, TabAndroid* tab); + + // Indicate via a list of property names if a tab is loading based on its + // WebContents. Whether the state has changed or not is used to determine if +@@ -176,6 +207,9 @@ class TabsEventRouter : public TabStripM + void WebContentsDestroyed() override; + + private: ++ // Use tab instead of web contents ++ TabAndroid* tab_; ++ + // Whether we are waiting to fire the 'complete' status change. This will + // occur the first time the WebContents stops loading after the + // NAV_ENTRY_COMMITTED was fired. The tab may go back into and out of the +@@ -196,7 +230,7 @@ class TabsEventRouter : public TabStripM + + // Gets the TabEntry for the given |contents|. Returns TabEntry* if found, + // nullptr if not. +- TabEntry* GetTabEntry(content::WebContents* contents); ++ TabEntry* GetTabEntry(TabAndroid* tab); + + using TabEntryMap = std::map>; + TabEntryMap tab_entries_; +@@ -209,6 +243,11 @@ class TabsEventRouter : public TabStripM + + BrowserTabStripTracker browser_tab_strip_tracker_; + ++ TabModel* observed_tab_model_ = nullptr; ++ base::WeakPtrFactory weak_ptr_factory_{this}; ++ ++ int last_tab_id_; ++ + ScopedObserver + tab_manager_scoped_observer_{this}; +--- a/chrome/browser/ui/android/tab_model/tab_model.cc ++++ b/chrome/browser/ui/android/tab_model/tab_model.cc +@@ -45,6 +45,14 @@ sessions::LiveTabContext* TabModel::GetL + return live_tab_context_.get(); + } + ++int TabModel::GetIndexForWebContents(content::WebContents* web_contents) const { ++ for (int i = 0; i < GetTabCount(); ++i) { ++ if (GetWebContentsAt(i) == web_contents) ++ return i; ++ } ++ return INVALID_TAB_INDEX; ++} ++ + content::WebContents* TabModel::GetActiveWebContents() const { + int active_index = GetActiveIndex(); + if (active_index == INVALID_TAB_INDEX) +--- a/chrome/browser/ui/android/tab_model/tab_model.h ++++ b/chrome/browser/ui/android/tab_model/tab_model.h +@@ -116,10 +116,12 @@ class TabModel { + + virtual int GetTabCount() const = 0; + virtual int GetActiveIndex() const = 0; ++ virtual int GetIndexForWebContents(content::WebContents* web_contents) const; + virtual content::WebContents* GetActiveWebContents() const; + virtual content::WebContents* GetWebContentsAt(int index) const = 0; + // This will return NULL if the tab has not yet been initialized. + virtual TabAndroid* GetTabAt(int index) const = 0; ++ virtual TabAndroid* GetTabForId(int id) const = 0; + + virtual void SetActiveIndex(int index) = 0; + virtual void CloseTabAt(int index) = 0; +--- a/chrome/browser/ui/browser_navigator.cc ++++ b/chrome/browser/ui/browser_navigator.cc +@@ -19,10 +19,14 @@ + #include "chrome/browser/prefetch/no_state_prefetch/prerender_manager_factory.h" + #include "chrome/browser/prefs/incognito_mode_prefs.h" + #include "chrome/browser/profiles/profile.h" ++#include "chrome/browser/profiles/profile_manager.h" + #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" + #include "chrome/browser/signin/signin_promo.h" + #include "chrome/browser/tab_contents/tab_util.h" + #include "chrome/browser/task_manager/web_contents_tags.h" ++#include "chrome/browser/android/tab_android.h" ++#include "chrome/browser/ui/android/tab_model/tab_model.h" ++#include "chrome/browser/ui/android/tab_model/tab_model_list.h" + #include "chrome/browser/ui/browser.h" + #include "chrome/browser/ui/browser_finder.h" + #include "chrome/browser/ui/browser_list.h" +@@ -92,16 +96,8 @@ bool allow_os_settings_in_tab = false; + // |params.url|. Not all browsers support multiple tabs, such as app frames and + // popups. TYPE_APP will only open a new tab if the URL is within the app scope. + bool WindowCanOpenTabs(const NavigateParams& params) { +- if (!params.browser) +- return false; +- +- if (params.browser->app_controller() && +- !params.browser->app_controller()->IsUrlInAppScope(params.url)) { +- return false; +- } +- +- return params.browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP) || +- params.browser->tab_strip_model()->empty(); ++ // TODO: Except for opening from shortcut , this is always true ++ return true; + } + + // Finds an existing Browser compatible with |profile|, making a new one if no +@@ -165,10 +161,7 @@ std::pair GetBrowserAndTa + if (app_id) { + std::string app_name = web_app::GenerateApplicationNameFromAppId(*app_id); + return { +- Browser::Create(Browser::CreateParams::CreateForApp( +- app_name, +- true, // trusted_source. Installed PWAs are considered trusted. +- params.window_bounds, profile, params.user_gesture)), ++ nullptr, + -1}; + } + } +@@ -190,7 +183,7 @@ std::pair GetBrowserAndTa + return {params.browser, -1}; + // Find a compatible window and re-execute this command in it. Otherwise + // re-run with NEW_WINDOW. +- return {GetOrCreateBrowser(profile, params.user_gesture), -1}; ++ return {nullptr, -1}; + case WindowOpenDisposition::SINGLETON_TAB: { + // If we have a browser window, check it first. + if (params.browser) { +@@ -217,7 +210,7 @@ std::pair GetBrowserAndTa + + // Find a compatible window and re-execute this command in it. Otherwise + // re-run with NEW_WINDOW. +- return {GetOrCreateBrowser(profile, params.user_gesture), -1}; ++ return {nullptr, -1}; + case WindowOpenDisposition::NEW_POPUP: { + // Make a new popup window. + // Coerce app-style if |source| represents an app. +@@ -235,22 +228,19 @@ std::pair GetBrowserAndTa + params.user_gesture); + browser_params.trusted_source = params.trusted_source; + browser_params.initial_bounds = params.window_bounds; +- return {Browser::Create(browser_params), -1}; ++ return {nullptr, -1}; + } +- return {Browser::Create(Browser::CreateParams::CreateForAppPopup( +- app_name, params.trusted_source, params.window_bounds, +- profile, params.user_gesture)), ++ return {nullptr, + -1}; + } + case WindowOpenDisposition::NEW_WINDOW: + // Make a new normal browser window. + return { +- Browser::Create(Browser::CreateParams(profile, params.user_gesture)), ++ nullptr, + -1}; + case WindowOpenDisposition::OFF_THE_RECORD: + // Make or find an incognito window. +- return {GetOrCreateBrowser(profile->GetPrimaryOTRProfile(), +- params.user_gesture), ++ return {nullptr, + -1}; + // The following types result in no navigation. + case WindowOpenDisposition::SAVE_TO_DISK: +@@ -266,13 +256,13 @@ std::pair GetBrowserAndTa + // conditions. + void NormalizeDisposition(NavigateParams* params) { + // Calculate the WindowOpenDisposition if necessary. +- if (params->browser->tab_strip_model()->empty() && ++ if (!TabModelList::GetCurrentTabModel()->GetTabCount() && + (params->disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB || + params->disposition == WindowOpenDisposition::CURRENT_TAB || + params->disposition == WindowOpenDisposition::SINGLETON_TAB)) { + params->disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + } +- if (params->browser->profile()->IsOffTheRecord() && ++ if (ProfileManager::GetActiveUserProfile()->IsOffTheRecord() && + params->disposition == WindowOpenDisposition::OFF_THE_RECORD) { + params->disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + } +@@ -411,10 +401,10 @@ std::unique_ptr Cr + scoped_refptr initial_site_instance_for_new_contents = + params.opener + ? params.opener->GetSiteInstance() +- : tab_util::GetSiteInstanceForNewTab(params.browser->profile(), url); ++ : tab_util::GetSiteInstanceForNewTab(ProfileManager::GetActiveUserProfile(), url); + + WebContents::CreateParams create_params( +- params.browser->profile(), initial_site_instance_for_new_contents); ++ ProfileManager::GetActiveUserProfile(), initial_site_instance_for_new_contents); + create_params.main_frame_name = params.frame_name; + if (params.opener) { + create_params.opener_render_frame_id = params.opener->GetRoutingID(); +@@ -440,7 +430,8 @@ std::unique_ptr Cr + // immediately. + BrowserNavigatorWebContentsAdoption::AttachTabHelpers(target_contents.get()); + #if BUILDFLAG(ENABLE_EXTENSIONS) +- apps::SetAppIdForWebContents(params.browser->profile(), target_contents.get(), ++ apps::SetAppIdForWebContents(ProfileManager::GetActiveUserProfile(), ++ target_contents.get(), + params.extension_app_id); + #endif + +@@ -460,8 +451,7 @@ std::unique_ptr Cr + + void Navigate(NavigateParams* params) { + Browser* source_browser = params->browser; +- if (source_browser) +- params->initiating_profile = source_browser->profile(); ++ params->initiating_profile = ProfileManager::GetActiveUserProfile(); + DCHECK(params->initiating_profile); + + if (source_browser && +@@ -511,9 +501,9 @@ void Navigate(NavigateParams* params) { + // the target browser. This must happen first, before + // GetBrowserForDisposition() has a chance to replace |params->browser| with + // another one. +- if (!params->source_contents && params->browser) { ++ if (!params->source_contents) { + params->source_contents = +- params->browser->tab_strip_model()->GetActiveWebContents(); ++ TabModelList::GetCurrentTabModel()->GetActiveWebContents(); + } + + WebContents* contents_to_navigate_or_insert = +@@ -525,17 +515,17 @@ void Navigate(NavigateParams* params) { + int singleton_index; + std::tie(params->browser, singleton_index) = + GetBrowserAndTabForDisposition(*params); +- if (!params->browser) +- return; ++// if (!params->browser) ++// return; + if (singleton_index != -1) { + contents_to_navigate_or_insert = +- params->browser->tab_strip_model()->GetWebContentsAt(singleton_index); ++ TabModelList::GetCurrentTabModel()->GetWebContentsAt(singleton_index); + } else if (params->disposition == WindowOpenDisposition::SWITCH_TO_TAB) { + // The user is trying to open a tab that no longer exists. If we open a new + // tab, it could leave orphaned NTPs around, but always overwriting the + // current tab could could clobber state that the user was trying to + // preserve. Fallback to the behavior used for singletons: overwrite the +- // current tab if it's the NTP, otherwise open a new tab. ++ // current tab if GetBrowserAndTabForDispositionit's the NTP, otherwise open a new tab. + params->disposition = WindowOpenDisposition::SINGLETON_TAB; + ShowSingletonTabOverwritingNTP(params->browser, std::move(*params)); + return; +@@ -578,10 +568,9 @@ void Navigate(NavigateParams* params) { + } + } + #endif +- + // Navigate() must not return early after this point. + +- if (GetSourceProfile(params) != params->browser->profile()) { ++ if (GetSourceProfile(params) != ProfileManager::GetActiveUserProfile()) { + // A tab is being opened from a link from a different profile, we must reset + // source information that may cause state to be shared. + params->opener = nullptr; +@@ -591,7 +580,7 @@ void Navigate(NavigateParams* params) { + } + + // Make sure the Browser is shown if params call for it. +- ScopedBrowserShower shower(params, &contents_to_navigate_or_insert); ++// ScopedBrowserShower shower(params, &contents_to_navigate_or_insert); + + // Makes sure any WebContents created by this function is destroyed if + // not properly added to a tab strip. +@@ -602,18 +591,18 @@ void Navigate(NavigateParams* params) { + NormalizeDisposition(params); + + // If a new window has been created, it needs to be shown. +- if (params->window_action == NavigateParams::NO_ACTION && +- source_browser != params->browser && +- params->browser->tab_strip_model()->empty()) { +- params->window_action = NavigateParams::SHOW_WINDOW; +- } ++// if (params->window_action == NavigateParams::NO_ACTION && ++// source_browser != params->browser && ++// params->browser->tab_strip_model()->empty()) { ++// params->window_action = NavigateParams::SHOW_WINDOW; ++// } + + // If we create a popup window from a non user-gesture, don't activate it. +- if (params->window_action == NavigateParams::SHOW_WINDOW && +- params->disposition == WindowOpenDisposition::NEW_POPUP && +- params->user_gesture == false) { +- params->window_action = NavigateParams::SHOW_WINDOW_INACTIVE; +- } ++// if (params->window_action == NavigateParams::SHOW_WINDOW && ++// params->disposition == WindowOpenDisposition::NEW_POPUP && ++// params->user_gesture == false) { ++// params->window_action = NavigateParams::SHOW_WINDOW_INACTIVE; ++// } + + // Determine if the navigation was user initiated. If it was, we need to + // inform the target WebContents, and we may need to update the UI. +@@ -665,8 +654,8 @@ void Navigate(NavigateParams* params) { + contents_to_navigate_or_insert, params->transition, + params->window_action, user_initiated); + } else if (singleton_index == -1) { +- if (source_browser != params->browser) +- params->tabstrip_index = params->browser->tab_strip_model()->count(); ++// if (source_browser != params->browser) ++// params->tabstrip_index = params->browser->tab_strip_model()->count(); + + // If some non-default value is set for the index, we should tell the + // TabStripModel to respect it. +@@ -676,14 +665,18 @@ void Navigate(NavigateParams* params) { + // Maybe notify that an open operation has been done from a gesture. + // TODO(crbug.com/1129028): preferably pipe this information through the + // TabStripModel instead. See bug for deeper discussion. +- if (params->user_gesture && source_browser == params->browser) +- params->browser->window()->LinkOpeningFromGesture(params->disposition); ++// if (params->user_gesture && source_browser == params->browser) ++// params->browser->window()->LinkOpeningFromGesture(params->disposition); + + DCHECK(contents_to_insert); + // The navigation should insert a new tab into the target Browser. +- params->browser->tab_strip_model()->AddWebContents( +- std::move(contents_to_insert), params->tabstrip_index, +- params->transition, params->tabstrip_add_types, params->group); ++ // Launch from active tab. ++ // TODO: Release the unique_ptr here. WebContentsAndroid will ++ // handle the deletion? ++ TabModel* tab_model = TabModelList::GetCurrentTabModel(); ++ tab_model->CreateTab( ++ tab_model->GetTabAt(tab_model->GetActiveIndex()), ++ contents_to_insert.release()); + } + + if (singleton_index >= 0) { +@@ -723,8 +716,7 @@ void Navigate(NavigateParams* params) { + should_close_this_tab = true; + } + } +- params->browser->tab_strip_model()->ActivateTabAt(singleton_index, +- {gesture_type}); ++ TabModelList::GetCurrentTabModel()->SetActiveIndex(singleton_index); + // Close tab after switch so index remains correct. + if (should_close_this_tab) + params->source_contents->Close(); +--- a/content/public/browser/web_contents_user_data.h ++++ b/content/public/browser/web_contents_user_data.h +@@ -45,6 +45,8 @@ class WebContentsUserData : public base: + // of the type was attached, returns nullptr. + static T* FromWebContents(WebContents* contents) { + DCHECK(contents); ++ if (!contents) ++ return nullptr; + return static_cast(contents->GetUserData(UserDataKey())); + } + static const T* FromWebContents(const WebContents* contents) { +--- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java ++++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelObserverJniBridge.java +@@ -126,7 +126,11 @@ class TabModelObserverJniBridge implemen + } + + @Override +- public void restoreCompleted() {} ++ public final void restoreCompleted() { ++ assert mNativeTabModelObserverJniBridge != 0; ++ TabModelObserverJniBridgeJni.get().restoreCompleted( ++ mNativeTabModelObserverJniBridge, TabModelObserverJniBridge.this); ++ } + + /** + * Creates an observer bridge for the given tab model. The native counterpart to this object +@@ -188,5 +192,7 @@ class TabModelObserverJniBridge implemen + long nativeTabModelObserverJniBridge, TabModelObserverJniBridge caller); + void tabRemoved( + long nativeTabModelObserverJniBridge, TabModelObserverJniBridge caller, Tab tab); ++ void restoreCompleted( ++ long nativeTabModelObserverJniBridge, TabModelObserverJniBridge caller); + } + } +--- a/chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.cc ++++ b/chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.cc +@@ -4,6 +4,7 @@ + + #include "chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.h" + ++#include "base/logging.h" + #include "chrome/android/chrome_jni_headers/TabModelObserverJniBridge_jni.h" + #include "chrome/browser/android/tab_android.h" + #include "chrome/browser/ui/android/tab_model/tab_model.h" +@@ -53,8 +54,9 @@ void TabModelObserverJniBridge::DidSelec + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); + TabModel::TabSelectionType type = GetTabSelectionType(env, jtype); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: DidSelectTab: type: " << static_cast(type); + for (auto& observer : observers_) +- observer.DidSelectTab(tab, type); ++ observer.DidSelectTab(tab, type, last_id); + } + + void TabModelObserverJniBridge::WillCloseTab(JNIEnv* env, +@@ -63,6 +65,7 @@ void TabModelObserverJniBridge::WillClos + bool animate) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: WillCloseTab"; + for (auto& observer : observers_) + observer.WillCloseTab(tab, animate); + } +@@ -71,6 +74,7 @@ void TabModelObserverJniBridge::DidClose + const JavaParamRef& jobj, + int tab_id, + bool incognito) { ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: DidCloseTab"; + for (auto& observer : observers_) + observer.DidCloseTab(tab_id, incognito); + } +@@ -82,6 +86,7 @@ void TabModelObserverJniBridge::WillAddT + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); + TabModel::TabLaunchType type = GetTabLaunchType(env, jtype); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: WillAddTab: type: " << static_cast(type); + for (auto& observer : observers_) + observer.WillAddTab(tab, type); + } +@@ -93,6 +98,7 @@ void TabModelObserverJniBridge::DidAddTa + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); + TabModel::TabLaunchType type = GetTabLaunchType(env, jtype); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: DidAddTab: type: " << static_cast(type); + for (auto& observer : observers_) + observer.DidAddTab(tab, type); + } +@@ -104,6 +110,7 @@ void TabModelObserverJniBridge::DidMoveT + int cur_index) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: DidMoveTab"; + for (auto& observer : observers_) + observer.DidMoveTab(tab, new_index, cur_index); + } +@@ -114,6 +121,7 @@ void TabModelObserverJniBridge::TabPendi + const JavaParamRef& jtab) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: TabPendingClosure"; + for (auto& observer : observers_) + observer.TabPendingClosure(tab); + } +@@ -124,6 +132,7 @@ void TabModelObserverJniBridge::TabClosu + const JavaParamRef& jtab) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: TabClosureUndone"; + for (auto& observer : observers_) + observer.TabClosureUndone(tab); + } +@@ -134,6 +143,7 @@ void TabModelObserverJniBridge::TabClosu + const JavaParamRef& jtab) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: TabClosureCommitted"; + for (auto& observer : observers_) + observer.TabClosureCommitted(tab); + } +@@ -143,6 +153,7 @@ void TabModelObserverJniBridge::AllTabsP + const JavaParamRef& jobj, + const JavaParamRef& jtabs) { + std::vector tabs; ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: AllTabsPendingClosure"; + + // |jtabs| is actually a Tab[]. Iterate over the array and convert it to + // a vector of TabAndroid*. +@@ -161,6 +172,7 @@ void TabModelObserverJniBridge::AllTabsP + void TabModelObserverJniBridge::AllTabsClosureCommitted( + JNIEnv* env, + const JavaParamRef& jobj) { ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: AllTabsClosureCommitted"; + for (auto& observer : observers_) + observer.AllTabsClosureCommitted(); + } +@@ -170,10 +182,19 @@ void TabModelObserverJniBridge::TabRemov + const JavaParamRef& jtab) { + TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); + CHECK(tab); ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: TabRemoved"; + for (auto& observer : observers_) + observer.TabRemoved(tab); + } + ++void TabModelObserverJniBridge::RestoreCompleted( ++ JNIEnv* env, ++ const JavaParamRef& jobj) { ++ LOG(INFO) << "tab_model_observer_jni_bridge.cc: RestoreCompleted"; ++ for (auto& observer : observers_) ++ observer.RestoreCompleted(); ++} ++ + void TabModelObserverJniBridge::AddObserver(TabModelObserver* observer) { + observers_.AddObserver(observer); + } +--- a/chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.h ++++ b/chrome/browser/ui/android/tab_model/tab_model_observer_jni_bridge.h +@@ -87,6 +87,10 @@ class TabModelObserverJniBridge { + const base::android::JavaParamRef& jobj, + const base::android::JavaParamRef& jtab); + ++ void RestoreCompleted( ++ JNIEnv* env, ++ const base::android::JavaParamRef& jobj); ++ + void AddObserver(TabModelObserver* observer); + void RemoveObserver(TabModelObserver* observer); + +--- a/chrome/browser/ui/android/tab_model/tab_model_observer.cc ++++ b/chrome/browser/ui/android/tab_model/tab_model_observer.cc +@@ -11,7 +11,7 @@ TabModelObserver::TabModelObserver() {} + TabModelObserver::~TabModelObserver() {} + + void TabModelObserver::DidSelectTab(TabAndroid* tab, +- TabModel::TabSelectionType type) {} ++ TabModel::TabSelectionType type, int last_id) {} + + void TabModelObserver::WillCloseTab(TabAndroid* tab, bool animate) {} + +@@ -39,3 +39,5 @@ void TabModelObserver::AllTabsPendingClo + void TabModelObserver::AllTabsClosureCommitted() {} + + void TabModelObserver::TabRemoved(TabAndroid* tab) {} ++ ++void TabModelObserver::RestoreCompleted() {} +--- a/chrome/browser/ui/android/tab_model/tab_model_observer.h ++++ b/chrome/browser/ui/android/tab_model/tab_model_observer.h +@@ -21,7 +21,7 @@ class TabModelObserver { + virtual ~TabModelObserver(); + + // Called when a |tab| is selected. +- virtual void DidSelectTab(TabAndroid* tab, TabModel::TabSelectionType type); ++ virtual void DidSelectTab(TabAndroid* tab, TabModel::TabSelectionType type, int last_id); + + // Called when a |tab| starts closing. + virtual void WillCloseTab(TabAndroid* tab, bool animate); +@@ -61,6 +61,9 @@ class TabModelObserver { + // the TabModel. + virtual void TabRemoved(TabAndroid* tab); + ++ // Called after all tabstates within TabModel are loaded from storage. ++ virtual void RestoreCompleted(); ++ + private: + DISALLOW_COPY_AND_ASSIGN(TabModelObserver); + }; +--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc ++++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc +@@ -137,6 +137,15 @@ TabAndroid* TabModelJniBridge::GetTabAt( + return jtab.is_null() ? NULL : TabAndroid::GetNativeTab(env, jtab); + } + ++TabAndroid* TabModelJniBridge::GetTabForId(int id) const { ++ for (int i = 0; i < GetTabCount(); ++i) { ++ TabAndroid* tab = GetTabAt(i); ++ if (tab && tab->GetAndroidId() == id) ++ return tab; ++ } ++ return nullptr; ++} ++ + void TabModelJniBridge::SetActiveIndex(int index) { + JNIEnv* env = AttachCurrentThread(); + Java_TabModelJniBridge_setIndex(env, java_object_.get(env), index); +--- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h ++++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.h +@@ -46,6 +46,7 @@ class TabModelJniBridge : public TabMode + int GetActiveIndex() const override; + content::WebContents* GetWebContentsAt(int index) const override; + TabAndroid* GetTabAt(int index) const override; ++ TabAndroid* GetTabForId(int id) const override; + + void SetActiveIndex(int index) override; + void CloseTabAt(int index) override; diff --git a/series b/series new file mode 100644 index 0000000..0cb286d --- /dev/null +++ b/series @@ -0,0 +1,14 @@ +Extensions/base/fix-disabled-supervised-user.patch +Extensions/base/gn.patch +Extensions/base/src.patch +Extensions/base/res.patch +Extensions/open-setting-in-new-tab.patch +Extensions/allow-select-folder.patch +Extensions/crx-download-install-prompt.patch +Extensions/add-chromium-webstore-extension.patch +Extensions/fix-extension-remove-button.patch +Extensions/extension-system-delayed-reload.patch +Extensions/add-api-os-android.patch +Extensions/profile-extra-parts-init.patch +Extensions/tab-api-fix.patch +Extensions/add-extension-menu-items.patch