summaryrefslogtreecommitdiffstats
path: root/services/voiceinteraction
diff options
context:
space:
mode:
Diffstat (limited to 'services/voiceinteraction')
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java123
1 files changed, 105 insertions, 18 deletions
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index e2b47c3..30d97b9 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -16,12 +16,17 @@
package com.android.server.voiceinteraction;
+import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.AssistContent;
import android.app.IActivityManager;
+import android.content.ClipData;
import android.content.ComponentName;
+import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
@@ -53,6 +58,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
final int mCallingUid;
final IActivityManager mAm;
final IWindowManager mIWindowManager;
+ final IBinder mPermissionOwner;
boolean mShown;
Bundle mShowArgs;
int mShowFlags;
@@ -83,15 +89,9 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
public void send(int resultCode, Bundle resultData) throws RemoteException {
synchronized (mLock) {
if (mShown) {
- if (mSession != null) {
- try {
- mSession.handleAssist(resultData);
- } catch (RemoteException e) {
- }
- } else {
- mHaveAssistData = true;
- mAssistData = resultData;
- }
+ mHaveAssistData = true;
+ mAssistData = resultData;
+ deliverAssistData();
}
}
}
@@ -109,6 +109,14 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mAm = ActivityManagerNative.getDefault();
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
+ IBinder permOwner = null;
+ try {
+ permOwner = mAm.newUriPermissionOwner("voicesession:"
+ + component.flattenToShortString());
+ } catch (RemoteException e) {
+ Slog.w("voicesession", "AM dead", e);
+ }
+ mPermissionOwner = permOwner;
mBindIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
mBindIntent.setComponent(mSessionComponentName);
mBound = mContext.bindServiceAsUser(mBindIntent, this,
@@ -138,7 +146,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = flags;
if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
try {
- mAm.requestAssistContextExtras(0, mAssistReceiver);
+ mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
+ mAssistReceiver);
} catch (RemoteException e) {
}
} else {
@@ -152,20 +161,91 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = 0;
} catch (RemoteException e) {
}
- if (mHaveAssistData) {
- try {
- mSession.handleAssist(mAssistData);
- mAssistData = null;
- mHaveAssistData = false;
- } catch (RemoteException e) {
- }
- }
+ deliverAssistData();
}
return true;
}
return false;
}
+ void grantUriPermission(Uri uri, int mode, int srcUid, int destUid, String destPkg) {
+ if (!"content".equals(uri.getScheme())) {
+ return;
+ }
+ long ident = Binder.clearCallingIdentity();
+ try {
+ // This will throw SecurityException for us.
+ mAm.checkGrantUriPermission(srcUid, null, ContentProvider.getUriWithoutUserId(uri),
+ mode, ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(srcUid)));
+ // No security exception, do the grant.
+ int sourceUserId = ContentProvider.getUserIdFromUri(uri, mUser);
+ uri = ContentProvider.getUriWithoutUserId(uri);
+ mAm.grantUriPermissionFromOwner(mPermissionOwner, srcUid, destPkg,
+ uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, mUser);
+ } catch (RemoteException e) {
+ } catch (SecurityException e) {
+ Slog.w(TAG, "Can't propagate permission", e);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+
+ }
+
+ void grantClipDataItemPermission(ClipData.Item item, int mode, int srcUid, int destUid,
+ String destPkg) {
+ if (item.getUri() != null) {
+ grantUriPermission(item.getUri(), mode, srcUid, destUid, destPkg);
+ }
+ Intent intent = item.getIntent();
+ if (intent != null && intent.getData() != null) {
+ grantUriPermission(intent.getData(), mode, srcUid, destUid, destPkg);
+ }
+ }
+
+ void grantClipDataPermissions(ClipData data, int mode, int srcUid, int destUid,
+ String destPkg) {
+ final int N = data.getItemCount();
+ for (int i=0; i<N; i++) {
+ grantClipDataItemPermission(data.getItemAt(i), mode, srcUid, destUid, destPkg);
+ }
+ }
+
+ void deliverAssistData() {
+ if (mSession == null || !mHaveAssistData) {
+ return;
+ }
+ if (mAssistData != null) {
+ int uid = mAssistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
+ if (uid >= 0) {
+ Bundle assistContext = mAssistData.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+ if (assistContext != null) {
+ AssistContent content = AssistContent.getAssistContent(assistContext);
+ if (content != null) {
+ Intent intent = content.getIntent();
+ if (intent != null) {
+ ClipData data = intent.getClipData();
+ if (data != null && Intent.isAccessUriMode(intent.getFlags())) {
+ grantClipDataPermissions(data, intent.getFlags(), uid,
+ mCallingUid, mSessionComponentName.getPackageName());
+ }
+ }
+ ClipData data = content.getClipData();
+ if (data != null) {
+ grantClipDataPermissions(data, Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ uid, mCallingUid, mSessionComponentName.getPackageName());
+ }
+ }
+ }
+ }
+ }
+ try {
+ mSession.handleAssist(mAssistData);
+ mAssistData = null;
+ mHaveAssistData = false;
+ } catch (RemoteException e) {
+ }
+ }
+
public boolean hideLocked() {
if (mBound) {
if (mShown) {
@@ -180,6 +260,13 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} catch (RemoteException e) {
}
}
+ try {
+ mAm.revokeUriPermissionFromOwner(mPermissionOwner, null,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ mUser);
+ } catch (RemoteException e) {
+ }
}
if (mFullyBound) {
mContext.unbindService(mFullConnection);