1/* 2 * Copyright (C) 2018 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 com.android.server.backup.transport; 18 19import static com.android.server.backup.TransportManager.SERVICE_ACTION_TRANSPORT_HOST; 20import static org.mockito.ArgumentMatchers.any; 21import static org.mockito.ArgumentMatchers.anyInt; 22import static org.mockito.Mockito.argThat; 23import static org.mockito.Mockito.spy; 24import static org.mockito.Mockito.verify; 25import static org.mockito.Mockito.when; 26 27import android.content.ComponentName; 28import android.content.Context; 29import android.content.Intent; 30import android.content.ServiceConnection; 31import android.os.Bundle; 32import android.os.UserHandle; 33import android.platform.test.annotations.Presubmit; 34 35import com.android.server.testing.FrameworkRobolectricTestRunner; 36import com.android.server.testing.SystemLoaderPackages; 37import org.junit.Before; 38import org.junit.Test; 39import org.junit.runner.RunWith; 40import org.mockito.ArgumentMatcher; 41import org.mockito.Mock; 42import org.mockito.MockitoAnnotations; 43import org.robolectric.annotation.Config; 44 45@RunWith(FrameworkRobolectricTestRunner.class) 46@Config(manifest = Config.NONE, sdk = 26) 47@SystemLoaderPackages({"com.android.server.backup"}) 48@Presubmit 49public class TransportClientManagerTest { 50 private static final String PACKAGE_NAME = "random.package.name"; 51 private static final String CLASS_NAME = "random.package.name.transport.Transport"; 52 53 @Mock private Context mContext; 54 @Mock private TransportConnectionListener mTransportConnectionListener; 55 private TransportClientManager mTransportClientManager; 56 private ComponentName mTransportComponent; 57 private Intent mBindIntent; 58 59 @Before 60 public void setUp() { 61 MockitoAnnotations.initMocks(this); 62 63 mTransportClientManager = new TransportClientManager(mContext, new TransportStats()); 64 mTransportComponent = new ComponentName(PACKAGE_NAME, CLASS_NAME); 65 mBindIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST).setComponent(mTransportComponent); 66 67 when(mContext.bindServiceAsUser( 68 any(Intent.class), 69 any(ServiceConnection.class), 70 anyInt(), 71 any(UserHandle.class))) 72 .thenReturn(true); 73 } 74 75 @Test 76 public void testGetTransportClient() { 77 TransportClient transportClient = 78 mTransportClientManager.getTransportClient(mTransportComponent, "caller"); 79 80 // Connect to be able to extract the intent 81 transportClient.connectAsync(mTransportConnectionListener, "caller"); 82 verify(mContext) 83 .bindServiceAsUser( 84 argThat(matchesIntentAndExtras(mBindIntent)), 85 any(ServiceConnection.class), 86 anyInt(), 87 any(UserHandle.class)); 88 } 89 90 @Test 91 public void testGetTransportClient_withExtras_createsTransportClientWithCorrectIntent() { 92 Bundle extras = new Bundle(); 93 extras.putBoolean("random_extra", true); 94 95 TransportClient transportClient = 96 mTransportClientManager.getTransportClient(mTransportComponent, extras, "caller"); 97 98 transportClient.connectAsync(mTransportConnectionListener, "caller"); 99 mBindIntent.putExtras(extras); 100 verify(mContext) 101 .bindServiceAsUser( 102 argThat(matchesIntentAndExtras(mBindIntent)), 103 any(ServiceConnection.class), 104 anyInt(), 105 any(UserHandle.class)); 106 } 107 108 @Test 109 public void testDisposeOfTransportClient() { 110 TransportClient transportClient = 111 spy(mTransportClientManager.getTransportClient(mTransportComponent, "caller")); 112 113 mTransportClientManager.disposeOfTransportClient(transportClient, "caller"); 114 115 verify(transportClient).unbind(any()); 116 verify(transportClient).markAsDisposed(); 117 } 118 119 private ArgumentMatcher<Intent> matchesIntentAndExtras(Intent expectedIntent) { 120 return (Intent actualIntent) -> { 121 if (!expectedIntent.filterEquals(actualIntent)) { 122 return false; 123 } 124 125 Bundle expectedExtras = expectedIntent.getExtras(); 126 Bundle actualExtras = actualIntent.getExtras(); 127 128 if (expectedExtras == null && actualExtras == null) { 129 return true; 130 } 131 132 if (expectedExtras == null || actualExtras == null) { 133 return false; 134 } 135 136 if (expectedExtras.size() != actualExtras.size()) { 137 return false; 138 } 139 140 for (String key : expectedExtras.keySet()) { 141 if (!expectedExtras.get(key).equals(actualExtras.get(key))) { 142 return false; 143 } 144 } 145 146 return true; 147 }; 148 } 149} 150