118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn/*
218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * Copyright (C) 2014 The Android Open Source Project
318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn *
418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * you may not use this file except in compliance with the License.
618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * You may obtain a copy of the License at
718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn *
818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn *
1018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * Unless required by applicable law or agreed to in writing, software
1118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * See the License for the specific language governing permissions and
1418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn * limitations under the License.
1518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn */
1618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
1718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornpackage android.service.voice;
1818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
1918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.Manifest;
20a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.app.AppGlobals;
2118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.ComponentName;
2218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.pm.PackageManager;
2318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.pm.ServiceInfo;
2418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.res.Resources;
2518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.res.TypedArray;
2618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.content.res.XmlResourceParser;
27a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackbornimport android.os.RemoteException;
2818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.util.AttributeSet;
2918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.util.Log;
3018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport android.util.Xml;
3118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport org.xmlpull.v1.XmlPullParser;
3218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport org.xmlpull.v1.XmlPullParserException;
3318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
3418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornimport java.io.IOException;
3518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
3618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn/** @hide */
3718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackbornpublic class VoiceInteractionServiceInfo {
3818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    static final String TAG = "VoiceInteractionServiceInfo";
3918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
4018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    private String mParseError;
4118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
4218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    private ServiceInfo mServiceInfo;
4318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    private String mSessionService;
44fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn    private String mRecognitionService;
4518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    private String mSettingsActivity;
465f560d056243638a83a4e7770035fdb66004c9d7Jorim Jaggi    private boolean mSupportsAssist;
47e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek    private boolean mSupportsLaunchFromKeyguard;
480af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani    private boolean mSupportsLocalInteraction;
4918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
5018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp)
5118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            throws PackageManager.NameNotFoundException {
5218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        this(pm, pm.getServiceInfo(comp, PackageManager.GET_META_DATA));
5318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
5418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
55a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn    public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp, int userHandle)
56c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn            throws PackageManager.NameNotFoundException {
57c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn        this(pm, getServiceInfoOrThrow(comp, userHandle));
58c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn    }
59c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn
60c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn    static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle)
61c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn            throws PackageManager.NameNotFoundException {
62c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn        try {
63c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn            ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(comp,
64b625e19a877dc8e128329d730bc5e9b8e8a2fce9Svetoslav Ganov                    PackageManager.GET_META_DATA
65b625e19a877dc8e128329d730bc5e9b8e8a2fce9Svetoslav Ganov                            | PackageManager.MATCH_DIRECT_BOOT_AWARE
66b625e19a877dc8e128329d730bc5e9b8e8a2fce9Svetoslav Ganov                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
67b625e19a877dc8e128329d730bc5e9b8e8a2fce9Svetoslav Ganov                            | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
68b625e19a877dc8e128329d730bc5e9b8e8a2fce9Svetoslav Ganov                    userHandle);
69c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn            if (si != null) {
70c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn                return si;
71c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn            }
72c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn        } catch (RemoteException e) {
73c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn        }
74c83189b5d6ab2fe5f1c38cbe22254f4995379c88Dianne Hackborn        throw new PackageManager.NameNotFoundException(comp.toString());
75a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn    }
76a351ab96987381ffe7ea29a7cdec1e7fbd1497d5Dianne Hackborn
7718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) {
787dbcbad577a32f16d75dde3fe1412c56c5a2a399Edward Savage-Jones        if (si == null) {
797dbcbad577a32f16d75dde3fe1412c56c5a2a399Edward Savage-Jones            mParseError = "Service not available";
807dbcbad577a32f16d75dde3fe1412c56c5a2a399Edward Savage-Jones            return;
817dbcbad577a32f16d75dde3fe1412c56c5a2a399Edward Savage-Jones        }
8218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) {
8318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mParseError = "Service does not require permission "
8418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                    + Manifest.permission.BIND_VOICE_INTERACTION;
8518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            return;
8618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        }
8718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
8818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        XmlResourceParser parser = null;
8918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        try {
9018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            parser = si.loadXmlMetaData(pm, VoiceInteractionService.SERVICE_META_DATA);
9118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            if (parser == null) {
9218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                mParseError = "No " + VoiceInteractionService.SERVICE_META_DATA
9318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                        + " meta-data for " + si.packageName;
9418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                return;
9518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            }
9618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
9718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            Resources res = pm.getResourcesForApplication(si.applicationInfo);
9818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
9918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            AttributeSet attrs = Xml.asAttributeSet(parser);
10018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
10118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            int type;
10218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
10318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                    && type != XmlPullParser.START_TAG) {
10418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            }
10518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
10618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            String nodeName = parser.getName();
10718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            if (!"voice-interaction-service".equals(nodeName)) {
10818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                mParseError = "Meta-data does not start with voice-interaction-service tag";
10918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                return;
11018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            }
11118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
11218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            TypedArray array = res.obtainAttributes(attrs,
11318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                    com.android.internal.R.styleable.VoiceInteractionService);
11418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mSessionService = array.getString(
11518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                    com.android.internal.R.styleable.VoiceInteractionService_sessionService);
116fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn            mRecognitionService = array.getString(
117fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn                    com.android.internal.R.styleable.VoiceInteractionService_recognitionService);
11818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mSettingsActivity = array.getString(
11918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                    com.android.internal.R.styleable.VoiceInteractionService_settingsActivity);
1205f560d056243638a83a4e7770035fdb66004c9d7Jorim Jaggi            mSupportsAssist = array.getBoolean(
1215f560d056243638a83a4e7770035fdb66004c9d7Jorim Jaggi                    com.android.internal.R.styleable.VoiceInteractionService_supportsAssist,
1220b68ff45125e449dd0b4120f530240093aa6253eJorim Jaggi                    false);
123e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek            mSupportsLaunchFromKeyguard = array.getBoolean(com.android.internal.
124e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek                    R.styleable.VoiceInteractionService_supportsLaunchVoiceAssistFromKeyguard,
125e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek                    false);
1260af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani            mSupportsLocalInteraction = array.getBoolean(com.android.internal.
1270af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani                    R.styleable.VoiceInteractionService_supportsLocalInteraction, false);
12818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            array.recycle();
12918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            if (mSessionService == null) {
13018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                mParseError = "No sessionService specified";
13118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn                return;
13218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            }
133ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            if (mRecognitionService == null) {
134ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                mParseError = "No recognitionService specified";
135ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn                return;
136ae6688b09649447e57468b3e7935691bc09ec9b9Dianne Hackborn            }
13718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        } catch (XmlPullParserException e) {
13818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mParseError = "Error parsing voice interation service meta-data: " + e;
13918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            Log.w(TAG, "error parsing voice interaction service meta-data", e);
14018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            return;
14118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        } catch (IOException e) {
14218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mParseError = "Error parsing voice interation service meta-data: " + e;
14318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            Log.w(TAG, "error parsing voice interaction service meta-data", e);
14418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            return;
14518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        } catch (PackageManager.NameNotFoundException e) {
14618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            mParseError = "Error parsing voice interation service meta-data: " + e;
14718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            Log.w(TAG, "error parsing voice interaction service meta-data", e);
14818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            return;
14918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        } finally {
15018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn            if (parser != null) parser.close();
15118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        }
15218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        mServiceInfo = si;
15318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
15418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
15518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public String getParseError() {
15618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        return mParseError;
15718f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
15818f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
15918f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public ServiceInfo getServiceInfo() {
16018f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        return mServiceInfo;
16118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
16218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
16318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public String getSessionService() {
16418f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        return mSessionService;
16518f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
16618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn
167fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn    public String getRecognitionService() {
168fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn        return mRecognitionService;
169fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn    }
170fee756ff91ab4d8f0e09ddb050d22d88ebb66ae7Dianne Hackborn
17118f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    public String getSettingsActivity() {
17218f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn        return mSettingsActivity;
17318f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn    }
1740b68ff45125e449dd0b4120f530240093aa6253eJorim Jaggi
1755f560d056243638a83a4e7770035fdb66004c9d7Jorim Jaggi    public boolean getSupportsAssist() {
1765f560d056243638a83a4e7770035fdb66004c9d7Jorim Jaggi        return mSupportsAssist;
1770b68ff45125e449dd0b4120f530240093aa6253eJorim Jaggi    }
178e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek
179e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek    public boolean getSupportsLaunchFromKeyguard() {
180e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek        return mSupportsLaunchFromKeyguard;
181e70d6535237d2e6f03adcd0bdc11e45ea714dc97Selim Cinek    }
1820af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani
1830af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani    public boolean getSupportsLocalInteraction() {
1840af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani        return mSupportsLocalInteraction;
1850af6fa7015cd9da08bf52c1efb13641d30fd6bd7Amith Yamasani    }
18618f0d357f9693fe787a3e3777d8fdf01357a6e3fDianne Hackborn}
187