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
This commit is contained in:
Felipe Leme 2019-01-15 08:32:42 -08:00
parent b407681aec
commit af4e4fd020
6 changed files with 167 additions and 22 deletions

View File

@ -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",

View File

@ -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<String> packages,
@Nullable List<ComponentName> 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<ComponentName> 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<String> 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,

View File

@ -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);

View File

@ -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<String> packages, in List<ComponentName> 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);
}

View File

@ -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<String> packages,
List<ComponentName> 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
}
}
}

View File

@ -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);
}