Deprecate AppListPreference and AppListPrefWithSettings
- Convert ManageAssist into DashboardFragment - Convert default assist pref to DefaultAppPickerFragment - Add PreferenceController for each pref - Add tests Bug: 35203386 Test: make RunSettingsRoboTests Change-Id: I0350a06cae7457809fb261e2d8ec99eda80cc50a
This commit is contained in:
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.settings.applications;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.support.v14.preference.SwitchPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.gestures.AssistGestureFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.voice.VoiceInputListPreference;
|
||||
|
||||
/**
|
||||
* Settings screen to manage everything about assist.
|
||||
*/
|
||||
public class ManageAssist extends SettingsPreferenceFragment
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String KEY_DEFAULT_ASSIST = "default_assist";
|
||||
private static final String KEY_ASSIST_GESTURE = "gesture_assist";
|
||||
private static final String KEY_CONTEXT = "context";
|
||||
private static final String KEY_SCREENSHOT = "screenshot";
|
||||
private static final String KEY_VOICE_INPUT = "voice_input_settings";
|
||||
private static final String KEY_FLASH = "flash";
|
||||
|
||||
private DefaultAssistPreference mDefaultAssitPref;
|
||||
private SwitchPreference mContextPref;
|
||||
private SwitchPreference mScreenshotPref;
|
||||
private SwitchPreference mFlashPref;
|
||||
private VoiceInputListPreference mVoiceInputPref;
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
private Preference mAssistGesturePref;
|
||||
private AssistGestureFeatureProvider mAssistGestureFeatureProvider;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
addPreferencesFromResource(R.xml.manage_assist);
|
||||
|
||||
mDefaultAssitPref = (DefaultAssistPreference) findPreference(KEY_DEFAULT_ASSIST);
|
||||
mDefaultAssitPref.setOnPreferenceChangeListener(this);
|
||||
|
||||
mAssistGesturePref = findPreference(KEY_ASSIST_GESTURE);
|
||||
mAssistGestureFeatureProvider =
|
||||
FeatureFactory.getFactory(getContext()).getAssistGestureFeatureProvider();
|
||||
|
||||
mContextPref = (SwitchPreference) findPreference(KEY_CONTEXT);
|
||||
mContextPref.setChecked(Settings.Secure.getInt(getContentResolver(),
|
||||
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0);
|
||||
mContextPref.setOnPreferenceChangeListener(this);
|
||||
|
||||
mScreenshotPref = (SwitchPreference) findPreference(KEY_SCREENSHOT);
|
||||
mScreenshotPref.setOnPreferenceChangeListener(this);
|
||||
|
||||
mFlashPref = (SwitchPreference) findPreference(KEY_FLASH);
|
||||
mFlashPref.setOnPreferenceChangeListener(this);
|
||||
mFooterPreferenceMixin.createFooterPreference()
|
||||
.setTitle(R.string.assist_footer);
|
||||
mVoiceInputPref = (VoiceInputListPreference) findPreference(KEY_VOICE_INPUT);
|
||||
updateUi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.APPLICATIONS_MANAGE_ASSIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mContextPref) {
|
||||
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_STRUCTURE_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
mHandler.post(() -> {
|
||||
guardFlashPref();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
if (preference == mScreenshotPref) {
|
||||
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
if (preference == mFlashPref) {
|
||||
Settings.Secure.putInt(getContentResolver(), Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
if (preference == mDefaultAssitPref) {
|
||||
String newAssitPackage = (String)newValue;
|
||||
if (newAssitPackage == null ||
|
||||
newAssitPackage.contentEquals(DefaultAssistPreference.ITEM_NONE_VALUE)) {
|
||||
setDefaultAssist(DefaultAssistPreference.ITEM_NONE_VALUE);
|
||||
return false;
|
||||
}
|
||||
|
||||
final String currentPackage = mDefaultAssitPref.getValue();
|
||||
if (currentPackage == null || !newAssitPackage.contentEquals(currentPackage)) {
|
||||
confirmNewAssist(newAssitPackage);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void guardFlashPref() {
|
||||
ComponentName assistant = mDefaultAssitPref.getCurrentAssist();
|
||||
|
||||
boolean isContextChecked = mContextPref.isChecked();
|
||||
boolean willShowFlash = AssistUtils.shouldDisclose(getContext(), assistant);
|
||||
boolean isSystemAssistant = AssistUtils.isPreinstalledAssistant(getContext(), assistant);
|
||||
|
||||
mFlashPref.setEnabled(isContextChecked && isSystemAssistant);
|
||||
mFlashPref.setChecked(willShowFlash);
|
||||
}
|
||||
|
||||
private void updateUi() {
|
||||
mDefaultAssitPref.refreshAssistApps();
|
||||
mVoiceInputPref.refreshVoiceInputs();
|
||||
|
||||
final ComponentName currentAssist = mDefaultAssitPref.getCurrentAssist();
|
||||
final boolean hasAssistant = currentAssist != null;
|
||||
if (hasAssistant) {
|
||||
getPreferenceScreen().addPreference(mContextPref);
|
||||
getPreferenceScreen().addPreference(mScreenshotPref);
|
||||
} else {
|
||||
getPreferenceScreen().removePreference(mContextPref);
|
||||
getPreferenceScreen().removePreference(mScreenshotPref);
|
||||
getPreferenceScreen().removePreference(mFlashPref);
|
||||
}
|
||||
|
||||
if (hasAssistant && mAssistGestureFeatureProvider.isSupported(getContext())) {
|
||||
getPreferenceScreen().addPreference(mAssistGesturePref);
|
||||
} else {
|
||||
getPreferenceScreen().removePreference(mAssistGesturePref);
|
||||
}
|
||||
|
||||
if (hasAssistant && AssistUtils.allowDisablingAssistDisclosure(getContext())) {
|
||||
getPreferenceScreen().addPreference(mFlashPref);
|
||||
} else {
|
||||
getPreferenceScreen().removePreference(mFlashPref);
|
||||
}
|
||||
|
||||
if (isCurrentAssistVoiceService()) {
|
||||
getPreferenceScreen().removePreference(mVoiceInputPref);
|
||||
} else {
|
||||
getPreferenceScreen().addPreference(mVoiceInputPref);
|
||||
mVoiceInputPref.setAssistRestrict(currentAssist);
|
||||
}
|
||||
|
||||
guardFlashPref();
|
||||
}
|
||||
|
||||
private boolean isCurrentAssistVoiceService() {
|
||||
ComponentName currentAssist = mDefaultAssitPref.getCurrentAssist();
|
||||
ComponentName activeService = mVoiceInputPref.getCurrentService();
|
||||
return currentAssist == null && activeService == null ||
|
||||
currentAssist != null && currentAssist.equals(activeService);
|
||||
}
|
||||
|
||||
private void confirmNewAssist(final String newAssitPackage) {
|
||||
final int selected = mDefaultAssitPref.findIndexOfValue(newAssitPackage);
|
||||
final CharSequence appLabel = mDefaultAssitPref.getEntries()[selected];
|
||||
|
||||
final String title = getString(R.string.assistant_security_warning_title, appLabel);
|
||||
final String message = getString(R.string.assistant_security_warning, appLabel);
|
||||
|
||||
final DialogInterface.OnClickListener onAgree = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setDefaultAssist(newAssitPackage);
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||
builder.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(R.string.assistant_security_warning_agree, onAgree)
|
||||
.setNegativeButton(R.string.assistant_security_warning_disagree, null);
|
||||
AlertDialog dialog = builder.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void setDefaultAssist(String assistPackage) {
|
||||
mDefaultAssitPref.setValue(assistPackage);
|
||||
updateUi();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class AssistContextPreferenceController extends PreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final String KEY_CONTEXT = "context";
|
||||
|
||||
private final AssistUtils mAssistUtils;
|
||||
private final SettingObserver mSettingObserver;
|
||||
|
||||
private Preference mPreference;
|
||||
private PreferenceScreen mScreen;
|
||||
|
||||
public AssistContextPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mSettingObserver = new SettingObserver();
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_CONTEXT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mScreen = screen;
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), true);
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), false);
|
||||
}
|
||||
|
||||
|
||||
private void updatePreference() {
|
||||
if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
|
||||
return;
|
||||
}
|
||||
if (isAvailable()) {
|
||||
if (mScreen.findPreference(getPreferenceKey()) == null) {
|
||||
// add it if it's not on scree
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
} else {
|
||||
mScreen.removePreference(mPreference);
|
||||
}
|
||||
|
||||
((TwoStatePreference) mPreference).setChecked(isChecked(mContext));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_STRUCTURE_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static boolean isChecked(Context context) {
|
||||
return Settings.Secure.getInt(context.getContentResolver(),
|
||||
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0;
|
||||
}
|
||||
|
||||
class SettingObserver extends AssistSettingObserver {
|
||||
|
||||
private final Uri URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
|
||||
|
||||
@Override
|
||||
protected List<Uri> getSettingUris() {
|
||||
return Arrays.asList(URI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChange() {
|
||||
updatePreference();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class AssistFlashScreenPreferenceController extends PreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final String KEY_FLASH = "flash";
|
||||
|
||||
private final AssistUtils mAssistUtils;
|
||||
private final SettingObserver mSettingObserver;
|
||||
private PreferenceScreen mScreen;
|
||||
private Preference mPreference;
|
||||
|
||||
public AssistFlashScreenPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mSettingObserver = new SettingObserver();
|
||||
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return getCurrentAssist() != null && allowDisablingAssistDisclosure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_FLASH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mScreen = screen;
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), true);
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updatePreference() {
|
||||
if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
|
||||
return;
|
||||
}
|
||||
if (isAvailable()) {
|
||||
if (mScreen.findPreference(getPreferenceKey()) == null) {
|
||||
// add it if it's not on scree
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
} else {
|
||||
mScreen.removePreference(mPreference);
|
||||
}
|
||||
ComponentName assistant = getCurrentAssist();
|
||||
|
||||
boolean isContextChecked = AssistContextPreferenceController.isChecked(mContext);
|
||||
|
||||
mPreference.setEnabled(isContextChecked && isPreInstalledAssistant(assistant));
|
||||
((TwoStatePreference) mPreference).setChecked(willShowFlash(assistant));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean willShowFlash(ComponentName assistant) {
|
||||
return AssistUtils.shouldDisclose(mContext, assistant);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isPreInstalledAssistant(ComponentName assistant) {
|
||||
return AssistUtils.isPreinstalledAssistant(mContext, assistant);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean allowDisablingAssistDisclosure() {
|
||||
return AssistUtils.allowDisablingAssistDisclosure(mContext);
|
||||
}
|
||||
|
||||
private ComponentName getCurrentAssist() {
|
||||
return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
|
||||
}
|
||||
|
||||
class SettingObserver extends AssistSettingObserver {
|
||||
|
||||
private final Uri URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSIST_DISCLOSURE_ENABLED);
|
||||
private final Uri CONTEXT_URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
|
||||
|
||||
@Override
|
||||
protected List<Uri> getSettingUris() {
|
||||
return Arrays.asList(URI, CONTEXT_URI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChange() {
|
||||
updatePreference();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class AssistScreenshotPreferenceController extends PreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final String KEY_SCREENSHOT = "screenshot";
|
||||
|
||||
private final AssistUtils mAssistUtils;
|
||||
private final SettingObserver mSettingObserver;
|
||||
|
||||
private PreferenceScreen mScreen;
|
||||
private Preference mPreference;
|
||||
|
||||
public AssistScreenshotPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mSettingObserver = new SettingObserver();
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mScreen = screen;
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_SCREENSHOT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), true);
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
|
||||
(boolean) newValue ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void updatePreference() {
|
||||
if (mPreference == null || !(mPreference instanceof TwoStatePreference)) {
|
||||
return;
|
||||
}
|
||||
if (isAvailable()) {
|
||||
if (mScreen.findPreference(getPreferenceKey()) == null) {
|
||||
// add it if it's not on scree
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
} else {
|
||||
mScreen.removePreference(mPreference);
|
||||
}
|
||||
final boolean checked = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_SCREENSHOT_ENABLED, 1) != 0;
|
||||
((TwoStatePreference) mPreference).setChecked(checked);
|
||||
final boolean contextChecked = Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1) != 0;
|
||||
mPreference.setEnabled(contextChecked);
|
||||
}
|
||||
|
||||
class SettingObserver extends AssistSettingObserver {
|
||||
|
||||
private final Uri URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSIST_SCREENSHOT_ENABLED);
|
||||
private final Uri CONTEXT_URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSIST_STRUCTURE_ENABLED);
|
||||
|
||||
@Override
|
||||
protected List<Uri> getSettingUris() {
|
||||
return Arrays.asList(URI, CONTEXT_URI);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChange() {
|
||||
updatePreference();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AssistSettingObserver extends ContentObserver {
|
||||
|
||||
private final Uri ASSIST_URI =
|
||||
Settings.Secure.getUriFor(Settings.Secure.ASSISTANT);
|
||||
|
||||
public AssistSettingObserver() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
public void register(ContentResolver cr, boolean register) {
|
||||
if (register) {
|
||||
cr.registerContentObserver(ASSIST_URI, false, this);
|
||||
final List<Uri> settingUri = getSettingUris();
|
||||
if (settingUri != null) {
|
||||
for (Uri uri : settingUri)
|
||||
cr.registerContentObserver(uri, false, this);
|
||||
}
|
||||
} else {
|
||||
cr.unregisterContentObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
super.onChange(selfChange, uri);
|
||||
boolean shouldUpdatePreference = false;
|
||||
final List<Uri> settingUri = getSettingUris();
|
||||
if (ASSIST_URI.equals(uri) || (settingUri != null && settingUri.contains(uri))) {
|
||||
shouldUpdatePreference = true;
|
||||
}
|
||||
if (shouldUpdatePreference) {
|
||||
onSettingChange();
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract List<Uri> getSettingUris();
|
||||
|
||||
public abstract void onSettingChange();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2017 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.
|
||||
@@ -11,49 +11,105 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.applications;
|
||||
package com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.service.voice.VoiceInteractionServiceInfo;
|
||||
import android.speech.RecognitionService;
|
||||
import android.util.AttributeSet;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.AppListPreferenceWithSettings;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultAssistPreference extends AppListPreferenceWithSettings {
|
||||
|
||||
private static final String TAG = DefaultAssistPreference.class.getSimpleName();
|
||||
public class DefaultAssistPicker extends DefaultAppPickerFragment {
|
||||
|
||||
private static final String TAG = "DefaultAssistPicker";
|
||||
private static final Intent ASSIST_SERVICE_PROBE =
|
||||
new Intent(VoiceInteractionService.SERVICE_INTERFACE);
|
||||
private static final Intent ASSIST_ACTIVITY_PROBE =
|
||||
new Intent(Intent.ACTION_ASSIST);
|
||||
private final List<Info> mAvailableAssistants = new ArrayList<>();
|
||||
|
||||
private final AssistUtils mAssistUtils;
|
||||
private AssistUtils mAssistUtils;
|
||||
|
||||
public DefaultAssistPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setShowItemNone(true);
|
||||
setDialogTitle(R.string.choose_assist_title);
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.DEFAULT_ASSIST_PICKER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldShowItemNone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean persistString(String value) {
|
||||
final Info info = findAssistantByPackageName(value);
|
||||
protected List<DefaultAppInfo> getCandidates() {
|
||||
mAvailableAssistants.clear();
|
||||
addAssistServices();
|
||||
addAssistActivities();
|
||||
|
||||
final List<String> packages = new ArrayList<>();
|
||||
final List<DefaultAppInfo> candidates = new ArrayList<>();
|
||||
for (Info info : mAvailableAssistants) {
|
||||
final String packageName = info.component.getPackageName();
|
||||
if (packages.contains(packageName)) {
|
||||
// A service appears before an activity thus overrides it if from the same package.
|
||||
continue;
|
||||
}
|
||||
packages.add(packageName);
|
||||
candidates.add(new DefaultAppInfo(mUserId, info.component));
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultAppKey() {
|
||||
final ComponentName cn = getCurrentAssist();
|
||||
if (cn != null) {
|
||||
return new DefaultAppInfo(mUserId, cn).getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getConfirmationMessage(DefaultAppInfo appInfo) {
|
||||
if (appInfo == null) {
|
||||
return null;
|
||||
}
|
||||
return getContext().getString(R.string.assistant_security_warning,
|
||||
appInfo.loadLabel(mPm.getPackageManager()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setDefaultAppKey(String key) {
|
||||
if (TextUtils.isEmpty(key)) {
|
||||
setAssistNone();
|
||||
return true;
|
||||
}
|
||||
ComponentName cn = ComponentName.unflattenFromString(key);
|
||||
final Info info = findAssistantByPackageName(cn.getPackageName());
|
||||
if (info == null) {
|
||||
setAssistNone();
|
||||
return true;
|
||||
@@ -67,20 +123,60 @@ public class DefaultAssistPreference extends AppListPreferenceWithSettings {
|
||||
return true;
|
||||
}
|
||||
|
||||
public ComponentName getCurrentAssist() {
|
||||
return mAssistUtils.getAssistComponentForUser(mUserId);
|
||||
}
|
||||
|
||||
private void addAssistServices() {
|
||||
final PackageManager pm = mPm.getPackageManager();
|
||||
final List<ResolveInfo> services = pm.queryIntentServices(
|
||||
ASSIST_SERVICE_PROBE, PackageManager.GET_META_DATA);
|
||||
for (ResolveInfo resolveInfo : services) {
|
||||
VoiceInteractionServiceInfo voiceInteractionServiceInfo =
|
||||
new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
|
||||
if (!voiceInteractionServiceInfo.getSupportsAssist()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mAvailableAssistants.add(new Info(
|
||||
new ComponentName(resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name),
|
||||
voiceInteractionServiceInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void addAssistActivities() {
|
||||
final PackageManager pm = mPm.getPackageManager();
|
||||
final List<ResolveInfo> activities = pm.queryIntentActivities(
|
||||
ASSIST_ACTIVITY_PROBE, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
for (ResolveInfo resolveInfo : activities) {
|
||||
mAvailableAssistants.add(new Info(
|
||||
new ComponentName(resolveInfo.activityInfo.packageName,
|
||||
resolveInfo.activityInfo.name)));
|
||||
}
|
||||
}
|
||||
|
||||
private Info findAssistantByPackageName(String packageName) {
|
||||
for (Info info : mAvailableAssistants) {
|
||||
if (TextUtils.equals(info.component.getPackageName(), packageName)) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setAssistNone() {
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.ASSISTANT, ITEM_NONE_VALUE);
|
||||
Settings.Secure.ASSISTANT, "");
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE, "");
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer());
|
||||
|
||||
setSummary(getContext().getText(R.string.default_assist_none));
|
||||
setSettingsComponent(null);
|
||||
}
|
||||
|
||||
private void setAssistService(Info serviceInfo) {
|
||||
final String serviceComponentName = serviceInfo.component.flattenToShortString();
|
||||
final String serviceComponentName = serviceInfo.component.
|
||||
flattenToShortString();
|
||||
final String serviceRecognizerName = new ComponentName(
|
||||
serviceInfo.component.getPackageName(),
|
||||
serviceInfo.voiceInteractionServiceInfo.getRecognitionService())
|
||||
@@ -92,13 +188,6 @@ public class DefaultAssistPreference extends AppListPreferenceWithSettings {
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE, serviceComponentName);
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_RECOGNITION_SERVICE, serviceRecognizerName);
|
||||
|
||||
setSummary(getEntry());
|
||||
final String settingsActivity =
|
||||
serviceInfo.voiceInteractionServiceInfo.getSettingsActivity();
|
||||
setSettingsComponent(settingsActivity == null ?
|
||||
null :
|
||||
new ComponentName(serviceInfo.component.getPackageName(), settingsActivity));
|
||||
}
|
||||
|
||||
private void setAssistActivity(Info activityInfo) {
|
||||
@@ -108,13 +197,10 @@ public class DefaultAssistPreference extends AppListPreferenceWithSettings {
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE, "");
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_RECOGNITION_SERVICE, getDefaultRecognizer());
|
||||
|
||||
setSummary(getEntry());
|
||||
setSettingsComponent(null);
|
||||
}
|
||||
|
||||
private String getDefaultRecognizer() {
|
||||
ResolveInfo resolveInfo = getContext().getPackageManager().resolveService(
|
||||
final ResolveInfo resolveInfo = mPm.getPackageManager().resolveService(
|
||||
new Intent(RecognitionService.SERVICE_INTERFACE),
|
||||
PackageManager.GET_META_DATA);
|
||||
if (resolveInfo == null || resolveInfo.serviceInfo == null) {
|
||||
@@ -126,76 +212,7 @@ public class DefaultAssistPreference extends AppListPreferenceWithSettings {
|
||||
resolveInfo.serviceInfo.name).flattenToShortString();
|
||||
}
|
||||
|
||||
private Info findAssistantByPackageName(String packageName) {
|
||||
for (int i = 0; i < mAvailableAssistants.size(); ++i) {
|
||||
Info info = mAvailableAssistants.get(i);
|
||||
if (info.component.getPackageName().equals(packageName)) {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addAssistServices() {
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
|
||||
List<ResolveInfo> services = pm.queryIntentServices(
|
||||
new Intent(VoiceInteractionService.SERVICE_INTERFACE),
|
||||
PackageManager.GET_META_DATA);
|
||||
for (int i = 0; i < services.size(); ++i) {
|
||||
ResolveInfo resolveInfo = services.get(i);
|
||||
VoiceInteractionServiceInfo voiceInteractionServiceInfo =
|
||||
new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
|
||||
if (!voiceInteractionServiceInfo.getSupportsAssist()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mAvailableAssistants.add(new Info(
|
||||
new ComponentName(resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name),
|
||||
voiceInteractionServiceInfo));
|
||||
}
|
||||
}
|
||||
|
||||
private void addAssistActivities() {
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
|
||||
List<ResolveInfo> activities = pm.queryIntentActivities(
|
||||
new Intent(Intent.ACTION_ASSIST),
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
for (int i = 0; i < activities.size(); ++i) {
|
||||
ResolveInfo resolveInfo = activities.get(i);
|
||||
mAvailableAssistants.add(new Info(
|
||||
new ComponentName(resolveInfo.activityInfo.packageName,
|
||||
resolveInfo.activityInfo.name)));
|
||||
}
|
||||
}
|
||||
|
||||
public ComponentName getCurrentAssist() {
|
||||
return mAssistUtils.getAssistComponentForUser(UserHandle.myUserId());
|
||||
}
|
||||
|
||||
public void refreshAssistApps() {
|
||||
mAvailableAssistants.clear();
|
||||
addAssistServices();
|
||||
addAssistActivities();
|
||||
|
||||
List<String> packages = new ArrayList<>();
|
||||
for (int i = 0; i < mAvailableAssistants.size(); ++i) {
|
||||
String packageName = mAvailableAssistants.get(i).component.getPackageName();
|
||||
if (packages.contains(packageName)) {
|
||||
// A service appears before an activity thus overrides it if from the same package.
|
||||
continue;
|
||||
}
|
||||
packages.add(packageName);
|
||||
}
|
||||
|
||||
ComponentName currentAssist = getCurrentAssist();
|
||||
setPackageNames(packages.toArray(new String[packages.size()]),
|
||||
currentAssist == null ? null : currentAssist.getPackageName());
|
||||
}
|
||||
|
||||
private static class Info {
|
||||
static class Info {
|
||||
public final ComponentName component;
|
||||
public final VoiceInteractionServiceInfo voiceInteractionServiceInfo;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.service.voice.VoiceInteractionServiceInfo;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultAssistPreferenceController extends DefaultAppPreferenceController {
|
||||
|
||||
private static final String KEY_DEFAULT_ASSIST = "default_assist";
|
||||
|
||||
private AssistUtils mAssistUtils;
|
||||
|
||||
public DefaultAssistPreferenceController(Context context) {
|
||||
super(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Intent getSettingIntent(DefaultAppInfo info) {
|
||||
final ComponentName cn = mAssistUtils.getAssistComponentForUser(mUserId);
|
||||
if (cn == null) {
|
||||
return null;
|
||||
}
|
||||
final Intent probe = new Intent(VoiceInteractionService.SERVICE_INTERFACE)
|
||||
.setPackage(cn.getPackageName());
|
||||
|
||||
final PackageManager pm = mPackageManager.getPackageManager();
|
||||
final List<ResolveInfo> services = pm.queryIntentServices(probe, PackageManager
|
||||
.GET_META_DATA);
|
||||
if (services == null || services.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final ResolveInfo resolveInfo = services.get(0);
|
||||
final VoiceInteractionServiceInfo voiceInfo =
|
||||
new VoiceInteractionServiceInfo(pm, resolveInfo.serviceInfo);
|
||||
if (!voiceInfo.getSupportsAssist()) {
|
||||
return null;
|
||||
}
|
||||
final String activity = voiceInfo.getSettingsActivity();
|
||||
return new Intent(Intent.ACTION_MAIN)
|
||||
.setComponent(new ComponentName(cn.getPackageName(), activity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_DEFAULT_ASSIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DefaultAppInfo getDefaultAppInfo() {
|
||||
final ComponentName cn = mAssistUtils.getAssistComponentForUser(mUserId);
|
||||
if (cn == null) {
|
||||
return null;
|
||||
}
|
||||
return new DefaultAppInfo(mUserId, cn);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPickerFragment;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultVoiceInputPicker extends DefaultAppPickerFragment {
|
||||
|
||||
private VoiceInputHelper mHelper;
|
||||
private AssistUtils mAssistUtils;
|
||||
private String mAssistRestrict;
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.DEFAULT_VOICE_INPUT_PICKER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mHelper = new VoiceInputHelper(context);
|
||||
mHelper.buildUi();
|
||||
final ComponentName assist = getCurrentAssist();
|
||||
if (isCurrentAssistVoiceService(assist, getCurrentService(mHelper))) {
|
||||
mAssistRestrict = assist.flattenToShortString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<VoiceInputDefaultAppInfo> getCandidates() {
|
||||
final List<VoiceInputDefaultAppInfo> candidates = new ArrayList<>();
|
||||
boolean hasEnabled = true;
|
||||
for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
|
||||
final boolean enabled = TextUtils.equals(info.key, mAssistRestrict);
|
||||
hasEnabled |= enabled;
|
||||
candidates.add(new VoiceInputDefaultAppInfo(mUserId, info, enabled));
|
||||
}
|
||||
|
||||
final boolean assistIsService = !hasEnabled;
|
||||
for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
|
||||
final boolean enabled = !assistIsService;
|
||||
candidates.add(new VoiceInputDefaultAppInfo(mUserId, info, enabled));
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultAppKey() {
|
||||
final ComponentName currentService = getCurrentService(mHelper);
|
||||
if (currentService == null) {
|
||||
return null;
|
||||
}
|
||||
return currentService.flattenToShortString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean setDefaultAppKey(String value) {
|
||||
for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
|
||||
if (TextUtils.equals(value, info.key)) {
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE, value);
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_RECOGNITION_SERVICE,
|
||||
new ComponentName(info.service.packageName,
|
||||
info.serviceInfo.getRecognitionService())
|
||||
.flattenToShortString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
|
||||
if (TextUtils.equals(value, info.key)) {
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_INTERACTION_SERVICE, "");
|
||||
Settings.Secure.putString(getContext().getContentResolver(),
|
||||
Settings.Secure.VOICE_RECOGNITION_SERVICE, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static ComponentName getCurrentService(VoiceInputHelper helper) {
|
||||
if (helper.mCurrentVoiceInteraction != null) {
|
||||
return helper.mCurrentVoiceInteraction;
|
||||
} else if (helper.mCurrentRecognizer != null) {
|
||||
return helper.mCurrentRecognizer;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private ComponentName getCurrentAssist() {
|
||||
return mAssistUtils.getAssistComponentForUser(mUserId);
|
||||
}
|
||||
|
||||
public static boolean isCurrentAssistVoiceService(ComponentName currentAssist,
|
||||
ComponentName currentVoiceService) {
|
||||
return currentAssist == null && currentVoiceService == null ||
|
||||
currentAssist != null && currentAssist.equals(currentVoiceService);
|
||||
}
|
||||
|
||||
public static class VoiceInputDefaultAppInfo extends DefaultAppInfo {
|
||||
|
||||
public VoiceInputHelper.BaseInfo mInfo;
|
||||
|
||||
public VoiceInputDefaultAppInfo(int userId, VoiceInputHelper.BaseInfo info,
|
||||
boolean enabled) {
|
||||
super(userId, info.componentName, null /* summary */, enabled);
|
||||
mInfo = info;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return mInfo.key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence loadLabel(PackageManager pm) {
|
||||
if (mInfo instanceof VoiceInputHelper.InteractionInfo) {
|
||||
return mInfo.appLabel;
|
||||
} else {
|
||||
return mInfo.label;
|
||||
}
|
||||
}
|
||||
|
||||
public Intent getSettingIntent() {
|
||||
if (mInfo.settings == null) {
|
||||
return null;
|
||||
}
|
||||
return new Intent(Intent.ACTION_MAIN).setComponent(mInfo.settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultVoiceInputPreferenceController extends DefaultAppPreferenceController
|
||||
implements LifecycleObserver, OnResume, OnPause {
|
||||
|
||||
private static final String KEY_VOICE_INPUT = "voice_input_settings";
|
||||
|
||||
private VoiceInputHelper mHelper;
|
||||
private AssistUtils mAssistUtils;
|
||||
private PreferenceScreen mScreen;
|
||||
private Preference mPreference;
|
||||
private SettingObserver mSettingObserver;
|
||||
|
||||
public DefaultVoiceInputPreferenceController(Context context, Lifecycle lifecycle) {
|
||||
super(context);
|
||||
mSettingObserver = new SettingObserver();
|
||||
mAssistUtils = new AssistUtils(context);
|
||||
mHelper = new VoiceInputHelper(context);
|
||||
mHelper.buildUi();
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
// If current assist is also voice service, don't show voice preference.
|
||||
final ComponentName currentVoiceService =
|
||||
DefaultVoiceInputPicker.getCurrentService(mHelper);
|
||||
final ComponentName currentAssist =
|
||||
mAssistUtils.getAssistComponentForUser(mUserId);
|
||||
return !DefaultVoiceInputPicker.isCurrentAssistVoiceService(
|
||||
currentAssist, currentVoiceService);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_VOICE_INPUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mScreen = screen;
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
super.displayPreference(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), true);
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(mPreference);
|
||||
updatePreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
mSettingObserver.register(mContext.getContentResolver(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DefaultAppInfo getDefaultAppInfo() {
|
||||
final String defaultKey = getDefaultAppKey();
|
||||
if (defaultKey == null) {
|
||||
return null;
|
||||
}
|
||||
for (VoiceInputHelper.InteractionInfo info : mHelper.mAvailableInteractionInfos) {
|
||||
if (TextUtils.equals(defaultKey, info.key)) {
|
||||
return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(
|
||||
mUserId, info, true /* enabled */);
|
||||
}
|
||||
}
|
||||
|
||||
for (VoiceInputHelper.RecognizerInfo info : mHelper.mAvailableRecognizerInfos) {
|
||||
if (TextUtils.equals(defaultKey, info.key)) {
|
||||
return new DefaultVoiceInputPicker.VoiceInputDefaultAppInfo(
|
||||
mUserId, info, true /* enabled */);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Intent getSettingIntent(DefaultAppInfo info) {
|
||||
final DefaultAppInfo appInfo = getDefaultAppInfo();
|
||||
if (appInfo == null
|
||||
|| !(appInfo instanceof DefaultVoiceInputPicker.VoiceInputDefaultAppInfo)) {
|
||||
return null;
|
||||
}
|
||||
return ((DefaultVoiceInputPicker.VoiceInputDefaultAppInfo) appInfo).getSettingIntent();
|
||||
}
|
||||
|
||||
private void updatePreference() {
|
||||
if (mPreference == null) {
|
||||
return;
|
||||
}
|
||||
mHelper.buildUi();
|
||||
if (isAvailable()) {
|
||||
if (mScreen.findPreference(getPreferenceKey()) == null) {
|
||||
// add it if it's not on scree
|
||||
mScreen.addPreference(mPreference);
|
||||
}
|
||||
} else {
|
||||
mScreen.removePreference(mPreference);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultAppKey() {
|
||||
final ComponentName currentService = DefaultVoiceInputPicker.getCurrentService(mHelper);
|
||||
if (currentService == null) {
|
||||
return null;
|
||||
}
|
||||
return currentService.flattenToShortString();
|
||||
}
|
||||
|
||||
class SettingObserver extends AssistSettingObserver {
|
||||
@Override
|
||||
protected List<Uri> getSettingUris() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingChange() {
|
||||
updatePreference();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.gestures.AssistGestureFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
public class GestureAssistPreferenceController extends PreferenceController {
|
||||
|
||||
private static final String KEY_ASSIST_GESTURE = "gesture_assist";
|
||||
|
||||
private AssistGestureFeatureProvider mFeatureProvider;
|
||||
|
||||
public GestureAssistPreferenceController(Context context) {
|
||||
super(context);
|
||||
mFeatureProvider = FeatureFactory.getFactory(context)
|
||||
.getAssistGestureFeatureProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mFeatureProvider.isSupported(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_ASSIST_GESTURE;
|
||||
}
|
||||
}
|
||||
103
src/com/android/settings/applications/assist/ManageAssist.java
Normal file
103
src/com/android/settings/applications/assist/ManageAssist.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Settings screen to manage everything about assist.
|
||||
*/
|
||||
public class ManageAssist extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "ManageAssist";
|
||||
|
||||
@Override
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.manage_assist;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
final Lifecycle lifecycle = getLifecycle();
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new DefaultAssistPreferenceController(context));
|
||||
controllers.add(new GestureAssistPreferenceController(context));
|
||||
controllers.add(new AssistContextPreferenceController(context, lifecycle));
|
||||
controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
|
||||
controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
|
||||
controllers.add(new DefaultVoiceInputPreferenceController(context, lifecycle));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.APPLICATIONS_MANAGE_ASSIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mFooterPreferenceMixin.createFooterPreference()
|
||||
.setTitle(R.string.assist_footer);
|
||||
}
|
||||
|
||||
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||
boolean enabled) {
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.manage_assist;
|
||||
return Arrays.asList(sir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
List<String> result = new ArrayList<>();
|
||||
new DefaultAssistPreferenceController(context).updateNonIndexableKeys(result);
|
||||
new GestureAssistPreferenceController(context).updateNonIndexableKeys(result);
|
||||
new AssistContextPreferenceController(context, null)
|
||||
.updateNonIndexableKeys(result);
|
||||
new AssistScreenshotPreferenceController(context, null)
|
||||
.updateNonIndexableKeys(result);
|
||||
new AssistFlashScreenPreferenceController(context, null)
|
||||
.updateNonIndexableKeys(result);
|
||||
new DefaultVoiceInputPreferenceController(context, null)
|
||||
.updateNonIndexableKeys(result);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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 com.android.settings.applications.assist;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.provider.Settings;
|
||||
import android.service.voice.VoiceInteractionService;
|
||||
import android.service.voice.VoiceInteractionServiceInfo;
|
||||
import android.speech.RecognitionService;
|
||||
import android.util.ArraySet;
|
||||
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;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class VoiceInputHelper {
|
||||
static final String TAG = "VoiceInputHelper";
|
||||
final Context mContext;
|
||||
|
||||
final List<ResolveInfo> mAvailableVoiceInteractions;
|
||||
final List<ResolveInfo> mAvailableRecognition;
|
||||
|
||||
static public class BaseInfo implements Comparable {
|
||||
public final ServiceInfo service;
|
||||
public final ComponentName componentName;
|
||||
public final String key;
|
||||
public final ComponentName settings;
|
||||
public final CharSequence label;
|
||||
public final String labelStr;
|
||||
public final CharSequence appLabel;
|
||||
|
||||
public BaseInfo(PackageManager pm, ServiceInfo _service, String _settings) {
|
||||
service = _service;
|
||||
componentName = new ComponentName(_service.packageName, _service.name);
|
||||
key = componentName.flattenToShortString();
|
||||
settings = _settings != null
|
||||
? new ComponentName(_service.packageName, _settings) : null;
|
||||
label = _service.loadLabel(pm);
|
||||
labelStr = label.toString();
|
||||
appLabel = _service.applicationInfo.loadLabel(pm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object another) {
|
||||
return labelStr.compareTo(((BaseInfo) another).labelStr);
|
||||
}
|
||||
}
|
||||
|
||||
static public class InteractionInfo extends BaseInfo {
|
||||
public final VoiceInteractionServiceInfo serviceInfo;
|
||||
|
||||
public InteractionInfo(PackageManager pm, VoiceInteractionServiceInfo _service) {
|
||||
super(pm, _service.getServiceInfo(), _service.getSettingsActivity());
|
||||
serviceInfo = _service;
|
||||
}
|
||||
}
|
||||
|
||||
static public class RecognizerInfo extends BaseInfo {
|
||||
public RecognizerInfo(PackageManager pm, ServiceInfo _service, String _settings) {
|
||||
super(pm, _service, _settings);
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<InteractionInfo> mAvailableInteractionInfos = new ArrayList<>();
|
||||
final ArrayList<RecognizerInfo> mAvailableRecognizerInfos = new ArrayList<>();
|
||||
|
||||
ComponentName mCurrentVoiceInteraction;
|
||||
ComponentName mCurrentRecognizer;
|
||||
|
||||
public VoiceInputHelper(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mAvailableVoiceInteractions = mContext.getPackageManager().queryIntentServices(
|
||||
new Intent(VoiceInteractionService.SERVICE_INTERFACE),
|
||||
PackageManager.GET_META_DATA);
|
||||
mAvailableRecognition = mContext.getPackageManager().queryIntentServices(
|
||||
new Intent(RecognitionService.SERVICE_INTERFACE),
|
||||
PackageManager.GET_META_DATA);
|
||||
}
|
||||
|
||||
public void buildUi() {
|
||||
// Get the currently selected interactor from the secure setting.
|
||||
String currentSetting = Settings.Secure.getString(
|
||||
mContext.getContentResolver(), Settings.Secure.VOICE_INTERACTION_SERVICE);
|
||||
if (currentSetting != null && !currentSetting.isEmpty()) {
|
||||
mCurrentVoiceInteraction = ComponentName.unflattenFromString(currentSetting);
|
||||
} else {
|
||||
mCurrentVoiceInteraction = null;
|
||||
}
|
||||
|
||||
ArraySet<ComponentName> interactorRecognizers = new ArraySet<>();
|
||||
|
||||
// Iterate through all the available interactors and load up their info to show
|
||||
// in the preference.
|
||||
int size = mAvailableVoiceInteractions.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ResolveInfo resolveInfo = mAvailableVoiceInteractions.get(i);
|
||||
VoiceInteractionServiceInfo info = new VoiceInteractionServiceInfo(
|
||||
mContext.getPackageManager(), resolveInfo.serviceInfo);
|
||||
if (info.getParseError() != null) {
|
||||
Log.w("VoiceInteractionService", "Error in VoiceInteractionService "
|
||||
+ resolveInfo.serviceInfo.packageName + "/"
|
||||
+ resolveInfo.serviceInfo.name + ": " + info.getParseError());
|
||||
continue;
|
||||
}
|
||||
mAvailableInteractionInfos.add(new InteractionInfo(mContext.getPackageManager(), info));
|
||||
interactorRecognizers.add(new ComponentName(resolveInfo.serviceInfo.packageName,
|
||||
info.getRecognitionService()));
|
||||
}
|
||||
Collections.sort(mAvailableInteractionInfos);
|
||||
|
||||
// Get the currently selected recognizer from the secure setting.
|
||||
currentSetting = Settings.Secure.getString(
|
||||
mContext.getContentResolver(), Settings.Secure.VOICE_RECOGNITION_SERVICE);
|
||||
if (currentSetting != null && !currentSetting.isEmpty()) {
|
||||
mCurrentRecognizer = ComponentName.unflattenFromString(currentSetting);
|
||||
} else {
|
||||
mCurrentRecognizer = null;
|
||||
}
|
||||
|
||||
// Iterate through all the available recognizers and load up their info to show
|
||||
// in the preference.
|
||||
size = mAvailableRecognition.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
ResolveInfo resolveInfo = mAvailableRecognition.get(i);
|
||||
ComponentName comp = new ComponentName(resolveInfo.serviceInfo.packageName,
|
||||
resolveInfo.serviceInfo.name);
|
||||
if (interactorRecognizers.contains(comp)) {
|
||||
//continue;
|
||||
}
|
||||
ServiceInfo si = resolveInfo.serviceInfo;
|
||||
XmlResourceParser parser = null;
|
||||
String settingsActivity = null;
|
||||
try {
|
||||
parser = si.loadXmlMetaData(mContext.getPackageManager(),
|
||||
RecognitionService.SERVICE_META_DATA);
|
||||
if (parser == null) {
|
||||
throw new XmlPullParserException("No " + RecognitionService.SERVICE_META_DATA +
|
||||
" meta-data for " + si.packageName);
|
||||
}
|
||||
|
||||
Resources res = mContext.getPackageManager().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 (!"recognition-service".equals(nodeName)) {
|
||||
throw new XmlPullParserException(
|
||||
"Meta-data does not start with recognition-service tag");
|
||||
}
|
||||
|
||||
TypedArray array = res.obtainAttributes(attrs,
|
||||
com.android.internal.R.styleable.RecognitionService);
|
||||
settingsActivity = array.getString(
|
||||
com.android.internal.R.styleable.RecognitionService_settingsActivity);
|
||||
array.recycle();
|
||||
} catch (XmlPullParserException e) {
|
||||
Log.e(TAG, "error parsing recognition service meta-data", e);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "error parsing recognition service meta-data", e);
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "error parsing recognition service meta-data", e);
|
||||
} finally {
|
||||
if (parser != null) parser.close();
|
||||
}
|
||||
mAvailableRecognizerInfos.add(new RecognizerInfo(mContext.getPackageManager(),
|
||||
resolveInfo.serviceInfo, settingsActivity));
|
||||
}
|
||||
Collections.sort(mAvailableRecognizerInfos);
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,23 @@ public class DefaultAppInfo {
|
||||
public final String summary;
|
||||
// Description for why this item is disabled, if null, the item is enabled.
|
||||
public final String disabledDescription;
|
||||
public final boolean enabled;
|
||||
|
||||
public DefaultAppInfo(int uid, ComponentName cn) {
|
||||
this(uid, cn, null /* summary */);
|
||||
}
|
||||
|
||||
public DefaultAppInfo(int uid, ComponentName cn, String summary) {
|
||||
this(uid, cn, summary, true /* enabled */);
|
||||
}
|
||||
|
||||
public DefaultAppInfo(int uid, ComponentName cn, String summary, boolean enabled) {
|
||||
packageItemInfo = null;
|
||||
userId = uid;
|
||||
componentName = cn;
|
||||
this.summary = summary;
|
||||
this.disabledDescription = null;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public DefaultAppInfo(PackageItemInfo info, String description) {
|
||||
@@ -52,6 +62,7 @@ public class DefaultAppInfo {
|
||||
componentName = null;
|
||||
summary = null;
|
||||
this.disabledDescription = description;
|
||||
enabled = true;
|
||||
}
|
||||
|
||||
public DefaultAppInfo(PackageItemInfo info) {
|
||||
|
||||
@@ -97,7 +97,7 @@ public abstract class DefaultAppPickerFragment extends InstrumentedPreferenceFra
|
||||
@VisibleForTesting
|
||||
public void updateCandidates() {
|
||||
mCandidates.clear();
|
||||
final List<DefaultAppInfo> candidateList = getCandidates();
|
||||
final List<? extends DefaultAppInfo> candidateList = getCandidates();
|
||||
if (candidateList != null) {
|
||||
for (DefaultAppInfo info : candidateList) {
|
||||
mCandidates.put(info.getKey(), info);
|
||||
@@ -134,6 +134,7 @@ public abstract class DefaultAppPickerFragment extends InstrumentedPreferenceFra
|
||||
pref.setEnabled(false);
|
||||
pref.setSummary(app.getValue().disabledDescription);
|
||||
}
|
||||
pref.setEnabled(info.enabled);
|
||||
pref.setOnClickListener(this);
|
||||
screen.addPreference(pref);
|
||||
}
|
||||
@@ -200,14 +201,15 @@ public abstract class DefaultAppPickerFragment extends InstrumentedPreferenceFra
|
||||
return null;
|
||||
}
|
||||
|
||||
protected abstract List<DefaultAppInfo> getCandidates();
|
||||
protected abstract List<? extends DefaultAppInfo> getCandidates();
|
||||
|
||||
protected abstract String getDefaultAppKey();
|
||||
|
||||
protected abstract boolean setDefaultAppKey(String key);
|
||||
|
||||
// Called after the user tries to select an item.
|
||||
protected void onSelectionPerformed(boolean success) {}
|
||||
protected void onSelectionPerformed(boolean success) {
|
||||
}
|
||||
|
||||
protected String getConfirmationMessage(DefaultAppInfo appInfo) {
|
||||
return null;
|
||||
|
||||
@@ -54,7 +54,7 @@ public class DefaultAutoFillPicker extends DefaultAppPickerFragment {
|
||||
.queryIntentServices(AUTO_FILL_PROBE, PackageManager.GET_META_DATA);
|
||||
for (ResolveInfo info : resolveInfos) {
|
||||
candidates.add(new DefaultAppInfo(mUserId, new ComponentName(
|
||||
info.serviceInfo.packageName, info.serviceInfo.name), null /* summary */));
|
||||
info.serviceInfo.packageName, info.serviceInfo.name)));
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class DefaultAutoFillPreferenceController extends DefaultAppPreferenceCon
|
||||
DefaultAutoFillPicker.SETTING);
|
||||
if (!TextUtils.isEmpty(flattenComponent)) {
|
||||
DefaultAppInfo appInfo = new DefaultAppInfo(
|
||||
mUserId, ComponentName.unflattenFromString(flattenComponent), null /*summary*/);
|
||||
mUserId, ComponentName.unflattenFromString(flattenComponent));
|
||||
return appInfo;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -75,7 +75,7 @@ public class DefaultHomePreferenceController extends DefaultAppPreferenceControl
|
||||
final ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
|
||||
final ComponentName currentDefaultHome = mPackageManager.getHomeActivities(homeActivities);
|
||||
|
||||
return new DefaultAppInfo(mUserId, currentDefaultHome, null /* summary */);
|
||||
return new DefaultAppInfo(mUserId, currentDefaultHome);
|
||||
}
|
||||
|
||||
private String getOnlyAppLabel() {
|
||||
|
||||
@@ -76,7 +76,7 @@ public class DefaultNotificationAssistantPicker extends DefaultAppPickerFragment
|
||||
}
|
||||
|
||||
candidates.add(new DefaultAppInfo(
|
||||
mUserId, new ComponentName(info.packageName, info.name), null /* summary */));
|
||||
mUserId, new ComponentName(info.packageName, info.name)));
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DefaultSmsPreferenceController extends DefaultAppPreferenceControll
|
||||
protected DefaultAppInfo getDefaultAppInfo() {
|
||||
final ComponentName app = SmsApplication.getDefaultSmsApplication(mContext, true);
|
||||
if (app != null) {
|
||||
return new DefaultAppInfo(mUserId, app, null /* summary */);
|
||||
return new DefaultAppInfo(mUserId, app);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user