summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nino Jagar <njagar@google.com> 2023-10-31 17:17:27 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-10-31 17:17:27 +0000
commite529440c4297564360cab35e717cc7f003b9373c (patch)
treefe4cef3e6befed514b7876a660fc714017390346
parent25693fe12e5bc6c39c19ddcd296d7810a5b1b330 (diff)
parent0f897955025323766d7852c99bef2fa0726288e1 (diff)
Merge "Allow service to update content protection allowlist" into main
-rw-r--r--core/java/android/service/contentcapture/ContentCaptureService.java62
-rw-r--r--core/java/android/service/contentcapture/IContentProtectionAllowlistCallback.aidl34
-rw-r--r--core/java/android/service/contentcapture/IContentProtectionService.aidl3
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java11
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java39
-rw-r--r--services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java53
8 files changed, 190 insertions, 33 deletions
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index 06e86af0208f..78248d9775f4 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -138,7 +138,8 @@ public abstract class ContentCaptureService extends Service {
new LocalDataShareAdapterResourceManager();
private Handler mHandler;
- private IContentCaptureServiceCallback mCallback;
+ @Nullable private IContentCaptureServiceCallback mContentCaptureServiceCallback;
+ @Nullable private IContentProtectionAllowlistCallback mContentProtectionAllowlistCallback;
private long mCallerMismatchTimeout = 1000;
private long mLastCallerMismatchLog;
@@ -215,6 +216,16 @@ public abstract class ContentCaptureService extends Service {
Binder.getCallingUid(),
events));
}
+
+ @Override
+ public void onUpdateAllowlistRequest(IBinder callback) {
+ mHandler.sendMessage(
+ obtainMessage(
+ ContentCaptureService::handleOnUpdateAllowlistRequest,
+ ContentCaptureService.this,
+ Binder.getCallingUid(),
+ callback));
+ }
};
/** Binder that receives calls from the app in the content capture flow. */
@@ -278,14 +289,31 @@ public abstract class ContentCaptureService extends Service {
*/
public final void setContentCaptureWhitelist(@Nullable Set<String> packages,
@Nullable Set<ComponentName> activities) {
- final IContentCaptureServiceCallback callback = mCallback;
- if (callback == null) {
- Log.w(TAG, "setContentCaptureWhitelist(): no server callback");
+
+ IContentCaptureServiceCallback contentCaptureCallback = mContentCaptureServiceCallback;
+ IContentProtectionAllowlistCallback contentProtectionAllowlistCallback =
+ mContentProtectionAllowlistCallback;
+
+ if (contentCaptureCallback == null && contentProtectionAllowlistCallback == null) {
+ Log.w(TAG, "setContentCaptureWhitelist(): missing both server callbacks");
+ return;
+ }
+
+ if (contentCaptureCallback != null) {
+ if (contentProtectionAllowlistCallback != null) {
+ throw new IllegalStateException("Have both server callbacks");
+ }
+ try {
+ contentCaptureCallback.setContentCaptureWhitelist(
+ toList(packages), toList(activities));
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
return;
}
try {
- callback.setContentCaptureWhitelist(toList(packages), toList(activities));
+ contentProtectionAllowlistCallback.setAllowlist(toList(packages));
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
@@ -314,7 +342,7 @@ public abstract class ContentCaptureService extends Service {
*/
public final void setContentCaptureConditions(@NonNull String packageName,
@Nullable Set<ContentCaptureCondition> conditions) {
- final IContentCaptureServiceCallback callback = mCallback;
+ final IContentCaptureServiceCallback callback = mContentCaptureServiceCallback;
if (callback == null) {
Log.w(TAG, "setContentCaptureConditions(): no server callback");
return;
@@ -425,7 +453,7 @@ public abstract class ContentCaptureService extends Service {
public final void disableSelf() {
if (sDebug) Log.d(TAG, "disableSelf()");
- final IContentCaptureServiceCallback callback = mCallback;
+ final IContentCaptureServiceCallback callback = mContentCaptureServiceCallback;
if (callback == null) {
Log.w(TAG, "disableSelf(): no server callback");
return;
@@ -464,13 +492,14 @@ public abstract class ContentCaptureService extends Service {
}
private void handleOnConnected(@NonNull IBinder callback) {
- mCallback = IContentCaptureServiceCallback.Stub.asInterface(callback);
+ mContentCaptureServiceCallback = IContentCaptureServiceCallback.Stub.asInterface(callback);
onConnected();
}
private void handleOnDisconnected() {
onDisconnected();
- mCallback = null;
+ mContentCaptureServiceCallback = null;
+ mContentProtectionAllowlistCallback = null;
}
//TODO(b/111276913): consider caching the InteractionSessionId for the lifetime of the session,
@@ -583,6 +612,16 @@ public abstract class ContentCaptureService extends Service {
onContentCaptureEvent(sessionId, endEvent);
}
+ private void handleOnUpdateAllowlistRequest(int uid, @NonNull IBinder callback) {
+ if (uid != Process.SYSTEM_UID) {
+ Log.e(TAG, "handleOnUpdateAllowlistRequest() not allowed for uid: " + uid);
+ return;
+ }
+ mContentProtectionAllowlistCallback =
+ IContentProtectionAllowlistCallback.Stub.asInterface(callback);
+ onConnected();
+ }
+
private void handleOnActivitySnapshot(int sessionId, @NonNull SnapshotData snapshotData) {
onActivitySnapshot(new ContentCaptureSessionId(sessionId), snapshotData);
}
@@ -701,13 +740,14 @@ public abstract class ContentCaptureService extends Service {
private void writeFlushMetrics(int sessionId, @Nullable ComponentName app,
@NonNull FlushMetrics flushMetrics, @Nullable ContentCaptureOptions options,
int flushReason) {
- if (mCallback == null) {
+ if (mContentCaptureServiceCallback == null) {
Log.w(TAG, "writeSessionFlush(): no server callback");
return;
}
try {
- mCallback.writeSessionFlush(sessionId, app, flushMetrics, options, flushReason);
+ mContentCaptureServiceCallback.writeSessionFlush(
+ sessionId, app, flushMetrics, options, flushReason);
} catch (RemoteException e) {
Log.e(TAG, "failed to write flush metrics: " + e);
}
diff --git a/core/java/android/service/contentcapture/IContentProtectionAllowlistCallback.aidl b/core/java/android/service/contentcapture/IContentProtectionAllowlistCallback.aidl
new file mode 100644
index 000000000000..8d5a15c1fdd2
--- /dev/null
+++ b/core/java/android/service/contentcapture/IContentProtectionAllowlistCallback.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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 android.service.contentcapture;
+
+import android.content.ComponentName;
+import android.view.contentcapture.ContentCaptureCondition;
+import android.service.contentcapture.FlushMetrics;
+import android.content.ContentCaptureOptions;
+
+import java.util.List;
+
+/**
+ * Interface for the callback used by the content protection service to call the system server and
+ * update the allowlist.
+ *
+ * @hide
+ */
+oneway interface IContentProtectionAllowlistCallback {
+ void setAllowlist(in List<String> packages);
+}
diff --git a/core/java/android/service/contentcapture/IContentProtectionService.aidl b/core/java/android/service/contentcapture/IContentProtectionService.aidl
index 4a13c3f63a33..25b248fcc8d4 100644
--- a/core/java/android/service/contentcapture/IContentProtectionService.aidl
+++ b/core/java/android/service/contentcapture/IContentProtectionService.aidl
@@ -17,6 +17,7 @@
package android.service.contentcapture;
import android.content.pm.ParceledListSlice;
+import android.os.IBinder;
import android.view.contentcapture.ContentCaptureEvent;
/**
@@ -27,4 +28,6 @@ import android.view.contentcapture.ContentCaptureEvent;
oneway interface IContentProtectionService {
void onLoginDetected(in ParceledListSlice events);
+
+ void onUpdateAllowlistRequest(in IBinder callback);
}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 5f612d6b0009..970baf2ce264 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -411,6 +411,15 @@ public final class ContentCaptureManager {
public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS =
"content_protection_allowlist_timeout_ms";
+ /**
+ * Sets the auto disconnect timeout for the content protection service in milliseconds.
+ *
+ * @hide
+ */
+ // Unit can't be in the name in order to pass the checkstyle hook, line would be too long.
+ public static final String DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT =
+ "content_protection_auto_disconnect_timeout_ms";
+
/** @hide */
@TestApi
public static final int LOGGING_LEVEL_OFF = 0;
@@ -465,6 +474,8 @@ public final class ContentCaptureManager {
public static final long DEFAULT_CONTENT_PROTECTION_ALLOWLIST_DELAY_MS = 30000;
/** @hide */
public static final long DEFAULT_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS = 250;
+ /** @hide */
+ public static final long DEFAULT_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT_MS = 3000;
private final Object mLock = new Object();
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9f4528b113e7..b2ff3c313837 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -22,9 +22,12 @@ import static android.service.contentcapture.ContentCaptureService.setClientStat
import static android.view.contentcapture.ContentCaptureHelper.toList;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_DELAY_MS;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS;
+import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT;
+import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_CONFIG;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_THRESHOLD;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_REQUIRED_GROUPS_CONFIG;
+import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION;
@@ -227,6 +230,9 @@ public class ContentCaptureManagerService extends
@GuardedBy("mLock")
long mDevCfgContentProtectionAllowlistTimeoutMs;
+ @GuardedBy("mLock")
+ long mDevCfgContentProtectionAutoDisconnectTimeoutMs;
+
private final Executor mDataShareExecutor = Executors.newCachedThreadPool();
private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -435,14 +441,15 @@ public class ContentCaptureManagerService extends
case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_IDLE_UNBIND_TIMEOUT:
case ContentCaptureManager
.DEVICE_CONFIG_PROPERTY_DISABLE_FLUSH_FOR_VIEW_TREE_APPEARING:
- case ContentCaptureManager
- .DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER:
- case ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE:
+ // Content protection below
+ case DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER:
+ case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE:
case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_REQUIRED_GROUPS_CONFIG:
case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_CONFIG:
case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_THRESHOLD:
case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_DELAY_MS:
case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS:
+ case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT:
setFineTuneParamsFromDeviceConfig();
return;
default:
@@ -502,8 +509,7 @@ public class ContentCaptureManagerService extends
mDevCfgContentProtectionBufferSize =
DeviceConfig.getInt(
DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
- ContentCaptureManager
- .DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE,
+ DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_BUFFER_SIZE,
ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_BUFFER_SIZE);
contentProtectionRequiredGroupsConfig =
DeviceConfig.getString(
@@ -533,7 +539,12 @@ public class ContentCaptureManagerService extends
DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS,
ContentCaptureManager.DEFAULT_CONTENT_PROTECTION_ALLOWLIST_TIMEOUT_MS);
-
+ mDevCfgContentProtectionAutoDisconnectTimeoutMs =
+ DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
+ DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT,
+ ContentCaptureManager
+ .DEFAULT_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT_MS);
contentProtectionAllowlistManagerOld = mContentProtectionAllowlistManager;
if (verbose) {
@@ -565,7 +576,9 @@ public class ContentCaptureManagerService extends
+ ", contentProtectionAllowlistDelayMs="
+ contentProtectionAllowlistDelayMs
+ ", contentProtectionAllowlistTimeoutMs="
- + contentProtectionAllowlistTimeoutMs);
+ + contentProtectionAllowlistTimeoutMs
+ + ", contentProtectionAutoDisconnectTimeoutMs="
+ + mDevCfgContentProtectionAutoDisconnectTimeoutMs);
}
}
@@ -893,6 +906,9 @@ public class ContentCaptureManagerService extends
pw.print(prefix2);
pw.print("contentProtectionAllowlistTimeoutMs: ");
pw.println(mDevCfgContentProtectionAllowlistTimeoutMs);
+ pw.print(prefix2);
+ pw.print("contentProtectionAutoDisconnectTimeoutMs: ");
+ pw.println(mDevCfgContentProtectionAutoDisconnectTimeoutMs);
pw.print(prefix);
pw.println("Global Options:");
mGlobalContentCaptureOptions.dump(prefix2, pw);
@@ -962,12 +978,14 @@ public class ContentCaptureManagerService extends
@Nullable
public RemoteContentProtectionService createRemoteContentProtectionService() {
ComponentName componentName;
+ long autoDisconnectTimeoutMs;
synchronized (mLock) {
if (!mDevCfgEnableContentProtectionReceiver
|| mContentProtectionServiceComponentName == null) {
return null;
}
componentName = mContentProtectionServiceComponentName;
+ autoDisconnectTimeoutMs = mDevCfgContentProtectionAutoDisconnectTimeoutMs;
}
// Check permissions by trying to construct {@link ContentCaptureServiceInfo}
@@ -978,19 +996,20 @@ public class ContentCaptureManagerService extends
return null;
}
- return createRemoteContentProtectionService(componentName);
+ return createRemoteContentProtectionService(componentName, autoDisconnectTimeoutMs);
}
/** @hide */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
@NonNull
protected RemoteContentProtectionService createRemoteContentProtectionService(
- @NonNull ComponentName componentName) {
+ @NonNull ComponentName componentName, long autoDisconnectTimeoutMs) {
return new RemoteContentProtectionService(
getContext(),
componentName,
UserHandle.getCallingUserId(),
- isBindInstantServiceAllowed());
+ isBindInstantServiceAllowed(),
+ autoDisconnectTimeoutMs);
}
/** @hide */
diff --git a/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java b/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java
index dd5545dcccc7..bc11fc3cdaf0 100644
--- a/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java
+++ b/services/contentcapture/java/com/android/server/contentprotection/RemoteContentProtectionService.java
@@ -22,14 +22,13 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ParceledListSlice;
import android.service.contentcapture.ContentCaptureService;
+import android.service.contentcapture.IContentProtectionAllowlistCallback;
import android.service.contentcapture.IContentProtectionService;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureEvent;
import com.android.internal.infra.ServiceConnector;
-import java.time.Duration;
-
/**
* Connector for the remote content protection service.
*
@@ -40,15 +39,16 @@ public class RemoteContentProtectionService
private static final String TAG = RemoteContentProtectionService.class.getSimpleName();
- private static final Duration AUTO_DISCONNECT_TIMEOUT = Duration.ofSeconds(3);
-
@NonNull private final ComponentName mComponentName;
+ private final long mAutoDisconnectTimeoutMs;
+
public RemoteContentProtectionService(
@NonNull Context context,
@NonNull ComponentName componentName,
int userId,
- boolean bindAllowInstant) {
+ boolean bindAllowInstant,
+ long autoDisconnectTimeoutMs) {
super(
context,
new Intent(ContentCaptureService.PROTECTION_SERVICE_INTERFACE)
@@ -57,11 +57,12 @@ public class RemoteContentProtectionService
userId,
IContentProtectionService.Stub::asInterface);
mComponentName = componentName;
+ mAutoDisconnectTimeoutMs = autoDisconnectTimeoutMs;
}
@Override // from ServiceConnector.Impl
protected long getAutoDisconnectTimeoutMs() {
- return AUTO_DISCONNECT_TIMEOUT.toMillis();
+ return mAutoDisconnectTimeoutMs;
}
@Override // from ServiceConnector.Impl
@@ -75,7 +76,13 @@ public class RemoteContentProtectionService
+ (isConnected ? "connected" : "disconnected"));
}
+ /** Calls the remote service when login is detected. */
public void onLoginDetected(@NonNull ParceledListSlice<ContentCaptureEvent> events) {
run(service -> service.onLoginDetected(events));
}
+
+ /** Calls the remote service with a request to update allowlist. */
+ public void onUpdateAllowlistRequest(@NonNull IContentProtectionAllowlistCallback callback) {
+ run(service -> service.onUpdateAllowlistRequest(callback.asBinder()));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
index 9a5241ea242a..6d13d876b06b 100644
--- a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
@@ -662,7 +662,7 @@ public class ContentCaptureManagerServiceTest {
@Override
protected RemoteContentProtectionService createRemoteContentProtectionService(
- @NonNull ComponentName componentName) {
+ @NonNull ComponentName componentName, long autoDisconnectTimeoutMs) {
mRemoteContentProtectionServicesCreated++;
return mMockRemoteContentProtectionService;
}
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
index 9135ef3a1286..6a7e2865fb32 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
@@ -21,12 +21,16 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ParceledListSlice;
+import android.os.Binder;
+import android.os.IBinder;
import android.os.UserHandle;
+import android.service.contentcapture.IContentProtectionAllowlistCallback;
import android.service.contentcapture.IContentProtectionService;
import android.view.contentcapture.ContentCaptureEvent;
@@ -57,21 +61,27 @@ import org.mockito.junit.MockitoRule;
@SmallTest
public class RemoteContentProtectionServiceTest {
- private final Context mContext = ApplicationProvider.getApplicationContext();
+ private static final long AUTO_DISCONNECT_TIMEOUT_MS = 12345L;
+
+ private static final IBinder BINDER = new Binder();
+
+ private static final Context CONTEXT = ApplicationProvider.getApplicationContext();
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Mock private IContentProtectionService mMockContentProtectionService;
+ @Mock private IContentProtectionAllowlistCallback mMockContentProtectionAllowlistCallback;
+
private RemoteContentProtectionService mRemoteContentProtectionService;
private int mConnectCallCount = 0;
@Before
public void setup() {
- ComponentName componentName = new ComponentName(mContext.getPackageName(), "TestClass");
+ ComponentName componentName = new ComponentName(CONTEXT.getPackageName(), "TestClass");
mRemoteContentProtectionService =
- new TestRemoteContentProtectionService(mContext, componentName);
+ new TestRemoteContentProtectionService(CONTEXT, componentName);
}
@Test
@@ -84,7 +94,7 @@ public class RemoteContentProtectionServiceTest {
public void getAutoDisconnectTimeoutMs() {
long actual = mRemoteContentProtectionService.getAutoDisconnectTimeoutMs();
- assertThat(actual).isEqualTo(3000L);
+ assertThat(actual).isEqualTo(AUTO_DISCONNECT_TIMEOUT_MS);
}
@Test
@@ -99,10 +109,43 @@ public class RemoteContentProtectionServiceTest {
verify(mMockContentProtectionService).onLoginDetected(events);
}
+ @Test
+ public void onUpdateAllowlistRequest() throws Exception {
+ when(mMockContentProtectionAllowlistCallback.asBinder()).thenReturn(BINDER);
+
+ mRemoteContentProtectionService.onUpdateAllowlistRequest(
+ mMockContentProtectionAllowlistCallback);
+
+ verify(mMockContentProtectionService).onUpdateAllowlistRequest(BINDER);
+ }
+
+ @Test
+ public void onServiceConnectionStatusChanged_connected_noSideEffects() {
+ mRemoteContentProtectionService.onServiceConnectionStatusChanged(
+ mMockContentProtectionService, /* isConnected= */ true);
+
+ verifyZeroInteractions(mMockContentProtectionService);
+ assertThat(mConnectCallCount).isEqualTo(0);
+ }
+
+ @Test
+ public void onServiceConnectionStatusChanged_disconnected_noSideEffects() {
+ mRemoteContentProtectionService.onServiceConnectionStatusChanged(
+ mMockContentProtectionService, /* isConnected= */ false);
+
+ verifyZeroInteractions(mMockContentProtectionService);
+ assertThat(mConnectCallCount).isEqualTo(0);
+ }
+
private final class TestRemoteContentProtectionService extends RemoteContentProtectionService {
TestRemoteContentProtectionService(Context context, ComponentName componentName) {
- super(context, componentName, UserHandle.myUserId(), /* bindAllowInstant= */ false);
+ super(
+ context,
+ componentName,
+ UserHandle.myUserId(),
+ /* bindAllowInstant= */ false,
+ AUTO_DISCONNECT_TIMEOUT_MS);
}
@Override // from ServiceConnector