Add getCurrentTransportComponent() API
Bug: 73640944
Test: atest RunFrameworksServicesRoboTests
Change-Id: I62193d63367c3b7564ccd41f5b103a7076764e3f
diff --git a/api/system-current.txt b/api/system-current.txt
index 1322a39..242e6f2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -484,6 +484,7 @@
method public long getAvailableRestoreToken(java.lang.String);
method public android.content.Intent getConfigurationIntent(java.lang.String);
method public java.lang.String getCurrentTransport();
+ method public android.content.ComponentName getCurrentTransportComponent();
method public android.content.Intent getDataManagementIntent(java.lang.String);
method public java.lang.String getDataManagementLabel(java.lang.String);
method public java.lang.String getDestinationString(java.lang.String);
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index debc32b..8e92393 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -443,6 +443,27 @@
}
/**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BACKUP)
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ checkServiceBinder();
+ if (sService != null) {
+ try {
+ return sService.getCurrentTransportComponent();
+ } catch (RemoteException e) {
+ Log.e(TAG, "getCurrentTransportComponent() couldn't connect");
+ }
+ }
+ return null;
+ }
+
+ /**
* Request a list of all available backup transports' names.
*
* @hide
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index f3ca746..1c55d8a 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -244,8 +244,6 @@
* {@code null} and MUST NOT be {@code null} when dataManagementIntent is not {@code null}.
* @throws SecurityException If the UID of the calling process differs from the package UID of
* {@code transportComponent} or if the caller does NOT have BACKUP permission.
- *
- * @hide
*/
void updateTransportAttributes(in ComponentName transportComponent, in String name,
in Intent configurationIntent, in String currentDestinationString,
@@ -257,6 +255,13 @@
*/
String getCurrentTransport();
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered. Callers must
+ * hold the android.permission.BACKUP permission to use this method.
+ */
+ ComponentName getCurrentTransportComponent();
+
/**
* Request a list of all available backup transports' names. Callers must
* hold the android.permission.BACKUP permission to use this method.
@@ -296,8 +301,6 @@
* the transport's name that is returned by {@link BackupTransport#name()}.
* @param listener A listener object to get a callback on the transport being selected. It may
* be {@code null}.
- *
- * @hide
*/
void selectBackupTransportAsync(in ComponentName transport, ISelectBackupTransportCallback listener);
@@ -364,7 +367,6 @@
* @param result In the case of a full backup measure operation, the estimated
* total file size that would result from the operation. Unused in all other
* cases.
- * {@hide}
*/
void opComplete(int token, long result);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index bd51af2..d7db471 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -2901,6 +2901,25 @@
return currentTransport;
}
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or {@code
+ * null} if no transport selected or if the transport selected is not registered.
+ */
+ @Override
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.BACKUP, "getCurrentTransportComponent");
+ long oldId = Binder.clearCallingIdentity();
+ try {
+ return mTransportManager.getCurrentTransportComponent();
+ } catch (TransportNotRegisteredException e) {
+ return null;
+ } finally {
+ Binder.restoreCallingIdentity(oldId);
+ }
+ }
+
// Report all known, available backup transports
@Override
public String[] listAllTransports() {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
index aabe7f6..f2219a0 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -16,6 +16,7 @@
package com.android.server.backup;
+import android.annotation.Nullable;
import android.app.IBackupAgent;
import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
@@ -132,6 +133,10 @@
// Report the name of the currently active transport
String getCurrentTransport();
+ // Report the component name of the host service of the currently active transport
+ @Nullable
+ ComponentName getCurrentTransportComponent();
+
// Report all known, available backup transports
String[] listAllTransports();
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 2abeaa6..787d667 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -19,8 +19,8 @@
import android.annotation.Nullable;
import android.app.backup.BackupManager;
import android.app.backup.IBackupManager;
-import android.app.backup.IBackupObserver;
import android.app.backup.IBackupManagerMonitor;
+import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
@@ -341,6 +341,17 @@
return (svc != null) ? svc.getCurrentTransport() : null;
}
+ /**
+ * Returns the {@link ComponentName} of the host service of the selected transport or
+ * {@code null} if no transport selected or if the transport selected is not registered.
+ */
+ @Override
+ @Nullable
+ public ComponentName getCurrentTransportComponent() {
+ BackupManagerServiceInterface svc = mService;
+ return (svc != null) ? svc.getCurrentTransportComponent() : null;
+ }
+
@Override
public String[] listAllTransports() throws RemoteException {
BackupManagerServiceInterface svc = mService;
diff --git a/services/backup/java/com/android/server/backup/TransportManager.java b/services/backup/java/com/android/server/backup/TransportManager.java
index 64e24d8..ddce6bb 100644
--- a/services/backup/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/java/com/android/server/backup/TransportManager.java
@@ -176,12 +176,30 @@
return mTransportWhitelist;
}
+ /** Returns the name of the selected transport or {@code null} if no transport selected. */
@Nullable
public String getCurrentTransportName() {
return mCurrentTransportName;
}
/**
+ * Returns the {@link ComponentName} of the host service of the selected transport or
+ * {@code null} if no transport selected.
+ *
+ * @throws TransportNotRegisteredException if the selected transport is not registered.
+ */
+ @Nullable
+ public ComponentName getCurrentTransportComponent()
+ throws TransportNotRegisteredException {
+ synchronized (mTransportLock) {
+ if (mCurrentTransportName == null) {
+ return null;
+ }
+ return getRegisteredTransportComponentOrThrowLocked(mCurrentTransportName);
+ }
+ }
+
+ /**
* Returns the transport name associated with {@code transportComponent}.
*
* @throws TransportNotRegisteredException if the transport is not registered.
@@ -325,6 +343,16 @@
}
@GuardedBy("mTransportLock")
+ private ComponentName getRegisteredTransportComponentOrThrowLocked(String transportName)
+ throws TransportNotRegisteredException {
+ ComponentName transportComponent = getRegisteredTransportComponentLocked(transportName);
+ if (transportComponent == null) {
+ throw new TransportNotRegisteredException(transportName);
+ }
+ return transportComponent;
+ }
+
+ @GuardedBy("mTransportLock")
private TransportDescription getRegisteredTransportDescriptionOrThrowLocked(
ComponentName transportComponent) throws TransportNotRegisteredException {
TransportDescription description =
diff --git a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
index 340100f..8399aaf 100644
--- a/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
+++ b/services/robotests/src/com/android/server/backup/BackupManagerServiceTest.java
@@ -76,10 +76,9 @@
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
- manifest = Config.NONE,
- sdk = 26,
- shadows = {ShadowAppBackupUtils.class, ShadowBackupPolicyEnforcer.class}
-)
+ manifest = Config.NONE,
+ sdk = 26,
+ shadows = {ShadowAppBackupUtils.class, ShadowBackupPolicyEnforcer.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class BackupManagerServiceTest {
@@ -406,6 +405,51 @@
mContext.getContentResolver(), Settings.Secure.BACKUP_TRANSPORT);
}
+ /* Tests for transport attributes */
+
+ @Test
+ public void testGetCurrentTransportComponent() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent())
+ .thenReturn(mTransport.getTransportComponent());
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isEqualTo(mTransport.getTransportComponent());
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenNoTransportSelected() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent()).thenReturn(null);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenTransportNotRegistered() throws Exception {
+ mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
+ when(mTransportManager.getCurrentTransportComponent())
+ .thenThrow(TransportNotRegisteredException.class);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ ComponentName transportComponent = backupManagerService.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_withoutPermission() throws Exception {
+ mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
+ BackupManagerService backupManagerService = createInitializedBackupManagerService();
+
+ expectThrows(SecurityException.class, backupManagerService::getCurrentTransportComponent);
+ }
+
/* Tests for updating transport attributes */
private static final int PACKAGE_UID = 10;
diff --git a/services/robotests/src/com/android/server/backup/TransportManagerTest.java b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
index c2e7595..051a4a0 100644
--- a/services/robotests/src/com/android/server/backup/TransportManagerTest.java
+++ b/services/robotests/src/com/android/server/backup/TransportManagerTest.java
@@ -77,10 +77,9 @@
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
- manifest = Config.NONE,
- sdk = 26,
- shadows = {FrameworkShadowContextImpl.class}
-)
+ manifest = Config.NONE,
+ sdk = 26,
+ shadows = {FrameworkShadowContextImpl.class})
@SystemLoaderPackages({"com.android.server.backup"})
@Presubmit
public class TransportManagerTest {
@@ -394,6 +393,36 @@
}
@Test
+ public void testGetCurrentTransportComponent() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1);
+
+ ComponentName transportComponent = transportManager.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isEqualTo(mTransportA1.getTransportComponent());
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenNoTransportSelected() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(null, mTransportA1);
+
+ ComponentName transportComponent = transportManager.getCurrentTransportComponent();
+
+ assertThat(transportComponent).isNull();
+ }
+
+ @Test
+ public void testGetCurrentTransportComponent_whenTransportNotRegistered() throws Exception {
+ TransportManager transportManager =
+ createTransportManagerWithRegisteredTransports(mTransportA1.unregistered());
+
+ expectThrows(
+ TransportNotRegisteredException.class,
+ transportManager::getCurrentTransportComponent);
+ }
+
+ @Test
public void testGetTransportClient_forRegisteredTransport() throws Exception {
TransportManager transportManager =
createTransportManagerWithRegisteredTransports(mTransportA1, mTransportA2);
diff --git a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
index 1fbadd4..5844131 100644
--- a/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/TransportTestUtils.java
@@ -55,6 +55,9 @@
ShadowPackageManager shadowPackageManager, TransportData... transports)
throws Exception {
for (TransportData transport : transports) {
+ if (transport.transportStatus == TransportStatus.UNREGISTERED) {
+ continue;
+ }
ComponentName transportComponent = transport.getTransportComponent();
String packageName = transportComponent.getPackageName();
ResolveInfo resolveInfo = resolveInfo(transportComponent);