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