1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package org.chromium.android_webview;
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.content.SharedPreferences;
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import android.webkit.ValueCallback;
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.base.ThreadUtils;
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.net.GURLUtils;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.HashSet;
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import java.util.Set;
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This class is used to manage permissions for the WebView's Geolocation JavaScript API.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Callbacks are posted on the UI thread.
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public final class AwGeolocationPermissions {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private static final String PREF_PREFIX =
249ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch            "AwGeolocationPermissions%";
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private final SharedPreferences mSharedPreferences;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public AwGeolocationPermissions(SharedPreferences sharedPreferences) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        mSharedPreferences = sharedPreferences;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Set one origin to be allowed.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void allow(String origin) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        String key = getOriginKey(origin);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (key != null) {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mSharedPreferences.edit().putBoolean(key, true).apply();
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Set one origin to be denied.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void deny(String origin) {
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        String key = getOriginKey(origin);
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (key != null) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mSharedPreferences.edit().putBoolean(key, false).apply();
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Clear the stored permission for a particular origin.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void clear(String origin) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        String key = getOriginKey(origin);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (key != null) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            mSharedPreferences.edit().remove(key).apply();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Clear stored permissions for all origins.
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void clearAll() {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SharedPreferences.Editor editor = null;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (String name : mSharedPreferences.getAll().keySet()) {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (name.startsWith(PREF_PREFIX)) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                if (editor == null) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    editor = mSharedPreferences.edit();
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                editor.remove(name);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (editor != null) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            editor.apply();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Synchronous method to get if an origin is set to be allowed.
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public boolean isOriginAllowed(String origin) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return mSharedPreferences.getBoolean(getOriginKey(origin), false);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Returns true if the origin is either set to allowed or denied.
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public boolean hasOrigin(String origin) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return mSharedPreferences.contains(getOriginKey(origin));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Asynchronous method to get if an origin set to be allowed.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void getAllowed(String origin, final ValueCallback<Boolean> callback) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        final boolean finalAllowed = isOriginAllowed(origin);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ThreadUtils.postOnUiThread(new Runnable() {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public void run() {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                callback.onReceiveValue(finalAllowed);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        });
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Async method to get the domains currently allowed or denied.
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    public void getOrigins(final ValueCallback<Set<String>> callback) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        final Set<String> origins = new HashSet<String>();
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        for (String name : mSharedPreferences.getAll().keySet()) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            if (name.startsWith(PREF_PREFIX)) {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                origins.add(name.substring(PREF_PREFIX.length()));
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ThreadUtils.postOnUiThread(new Runnable() {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            @Override
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            public void run() {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                callback.onReceiveValue(origins);
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        });
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    /**
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     * Get the domain of an URL using the GURL library.
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     */
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    private String getOriginKey(String url) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        String origin = GURLUtils.getOrigin(url);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (origin.isEmpty()) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            return null;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return PREF_PREFIX + origin;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
136