blob: 1bc3afb6bfd8661643c74705e3ec3c49798e69a6 [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;
Panos Thomasb298aad2014-10-22 12:24:21 -070034import org.codeaurora.swe.GeolocationPermissions.GeolocationPolicyChange;
35import org.codeaurora.swe.GeolocationPermissions.GeolocationPolicyListener;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070036import org.json.JSONArray;
37
38import android.app.AlertDialog;
39import android.content.Context;
40import android.content.DialogInterface;
41import android.net.Uri;
42import android.util.AttributeSet;
43import android.view.View;
44import android.webkit.ValueCallback;
45import android.widget.ImageButton;
46
Panos Thomasb298aad2014-10-22 12:24:21 -070047public class LocationButton extends ImageButton implements GeolocationPolicyListener {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070048 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();
Tarun Nainani8eb00912014-07-17 12:28:32 -070074 init();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070075 }
76
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070077 private void updateGeolocationPermissions() {
78 mGeolocationPermissions = mCurrentIncognito ?
79 GeolocationPermissions.getIncognitoInstance() :
80 GeolocationPermissions.getInstance();
Panos Thomasb298aad2014-10-22 12:24:21 -070081
82 mGeolocationPermissions.addListener(this);
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070083 }
84
85 // TODO: Perform this initilalization only after the engine initialization is complete.
86 private void init() {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070087 mCurrentTabId = -1;
88 mCurrentOrigin = null;
89 mCurrentIncognito = false;
90
91 setOnClickListener(new View.OnClickListener() {
92 @Override
93 public void onClick(View v) {
94 if (!mCurrentOrigin.isEmpty()) {
95 final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -070096 updateGeolocationPermissions();
97 final GeolocationPermissions geolocationPermissions = mGeolocationPermissions;
Axesh R. Ajmera2e241242014-05-19 15:53:38 -070098 DialogInterface.OnClickListener alertDialogListener =
99 new AlertDialog.OnClickListener() {
100 public void onClick(DialogInterface dlg, int which) {
101 String origin = mCurrentOrigin;
102 int selectedPosition = ((AlertDialog)dlg)
103 .getListView().getCheckedItemPosition();
104 switch (selectedPosition) {
105 case 0: // Deny forever
106 geolocationPermissions.deny(origin);
107 break;
108 case 1: // Extend for 24 hours
109 // encode the expiration time and origin as a JSON string
110 JSONArray jsonArray = new JSONArray();
111 jsonArray.put(System.currentTimeMillis() + MILLIS_PER_DAY);
112 jsonArray.put(origin);
113 geolocationPermissions.allow(jsonArray.toString());
114 break;
115 case 2: // Allow forever
116 geolocationPermissions.allow(origin);
117 break;
118 case 3: // Always ask
119 geolocationPermissions.clear(origin);
120 break;
121 default:
122 break;
123 }
124 }};
125
126 builder.setTitle(String.format(getResources()
127 .getString(R.string.geolocation_settings_page_dialog_title),
128 "http".equals(Uri.parse(mCurrentOrigin).getScheme()) ?
129 mCurrentOrigin.substring(7) : mCurrentOrigin))
130 .setPositiveButton(R.string.geolocation_settings_page_dialog_ok_button,
131 alertDialogListener)
132 .setNegativeButton(R.string.geolocation_settings_page_dialog_cancel_button, null);
133
134 final ValueCallback<Long> getExpirationCallback = new ValueCallback<Long>() {
135 public void onReceiveValue(Long expirationTime) {
136 if (expirationTime != null) {
137 geolocationPolicyExpiration = expirationTime.longValue();
138 // Set radio button and location icon
139 if (!geolocationPolicyOriginAllowed) {
140 // 0: Deny forever
141 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 0, null);
142 } else {
143 if (geolocationPolicyExpiration
144 != GeolocationPermissions.DO_NOT_EXPIRE) {
145 // 1: Allow for 24 hours
146 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 1, null);
147 } else {
148 // 2: Allow forever
149 builder.setSingleChoiceItems(R.array.geolocation_settings_choices, 2, null);
150 }
151 }
152 }
153 builder.show();
154 }};
155
156 final ValueCallback<Boolean> getAllowedCallback = new ValueCallback<Boolean>() {
157 public void onReceiveValue(Boolean allowed) {
158 if (allowed != null) {
159 geolocationPolicyOriginAllowed = allowed.booleanValue();
160 //Get the policy expiration time
161 geolocationPermissions
162 .getExpirationTime(mCurrentOrigin, getExpirationCallback);
163 }
164 }};
165
166 geolocationPermissions.hasOrigin(mCurrentOrigin,
167 new ValueCallback<Boolean>() {
168 public void onReceiveValue(Boolean hasOrigin) {
169 if (hasOrigin != null && hasOrigin.booleanValue()) {
170 //Get whether origin is allowed or denied
171 geolocationPermissions.getAllowed(mCurrentOrigin,
172 getAllowedCallback);
173 }
174 }
175 });
176 }
177 }
178 });
179 }
180
181 public void onTabDataChanged(Tab tab) {
182 long tabId = tab.getId();
183 String origin = GeolocationPermissions.getOriginFromUrl(tab.getUrl());
184 boolean incognito = tab.isPrivateBrowsingEnabled();
185
186 if (mCurrentTabId != tabId) {
187 mCurrentTabId = tabId;
188 mCurrentOrigin = origin;
Panos Thomasb298aad2014-10-22 12:24:21 -0700189 // Switch GeolocationPermissions if we went from a regular to an
190 // incognito tab or vice versa
191 if (mCurrentIncognito != incognito) {
192 mCurrentIncognito = incognito;
193 mGeolocationPermissions = mCurrentIncognito ?
194 GeolocationPermissions.getIncognitoInstance() :
195 GeolocationPermissions.getInstance();
196 mGeolocationPermissions.addListener(this);
197 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700198 update();
199 }
Panos Thomasb298aad2014-10-22 12:24:21 -0700200 // Update icon if we are in the same Tab and origin has changed
201 else if (!((mCurrentOrigin == null && origin == null) ||
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700202 (mCurrentOrigin != null && origin != null
Panos Thomasb298aad2014-10-22 12:24:21 -0700203 && mCurrentOrigin.equals(origin)))) {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700204 mCurrentOrigin = origin;
205 update();
206 }
207 }
208
Panos Thomasb298aad2014-10-22 12:24:21 -0700209 /**
210 * This method is called when we navigate away from an origin on the same Tab or
211 * when a new Tab is created.
212 */
213 private void update() {
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700214 if (mCurrentOrigin != null) {
Kulanthaivel Palanichamy77942682014-10-28 11:52:06 -0700215 updateGeolocationPermissions();
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700216 mGeolocationPermissions.hasOrigin(mCurrentOrigin,
217 new ValueCallback<Boolean>() {
218 public void onReceiveValue(Boolean hasOrigin) {
219 if (hasOrigin != null && hasOrigin.booleanValue()) {
220 mGeolocationPermissions.getAllowed(mCurrentOrigin,
221 new ValueCallback<Boolean>() {
222 public void onReceiveValue(Boolean allowed) {
223 if (allowed != null) {
224 if (allowed.booleanValue()) {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800225 LocationButton.this.setImageResource(R.drawable.ic_action_gps_on);
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700226 LocationButton.this.setVisibility(VISIBLE);
227 } else {
Enrico Ros1f5a0952014-11-18 20:15:48 -0800228 LocationButton.this.setImageResource(R.drawable.ic_action_gps_off);
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700229 LocationButton.this.setVisibility(VISIBLE);
230 }
231 }
232 }
233 });
234 } else {
235 LocationButton.this.setVisibility(GONE);
236 }
237 }
238 });
239 } else {
240 this.setVisibility(GONE);
241 }
242 }
243
Panos Thomasb298aad2014-10-22 12:24:21 -0700244 public void onGeolocationPolicyChanged(GeolocationPolicyChange change) {
245 if (mCurrentOrigin != null) {
246 int action = change.getAction();
247
248 if (action == GeolocationPermissions.ALL_POLICIES_REMOVED) {
249 this.setVisibility(GONE);
250 return;
251 } else if (change.getOrigin() != null && mCurrentOrigin.equals(change.getOrigin())) {
252 switch (action) {
253 case GeolocationPermissions.ORIGIN_ALLOWED:
254 this.setImageResource(R.drawable.ic_action_gps_on);
255 this.setVisibility(VISIBLE);
256 break;
257 case GeolocationPermissions.ORIGIN_DENIED:
258 this.setImageResource(R.drawable.ic_action_gps_off);
259 this.setVisibility(VISIBLE);
260 break;
261 case GeolocationPermissions.ORIGIN_POLICY_REMOVED:
262 this.setVisibility(GONE);
263 break;
264 default:
265 break;
266 }
267 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700268 }
269 }
Axesh R. Ajmera2e241242014-05-19 15:53:38 -0700270}