Loading services/backup/java/com/android/server/backup/TransportManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -455,7 +455,7 @@ public class TransportManager { } } interface TransportBoundListener { public interface TransportBoundListener { /** Should return true if this is a valid transport. */ boolean onTransportBound(IBackupTransport binder); } Loading services/robotests/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ LOCAL_TEST_PACKAGE := FrameworksServicesLib LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java include prebuilts/misc/common/robolectric/run_robotests.mk services/robotests/src/com/android/server/backup/TransportManagerTest.java +117 −48 Original line number Diff line number Diff line Loading @@ -18,32 +18,36 @@ package com.android.server.backup; import static com.google.common.truth.Truth.assertThat; import android.annotation.RequiresPermission; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.UserHandle; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import com.android.server.backup.testing.BackupTransportStub; import com.android.server.backup.testing.DefaultPackageManagerWithQueryIntentServicesAsUser; import com.android.server.backup.testing.ShadowBackupTransportStub; import com.android.server.backup.testing.ShadowContextImplWithBindServiceAsUser; import com.android.server.backup.testing.TransportBoundListenerStub; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.res.ResourceLoader; import org.robolectric.res.builder.DefaultPackageManager; import org.robolectric.res.builder.RobolectricPackageManager; import org.robolectric.shadows.ShadowContextImpl; import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLooper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; Loading @@ -51,12 +55,18 @@ import java.util.List; @Config( manifest = Config.NONE, sdk = 23, shadows = {TransportManagerTest.ShadowContextImplWithBindServiceAsUser.class} shadows = { ShadowContextImplWithBindServiceAsUser.class, ShadowBackupTransportStub.class } ) @Presubmit public class TransportManagerTest { private static final String PACKAGE_NAME = "some.package.name"; private static final String TRANSPORT1_NAME = "transport1.name"; private static final String TRANSPORT2_NAME = "transport2.name"; private static final List<String> TRANSPORTS_NAMES = Arrays.asList( TRANSPORT1_NAME, TRANSPORT2_NAME); private static final ComponentName TRANSPORT1_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, TRANSPORT1_NAME); private static final ComponentName TRANSPORT2_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, Loading @@ -66,72 +76,131 @@ public class TransportManagerTest { private RobolectricPackageManager mPackageManager; @Mock private TransportManager.TransportBoundListener mTransportBoundListener; @Mock private IBinder mTransport1BinderMock; @Mock private IBinder mTransport2BinderMock; private final BackupTransportStub mTransport1Stub = new BackupTransportStub(TRANSPORT1_NAME); private final BackupTransportStub mTransport2Stub = new BackupTransportStub(TRANSPORT2_NAME); private final TransportBoundListenerStub mTransportBoundListenerStub = new TransportBoundListenerStub(true); @Before public void setUp() { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); ShadowLog.stream = System.out; mPackageManager = new DefaultPackageManagerWithQueryIntentServicesAsUser( RuntimeEnvironment.getAppResourceLoader()); RuntimeEnvironment.setRobolectricPackageManager(mPackageManager); ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT1_COMPONENT_NAME, mTransport1BinderMock); ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT2_COMPONENT_NAME, mTransport2BinderMock); ShadowBackupTransportStub.sBinderTransportMap.put(mTransport1BinderMock, mTransport1Stub); ShadowBackupTransportStub.sBinderTransportMap.put(mTransport2BinderMock, mTransport2Stub); } @Test public void onPackageAdded_bindsToAllTransports() { Intent intent = new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST); intent.setPackage(PACKAGE_NAME); public void onPackageAdded_bindsToAllTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = PACKAGE_NAME; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); mPackageManager.addPackage(packageInfo); assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn( TRANSPORTS_COMPONENT_NAMES); assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn( TRANSPORTS_NAMES); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isTrue(); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue(); } ResolveInfo transport1 = new ResolveInfo(); transport1.serviceInfo = new ServiceInfo(); transport1.serviceInfo.packageName = PACKAGE_NAME; transport1.serviceInfo.name = TRANSPORT1_NAME; @Test public void onPackageAdded_whitelistIsNull_doesNotBindToTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); ResolveInfo transport2 = new ResolveInfo(); transport2.serviceInfo = new ServiceInfo(); transport2.serviceInfo.packageName = PACKAGE_NAME; transport2.serviceInfo.name = TRANSPORT2_NAME; TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), null /* whitelist */, null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); mPackageManager.addResolveInfoForIntent(intent, Arrays.asList(transport1, transport2)); assertThat(transportManager.getAllTransportComponents()).isEmpty(); assertThat(transportManager.getBoundTransportNames()).isEmpty(); assertThat(mTransportBoundListenerStub.isCalled()).isFalse(); } @Test public void onPackageAdded_onlyOneTransportWhitelisted_onlyConnectsToWhitelistedTransport() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null, mTransportBoundListener, new HashSet<>(Collections.singleton(TRANSPORT2_COMPONENT_NAME)), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn( TRANSPORTS_COMPONENT_NAMES); Collections.singleton(TRANSPORT2_COMPONENT_NAME)); assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn( Collections.singleton(TRANSPORT2_NAME)); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isFalse(); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue(); } private static class DefaultPackageManagerWithQueryIntentServicesAsUser extends DefaultPackageManager { @Test public void onPackageAdded_appIsNotPrivileged_doesNotBindToTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, 0); /* package */ DefaultPackageManagerWithQueryIntentServicesAsUser( ResourceLoader appResourceLoader) { super(appResourceLoader); } TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); @Override public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { return super.queryIntentServices(intent, flags); } assertThat(transportManager.getAllTransportComponents()).isEmpty(); assertThat(transportManager.getBoundTransportNames()).isEmpty(); assertThat(mTransportBoundListenerStub.isCalled()).isFalse(); } @Implements(className = ShadowContextImpl.CLASS_NAME) public static class ShadowContextImplWithBindServiceAsUser extends ShadowContextImpl { private void setUpPackageWithTransports(String packageName, List<String> transportNames, int flags) throws Exception { PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = packageName; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.privateFlags = flags; mPackageManager.addPackage(packageInfo); @Implementation public boolean bindServiceAsUser(@RequiresPermission Intent service, ServiceConnection conn, int flags, UserHandle user) { return true; List<ResolveInfo> transportsInfo = new ArrayList<>(); for (String transportName : transportNames) { ResolveInfo info = new ResolveInfo(); info.serviceInfo = new ServiceInfo(); info.serviceInfo.packageName = packageName; info.serviceInfo.name = transportName; transportsInfo.add(info); } Intent intent = new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST); intent.setPackage(packageName); mPackageManager.addResolveInfoForIntent(intent, transportsInfo); } } services/robotests/src/com/android/server/backup/testing/BackupTransportStub.java 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.testing; import android.app.backup.RestoreDescription; import android.app.backup.RestoreSet; import android.content.Intent; import android.content.pm.PackageInfo; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import com.android.internal.backup.IBackupTransport; /** * Stub backup transport, doing nothing and returning default values. */ public class BackupTransportStub implements IBackupTransport { private final String mName; public BackupTransportStub(String name) { mName = name; } @Override public IBinder asBinder() { return null; } @Override public String name() throws RemoteException { return mName; } @Override public Intent configurationIntent() throws RemoteException { return null; } @Override public String currentDestinationString() throws RemoteException { return null; } @Override public Intent dataManagementIntent() throws RemoteException { return null; } @Override public String dataManagementLabel() throws RemoteException { return null; } @Override public String transportDirName() throws RemoteException { return null; } @Override public long requestBackupTime() throws RemoteException { return 0; } @Override public int initializeDevice() throws RemoteException { return 0; } @Override public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) throws RemoteException { return 0; } @Override public int clearBackupData(PackageInfo packageInfo) throws RemoteException { return 0; } @Override public int finishBackup() throws RemoteException { return 0; } @Override public RestoreSet[] getAvailableRestoreSets() throws RemoteException { return new RestoreSet[0]; } @Override public long getCurrentRestoreSet() throws RemoteException { return 0; } @Override public int startRestore(long token, PackageInfo[] packages) throws RemoteException { return 0; } @Override public RestoreDescription nextRestorePackage() throws RemoteException { return null; } @Override public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException { return 0; } @Override public void finishRestore() throws RemoteException { } @Override public long requestFullBackupTime() throws RemoteException { return 0; } @Override public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, int flags) throws RemoteException { return 0; } @Override public int checkFullBackupSize(long size) throws RemoteException { return 0; } @Override public int sendBackupData(int numBytes) throws RemoteException { return 0; } @Override public void cancelFullBackup() throws RemoteException { } @Override public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup) throws RemoteException { return false; } @Override public long getBackupQuota(String packageName, boolean isFullBackup) throws RemoteException { return 0; } @Override public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) throws RemoteException { return 0; } @Override public int abortFullRestore() throws RemoteException { return 0; } } services/robotests/src/com/android/server/backup/testing/DefaultPackageManagerWithQueryIntentServicesAsUser.java 0 → 100644 +43 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.testing; import android.content.Intent; import android.content.pm.ResolveInfo; import org.robolectric.res.ResourceLoader; import org.robolectric.res.builder.DefaultPackageManager; import java.util.List; /** * Implementation of PackageManager for Robolectric which handles queryIntentServicesAsUser(). */ public class DefaultPackageManagerWithQueryIntentServicesAsUser extends DefaultPackageManager { /* package */ public DefaultPackageManagerWithQueryIntentServicesAsUser( ResourceLoader appResourceLoader) { super(appResourceLoader); } @Override public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { return super.queryIntentServices(intent, flags); } } Loading
services/backup/java/com/android/server/backup/TransportManager.java +1 −1 Original line number Diff line number Diff line Loading @@ -455,7 +455,7 @@ public class TransportManager { } } interface TransportBoundListener { public interface TransportBoundListener { /** Should return true if this is a valid transport. */ boolean onTransportBound(IBackupTransport binder); } Loading
services/robotests/Android.mk +2 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,6 @@ LOCAL_STATIC_JAVA_LIBRARIES := \ LOCAL_TEST_PACKAGE := FrameworksServicesLib LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java include prebuilts/misc/common/robolectric/run_robotests.mk
services/robotests/src/com/android/server/backup/TransportManagerTest.java +117 −48 Original line number Diff line number Diff line Loading @@ -18,32 +18,36 @@ package com.android.server.backup; import static com.google.common.truth.Truth.assertThat; import android.annotation.RequiresPermission; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.os.UserHandle; import android.os.IBinder; import android.platform.test.annotations.Presubmit; import com.android.server.backup.testing.BackupTransportStub; import com.android.server.backup.testing.DefaultPackageManagerWithQueryIntentServicesAsUser; import com.android.server.backup.testing.ShadowBackupTransportStub; import com.android.server.backup.testing.ShadowContextImplWithBindServiceAsUser; import com.android.server.backup.testing.TransportBoundListenerStub; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.res.ResourceLoader; import org.robolectric.res.builder.DefaultPackageManager; import org.robolectric.res.builder.RobolectricPackageManager; import org.robolectric.shadows.ShadowContextImpl; import org.robolectric.shadows.ShadowLog; import org.robolectric.shadows.ShadowLooper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; Loading @@ -51,12 +55,18 @@ import java.util.List; @Config( manifest = Config.NONE, sdk = 23, shadows = {TransportManagerTest.ShadowContextImplWithBindServiceAsUser.class} shadows = { ShadowContextImplWithBindServiceAsUser.class, ShadowBackupTransportStub.class } ) @Presubmit public class TransportManagerTest { private static final String PACKAGE_NAME = "some.package.name"; private static final String TRANSPORT1_NAME = "transport1.name"; private static final String TRANSPORT2_NAME = "transport2.name"; private static final List<String> TRANSPORTS_NAMES = Arrays.asList( TRANSPORT1_NAME, TRANSPORT2_NAME); private static final ComponentName TRANSPORT1_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, TRANSPORT1_NAME); private static final ComponentName TRANSPORT2_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, Loading @@ -66,72 +76,131 @@ public class TransportManagerTest { private RobolectricPackageManager mPackageManager; @Mock private TransportManager.TransportBoundListener mTransportBoundListener; @Mock private IBinder mTransport1BinderMock; @Mock private IBinder mTransport2BinderMock; private final BackupTransportStub mTransport1Stub = new BackupTransportStub(TRANSPORT1_NAME); private final BackupTransportStub mTransport2Stub = new BackupTransportStub(TRANSPORT2_NAME); private final TransportBoundListenerStub mTransportBoundListenerStub = new TransportBoundListenerStub(true); @Before public void setUp() { public void setUp() throws Exception { MockitoAnnotations.initMocks(this); ShadowLog.stream = System.out; mPackageManager = new DefaultPackageManagerWithQueryIntentServicesAsUser( RuntimeEnvironment.getAppResourceLoader()); RuntimeEnvironment.setRobolectricPackageManager(mPackageManager); ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT1_COMPONENT_NAME, mTransport1BinderMock); ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT2_COMPONENT_NAME, mTransport2BinderMock); ShadowBackupTransportStub.sBinderTransportMap.put(mTransport1BinderMock, mTransport1Stub); ShadowBackupTransportStub.sBinderTransportMap.put(mTransport2BinderMock, mTransport2Stub); } @Test public void onPackageAdded_bindsToAllTransports() { Intent intent = new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST); intent.setPackage(PACKAGE_NAME); public void onPackageAdded_bindsToAllTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = PACKAGE_NAME; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); mPackageManager.addPackage(packageInfo); assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn( TRANSPORTS_COMPONENT_NAMES); assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn( TRANSPORTS_NAMES); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isTrue(); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue(); } ResolveInfo transport1 = new ResolveInfo(); transport1.serviceInfo = new ServiceInfo(); transport1.serviceInfo.packageName = PACKAGE_NAME; transport1.serviceInfo.name = TRANSPORT1_NAME; @Test public void onPackageAdded_whitelistIsNull_doesNotBindToTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); ResolveInfo transport2 = new ResolveInfo(); transport2.serviceInfo = new ServiceInfo(); transport2.serviceInfo.packageName = PACKAGE_NAME; transport2.serviceInfo.name = TRANSPORT2_NAME; TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), null /* whitelist */, null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); mPackageManager.addResolveInfoForIntent(intent, Arrays.asList(transport1, transport2)); assertThat(transportManager.getAllTransportComponents()).isEmpty(); assertThat(transportManager.getBoundTransportNames()).isEmpty(); assertThat(mTransportBoundListenerStub.isCalled()).isFalse(); } @Test public void onPackageAdded_onlyOneTransportWhitelisted_onlyConnectsToWhitelistedTransport() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED); TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null, mTransportBoundListener, new HashSet<>(Collections.singleton(TRANSPORT2_COMPONENT_NAME)), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn( TRANSPORTS_COMPONENT_NAMES); Collections.singleton(TRANSPORT2_COMPONENT_NAME)); assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn( Collections.singleton(TRANSPORT2_NAME)); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isFalse(); assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue(); } private static class DefaultPackageManagerWithQueryIntentServicesAsUser extends DefaultPackageManager { @Test public void onPackageAdded_appIsNotPrivileged_doesNotBindToTransports() throws Exception { setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, 0); /* package */ DefaultPackageManagerWithQueryIntentServicesAsUser( ResourceLoader appResourceLoader) { super(appResourceLoader); } TransportManager transportManager = new TransportManager( RuntimeEnvironment.application.getApplicationContext(), new HashSet<>(TRANSPORTS_COMPONENT_NAMES), null /* defaultTransport */, mTransportBoundListenerStub, ShadowLooper.getMainLooper()); transportManager.onPackageAdded(PACKAGE_NAME); @Override public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { return super.queryIntentServices(intent, flags); } assertThat(transportManager.getAllTransportComponents()).isEmpty(); assertThat(transportManager.getBoundTransportNames()).isEmpty(); assertThat(mTransportBoundListenerStub.isCalled()).isFalse(); } @Implements(className = ShadowContextImpl.CLASS_NAME) public static class ShadowContextImplWithBindServiceAsUser extends ShadowContextImpl { private void setUpPackageWithTransports(String packageName, List<String> transportNames, int flags) throws Exception { PackageInfo packageInfo = new PackageInfo(); packageInfo.packageName = packageName; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.privateFlags = flags; mPackageManager.addPackage(packageInfo); @Implementation public boolean bindServiceAsUser(@RequiresPermission Intent service, ServiceConnection conn, int flags, UserHandle user) { return true; List<ResolveInfo> transportsInfo = new ArrayList<>(); for (String transportName : transportNames) { ResolveInfo info = new ResolveInfo(); info.serviceInfo = new ServiceInfo(); info.serviceInfo.packageName = packageName; info.serviceInfo.name = transportName; transportsInfo.add(info); } Intent intent = new Intent(TransportManager.SERVICE_ACTION_TRANSPORT_HOST); intent.setPackage(packageName); mPackageManager.addResolveInfoForIntent(intent, transportsInfo); } }
services/robotests/src/com/android/server/backup/testing/BackupTransportStub.java 0 → 100644 +179 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.testing; import android.app.backup.RestoreDescription; import android.app.backup.RestoreSet; import android.content.Intent; import android.content.pm.PackageInfo; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import com.android.internal.backup.IBackupTransport; /** * Stub backup transport, doing nothing and returning default values. */ public class BackupTransportStub implements IBackupTransport { private final String mName; public BackupTransportStub(String name) { mName = name; } @Override public IBinder asBinder() { return null; } @Override public String name() throws RemoteException { return mName; } @Override public Intent configurationIntent() throws RemoteException { return null; } @Override public String currentDestinationString() throws RemoteException { return null; } @Override public Intent dataManagementIntent() throws RemoteException { return null; } @Override public String dataManagementLabel() throws RemoteException { return null; } @Override public String transportDirName() throws RemoteException { return null; } @Override public long requestBackupTime() throws RemoteException { return 0; } @Override public int initializeDevice() throws RemoteException { return 0; } @Override public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) throws RemoteException { return 0; } @Override public int clearBackupData(PackageInfo packageInfo) throws RemoteException { return 0; } @Override public int finishBackup() throws RemoteException { return 0; } @Override public RestoreSet[] getAvailableRestoreSets() throws RemoteException { return new RestoreSet[0]; } @Override public long getCurrentRestoreSet() throws RemoteException { return 0; } @Override public int startRestore(long token, PackageInfo[] packages) throws RemoteException { return 0; } @Override public RestoreDescription nextRestorePackage() throws RemoteException { return null; } @Override public int getRestoreData(ParcelFileDescriptor outFd) throws RemoteException { return 0; } @Override public void finishRestore() throws RemoteException { } @Override public long requestFullBackupTime() throws RemoteException { return 0; } @Override public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor socket, int flags) throws RemoteException { return 0; } @Override public int checkFullBackupSize(long size) throws RemoteException { return 0; } @Override public int sendBackupData(int numBytes) throws RemoteException { return 0; } @Override public void cancelFullBackup() throws RemoteException { } @Override public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup) throws RemoteException { return false; } @Override public long getBackupQuota(String packageName, boolean isFullBackup) throws RemoteException { return 0; } @Override public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) throws RemoteException { return 0; } @Override public int abortFullRestore() throws RemoteException { return 0; } }
services/robotests/src/com/android/server/backup/testing/DefaultPackageManagerWithQueryIntentServicesAsUser.java 0 → 100644 +43 −0 Original line number Diff line number Diff line /* * Copyright (C) 2017 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.testing; import android.content.Intent; import android.content.pm.ResolveInfo; import org.robolectric.res.ResourceLoader; import org.robolectric.res.builder.DefaultPackageManager; import java.util.List; /** * Implementation of PackageManager for Robolectric which handles queryIntentServicesAsUser(). */ public class DefaultPackageManagerWithQueryIntentServicesAsUser extends DefaultPackageManager { /* package */ public DefaultPackageManagerWithQueryIntentServicesAsUser( ResourceLoader appResourceLoader) { super(appResourceLoader); } @Override public List<ResolveInfo> queryIntentServicesAsUser(Intent intent, int flags, int userId) { return super.queryIntentServices(intent, flags); } }