blob: 304add196e83d5f42b8cffecfc48db9a232463f7 [file] [log] [blame]
// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package org.mozc.android.inputmethod.japanese.preference;
import org.mozc.android.inputmethod.japanese.resources.R;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.util.regex.Pattern;
/**
* Mini browser to show licenses.
*
* <p>We must show some web sites (e.g. EULA) from preference screen.
* However in some special environments default browser is not installed so
* even if an Intent is issued nothing will happen.
* This mini browser accepts an Intent and shows its content (of which URL is included as
* Intent's data) like as a browser.
*
*/
public class MiniBrowserActivity extends Activity {
// TODO(matsuzakit): "print" link is meaningless. Should be invisible.
// TODO(matsuzakit): CSS needs to be improved.
@VisibleForTesting
static final class MiniBrowserClient extends WebViewClient {
private final String restrictionPattern;
private final PackageManager packageManager;
private final Context context;
@VisibleForTesting
MiniBrowserClient(String restrictionPattern, PackageManager packageManager, Context context) {
Preconditions.checkNotNull(restrictionPattern);
Preconditions.checkNotNull(packageManager);
Preconditions.checkNotNull(packageManager);
this.restrictionPattern = restrictionPattern;
this.packageManager = packageManager;
this.context = context;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
Preconditions.checkNotNull(view);
Preconditions.checkNotNull(url);
// Use temporary matcher intentionally.
// Regex engine is rather heavy to instantiate so use it as less as possible.
if (!Pattern.matches(restrictionPattern, url)) {
// If the URL's doesn't match restriction pattern,
// delegate the operation to the default browser.
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
if (!packageManager.queryIntentActivities(browserIntent, 0).isEmpty()) {
context.startActivity(browserIntent);
}
// If no default browser is available, do nothing.
return true;
}
// Prevent from invoking default browser.
// In some special environment default browser is not installed.
return false;
} catch (Throwable e) {
// This method might be called from native layer.
// Therefore throwing something from here causes native crash.
// To prevent from native crash, catches all here.
// At least SecurityException must be caught here for Android-TV.
return true;
}
}
}
private Optional<WebView> webView = Optional.absent();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
this.webView = Optional.of(webView);
webView.setWebViewClient(
new MiniBrowserClient(getResources().getString(R.string.pref_url_restriction_regex),
getPackageManager(), this));
webView.loadUrl(getIntent().getData().toString());
setContentView(webView);
}
@Override
protected void onPause() {
// Clear cache in order to show appropriate website even if system locale is changed.
if (this.webView.isPresent()) {
this.webView.get().clearCache(true);
}
super.onPause();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Preconditions.checkNotNull(event);
// Enable back-key inside the webview.
// If no history exists, default behavior is executed (finish the activity).
if (keyCode == KeyEvent.KEYCODE_BACK && webView.isPresent() && webView.get().canGoBack()) {
webView.get().goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}