Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36c5613a authored by Annie Meng's avatar Annie Meng
Browse files

Update transport connection with registration info

When connecting to a transport, let the transport
know if this connection is for registration. This is to
prevent updating transport attributes during registration
in GMSCore.

Bug: 72730566
Test: 1) m -j ROBOTEST_FILTER=TransportManagerTest RunFrameworksServicesRoboTests
2) m -j ROBOTEST_FILTER=TransportClientManagerTest RunFrameworksServicesRoboTests
3) adb reboot; adb logcat | grep BackupTransportManager; check no errors with "...not registered tried to change description"
4) GMSCore Robo tests
Change-Id: I5adf6ea3e668a8e8ed8c568728d109814b6f8975
parent bcaeb104
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.pm.ApplicationInfo;
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 @@ public class TransportManager {
    @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 @@ public class TransportManager {

        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);
+27 −2
Original line number Diff line number Diff line
@@ -22,10 +22,9 @@ import static com.android.server.backup.transport.TransportUtils.formatMessage;
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 class TransportClientManager {
    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(
+44 −11
Original line number Diff line number Diff line
@@ -19,14 +19,12 @@ package com.android.server.backup;
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.mockito.Mockito.when;
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.Intent;
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.FrameworkRobolectricTestRunner;
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.RuntimeEnvironment;
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 @@ public class TransportManagerTest {
    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;
@@ -194,6 +208,22 @@ public class TransportManagerTest {
        verify(mListener, never()).onTransportRegistered(any(), any());
    }

    @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);
@@ -580,6 +610,9 @@ public class TransportManagerTest {
            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;
+122 −0
Original line number Diff line number Diff line
/*
 * 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;
        };
    }
}