Merge "Update transport connection with registration info"
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index 7e179e5..501ff29 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -26,6 +26,7 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
@@ -57,6 +58,8 @@
@VisibleForTesting
public static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
+ private static final String EXTRA_TRANSPORT_REGISTRATION = "transport_registration";
+
private final Intent mTransportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
private final Context mContext;
private final PackageManager mPackageManager;
@@ -582,8 +585,12 @@
String transportString = transportComponent.flattenToShortString();
String callerLogString = "TransportManager.registerTransport()";
- TransportClient transportClient =
- mTransportClientManager.getTransportClient(transportComponent, callerLogString);
+
+ Bundle extras = new Bundle();
+ extras.putBoolean(EXTRA_TRANSPORT_REGISTRATION, true);
+
+ TransportClient transportClient = mTransportClientManager.getTransportClient(
+ transportComponent, extras, callerLogString);
final IBackupTransport transport;
try {
transport = transportClient.connectOrThrow(callerLogString);
diff --git a/services/backup/java/com/android/server/backup/transport/TransportClientManager.java b/services/backup/java/com/android/server/backup/transport/TransportClientManager.java
index 4041932..96e7d2f 100644
--- a/services/backup/java/com/android/server/backup/transport/TransportClientManager.java
+++ b/services/backup/java/com/android/server/backup/transport/TransportClientManager.java
@@ -22,10 +22,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-
+import android.os.Bundle;
import com.android.server.backup.TransportManager;
import com.android.server.backup.transport.TransportUtils.Priority;
-
import java.io.PrintWriter;
import java.util.Map;
import java.util.WeakHashMap;
@@ -59,6 +58,32 @@
public TransportClient getTransportClient(ComponentName transportComponent, String caller) {
Intent bindIntent =
new Intent(SERVICE_ACTION_TRANSPORT_HOST).setComponent(transportComponent);
+
+ return getTransportClient(transportComponent, caller, bindIntent);
+ }
+
+ /**
+ * Retrieves a {@link TransportClient} for the transport identified by {@param
+ * transportComponent} whose binding intent will have the {@param extras} extras.
+ *
+ * @param transportComponent The {@link ComponentName} of the transport.
+ * @param extras A {@link Bundle} of extras to pass to the binding intent.
+ * @param caller A {@link String} identifying the caller for logging/debugging purposes. Check
+ * {@link TransportClient#connectAsync(TransportConnectionListener, String)} for more
+ * details.
+ * @return A {@link TransportClient}.
+ */
+ public TransportClient getTransportClient(
+ ComponentName transportComponent, Bundle extras, String caller) {
+ Intent bindIntent =
+ new Intent(SERVICE_ACTION_TRANSPORT_HOST).setComponent(transportComponent);
+ bindIntent.putExtras(extras);
+
+ return getTransportClient(transportComponent, caller, bindIntent);
+ }
+
+ private TransportClient getTransportClient(
+ ComponentName transportComponent, String caller, Intent bindIntent) {
synchronized (mTransportClientsLock) {
TransportClient transportClient =
new TransportClient(
diff --git a/services/robotests/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
index 44ac803..503adb2 100644
--- a/services/robotests/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
@@ -19,14 +19,12 @@
import static com.android.server.backup.testing.TransportData.genericTransport;
import static com.android.server.backup.testing.TransportTestUtils.mockTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransportsForTransportManager;
+
import static com.google.common.truth.Truth.assertThat;
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singletonList;
-import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toSet;
-import static java.util.stream.Stream.concat;
+
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -35,6 +33,13 @@
import static org.robolectric.shadow.api.Shadow.extract;
import static org.testng.Assert.expectThrows;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static java.util.stream.Stream.concat;
+
import android.annotation.Nullable;
import android.app.backup.BackupManager;
import android.content.ComponentName;
@@ -43,6 +48,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.platform.test.annotations.Presubmit;
+
import com.android.server.backup.testing.ShadowContextImplForBackup;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
@@ -54,11 +60,7 @@
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.FrameworkShadowContextImpl;
import com.android.server.testing.shadows.FrameworkShadowPackageManager;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Stream;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -69,6 +71,12 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowPackageManager;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Stream;
+
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
manifest = Config.NONE,
@@ -81,6 +89,12 @@
private static final String PACKAGE_A = "some.package.a";
private static final String PACKAGE_B = "some.package.b";
+ /**
+ * GMSCore depends on this constant so we define it here on top of the definition in
+ * {@link TransportManager} to verify this extra is passed
+ */
+ private static final String EXTRA_TRANSPORT_REGISTRATION = "transport_registration";
+
@Mock private OnTransportRegisteredListener mListener;
@Mock private TransportClientManager mTransportClientManager;
private TransportData mTransportA1;
@@ -195,6 +209,22 @@
}
@Test
+ public void testRegisterTransports_passesRegistrationExtraToGetTransportClient()
+ throws Exception {
+ setUpPackage(PACKAGE_A, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+ setUpTransports(mTransportA1);
+ TransportManager transportManager = createTransportManager(mTransportA1);
+
+ transportManager.registerTransports();
+
+ verify(mTransportClientManager)
+ .getTransportClient(
+ eq(mTransportA1.getTransportComponent()),
+ argThat(bundle -> bundle.getBoolean(EXTRA_TRANSPORT_REGISTRATION)),
+ anyString());
+ }
+
+ @Test
public void testOnPackageAdded_registerTransports() throws Exception {
setUpPackage(PACKAGE_A, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
setUpTransports(mTransportA1);
@@ -580,6 +610,9 @@
when(mTransportClientManager.getTransportClient(
eq(transport.getTransportComponent()), any()))
.thenReturn(transportMock.transportClient);
+ when(mTransportClientManager.getTransportClient(
+ eq(transport.getTransportComponent()), any(), any()))
+ .thenReturn(transportMock.transportClient);
transportMocks.add(transportMock);
}
return transportMocks;
diff --git a/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java b/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java
new file mode 100644
index 0000000..5e3c974
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/transport/TransportClientManagerTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.transport;
+
+import static com.android.server.backup.TransportManager.SERVICE_ACTION_TRANSPORT_HOST;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.argThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class TransportClientManagerTest {
+
+ private static final String PACKAGE_NAME = "random.package.name";
+ private static final String CLASS_NAME = "random.package.name.transport.Transport";
+
+ @Mock private Context mContext;
+ @Mock private TransportConnectionListener mTransportConnectionListener;
+ private TransportClientManager mTransportClientManager;
+ private ComponentName mTransportComponent;
+ private Intent mBindIntent;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mTransportClientManager = new TransportClientManager(mContext);
+ mTransportComponent = new ComponentName(PACKAGE_NAME, CLASS_NAME);
+ mBindIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST).setComponent(mTransportComponent);
+
+ when(mContext.bindServiceAsUser(
+ any(Intent.class),
+ any(ServiceConnection.class),
+ anyInt(),
+ any(UserHandle.class)))
+ .thenReturn(true);
+ }
+
+ @Test
+ public void testGetTransportClient_withExtras_createsTransportClientWithCorrectIntent() {
+ Bundle extras = new Bundle();
+ extras.putBoolean("random_extra", true);
+ mBindIntent.putExtras(extras);
+
+ TransportClient transportClient =
+ mTransportClientManager.getTransportClient(mTransportComponent, extras, "caller");
+
+ transportClient.connectAsync(mTransportConnectionListener, "caller");
+ verify(mContext)
+ .bindServiceAsUser(
+ argThat(matchesIntentAndExtras(mBindIntent)),
+ any(ServiceConnection.class),
+ anyInt(),
+ any(UserHandle.class));
+ }
+
+ private ArgumentMatcher<Intent> matchesIntentAndExtras(Intent expectedIntent) {
+ return (Intent actualIntent) -> {
+ if (!expectedIntent.filterEquals(actualIntent)) {
+ return false;
+ }
+
+ Bundle expectedExtras = expectedIntent.getExtras();
+ Bundle actualExtras = actualIntent.getExtras();
+
+ if (expectedExtras == null && actualExtras == null) {
+ return true;
+ }
+
+ if (expectedExtras == null || actualExtras == null) {
+ return false;
+ }
+
+ if (expectedExtras.size() != actualExtras.size()) {
+ return false;
+ }
+
+ for (String key : expectedExtras.keySet()) {
+ if (!expectedExtras.get(key).equals(actualExtras.get(key))) {
+ return false;
+ }
+ }
+
+ return true;
+ };
+ }
+}