blob: 565c7e638aacdb09e6e450c211143b905a89bbc7 [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);
Robert Berry39194c02018-01-11 13:50:56 +0000147 when(transportClientMock.connect(any())).thenReturn(transportMock);
Bernardo Rufino516ac9572018-01-04 14:16:32 +0000148
Bernardo Rufino41349c02018-01-10 21:09:28 +0000149 return new TransportMock(transportClientMock, transportMock);
150 } else {
151 // Transport registered but unavailable
152 when(transportClientMock.connectOrThrow(any()))
153 .thenThrow(TransportNotAvailableException.class);
Robert Berry39194c02018-01-11 13:50:56 +0000154 when(transportClientMock.connect(any())).thenReturn(null);
Bernardo Rufinofa518532018-01-02 16:01:53 +0000155
Bernardo Rufino41349c02018-01-10 21:09:28 +0000156 return new TransportMock(transportClientMock, null);
157 }
158 } else {
159 // Transport not registered
160 return new TransportMock(null, null);
Bernardo Rufinofa518532018-01-02 16:01:53 +0000161 }
Bernardo Rufino41349c02018-01-10 21:09:28 +0000162 }
Bernardo Rufinofa518532018-01-02 16:01:53 +0000163
Bernardo Rufino41349c02018-01-10 21:09:28 +0000164 private static IBackupTransport mockTransportBinder(TransportData transport) throws Exception {
165 IBackupTransport transportBinder = mock(IBackupTransport.class);
166 try {
167 when(transportBinder.name()).thenReturn(transport.transportName);
168 when(transportBinder.transportDirName()).thenReturn(transport.transportDirName);
169 when(transportBinder.configurationIntent()).thenReturn(transport.configurationIntent);
170 when(transportBinder.currentDestinationString())
171 .thenReturn(transport.currentDestinationString);
172 when(transportBinder.dataManagementIntent()).thenReturn(transport.dataManagementIntent);
173 when(transportBinder.dataManagementLabel()).thenReturn(transport.dataManagementLabel);
174 } catch (RemoteException e) {
175 fail("RemoteException?");
Bernardo Rufinofa518532018-01-02 16:01:53 +0000176 }
Bernardo Rufino41349c02018-01-10 21:09:28 +0000177 return transportBinder;
178 }
179
180 public static class TransportMock {
181 @Nullable public final TransportClient transportClient;
182 @Nullable public final IBackupTransport transport;
183
184 private TransportMock(
185 @Nullable TransportClient transportClient, @Nullable IBackupTransport transport) {
186 this.transportClient = transportClient;
187 this.transport = transport;
188 }
189 }
190
191 @IntDef({
192 TransportStatus.REGISTERED_AVAILABLE,
193 TransportStatus.REGISTERED_UNAVAILABLE,
194 TransportStatus.UNREGISTERED
195 })
196 public @interface TransportStatus {
197 int REGISTERED_AVAILABLE = 0;
198 int REGISTERED_UNAVAILABLE = 1;
199 int UNREGISTERED = 2;
Bernardo Rufinofa518532018-01-02 16:01:53 +0000200 }
201
202 private TransportTestUtils() {}
203}