1 /*
2  * Copyright (C) 2017 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 com.android.settings.applications.assist;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.provider.Settings;
23 import android.text.TextUtils;
24 
25 import com.android.internal.app.AssistUtils;
26 import com.android.internal.logging.nano.MetricsProto;
27 import com.android.settings.applications.PackageManagerWrapper;
28 import com.android.settings.applications.defaultapps.DefaultAppInfo;
29 import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
30 
31 import java.util.ArrayList;
32 import java.util.List;
33 
34 public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
35 
36     private VoiceInputHelper mHelper;
37     private AssistUtils mAssistUtils;
38     private String mAssistRestrict;
39 
40     @Override
getMetricsCategory()41     public int getMetricsCategory() {
42         return MetricsProto.MetricsEvent.DEFAULT_VOICE_INPUT_PICKER;
43     }
44 
45     @Override
onAttach(Context context)46     public void onAttach(Context context) {
47         super.onAttach(context);
48         mAssistUtils = new AssistUtils(context);
49         mHelper = new VoiceInputHelper(context);
50         mHelper.buildUi();
51         final ComponentName assist = getCurrentAssist();
52         if (isCurrentAssistVoiceService(assist, getCurrentService(mHelper))) {
53             mAssistRestrict = assist.flattenToShortString();
54         }
55     }
56 
57     @Override
getCandidates()58     protected List<VoiceInputDefaultAppInfo> getCandidates() {
59         final List<VoiceInputDefaultAppInfo> candidates = new ArrayList<>();
60         boolean hasEnabled = true;
61         for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
62             final boolean enabled = TextUtils.equals(info.key, mAssistRestrict);
63             hasEnabled |= enabled;
64             candidates.add(new VoiceInputDefaultAppInfo(mPm, mUserId, info, enabled));
65         }
66 
67         final boolean assistIsService = !hasEnabled;
68         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
69             final boolean enabled = !assistIsService;
70             candidates.add(new VoiceInputDefaultAppInfo(mPm, mUserId, info, enabled));
71         }
72         return candidates;
73     }
74 
75     @Override
getDefaultKey()76     protected String getDefaultKey() {
77         final ComponentName currentService = getCurrentService(mHelper);
78         if (currentService == null) {
79             return null;
80         }
81         return currentService.flattenToShortString();
82     }
83 
84     @Override
setDefaultKey(String value)85     protected boolean setDefaultKey(String value) {
86         for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
87             if (TextUtils.equals(value, info.key)) {
88                 Settings.Secure.putString(getContext().getContentResolver(),
89                         Settings.Secure.VOICE_INTERACTION_SERVICE, value);
90                 Settings.Secure.putString(getContext().getContentResolver(),
91                         Settings.Secure.VOICE_RECOGNITION_SERVICE,
92                         new ComponentName(info.service.packageName,
93                                 info.serviceInfo.getRecognitionService())
94                                 .flattenToShortString());
95                 return true;
96             }
97         }
98 
99         for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
100             if (TextUtils.equals(value, info.key)) {
101                 Settings.Secure.putString(getContext().getContentResolver(),
102                         Settings.Secure.VOICE_INTERACTION_SERVICE, "");
103                 Settings.Secure.putString(getContext().getContentResolver(),
104                         Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
105                 return true;
106             }
107         }
108         return true;
109     }
110 
getCurrentService(VoiceInputHelper helper)111     public static ComponentName getCurrentService(VoiceInputHelper helper) {
112         if (helper.mCurrentVoiceInteraction != null) {
113             return helper.mCurrentVoiceInteraction;
114         } else if (helper.mCurrentRecognizer != null) {
115             return helper.mCurrentRecognizer;
116         } else {
117             return null;
118         }
119     }
120 
getCurrentAssist()121     private ComponentName getCurrentAssist() {
122         return mAssistUtils.getAssistComponentForUser(mUserId);
123     }
124 
isCurrentAssistVoiceService(ComponentName currentAssist, ComponentName currentVoiceService)125     public static boolean isCurrentAssistVoiceService(ComponentName currentAssist,
126             ComponentName currentVoiceService) {
127         return currentAssist == null && currentVoiceService == null ||
128                 currentAssist != null && currentAssist.equals(currentVoiceService);
129     }
130 
131     public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
132 
133         public VoiceInputHelper.BaseInfo mInfo;
134 
VoiceInputDefaultAppInfo(PackageManagerWrapper pm, int userId, VoiceInputHelper.BaseInfo info, boolean enabled)135         public VoiceInputDefaultAppInfo(PackageManagerWrapper pm, int userId,
136                 VoiceInputHelper.BaseInfo info, boolean enabled) {
137             super(pm, userId, info.componentName, null /* summary */, enabled);
138             mInfo = info;
139         }
140 
141         @Override
getKey()142         public String getKey() {
143             return mInfo.key;
144         }
145 
146         @Override
loadLabel()147         public CharSequence loadLabel() {
148             if (mInfo instanceof VoiceInputHelper.InteractionInfo) {
149                 return mInfo.appLabel;
150             } else {
151                 return mInfo.label;
152             }
153         }
154 
getSettingIntent()155         public Intent getSettingIntent() {
156             if (mInfo.settings == null) {
157                 return null;
158             }
159             return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.settings);
160         }
161     }
162 }
163