// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.chrome.browser.customtabs; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.AsyncTask; import android.view.Menu; import android.view.MenuItem; import org.chromium.base.BuildInfo; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.appmenu.AppMenuPropertiesDelegate; import org.chromium.chrome.browser.share.ShareHelper; import org.chromium.chrome.browser.tab.Tab; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; /** * App menu properties delegate for {@link CustomTabActivity}. */ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegate { private static final String SAMPLE_URL = "https://www.google.com"; private final boolean mShowShare; private final boolean mIsMediaViewer; private final List<String> mMenuEntries; private final Map<MenuItem, Integer> mItemToIndexMap = new HashMap<MenuItem, Integer>(); private final AsyncTask<Void, Void, String> mDefaultBrowserFetcher; private boolean mIsCustomEntryAdded; /** * Creates an {@link CustomTabAppMenuPropertiesDelegate} instance. */ public CustomTabAppMenuPropertiesDelegate(final ChromeActivity activity, List<String> menuEntries, boolean showShare, final boolean isOpenedByChrome, final boolean isMediaViewer) { super(activity); mMenuEntries = menuEntries; mShowShare = showShare; mIsMediaViewer = isMediaViewer; mDefaultBrowserFetcher = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { String packageLabel = null; if (isOpenedByChrome) { // If the Custom Tab was created by Chrome, Chrome should open it. packageLabel = BuildInfo.getPackageLabel(activity); } else { // Check if there is a default handler for the Intent. If so, grab its label. Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(SAMPLE_URL)); PackageManager pm = activity.getPackageManager(); ResolveInfo info = pm.resolveActivity(intent, 0); if (info != null && info.match != 0) { packageLabel = info.loadLabel(pm).toString(); } } return packageLabel == null ? activity.getString(R.string.menu_open_in_product_default) : activity.getString(R.string.menu_open_in_product, packageLabel); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override public void prepareMenu(Menu menu) { Tab currentTab = mActivity.getActivityTab(); if (currentTab != null) { MenuItem forwardMenuItem = menu.findItem(R.id.forward_menu_id); forwardMenuItem.setEnabled(currentTab.canGoForward()); mReloadMenuItem = menu.findItem(R.id.reload_menu_id); mReloadMenuItem.setIcon(R.drawable.btn_reload_stop); loadingStateChanged(currentTab.isLoading()); MenuItem shareItem = menu.findItem(R.id.share_row_menu_id); shareItem.setVisible(mShowShare); shareItem.setEnabled(mShowShare); if (mShowShare) { ShareHelper.configureDirectShareMenuItem( mActivity, menu.findItem(R.id.direct_share_menu_id)); } MenuItem iconRow = menu.findItem(R.id.icon_row_menu_id); MenuItem openInChromeItem = menu.findItem(R.id.open_in_browser_id); if (mIsMediaViewer) { // Most of the menu items don't make sense when viewing media. iconRow.setVisible(false); openInChromeItem.setVisible(false); } else { try { openInChromeItem.setTitle(mDefaultBrowserFetcher.get()); } catch (InterruptedException | ExecutionException e) { openInChromeItem.setTitle( mActivity.getString(R.string.menu_open_in_product_default)); } } // Add custom menu items. Make sure they are only added once. if (!mIsCustomEntryAdded) { mIsCustomEntryAdded = true; for (int i = 0; i < mMenuEntries.size(); i++) { MenuItem item = menu.add(0, 0, 1, mMenuEntries.get(i)); mItemToIndexMap.put(item, i); } } } } /** * @return The index that the given menu item should appear in the result of * {@link CustomTabIntentDataProvider#getMenuTitles()}. Returns -1 if item not found. */ public int getIndexOfMenuItem(MenuItem menuItem) { if (!mItemToIndexMap.containsKey(menuItem)) { return -1; } return mItemToIndexMap.get(menuItem).intValue(); } @Override public int getFooterResourceId() { return mIsMediaViewer ? 0 : R.layout.powered_by_chrome_footer; } /** * Get the {@link MenuItem} object associated with the given title. If multiple menu items have * the same title, a random one will be returned. This method is for testing purpose _only_. */ @VisibleForTesting MenuItem getMenuItemForTitle(String title) { for (MenuItem item : mItemToIndexMap.keySet()) { if (item.getTitle().equals(title)) return item; } return null; } }