// 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.test;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.EmptyTabObserver;
import org.chromium.chrome.browser.Tab;
import org.chromium.chrome.browser.tab.ChromeTab;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.content.browser.test.util.CallbackHelper;
import org.chromium.content.browser.test.util.TestTouchUtils;

import java.util.concurrent.TimeoutException;

/**
 * The base class of the ChromeTabbedActivity specific tests. It provides the common methods
 * to access the ChromeTabbedActivity UI.
 */
@CommandLineFlags.Add(ChromeSwitches.DISABLE_DOCUMENT_MODE)
public abstract class ChromeTabbedActivityTestBase extends
        ChromeActivityTestCaseBase<ChromeTabbedActivity> {
    private static final String TAG = "ChromeTabbedActivityTestBase";

    public ChromeTabbedActivityTestBase() {
        super(ChromeTabbedActivity.class);
    }

    /**
     * Load a url in multiple new tabs in parallel. Each {@link ChromeTab} will pretend to be
     * created from a link.
     *
     * @param url The url of the page to load.
     * @param numTabs The number of tabs to open.
     */
    public void loadUrlInManyNewTabs(final String url, final int numTabs)
            throws InterruptedException {
        final CallbackHelper[] pageLoadedCallbacks = new CallbackHelper[numTabs];
        final int[] tabIds = new int[numTabs];
        for (int i = 0; i < numTabs; ++i) {
            final int index = i;
            getInstrumentation().runOnMainSync(new Runnable() {
                @Override
                public void run() {
                    Tab currentTab = getActivity().getCurrentTabCreator().launchUrl(
                            url, TabLaunchType.FROM_LINK);
                    final CallbackHelper pageLoadCallback = new CallbackHelper();
                    pageLoadedCallbacks[index] = pageLoadCallback;
                    currentTab.addObserver(new EmptyTabObserver() {
                        @Override
                        public void onPageLoadFinished(Tab tab) {
                            pageLoadCallback.notifyCalled();
                            tab.removeObserver(this);
                        }
                    });
                    tabIds[index] = currentTab.getId();
                }
            });
        }
        //  When opening many tabs some may be frozen due to memory pressure and won't send
        //  PAGE_LOAD_FINISHED events. Iterate over the newly opened tabs and wait for each to load.
        for (int i = 0; i < numTabs; ++i) {
            final TabModel tabModel = getActivity().getCurrentTabModel();
            final Tab tab = TabModelUtils.getTabById(tabModel, tabIds[i]);
            getInstrumentation().runOnMainSync(new Runnable() {
                @Override
                public void run() {
                    TabModelUtils.setIndex(tabModel, tabModel.indexOf(tab));
                }
            });
            try {
                pageLoadedCallbacks[i].waitForCallback(0);
            } catch (TimeoutException e) {
                fail("PAGE_LOAD_FINISHED was not received for tabId=" + tabIds[i]);
            }
        }
    }

    @Override
    protected void startActivityCompletely(Intent intent) {
        Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(
                ChromeTabbedActivity.class.getName(), null, false);
        Activity activity = getInstrumentation().startActivitySync(intent);
        assertNotNull("Main activity did not start", activity);
        ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity)
                monitor.waitForActivityWithTimeout(ACTIVITY_START_TIMEOUT_MS);
        assertNotNull("ChromeTabbedActivity did not start", tabbedActivity);
        setActivity(tabbedActivity);
        Log.d(TAG, "startActivityCompletely <<");
    }

    /**
     * Long presses the view, selects an item from the context menu, and
     * asserts that a new tab is opened and is incognito iff expectIncognito is true.
     * @param view The View to long press.
     * @param contextMenuItemId The context menu item to select on the view.
     * @param expectIncognito Whether the opened tab is expected to be incognito.
     * @param expectedUrl The expected url for the new tab.
     */
    protected void invokeContextMenuAndOpenInANewTab(View view, int contextMenuItemId,
            boolean expectIncognito, final String expectedUrl) throws InterruptedException {
        final CallbackHelper createdCallback = new CallbackHelper();
        final TabModel tabModel = getActivity().getTabModelSelector().getModel(expectIncognito);
        tabModel.addObserver(new EmptyTabModelObserver() {
            @Override
            public void didAddTab(Tab tab, TabLaunchType type) {
                if (TextUtils.equals(expectedUrl, tab.getUrl())) {
                    createdCallback.notifyCalled();
                    tabModel.removeObserver(this);
                }
            }
        });

        TestTouchUtils.longClickView(getInstrumentation(), view);
        assertTrue(getInstrumentation().invokeContextMenuAction(getActivity(),
                contextMenuItemId, 0));

        try {
            createdCallback.waitForCallback(0);
        } catch (TimeoutException e) {
            fail("Never received tab creation event");
        }

        if (expectIncognito) {
            assertTrue(getActivity().getTabModelSelector().isIncognitoSelected());
        } else {
            assertFalse(getActivity().getTabModelSelector().isIncognitoSelected());
        }
    }
}

@@ -213,143 +213,22 @@
 oid.
-app.Activity;%0Aimport android.app.Instrumentation;%0Aimport android.content.Intent;%0Aimport android.text.TextUtils;%0Aimport android.util.Log
+text.TextUtils
 ;%0Aim
@@ -3740,692 +3740,8 @@
  %7D%0A%0A
-    @Override%0A    protected void startActivityCompletely(Intent intent) %7B%0A        Instrumentation.ActivityMonitor monitor = getInstrumentation().addMonitor(%0A                ChromeTabbedActivity.class.getName(), null, false);%0A        Activity activity = getInstrumentation().startActivitySync(intent);%0A        assertNotNull(%22Main activity did not start%22, activity);%0A        ChromeTabbedActivity tabbedActivity = (ChromeTabbedActivity)%0A                monitor.waitForActivityWithTimeout(ACTIVITY_START_TIMEOUT_MS);%0A        assertNotNull(%22ChromeTabbedActivity did not start%22, tabbedActivity);%0A        setActivity(tabbedActivity);%0A        Log.d(TAG, %22startActivityCompletely %3C%3C%22);%0A    %7D%0A%0A
     

Remove ChromeTabbedActivityTestBase.startActivityCompletely().