/*
 * Copyright (C) 2014 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.voice;

import android.Manifest;
import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.RemoteException;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

@hide
/** @hide */
public class VoiceInteractionServiceInfo { static final String TAG = "VoiceInteractionServiceInfo"; private String mParseError; private ServiceInfo mServiceInfo; private String mSessionService; private String mRecognitionService; private String mSettingsActivity; private boolean mSupportsAssist; private boolean mSupportsLaunchFromKeyguard; private boolean mSupportsLocalInteraction; public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp) throws PackageManager.NameNotFoundException { this(pm, pm.getServiceInfo(comp, PackageManager.GET_META_DATA)); } public VoiceInteractionServiceInfo(PackageManager pm, ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { this(pm, getServiceInfoOrThrow(comp, userHandle)); } static ServiceInfo getServiceInfoOrThrow(ComponentName comp, int userHandle) throws PackageManager.NameNotFoundException { try { ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(comp, PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userHandle); if (si != null) { return si; } } catch (RemoteException e) { } throw new PackageManager.NameNotFoundException(comp.toString()); } public VoiceInteractionServiceInfo(PackageManager pm, ServiceInfo si) { if (si == null) { mParseError = "Service not available"; return; } if (!Manifest.permission.BIND_VOICE_INTERACTION.equals(si.permission)) { mParseError = "Service does not require permission " + Manifest.permission.BIND_VOICE_INTERACTION; return; } XmlResourceParser parser = null; try { parser = si.loadXmlMetaData(pm, VoiceInteractionService.SERVICE_META_DATA); if (parser == null) { mParseError = "No " + VoiceInteractionService.SERVICE_META_DATA + " meta-data for " + si.packageName; return; } Resources res = pm.getResourcesForApplication(si.applicationInfo); AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type=parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { } String nodeName = parser.getName(); if (!"voice-interaction-service".equals(nodeName)) { mParseError = "Meta-data does not start with voice-interaction-service tag"; return; } TypedArray array = res.obtainAttributes(attrs, com.android.internal.R.styleable.VoiceInteractionService); mSessionService = array.getString( com.android.internal.R.styleable.VoiceInteractionService_sessionService); mRecognitionService = array.getString( com.android.internal.R.styleable.VoiceInteractionService_recognitionService); mSettingsActivity = array.getString( com.android.internal.R.styleable.VoiceInteractionService_settingsActivity); mSupportsAssist = array.getBoolean( com.android.internal.R.styleable.VoiceInteractionService_supportsAssist, false); mSupportsLaunchFromKeyguard = array.getBoolean(com.android.internal. R.styleable.VoiceInteractionService_supportsLaunchVoiceAssistFromKeyguard, false); mSupportsLocalInteraction = array.getBoolean(com.android.internal. R.styleable.VoiceInteractionService_supportsLocalInteraction, false); array.recycle(); if (mSessionService == null) { mParseError = "No sessionService specified"; return; } if (mRecognitionService == null) { mParseError = "No recognitionService specified"; return; } } catch (XmlPullParserException e) { mParseError = "Error parsing voice interation service meta-data: " + e; Log.w(TAG, "error parsing voice interaction service meta-data", e); return; } catch (IOException e) { mParseError = "Error parsing voice interation service meta-data: " + e; Log.w(TAG, "error parsing voice interaction service meta-data", e); return; } catch (PackageManager.NameNotFoundException e) { mParseError = "Error parsing voice interation service meta-data: " + e; Log.w(TAG, "error parsing voice interaction service meta-data", e); return; } finally { if (parser != null) parser.close(); } mServiceInfo = si; } public String getParseError() { return mParseError; } public ServiceInfo getServiceInfo() { return mServiceInfo; } public String getSessionService() { return mSessionService; } public String getRecognitionService() { return mRecognitionService; } public String getSettingsActivity() { return mSettingsActivity; } public boolean getSupportsAssist() { return mSupportsAssist; } public boolean getSupportsLaunchFromKeyguard() { return mSupportsLaunchFromKeyguard; } public boolean getSupportsLocalInteraction() { return mSupportsLocalInteraction; } }