WebsiteSettingsFragment.java revision 99b3ae1a384981f96fca5432f3d20bf4e8d13667
1e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard/*
2e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * Copyright (C) 2009 The Android Open Source Project
3e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard *
4e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * Licensed under the Apache License, Version 2.0 (the "License");
5e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * you may not use this file except in compliance with the License.
6e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * You may obtain a copy of the License at
7e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard *
8e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard *      http://www.apache.org/licenses/LICENSE-2.0
9e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard *
10e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * Unless required by applicable law or agreed to in writing, software
11e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * distributed under the License is distributed on an "AS IS" BASIS,
12e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * See the License for the specific language governing permissions and
14e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * limitations under the License.
15e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard */
16e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
17e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardpackage com.android.browser;
18e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
19e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.app.AlertDialog;
20e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.app.ListActivity;
21e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.content.Context;
22e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.content.DialogInterface;
23e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.database.Cursor;
24e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.graphics.Bitmap;
25e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.graphics.BitmapFactory;
26e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.net.Uri;
27e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.os.Bundle;
28e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.provider.Browser;
29e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.util.Log;
30e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.view.KeyEvent;
31e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.view.LayoutInflater;
32b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdochimport android.view.Menu;
33b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdochimport android.view.MenuInflater;
34b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdochimport android.view.MenuItem;
35e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.view.View;
36e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.view.ViewGroup;
37f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Blockimport android.webkit.GeolocationPermissions;
3899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roardimport android.webkit.ValueCallback;
39e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.webkit.WebIconDatabase;
40e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.webkit.WebStorage;
41e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.widget.ArrayAdapter;
42e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.widget.AdapterView;
43e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.widget.AdapterView.OnItemClickListener;
44e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.widget.ImageView;
45e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport android.widget.TextView;
46e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
47e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport java.util.HashMap;
48ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Blockimport java.util.HashSet;
49e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport java.util.Iterator;
50089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Blockimport java.util.Map;
51e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport java.util.Set;
52e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardimport java.util.Vector;
53e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
54e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard/**
55e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard * Manage the settings for an origin.
56089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block * We use it to keep track of the 'HTML5' settings, i.e. database (webstorage)
57089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block * and Geolocation.
58e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard */
59e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roardpublic class WebsiteSettingsActivity extends ListActivity {
60e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
61e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    private String LOGTAG = "WebsiteSettingsActivity";
62e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    private static String sMBStored = null;
63e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    private SiteAdapter mAdapter = null;
64e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
65e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    class Site {
66e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private String mOrigin;
67e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private String mTitle;
68e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private Bitmap mIcon;
69089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        private int mFeatures;
70089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
71089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        // These constants provide the set of features that a site may support
72089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        // They must be consecutive. To add a new feature, add a new FEATURE_XXX
73089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        // variable with value equal to the current value of FEATURE_COUNT, then
74089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        // increment FEATURE_COUNT.
75089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        private final static int FEATURE_WEB_STORAGE = 0;
76f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block        private final static int FEATURE_GEOLOCATION = 1;
77089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        // The number of features available.
78f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block        private final static int FEATURE_COUNT = 2;
79e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
801ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        public Site(String origin) {
81e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mOrigin = origin;
821ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            mTitle = null;
831ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            mIcon = null;
84089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            mFeatures = 0;
85089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        }
86089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
87089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        public void addFeature(int feature) {
88089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            mFeatures |= (1 << feature);
89089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        }
90089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
91089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        public boolean hasFeature(int feature) {
92089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            return (mFeatures & (1 << feature)) != 0;
93089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        }
94089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
95089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        /**
96089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * Gets the number of features supported by this site.
97089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         */
98089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        public int getFeatureCount() {
99089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            int count = 0;
100089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            for (int i = 0; i < FEATURE_COUNT; ++i) {
101089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                count += hasFeature(i) ? 1 : 0;
102089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            }
103089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            return count;
104089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        }
105089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
106089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        /**
107089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * Gets the ID of the nth (zero-based) feature supported by this site.
108089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * The return value is a feature ID - one of the FEATURE_XXX values.
109089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * This is required to determine which feature is displayed at a given
110089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * position in the list of features for this site. This is used both
111f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block         * when populating the view and when responding to clicks on the list.
112089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         */
113089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        public int getFeatureByIndex(int n) {
114089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            int j = -1;
115089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            for (int i = 0; i < FEATURE_COUNT; ++i) {
116089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                j += hasFeature(i) ? 1 : 0;
117089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                if (j == n) {
118089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                    return i;
119089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                }
120089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            }
121089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            return -1;
122e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
123e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
124e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public String getOrigin() {
125e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            return mOrigin;
126e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
127e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
128e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public void setTitle(String title) {
129e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mTitle = title;
130e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
131e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
132e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public void setIcon(Bitmap icon) {
133e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mIcon = icon;
134e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
135e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
136e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public Bitmap getIcon() {
137e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            return mIcon;
138e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
1391ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block
1401ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        public String getPrettyOrigin() {
1411ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            return mTitle == null ? null : hideHttp(mOrigin);
1421ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        }
1431ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block
1441ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        public String getPrettyTitle() {
1451ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            return mTitle == null ? hideHttp(mOrigin) : mTitle;
1461ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        }
1471ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block
1481ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        private String hideHttp(String str) {
1491ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            Uri uri = Uri.parse(str);
1501ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block            return "http".equals(uri.getScheme()) ?  str.substring(7) : str;
1511ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block        }
152e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    }
153e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
154e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    class SiteAdapter extends ArrayAdapter<Site>
155e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            implements AdapterView.OnItemClickListener {
156e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private int mResource;
157e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private LayoutInflater mInflater;
158e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private Bitmap mDefaultIcon;
159c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        private Bitmap mUsageEmptyIcon;
160c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        private Bitmap mUsageLowIcon;
161c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        private Bitmap mUsageMediumIcon;
162c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        private Bitmap mUsageHighIcon;
163c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        private Bitmap mLocationIcon;
164e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        private Site mCurrentSite;
165e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
166e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public SiteAdapter(Context context, int rsc) {
167e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            super(context, rsc);
168e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mResource = rsc;
169e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
170e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            mDefaultIcon = BitmapFactory.decodeResource(getResources(),
171e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    R.drawable.ic_launcher_shortcut_browser_bookmark);
172c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            mUsageEmptyIcon = BitmapFactory.decodeResource(getResources(),
173c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                    R.drawable.usage_empty);
174c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            mUsageLowIcon = BitmapFactory.decodeResource(getResources(),
175c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                    R.drawable.usage_low);
176c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            mUsageMediumIcon = BitmapFactory.decodeResource(getResources(),
177c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                    R.drawable.usage_medium);
178c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            mUsageHighIcon = BitmapFactory.decodeResource(getResources(),
179c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                    R.drawable.usage_high);
180c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            mLocationIcon = BitmapFactory.decodeResource(getResources(),
181c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                    R.drawable.location);
18299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            askForOrigins();
183e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
184e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
185089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        /**
186089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * Adds the specified feature to the site corresponding to supplied
187089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         * origin in the map. Creates the site if it does not already exist.
188089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block         */
189089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        private void addFeatureToSite(Map sites, String origin, int feature) {
190089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            Site site = null;
191089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            if (sites.containsKey(origin)) {
192089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                site = (Site) sites.get(origin);
193089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            } else {
194089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                site = new Site(origin);
195089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                sites.put(origin, site);
196089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            }
197089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            site.addFeature(feature);
198089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block        }
199089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block
20099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        public void askForOrigins() {
201089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // Get the list of origins we want to display.
202089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // All 'HTML 5 modules' (Database, Geolocation etc) form these
203089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // origin strings using WebCore::SecurityOrigin::toString(), so it's
204089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // safe to group origins here. Note that WebCore::SecurityOrigin
205089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // uses 0 (which is not printed) for the port if the port is the
206089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // default for the protocol. Eg http://www.google.com and
207089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // http://www.google.com:80 both record a port of 0 and hence
208089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            // toString() == 'http://www.google.com' for both.
20999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
21099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            WebStorage.getInstance().getOrigins(new ValueCallback<Map>() {
21199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                public void onReceiveValue(Map origins) {
21299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    Map sites = new HashMap<String, Site>();
21399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    if (origins != null) {
21499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        Iterator<String> iter = origins.keySet().iterator();
21599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        while (iter.hasNext()) {
21699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            addFeatureToSite(sites, iter.next(), Site.FEATURE_WEB_STORAGE);
21799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        }
21899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    }
21999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    askForGeolocation(sites);
220e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                }
22199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            });
22299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        }
22399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
22499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        public void askForGeolocation(final Map sites) {
22599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            GeolocationPermissions.getInstance().getOrigins(new ValueCallback<Set>() {
22699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                public void onReceiveValue(Set origins) {
22799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    if (origins != null) {
22899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        Iterator<String> iter = origins.iterator();
22999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        while (iter.hasNext()) {
23099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            addFeatureToSite(sites, iter.next(), Site.FEATURE_GEOLOCATION);
23199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        }
23299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    }
23399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    populateIcons(sites);
23499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                    populateOrigins(sites);
235f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                }
23699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            });
23799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        }
238e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
23999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        public void populateIcons(Map sites) {
240ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            // Create a map from host to origin. This is used to add metadata
241ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            // (title, icon) for this origin from the bookmarks DB.
242ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            HashMap hosts = new HashMap<String, Set<Site> >();
243089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            Set keys = sites.keySet();
244089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            Iterator<String> originIter = keys.iterator();
245089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            while (originIter.hasNext()) {
246089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                String origin = originIter.next();
247089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                Site site = (Site) sites.get(origin);
248089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                String host = Uri.parse(origin).getHost();
249ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                Set hostSites = null;
250ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                if (hosts.containsKey(host)) {
251ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                    hostSites = (Set) hosts.get(host);
252ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                } else {
253ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                    hostSites = new HashSet<Site>();
254ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                    hosts.put(host, hostSites);
255ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                }
256ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                hostSites.add(site);
257ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            }
258ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block
259ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            // Check the bookmark DB. If we have data for a host used by any of
260ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block            // our origins, use it to set their title and favicon
261e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            Cursor c = getContext().getContentResolver().query(Browser.BOOKMARKS_URI,
262e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    new String[] { Browser.BookmarkColumns.URL, Browser.BookmarkColumns.TITLE,
263e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    Browser.BookmarkColumns.FAVICON }, "bookmark = 1", null, null);
264e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
265e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if ((c != null) && c.moveToFirst()) {
266e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
267e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                int titleIndex = c.getColumnIndex(Browser.BookmarkColumns.TITLE);
268e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                int faviconIndex = c.getColumnIndex(Browser.BookmarkColumns.FAVICON);
269e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                do {
270e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    String url = c.getString(urlIndex);
271e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    String host = Uri.parse(url).getHost();
272ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                    if (hosts.containsKey(host)) {
273e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                        String title = c.getString(titleIndex);
274ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                        Bitmap bmp = null;
275e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                        byte[] data = c.getBlob(faviconIndex);
276e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                        if (data != null) {
277ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                            bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
278ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                        }
279ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                        Set matchingSites = (Set) hosts.get(host);
280089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                        Iterator<Site> sitesIter = matchingSites.iterator();
281ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                        while (sitesIter.hasNext()) {
282ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                            Site site = sitesIter.next();
283ee0d639003a5dec32cf45416b0c751def2d4d25aSteve Block                            site.setTitle(title);
284e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                            if (bmp != null) {
285e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                                site.setIcon(bmp);
286e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                            }
287e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                        }
288e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    }
289e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                } while (c.moveToNext());
290e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
291e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
292d95fb21110c4787a9a37c1616ab8490020ceb531Nicolas Roard            c.close();
29399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        }
29499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
29599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
29699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        public void populateOrigins(Map sites) {
29799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            clear();
298d95fb21110c4787a9a37c1616ab8490020ceb531Nicolas Roard
299e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            // We can now simply populate our array with Site instances
30099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            Set keys = sites.keySet();
30199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            Iterator<String> originIter = keys.iterator();
302089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            while (originIter.hasNext()) {
303089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                String origin = originIter.next();
304089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                Site site = (Site) sites.get(origin);
305e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                add(site);
306e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
307e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
30899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            notifyDataSetChanged();
30999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
310e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (getCount() == 0) {
311e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                finish(); // we close the screen
312e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
313e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
314e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
315e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public int getCount() {
316e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (mCurrentSite == null) {
317e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                return super.getCount();
318e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
319089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block            return mCurrentSite.getFeatureCount();
320e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
321e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
322764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block        public String sizeValueToString(long bytes) {
323764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            // We display the size in MB, to 1dp, rounding up to the next 0.1MB.
324764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            // bytes should always be greater than zero.
325764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            if (bytes <= 0) {
326764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block                Log.e(LOGTAG, "sizeValueToString called with non-positive value");
327e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                return "0";
328e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
329764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            float megabytes = (float) bytes / (1024.0F * 1024.0F);
330764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            int truncated = (int) Math.ceil(megabytes * 10.0F);
331764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            float result = (float) (truncated / 10.0F);
332764f0c9765aadeaadd3fbad11b18ab67dd96967dSteve Block            return String.valueOf(result);
333e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
334e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
335e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        /*
336e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard         * If we receive the back event and are displaying
337e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard         * site's settings, we want to go back to the main
338e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard         * list view. If not, we just do nothing (see
339e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard         * dispatchKeyEvent() below).
340e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard         */
341e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public boolean backKeyPressed() {
342e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (mCurrentSite != null) {
343e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                mCurrentSite = null;
34499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                askForOrigins();
345e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                return true;
346e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
347e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            return false;
348e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
349e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
35099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        /**
35199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard         * @hide
35299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard         * Utility function
35399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard         * Set the icon according to the usage
35499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard         */
35599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        public void setIconForUsage(ImageView usageIcon, long usageInBytes) {
35699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            float usageInMegabytes = (float) usageInBytes / (1024.0F * 1024.0F);
35799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            usageIcon.setVisibility(View.VISIBLE);
35899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
35999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            // We set the correct icon:
36099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            // 0 < empty < 0.1MB
36199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            // 0.1MB < low < 3MB
36299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            // 3MB < medium < 6MB
36399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            // 6MB < high
36499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            if (usageInMegabytes <= 0.1) {
36599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                usageIcon.setImageBitmap(mUsageEmptyIcon);
36699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            } else if (usageInMegabytes > 0.1 && usageInMegabytes <= 3) {
36799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                usageIcon.setImageBitmap(mUsageLowIcon);
36899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            } else if (usageInMegabytes > 3 && usageInMegabytes <= 6) {
36999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                usageIcon.setImageBitmap(mUsageMediumIcon);
37099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            } else if (usageInMegabytes > 6) {
37199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                usageIcon.setImageBitmap(mUsageHighIcon);
37299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            }
37399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard        }
37499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard
375e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public View getView(int position, View convertView, ViewGroup parent) {
376e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            View view;
37799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            final TextView title;
37899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            final TextView subtitle;
379e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            ImageView icon;
38099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard            final ImageView usageIcon;
381c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            ImageView locationIcon;
382e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
383e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (convertView == null) {
384e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                view = mInflater.inflate(mResource, parent, false);
385e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            } else {
386e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                view = convertView;
387e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
388e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
389e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            title = (TextView) view.findViewById(R.id.title);
390e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            subtitle = (TextView) view.findViewById(R.id.subtitle);
391e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            icon = (ImageView) view.findViewById(R.id.icon);
392c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            usageIcon = (ImageView) view.findViewById(R.id.usage_icon);
393c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            locationIcon = (ImageView) view.findViewById(R.id.location_icon);
394c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            usageIcon.setVisibility(View.GONE);
395c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard            locationIcon.setVisibility(View.GONE);
396e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
397e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (mCurrentSite == null) {
3984d055a532447cd1adfeac2abebdf365b38fb8a15Steve Block                setTitle(getString(R.string.pref_extras_website_settings));
3994d055a532447cd1adfeac2abebdf365b38fb8a15Steve Block
400e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                Site site = getItem(position);
4011ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block                title.setText(site.getPrettyTitle());
4021ad98cf1e4fb36e7164024f8c1a1098ac2ecaed6Steve Block                subtitle.setText(site.getPrettyOrigin());
403e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                icon.setVisibility(View.VISIBLE);
404c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                usageIcon.setVisibility(View.INVISIBLE);
405c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                locationIcon.setVisibility(View.INVISIBLE);
406e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                Bitmap bmp = site.getIcon();
407e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                if (bmp == null) {
408e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                    bmp = mDefaultIcon;
409e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                }
410e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                icon.setImageBitmap(bmp);
411e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                // We set the site as the view's tag,
412e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                // so that we can get it in onItemClick()
413e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                view.setTag(site);
414c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard
415c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                if (site.hasFeature(Site.FEATURE_WEB_STORAGE)) {
416c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                  String origin = site.getOrigin();
41799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                  WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() {
41899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                      public void onReceiveValue(Long value) {
41999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                          if (value != null) {
42099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                              setIconForUsage(usageIcon, value.longValue());
42199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                          }
42299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                      }
42399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                  });
424c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                }
425c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard
426c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                if (site.hasFeature(Site.FEATURE_GEOLOCATION)) {
427c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                  locationIcon.setVisibility(View.VISIBLE);
428c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                  locationIcon.setImageBitmap(mLocationIcon);
429c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard                }
430e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            } else {
4314d055a532447cd1adfeac2abebdf365b38fb8a15Steve Block                setTitle(mCurrentSite.getPrettyTitle());
432e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                icon.setVisibility(View.GONE);
433089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                String origin = mCurrentSite.getOrigin();
434089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                switch (mCurrentSite.getFeatureByIndex(position)) {
435089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                    case Site.FEATURE_WEB_STORAGE:
43699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        WebStorage.getInstance().getUsageForOrigin(origin, new ValueCallback<Long>() {
43799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            public void onReceiveValue(Long value) {
43899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                if (value != null) {
43999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    String usage = sizeValueToString(value.longValue()) + " " + sMBStored;
44099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    title.setText(R.string.webstorage_clear_data_title);
44199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    subtitle.setText(usage);
44299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                }
44399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            }
44499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        });
445089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                        break;
446f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                    case Site.FEATURE_GEOLOCATION:
447f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                        title.setText(R.string.geolocation_settings_page_title);
44899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        GeolocationPermissions.getInstance().getAllowed(origin, new ValueCallback<Boolean>() {
44999b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            public void onReceiveValue(Boolean allowed) {
45099b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                if (allowed != null) {
45199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    if (allowed.booleanValue()) {
45299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                        subtitle.setText(R.string.geolocation_settings_page_summary_allowed);
45399b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    } else {
45499b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                        subtitle.setText(R.string.geolocation_settings_page_summary_not_allowed);
45599b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    }
45699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                }
45799b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                            }
45899b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                        });
459f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                        break;
460e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                }
461e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
462e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
463e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            return view;
464e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
465e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
466e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        public void onItemClick(AdapterView<?> parent,
467e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                                View view,
468e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                                int position,
469e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                                long id) {
470e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if (mCurrentSite != null) {
471089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                switch (mCurrentSite.getFeatureByIndex(position)) {
472089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                    case Site.FEATURE_WEB_STORAGE:
473089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                        new AlertDialog.Builder(getContext())
474089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .setTitle(R.string.webstorage_clear_data_dialog_title)
475089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .setMessage(R.string.webstorage_clear_data_dialog_message)
476089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .setPositiveButton(R.string.webstorage_clear_data_dialog_ok_button,
477089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                                               new AlertDialog.OnClickListener() {
478089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                                public void onClick(DialogInterface dlg, int which) {
479089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                                    WebStorage.getInstance().deleteOrigin(mCurrentSite.getOrigin());
480089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                                    mCurrentSite = null;
48199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    askForOrigins();
482089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                                }})
483089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .setNegativeButton(R.string.webstorage_clear_data_dialog_cancel_button, null)
484089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .setIcon(android.R.drawable.ic_dialog_alert)
485089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                            .show();
486089ce3ae9bca8a7f5bb84605dfabb7c65aa8aa5bSteve Block                        break;
487f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                    case Site.FEATURE_GEOLOCATION:
488f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                        new AlertDialog.Builder(getContext())
489f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .setTitle(R.string.geolocation_settings_page_dialog_title)
490f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .setMessage(R.string.geolocation_settings_page_dialog_message)
491f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
492f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                                               new AlertDialog.OnClickListener() {
493f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                                public void onClick(DialogInterface dlg, int which) {
494f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                                    GeolocationPermissions.getInstance().clear(mCurrentSite.getOrigin());
495f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                                    mCurrentSite = null;
49699b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                    askForOrigins();
497f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                                }})
498f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null)
499f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .setIcon(android.R.drawable.ic_dialog_alert)
500f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                            .show();
501f344d03c0b01d30575ba1ddd1ed340705c6f5a97Steve Block                        break;
502e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                }
503e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            } else {
504e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                mCurrentSite = (Site) view.getTag();
505e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                notifyDataSetChanged();
506e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
507e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
508e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    }
509e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
510e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    /**
511e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard     * Intercepts the back key to immediately notify
512e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard     * NativeDialog that we are done.
513e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard     */
514e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    public boolean dispatchKeyEvent(KeyEvent event) {
515e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
516e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            && (event.getAction() == KeyEvent.ACTION_DOWN)) {
517e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            if ((mAdapter != null) && (mAdapter.backKeyPressed())){
518e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard                return true; // event consumed
519e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            }
520e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
521e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        return super.dispatchKeyEvent(event);
522e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    }
523e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard
524e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    @Override
525e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    protected void onCreate(Bundle icicle) {
526e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        super.onCreate(icicle);
527e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        if (sMBStored == null) {
528e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard            sMBStored = getString(R.string.webstorage_origin_summary_mb_stored);
529e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        }
530c5702320cd0c66520de57ce8fea9676476cc042aNicolas Roard        mAdapter = new SiteAdapter(this, R.layout.website_settings_row);
531e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        setListAdapter(mAdapter);
532e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard        getListView().setOnItemClickListener(mAdapter);
533e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard    }
534b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch
535b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    @Override
536b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    public boolean onCreateOptionsMenu(Menu menu) {
537b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        MenuInflater inflater = getMenuInflater();
538b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        inflater.inflate(R.menu.websitesettings, menu);
539b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        return true;
540b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    }
541b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch
542b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    @Override
543b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    public boolean onPrepareOptionsMenu(Menu menu) {
544b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        // If we aren't listing any sites hide the clear all button (and hence the menu).
545b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        return mAdapter.getCount() > 0;
546b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    }
547b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch
548b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    @Override
549b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    public boolean onOptionsItemSelected(MenuItem item) {
550b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        switch (item.getItemId()) {
551b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch            case R.id.website_settings_menu_clear_all:
552b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                // Show the prompt to clear all origins of their data and geolocation permissions.
553b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                new AlertDialog.Builder(this)
554b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .setTitle(R.string.website_settings_clear_all_dialog_title)
555b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .setMessage(R.string.website_settings_clear_all_dialog_message)
556b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .setPositiveButton(R.string.website_settings_clear_all_dialog_ok_button,
557b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                                new AlertDialog.OnClickListener() {
558b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                                    public void onClick(DialogInterface dlg, int which) {
559b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                                        WebStorage.getInstance().deleteAllData();
560b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                                        GeolocationPermissions.getInstance().clearAll();
56199b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                        mAdapter.askForOrigins();
56299b3ae1a384981f96fca5432f3d20bf4e8d13667Nicolas Roard                                        finish();
563b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                                    }})
564b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .setNegativeButton(R.string.website_settings_clear_all_dialog_cancel_button, null)
565b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .setIcon(android.R.drawable.ic_dialog_alert)
566b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                        .show();
567b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch                return true;
568b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        }
569b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch        return false;
570b9daacb7513c5a42000285ad456cc614af1915c0Ben Murdoch    }
571e46990ea925f41bdb4d504c91a681e826f4b6eb1Nicolas Roard}
572