Home | History | Annotate | Download | only in browser
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.browser;
     18 
     19 import android.app.AlertDialog;
     20 import android.app.ListActivity;
     21 import android.content.Context;
     22 import android.content.DialogInterface;
     23 import android.database.Cursor;
     24 import android.graphics.Bitmap;
     25 import android.graphics.BitmapFactory;
     26 import android.net.Uri;
     27 import android.os.Bundle;
     28 import android.provider.Browser;
     29 import android.util.Log;
     30 import android.view.KeyEvent;
     31 import android.view.LayoutInflater;
     32 import android.view.Menu;
     33 import android.view.MenuInflater;
     34 import android.view.MenuItem;
     35 import android.view.View;
     36 import android.view.ViewGroup;
     37 import android.webkit.GeolocationPermissions;
     38 import android.webkit.ValueCallback;
     39 import android.webkit.WebIconDatabase;
     40 import android.webkit.WebStorage;
     41 import android.widget.ArrayAdapter;
     42 import android.widget.AdapterView;
     43 import android.widget.AdapterView.OnItemClickListener;
     44 import android.widget.ImageView;
     45 import android.widget.TextView;
     46 
     47 import java.util.HashMap;
     48 import java.util.HashSet;
     49 import java.util.Iterator;
     50 import java.util.Map;
     51 import java.util.Set;
     52 import java.util.Vector;
     53 
     54 /**
     55  * Manage the settings for an origin.
     56  * We use it to keep track of the 'HTML5' settings, i.e. database (webstorage)
     57  * and Geolocation.
     58  */
     59 public class WebsiteSettingsActivity extends ListActivity {
     60 
     61     private String LOGTAG = "WebsiteSettingsActivity";
     62     private static String sMBStored = null;
     63     private SiteAdapter mAdapter = null;
     64 
     65     class Site {
     66         private String mOrigin;
     67         private String mTitle;
     68         private Bitmap mIcon;
     69         private int mFeatures;
     70 
     71         // These constants provide the set of features that a site may support
     72         // They must be consecutive. To add a new feature, add a new FEATURE_XXX
     73         // variable with value equal to the current value of FEATURE_COUNT, then
     74         // increment FEATURE_COUNT.
     75         private final static int FEATURE_WEB_STORAGE = 0;
     76         private final static int FEATURE_GEOLOCATION = 1;
     77         // The number of features available.
     78         private final static int FEATURE_COUNT = 2;
     79 
     80         public Site(String origin) {
     81             mOrigin = origin;
     82             mTitle = null;
     83             mIcon = null;
     84             mFeatures = 0;
     85         }
     86 
     87         public void addFeature(int feature) {
     88             mFeatures |= (1 << feature);
     89         }
     90 
     91         public void removeFeature(int feature) {
     92             mFeatures &= ~(1 << feature);
     93         }
     94 
     95         public boolean hasFeature(int feature) {
     96             return (mFeatures & (1 << feature)) != 0;
     97         }
     98 
     99         /**
    100          * Gets the number of features supported by this site.
    101          */
    102         public int getFeatureCount() {
    103             int count = 0;
    104             for (int i = 0; i < FEATURE_COUNT; ++i) {
    105                 count += hasFeature(i) ? 1 : 0;
    106             }
    107             return count;
    108         }
    109 
    110         /**
    111          * Gets the ID of the nth (zero-based) feature supported by this site.
    112          * The return value is a feature ID - one of the FEATURE_XXX values.
    113          * This is required to determine which feature is displayed at a given
    114          * position in the list of features for this site. This is used both
    115          * when populating the view and when responding to clicks on the list.
    116          */
    117         public int getFeatureByIndex(int n) {
    118             int j = -1;
    119             for (int i = 0; i < FEATURE_COUNT; ++i) {
    120                 j += hasFeature(i) ? 1 : 0;
    121                 if (j == n) {
    122                     return i;
    123                 }
    124             }
    125             return -1;
    126         }
    127 
    128         public String getOrigin() {
    129             return mOrigin;
    130         }
    131 
    132         public void setTitle(String title) {
    133             mTitle = title;
    134         }
    135 
    136         public void setIcon(Bitmap icon) {
    137             mIcon = icon;
    138         }
    139 
    140         public Bitmap getIcon() {
    141             return mIcon;
    142         }
    143 
    144         public String getPrettyOrigin() {
    145             return mTitle == null ? null : hideHttp(mOrigin);
    146         }
    147 
    148         public String getPrettyTitle() {
    149             return mTitle == null ? hideHttp(mOrigin) : mTitle;
    150         }
    151 
    152         private String hideHttp(String str) {
    153             Uri uri = Uri.parse(str);
    154             return "http".equals(uri.getScheme()) ?  str.substring(7) : str;
    155         }
    156     }
    157 
    158     class SiteAdapter extends ArrayAdapter<Site>
    159             implements AdapterView.OnItemClickListener {
    160         private int mResource;
    161         private LayoutInflater mInflater;
    162         private Bitmap mDefaultIcon;
    163         private Bitmap mUsageEmptyIcon;
    164         private Bitmap mUsageLowIcon;
    165         private Bitmap mUsageHighIcon;
    166         private Bitmap mLocationAllowedIcon;
    167         private Bitmap mLocationDisallowedIcon;
    168         private Site mCurrentSite;
    169 
    170         public SiteAdapter(Context context, int rsc) {
    171             super(context, rsc);
    172             mResource = rsc;
    173             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    174             mDefaultIcon = BitmapFactory.decodeResource(getResources(),
    175                     R.drawable.app_web_browser_sm);
    176             mUsageEmptyIcon = BitmapFactory.decodeResource(getResources(),
    177                     R.drawable.ic_list_data_off);
    178             mUsageLowIcon = BitmapFactory.decodeResource(getResources(),
    179                     R.drawable.ic_list_data_small);
    180             mUsageHighIcon = BitmapFactory.decodeResource(getResources(),
    181                     R.drawable.ic_list_data_large);
    182             mLocationAllowedIcon = BitmapFactory.decodeResource(getResources(),
    183                     R.drawable.ic_list_gps_on);
    184             mLocationDisallowedIcon = BitmapFactory.decodeResource(getResources(),
    185                     R.drawable.ic_list_gps_denied);
    186             askForOrigins();
    187         }
    188 
    189         /**
    190          * Adds the specified feature to the site corresponding to supplied
    191          * origin in the map. Creates the site if it does not already exist.
    192          */
    193         private void addFeatureToSite(Map sites, String origin, int feature) {
    194             Site site = null;
    195             if (sites.containsKey(origin)) {
    196                 site = (Site) sites.get(origin);
    197             } else {
    198                 site = new Site(origin);
    199                 sites.put(origin, site);
    200             }
    201             site.addFeature(feature);
    202         }
    203 
    204         public void askForOrigins() {
    205             // Get the list of origins we want to display.
    206             // All 'HTML 5 modules' (Database, Geolocation etc) form these
    207             // origin strings using WebCore::SecurityOrigin::toString(), so it's
    208             // safe to group origins here. Note that WebCore::SecurityOrigin
    209             // uses 0 (which is not printed) for the port if the port is the
    210             // default for the protocol. Eg http://www.google.com and
    211             // http://www.google.com:80 both record a port of 0 and hence
    212             // toString() == 'http://www.google.com' for both.
    213 
    214             WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
    215                 public void onReceiveValue(Map origins) {
    216                     Map sites = new HashMap<String, Site>();
    217                     if (origins != null) {
    218                         Iterator<String> iter = origins.keySet().iterator();
    219                         while (iter.hasNext()) {
    220                             addFeatureToSite(sites, iter.next(), Site.FEATURE_WEB_STORAGE);
    221                         }
    222                     }
    223                     askForGeolocation(sites);
    224                 }
    225             });
    226         }
    227 
    228         public void askForGeolocation(final Map sites) {
    229             GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set<String> >() {
    230                 public void onReceiveValue(Set<String> origins) {
    231                     if (origins != null) {
    232                         Iterator<String> iter = origins.iterator();
    233                         while (iter.hasNext()) {
    234                             addFeatureToSite(sites, iter.next(), Site.FEATURE_GEOLOCATION);
    235                         }
    236                     }
    237                     populateIcons(sites);
    238                     populateOrigins(sites);
    239                 }
    240             });
    241         }
    242 
    243         public void populateIcons(Map sites) {
    244             // Create a map from host to origin. This is used to add metadata
    245             // (title, icon) for this origin from the bookmarks DB.
    246             HashMap hosts = new HashMap<String, Set<Site> >();
    247             Set keys = sites.keySet();
    248             Iterator<String> originIter = keys.iterator();
    249             while (originIter.hasNext()) {
    250                 String origin = originIter.next();
    251                 Site site = (Site) sites.get(origin);
    252                 String host = Uri.parse(origin).getHost();
    253                 Set hostSites = null;
    254                 if (hosts.containsKey(host)) {
    255                     hostSites = (Set) hosts.get(host);
    256                 } else {
    257                     hostSites = new HashSet<Site>();
    258                     hosts.put(host, hostSites);
    259                 }
    260                 hostSites.add(site);
    261             }
    262 
    263             // Check the bookmark DB. If we have data for a host used by any of
    264             // our origins, use it to set their title and favicon
    265             Cursor c = getContext().getContentResolver().query(Browser.BOOKMARKS_URI,
    266                     new String[] { Browser.BookmarkColumns.URL, Browser.BookmarkColumns.TITLE,
    267                     Browser.BookmarkColumns.FAVICON }, "bookmark = 1", null, null);
    268 
    269             if ((c != null) && c.moveToFirst()) {
    270                 int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
    271                 int titleIndex = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
    272                 int faviconIndex = c.getColumnIndex(Browser.BookmarkColumns.FAVICON);
    273                 do {
    274                     String url = c.getString(urlIndex);
    275                     String host = Uri.parse(url).getHost();
    276                     if (hosts.containsKey(host)) {
    277                         String title = c.getString(titleIndex);
    278                         Bitmap bmp = null;
    279                         byte[] data = c.getBlob(faviconIndex);
    280                         if (data != null) {
    281                             bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
    282                         }
    283                         Set matchingSites = (Set) hosts.get(host);
    284                         Iterator<Site> sitesIter = matchingSites.iterator();
    285                         while (sitesIter.hasNext()) {
    286                             Site site = sitesIter.next();
    287                             // We should only set the title if the bookmark is for the root
    288                             // (i.e. www.google.com), as website settings act on the origin
    289                             // as a whole rather than a single page under that origin. If the
    290                             // user has bookmarked a page under the root but *not* the root,
    291                             // then we risk displaying the title of that page which may or
    292                             // may not have any relevance to the origin.
    293                             if (url.equals(site.getOrigin()) ||
    294                                     (new String(site.getOrigin()+"/")).equals(url)) {
    295                                 site.setTitle(title);
    296                             }
    297                             if (bmp != null) {
    298                                 site.setIcon(bmp);
    299                             }
    300                         }
    301                     }
    302                 } while (c.moveToNext());
    303             }
    304 
    305             c.close();
    306         }
    307 
    308 
    309         public void populateOrigins(Map sites) {
    310             clear();
    311 
    312             // We can now simply populate our array with Site instances
    313             Set keys = sites.keySet();
    314             Iterator<String> originIter = keys.iterator();
    315             while (originIter.hasNext()) {
    316                 String origin = originIter.next();
    317                 Site site = (Site) sites.get(origin);
    318                 add(site);
    319             }
    320 
    321             notifyDataSetChanged();
    322 
    323             if (getCount() == 0) {
    324                 finish(); // we close the screen
    325             }
    326         }
    327 
    328         public int getCount() {
    329             if (mCurrentSite == null) {
    330                 return super.getCount();
    331             }
    332             return mCurrentSite.getFeatureCount();
    333         }
    334 
    335         public String sizeValueToString(long bytes) {
    336             // We display the size in MB, to 1dp, rounding up to the next 0.1MB.
    337             // bytes should always be greater than zero.
    338             if (bytes <= 0) {
    339                 Log.e(LOGTAG, "sizeValueToString called with non-positive value: " + bytes);
    340                 return "0";
    341             }
    342             float megabytes = (float) bytes / (1024.0F * 1024.0F);
    343             int truncated = (int) Math.ceil(megabytes * 10.0F);
    344             float result = (float) (truncated / 10.0F);
    345             return String.valueOf(result);
    346         }
    347 
    348         /*
    349          * If we receive the back event and are displaying
    350          * site's settings, we want to go back to the main
    351          * list view. If not, we just do nothing (see
    352          * dispatchKeyEvent() below).
    353          */
    354         public boolean backKeyPressed() {
    355             if (mCurrentSite != null) {
    356                 mCurrentSite = null;
    357                 askForOrigins();
    358                 return true;
    359             }
    360             return false;
    361         }
    362 
    363         /**
    364          * @hide
    365          * Utility function
    366          * Set the icon according to the usage
    367          */
    368         public void setIconForUsage(ImageView usageIcon, long usageInBytes) {
    369             float usageInMegabytes = (float) usageInBytes / (1024.0F * 1024.0F);
    370             // We set the correct icon:
    371             // 0 < empty < 0.1MB
    372             // 0.1MB < low < 5MB
    373             // 5MB < high
    374             if (usageInMegabytes <= 0.1) {
    375                 usageIcon.setImageBitmap(mUsageEmptyIcon);
    376             } else if (usageInMegabytes > 0.1 && usageInMegabytes <= 5) {
    377                 usageIcon.setImageBitmap(mUsageLowIcon);
    378             } else if (usageInMegabytes > 5) {
    379                 usageIcon.setImageBitmap(mUsageHighIcon);
    380             }
    381         }
    382 
    383         public View getView(int position, View convertView, ViewGroup parent) {
    384             View view;
    385             final TextView title;
    386             final TextView subtitle;
    387             final ImageView icon;
    388             final ImageView usageIcon;
    389             final ImageView locationIcon;
    390             final ImageView featureIcon;
    391 
    392             if (convertView == null) {
    393                 view = mInflater.inflate(mResource, parent, false);
    394             } else {
    395                 view = convertView;
    396             }
    397 
    398             title = (TextView) view.findViewById(R.id.title);
    399             subtitle = (TextView) view.findViewById(R.id.subtitle);
    400             icon = (ImageView) view.findViewById(R.id.icon);
    401             featureIcon = (ImageView) view.findViewById(R.id.feature_icon);
    402             usageIcon = (ImageView) view.findViewById(R.id.usage_icon);
    403             locationIcon = (ImageView) view.findViewById(R.id.location_icon);
    404             usageIcon.setVisibility(View.GONE);
    405             locationIcon.setVisibility(View.GONE);
    406 
    407             if (mCurrentSite == null) {
    408                 setTitle(getString(R.string.pref_extras_website_settings));
    409 
    410                 Site site = getItem(position);
    411                 title.setText(site.getPrettyTitle());
    412                 String subtitleText = site.getPrettyOrigin();
    413                 if (subtitleText != null) {
    414                     title.setMaxLines(1);
    415                     title.setSingleLine(true);
    416                     subtitle.setVisibility(View.VISIBLE);
    417                     subtitle.setText(subtitleText);
    418                 } else {
    419                     subtitle.setVisibility(View.GONE);
    420                     title.setMaxLines(2);
    421                     title.setSingleLine(false);
    422                 }
    423 
    424                 icon.setVisibility(View.VISIBLE);
    425                 usageIcon.setVisibility(View.INVISIBLE);
    426                 locationIcon.setVisibility(View.INVISIBLE);
    427                 featureIcon.setVisibility(View.GONE);
    428                 Bitmap bmp = site.getIcon();
    429                 if (bmp == null) {
    430                     bmp = mDefaultIcon;
    431                 }
    432                 icon.setImageBitmap(bmp);
    433                 // We set the site as the view's tag,
    434                 // so that we can get it in onItemClick()
    435                 view.setTag(site);
    436 
    437                 String origin = site.getOrigin();
    438                 if (site.hasFeature(Site.FEATURE_WEB_STORAGE)) {
    439                     WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() {
    440                         public void onReceiveValue(Long value) {
    441                             if (value != null) {
    442                                 setIconForUsage(usageIcon, value.longValue());
    443                                 usageIcon.setVisibility(View.VISIBLE);
    444                             }
    445                         }
    446                     });
    447                 }
    448 
    449                 if (site.hasFeature(Site.FEATURE_GEOLOCATION)) {
    450                     locationIcon.setVisibility(View.VISIBLE);
    451                     GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() {
    452                         public void onReceiveValue(Boolean allowed) {
    453                             if (allowed != null) {
    454                                 if (allowed.booleanValue()) {
    455                                     locationIcon.setImageBitmap(mLocationAllowedIcon);
    456                                 } else {
    457                                     locationIcon.setImageBitmap(mLocationDisallowedIcon);
    458                                 }
    459                             }
    460                         }
    461                     });
    462                 }
    463             } else {
    464                 icon.setVisibility(View.GONE);
    465                 locationIcon.setVisibility(View.GONE);
    466                 usageIcon.setVisibility(View.GONE);
    467                 featureIcon.setVisibility(View.VISIBLE);
    468                 setTitle(mCurrentSite.getPrettyTitle());
    469                 String origin = mCurrentSite.getOrigin();
    470                 switch (mCurrentSite.getFeatureByIndex(position)) {
    471                     case Site.FEATURE_WEB_STORAGE:
    472                         WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() {
    473                             public void onReceiveValue(Long value) {
    474                                 if (value != null) {
    475                                     String usage = sizeValueToString(value.longValue()) + " " + sMBStored;
    476                                     title.setText(R.string.webstorage_clear_data_title);
    477                                     subtitle.setText(usage);
    478                                     subtitle.setVisibility(View.VISIBLE);
    479                                     setIconForUsage(featureIcon, value.longValue());
    480                                 }
    481                             }
    482                         });
    483                         break;
    484                     case Site.FEATURE_GEOLOCATION:
    485                         title.setText(R.string.geolocation_settings_page_title);
    486                         GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() {
    487                             public void onReceiveValue(Boolean allowed) {
    488                                 if (allowed != null) {
    489                                     if (allowed.booleanValue()) {
    490                                         subtitle.setText(R.string.geolocation_settings_page_summary_allowed);
    491                                         featureIcon.setImageBitmap(mLocationAllowedIcon);
    492                                     } else {
    493                                         subtitle.setText(R.string.geolocation_settings_page_summary_not_allowed);
    494                                         featureIcon.setImageBitmap(mLocationDisallowedIcon);
    495                                     }
    496                                     subtitle.setVisibility(View.VISIBLE);
    497                                 }
    498                             }
    499                         });
    500                         break;
    501                 }
    502             }
    503 
    504             return view;
    505         }
    506 
    507         public void onItemClick(AdapterView<?> parent,
    508                                 View view,
    509                                 int position,
    510                                 long id) {
    511             if (mCurrentSite != null) {
    512                 switch (mCurrentSite.getFeatureByIndex(position)) {
    513                     case Site.FEATURE_WEB_STORAGE:
    514                         new AlertDialog.Builder(getContext())
    515                             .setTitle(R.string.webstorage_clear_data_dialog_title)
    516                             .setMessage(R.string.webstorage_clear_data_dialog_message)
    517                             .setPositiveButton(R.string.webstorage_clear_data_dialog_ok_button,
    518                                                new AlertDialog.OnClickListener() {
    519                                 public void onClick(DialogInterface dlg, int which) {
    520                                     WebStorage.getInstance().deleteOrigin(mCurrentSite.getOrigin());
    521                                     // If this site has no more features, then go back to the
    522                                     // origins list.
    523                                     mCurrentSite.removeFeature(Site.FEATURE_WEB_STORAGE);
    524                                     if (mCurrentSite.getFeatureCount() == 0) {
    525                                         mCurrentSite = null;
    526                                     }
    527                                     askForOrigins();
    528                                     notifyDataSetChanged();
    529                                 }})
    530                             .setNegativeButton(R.string.webstorage_clear_data_dialog_cancel_button, null)
    531                             .setIcon(android.R.drawable.ic_dialog_alert)
    532                             .show();
    533                         break;
    534                     case Site.FEATURE_GEOLOCATION:
    535                         new AlertDialog.Builder(getContext())
    536                             .setTitle(R.string.geolocation_settings_page_dialog_title)
    537                             .setMessage(R.string.geolocation_settings_page_dialog_message)
    538                             .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
    539                                                new AlertDialog.OnClickListener() {
    540                                 public void onClick(DialogInterface dlg, int which) {
    541                                     GeolocationPermissions.getInstance().clear(mCurrentSite.getOrigin());
    542                                     mCurrentSite.removeFeature(Site.FEATURE_GEOLOCATION);
    543                                     if (mCurrentSite.getFeatureCount() == 0) {
    544                                         mCurrentSite = null;
    545                                     }
    546                                     askForOrigins();
    547                                     notifyDataSetChanged();
    548                                 }})
    549                             .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null)
    550                             .setIcon(android.R.drawable.ic_dialog_alert)
    551                             .show();
    552                         break;
    553                 }
    554             } else {
    555                 mCurrentSite = (Site) view.getTag();
    556                 notifyDataSetChanged();
    557             }
    558         }
    559 
    560         public Site currentSite() {
    561             return mCurrentSite;
    562         }
    563     }
    564 
    565     /**
    566      * Intercepts the back key to immediately notify
    567      * NativeDialog that we are done.
    568      */
    569     public boolean dispatchKeyEvent(KeyEvent event) {
    570         if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
    571             && (event.getAction() == KeyEvent.ACTION_DOWN)) {
    572             if ((mAdapter != null) && (mAdapter.backKeyPressed())){
    573                 return true; // event consumed
    574             }
    575         }
    576         return super.dispatchKeyEvent(event);
    577     }
    578 
    579     @Override
    580     protected void onCreate(Bundle icicle) {
    581         super.onCreate(icicle);
    582         if (sMBStored == null) {
    583             sMBStored = getString(R.string.webstorage_origin_summary_mb_stored);
    584         }
    585         mAdapter = new SiteAdapter(this, R.layout.website_settings_row);
    586         setListAdapter(mAdapter);
    587         getListView().setOnItemClickListener(mAdapter);
    588     }
    589 
    590     @Override
    591     public boolean onCreateOptionsMenu(Menu menu) {
    592         MenuInflater inflater = getMenuInflater();
    593         inflater.inflate(R.menu.websitesettings, menu);
    594         return true;
    595     }
    596 
    597     @Override
    598     public boolean onPrepareOptionsMenu(Menu menu) {
    599         // If we are not on the sites list (rather on the page for a specific site) or
    600         // we aren't listing any sites hide the clear all button (and hence the menu).
    601         return  mAdapter.currentSite() == null && mAdapter.getCount() > 0;
    602     }
    603 
    604     @Override
    605     public boolean onOptionsItemSelected(MenuItem item) {
    606         switch (item.getItemId()) {
    607             case R.id.website_settings_menu_clear_all:
    608                 // Show the prompt to clear all origins of their data and geolocation permissions.
    609                 new AlertDialog.Builder(this)
    610                         .setTitle(R.string.website_settings_clear_all_dialog_title)
    611                         .setMessage(R.string.website_settings_clear_all_dialog_message)
    612                         .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button,
    613                                 new AlertDialog.OnClickListener() {
    614                                     public void onClick(DialogInterface dlg, int which) {
    615                                         WebStorage.getInstance().deleteAllData();
    616                                         GeolocationPermissions.getInstance().clearAll();
    617                                         WebStorageSizeManager.resetLastOutOfSpaceNotificationTime();
    618                                         mAdapter.askForOrigins();
    619                                         finish();
    620                                     }})
    621                         .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, null)
    622                         .setIcon(android.R.drawable.ic_dialog_alert)
    623                         .show();
    624                 return true;
    625         }
    626         return false;
    627     }
    628 }
    629