VoiceInteractionManagerServiceImpl.java revision 91097de49b0f683b00e26a75dbc0ac6082344137
191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn/*
291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Copyright (C) 2014 The Android Open Source Project
391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn *
491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * you may not use this file except in compliance with the License.
691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * You may obtain a copy of the License at
791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn *
891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn *
1091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
1191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * See the License for the specific language governing permissions and
1491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn * limitations under the License.
1591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn */
1691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
1791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornpackage com.android.server.voiceinteraction;
1891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
1991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.app.ActivityManagerNative;
2091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.app.IActivityManager;
2191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.ComponentName;
2291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Context;
2391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.Intent;
2491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.ServiceConnection;
2591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.pm.PackageManager;
2691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.content.pm.ServiceInfo;
2791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.Handler;
2891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.IBinder;
2991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.RemoteException;
3091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.os.UserHandle;
3191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.service.voice.IVoiceInteractionService;
3291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.service.voice.IVoiceInteractionSession;
3391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.service.voice.VoiceInteractionService;
3491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport android.util.Slog;
3591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornimport com.android.internal.app.IVoiceInteractor;
3691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
3791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackbornclass VoiceInteractionManagerServiceImpl {
3891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final static String TAG = "VoiceInteractionServiceManager";
3991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
4091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final Context mContext;
4191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final Handler mHandler;
4291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final Object mLock;
4391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final int mUser;
4491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final ComponentName mComponent;
4591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final IActivityManager mAm;
4691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    boolean mBound = false;
4791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    IVoiceInteractionService mService;
4891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    IVoiceInteractionSession mActiveSession;
4991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    IVoiceInteractor mActiveInteractor;
5091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
5191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    final ServiceConnection mConnection = new ServiceConnection() {
5291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
5391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void onServiceConnected(ComponentName name, IBinder service) {
5491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            synchronized (mLock) {
5591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                mService = IVoiceInteractionService.Stub.asInterface(service);
5691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
5791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
5891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
5991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        @Override
6091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        public void onServiceDisconnected(ComponentName name) {
6191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mService = null;
6291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
6391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    };
6491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
6591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    VoiceInteractionManagerServiceImpl(Context context, Handler handler, Object lock,
6691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            int userHandle, ComponentName service) {
6791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mContext = context;
6891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mHandler = handler;
6991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mLock = lock;
7091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mUser = userHandle;
7191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mComponent = service;
7291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mAm = ActivityManagerNative.getDefault();
7391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
7491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
7591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    public int startVoiceActivityLocked(int callingPid, int callingUid, Intent intent,
7691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor) {
7791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        if (session == null) {
7891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            throw new NullPointerException("session is null");
7991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
8091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        if (interactor == null) {
8191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            throw new NullPointerException("interactor is null");
8291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
8391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        if (mActiveSession != null) {
8491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            // XXX cancel current session.
8591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
8691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        intent.addCategory(Intent.CATEGORY_VOICE);
8791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
8891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mActiveSession = session;
8991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mActiveInteractor = interactor;
9091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        try {
9191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return mAm.startVoiceActivity(mComponent.getPackageName(), callingPid, callingUid,
9291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    intent, resolvedType, mActiveSession, mActiveInteractor,
9391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                    0, null, null, null, mUser);
9491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        } catch (RemoteException e) {
9591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            throw new IllegalStateException("Unexpected remote error", e);
9691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
9791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
9891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
9991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    void startLocked() {
10091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
10191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        intent.setComponent(mComponent);
10291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        try {
10391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            ServiceInfo si = mContext.getPackageManager().getServiceInfo(mComponent, 0);
10491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            if (!android.Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
10591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                Slog.w(TAG, "Not using voice interaction service " + mComponent
10691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + ": does not require permission "
10791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                        + android.Manifest.permission.BIND_VOICE_INTERACTION);
10891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                return;
10991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            }
11091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
11191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            Slog.w(TAG, "Unable to find voice interaction service: " + mComponent, e);
11291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            return;
11391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
11491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mContext.bindServiceAsUser(intent, mConnection,
11591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn                Context.BIND_AUTO_CREATE, new UserHandle(mUser));
11691097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        mBound = true;
11791097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
11891097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn
11991097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    void shutdownLocked() {
12091097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        if (mBound) {
12191097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mContext.unbindService(mConnection);
12291097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn            mBound = false;
12391097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn        }
12491097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn    }
12591097de49b0f683b00e26a75dbc0ac6082344137Dianne Hackborn}
126