/talkback_preics/src/com/google/android/marvin/talkback/PluginPreferencesActivity.java
Java | 194 lines | 133 code | 20 blank | 41 comment | 9 complexity | 7c2ad96922e0f766af10eadf82b95876 MD5 | raw file
1/* 2 * Copyright 2010 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.google.android.marvin.talkback; 18 19import android.app.AlertDialog; 20import android.content.ComponentName; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.content.DialogInterface.OnClickListener; 24import android.content.pm.ServiceInfo; 25import android.net.Uri; 26import android.os.Bundle; 27import android.preference.CheckBoxPreference; 28import android.preference.Preference; 29import android.preference.PreferenceActivity; 30import android.preference.Preference.OnPreferenceChangeListener; 31import android.view.ContextMenu; 32import android.view.MenuInflater; 33import android.view.MenuItem; 34import android.view.View; 35import android.view.ContextMenu.ContextMenuInfo; 36import android.widget.AdapterView.AdapterContextMenuInfo; 37 38import java.util.List; 39 40/** 41 * This class is preference activity that manages TalkBack plug-ins. 42 * 43 * @author svetoslavganov@google.com (Svetoslav R. Ganov) 44 * 45 */ 46public class PluginPreferencesActivity extends PreferenceActivity 47 implements OnPreferenceChangeListener { 48 49 /** 50 * Meta-data key to obtain if the plug-in defines classes. 51 */ 52 private static final String KEY_METADATA_DEFINESCLASSES = "definesclasses"; 53 54 /** 55 * Monitor to handle add/remove/change of packages. 56 */ 57 private BasePackageMonitor mPackageMonitor; 58 59 /** 60 * Cached list of the installed plug-ins; 61 */ 62 private List<ServiceInfo> mPlugins; 63 64 @Override 65 public void onCreate(Bundle icicle) { 66 super.onCreate(icicle); 67 68 mPlugins = PluginManager.getPlugins(getPackageManager()); 69 mPackageMonitor = new BasePackageMonitor() { 70 @Override 71 protected void onPackageAdded(String packageName) { 72 mPlugins = PluginManager.getPlugins(getPackageManager()); 73 addEnabledPluginsCheckboxPreferences(); 74 } 75 76 @Override 77 protected void onPackageChanged(String packageName) { 78 mPlugins = PluginManager.getPlugins(getPackageManager()); 79 addEnabledPluginsCheckboxPreferences(); 80 } 81 82 @Override 83 protected void onPackageRemoved(String packageName) { 84 mPlugins = PluginManager.getPlugins(getPackageManager()); 85 addEnabledPluginsCheckboxPreferences(); 86 } 87 }; 88 89 setPreferenceScreen(getPreferenceManager().createPreferenceScreen(this)); 90 addEnabledPluginsCheckboxPreferences(); 91 registerForContextMenu(getListView()); 92 mPackageMonitor.register(this); 93 } 94 95 @Override 96 protected void onDestroy() { 97 mPackageMonitor.unregister(); 98 super.onDestroy(); 99 } 100 101 @Override 102 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 103 super.onCreateContextMenu(menu, v, menuInfo); 104 MenuInflater inflater = getMenuInflater(); 105 inflater.inflate(R.menu.manage_plugin_context_menu, menu); 106 } 107 108 @Override 109 public boolean onContextItemSelected(MenuItem item) { 110 AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 111 switch (item.getItemId()) { 112 case R.id.uninstall_plugin: 113 int index = info.position; 114 CheckBoxPreference preferene = (CheckBoxPreference) getPreferenceScreen() 115 .getPreference(index); 116 uninstallPlugin(preferene.getKey()); 117 return true; 118 default: 119 return super.onContextItemSelected(item); 120 } 121 } 122 123 /** 124 * Sends the user to the uninstall screen for the given <code>packageName</code>. 125 */ 126 private void uninstallPlugin(String pluginName) { 127 ComponentName componentName = ComponentName.unflattenFromString(pluginName); 128 Uri packageURI = Uri.parse("package:" + componentName.getPackageName()); 129 Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI); 130 startActivity(uninstallIntent); 131 } 132 133 /** 134 * Adds check-box preferences to this screen for each installed plug-in 135 * and whose checked state corresponds to the plug-in enabled state. 136 */ 137 private void addEnabledPluginsCheckboxPreferences() { 138 List<ServiceInfo> installedPlugins = mPlugins; 139 140 getPreferenceScreen().removeAll(); 141 for (ServiceInfo installedPlugin : installedPlugins) { 142 String key = new ComponentName(installedPlugin.packageName, 143 installedPlugin.name).flattenToString(); 144 CheckBoxPreference preference = new CheckBoxPreference(this); 145 preference.setKey(key); 146 preference.setTitle(installedPlugin.loadLabel(getPackageManager())); 147 preference.setOnPreferenceChangeListener(this); 148 getPreferenceScreen().addPreference(preference); 149 } 150 } 151 152 public boolean onPreferenceChange(Preference preference, Object newValue) { 153 if (newValue == Boolean.TRUE && preference instanceof CheckBoxPreference) { 154 CheckBoxPreference checkBoxPreference = (CheckBoxPreference) preference; 155 ComponentName pluginComponentName = ComponentName.unflattenFromString(preference 156 .getKey()); 157 for (ServiceInfo plugin : mPlugins) { 158 if (plugin.packageName.equals(pluginComponentName.getPackageName()) 159 && plugin.name.equals(pluginComponentName.getClassName()) 160 && plugin.metaData.getBoolean(KEY_METADATA_DEFINESCLASSES, false)) { 161 showTalkBackPluginDefinesClassesDialog(plugin, checkBoxPreference); 162 return false; 163 } 164 } 165 } 166 return true; 167 } 168 169 /** 170 * Shows dialog to obtain informed consent for enabling a class defining 171 * <code>plugin</code>. 172 */ 173 private void showTalkBackPluginDefinesClassesDialog(ServiceInfo plugin, 174 CheckBoxPreference preference) { 175 final CheckBoxPreference finalPreference = preference; 176 new AlertDialog.Builder(this) 177 .setTitle(getString(R.string.title_warning_talkback_plugin_security)) 178 .setMessage(getString(R.string.message_warning_talkback_plugin_security, 179 plugin.applicationInfo.loadLabel(getPackageManager()))) 180 .setPositiveButton(android.R.string.ok, 181 new DialogInterface.OnClickListener() { 182 public void onClick(DialogInterface dialog, int id) { 183 finalPreference.setChecked(true); 184 } 185 }) 186 .setNegativeButton(android.R.string.cancel, new OnClickListener() { 187 public void onClick(DialogInterface dialog, int which) { 188 finalPreference.setChecked(false); 189 } 190 }) 191 .create() 192 .show(); 193 } 194}