1db22ec4ee014900988062d910bc810172a07df56John Reck/*
2db22ec4ee014900988062d910bc810172a07df56John Reck * Copyright (C) 2011 The Android Open Source Project
3db22ec4ee014900988062d910bc810172a07df56John Reck *
4db22ec4ee014900988062d910bc810172a07df56John Reck * Licensed under the Apache License, Version 2.0 (the "License");
5db22ec4ee014900988062d910bc810172a07df56John Reck * you may not use this file except in compliance with the License.
6db22ec4ee014900988062d910bc810172a07df56John Reck * You may obtain a copy of the License at
7db22ec4ee014900988062d910bc810172a07df56John Reck *
8db22ec4ee014900988062d910bc810172a07df56John Reck *      http://www.apache.org/licenses/LICENSE-2.0
9db22ec4ee014900988062d910bc810172a07df56John Reck *
10db22ec4ee014900988062d910bc810172a07df56John Reck * Unless required by applicable law or agreed to in writing, software
11db22ec4ee014900988062d910bc810172a07df56John Reck * distributed under the License is distributed on an "AS IS" BASIS,
12db22ec4ee014900988062d910bc810172a07df56John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13db22ec4ee014900988062d910bc810172a07df56John Reck * See the License for the specific language governing permissions and
14db22ec4ee014900988062d910bc810172a07df56John Reck * limitations under the License.
15db22ec4ee014900988062d910bc810172a07df56John Reck */
16db22ec4ee014900988062d910bc810172a07df56John Reckpackage com.android.browser;
17db22ec4ee014900988062d910bc810172a07df56John Reck
18db22ec4ee014900988062d910bc810172a07df56John Reckimport android.app.Activity;
19db22ec4ee014900988062d910bc810172a07df56John Reckimport android.content.Intent;
20db22ec4ee014900988062d910bc810172a07df56John Reckimport android.net.Uri;
21db22ec4ee014900988062d910bc810172a07df56John Reckimport android.provider.Browser;
22db22ec4ee014900988062d910bc810172a07df56John Reckimport android.test.ActivityInstrumentationTestCase2;
23db22ec4ee014900988062d910bc810172a07df56John Reckimport android.text.TextUtils;
24db22ec4ee014900988062d910bc810172a07df56John Reckimport android.webkit.WebView;
25db22ec4ee014900988062d910bc810172a07df56John Reck
26db22ec4ee014900988062d910bc810172a07df56John Reckpublic class IntentHandlerTests extends ActivityInstrumentationTestCase2<BrowserActivity> {
27db22ec4ee014900988062d910bc810172a07df56John Reck
28db22ec4ee014900988062d910bc810172a07df56John Reck    // How long to wait to receive onPageStarted
29db22ec4ee014900988062d910bc810172a07df56John Reck    static final int START_LOAD_TIMEOUT = 20000; // ms
30db22ec4ee014900988062d910bc810172a07df56John Reck    static final int POLL_INTERVAL = 50; // ms
31db22ec4ee014900988062d910bc810172a07df56John Reck    boolean mHasStarted = false;
32db22ec4ee014900988062d910bc810172a07df56John Reck
33db22ec4ee014900988062d910bc810172a07df56John Reck    public IntentHandlerTests() {
34db22ec4ee014900988062d910bc810172a07df56John Reck        super(BrowserActivity.class);
35db22ec4ee014900988062d910bc810172a07df56John Reck    }
36db22ec4ee014900988062d910bc810172a07df56John Reck
37db22ec4ee014900988062d910bc810172a07df56John Reck    public void testSwitchToTabWithUrl() throws Throwable {
38db22ec4ee014900988062d910bc810172a07df56John Reck        Intent intent = new Intent(Intent.ACTION_VIEW);
39db22ec4ee014900988062d910bc810172a07df56John Reck        intent.setData(Uri.parse("http://google.com/"));
40db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
41db22ec4ee014900988062d910bc810172a07df56John Reck        Controller controller = getActivity().getController();
42db22ec4ee014900988062d910bc810172a07df56John Reck        Tab tabGoogle = controller.getCurrentTab();
43db22ec4ee014900988062d910bc810172a07df56John Reck        assertNotNull("Current tab (google.com", tabGoogle);
44db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals("http://google.com/", tabGoogle.getOriginalUrl());
45db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(1, controller.getTabs().size());
46db22ec4ee014900988062d910bc810172a07df56John Reck        intent.setData(Uri.parse("http://maps.google.com/"));
47db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
48db22ec4ee014900988062d910bc810172a07df56John Reck        Tab tabMaps = controller.getCurrentTab();
49db22ec4ee014900988062d910bc810172a07df56John Reck        assertNotSame(tabGoogle, tabMaps);
50db22ec4ee014900988062d910bc810172a07df56John Reck        assertNotNull("Current tab (maps.google.com)", tabMaps);
51db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(2, controller.getTabs().size());
52db22ec4ee014900988062d910bc810172a07df56John Reck        intent.setData(Uri.parse("http://google.com/"));
53db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
54db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(tabGoogle, controller.getCurrentTab());
55db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(2, controller.getTabs().size());
56db22ec4ee014900988062d910bc810172a07df56John Reck    }
57db22ec4ee014900988062d910bc810172a07df56John Reck
58db22ec4ee014900988062d910bc810172a07df56John Reck    public void testShortcut() throws Throwable {
59db22ec4ee014900988062d910bc810172a07df56John Reck        Intent intent = BookmarkUtils.createShortcutIntent("http://google.com/");
60db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
61db22ec4ee014900988062d910bc810172a07df56John Reck        Controller controller = getActivity().getController();
62db22ec4ee014900988062d910bc810172a07df56John Reck        Tab tabGoogle = controller.getCurrentTab();
63db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals("http://google.com/", tabGoogle.getOriginalUrl());
64db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(1, controller.getTabs().size());
65db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
66db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(1, controller.getTabs().size());
67db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(tabGoogle, controller.getCurrentTab());
68db22ec4ee014900988062d910bc810172a07df56John Reck        directlyLoadUrl(tabGoogle, "http://maps.google.com/");
69db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
70db22ec4ee014900988062d910bc810172a07df56John Reck        if (BrowserActivity.isTablet(getActivity())) {
71db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(2, controller.getTabs().size());
72db22ec4ee014900988062d910bc810172a07df56John Reck            assertNotSame(tabGoogle, controller.getCurrentTab());
73db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals("http://maps.google.com/", tabGoogle.getOriginalUrl());
74db22ec4ee014900988062d910bc810172a07df56John Reck            Tab currentTab = controller.getCurrentTab();
75db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals("http://google.com/", currentTab.getOriginalUrl());
76db22ec4ee014900988062d910bc810172a07df56John Reck        } else {
77db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(1, controller.getTabs().size());
78db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(tabGoogle, controller.getCurrentTab());
79db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals("http://google.com/", tabGoogle.getOriginalUrl());
80db22ec4ee014900988062d910bc810172a07df56John Reck        }
81db22ec4ee014900988062d910bc810172a07df56John Reck    }
82db22ec4ee014900988062d910bc810172a07df56John Reck
83db22ec4ee014900988062d910bc810172a07df56John Reck    public void testApplication() throws Throwable {
84db22ec4ee014900988062d910bc810172a07df56John Reck        Intent intent = new Intent(Intent.ACTION_VIEW);
85db22ec4ee014900988062d910bc810172a07df56John Reck        intent.setData(Uri.parse("http://google.com/"));
86db22ec4ee014900988062d910bc810172a07df56John Reck        intent.putExtra(Browser.EXTRA_APPLICATION_ID, getClass().getName());
87db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
88db22ec4ee014900988062d910bc810172a07df56John Reck        Controller controller = getActivity().getController();
89db22ec4ee014900988062d910bc810172a07df56John Reck        Tab tabGoogle = controller.getCurrentTab();
90db22ec4ee014900988062d910bc810172a07df56John Reck        assertNotNull("Current tab (google.com", tabGoogle);
91db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals("http://google.com/", tabGoogle.getOriginalUrl());
92db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals(1, controller.getTabs().size());
93db22ec4ee014900988062d910bc810172a07df56John Reck        intent.setData(Uri.parse("http://maps.google.com/"));
94db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent);
95db22ec4ee014900988062d910bc810172a07df56John Reck        Tab tabMaps = controller.getCurrentTab();
96db22ec4ee014900988062d910bc810172a07df56John Reck        assertEquals("http://maps.google.com/", tabMaps.getOriginalUrl());
97db22ec4ee014900988062d910bc810172a07df56John Reck        if (BrowserActivity.isTablet(getActivity())) {
98db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(2, controller.getTabs().size());
99db22ec4ee014900988062d910bc810172a07df56John Reck            assertNotSame(tabGoogle, tabMaps);
100db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals("http://google.com/", tabGoogle.getOriginalUrl());
101db22ec4ee014900988062d910bc810172a07df56John Reck        } else {
102db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(1, controller.getTabs().size());
103db22ec4ee014900988062d910bc810172a07df56John Reck            assertEquals(tabGoogle, tabMaps);
104db22ec4ee014900988062d910bc810172a07df56John Reck        }
105db22ec4ee014900988062d910bc810172a07df56John Reck    }
106db22ec4ee014900988062d910bc810172a07df56John Reck
107db22ec4ee014900988062d910bc810172a07df56John Reck    /**
108db22ec4ee014900988062d910bc810172a07df56John Reck     * Simulate clicking a link by loading a URL directly on the WebView,
109db22ec4ee014900988062d910bc810172a07df56John Reck     * bypassing Tab, Controller, etc..
110db22ec4ee014900988062d910bc810172a07df56John Reck     * @throws Throwable
111db22ec4ee014900988062d910bc810172a07df56John Reck     */
112db22ec4ee014900988062d910bc810172a07df56John Reck    private void directlyLoadUrl(final Tab tab, final String url) throws Throwable {
113db22ec4ee014900988062d910bc810172a07df56John Reck        runTestOnUiThread(new Runnable() {
114db22ec4ee014900988062d910bc810172a07df56John Reck            @Override
115db22ec4ee014900988062d910bc810172a07df56John Reck            public void run() {
116db22ec4ee014900988062d910bc810172a07df56John Reck                WebView web = tab.getWebView();
117db22ec4ee014900988062d910bc810172a07df56John Reck                web.loadUrl(url);
118db22ec4ee014900988062d910bc810172a07df56John Reck            }
119db22ec4ee014900988062d910bc810172a07df56John Reck        });
120db22ec4ee014900988062d910bc810172a07df56John Reck        waitForLoadStart(tab, url);
121db22ec4ee014900988062d910bc810172a07df56John Reck    }
122db22ec4ee014900988062d910bc810172a07df56John Reck
123db22ec4ee014900988062d910bc810172a07df56John Reck    void waitForLoadStart(final Tab tab, final String url) throws InterruptedException {
124db22ec4ee014900988062d910bc810172a07df56John Reck        long start = System.currentTimeMillis();
125db22ec4ee014900988062d910bc810172a07df56John Reck        while (!TextUtils.equals(tab.getOriginalUrl(), url)) {
126db22ec4ee014900988062d910bc810172a07df56John Reck            if (start + START_LOAD_TIMEOUT < System.currentTimeMillis()) {
127db22ec4ee014900988062d910bc810172a07df56John Reck                throw new RuntimeException("Didn't receive onPageStarted!");
128db22ec4ee014900988062d910bc810172a07df56John Reck            }
129db22ec4ee014900988062d910bc810172a07df56John Reck            Thread.sleep(POLL_INTERVAL);
130db22ec4ee014900988062d910bc810172a07df56John Reck        }
131db22ec4ee014900988062d910bc810172a07df56John Reck    }
132db22ec4ee014900988062d910bc810172a07df56John Reck
133db22ec4ee014900988062d910bc810172a07df56John Reck    private void sendIntent(final Intent intent) throws Throwable {
134db22ec4ee014900988062d910bc810172a07df56John Reck        sendIntent(intent, true);
135db22ec4ee014900988062d910bc810172a07df56John Reck    }
136db22ec4ee014900988062d910bc810172a07df56John Reck
137db22ec4ee014900988062d910bc810172a07df56John Reck    private void sendIntent(final Intent intent, boolean waitForLoadStart) throws Throwable {
138db22ec4ee014900988062d910bc810172a07df56John Reck        if (!mHasStarted) {
139db22ec4ee014900988062d910bc810172a07df56John Reck            // Prevent crash recovery from happening
140db22ec4ee014900988062d910bc810172a07df56John Reck            intent.putExtra(Controller.NO_CRASH_RECOVERY, true);
141db22ec4ee014900988062d910bc810172a07df56John Reck            setActivityIntent(intent);
142db22ec4ee014900988062d910bc810172a07df56John Reck            getActivity();
143db22ec4ee014900988062d910bc810172a07df56John Reck        } else {
144db22ec4ee014900988062d910bc810172a07df56John Reck            final Activity activity = getActivity();
145db22ec4ee014900988062d910bc810172a07df56John Reck            runTestOnUiThread(new Runnable() {
146db22ec4ee014900988062d910bc810172a07df56John Reck                @Override
147db22ec4ee014900988062d910bc810172a07df56John Reck                public void run() {
148db22ec4ee014900988062d910bc810172a07df56John Reck                    getInstrumentation().callActivityOnNewIntent(activity, intent);
149db22ec4ee014900988062d910bc810172a07df56John Reck                }
150db22ec4ee014900988062d910bc810172a07df56John Reck            });
151db22ec4ee014900988062d910bc810172a07df56John Reck        }
152db22ec4ee014900988062d910bc810172a07df56John Reck        if (waitForLoadStart) {
153db22ec4ee014900988062d910bc810172a07df56John Reck            String url = intent.getDataString();
154db22ec4ee014900988062d910bc810172a07df56John Reck            Tab tab = getActivity().getController().getCurrentTab();
155db22ec4ee014900988062d910bc810172a07df56John Reck            waitForLoadStart(tab, url);
156db22ec4ee014900988062d910bc810172a07df56John Reck        }
157db22ec4ee014900988062d910bc810172a07df56John Reck    }
158db22ec4ee014900988062d910bc810172a07df56John Reck
159db22ec4ee014900988062d910bc810172a07df56John Reck    @Override
160db22ec4ee014900988062d910bc810172a07df56John Reck    public BrowserActivity getActivity() {
161db22ec4ee014900988062d910bc810172a07df56John Reck        mHasStarted = true;
162db22ec4ee014900988062d910bc810172a07df56John Reck        return super.getActivity();
163db22ec4ee014900988062d910bc810172a07df56John Reck    }
164db22ec4ee014900988062d910bc810172a07df56John Reck}
165