1 /* 2 * Copyright (C) 2015 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 package com.android.support.car.apitest; 17 18 import android.support.car.Car; 19 import android.support.car.CarAppContextManager; 20 import android.test.suitebuilder.annotation.MediumTest; 21 import android.util.Log; 22 23 import java.util.concurrent.Semaphore; 24 import java.util.concurrent.TimeUnit; 25 26 @MediumTest 27 public class CarAppContextManagerTest extends CarApiTestBase { 28 private static final String TAG = CarAppContextManager.class.getSimpleName(); 29 private CarAppContextManager mManager; 30 31 @Override 32 protected void setUp() throws Exception { 33 super.setUp(); 34 mManager = (CarAppContextManager) getCar().getCarManager(Car.APP_CONTEXT_SERVICE); 35 assertNotNull(mManager); 36 } 37 38 public void testSetActiveNullListener() throws Exception { 39 try { 40 mManager.setActiveContexts(null, CarAppContextManager.APP_CONTEXT_NAVIGATION); 41 fail(); 42 } catch (IllegalStateException e) { 43 // expected 44 } 45 } 46 47 public void testRegisterNull() throws Exception { 48 try { 49 mManager.registerContextListener(null, 0); 50 fail(); 51 } catch (IllegalArgumentException e) { 52 // expected 53 } 54 } 55 56 public void testRegisterUnregister() throws Exception { 57 ContextChangeListerner listener = new ContextChangeListerner(); 58 ContextChangeListerner listener2 = new ContextChangeListerner(); 59 mManager.registerContextListener(listener, 0); 60 mManager.registerContextListener(listener2, 0); 61 mManager.unregisterContextListener(); 62 // this one is no-op 63 mManager.unregisterContextListener(); 64 } 65 66 public void testContextChange() throws Exception { 67 DefaultServiceConnectionListener connectionListener = 68 new DefaultServiceConnectionListener(); 69 Car car2 = Car.createCar(getContext(), connectionListener, null); 70 car2.connect(); 71 connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); 72 CarAppContextManager manager2 = (CarAppContextManager) 73 car2.getCarManager(Car.APP_CONTEXT_SERVICE); 74 assertNotNull(manager2); 75 76 assertEquals(0, mManager.getActiveAppContexts()); 77 ContextChangeListerner change = new ContextChangeListerner(); 78 ContextChangeListerner change2 = new ContextChangeListerner(); 79 ContextOwnershipChangeListerner owner = new ContextOwnershipChangeListerner(); 80 ContextOwnershipChangeListerner owner2 = new ContextOwnershipChangeListerner(); 81 mManager.registerContextListener(change, CarAppContextManager.APP_CONTEXT_NAVIGATION | 82 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 83 manager2.registerContextListener(change2, CarAppContextManager.APP_CONTEXT_NAVIGATION | 84 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 85 86 mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION); 87 int expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION; 88 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 89 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 90 assertTrue(mManager.isOwningContext(expectedContexts)); 91 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 92 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION | 93 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 94 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 95 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 96 assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 97 expectedContexts)); 98 // change should not get notification for its own change 99 assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 100 101 mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 102 expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION | 103 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND; 104 assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 105 assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 106 assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION | 107 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 108 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 109 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 110 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 111 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 112 assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 113 expectedContexts)); 114 // change should not get notification for its own change 115 assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 116 117 // this should be no-op 118 mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION); 119 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 120 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 121 assertFalse(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 122 assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 123 124 manager2.setActiveContexts(owner2, CarAppContextManager.APP_CONTEXT_NAVIGATION); 125 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 126 assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 127 assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 128 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 129 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 130 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 131 assertTrue(owner.waitForOwnershipLossAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 132 CarAppContextManager.APP_CONTEXT_NAVIGATION)); 133 134 // no-op as it is not owning it 135 mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); 136 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 137 assertTrue(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 138 assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 139 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 140 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 141 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 142 143 mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 144 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 145 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 146 assertTrue(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 147 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 148 expectedContexts = CarAppContextManager.APP_CONTEXT_NAVIGATION; 149 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 150 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 151 assertTrue(change2.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 152 CarAppContextManager.APP_CONTEXT_NAVIGATION)); 153 assertFalse(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 154 155 manager2.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); 156 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 157 assertFalse(mManager.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 158 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_NAVIGATION)); 159 assertFalse(manager2.isOwningContext(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND)); 160 expectedContexts = 0; 161 assertEquals(expectedContexts, mManager.getActiveAppContexts()); 162 assertEquals(expectedContexts, manager2.getActiveAppContexts()); 163 assertTrue(change.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 164 mManager.unregisterContextListener(); 165 manager2.unregisterContextListener(); 166 } 167 168 public void testFilter() throws Exception { 169 DefaultServiceConnectionListener connectionListener = 170 new DefaultServiceConnectionListener(); 171 Car car2 = Car.createCar(getContext(), connectionListener); 172 car2.connect(); 173 connectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS); 174 CarAppContextManager manager2 = (CarAppContextManager) 175 car2.getCarManager(Car.APP_CONTEXT_SERVICE); 176 assertNotNull(manager2); 177 178 assertEquals(0, mManager.getActiveAppContexts()); 179 ContextChangeListerner change = new ContextChangeListerner(); 180 ContextChangeListerner listener = new ContextChangeListerner(); 181 ContextOwnershipChangeListerner owner = new ContextOwnershipChangeListerner(); 182 mManager.registerContextListener(change, CarAppContextManager.APP_CONTEXT_NAVIGATION | 183 CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 184 manager2.registerContextListener(listener, CarAppContextManager.APP_CONTEXT_NAVIGATION); 185 mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_NAVIGATION); 186 assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 187 CarAppContextManager.APP_CONTEXT_NAVIGATION)); 188 mManager.setActiveContexts(owner, CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 189 assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 190 mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_VOICE_COMMAND); 191 assertFalse(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 192 mManager.resetActiveContexts(CarAppContextManager.APP_CONTEXT_NAVIGATION); 193 assertTrue(listener.waitForContextChangeAndAssert(DEFAULT_WAIT_TIMEOUT_MS, 0)); 194 } 195 196 private class ContextChangeListerner implements CarAppContextManager.AppContextChangeListener { 197 private int mLastChangeEvent; 198 private final Semaphore mChangeWait = new Semaphore(0); 199 200 public boolean waitForContextChangeAndAssert(long timeoutMs, int expectedContexts) 201 throws Exception { 202 if (!mChangeWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { 203 return false; 204 } 205 assertEquals(expectedContexts, mLastChangeEvent); 206 return true; 207 } 208 @Override 209 public void onAppContextChange(int activeContexts) { 210 Log.i(TAG, "onAppContextChange " + Integer.toHexString(activeContexts)); 211 assertMainThread(); 212 mLastChangeEvent = activeContexts; 213 mChangeWait.release(); 214 } 215 } 216 217 private class ContextOwnershipChangeListerner 218 implements CarAppContextManager.AppContextOwnershipChangeListener { 219 private int mLastLossEvent; 220 private final Semaphore mLossEventWait = new Semaphore(0); 221 222 public boolean waitForOwnershipLossAndAssert(long timeoutMs, int expectedContexts) 223 throws Exception { 224 if (!mLossEventWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) { 225 return false; 226 } 227 assertEquals(expectedContexts, mLastLossEvent); 228 return true; 229 } 230 231 @Override 232 public void onAppContextOwnershipLoss(int context) { 233 Log.i(TAG, "onAppContextOwnershipLoss " + Integer.toHexString(context)); 234 assertMainThread(); 235 mLastLossEvent = context; 236 mLossEventWait.release(); 237 } 238 } 239 } 240