blob: e1dc7b5e151e2c578483b0ffc0bd7fa866a1c6a9 [file] [log] [blame]
Bernardo Rufinofa518532018-01-02 16:01:53 +00001/*
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.testing;
18
Bernardo Rufino41349c02018-01-10 21:09:28 +000019import static com.android.server.backup.testing.TestUtils.uncheck;
20
21import static org.junit.Assert.fail;
Bernardo Rufinofa518532018-01-02 16:01:53 +000022import static org.mockito.ArgumentMatchers.any;
23import static org.mockito.ArgumentMatchers.eq;
24import static org.mockito.Mockito.mock;
25import static org.mockito.Mockito.when;
26
Bernardo Rufino41349c02018-01-10 21:09:28 +000027import static java.util.stream.Collectors.toList;
28
Bernardo Rufinofa518532018-01-02 16:01:53 +000029import android.annotation.Nullable;
Bernardo Rufino516ac9572018-01-04 14:16:32 +000030import android.content.ComponentName;
Bernardo Rufino41349c02018-01-10 21:09:28 +000031import android.content.Intent;
32import android.content.pm.ResolveInfo;
33import android.content.pm.ServiceInfo;
34import android.os.RemoteException;
35import android.support.annotation.IntDef;
Bernardo Rufinofa518532018-01-02 16:01:53 +000036
37import com.android.internal.backup.IBackupTransport;
38import com.android.server.backup.TransportManager;
39import com.android.server.backup.transport.TransportClient;
40import com.android.server.backup.transport.TransportNotAvailableException;
Bernardo Rufino516ac9572018-01-04 14:16:32 +000041import com.android.server.backup.transport.TransportNotRegisteredException;
Bernardo Rufinofa518532018-01-02 16:01:53 +000042
Bernardo Rufino41349c02018-01-10 21:09:28 +000043import org.robolectric.shadows.ShadowPackageManager;
44
Bernardo Rufinofa518532018-01-02 16:01:53 +000045import java.util.List;
Bernardo Rufino41349c02018-01-10 21:09:28 +000046import java.util.stream.Stream;
Bernardo Rufinofa518532018-01-02 16:01:53 +000047
48public class TransportTestUtils {
Bernardo Rufino41349c02018-01-10 21:09:28 +000049 /**
50 * Differently from {@link #setUpTransports(TransportManager, TransportData...)}, which
51 * configures {@link TransportManager}, this is meant to mock the environment for a real
52 * TransportManager.
53 */
54 public static void setUpTransportsForTransportManager(
55 ShadowPackageManager shadowPackageManager, TransportData... transports)
56 throws Exception {
57 for (TransportData transport : transports) {
58 ComponentName transportComponent = transport.getTransportComponent();
59 String packageName = transportComponent.getPackageName();
60 ResolveInfo resolveInfo = resolveInfo(transportComponent);
61 shadowPackageManager.addResolveInfoForIntent(transportIntent(), resolveInfo);
62 shadowPackageManager.addResolveInfoForIntent(
63 transportIntent().setPackage(packageName), resolveInfo);
64 }
65 }
Bernardo Rufinofa518532018-01-02 16:01:53 +000066
Bernardo Rufino41349c02018-01-10 21:09:28 +000067 private static Intent transportIntent() {
68 return new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST);
69 }
Bernardo Rufinofa518532018-01-02 16:01:53 +000070
Bernardo Rufino41349c02018-01-10 21:09:28 +000071 private static ResolveInfo resolveInfo(ComponentName transportComponent) {
72 ResolveInfo resolveInfo = new ResolveInfo();
73 resolveInfo.serviceInfo = new ServiceInfo();
74 resolveInfo.serviceInfo.packageName = transportComponent.getPackageName();
75 resolveInfo.serviceInfo.name = transportComponent.getClassName();
76 return resolveInfo;
Bernardo Rufinofa518532018-01-02 16:01:53 +000077 }
78
Bernardo Rufino516ac9572018-01-04 14:16:32 +000079 /** {@code transportName} has to be in the {@link ComponentName} format (with '/') */
Bernardo Rufino41349c02018-01-10 21:09:28 +000080 public static TransportMock setUpCurrentTransport(
81 TransportManager transportManager, TransportData transport) throws Exception {
82 TransportMock transportMock = setUpTransports(transportManager, transport).get(0);
83 if (transportMock.transportClient != null) {
84 when(transportManager.getCurrentTransportClient(any()))
85 .thenReturn(transportMock.transportClient);
86 }
87 return transportMock;
Bernardo Rufinofa518532018-01-02 16:01:53 +000088 }
89
90 /** @see #setUpTransport(TransportManager, TransportData) */
Bernardo Rufino41349c02018-01-10 21:09:28 +000091 public static List<TransportMock> setUpTransports(
Bernardo Rufinofa518532018-01-02 16:01:53 +000092 TransportManager transportManager, TransportData... transports) throws Exception {
Bernardo Rufino41349c02018-01-10 21:09:28 +000093 return Stream.of(transports)
94 .map(transport -> uncheck(() -> setUpTransport(transportManager, transport)))
95 .collect(toList());
Bernardo Rufinofa518532018-01-02 16:01:53 +000096 }
97
Bernardo Rufino41349c02018-01-10 21:09:28 +000098 public static TransportMock setUpTransport(
99 TransportManager transportManager, TransportData transport) throws Exception {
100 int status = transport.transportStatus;
Bernardo Rufinofa518532018-01-02 16:01:53 +0000101 String transportName = transport.transportName;
Bernardo Rufino41349c02018-01-10 21:09:28 +0000102 ComponentName transportComponent = transport.getTransportComponent();
103 String transportDirName = transport.transportDirName;
Bernardo Rufinofa518532018-01-02 16:01:53 +0000104
Bernardo Rufino41349c02018-01-10 21:09:28 +0000105 TransportMock transportMock = mockTransport(transport);
106 if (status == TransportStatus.REGISTERED_AVAILABLE
107 || status == TransportStatus.REGISTERED_UNAVAILABLE) {
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000108 // Transport registered
109 when(transportManager.getTransportClient(eq(transportName), any()))
Bernardo Rufino41349c02018-01-10 21:09:28 +0000110 .thenReturn(transportMock.transportClient);
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000111 when(transportManager.getTransportClientOrThrow(eq(transportName), any()))
Bernardo Rufino41349c02018-01-10 21:09:28 +0000112 .thenReturn(transportMock.transportClient);
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000113 when(transportManager.getTransportName(transportComponent)).thenReturn(transportName);
114 when(transportManager.getTransportDirName(eq(transportName)))
115 .thenReturn(transportDirName);
116 when(transportManager.getTransportDirName(eq(transportComponent)))
117 .thenReturn(transportDirName);
Bernardo Rufino41349c02018-01-10 21:09:28 +0000118 // TODO: Mock rest of description methods
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000119 } else {
120 // Transport not registered
121 when(transportManager.getTransportClient(eq(transportName), any())).thenReturn(null);
122 when(transportManager.getTransportClientOrThrow(eq(transportName), any()))
123 .thenThrow(TransportNotRegisteredException.class);
124 when(transportManager.getTransportName(transportComponent))
125 .thenThrow(TransportNotRegisteredException.class);
126 when(transportManager.getTransportDirName(eq(transportName)))
127 .thenThrow(TransportNotRegisteredException.class);
128 when(transportManager.getTransportDirName(eq(transportComponent)))
129 .thenThrow(TransportNotRegisteredException.class);
Bernardo Rufinofa518532018-01-02 16:01:53 +0000130 }
Bernardo Rufino41349c02018-01-10 21:09:28 +0000131 return transportMock;
Bernardo Rufinofa518532018-01-02 16:01:53 +0000132 }
133
Bernardo Rufino41349c02018-01-10 21:09:28 +0000134 public static TransportMock mockTransport(TransportData transport) throws Exception {
135 final TransportClient transportClientMock;
136 int status = transport.transportStatus;
137 ComponentName transportComponent = transport.getTransportComponent();
138 if (status == TransportStatus.REGISTERED_AVAILABLE
139 || status == TransportStatus.REGISTERED_UNAVAILABLE) {
140 // Transport registered
141 transportClientMock = mock(TransportClient.class);
142 when(transportClientMock.getTransportComponent()).thenReturn(transportComponent);
143 if (status == TransportStatus.REGISTERED_AVAILABLE) {
144 // Transport registered and available
145 IBackupTransport transportMock = mockTransportBinder(transport);
146 when(transportClientMock.connectOrThrow(any())).thenReturn(transportMock);
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000147
Bernardo Rufino41349c02018-01-10 21:09:28 +0000148 return new TransportMock(transportClientMock, transportMock);
149 } else {
150 // Transport registered but unavailable
151 when(transportClientMock.connectOrThrow(any()))
152 .thenThrow(TransportNotAvailableException.class);
Bernardo Rufinofa518532018-01-02 16:01:53 +0000153
Bernardo Rufino41349c02018-01-10 21:09:28 +0000154 return new TransportMock(transportClientMock, null);
155 }
156 } else {
157 // Transport not registered
158 return new TransportMock(null, null);
Bernardo Rufinofa518532018-01-02 16:01:53 +0000159 }
Bernardo Rufino41349c02018-01-10 21:09:28 +0000160 }
Bernardo Rufinofa518532018-01-02 16:01:53 +0000161
Bernardo Rufino41349c02018-01-10 21:09:28 +0000162 private static IBackupTransport mockTransportBinder(TransportData transport) throws Exception {
163 IBackupTransport transportBinder = mock(IBackupTransport.class);
164 try {
165 when(transportBinder.name()).thenReturn(transport.transportName);
166 when(transportBinder.transportDirName()).thenReturn(transport.transportDirName);
167 when(transportBinder.configurationIntent()).thenReturn(transport.configurationIntent);
168 when(transportBinder.currentDestinationString())
169 .thenReturn(transport.currentDestinationString);
170 when(transportBinder.dataManagementIntent()).thenReturn(transport.dataManagementIntent);
171 when(transportBinder.dataManagementLabel()).thenReturn(transport.dataManagementLabel);
172 } catch (RemoteException e) {
173 fail("RemoteException?");
Bernardo Rufinofa518532018-01-02 16:01:53 +0000174 }
Bernardo Rufino41349c02018-01-10 21:09:28 +0000175 return transportBinder;
176 }
177
178 public static class TransportMock {
179 @Nullable public final TransportClient transportClient;
180 @Nullable public final IBackupTransport transport;
181
182 private TransportMock(
183 @Nullable TransportClient transportClient, @Nullable IBackupTransport transport) {
184 this.transportClient = transportClient;
185 this.transport = transport;
186 }
187 }
188
189 @IntDef({
190 TransportStatus.REGISTERED_AVAILABLE,
191 TransportStatus.REGISTERED_UNAVAILABLE,
192 TransportStatus.UNREGISTERED
193 })
194 public @interface TransportStatus {
195 int REGISTERED_AVAILABLE = 0;
196 int REGISTERED_UNAVAILABLE = 1;
197 int UNREGISTERED = 2;
Bernardo Rufinofa518532018-01-02 16:01:53 +0000198 }
199
200 private TransportTestUtils() {}
201}