Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved WebView permission handling in EclairUtil.java #3380

Open
wants to merge 1 commit into
base: ucr
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,121 +1,104 @@
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2009-2011 Google, All Rights reserved
// Copyright 2011-2012 MIT, All rights reserved
// Copyright 2011-2012 MIT, All Rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package com.google.appinventor.components.runtime.util;

import com.google.appinventor.components.runtime.WebViewer;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;

import android.text.InputType;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.EditText;

/**
* Helper methods for calling methods added in Eclair (2.0, API level 5)
*
* @author Ryan Bis
*
* Utility class for handling Android API features related to WebView and geolocation.
*/
public class EclairUtil {

private EclairUtil() {
// Private constructor to prevent instantiation
}

/**
* Calls {@link Activity#overridePendingTransition(int, int)}. This is used
* to set a different animation type for screen transition animations.
* Overrides the pending transition animation for an activity.
*
* @param activity - The activity handling the animation
* @param enterAnim - The enter animation type
* @param exitAnim - The exit animation type
* @param activity The activity handling the animation.
* @param enterAnim The enter animation.
* @param exitAnim The exit animation.
*/
public static void overridePendingTransitions(Activity activity, int enterAnim, int exitAnim) {
activity.overridePendingTransition(enterAnim, exitAnim);
if (activity != null) {
activity.overridePendingTransition(enterAnim, exitAnim);
}
}

/**
* Setup Dialog Box to request location permission from end-user for the Javascript
* location (navigator.geolocation.getCurrentLocation()) API.
* Configures a WebView to request location permission from users when needed.
*
* @param webview - The WebView component running the Javascript engine that needs permission
* @param activity - Its containing activity used for placing the dialog box
* @param caller The WebViewer instance.
* @param webview The WebView component requesting geolocation.
* @param activity The activity hosting the WebView.
*/

public static void setupWebViewGeoLoc(final WebViewer caller, WebView webview, final Activity activity) {
if (webview == null || activity == null) return;

webview.getSettings().setGeolocationDatabasePath(activity.getFilesDir().getAbsolutePath());
webview.getSettings().setDatabaseEnabled(true);

webview.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
Callback callback) {
final Callback theCallback = callback;
final String theOrigin = origin;
if (!caller.PromptforPermission()) { // Don't prompt, assume permission
callback.invoke(origin, true, true);
return;
}
AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
alertDialog.setTitle("Permission Request");
if (origin.equals("file://"))
origin = "This Application";
alertDialog.setMessage(origin + " would like to access your location.");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Allow",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
theCallback.invoke(theOrigin, true, true);
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Refuse",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
theCallback.invoke(theOrigin, false, true);
}
});
alertDialog.show();
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
if (!caller.PromptforPermission()) {
callback.invoke(origin, true, true);
return;
}
});

String displayOrigin = origin.equals("file://") ? "This Application" : origin;

new AlertDialog.Builder(activity)
.setTitle("Permission Request")
.setMessage(displayOrigin + " would like to access your location.")
.setPositiveButton("Allow", (dialog, which) -> callback.invoke(origin, true, true))
.setNegativeButton("Refuse", (dialog, which) -> callback.invoke(origin, false, true))
.show();
}
});
}

/**
* Clear Stored Location permissions. When the geolocation API is used in
* the WebViewer, the end user is prompted on a per URL basis for whether
* or not permission should be granted to access their location. This
* function clears this information for all locations.
*
* As the permissions interface is not available on phones older then
* Eclair, this function is a no-op on older phones.
* Clears all stored geolocation permissions for the WebView.
*/
public static void clearWebViewGeoLoc() {
GeolocationPermissions permissions = GeolocationPermissions.getInstance();
permissions.clearAll();
GeolocationPermissions.getInstance().clearAll();
}

public static String getInstallerPackageName(String pname, Activity form) {
return form.getPackageManager().getInstallerPackageName(pname);
/**
* Retrieves the installer package name for a given package.
*
* @param packageName The package name.
* @param activity The activity context.
* @return The installer package name, or null if not found.
*/
public static String getInstallerPackageName(String packageName, Activity activity) {
if (activity == null || packageName == null) return null;
return activity.getPackageManager().getInstallerPackageName(packageName);
}

/**
* Disable suggestions on EditText widgets. This was added to
* support SDK levels where suggestions crashed apps without the
* appropriate Android Support library compiled into the app.
* Disables text suggestions on an EditText field.
*
* @param textview EditText widget to have its suggestion feature
* disabled.
* @param editText The EditText widget.
*/
public static void disableSuggestions(EditText textview) {
textview.setInputType(textview.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
public static void disableSuggestions(EditText editText) {
if (editText != null) {
editText.setInputType(editText.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
}

}