diff options
Diffstat (limited to 'src/com/android/browser/GearsSettingsDialog.java')
| -rw-r--r-- | src/com/android/browser/GearsSettingsDialog.java | 500 |
1 files changed, 500 insertions, 0 deletions
diff --git a/src/com/android/browser/GearsSettingsDialog.java b/src/com/android/browser/GearsSettingsDialog.java new file mode 100644 index 000000000..dead4f247 --- /dev/null +++ b/src/com/android/browser/GearsSettingsDialog.java @@ -0,0 +1,500 @@ +/* + * Copyright (C) 2008 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.browser; + +import android.app.Activity; +import android.content.Context; +import android.os.Handler; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.RadioButton; +import android.widget.TextView; + +import com.android.browser.GearsPermissions.OriginPermissions; +import com.android.browser.GearsPermissions.PermissionsChangesListener; +import com.android.browser.GearsPermissions.PermissionType; + +import java.util.Vector; +import java.util.List; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +/** + * Gears Settings dialog + */ +class GearsSettingsDialog extends GearsBaseDialog + implements PermissionsChangesListener { + + private static final String TAG = "GearsPermissionsDialog"; + private Vector<OriginPermissions> mSitesPermissions = null; + private Vector<OriginPermissions> mOriginalPermissions = null; + private Vector<OriginPermissions> mCurrentPermissions = null; + + private Vector<PermissionType> mPermissions; + + // We declare the permissions globally to simplify the code + private final PermissionType LOCAL_STORAGE = + new PermissionType(LOCAL_STORAGE_STRING); + private final PermissionType LOCATION_DATA = + new PermissionType(LOCATION_DATA_STRING); + + private boolean mChanges = false; + + + public GearsSettingsDialog(Activity activity, + Handler handler, + String arguments) { + super (activity, handler, arguments); + } + + public void setup() { + // First let's add the permissions' resources + LOCAL_STORAGE.setResources(R.id.local_storage_choice, + R.id.local_storage_allowed, + R.id.local_storage_denied); + + LOCATION_DATA.setResources(R.id.location_data_choice, + R.id.location_data_allowed, + R.id.location_data_denied); + + // add the permissions to the list of permissions. + mPermissions = new Vector<PermissionType>(); + mPermissions.add(LOCAL_STORAGE); + mPermissions.add(LOCATION_DATA); + OriginPermissions.setListener(this); + + + inflate(R.layout.gears_dialog_settings, R.id.panel_content); + setupDialog(); + setupButtons(0, + R.string.settings_button_allow, + R.string.settings_button_deny); + + // by default disable the allow button (it will get enabled if + // something is changed by the user) + View buttonView = findViewById(R.id.button_allow); + if (buttonView != null) { + Button button = (Button) buttonView; + button.setEnabled(false); + } + + View gearsVersionView = findViewById(R.id.gears_version); + if (gearsVersionView != null) { + TextView gearsVersion = (TextView) gearsVersionView; + gearsVersion.setText(mGearsVersion); + } + + // We manage the permissions using three vectors, mSitesPermissions, + // mOriginalPermissions and mCurrentPermissions. + // The dialog's arguments are parsed and a list of permissions is + // generated and stored in those three vectors. + // mOriginalPermissions is a separate copy and will not be modified; + // mSitesPermissions contains the current permissions _only_ -- + // if an origin is removed, it is also removed from mSitesPermissions. + // Finally, mCurrentPermissions contains the current permissions and + // is a clone of mSitesPermissions, but removed sites aren't removed, + // their permissions are simply set to PERMISSION_NOT_SET. This + // allows us to easily generate the final difference between the + // original permissions and the final permissions, while directly + // using mSitesPermissions for the listView adapter (SettingsAdapter). + + mSitesPermissions = new Vector<OriginPermissions>(); + mOriginalPermissions = new Vector<OriginPermissions>(); + + try { + JSONObject json = new JSONObject(mDialogArguments); + if (json.has("permissions")) { + JSONArray jsonArray = json.getJSONArray("permissions"); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject infos = jsonArray.getJSONObject(i); + String name = null; + int localStorage = PermissionType.PERMISSION_NOT_SET; + int locationData = PermissionType.PERMISSION_NOT_SET; + if (infos.has("name")) { + name = infos.getString("name"); + } + if (infos.has(LOCAL_STORAGE_STRING)) { + JSONObject perm = infos.getJSONObject(LOCAL_STORAGE_STRING); + if (perm.has("permissionState")) { + localStorage = perm.getInt("permissionState"); + } + } + if (infos.has(LOCATION_DATA_STRING)) { + JSONObject perm = infos.getJSONObject(LOCATION_DATA_STRING); + if (perm.has("permissionState")) { + locationData = perm.getInt("permissionState"); + } + } + OriginPermissions perms = new OriginPermissions(name); + perms.setPermission(LOCAL_STORAGE, localStorage); + perms.setPermission(LOCATION_DATA, locationData); + + mSitesPermissions.add(perms); + mOriginalPermissions.add(new OriginPermissions(perms)); + } + } + } catch (JSONException e) { + Log.e(TAG, "JSON exception ", e); + } + mCurrentPermissions = (Vector<OriginPermissions>)mSitesPermissions.clone(); + + View listView = findViewById(R.id.sites_list); + if (listView != null) { + ListView list = (ListView) listView; + list.setAdapter(new SettingsAdapter(mActivity, mSitesPermissions)); + } + if (mDebug) { + printPermissions(); + } + } + + public void setupDialog() { + View dialogTitleView = findViewById(R.id.dialog_title); + if (dialogTitleView != null) { + TextView dialogTitle = (TextView) dialogTitleView; + dialogTitle.setText(R.string.settings_title); + dialogTitle.setVisibility(View.VISIBLE); + } + View dialogSubtitleView = findViewById(R.id.dialog_subtitle); + if (dialogSubtitleView != null) { + TextView dialogSubtitle = (TextView) dialogSubtitleView; + dialogSubtitle.setText(R.string.settings_message); + dialogSubtitle.setVisibility(View.VISIBLE); + } + View iconView = findViewById(R.id.icon); + if (iconView != null) { + ImageView icon = (ImageView) iconView; + icon.setImageResource(R.drawable.gears_icon_32x32); + } + } + + /** + * GearsPermissions.PermissionsChangesListener delegate + */ + public boolean setPermission(PermissionType type, int perm) { + if (mChanges == false) { + signalChanges(); + } + return mChanges; + } + + /** + * Controller class for binding the model (OriginPermissions) with + * the UI. + */ + class PermissionController { + final static int ALLOWED_BUTTON = 1; + final static int DENIED_BUTTON = 2; + private int mButtonType; + private PermissionType mPermissionType; + private OriginPermissions mPermissions; + + PermissionController(PermissionType permissionType, int buttonType, + OriginPermissions permissions) { + mPermissionType = permissionType; + mButtonType = buttonType; + mPermissions = permissions; + } + + public boolean isChecked() { + boolean checked = false; + + switch (mButtonType) { + case ALLOWED_BUTTON: + if (mPermissions.getPermission(mPermissionType) == + PermissionType.PERMISSION_ALLOWED) { + checked = true; + } break; + case DENIED_BUTTON: + if (mPermissions.getPermission(mPermissionType) == + PermissionType.PERMISSION_DENIED) { + checked = true; + } + } + return checked; + } + + public String print() { + return printType() + " for " + mPermissions.getOrigin(); + } + + private String printType() { + switch (mButtonType) { + case ALLOWED_BUTTON: + return "ALLOWED_BUTTON"; + case DENIED_BUTTON: + return "DENIED_BUTTON"; + } + return "UNKNOWN BUTTON"; + } + + public void changed(boolean isChecked) { + if (isChecked == isChecked()) { + return; // already set + } + + switch (mButtonType) { + case ALLOWED_BUTTON: + mPermissions.setPermission(mPermissionType, + PermissionType.PERMISSION_ALLOWED); + break; + case DENIED_BUTTON: + mPermissions.setPermission(mPermissionType, + PermissionType.PERMISSION_DENIED); + break; + } + } + } + + + + /** + * Adapter class for the list view in the settings dialog + * + * Every row in the settings dialog display the permissions + * for a given origin. For every type of permission + * (location, local data...) there is two radio buttons to + * authorize or deny the permission. + * A remove button is also present to let the user remove + * all the authorization of an origin in one step. + */ + class SettingsAdapter extends ArrayAdapter { + private Activity mContext; + private List mItems; + + SettingsAdapter(Activity context, List items) { + super(context, R.layout.gears_dialog_settings_row, items); + mContext = context; + mItems = items; + } + + /* + * setup the necessary listeners for the radiobuttons + * When the buttons are clicked the permissions change. + */ + private void createAndSetButtonListener(View buttonView, + OriginPermissions perms, PermissionType permissionType, + int buttonType) { + if (buttonView == null) { + return; + } + RadioButton button = (RadioButton) buttonView; + + button.setOnCheckedChangeListener(null); + PermissionController p = new PermissionController(permissionType, + buttonType, perms); + button.setTag(p); + + CompoundButton.OnCheckedChangeListener listener = + new CompoundButton.OnCheckedChangeListener() { + public void onCheckedChanged(CompoundButton buttonView, + boolean isChecked) { + PermissionController perm = (PermissionController)buttonView.getTag(); + perm.changed(isChecked); + } + }; + + button.setOnCheckedChangeListener(listener); + + if (p.isChecked() != button.isChecked()) { + button.setChecked(p.isChecked()); + } + } + + /* + * setup the remove button for an origin: each row has a global + * remove button in addition to the radio buttons controlling the + * permissions. + */ + private void setRemoveButton(Button button, OriginPermissions perms) { + Button.OnClickListener listener = new Button.OnClickListener() { + public void onClick(View buttonView) { + if (mChanges == false) { + signalChanges(); + } + OriginPermissions perm = (OriginPermissions) buttonView.getTag(); + perm.setPermission(LOCAL_STORAGE, PermissionType.PERMISSION_NOT_SET); + perm.setPermission(LOCATION_DATA, PermissionType.PERMISSION_NOT_SET); + mSitesPermissions.remove(perm); + + View view = findViewById(R.id.sites_list); + if (view != null) { + ListView listView = (ListView) view; + ListAdapter listAdapter = listView.getAdapter(); + if (listAdapter != null) { + SettingsAdapter settingsAdapter = (SettingsAdapter) listAdapter; + settingsAdapter.notifyDataSetChanged(); + } + } + } + }; + button.setTag(perms); + button.setOnClickListener(listener); + } + + public View getView(int position, View convertView, ViewGroup parent) { + View row = convertView; + if (row == null) { // no cached view, we create one + LayoutInflater inflater = (LayoutInflater) getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + row = inflater.inflate(R.layout.gears_dialog_settings_row, null); + } + + OriginPermissions perms = (OriginPermissions) mItems.get(position); + + View nameView = row.findViewById(R.id.origin_name); + if (nameView != null) { + TextView originName = (TextView) nameView; + originName.setText(perms.getOrigin()); + } + + View removeButtonView = row.findViewById(R.id.origin_remove); + if (removeButtonView != null) { + Button removeButton = (Button) removeButtonView; + setRemoveButton(removeButton, perms); + } + + for (int i = 0; i < mPermissions.size(); i++) { + PermissionType type = mPermissions.get(i); + int rowRsc = type.getRowRsc(); + int allowedButtonRsc = type.getAllowedButtonRsc(); + int deniedButtonRsc = type.getDeniedButtonRsc(); + + View rowView = row.findViewById(rowRsc); + if (rowView != null) { + int perm = perms.getPermission(type); + if (perm != PermissionType.PERMISSION_NOT_SET) { + createAndSetButtonListener(row.findViewById(allowedButtonRsc), + perms, type, PermissionController.ALLOWED_BUTTON); + createAndSetButtonListener(row.findViewById(deniedButtonRsc), + perms, type, PermissionController.DENIED_BUTTON); + rowView.setVisibility(View.VISIBLE); + } else { + rowView.setVisibility(View.GONE); + } + } + } + + return row; + } + } + + /** + * Utility method used in debug mode to print the list of + * permissions (original values and current values). + */ + public void printPermissions() { + Log.v(TAG, "Original Permissions: "); + for (int i = 0; i < mOriginalPermissions.size(); i++) { + OriginPermissions p = mOriginalPermissions.get(i); + p.print(); + } + Log.v(TAG, "Current Permissions: "); + for (int i = 0; i < mSitesPermissions.size(); i++) { + OriginPermissions p = mSitesPermissions.get(i); + p.print(); + } + } + + /** + * Utility method used by the settings dialog, signaling + * the user the settings have been modified. + * We reflect this by enabling the Allow button (disabled + * by default). + */ + public void signalChanges() { + View view = findViewById(R.id.button_allow); + if (view != null) { + Button button = (Button) view; + button.setEnabled(true); + } + mChanges = true; + } + + /** + * Computes the difference between the original permissions and the + * current ones. Returns a json-formatted string. + * It is used by the Settings dialog. + */ + public String computeDiff(boolean modif) { + String ret = null; + try { + JSONObject results = new JSONObject(); + JSONArray permissions = new JSONArray(); + + for (int i = 0; modif && i < mOriginalPermissions.size(); i++) { + OriginPermissions original = mOriginalPermissions.get(i); + OriginPermissions current = mCurrentPermissions.get(i); + JSONObject permission = new JSONObject(); + boolean modifications = false; + + for (int j = 0; j < mPermissions.size(); j++) { + PermissionType type = mPermissions.get(j); + + if (current.getPermission(type) != original.getPermission(type)) { + JSONObject state = new JSONObject(); + state.put("permissionState", current.getPermission(type)); + permission.put(type.getName(), state); + modifications = true; + } + } + + if (modifications) { + permission.put("name", current.getOrigin()); + permissions.put(permission); + } + } + results.put("modifiedOrigins", permissions); + ret = results.toString(); + } catch (JSONException e) { + Log.e(TAG, "JSON exception ", e); + } + return ret; + } + + public String closeDialog(int closingType) { + String ret = null; + switch (closingType) { + case ALWAYS_DENY: + ret = "{\"allow\": false }"; + break; + case ALLOW: + ret = computeDiff(true); + break; + case DENY: + ret = computeDiff(false); + break; + } + + if (mDebug) { + printPermissions(); + } + + return ret; + } + +} |
