/talkback_preics/src/com/google/android/marvin/talkback/PluginPreferencesActivity.java

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