blob: e805e4385da83b65fd7ece09ac3c03ebf1fdd2ce [file] [log] [blame]
Axesh R. Ajmera2e241242014-05-19 15:53:38 -07001/*
2 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 */
30
31package com.android.browser;
32
33import org.codeaurora.swe.GeolocationPermissions;
34import org.codeaurora.swe.GeolocationPermissions.OnGeolocationPolicyModifiedListener;
35import org.json.JSONArray;
36
37import android.app.AlertDialog;
38import android.content.Context;
39import android.content.DialogInterface;
40import android.net.Uri;
41import android.util.AttributeSet;
42import android.view.View;
43import android.webkit.ValueCallback;
44import android.widget.ImageButton;
45
46public class LocationButton extends ImageButton
47 implements OnGeolocationPolicyModifiedListener {
48 private GeolocationPermissions mGeolocationPermissions;
49 private long mCurrentTabId;
50 private String mCurrentOrigin;
51 private boolean mCurrentIncognito;
52
53 private static final long MILLIS_PER_DAY = 86400000;
54
55 protected long geolocationPolicyExpiration;
56 protected boolean geolocationPolicyOriginAllowed;
57
58 public LocationButton(Context context) {
59 super(context);
60 }
61
62 public LocationButton(Context context, AttributeSet attrs) {
63 super(context, attrs);
64
65 }
66
67 public LocationButton(Context context, AttributeSet attrs, int defStyle) {
68 super(context, attrs, defStyle);
69 }
70
71 @Override
72 protected void onFinishInflate() {
73 super.onFinishInflate();
74 init();
75 }
76
77 private void init() {
78 mGeolocationPermissions = GeolocationPermissions.getInstance();
79 mGeolocationPermissions.registerOnGeolocationPolicyModifiedListener(this);
80 mCurrentTabId = -1;
81 mCurrentOrigin = null;
82 mCurrentIncognito = false;
83
84 setOnClickListener(new View.OnClickListener() {
85 @Override
86 public void onClick(View v) {
87 if (!mCurrentOrigin.isEmpty()) {
88 final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
89 final GeolocationPermissions geolocationPermissions =
90 (mCurrentIncognito ?
91 GeolocationPermissions.getIncognitoInstance() :
92 GeolocationPermissions.getInstance());
93
94 DialogInterface.OnClickListener alertDialogListener =
95 new AlertDialog.OnClickListener() {
96 public void onClick(DialogInterface dlg, int which) {
97 String origin = mCurrentOrigin;
98 int selectedPosition = ((AlertDialog)dlg)
99 .getListView().getCheckedItemPosition();
100 switch (selectedPosition) {
101 case 0: // Deny forever
102 geolocationPermissions.deny(origin);
103 break;
104 case 1: // Extend for 24 hours
105 // encode the expiration time and origin as a JSON string
106 JSONArray jsonArray = new JSONArray();
107 jsonArray.put(System.currentTimeMillis() + MILLIS_PER_DAY);
108 jsonArray.put(origin);
109 geolocationPermissions.allow(jsonArray.toString());
110 break;
111 case 2: // Allow forever
112 geolocationPermissions.allow(origin);
113 break;
114 case 3: // Always ask
115 geolocationPermissions.clear(origin);
116 break;
117 default:
118 break;
119 }
120 }};
121
122 builder.setTitle(String.format(getResources()
123 .getString(R.string.geolocation_settings_page_dialog_title),
124 "http".equals(Uri.parse(mCurrentOrigin).getScheme()) ?
125 mCurrentOrigin.substring(7) : mCurrentOrigin))
126 .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
127 alertDialogListener)
128 .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null);
129
130 final ValueCallback<Long> getExpirationCallback = new ValueCallback<Long>() {
131 public void onReceiveValue(Long expirationTime) {
132 if (expirationTime != null) {
133 geolocationPolicyExpiration = expirationTime.longValue();
134 // Set radio button and location icon
135 if (!geolocationPolicyOriginAllowed) {
136 // 0: Deny forever
137 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 0, null);
138 } else {
139 if (geolocationPolicyExpiration
140 != GeolocationPermissions.DO_NOT_EXPIRE) {
141 // 1: Allow for 24 hours
142 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 1, null);
143 } else {
144 // 2: Allow forever
145 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 2, null);
146 }
147 }
148 }
149 builder.show();
150 }};
151
152 final ValueCallback<Boolean> getAllowedCallback = new ValueCallback<Boolean>() {
153 public void onReceiveValue(Boolean allowed) {
154 if (allowed != null) {
155 geolocationPolicyOriginAllowed = allowed.booleanValue();
156 //Get the policy expiration time
157 geolocationPermissions
158 .getExpirationTime(mCurrentOrigin, getExpirationCallback);
159 }
160 }};
161
162 geolocationPermissions.hasOrigin(mCurrentOrigin,
163 new ValueCallback<Boolean>() {
164 public void onReceiveValue(Boolean hasOrigin) {
165 if (hasOrigin != null && hasOrigin.booleanValue()) {
166 //Get whether origin is allowed or denied
167 geolocationPermissions.getAllowed(mCurrentOrigin,
168 getAllowedCallback);
169 }
170 }
171 });
172 }
173 }
174 });
175 }
176
177 public void onTabDataChanged(Tab tab) {
178 long tabId = tab.getId();
179 String origin = GeolocationPermissions.getOriginFromUrl(tab.getUrl());
180 boolean incognito = tab.isPrivateBrowsingEnabled();
181
182 if (mCurrentTabId != tabId) {
183 mCurrentTabId = tabId;
184 mCurrentOrigin = origin;
185
186 // Switch GeolocationPermissions if we went from a regular to an
187 // incognito tab or vice versa
188 if (mCurrentIncognito != incognito) {
189 mCurrentIncognito = incognito;
190 mGeolocationPermissions = mCurrentIncognito ?
191 GeolocationPermissions.getIncognitoInstance() :
192 GeolocationPermissions.getInstance();
193 mGeolocationPermissions.registerOnGeolocationPolicyModifiedListener(this);
194 }
195 update();
196 }
197 // Update icon if we are in the same tab and origin has changed
198 else if (!((mCurrentOrigin == null && origin == null) ||
199 (mCurrentOrigin != null && origin != null
200 && mCurrentOrigin.equals(origin)))) {
201 mCurrentOrigin = origin;
202 update();
203 }
204 }
205
206 public void update() {
207 if (mCurrentOrigin != null) {
208 mGeolocationPermissions.hasOrigin(mCurrentOrigin,
209 new ValueCallback<Boolean>() {
210 public void onReceiveValue(Boolean hasOrigin) {
211 if (hasOrigin != null && hasOrigin.booleanValue()) {
212 mGeolocationPermissions.getAllowed(mCurrentOrigin,
213 new ValueCallback<Boolean>() {
214 public void onReceiveValue(Boolean allowed) {
215 if (allowed != null) {
216 if (allowed.booleanValue()) {
217 LocationButton.this.setImageResource(R.drawable.ic_gps_on_holo_dark);
218 LocationButton.this.setVisibility(VISIBLE);
219 } else {
220 LocationButton.this.setImageResource(R.drawable.ic_gps_denied_holo_dark);
221 LocationButton.this.setVisibility(VISIBLE);
222 }
223 }
224 }
225 });
226 } else {
227 LocationButton.this.setVisibility(GONE);
228 }
229 }
230 });
231 } else {
232 this.setVisibility(GONE);
233 }
234 }
235
236 @Override
237 public void onGeolocationPolicyAdded(String origin, boolean allow) {
238 if (mCurrentOrigin != null && mCurrentOrigin.equals(origin)) {
239 this.setImageResource(allow ? R.drawable.ic_gps_on_holo_dark :
240 R.drawable.ic_gps_denied_holo_dark);
241 this.setVisibility(VISIBLE);
242 }
243 }
244
245 @Override
246 public void onGeolocationPolicyCleared(String origin) {
247 if (mCurrentOrigin != null && mCurrentOrigin.equals(origin)) {
248 this.setVisibility(GONE);
249 }
250 }
251
252 @Override
253 public void onGeolocationPolicyClearedAll() {
254 this.setVisibility(GONE);
255 }
256
257}