• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.voiceinteraction.service;
18 
19 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
20 
21 import android.content.ComponentName;
22 import android.content.Intent;
23 import android.net.Uri;
24 import android.os.Bundle;
25 import android.service.voice.AlwaysOnHotwordDetector;
26 import android.service.voice.VoiceInteractionService;
27 import android.util.Log;
28 import android.voiceinteraction.common.Utils;
29 
30 import java.util.Collections;
31 import java.util.Locale;
32 import java.util.Set;
33 
34 public class MainInteractionService extends VoiceInteractionService {
35     static final String TAG = "MainInteractionService";
36     private Intent mIntent;
37     private boolean mReady = false;
38 
39     @Override
onReady()40     public void onReady() {
41         super.onReady();
42         mReady = true;
43     }
44 
45     @Override
onStartCommand(Intent intent, int flags, int startId)46     public int onStartCommand(Intent intent, int flags, int startId) {
47         Log.i(TAG, "onStartCommand received");
48         mIntent = intent;
49 
50         if (mIntent == null || !mReady) {
51             Log.wtf(TAG, "Can't start because either intent is null or onReady() "
52                     + "is not called yet. mIntent = " + mIntent + ", mReady = " + mReady);
53             return START_NOT_STICKY;
54         }
55 
56         final int testEvent = mIntent.getIntExtra(Utils.KEY_TEST_EVENT, -1);
57         if (testEvent == Utils.VIS_NORMAL_TEST) {
58             maybeStart();
59         } else if (testEvent == Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_TEST) {
60             runWithShellPermissionIdentity(() -> {
61                 callCreateAlwaysOnHotwordDetector();
62             });
63         }
64         return START_NOT_STICKY;
65     }
66 
maybeStart()67     private void maybeStart() {
68         Bundle args = mIntent.getExtras();
69         final String className = (args != null)
70                 ? args.getString(Utils.VOICE_INTERACTION_KEY_CLASS) : null;
71         if (className == null) {
72             Log.i(TAG, "Yay! about to start session with TestApp");
73             if (isActiveService(this, new ComponentName(this, getClass()))) {
74                 // Call to verify onGetSupportedVoiceActions is available.
75                 onGetSupportedVoiceActions(Collections.emptySet());
76                 args = new Bundle();
77                 Intent intent = new Intent()
78                         .setAction(Intent.ACTION_VIEW)
79                         .addCategory(Intent.CATEGORY_VOICE)
80                         .addCategory(Intent.CATEGORY_BROWSABLE)
81                         .setData(Uri.parse("https://android.voiceinteraction.testapp"
82                                 + "/TestApp"));
83                 args.putParcelable("intent", intent);
84                 Log.v(TAG, "showSession(): " + args);
85                 showSession(args, 0);
86             } else {
87                 Log.wtf(TAG, "**** Not starting MainInteractionService because" +
88                         " it is not set as the current voice interaction service");
89             }
90         } else {
91             showSession(args, 0);
92         }
93     }
94 
95     @Override
onGetSupportedVoiceActions(Set<String> voiceActions)96     public Set<String> onGetSupportedVoiceActions(Set<String> voiceActions) {
97         Log.v(TAG, "onGetSupportedVoiceActions " + voiceActions);
98         return super.onGetSupportedVoiceActions(voiceActions);
99     }
100 
callCreateAlwaysOnHotwordDetector()101     private void callCreateAlwaysOnHotwordDetector() {
102         Log.i(TAG, "callCreateAlwaysOnHotwordDetector()");
103         try {
104             createAlwaysOnHotwordDetector(/* keyphrase */ "Hello Google",
105                     Locale.forLanguageTag("en-US"), /* options */ null, /* sharedMemory */ null,
106                     new AlwaysOnHotwordDetector.Callback() {
107                         @Override
108                         public void onAvailabilityChanged(int status) {
109                             Log.i(TAG, "onAvailabilityChanged(" + status + ")");
110                         }
111 
112                         @Override
113                         public void onDetected(AlwaysOnHotwordDetector.EventPayload eventPayload) {
114                             Log.i(TAG, "onDetected");
115                         }
116 
117                         @Override
118                         public void onError() {
119                             Log.i(TAG, "onError");
120                         }
121 
122                         @Override
123                         public void onRecognitionPaused() {
124                             Log.i(TAG, "onRecognitionPaused");
125                         }
126 
127                         @Override
128                         public void onRecognitionResumed() {
129                             Log.i(TAG, "onRecognitionResumed");
130                         }
131                     });
132         } catch (IllegalStateException e) {
133             Log.w(TAG, "callCreateAlwaysOnHotwordDetector() exception: " + e);
134             broadcastIntentWithResult(
135                     Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT,
136                     Utils.HOTWORD_DETECTION_SERVICE_TRIGGER_ILLEGAL_STATE_EXCEPTION);
137         }
138     }
139 
broadcastIntentWithResult(String intentName, int result)140     private void broadcastIntentWithResult(String intentName, int result) {
141         Intent intent = new Intent(intentName)
142                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND | Intent.FLAG_RECEIVER_REGISTERED_ONLY)
143                 .putExtra(Utils.KEY_TEST_RESULT, result);
144         Log.d(TAG, "broadcast intent = " + intent + ", result = " + result);
145         sendBroadcast(intent);
146     }
147 }
148