1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.customtabs; 18 19import static org.junit.Assert.assertEquals; 20import static org.junit.Assert.assertTrue; 21import static org.junit.Assert.fail; 22 23import android.content.ComponentName; 24import android.content.Context; 25import android.content.Intent; 26import android.net.Uri; 27import android.os.Bundle; 28import android.support.test.filters.SmallTest; 29import android.support.test.rule.ActivityTestRule; 30import android.support.test.rule.ServiceTestRule; 31import android.support.test.runner.AndroidJUnit4; 32import android.support.testutils.PollingCheck; 33 34import org.junit.Before; 35import org.junit.Rule; 36import org.junit.Test; 37import org.junit.runner.RunWith; 38 39import java.util.concurrent.TimeoutException; 40import java.util.concurrent.atomic.AtomicBoolean; 41 42 43/** 44 * Tests for a complete loop between a browser side {@link CustomTabsService} 45 * and a client side {@link PostMessageService}. Both services are bound to through 46 * {@link ServiceTestRule}, but {@link CustomTabsCallback#extraCallback} is used to link browser 47 * side actions. 48 */ 49@RunWith(AndroidJUnit4.class) 50@SmallTest 51public class PostMessageTest { 52 @Rule 53 public final ServiceTestRule mServiceRule; 54 @Rule 55 public final ActivityTestRule<TestActivity> mActivityTestRule; 56 private TestCustomTabsCallback mCallback; 57 private Context mContext; 58 private CustomTabsServiceConnection mCustomTabsServiceConnection; 59 private PostMessageServiceConnection mPostMessageServiceConnection; 60 private AtomicBoolean mCustomTabsServiceConnected; 61 private boolean mPostMessageServiceConnected; 62 private CustomTabsSession mSession; 63 64 public PostMessageTest() { 65 mActivityTestRule = new ActivityTestRule<TestActivity>(TestActivity.class); 66 mServiceRule = new ServiceTestRule(); 67 mCustomTabsServiceConnected = new AtomicBoolean(false); 68 } 69 70 71 @Before 72 public void setup() { 73 // Bind to PostMessageService only after CustomTabsService sends the callback to do so. This 74 // callback is sent after requestPostMessageChannel is called. 75 mCallback = new TestCustomTabsCallback() { 76 @Override 77 public void extraCallback(String callbackName, Bundle args) { 78 if (TestCustomTabsService.CALLBACK_BIND_TO_POST_MESSAGE.equals(callbackName)) { 79 Intent postMessageServiceIntent = new Intent(); 80 postMessageServiceIntent.setClassName( 81 mContext.getPackageName(), PostMessageService.class.getName()); 82 try { 83 mServiceRule.bindService(postMessageServiceIntent, 84 mPostMessageServiceConnection, Context.BIND_AUTO_CREATE); 85 } catch (TimeoutException e) { 86 fail(); 87 } 88 } 89 } 90 }; 91 mContext = mActivityTestRule.getActivity(); 92 mCustomTabsServiceConnection = new CustomTabsServiceConnection() { 93 @Override 94 public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) { 95 mSession = client.newSession(mCallback); 96 mCustomTabsServiceConnected.set(true); 97 } 98 99 @Override 100 public void onServiceDisconnected(ComponentName componentName) { 101 mCustomTabsServiceConnected.set(false); 102 } 103 }; 104 mPostMessageServiceConnection = new PostMessageServiceConnection( 105 new CustomTabsSessionToken(mCallback.getStub())) { 106 @Override 107 public void onPostMessageServiceConnected() { 108 mPostMessageServiceConnected = true; 109 } 110 111 @Override 112 public void onPostMessageServiceDisconnected() { 113 mPostMessageServiceConnected = false; 114 } 115 }; 116 Intent customTabsServiceIntent = new Intent(); 117 customTabsServiceIntent.setClassName( 118 mContext.getPackageName(), TestCustomTabsService.class.getName()); 119 try { 120 mServiceRule.bindService(customTabsServiceIntent, 121 mCustomTabsServiceConnection, Context.BIND_AUTO_CREATE); 122 } catch (TimeoutException e) { 123 fail(); 124 } 125 } 126 127 @Test 128 public void testCustomTabsConnection() { 129 PollingCheck.waitFor(500, new PollingCheck.PollingCheckCondition() { 130 @Override 131 public boolean canProceed() { 132 return mCustomTabsServiceConnected.get(); 133 } 134 }); 135 assertTrue(mCustomTabsServiceConnected.get()); 136 assertTrue(mSession.requestPostMessageChannel(Uri.EMPTY)); 137 assertEquals(CustomTabsService.RESULT_SUCCESS, mSession.postMessage("", null)); 138 PollingCheck.waitFor(500, new PollingCheck.PollingCheckCondition() { 139 @Override 140 public boolean canProceed() { 141 return mPostMessageServiceConnected; 142 } 143 }); 144 assertTrue(mPostMessageServiceConnected); 145 } 146} 147