1914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal/*
2914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Copyright (C) 2017 The Android Open Source Project
3914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
4914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Licensed under the Apache License, Version 2.0 (the "License");
5914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * you may not use this file except in compliance with the License.
6914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * You may obtain a copy of the License at
7914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
8914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *      http://www.apache.org/licenses/LICENSE-2.0
9914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal *
10914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Unless required by applicable law or agreed to in writing, software
11914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * distributed under the License is distributed on an "AS IS" BASIS,
12914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * See the License for the specific language governing permissions and
14914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * limitations under the License.
15914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal */
16914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
17914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalpackage android.support.customtabs;
18914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
19914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport static org.junit.Assert.assertEquals;
20914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport static org.junit.Assert.assertTrue;
21914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport static org.junit.Assert.fail;
22914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
23914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.content.ComponentName;
24914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.content.Context;
25914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.content.Intent;
26914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.net.Uri;
27914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.os.Bundle;
28914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.support.test.filters.SmallTest;
29914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.support.test.rule.ActivityTestRule;
30914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.support.test.rule.ServiceTestRule;
31914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport android.support.test.runner.AndroidJUnit4;
326d20a527c6adad79f5fb48ec8bc02d738db1e1d2Aurimas Liutikasimport android.support.testutils.PollingCheck;
33914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
34914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport org.junit.Before;
35914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport org.junit.Rule;
36914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport org.junit.Test;
37914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport org.junit.runner.RunWith;
38914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
39914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalimport java.util.concurrent.TimeoutException;
4046ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysalimport java.util.concurrent.atomic.AtomicBoolean;
41914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
42914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
43914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal/**
44914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * Tests for a complete loop between a browser side {@link CustomTabsService}
45914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * and a client side {@link PostMessageService}. Both services are bound to through
46914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * {@link ServiceTestRule}, but {@link CustomTabsCallback#extraCallback} is used to link browser
47914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal * side actions.
48914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal */
49914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal@RunWith(AndroidJUnit4.class)
50914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal@SmallTest
51914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysalpublic class PostMessageTest {
52914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    @Rule
53914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public final ServiceTestRule mServiceRule;
54914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    @Rule
55914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public final ActivityTestRule<TestActivity> mActivityTestRule;
56914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private TestCustomTabsCallback mCallback;
57914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private Context mContext;
58914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private CustomTabsServiceConnection mCustomTabsServiceConnection;
59914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private PostMessageServiceConnection mPostMessageServiceConnection;
6046ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal    private AtomicBoolean mCustomTabsServiceConnected;
61914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private boolean mPostMessageServiceConnected;
62914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    private CustomTabsSession mSession;
63914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
64914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public PostMessageTest() {
65914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mActivityTestRule = new ActivityTestRule<TestActivity>(TestActivity.class);
66914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mServiceRule = new ServiceTestRule();
6746ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal        mCustomTabsServiceConnected = new AtomicBoolean(false);
68914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
69914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
70914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
71914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    @Before
72914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public void setup() {
73914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        // Bind to PostMessageService only after CustomTabsService sends the callback to do so. This
74914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        // callback is sent after requestPostMessageChannel is called.
75914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mCallback = new TestCustomTabsCallback() {
76914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
77914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void extraCallback(String callbackName, Bundle args) {
78914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                if (TestCustomTabsService.CALLBACK_BIND_TO_POST_MESSAGE.equals(callbackName)) {
79914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    Intent postMessageServiceIntent = new Intent();
80914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    postMessageServiceIntent.setClassName(
81914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                            mContext.getPackageName(), PostMessageService.class.getName());
82914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    try {
83914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        mServiceRule.bindService(postMessageServiceIntent,
84914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                                mPostMessageServiceConnection, Context.BIND_AUTO_CREATE);
85914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    } catch (TimeoutException e) {
86914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                        fail();
87914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    }
88914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                }
89914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
90914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        };
91914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mContext = mActivityTestRule.getActivity();
92914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mCustomTabsServiceConnection = new CustomTabsServiceConnection() {
93914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
94914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
95914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mSession = client.newSession(mCallback);
9646ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal                mCustomTabsServiceConnected.set(true);
97914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
98914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
99914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
100914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onServiceDisconnected(ComponentName componentName) {
10146ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal                mCustomTabsServiceConnected.set(false);
102914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
103914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        };
104914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        mPostMessageServiceConnection = new PostMessageServiceConnection(
105914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                new CustomTabsSessionToken(mCallback.getStub())) {
106914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
107914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onPostMessageServiceConnected() {
108914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mPostMessageServiceConnected = true;
109914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
110914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
111914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
112914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public void onPostMessageServiceDisconnected() {
113914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mPostMessageServiceConnected = false;
114914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
115914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        };
116914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        Intent customTabsServiceIntent = new Intent();
117914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        customTabsServiceIntent.setClassName(
118914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                mContext.getPackageName(), TestCustomTabsService.class.getName());
119914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        try {
120914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            mServiceRule.bindService(customTabsServiceIntent,
121914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                    mCustomTabsServiceConnection, Context.BIND_AUTO_CREATE);
122914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        } catch (TimeoutException e) {
123914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            fail();
124914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        }
125914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
126914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal
127914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    @Test
128914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    public void testCustomTabsConnection() {
129914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        PollingCheck.waitFor(500, new PollingCheck.PollingCheckCondition() {
130914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
131914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public boolean canProceed() {
13246ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal                return mCustomTabsServiceConnected.get();
133914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
134914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        });
13546ecf802b827e0b515da29a9b4098abc8ed9d4dbYusuf Ozuysal        assertTrue(mCustomTabsServiceConnected.get());
136914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        assertTrue(mSession.requestPostMessageChannel(Uri.EMPTY));
137914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        assertEquals(CustomTabsService.RESULT_SUCCESS, mSession.postMessage("", null));
138914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        PollingCheck.waitFor(500, new PollingCheck.PollingCheckCondition() {
139914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            @Override
140914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            public boolean canProceed() {
141914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal                return mPostMessageServiceConnected;
142914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal            }
143914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        });
144914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal        assertTrue(mPostMessageServiceConnected);
145914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal    }
146914073c7cf933229a3f51ddeddb63bb9725a70beYusuf Ozuysal}
147