PageRenderTime 46ms CodeModel.GetById 10ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 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}