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/VoiceInteractionManagerService.java40
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java156
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java285
3 files changed, 342 insertions, 139 deletions
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index fd990d7..6b8c49c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -385,7 +385,7 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
- public void startSession(IVoiceInteractionService service, Bundle args, int flags) {
+ public void showSession(IVoiceInteractionService service, Bundle args, int flags) {
synchronized (this) {
if (mImpl == null || mImpl.mService == null
|| service.asBinder() != mImpl.mService.asBinder()) {
@@ -396,7 +396,7 @@ public class VoiceInteractionManagerService extends SystemService {
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.startSessionLocked(callingPid, callingUid, args, flags);
+ mImpl.showSessionLocked(callingPid, callingUid, args, flags);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -424,6 +424,42 @@ public class VoiceInteractionManagerService extends SystemService {
}
@Override
+ public boolean showSessionFromSession(IBinder token, Bundle sessionArgs, int flags) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "showSessionFromSession without running voice interaction service");
+ return false;
+ }
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ return mImpl.showSessionLocked(callingPid, callingUid, sessionArgs, flags);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
+ @Override
+ public boolean hideSessionFromSession(IBinder token) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "hideSessionFromSession without running voice interaction service");
+ return false;
+ }
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ return mImpl.hideSessionLocked(callingPid, callingUid);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
+ @Override
public int startVoiceActivity(IBinder token, Intent intent, String resolvedType) {
synchronized (this) {
if (mImpl == null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index e80f702..9e92867 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -26,7 +26,6 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
-import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -35,20 +34,17 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
-import android.service.voice.IVoiceInteractionSessionService;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
import android.util.Slog;
import android.view.IWindowManager;
-import android.view.WindowManager;
import com.android.internal.app.IVoiceInteractor;
-import com.android.internal.os.IResultReceiver;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-class VoiceInteractionManagerServiceImpl {
+class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
final static String TAG = "VoiceInteractionServiceManager";
final boolean mValid;
@@ -65,7 +61,7 @@ class VoiceInteractionManagerServiceImpl {
boolean mBound = false;
IVoiceInteractionService mService;
- SessionConnection mActiveSession;
+ VoiceInteractionSessionConnection mActiveSession;
final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -101,124 +97,6 @@ class VoiceInteractionManagerServiceImpl {
}
};
- final class SessionConnection implements ServiceConnection {
- final IBinder mToken = new Binder();
- final Bundle mArgs;
- final int mFlags;
- boolean mBound;
- IVoiceInteractionSessionService mService;
- IVoiceInteractionSession mSession;
- IVoiceInteractor mInteractor;
- boolean mHaveAssistData;
- Bundle mAssistData;
-
- final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
- @Override
- public void send(int resultCode, Bundle resultData) throws RemoteException {
- synchronized (mLock) {
- mHaveAssistData = true;
- mAssistData = resultData;
- if (mSession != null) {
- try {
- mSession.handleAssist(resultData);
- } catch (RemoteException e) {
- }
- }
- }
- }
- };
-
- SessionConnection(Bundle args, int flags) {
- mArgs = args;
- mFlags = flags;
- Intent serviceIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
- serviceIntent.setComponent(mSessionComponentName);
- mBound = mContext.bindServiceAsUser(serviceIntent, this,
- Context.BIND_AUTO_CREATE, new UserHandle(mUser));
- if (mBound) {
- try {
- mIWindowManager.addWindowToken(mToken,
- WindowManager.LayoutParams.TYPE_VOICE_INTERACTION);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed adding window token", e);
- }
- if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
- try {
- mAm.requestAssistContextExtras(0, mAssistReceiver);
- } catch (RemoteException e) {
- }
- } else {
- mHaveAssistData = true;
- }
- } else {
- Slog.w(TAG, "Failed binding to voice interaction session service " + mComponent);
- }
- }
-
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- synchronized (mLock) {
- mService = IVoiceInteractionSessionService.Stub.asInterface(service);
- if (mActiveSession == this) {
- try {
- mService.newSession(mToken, mArgs, mFlags);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed adding window token", e);
- }
- }
- }
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mService = null;
- }
-
- public void cancel() {
- if (mBound) {
- if (mSession != null) {
- try {
- mSession.destroy();
- } catch (RemoteException e) {
- Slog.w(TAG, "Voice interation session already dead");
- }
- }
- if (mSession != null) {
- try {
- mAm.finishVoiceTask(mSession);
- } catch (RemoteException e) {
- }
- }
- mContext.unbindService(this);
- try {
- mIWindowManager.removeWindowToken(mToken);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failed removing window token", e);
- }
- mBound = false;
- mService = null;
- mSession = null;
- mInteractor = null;
- }
- }
-
- public void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("mToken="); pw.println(mToken);
- pw.print(prefix); pw.print("mArgs="); pw.println(mArgs);
- pw.print(prefix); pw.print("mFlags=0x"); pw.println(Integer.toHexString(mFlags));
- pw.print(prefix); pw.print("mBound="); pw.println(mBound);
- if (mBound) {
- pw.print(prefix); pw.print("mService="); pw.println(mService);
- pw.print(prefix); pw.print("mSession="); pw.println(mSession);
- pw.print(prefix); pw.print("mInteractor="); pw.println(mInteractor);
- }
- pw.print(prefix); pw.print("mHaveAssistData="); pw.println(mHaveAssistData);
- if (mHaveAssistData) {
- pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
- }
- }
- };
-
VoiceInteractionManagerServiceImpl(Context context, Handler handler, Object lock,
int userHandle, ComponentName service) {
mContext = context;
@@ -256,12 +134,16 @@ class VoiceInteractionManagerServiceImpl {
mContext.registerReceiver(mBroadcastReceiver, filter, null, handler);
}
- public void startSessionLocked(int callingPid, int callingUid, Bundle args, int flags) {
- if (mActiveSession != null) {
- mActiveSession.cancel();
- mActiveSession = null;
+ public boolean showSessionLocked(int callingPid, int callingUid, Bundle args, int flags) {
+ if (mActiveSession == null) {
+ mActiveSession = new VoiceInteractionSessionConnection(mLock, mSessionComponentName,
+ mUser, mContext, this, callingPid, callingUid);
}
- mActiveSession = new SessionConnection(args, flags);
+ return mActiveSession.showLocked(args, flags);
+ }
+
+ public boolean hideSessionLocked(int callingPid, int callingUid) {
+ return mActiveSession.hideLocked();
}
public boolean deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
@@ -270,14 +152,7 @@ class VoiceInteractionManagerServiceImpl {
Slog.w(TAG, "deliverNewSession does not match active session");
return false;
}
- mActiveSession.mSession = session;
- mActiveSession.mInteractor = interactor;
- if (mActiveSession.mHaveAssistData) {
- try {
- session.handleAssist(mActiveSession.mAssistData);
- } catch (RemoteException e) {
- }
- }
+ mActiveSession.deliverNewSessionLocked(session, interactor);
return true;
}
@@ -367,4 +242,11 @@ class VoiceInteractionManagerServiceImpl {
Slog.w(TAG, "RemoteException while calling soundModelsChanged", e);
}
}
+
+ @Override
+ public void sessionConnectionGone(VoiceInteractionSessionConnection connection) {
+ synchronized (mLock) {
+ finishLocked(connection.mCallingPid, connection.mCallingUid, connection.mToken);
+ }
+ }
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
new file mode 100644
index 0000000..e2b47c3
--- /dev/null
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2015 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 com.android.server.voiceinteraction;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.service.voice.IVoiceInteractionSession;
+import android.service.voice.IVoiceInteractionSessionService;
+import android.service.voice.VoiceInteractionService;
+import android.util.Slog;
+import android.view.IWindowManager;
+import android.view.WindowManager;
+import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
+
+import java.io.PrintWriter;
+
+final class VoiceInteractionSessionConnection implements ServiceConnection {
+ final static String TAG = "VoiceInteractionServiceManager";
+
+ final IBinder mToken = new Binder();
+ final Object mLock;
+ final ComponentName mSessionComponentName;
+ final Intent mBindIntent;
+ final int mUser;
+ final Context mContext;
+ final Callback mCallback;
+ final int mCallingPid;
+ final int mCallingUid;
+ final IActivityManager mAm;
+ final IWindowManager mIWindowManager;
+ boolean mShown;
+ Bundle mShowArgs;
+ int mShowFlags;
+ boolean mBound;
+ boolean mFullyBound;
+ boolean mCanceled;
+ IVoiceInteractionSessionService mService;
+ IVoiceInteractionSession mSession;
+ IVoiceInteractor mInteractor;
+ boolean mHaveAssistData;
+ Bundle mAssistData;
+
+ public interface Callback {
+ public void sessionConnectionGone(VoiceInteractionSessionConnection connection);
+ }
+
+ final ServiceConnection mFullConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ }
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ };
+
+ final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
+ @Override
+ 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;
+ }
+ }
+ }
+ }
+ };
+
+ public VoiceInteractionSessionConnection(Object lock, ComponentName component, int user,
+ Context context, Callback callback, int callingPid, int callingUid) {
+ mLock = lock;
+ mSessionComponentName = component;
+ mUser = user;
+ mContext = context;
+ mCallback = callback;
+ mCallingPid = callingPid;
+ mCallingUid = callingUid;
+ mAm = ActivityManagerNative.getDefault();
+ mIWindowManager = IWindowManager.Stub.asInterface(
+ ServiceManager.getService(Context.WINDOW_SERVICE));
+ mBindIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+ mBindIntent.setComponent(mSessionComponentName);
+ mBound = mContext.bindServiceAsUser(mBindIntent, this,
+ Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
+ if (mBound) {
+ try {
+ mIWindowManager.addWindowToken(mToken,
+ WindowManager.LayoutParams.TYPE_VOICE_INTERACTION);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed adding window token", e);
+ }
+ } else {
+ Slog.w(TAG, "Failed binding to voice interaction session service "
+ + mSessionComponentName);
+ }
+ }
+
+ public boolean showLocked(Bundle args, int flags) {
+ if (mBound) {
+ if (!mFullyBound) {
+ mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection,
+ Context.BIND_AUTO_CREATE|Context.BIND_TREAT_LIKE_ACTIVITY,
+ new UserHandle(mUser));
+ }
+ mShown = true;
+ mShowArgs = args;
+ mShowFlags = flags;
+ if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
+ try {
+ mAm.requestAssistContextExtras(0, mAssistReceiver);
+ } catch (RemoteException e) {
+ }
+ } else {
+ mHaveAssistData = false;
+ mAssistData = null;
+ }
+ if (mSession != null) {
+ try {
+ mSession.show(mShowArgs, mShowFlags);
+ mShowArgs = null;
+ mShowFlags = 0;
+ } catch (RemoteException e) {
+ }
+ if (mHaveAssistData) {
+ try {
+ mSession.handleAssist(mAssistData);
+ mAssistData = null;
+ mHaveAssistData = false;
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public boolean hideLocked() {
+ if (mBound) {
+ if (mShown) {
+ mShown = false;
+ mShowArgs = null;
+ mShowFlags = 0;
+ mHaveAssistData = false;
+ mAssistData = null;
+ if (mSession != null) {
+ try {
+ mSession.hide();
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ if (mFullyBound) {
+ mContext.unbindService(mFullConnection);
+ mFullyBound = false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public boolean deliverNewSessionLocked(IVoiceInteractionSession session,
+ IVoiceInteractor interactor) {
+ mSession = session;
+ mInteractor = interactor;
+ if (mShown) {
+ try {
+ session.show(mShowArgs, mShowFlags);
+ mShowArgs = null;
+ mShowFlags = 0;
+ } catch (RemoteException e) {
+ }
+ if (mHaveAssistData) {
+ try {
+ session.handleAssist(mAssistData);
+ mAssistData = null;
+ mHaveAssistData = false;
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mLock) {
+ mService = IVoiceInteractionSessionService.Stub.asInterface(service);
+ if (!mCanceled) {
+ try {
+ mService.newSession(mToken, mShowArgs, mShowFlags);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed adding window token", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mCallback.sessionConnectionGone(this);
+ mService = null;
+ }
+
+ public void cancel() {
+ mCanceled = true;
+ if (mBound) {
+ if (mSession != null) {
+ try {
+ mSession.destroy();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Voice interation session already dead");
+ }
+ }
+ if (mSession != null) {
+ try {
+ mAm.finishVoiceTask(mSession);
+ } catch (RemoteException e) {
+ }
+ }
+ mContext.unbindService(this);
+ try {
+ mIWindowManager.removeWindowToken(mToken);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed removing window token", e);
+ }
+ mBound = false;
+ mService = null;
+ mSession = null;
+ mInteractor = null;
+ }
+ if (mFullyBound) {
+ mContext.unbindService(mFullConnection);
+ mFullyBound = false;
+ }
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.print("mToken="); pw.println(mToken);
+ pw.print(prefix); pw.print("mShown="); pw.println(mShown);
+ pw.print(prefix); pw.print("mShowArgs="); pw.println(mShowArgs);
+ pw.print(prefix); pw.print("mShowFlags=0x"); pw.println(Integer.toHexString(mShowFlags));
+ pw.print(prefix); pw.print("mBound="); pw.println(mBound);
+ if (mBound) {
+ pw.print(prefix); pw.print("mService="); pw.println(mService);
+ pw.print(prefix); pw.print("mSession="); pw.println(mSession);
+ pw.print(prefix); pw.print("mInteractor="); pw.println(mInteractor);
+ }
+ pw.print(prefix); pw.print("mHaveAssistData="); pw.println(mHaveAssistData);
+ if (mHaveAssistData) {
+ pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
+ }
+ }
+};