From af4e4fd020c2e719079d81a00f9f58b15c240b20 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Tue, 15 Jan 2019 08:32:42 -0800 Subject: [PATCH] Added IContentCaptureServiceCallback. This binder object will be used to implement the ContentCaptureService methods that require calls to system server. Bug: 122595322 Test: atest CtsContentCaptureServiceTestCases Change-Id: If918af540f78777d00970e0fc75df458aad168b7 --- Android.bp | 1 + .../contentcapture/ContentCaptureService.java | 75 +++++++++++++++---- .../IContentCaptureService.aidl | 4 +- .../IContentCaptureServiceCallback.aidl | 35 +++++++++ .../ContentCapturePerUserService.java | 60 ++++++++++++++- .../RemoteContentCaptureService.java | 14 +++- 6 files changed, 167 insertions(+), 22 deletions(-) create mode 100644 core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl diff --git a/Android.bp b/Android.bp index 7e97e66a9e80..6cdbeb0c3430 100644 --- a/Android.bp +++ b/Android.bp @@ -305,6 +305,7 @@ java_defaults { "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl", "core/java/android/service/gatekeeper/IGateKeeperService.aidl", "core/java/android/service/contentcapture/IContentCaptureService.aidl", + "core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl", "core/java/android/service/notification/INotificationListener.aidl", "core/java/android/service/notification/IStatusBarNotificationHolder.aidl", "core/java/android/service/notification/IConditionListener.aidl", diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java index e5e028d22d97..bedd2a055297 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -48,6 +48,7 @@ import com.android.internal.os.IResultReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -77,6 +78,7 @@ public abstract class ContentCaptureService extends Service { "android.service.contentcapture.ContentCaptureService"; private Handler mHandler; + private IContentCaptureServiceCallback mCallback; /** * Binder that receives calls from the system server. @@ -84,9 +86,15 @@ public abstract class ContentCaptureService extends Service { private final IContentCaptureService mServerInterface = new IContentCaptureService.Stub() { @Override - public void onConnectedStateChanged(boolean state) { - mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnConnectedStateChanged, - ContentCaptureService.this, state)); + public void onConnected(IBinder callback) { + mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnConnected, + ContentCaptureService.this, callback)); + } + + @Override + public void onDisconnected() { + mHandler.sendMessage(obtainMessage(ContentCaptureService::handleOnDisconnected, + ContentCaptureService.this)); } @Override @@ -166,7 +174,16 @@ public abstract class ContentCaptureService extends Service { */ public final void setContentCaptureWhitelist(@Nullable List packages, @Nullable List activities) { - //TODO(b/122595322): implement + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "setContentCaptureWhitelist(): no server callback"); + return; + } + try { + callback.setContentCaptureWhitelist(packages, activities); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } } /** @@ -177,7 +194,16 @@ public abstract class ContentCaptureService extends Service { */ public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity, boolean enabled) { - //TODO(b/122595322): implement + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "setActivityContentCaptureEnabled(): no server callback"); + return; + } + try { + callback.setActivityContentCaptureEnabled(activity, enabled); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } } /** @@ -188,7 +214,16 @@ public abstract class ContentCaptureService extends Service { */ public final void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) { - //TODO(b/122595322): implement + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "setPackageContentCaptureEnabled(): no server callback"); + return; + } + try { + callback.setPackageContentCaptureEnabled(packageName, enabled); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } } /** @@ -197,7 +232,12 @@ public abstract class ContentCaptureService extends Service { */ @NonNull public final Set getContentCaptureDisabledActivities() { - //TODO(b/122595322): implement + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "getContentCaptureDisabledActivities(): no server callback"); + return Collections.emptySet(); + } + //TODO(b/122595322): implement (using SyncResultReceiver) return null; } @@ -207,7 +247,12 @@ public abstract class ContentCaptureService extends Service { */ @NonNull public final Set getContentCaptureDisabledPackages() { - //TODO(b/122595322): implement + final IContentCaptureServiceCallback callback = mCallback; + if (callback == null) { + Log.w(TAG, "getContentCaptureDisabledPackages(): no server callback"); + return Collections.emptySet(); + } + //TODO(b/122595322): implement (using SyncResultReceiver) return null; } @@ -307,12 +352,14 @@ public abstract class ContentCaptureService extends Service { } } - private void handleOnConnectedStateChanged(boolean state) { - if (state) { - onConnected(); - } else { - onDisconnected(); - } + private void handleOnConnected(@NonNull IBinder callback) { + mCallback = IContentCaptureServiceCallback.Stub.asInterface(callback); + onConnected(); + } + + private void handleOnDisconnected() { + onDisconnected(); + mCallback = null; } //TODO(b/111276913): consider caching the InteractionSessionId for the lifetime of the session, diff --git a/core/java/android/service/contentcapture/IContentCaptureService.aidl b/core/java/android/service/contentcapture/IContentCaptureService.aidl index 1b4cccf630a0..a8dd21392337 100644 --- a/core/java/android/service/contentcapture/IContentCaptureService.aidl +++ b/core/java/android/service/contentcapture/IContentCaptureService.aidl @@ -16,6 +16,7 @@ package android.service.contentcapture; +import android.os.IBinder; import android.service.contentcapture.SnapshotData; import android.view.contentcapture.ContentCaptureContext; @@ -29,7 +30,8 @@ import java.util.List; * @hide */ oneway interface IContentCaptureService { - void onConnectedStateChanged(boolean state); + void onConnected(IBinder callback); + void onDisconnected(); void onSessionStarted(in ContentCaptureContext context, String sessionId, int uid, in IResultReceiver clientReceiver); void onSessionFinished(String sessionId); diff --git a/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl new file mode 100644 index 000000000000..e84bd6fdf2b6 --- /dev/null +++ b/core/java/android/service/contentcapture/IContentCaptureServiceCallback.aidl @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 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 com.android.internal.os.IResultReceiver; + +import java.util.List; + +/** + * Interface from the Content Capture service to the system. + * + * @hide + */ +oneway interface IContentCaptureServiceCallback { + void setContentCaptureWhitelist(in List packages, in List activities); + void setActivityContentCaptureEnabled(in ComponentName activity, boolean enabled); + void setPackageContentCaptureEnabled(in String packageName, boolean enabled); + void getContentCaptureDisabledActivities(in IResultReceiver receiver); + void getContentCaptureDisabledPackages(in IResultReceiver receiver); +} diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java index 09aa4212654e..e0aa23dcf37d 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -36,8 +36,10 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.service.contentcapture.ContentCaptureService; +import android.service.contentcapture.IContentCaptureServiceCallback; import android.service.contentcapture.SnapshotData; import android.util.ArrayMap; +import android.util.Log; import android.util.Slog; import android.view.contentcapture.ContentCaptureSession; @@ -48,6 +50,7 @@ import com.android.server.infra.AbstractPerUserSystemService; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; /** * Per-user instance of {@link ContentCaptureManagerService}. @@ -72,6 +75,9 @@ final class ContentCapturePerUserService @GuardedBy("mLock") private RemoteContentCaptureService mRemoteService; + private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback = + new ContentCaptureServiceRemoteCallback(); + // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's ContentCapturePerUserService(@NonNull ContentCaptureManagerService master, @@ -100,10 +106,10 @@ final class ContentCapturePerUserService } if (!disabled) { - mRemoteService = new RemoteContentCaptureService( - mMaster.getContext(), - ContentCaptureService.SERVICE_INTERFACE, serviceComponentName, mUserId, this, - mMaster.isBindInstantServiceAllowed(), mMaster.verbose); + mRemoteService = new RemoteContentCaptureService(mMaster.getContext(), + ContentCaptureService.SERVICE_INTERFACE, serviceComponentName, + mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(), + mMaster.verbose); } } @@ -338,4 +344,50 @@ final class ContentCapturePerUserService } return null; } + + private final class ContentCaptureServiceRemoteCallback extends + IContentCaptureServiceCallback.Stub { + + @Override + public void setContentCaptureWhitelist(List packages, + List activities) { + if (mMaster.verbose) { + Log.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities=" + + activities + ")"); + } + // TODO(b/122595322): implement + // TODO(b/119613670): log metrics + } + + @Override + public void setActivityContentCaptureEnabled(ComponentName activity, boolean enabled) { + if (mMaster.verbose) { + Log.v(TAG, "setActivityContentCaptureEnabled(activity=" + activity + ", enabled=" + + enabled + ")"); + } + // TODO(b/122595322): implement + // TODO(b/119613670): log metrics + } + + @Override + public void setPackageContentCaptureEnabled(String packageName, boolean enabled) { + if (mMaster.verbose) { + Log.v(TAG, + "setPackageContentCaptureEnabled(packageName=" + packageName + ", enabled=" + + enabled + ")"); + } + // TODO(b/122595322): implement + // TODO(b/119613670): log metrics + } + + @Override + public void getContentCaptureDisabledActivities(IResultReceiver receiver) { + // TODO(b/122595322): implement + } + + @Override + public void getContentCaptureDisabledPackages(IResultReceiver receiver) { + // TODO(b/122595322): implement + } + } } diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java index 824162868e19..12742ca0a46f 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java @@ -21,6 +21,7 @@ import android.content.ComponentName; import android.content.Context; import android.os.IBinder; import android.service.contentcapture.IContentCaptureService; +import android.service.contentcapture.IContentCaptureServiceCallback; import android.service.contentcapture.SnapshotData; import android.text.format.DateUtils; import android.util.Slog; @@ -35,12 +36,15 @@ final class RemoteContentCaptureService private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS; + private final IBinder mServerCallback; + RemoteContentCaptureService(Context context, String serviceInterface, - ComponentName componentName, int userId, + ComponentName serviceComponentName, IContentCaptureServiceCallback callback, int userId, ContentCaptureServiceCallbacks callbacks, boolean bindInstantServiceAllowed, boolean verbose) { - super(context, serviceInterface, componentName, userId, callbacks, + super(context, serviceInterface, serviceComponentName, userId, callbacks, bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2); + mServerCallback = callback.asBinder(); // Bind right away, which will trigger a onConnected() on service's scheduleBind(); @@ -69,7 +73,11 @@ final class RemoteContentCaptureService scheduleUnbind(); } try { - mService.onConnectedStateChanged(state); + if (state) { + mService.onConnected(mServerCallback); + } else { + mService.onDisconnected(); + } } catch (Exception e) { Slog.w(mTag, "Exception calling onConnectedStateChanged(" + state + "): " + e); }