blob: acd670f6748c44c3a69d3131d2ce94149c15ab61 [file] [log] [blame]
Artem Iglikov5ed1dab2017-05-25 15:56:05 +01001/*
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 com.android.server.backup;
18
19import static com.google.common.truth.Truth.assertThat;
20
Artem Iglikov19e12272017-05-31 17:12:28 +010021import static org.mockito.Mockito.mock;
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000022import static org.mockito.Mockito.when;
Bernardo Rufino90a88022017-11-13 17:19:15 +000023import static org.robolectric.shadow.api.Shadow.extract;
Bernardo Rufino24476872017-12-21 11:43:16 +000024import static org.testng.Assert.expectThrows;
Artem Iglikov19e12272017-05-31 17:12:28 +010025
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000026import android.annotation.Nullable;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010027import android.content.ComponentName;
28import android.content.Intent;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010029import android.content.pm.ApplicationInfo;
30import android.content.pm.PackageInfo;
31import android.content.pm.ResolveInfo;
32import android.content.pm.ServiceInfo;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010033import android.os.IBinder;
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000034import android.os.RemoteException;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010035import android.platform.test.annotations.Presubmit;
36
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000037import com.android.internal.backup.IBackupTransport;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010038import com.android.server.backup.testing.ShadowBackupTransportStub;
Artem Iglikov19e12272017-05-31 17:12:28 +010039import com.android.server.backup.testing.ShadowContextImplForBackup;
Bernardo Rufino90a88022017-11-13 17:19:15 +000040import com.android.server.backup.testing.ShadowPackageManagerForBackup;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010041import com.android.server.backup.testing.TransportBoundListenerStub;
Bernardo Rufinoab953332017-11-22 22:10:32 +000042import com.android.server.backup.transport.TransportClient;
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000043import com.android.server.backup.transport.TransportNotRegisteredException;
Bernardo Rufino90a88022017-11-13 17:19:15 +000044import com.android.server.testing.FrameworkRobolectricTestRunner;
45import com.android.server.testing.SystemLoaderClasses;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010046
Artem Iglikov19e12272017-05-31 17:12:28 +010047import org.junit.After;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010048import org.junit.Before;
49import org.junit.Test;
50import org.junit.runner.RunWith;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010051import org.mockito.MockitoAnnotations;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010052import org.robolectric.RuntimeEnvironment;
53import org.robolectric.annotation.Config;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010054import org.robolectric.shadows.ShadowLog;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010055import org.robolectric.shadows.ShadowLooper;
Bernardo Rufino90a88022017-11-13 17:19:15 +000056import org.robolectric.shadows.ShadowPackageManager;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010057
Artem Iglikovbd476ea2017-09-01 10:57:26 +010058import java.util.ArrayList;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010059import java.util.Arrays;
Artem Iglikovbd476ea2017-09-01 10:57:26 +010060import java.util.Collections;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010061import java.util.HashSet;
62import java.util.List;
63
Bernardo Rufino90a88022017-11-13 17:19:15 +000064@RunWith(FrameworkRobolectricTestRunner.class)
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010065@Config(
66 manifest = Config.NONE,
Bernardo Rufino90a88022017-11-13 17:19:15 +000067 sdk = 26,
Artem Iglikovbd476ea2017-09-01 10:57:26 +010068 shadows = {
Artem Iglikov19e12272017-05-31 17:12:28 +010069 ShadowContextImplForBackup.class,
Bernardo Rufino90a88022017-11-13 17:19:15 +000070 ShadowBackupTransportStub.class,
71 ShadowPackageManagerForBackup.class
Artem Iglikovbd476ea2017-09-01 10:57:26 +010072 }
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010073)
Bernardo Rufino90a88022017-11-13 17:19:15 +000074@SystemLoaderClasses({TransportManager.class})
Artem Iglikovbd476ea2017-09-01 10:57:26 +010075@Presubmit
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010076public class TransportManagerTest {
77 private static final String PACKAGE_NAME = "some.package.name";
Artem Iglikov19e12272017-05-31 17:12:28 +010078 private static final String ANOTHER_PACKAGE_NAME = "another.package.name";
79
80 private TransportInfo mTransport1;
81 private TransportInfo mTransport2;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010082
Bernardo Rufino90a88022017-11-13 17:19:15 +000083 private ShadowPackageManager mPackageManagerShadow;
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010084
Artem Iglikovbd476ea2017-09-01 10:57:26 +010085 private final TransportBoundListenerStub mTransportBoundListenerStub =
86 new TransportBoundListenerStub(true);
Artem Iglikov5ed1dab2017-05-25 15:56:05 +010087
88 @Before
Artem Iglikovbd476ea2017-09-01 10:57:26 +010089 public void setUp() throws Exception {
90 MockitoAnnotations.initMocks(this);
91
92 ShadowLog.stream = System.out;
Bernardo Rufino90a88022017-11-13 17:19:15 +000093
94 mPackageManagerShadow =
95 (ShadowPackageManagerForBackup)
96 extract(RuntimeEnvironment.application.getPackageManager());
Artem Iglikovbd476ea2017-09-01 10:57:26 +010097
Bernardo Rufino7f14ede2017-12-08 19:55:03 +000098 mTransport1 = new TransportInfo(
99 PACKAGE_NAME,
100 "transport1.name",
101 new Intent(),
102 "currentDestinationString",
103 new Intent(),
104 "dataManagementLabel");
105 mTransport2 = new TransportInfo(
106 PACKAGE_NAME,
107 "transport2.name",
108 new Intent(),
109 "currentDestinationString",
110 new Intent(),
111 "dataManagementLabel");
Artem Iglikov19e12272017-05-31 17:12:28 +0100112
113 ShadowContextImplForBackup.sComponentBinderMap.put(mTransport1.componentName,
114 mTransport1.binder);
115 ShadowContextImplForBackup.sComponentBinderMap.put(mTransport2.componentName,
116 mTransport2.binder);
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000117 ShadowBackupTransportStub.sBinderTransportMap.put(
118 mTransport1.binder, mTransport1.binderInterface);
119 ShadowBackupTransportStub.sBinderTransportMap.put(
120 mTransport2.binder, mTransport2.binderInterface);
Artem Iglikov19e12272017-05-31 17:12:28 +0100121 }
122
123 @After
124 public void tearDown() throws Exception {
125 ShadowContextImplForBackup.resetBackupShadowState();
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100126 }
127
128 @Test
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100129 public void onPackageAdded_bindsToAllTransports() throws Exception {
Artem Iglikov19e12272017-05-31 17:12:28 +0100130 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100131 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100132
133 TransportManager transportManager = new TransportManager(
134 RuntimeEnvironment.application.getApplicationContext(),
Artem Iglikov19e12272017-05-31 17:12:28 +0100135 new HashSet<>(Arrays.asList(
136 mTransport1.componentName, mTransport2.componentName)),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100137 null /* defaultTransport */,
138 mTransportBoundListenerStub,
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100139 ShadowLooper.getMainLooper());
140 transportManager.onPackageAdded(PACKAGE_NAME);
141
142 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
Artem Iglikov19e12272017-05-31 17:12:28 +0100143 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100144 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
Artem Iglikov19e12272017-05-31 17:12:28 +0100145 Arrays.asList(mTransport1.name, mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000146 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
147 .isTrue();
148 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
149 .isTrue();
Artem Iglikov19e12272017-05-31 17:12:28 +0100150 }
151
152 @Test
153 public void onPackageAdded_oneTransportUnavailable_bindsToOnlyOneTransport() throws Exception {
154 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
155 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
156
157 ShadowContextImplForBackup.sUnbindableComponents.add(mTransport1.componentName);
158
159 TransportManager transportManager = new TransportManager(
160 RuntimeEnvironment.application.getApplicationContext(),
161 new HashSet<>(Arrays.asList(
162 mTransport1.componentName, mTransport2.componentName)),
163 null /* defaultTransport */,
164 mTransportBoundListenerStub,
165 ShadowLooper.getMainLooper());
166 transportManager.onPackageAdded(PACKAGE_NAME);
167
168 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
169 Collections.singleton(mTransport2.componentName));
170 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
171 Collections.singleton(mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000172 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
173 .isFalse();
174 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
175 .isTrue();
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100176 }
177
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100178 @Test
179 public void onPackageAdded_whitelistIsNull_doesNotBindToTransports() throws Exception {
Artem Iglikov19e12272017-05-31 17:12:28 +0100180 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100181 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100182
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100183 TransportManager transportManager = new TransportManager(
184 RuntimeEnvironment.application.getApplicationContext(),
185 null /* whitelist */,
186 null /* defaultTransport */,
187 mTransportBoundListenerStub,
188 ShadowLooper.getMainLooper());
189 transportManager.onPackageAdded(PACKAGE_NAME);
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100190
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100191 assertThat(transportManager.getAllTransportComponents()).isEmpty();
192 assertThat(transportManager.getBoundTransportNames()).isEmpty();
193 assertThat(mTransportBoundListenerStub.isCalled()).isFalse();
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100194 }
195
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100196 @Test
197 public void onPackageAdded_onlyOneTransportWhitelisted_onlyConnectsToWhitelistedTransport()
198 throws Exception {
Artem Iglikov19e12272017-05-31 17:12:28 +0100199 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100200 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100201
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100202 TransportManager transportManager = new TransportManager(
203 RuntimeEnvironment.application.getApplicationContext(),
Artem Iglikov19e12272017-05-31 17:12:28 +0100204 new HashSet<>(Collections.singleton(mTransport2.componentName)),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100205 null /* defaultTransport */,
206 mTransportBoundListenerStub,
207 ShadowLooper.getMainLooper());
208 transportManager.onPackageAdded(PACKAGE_NAME);
209
210 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
Artem Iglikov19e12272017-05-31 17:12:28 +0100211 Collections.singleton(mTransport2.componentName));
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100212 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
Artem Iglikov19e12272017-05-31 17:12:28 +0100213 Collections.singleton(mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000214 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
215 .isFalse();
216 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
217 .isTrue();
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100218 }
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100219
220 @Test
221 public void onPackageAdded_appIsNotPrivileged_doesNotBindToTransports() throws Exception {
Artem Iglikov19e12272017-05-31 17:12:28 +0100222 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2), 0);
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100223
224 TransportManager transportManager = new TransportManager(
225 RuntimeEnvironment.application.getApplicationContext(),
Artem Iglikov19e12272017-05-31 17:12:28 +0100226 new HashSet<>(Arrays.asList(
227 mTransport1.componentName, mTransport2.componentName)),
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100228 null /* defaultTransport */,
229 mTransportBoundListenerStub,
230 ShadowLooper.getMainLooper());
231 transportManager.onPackageAdded(PACKAGE_NAME);
232
233 assertThat(transportManager.getAllTransportComponents()).isEmpty();
234 assertThat(transportManager.getBoundTransportNames()).isEmpty();
235 assertThat(mTransportBoundListenerStub.isCalled()).isFalse();
236 }
237
Artem Iglikov19e12272017-05-31 17:12:28 +0100238 @Test
239 public void onPackageRemoved_transportsUnbound() throws Exception {
240 TransportManager transportManager = createTransportManagerAndSetUpTransports(
241 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
242
243 transportManager.onPackageRemoved(PACKAGE_NAME);
244
245 assertThat(transportManager.getAllTransportComponents()).isEmpty();
246 assertThat(transportManager.getBoundTransportNames()).isEmpty();
247 }
248
249 @Test
250 public void onPackageRemoved_incorrectPackageName_nothingHappens() throws Exception {
251 TransportManager transportManager = createTransportManagerAndSetUpTransports(
252 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
253
254 transportManager.onPackageRemoved(ANOTHER_PACKAGE_NAME);
255
256 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
257 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
258 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
259 Arrays.asList(mTransport1.name, mTransport2.name));
260 }
261
262 @Test
263 public void onPackageChanged_oneComponentChanged_onlyOneTransportRebound() throws Exception {
264 TransportManager transportManager = createTransportManagerAndSetUpTransports(
265 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
266
267 transportManager.onPackageChanged(PACKAGE_NAME, new String[]{mTransport2.name});
268
269 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
270 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
271 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
272 Arrays.asList(mTransport1.name, mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000273 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
274 .isFalse();
275 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
276 .isTrue();
Artem Iglikov19e12272017-05-31 17:12:28 +0100277 }
278
279 @Test
280 public void onPackageChanged_nothingChanged_noTransportsRebound() throws Exception {
281 TransportManager transportManager = createTransportManagerAndSetUpTransports(
282 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
283
284 transportManager.onPackageChanged(PACKAGE_NAME, new String[0]);
285
286 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
287 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
288 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
289 Arrays.asList(mTransport1.name, mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000290 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
291 .isFalse();
292 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
293 .isFalse();
Artem Iglikov19e12272017-05-31 17:12:28 +0100294 }
295
296 @Test
297 public void onPackageChanged_unexpectedComponentChanged_noTransportsRebound() throws Exception {
298 TransportManager transportManager = createTransportManagerAndSetUpTransports(
299 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
300
301 transportManager.onPackageChanged(PACKAGE_NAME, new String[]{"unexpected.component"});
302
303 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
304 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
305 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
306 Arrays.asList(mTransport1.name, mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000307 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
308 .isFalse();
309 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
310 .isFalse();
Artem Iglikov19e12272017-05-31 17:12:28 +0100311 }
312
313 @Test
314 public void onPackageChanged_transportsRebound() throws Exception {
315 TransportManager transportManager = createTransportManagerAndSetUpTransports(
316 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
317
318 transportManager.onPackageChanged(PACKAGE_NAME, new String[]{mTransport2.name});
319
320 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
321 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
322 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
323 Arrays.asList(mTransport1.name, mTransport2.name));
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000324 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.binderInterface))
325 .isFalse();
326 assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.binderInterface))
327 .isTrue();
Artem Iglikov19e12272017-05-31 17:12:28 +0100328 }
329
330 @Test
331 public void getTransportBinder_returnsCorrectBinder() throws Exception {
332 TransportManager transportManager = createTransportManagerAndSetUpTransports(
333 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
334
335 assertThat(transportManager.getTransportBinder(mTransport1.name)).isEqualTo(
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000336 mTransport1.binderInterface);
Artem Iglikov19e12272017-05-31 17:12:28 +0100337 assertThat(transportManager.getTransportBinder(mTransport2.name)).isEqualTo(
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000338 mTransport2.binderInterface);
Artem Iglikov19e12272017-05-31 17:12:28 +0100339 }
340
341 @Test
342 public void getTransportBinder_incorrectTransportName_returnsNull() throws Exception {
343 TransportManager transportManager = createTransportManagerAndSetUpTransports(
344 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
345
346 assertThat(transportManager.getTransportBinder("incorrect.transport")).isNull();
347 }
348
349 @Test
350 public void getTransportBinder_oneTransportUnavailable_returnsCorrectBinder() throws Exception {
351 TransportManager transportManager =
352 createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
353 Collections.singletonList(mTransport1), mTransport1.name);
354
355 assertThat(transportManager.getTransportBinder(mTransport1.name)).isNull();
356 assertThat(transportManager.getTransportBinder(mTransport2.name)).isEqualTo(
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000357 mTransport2.binderInterface);
Artem Iglikov19e12272017-05-31 17:12:28 +0100358 }
359
360 @Test
361 public void getCurrentTransport_selectTransportNotCalled_returnsDefaultTransport()
362 throws Exception {
363 TransportManager transportManager = createTransportManagerAndSetUpTransports(
364 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
365
366 assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport1.name);
367 }
368
369 @Test
370 public void getCurrentTransport_selectTransportCalled_returnsCorrectTransport()
371 throws Exception {
372 TransportManager transportManager = createTransportManagerAndSetUpTransports(
373 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
374
375 assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport1.name);
376
377 transportManager.selectTransport(mTransport2.name);
378
379 assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport2.name);
380 }
381
382 @Test
383 public void getCurrentTransportBinder_returnsCorrectBinder() throws Exception {
384 TransportManager transportManager = createTransportManagerAndSetUpTransports(
385 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
386
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000387 assertThat(transportManager.getCurrentTransportBinder())
388 .isEqualTo(mTransport1.binderInterface);
Artem Iglikov19e12272017-05-31 17:12:28 +0100389 }
390
391 @Test
392 public void getCurrentTransportBinder_transportNotBound_returnsNull() throws Exception {
393 TransportManager transportManager =
394 createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
395 Collections.singletonList(mTransport1), mTransport2.name);
396
397 transportManager.selectTransport(mTransport1.name);
398
399 assertThat(transportManager.getCurrentTransportBinder()).isNull();
400 }
401
402 @Test
403 public void getTransportName_returnsCorrectTransportName() throws Exception {
404 TransportManager transportManager = createTransportManagerAndSetUpTransports(
405 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
406
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000407 assertThat(transportManager.getTransportName(mTransport1.binderInterface))
408 .isEqualTo(mTransport1.name);
409 assertThat(transportManager.getTransportName(mTransport2.binderInterface))
410 .isEqualTo(mTransport2.name);
Artem Iglikov19e12272017-05-31 17:12:28 +0100411 }
412
413 @Test
414 public void getTransportName_transportNotBound_returnsNull() throws Exception {
415 TransportManager transportManager =
416 createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
417 Collections.singletonList(mTransport1), mTransport1.name);
418
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000419 assertThat(transportManager.getTransportName(mTransport1.binderInterface)).isNull();
420 assertThat(transportManager.getTransportName(mTransport2.binderInterface))
421 .isEqualTo(mTransport2.name);
Artem Iglikov19e12272017-05-31 17:12:28 +0100422 }
423
424 @Test
425 public void getTransportWhitelist_returnsCorrectWhiteList() throws Exception {
426 TransportManager transportManager = new TransportManager(
427 RuntimeEnvironment.application.getApplicationContext(),
428 new HashSet<>(Arrays.asList(mTransport1.componentName, mTransport2.componentName)),
429 mTransport1.name,
430 mTransportBoundListenerStub,
431 ShadowLooper.getMainLooper());
432
433 assertThat(transportManager.getTransportWhitelist()).containsExactlyElementsIn(
434 Arrays.asList(mTransport1.componentName, mTransport2.componentName));
435 }
436
437 @Test
438 public void getTransportWhitelist_whiteListIsNull_returnsEmptyArray() throws Exception {
439 TransportManager transportManager = new TransportManager(
440 RuntimeEnvironment.application.getApplicationContext(),
441 null /* whitelist */,
442 mTransport1.name,
443 mTransportBoundListenerStub,
444 ShadowLooper.getMainLooper());
445
446 assertThat(transportManager.getTransportWhitelist()).isEmpty();
447 }
448
449 @Test
450 public void selectTransport_setsTransportCorrectlyAndReturnsPreviousTransport()
451 throws Exception {
452 TransportManager transportManager = new TransportManager(
453 RuntimeEnvironment.application.getApplicationContext(),
454 null /* whitelist */,
455 mTransport1.name,
456 mTransportBoundListenerStub,
457 ShadowLooper.getMainLooper());
458
459 assertThat(transportManager.selectTransport(mTransport2.name)).isEqualTo(mTransport1.name);
460 assertThat(transportManager.selectTransport(mTransport1.name)).isEqualTo(mTransport2.name);
461 }
462
Artem Iglikov026e9332017-06-01 13:06:29 +0100463 @Test
Bernardo Rufinoab953332017-11-22 22:10:32 +0000464 public void getTransportClient_forRegisteredTransport_returnCorrectly() throws Exception {
465 TransportManager transportManager =
466 createTransportManagerAndSetUpTransports(
467 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
468
469 TransportClient transportClient =
470 transportManager.getTransportClient(mTransport1.name, "caller");
471
472 assertThat(transportClient.getTransportComponent()).isEqualTo(mTransport1.componentName);
473 }
474
475 @Test
476 public void getTransportClient_forOldNameOfTransportThatChangedName_returnsNull()
477 throws Exception {
478 TransportManager transportManager =
479 createTransportManagerAndSetUpTransports(
480 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000481 transportManager.updateTransportAttributes(
Bernardo Rufinoab953332017-11-22 22:10:32 +0000482 mTransport1.componentName, "newName", null, "destinationString", null, null);
483
484 TransportClient transportClient =
485 transportManager.getTransportClient(mTransport1.name, "caller");
486
487 assertThat(transportClient).isNull();
488 }
489
490 @Test
491 public void getTransportClient_forNewNameOfTransportThatChangedName_returnsCorrectly()
492 throws Exception {
493 TransportManager transportManager =
494 createTransportManagerAndSetUpTransports(
495 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000496 transportManager.updateTransportAttributes(
Bernardo Rufinoab953332017-11-22 22:10:32 +0000497 mTransport1.componentName, "newName", null, "destinationString", null, null);
498
499 TransportClient transportClient =
500 transportManager.getTransportClient("newName", "caller");
501
502 assertThat(transportClient.getTransportComponent()).isEqualTo(mTransport1.componentName);
503 }
504
505 @Test
506 public void getTransportName_forTransportThatChangedName_returnsNewName()
507 throws Exception {
508 TransportManager transportManager =
509 createTransportManagerAndSetUpTransports(
510 Arrays.asList(mTransport1, mTransport2), mTransport1.name);
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000511 transportManager.updateTransportAttributes(
Bernardo Rufinoab953332017-11-22 22:10:32 +0000512 mTransport1.componentName, "newName", null, "destinationString", null, null);
513
514 String transportName = transportManager.getTransportName(mTransport1.componentName);
515
516 assertThat(transportName).isEqualTo("newName");
517 }
518
Bernardo Rufino998fdaa2017-12-05 17:27:45 +0000519 @Test
520 public void isTransportRegistered_returnsCorrectly() throws Exception {
521 TransportManager transportManager =
522 createTransportManagerAndSetUpTransports(
523 Collections.singletonList(mTransport1),
524 Collections.singletonList(mTransport2),
525 mTransport1.name);
526
527 assertThat(transportManager.isTransportRegistered(mTransport1.name)).isTrue();
528 assertThat(transportManager.isTransportRegistered(mTransport2.name)).isFalse();
529 }
530
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000531 @Test
532 public void getTransportAttributes_forRegisteredTransport_returnsCorrectValues()
533 throws Exception {
534 TransportManager transportManager =
535 createTransportManagerAndSetUpTransports(
536 Collections.singletonList(mTransport1),
537 mTransport1.name);
538
539 assertThat(transportManager.getTransportConfigurationIntent(mTransport1.name))
540 .isEqualTo(mTransport1.binderInterface.configurationIntent());
541 assertThat(transportManager.getTransportDataManagementIntent(mTransport1.name))
542 .isEqualTo(mTransport1.binderInterface.dataManagementIntent());
543 assertThat(transportManager.getTransportDataManagementLabel(mTransport1.name))
544 .isEqualTo(mTransport1.binderInterface.dataManagementLabel());
545 assertThat(transportManager.getTransportDirName(mTransport1.name))
546 .isEqualTo(mTransport1.binderInterface.transportDirName());
547 }
548
549 @Test
550 public void getTransportAttributes_forUnregisteredTransport_throws()
551 throws Exception {
552 TransportManager transportManager =
553 createTransportManagerAndSetUpTransports(
554 Collections.singletonList(mTransport1),
555 Collections.singletonList(mTransport2),
556 mTransport1.name);
557
558 expectThrows(
559 TransportNotRegisteredException.class,
560 () -> transportManager.getTransportConfigurationIntent(mTransport2.name));
561 expectThrows(
562 TransportNotRegisteredException.class,
563 () -> transportManager.getTransportDataManagementIntent(
564 mTransport2.name));
565 expectThrows(
566 TransportNotRegisteredException.class,
567 () -> transportManager.getTransportDataManagementLabel(mTransport2.name));
568 expectThrows(
569 TransportNotRegisteredException.class,
570 () -> transportManager.getTransportDirName(mTransport2.name));
571 }
572
Artem Iglikov19e12272017-05-31 17:12:28 +0100573 private void setUpPackageWithTransports(String packageName, List<TransportInfo> transports,
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100574 int flags) throws Exception {
575 PackageInfo packageInfo = new PackageInfo();
576 packageInfo.packageName = packageName;
577 packageInfo.applicationInfo = new ApplicationInfo();
578 packageInfo.applicationInfo.privateFlags = flags;
579
Bernardo Rufino90a88022017-11-13 17:19:15 +0000580 mPackageManagerShadow.addPackage(packageInfo);
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100581
582 List<ResolveInfo> transportsInfo = new ArrayList<>();
Artem Iglikov19e12272017-05-31 17:12:28 +0100583 for (TransportInfo transport : transports) {
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100584 ResolveInfo info = new ResolveInfo();
585 info.serviceInfo = new ServiceInfo();
586 info.serviceInfo.packageName = packageName;
Artem Iglikov19e12272017-05-31 17:12:28 +0100587 info.serviceInfo.name = transport.name;
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100588 transportsInfo.add(info);
589 }
590
591 Intent intent = new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST);
592 intent.setPackage(packageName);
593
Bernardo Rufino90a88022017-11-13 17:19:15 +0000594 mPackageManagerShadow.addResolveInfoForIntent(intent, transportsInfo);
Artem Iglikovbd476ea2017-09-01 10:57:26 +0100595 }
596
Artem Iglikov19e12272017-05-31 17:12:28 +0100597 private TransportManager createTransportManagerAndSetUpTransports(
598 List<TransportInfo> availableTransports, String defaultTransportName) throws Exception {
599 return createTransportManagerAndSetUpTransports(availableTransports,
600 Collections.<TransportInfo>emptyList(), defaultTransportName);
601 }
602
603 private TransportManager createTransportManagerAndSetUpTransports(
604 List<TransportInfo> availableTransports, List<TransportInfo> unavailableTransports,
605 String defaultTransportName)
606 throws Exception {
607 List<String> availableTransportsNames = new ArrayList<>();
608 List<ComponentName> availableTransportsComponentNames = new ArrayList<>();
609 for (TransportInfo transport : availableTransports) {
610 availableTransportsNames.add(transport.name);
611 availableTransportsComponentNames.add(transport.componentName);
612 }
613
614 List<ComponentName> allTransportsComponentNames = new ArrayList<>();
615 allTransportsComponentNames.addAll(availableTransportsComponentNames);
616 for (TransportInfo transport : unavailableTransports) {
617 allTransportsComponentNames.add(transport.componentName);
618 }
619
620 for (TransportInfo transport : unavailableTransports) {
621 ShadowContextImplForBackup.sUnbindableComponents.add(transport.componentName);
622 }
623
624 setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
625 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
626
627 TransportManager transportManager = new TransportManager(
628 RuntimeEnvironment.application.getApplicationContext(),
629 new HashSet<>(allTransportsComponentNames),
630 defaultTransportName,
631 mTransportBoundListenerStub,
632 ShadowLooper.getMainLooper());
633 transportManager.onPackageAdded(PACKAGE_NAME);
634
635 assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
636 availableTransportsComponentNames);
637 assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
638 availableTransportsNames);
639 for (TransportInfo transport : availableTransports) {
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000640 assertThat(mTransportBoundListenerStub.isCalledForTransport(transport.binderInterface))
641 .isTrue();
Artem Iglikov19e12272017-05-31 17:12:28 +0100642 }
643 for (TransportInfo transport : unavailableTransports) {
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000644 assertThat(mTransportBoundListenerStub.isCalledForTransport(transport.binderInterface))
645 .isFalse();
Artem Iglikov19e12272017-05-31 17:12:28 +0100646 }
647
648 mTransportBoundListenerStub.resetState();
649
650 return transportManager;
651 }
652
653 private static class TransportInfo {
654 public final String packageName;
655 public final String name;
656 public final ComponentName componentName;
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000657 public final IBackupTransport binderInterface;
Artem Iglikov19e12272017-05-31 17:12:28 +0100658 public final IBinder binder;
659
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000660 TransportInfo(
661 String packageName,
662 String name,
663 @Nullable Intent configurationIntent,
664 String currentDestinationString,
665 @Nullable Intent dataManagementIntent,
666 String dataManagementLabel) {
Artem Iglikov19e12272017-05-31 17:12:28 +0100667 this.packageName = packageName;
668 this.name = name;
669 this.componentName = new ComponentName(packageName, name);
Artem Iglikov19e12272017-05-31 17:12:28 +0100670 this.binder = mock(IBinder.class);
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000671 IBackupTransport transport = mock(IBackupTransport.class);
672 try {
673 when(transport.name()).thenReturn(name);
674 when(transport.configurationIntent()).thenReturn(configurationIntent);
675 when(transport.currentDestinationString()).thenReturn(currentDestinationString);
676 when(transport.dataManagementIntent()).thenReturn(dataManagementIntent);
677 when(transport.dataManagementLabel()).thenReturn(dataManagementLabel);
678 } catch (RemoteException e) {
679 // Only here to mock methods that throw RemoteException
680 }
681 this.binderInterface = transport;
Artem Iglikov19e12272017-05-31 17:12:28 +0100682 }
683 }
Bernardo Rufino7f14ede2017-12-08 19:55:03 +0000684
Artem Iglikov5ed1dab2017-05-25 15:56:05 +0100685}