You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
7.7 KiB
214 lines
7.7 KiB
package acr.browser.lightning.view; |
|
|
|
import android.Manifest; |
|
import android.app.Activity; |
|
import android.content.DialogInterface; |
|
import android.content.res.Resources; |
|
import android.graphics.Bitmap; |
|
import android.graphics.BitmapFactory; |
|
import android.net.Uri; |
|
import android.os.Message; |
|
import android.support.annotation.NonNull; |
|
import android.support.annotation.Nullable; |
|
import android.support.v7.app.AlertDialog; |
|
import android.view.LayoutInflater; |
|
import android.view.View; |
|
import android.webkit.GeolocationPermissions; |
|
import android.webkit.ValueCallback; |
|
import android.webkit.WebChromeClient; |
|
import android.webkit.WebView; |
|
|
|
import com.anthonycr.bonsai.Schedulers; |
|
import com.anthonycr.grant.PermissionsManager; |
|
import com.anthonycr.grant.PermissionsResultAction; |
|
|
|
import javax.inject.Inject; |
|
|
|
import acr.browser.lightning.R; |
|
import acr.browser.lightning.BrowserApp; |
|
import acr.browser.lightning.controller.UIController; |
|
import acr.browser.lightning.dialog.BrowserDialog; |
|
import acr.browser.lightning.favicon.FaviconModel; |
|
import acr.browser.lightning.utils.Preconditions; |
|
|
|
public class LightningChromeClient extends WebChromeClient { |
|
|
|
private static final String[] PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; |
|
|
|
@NonNull private final Activity mActivity; |
|
@NonNull private final LightningView mLightningView; |
|
@NonNull private final UIController mUIController; |
|
@Inject FaviconModel mFaviconModel; |
|
|
|
LightningChromeClient(@NonNull Activity activity, @NonNull LightningView lightningView) { |
|
Preconditions.checkNonNull(activity); |
|
Preconditions.checkNonNull(lightningView); |
|
BrowserApp.getAppComponent().inject(this); |
|
mActivity = activity; |
|
mUIController = (UIController) activity; |
|
mLightningView = lightningView; |
|
} |
|
|
|
@Override |
|
public void onProgressChanged(WebView view, int newProgress) { |
|
if (mLightningView.isShown()) { |
|
mUIController.updateProgress(newProgress); |
|
} |
|
} |
|
|
|
@Override |
|
public void onReceivedIcon(@NonNull WebView view, Bitmap icon) { |
|
mLightningView.getTitleInfo().setFavicon(icon); |
|
mUIController.tabChanged(mLightningView); |
|
cacheFavicon(view.getUrl(), icon); |
|
} |
|
|
|
/** |
|
* Naive caching of the favicon according to the domain name of the URL |
|
* |
|
* @param icon the icon to cache |
|
*/ |
|
private void cacheFavicon(@Nullable final String url, @Nullable final Bitmap icon) { |
|
if (icon == null || url == null) { |
|
return; |
|
} |
|
|
|
mFaviconModel.cacheFaviconForUrl(icon, url) |
|
.subscribeOn(Schedulers.io()) |
|
.subscribe(); |
|
} |
|
|
|
|
|
@Override |
|
public void onReceivedTitle(@Nullable WebView view, @Nullable String title) { |
|
if (title != null && !title.isEmpty()) { |
|
mLightningView.getTitleInfo().setTitle(title); |
|
} else { |
|
mLightningView.getTitleInfo().setTitle(mActivity.getString(R.string.untitled)); |
|
} |
|
mUIController.tabChanged(mLightningView); |
|
if (view != null && view.getUrl() != null) { |
|
mUIController.updateHistory(title, view.getUrl()); |
|
} |
|
} |
|
|
|
@Override |
|
public void onGeolocationPermissionsShowPrompt(@NonNull final String origin, |
|
@NonNull final GeolocationPermissions.Callback callback) { |
|
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, PERMISSIONS, new PermissionsResultAction() { |
|
@Override |
|
public void onGranted() { |
|
final boolean remember = true; |
|
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); |
|
builder.setTitle(mActivity.getString(R.string.location)); |
|
String org; |
|
if (origin.length() > 50) { |
|
org = origin.subSequence(0, 50) + "..."; |
|
} else { |
|
org = origin; |
|
} |
|
builder.setMessage(org + mActivity.getString(R.string.message_location)) |
|
.setCancelable(true) |
|
.setPositiveButton(mActivity.getString(R.string.action_allow), |
|
new DialogInterface.OnClickListener() { |
|
@Override |
|
public void onClick(DialogInterface dialog, int id) { |
|
callback.invoke(origin, true, remember); |
|
} |
|
}) |
|
.setNegativeButton(mActivity.getString(R.string.action_dont_allow), |
|
new DialogInterface.OnClickListener() { |
|
@Override |
|
public void onClick(DialogInterface dialog, int id) { |
|
callback.invoke(origin, false, remember); |
|
} |
|
}); |
|
AlertDialog alert = builder.create(); |
|
alert.show(); |
|
BrowserDialog.setDialogSize(mActivity, alert); |
|
} |
|
|
|
@Override |
|
public void onDenied(String permission) { |
|
//TODO show message and/or turn off setting |
|
} |
|
}); |
|
} |
|
|
|
@Override |
|
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, |
|
Message resultMsg) { |
|
mUIController.onCreateWindow(resultMsg); |
|
return true; |
|
} |
|
|
|
@Override |
|
public void onCloseWindow(WebView window) { |
|
mUIController.onCloseWindow(mLightningView); |
|
} |
|
|
|
@SuppressWarnings("unused") |
|
public void openFileChooser(ValueCallback<Uri> uploadMsg) { |
|
mUIController.openFileChooser(uploadMsg); |
|
} |
|
|
|
@SuppressWarnings("unused") |
|
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { |
|
mUIController.openFileChooser(uploadMsg); |
|
} |
|
|
|
@SuppressWarnings("unused") |
|
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { |
|
mUIController.openFileChooser(uploadMsg); |
|
} |
|
|
|
@Override |
|
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, |
|
WebChromeClient.FileChooserParams fileChooserParams) { |
|
mUIController.showFileChooser(filePathCallback); |
|
return true; |
|
} |
|
|
|
/** |
|
* Obtain an image that is displayed as a placeholder on a video until the video has initialized |
|
* and can begin loading. |
|
* |
|
* @return a Bitmap that can be used as a place holder for videos. |
|
*/ |
|
@Nullable |
|
@Override |
|
public Bitmap getDefaultVideoPoster() { |
|
final Resources resources = mActivity.getResources(); |
|
return BitmapFactory.decodeResource(resources, android.R.drawable.spinner_background); |
|
} |
|
|
|
/** |
|
* Inflate a view to send to a LightningView when it needs to display a video and has to |
|
* show a loading dialog. Inflates a progress view and returns it. |
|
* |
|
* @return A view that should be used to display the state |
|
* of a video's loading progress. |
|
*/ |
|
@Override |
|
public View getVideoLoadingProgressView() { |
|
LayoutInflater inflater = LayoutInflater.from(mActivity); |
|
return inflater.inflate(R.layout.video_loading_progress, null); |
|
} |
|
|
|
@Override |
|
public void onHideCustomView() { |
|
mUIController.onHideCustomView(); |
|
} |
|
|
|
@Override |
|
public void onShowCustomView(View view, CustomViewCallback callback) { |
|
mUIController.onShowCustomView(view, callback); |
|
} |
|
|
|
@SuppressWarnings("deprecation") |
|
@Override |
|
public void onShowCustomView(View view, int requestedOrientation, |
|
CustomViewCallback callback) { |
|
mUIController.onShowCustomView(view, callback, requestedOrientation); |
|
} |
|
}
|
|
|