1/* 2 * Copyright (C) 2016 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 */ 16package android.support.v4.media; 17 18import static android.support.test.InstrumentationRegistry.getInstrumentation; 19 20import static junit.framework.Assert.assertEquals; 21import static junit.framework.Assert.assertFalse; 22import static junit.framework.Assert.assertNotNull; 23import static junit.framework.Assert.assertNull; 24import static junit.framework.Assert.assertTrue; 25 26import android.content.ComponentName; 27import android.os.Build; 28import android.os.Bundle; 29import android.support.test.filters.MediumTest; 30import android.support.test.filters.SmallTest; 31import android.support.test.runner.AndroidJUnit4; 32import android.support.testutils.PollingCheck; 33import android.support.v4.media.MediaBrowserCompat.MediaItem; 34 35import org.junit.Before; 36import org.junit.Test; 37import org.junit.runner.RunWith; 38 39import java.util.List; 40 41/** 42 * Test {@link android.support.v4.media.MediaBrowserServiceCompat}. 43 */ 44@RunWith(AndroidJUnit4.class) 45public class MediaBrowserServiceCompatTest { 46 // The maximum time to wait for an operation. 47 private static final long TIME_OUT_MS = 3000L; 48 private static final long WAIT_TIME_FOR_NO_RESPONSE_MS = 500L; 49 private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName( 50 "android.support.mediacompat.test", 51 "android.support.v4.media.StubMediaBrowserServiceCompat"); 52 private static final ComponentName TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION = 53 new ComponentName( 54 "android.support.mediacompat.test", 55 "android.support.v4.media" 56 + ".StubMediaBrowserServiceCompatWithDelayedMediaSession"); 57 private static final String TEST_KEY_1 = "key_1"; 58 private static final String TEST_VALUE_1 = "value_1"; 59 private static final String TEST_KEY_2 = "key_2"; 60 private static final String TEST_VALUE_2 = "value_2"; 61 private static final String TEST_KEY_3 = "key_3"; 62 private static final String TEST_VALUE_3 = "value_3"; 63 private static final String TEST_KEY_4 = "key_4"; 64 private static final String TEST_VALUE_4 = "value_4"; 65 private final Object mWaitLock = new Object(); 66 67 private final ConnectionCallback mConnectionCallback = new ConnectionCallback(); 68 private final SubscriptionCallback mSubscriptionCallback = new SubscriptionCallback(); 69 private final ItemCallback mItemCallback = new ItemCallback(); 70 private final SearchCallback mSearchCallback = new SearchCallback(); 71 72 private MediaBrowserCompat mMediaBrowser; 73 private MediaBrowserCompat mMediaBrowserForDelayedMediaSession; 74 private StubMediaBrowserServiceCompat mMediaBrowserService; 75 private Bundle mRootHints; 76 77 @Before 78 public void setUp() throws Exception { 79 getInstrumentation().runOnMainSync(new Runnable() { 80 @Override 81 public void run() { 82 mRootHints = new Bundle(); 83 mRootHints.putBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_RECENT, true); 84 mRootHints.putBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_OFFLINE, true); 85 mRootHints.putBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_SUGGESTED, true); 86 mMediaBrowser = new MediaBrowserCompat(getInstrumentation().getTargetContext(), 87 TEST_BROWSER_SERVICE, mConnectionCallback, mRootHints); 88 } 89 }); 90 synchronized (mWaitLock) { 91 mMediaBrowser.connect(); 92 mWaitLock.wait(TIME_OUT_MS); 93 } 94 assertNotNull(mMediaBrowserService); 95 mMediaBrowserService.mCustomActionExtras = null; 96 mMediaBrowserService.mCustomActionResult = null; 97 } 98 99 @Test 100 @SmallTest 101 public void testGetSessionToken() { 102 assertEquals(StubMediaBrowserServiceCompat.sSession.getSessionToken(), 103 mMediaBrowserService.getSessionToken()); 104 } 105 106 @Test 107 @SmallTest 108 public void testNotifyChildrenChanged() throws Exception { 109 synchronized (mWaitLock) { 110 mSubscriptionCallback.reset(); 111 mMediaBrowser.subscribe( 112 StubMediaBrowserServiceCompat.MEDIA_ID_ROOT, mSubscriptionCallback); 113 mWaitLock.wait(TIME_OUT_MS); 114 assertTrue(mSubscriptionCallback.mOnChildrenLoaded); 115 116 mSubscriptionCallback.reset(); 117 mMediaBrowserService.notifyChildrenChanged(StubMediaBrowserServiceCompat.MEDIA_ID_ROOT); 118 mWaitLock.wait(TIME_OUT_MS); 119 assertTrue(mSubscriptionCallback.mOnChildrenLoaded); 120 } 121 } 122 123 @Test 124 @SmallTest 125 public void testNotifyChildrenChangedWithPagination() throws Exception { 126 synchronized (mWaitLock) { 127 final int pageSize = 5; 128 final int page = 2; 129 Bundle options = new Bundle(); 130 options.putInt(MediaBrowserCompat.EXTRA_PAGE_SIZE, pageSize); 131 options.putInt(MediaBrowserCompat.EXTRA_PAGE, page); 132 133 mSubscriptionCallback.reset(); 134 mMediaBrowser.subscribe(StubMediaBrowserServiceCompat.MEDIA_ID_ROOT, options, 135 mSubscriptionCallback); 136 mWaitLock.wait(TIME_OUT_MS); 137 assertTrue(mSubscriptionCallback.mOnChildrenLoadedWithOptions); 138 139 mSubscriptionCallback.reset(); 140 mMediaBrowserService.notifyChildrenChanged(StubMediaBrowserServiceCompat.MEDIA_ID_ROOT); 141 mWaitLock.wait(TIME_OUT_MS); 142 assertTrue(mSubscriptionCallback.mOnChildrenLoadedWithOptions); 143 } 144 } 145 146 @Test 147 @MediumTest 148 public void testDelayedNotifyChildrenChanged() throws Exception { 149 synchronized (mWaitLock) { 150 mSubscriptionCallback.reset(); 151 mMediaBrowser.subscribe(StubMediaBrowserServiceCompat.MEDIA_ID_CHILDREN_DELAYED, 152 mSubscriptionCallback); 153 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 154 assertFalse(mSubscriptionCallback.mOnChildrenLoaded); 155 156 mMediaBrowserService.sendDelayedNotifyChildrenChanged(); 157 mWaitLock.wait(TIME_OUT_MS); 158 assertTrue(mSubscriptionCallback.mOnChildrenLoaded); 159 160 mSubscriptionCallback.reset(); 161 mMediaBrowserService.notifyChildrenChanged( 162 StubMediaBrowserServiceCompat.MEDIA_ID_CHILDREN_DELAYED); 163 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 164 assertFalse(mSubscriptionCallback.mOnChildrenLoaded); 165 166 mMediaBrowserService.sendDelayedNotifyChildrenChanged(); 167 mWaitLock.wait(TIME_OUT_MS); 168 assertTrue(mSubscriptionCallback.mOnChildrenLoaded); 169 } 170 } 171 172 @Test 173 @MediumTest 174 public void testDelayedItem() throws Exception { 175 synchronized (mWaitLock) { 176 mItemCallback.reset(); 177 mMediaBrowser.getItem( 178 StubMediaBrowserServiceCompat.MEDIA_ID_CHILDREN_DELAYED, mItemCallback); 179 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 180 assertFalse(mItemCallback.mOnItemLoaded); 181 182 mItemCallback.reset(); 183 mMediaBrowserService.sendDelayedItemLoaded(); 184 mWaitLock.wait(TIME_OUT_MS); 185 assertTrue(mItemCallback.mOnItemLoaded); 186 } 187 } 188 189 @Test 190 @SmallTest 191 public void testSearch() throws Exception { 192 final String key = "test-key"; 193 final String val = "test-val"; 194 195 synchronized (mWaitLock) { 196 mSearchCallback.reset(); 197 mMediaBrowser.search(StubMediaBrowserServiceCompat.SEARCH_QUERY_FOR_NO_RESULT, null, 198 mSearchCallback); 199 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 200 assertTrue(mSearchCallback.mOnSearchResult); 201 assertTrue(mSearchCallback.mSearchResults != null 202 && mSearchCallback.mSearchResults.size() == 0); 203 assertEquals(null, mSearchCallback.mSearchExtras); 204 205 mSearchCallback.reset(); 206 mMediaBrowser.search(StubMediaBrowserServiceCompat.SEARCH_QUERY_FOR_ERROR, null, 207 mSearchCallback); 208 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 209 assertTrue(mSearchCallback.mOnSearchResult); 210 assertNull(mSearchCallback.mSearchResults); 211 assertEquals(null, mSearchCallback.mSearchExtras); 212 213 mSearchCallback.reset(); 214 Bundle extras = new Bundle(); 215 extras.putString(key, val); 216 mMediaBrowser.search(StubMediaBrowserServiceCompat.SEARCH_QUERY, extras, 217 mSearchCallback); 218 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 219 assertTrue(mSearchCallback.mOnSearchResult); 220 assertNotNull(mSearchCallback.mSearchResults); 221 for (MediaItem item : mSearchCallback.mSearchResults) { 222 assertNotNull(item.getMediaId()); 223 assertTrue(item.getMediaId().contains(StubMediaBrowserServiceCompat.SEARCH_QUERY)); 224 } 225 assertNotNull(mSearchCallback.mSearchExtras); 226 assertEquals(val, mSearchCallback.mSearchExtras.getString(key)); 227 } 228 } 229 230 @Test 231 @SmallTest 232 public void testSendCustomAction() throws Exception { 233 synchronized (mWaitLock) { 234 CustomActionCallback callback = new CustomActionCallback(); 235 Bundle extras = new Bundle(); 236 extras.putString(TEST_KEY_1, TEST_VALUE_1); 237 mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras, 238 callback); 239 new PollingCheck(TIME_OUT_MS) { 240 @Override 241 protected boolean check() { 242 return mMediaBrowserService.mCustomActionResult != null; 243 } 244 }.run(); 245 assertNotNull(mMediaBrowserService.mCustomActionResult); 246 assertNotNull(mMediaBrowserService.mCustomActionExtras); 247 assertEquals(TEST_VALUE_1, 248 mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1)); 249 250 callback.reset(); 251 Bundle bundle1 = new Bundle(); 252 bundle1.putString(TEST_KEY_2, TEST_VALUE_2); 253 mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle1); 254 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 255 assertTrue(callback.mOnProgressUpdateCalled); 256 assertNotNull(callback.mExtras); 257 assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1)); 258 assertNotNull(callback.mData); 259 assertEquals(TEST_VALUE_2, callback.mData.getString(TEST_KEY_2)); 260 261 callback.reset(); 262 Bundle bundle2 = new Bundle(); 263 bundle2.putString(TEST_KEY_3, TEST_VALUE_3); 264 mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle2); 265 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 266 assertTrue(callback.mOnProgressUpdateCalled); 267 assertNotNull(callback.mExtras); 268 assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1)); 269 assertNotNull(callback.mData); 270 assertEquals(TEST_VALUE_3, callback.mData.getString(TEST_KEY_3)); 271 272 Bundle bundle3 = new Bundle(); 273 bundle3.putString(TEST_KEY_4, TEST_VALUE_4); 274 callback.reset(); 275 mMediaBrowserService.mCustomActionResult.sendResult(bundle3); 276 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 277 assertTrue(callback.mOnResultCalled); 278 assertNotNull(callback.mExtras); 279 assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1)); 280 assertNotNull(callback.mData); 281 assertEquals(TEST_VALUE_4, callback.mData.getString(TEST_KEY_4)); 282 } 283 } 284 285 @Test 286 @SmallTest 287 public void testSendCustomActionWithDetachedError() throws Exception { 288 synchronized (mWaitLock) { 289 CustomActionCallback callback = new CustomActionCallback(); 290 Bundle extras = new Bundle(); 291 extras.putString(TEST_KEY_1, TEST_VALUE_1); 292 mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras, 293 callback); 294 new PollingCheck(TIME_OUT_MS) { 295 @Override 296 protected boolean check() { 297 return mMediaBrowserService.mCustomActionResult != null; 298 } 299 }.run(); 300 assertNotNull(mMediaBrowserService.mCustomActionResult); 301 assertNotNull(mMediaBrowserService.mCustomActionExtras); 302 assertEquals(TEST_VALUE_1, 303 mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1)); 304 305 callback.reset(); 306 Bundle bundle1 = new Bundle(); 307 bundle1.putString(TEST_KEY_2, TEST_VALUE_2); 308 mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle1); 309 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 310 assertTrue(callback.mOnProgressUpdateCalled); 311 assertNotNull(callback.mExtras); 312 assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1)); 313 assertNotNull(callback.mData); 314 assertEquals(TEST_VALUE_2, callback.mData.getString(TEST_KEY_2)); 315 316 callback.reset(); 317 Bundle bundle2 = new Bundle(); 318 bundle2.putString(TEST_KEY_3, TEST_VALUE_3); 319 mMediaBrowserService.mCustomActionResult.sendError(bundle2); 320 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 321 assertTrue(callback.mOnErrorCalled); 322 assertNotNull(callback.mExtras); 323 assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1)); 324 assertNotNull(callback.mData); 325 assertEquals(TEST_VALUE_3, callback.mData.getString(TEST_KEY_3)); 326 } 327 } 328 329 @Test 330 @SmallTest 331 public void testSendCustomActionWithNullCallback() throws Exception { 332 Bundle extras = new Bundle(); 333 extras.putString(TEST_KEY_1, TEST_VALUE_1); 334 mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras, null); 335 new PollingCheck(TIME_OUT_MS) { 336 @Override 337 protected boolean check() { 338 return mMediaBrowserService.mCustomActionResult != null; 339 } 340 }.run(); 341 assertNotNull(mMediaBrowserService.mCustomActionResult); 342 assertNotNull(mMediaBrowserService.mCustomActionExtras); 343 assertEquals(TEST_VALUE_1, mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1)); 344 } 345 346 @Test 347 @SmallTest 348 public void testSendCustomActionWithError() throws Exception { 349 synchronized (mWaitLock) { 350 CustomActionCallback callback = new CustomActionCallback(); 351 mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION_FOR_ERROR, 352 null, callback); 353 new PollingCheck(TIME_OUT_MS) { 354 @Override 355 protected boolean check() { 356 return mMediaBrowserService.mCustomActionResult != null; 357 } 358 }.run(); 359 assertNotNull(mMediaBrowserService.mCustomActionResult); 360 assertNull(mMediaBrowserService.mCustomActionExtras); 361 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 362 assertTrue(callback.mOnErrorCalled); 363 } 364 } 365 366 @Test 367 @SmallTest 368 public void testBrowserRoot() { 369 final String id = "test-id"; 370 final String key = "test-key"; 371 final String val = "test-val"; 372 final Bundle extras = new Bundle(); 373 extras.putString(key, val); 374 375 MediaBrowserServiceCompat.BrowserRoot browserRoot = 376 new MediaBrowserServiceCompat.BrowserRoot(id, extras); 377 assertEquals(id, browserRoot.getRootId()); 378 assertEquals(val, browserRoot.getExtras().getString(key)); 379 } 380 381 382 @Test 383 @SmallTest 384 public void testDelayedSetSessionToken() throws Exception { 385 // This test has no meaning in API 21. The framework MediaBrowserService just connects to 386 // the media browser without waiting setMediaSession() to be called. 387 if (Build.VERSION.SDK_INT == 21) { 388 return; 389 } 390 final ConnectionCallbackForDelayedMediaSession callback = 391 new ConnectionCallbackForDelayedMediaSession(); 392 393 getInstrumentation().runOnMainSync(new Runnable() { 394 @Override 395 public void run() { 396 mMediaBrowserForDelayedMediaSession = 397 new MediaBrowserCompat(getInstrumentation().getTargetContext(), 398 TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION, callback, null); 399 } 400 }); 401 402 synchronized (mWaitLock) { 403 mMediaBrowserForDelayedMediaSession.connect(); 404 mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS); 405 assertEquals(0, callback.mConnectedCount); 406 407 StubMediaBrowserServiceCompatWithDelayedMediaSession.sInstance.callSetSessionToken(); 408 mWaitLock.wait(TIME_OUT_MS); 409 assertEquals(1, callback.mConnectedCount); 410 411 if (Build.VERSION.SDK_INT >= 21) { 412 assertNotNull( 413 mMediaBrowserForDelayedMediaSession.getSessionToken().getExtraBinder()); 414 } 415 } 416 } 417 418 private void assertRootHints(MediaItem item) { 419 Bundle rootHints = item.getDescription().getExtras(); 420 assertNotNull(rootHints); 421 assertEquals(mRootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_RECENT), 422 rootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_RECENT)); 423 assertEquals(mRootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_OFFLINE), 424 rootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_OFFLINE)); 425 assertEquals(mRootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_SUGGESTED), 426 rootHints.getBoolean(MediaBrowserServiceCompat.BrowserRoot.EXTRA_SUGGESTED)); 427 } 428 429 private class ConnectionCallback extends MediaBrowserCompat.ConnectionCallback { 430 @Override 431 public void onConnected() { 432 synchronized (mWaitLock) { 433 mMediaBrowserService = StubMediaBrowserServiceCompat.sInstance; 434 mWaitLock.notify(); 435 } 436 } 437 } 438 439 private class SubscriptionCallback extends MediaBrowserCompat.SubscriptionCallback { 440 boolean mOnChildrenLoaded; 441 boolean mOnChildrenLoadedWithOptions; 442 443 @Override 444 public void onChildrenLoaded(String parentId, List<MediaItem> children) { 445 synchronized (mWaitLock) { 446 mOnChildrenLoaded = true; 447 if (children != null) { 448 for (MediaItem item : children) { 449 assertRootHints(item); 450 } 451 } 452 mWaitLock.notify(); 453 } 454 } 455 456 @Override 457 public void onChildrenLoaded(String parentId, List<MediaItem> children, Bundle options) { 458 synchronized (mWaitLock) { 459 mOnChildrenLoadedWithOptions = true; 460 if (children != null) { 461 for (MediaItem item : children) { 462 assertRootHints(item); 463 } 464 } 465 mWaitLock.notify(); 466 } 467 } 468 469 public void reset() { 470 mOnChildrenLoaded = false; 471 mOnChildrenLoadedWithOptions = false; 472 } 473 } 474 475 private class ItemCallback extends MediaBrowserCompat.ItemCallback { 476 boolean mOnItemLoaded; 477 478 @Override 479 public void onItemLoaded(MediaItem item) { 480 synchronized (mWaitLock) { 481 mOnItemLoaded = true; 482 assertRootHints(item); 483 mWaitLock.notify(); 484 } 485 } 486 487 public void reset() { 488 mOnItemLoaded = false; 489 } 490 } 491 492 private class SearchCallback extends MediaBrowserCompat.SearchCallback { 493 boolean mOnSearchResult; 494 Bundle mSearchExtras; 495 List<MediaItem> mSearchResults; 496 497 @Override 498 public void onSearchResult(String query, Bundle extras, List<MediaItem> items) { 499 synchronized (mWaitLock) { 500 mOnSearchResult = true; 501 mSearchResults = items; 502 mSearchExtras = extras; 503 mWaitLock.notify(); 504 } 505 } 506 507 @Override 508 public void onError(String query, Bundle extras) { 509 synchronized (mWaitLock) { 510 mOnSearchResult = true; 511 mSearchResults = null; 512 mSearchExtras = extras; 513 mWaitLock.notify(); 514 } 515 } 516 517 public void reset() { 518 mOnSearchResult = false; 519 mSearchExtras = null; 520 mSearchResults = null; 521 } 522 } 523 524 private class CustomActionCallback extends MediaBrowserCompat.CustomActionCallback { 525 String mAction; 526 Bundle mExtras; 527 Bundle mData; 528 boolean mOnProgressUpdateCalled; 529 boolean mOnResultCalled; 530 boolean mOnErrorCalled; 531 532 @Override 533 public void onProgressUpdate(String action, Bundle extras, Bundle data) { 534 synchronized (mWaitLock) { 535 mOnProgressUpdateCalled = true; 536 mAction = action; 537 mExtras = extras; 538 mData = data; 539 mWaitLock.notify(); 540 } 541 } 542 543 @Override 544 public void onResult(String action, Bundle extras, Bundle resultData) { 545 synchronized (mWaitLock) { 546 mOnResultCalled = true; 547 mAction = action; 548 mExtras = extras; 549 mData = resultData; 550 mWaitLock.notify(); 551 } 552 } 553 554 @Override 555 public void onError(String action, Bundle extras, Bundle data) { 556 synchronized (mWaitLock) { 557 mOnErrorCalled = true; 558 mAction = action; 559 mExtras = extras; 560 mData = data; 561 mWaitLock.notify(); 562 } 563 } 564 565 public void reset() { 566 mOnResultCalled = false; 567 mOnProgressUpdateCalled = false; 568 mOnErrorCalled = false; 569 mAction = null; 570 mExtras = null; 571 mData = null; 572 } 573 } 574 575 private class ConnectionCallbackForDelayedMediaSession extends 576 MediaBrowserCompat.ConnectionCallback { 577 private int mConnectedCount = 0; 578 579 @Override 580 public void onConnected() { 581 synchronized (mWaitLock) { 582 mConnectedCount++; 583 mWaitLock.notify(); 584 } 585 } 586 }; 587 588} 589