diff --git a/src/acr/browser/lightning/BrowserActivity.java b/src/acr/browser/lightning/BrowserActivity.java index f563b90..dc4da07 100644 --- a/src/acr/browser/lightning/BrowserActivity.java +++ b/src/acr/browser/lightning/BrowserActivity.java @@ -530,7 +530,7 @@ public class BrowserActivity extends Activity implements BrowserController { wkp.setProxy("acr.browser.lightning.BrowserApp", getApplicationContext(), host, port); } catch (Exception e) { - Log.d(Constants.LOGTAG, "error enabling web proxying", e); + Log.d(Constants.TAG, "error enabling web proxying", e); } } @@ -734,7 +734,7 @@ public class BrowserActivity extends Activity implements BrowserController { newTab(null, true); return true; case R.id.action_incognito: - startActivity(new Intent(Constants.INCOGNITO_INTENT)); + startActivity(new Intent(this, IncognitoActivity.class)); return true; case R.id.action_share: if (!mCurrentView.getUrl().startsWith(Constants.FILE)) { @@ -766,7 +766,7 @@ public class BrowserActivity extends Activity implements BrowserController { } return true; case R.id.action_settings: - startActivity(new Intent(Constants.SETTINGS_INTENT)); + startActivity(new Intent(this, SettingsActivity.class)); return true; case R.id.action_history: openHistory(); @@ -1053,6 +1053,18 @@ public class BrowserActivity extends Activity implements BrowserController { } } + @Override + public void closeEmptyTab() { + if (mCurrentView != null + && mCurrentView.getWebView().copyBackForwardList().getSize() == 0) { + closeCurrentTab(); + } + } + + private void closeCurrentTab() { + //don't delete the tab because the browser will close and mess stuff up + } + private void selectItem(final int position) { // update selected item and title, then close the drawer @@ -1150,21 +1162,21 @@ public class BrowserActivity extends Activity implements BrowserController { PreferenceConstants.CLEAR_CACHE_EXIT, false) && mCurrentView != null && !isIncognito()) { mCurrentView.clearCache(true); - Log.i(Constants.LOGTAG, "Cache Cleared"); + Log.i(Constants.TAG, "Cache Cleared"); } if (mPreferences.getBoolean( PreferenceConstants.CLEAR_HISTORY_EXIT, false) && !isIncognito()) { clearHistory(); - Log.i(Constants.LOGTAG, "History Cleared"); + Log.i(Constants.TAG, "History Cleared"); } if (mPreferences.getBoolean( PreferenceConstants.CLEAR_COOKIES_EXIT, false) && !isIncognito()) { clearCookies(); - Log.i(Constants.LOGTAG, "Cookies Cleared"); + Log.i(Constants.TAG, "Cookies Cleared"); } if (reference != null) { @@ -1186,7 +1198,7 @@ public class BrowserActivity extends Activity implements BrowserController { closeActivity(); } - Log.i(Constants.LOGTAG, "deleted tab"); + Log.i(Constants.TAG, "deleted tab"); } @Override @@ -1195,19 +1207,19 @@ public class BrowserActivity extends Activity implements BrowserController { if (mPreferences.getBoolean(PreferenceConstants.CLEAR_CACHE_EXIT, false) && mCurrentView != null && !isIncognito()) { mCurrentView.clearCache(true); - Log.i(Constants.LOGTAG, "Cache Cleared"); + Log.i(Constants.TAG, "Cache Cleared"); } if (mPreferences.getBoolean(PreferenceConstants.CLEAR_HISTORY_EXIT, false) && !isIncognito()) { clearHistory(); - Log.i(Constants.LOGTAG, "History Cleared"); + Log.i(Constants.TAG, "History Cleared"); } if (mPreferences.getBoolean(PreferenceConstants.CLEAR_COOKIES_EXIT, false) && !isIncognito()) { clearCookies(); - Log.i(Constants.LOGTAG, "Cookies Cleared"); + Log.i(Constants.TAG, "Cookies Cleared"); } mCurrentView = null; @@ -1258,7 +1270,7 @@ public class BrowserActivity extends Activity implements BrowserController { mDrawerLayout.closeDrawer(mDrawerRight); } else { if (mCurrentView != null) { - Log.i(Constants.LOGTAG, "onBackPressed"); + Log.i(Constants.TAG, "onBackPressed"); if (mCurrentView.canGoBack()) { if (!mCurrentView.isShown()) { onHideCustomView(); @@ -1269,7 +1281,7 @@ public class BrowserActivity extends Activity implements BrowserController { deleteTab(mDrawerList.getCheckedItemPosition()); } } else { - Log.e(Constants.LOGTAG, + Log.e(Constants.TAG, "So madness. Much confusion. Why happen."); super.onBackPressed(); } @@ -1279,7 +1291,7 @@ public class BrowserActivity extends Activity implements BrowserController { @Override protected void onPause() { super.onPause(); - Log.i(Constants.LOGTAG, "onPause"); + Log.i(Constants.TAG, "onPause"); if (mCurrentView != null) { mCurrentView.pauseTimers(); mCurrentView.onPause(); @@ -1311,7 +1323,7 @@ public class BrowserActivity extends Activity implements BrowserController { @Override protected void onDestroy() { - Log.i(Constants.LOGTAG, "onDestroy"); + Log.i(Constants.TAG, "onDestroy"); if (mHistoryDatabase != null) { if (mHistoryDatabase.isOpen()) mHistoryDatabase.close(); @@ -1326,7 +1338,7 @@ public class BrowserActivity extends Activity implements BrowserController { @Override protected void onResume() { super.onResume(); - Log.i(Constants.LOGTAG, "onResume"); + Log.i(Constants.TAG, "onResume"); if (SettingsController.getClearHistory()) { } if (mSearchAdapter != null) { @@ -1790,13 +1802,13 @@ public class BrowserActivity extends Activity implements BrowserController { cursor.close(); cursor = null; } catch (IllegalStateException e) { - Log.e(Constants.LOGTAG, + Log.e(Constants.TAG, "IllegalStateException in updateHistory"); } catch (NullPointerException e) { - Log.e(Constants.LOGTAG, + Log.e(Constants.TAG, "NullPointerException in updateHistory"); } catch (SQLiteException e) { - Log.e(Constants.LOGTAG, "SQLiteException in updateHistory"); + Log.e(Constants.TAG, "SQLiteException in updateHistory"); } } }; @@ -2146,7 +2158,7 @@ public class BrowserActivity extends Activity implements BrowserController { if (mCustomView == null || mCustomViewCallback == null || mCurrentView == null) return; - Log.i(Constants.LOGTAG, "onHideCustomView"); + Log.i(Constants.TAG, "onHideCustomView"); mCurrentView.setVisibility(View.VISIBLE); mCustomView.setKeepScreenOn(false); setFullscreen(mPreferences.getBoolean( diff --git a/src/acr/browser/lightning/BrowserController.java b/src/acr/browser/lightning/BrowserController.java index 9c86524..7599087 100644 --- a/src/acr/browser/lightning/BrowserController.java +++ b/src/acr/browser/lightning/BrowserController.java @@ -46,4 +46,6 @@ public interface BrowserController { public void openBookmarkPage(WebView view); public boolean isActionBarShowing(); + + public void closeEmptyTab(); } diff --git a/src/acr/browser/lightning/IntentUtils.java b/src/acr/browser/lightning/IntentUtils.java new file mode 100644 index 0000000..9b08978 --- /dev/null +++ b/src/acr/browser/lightning/IntentUtils.java @@ -0,0 +1,101 @@ +package acr.browser.lightning; + +import java.net.URISyntaxException; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.util.Log; +import android.webkit.WebView; + +public class IntentUtils { + + private Activity mActivity; + private BrowserController mController; + static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile("(?i)" + + // switch on case insensitive matching + "(" + + // begin group for schema + "(?:http|https|file):\\/\\/" + "|(?:inline|data|about|javascript):" + + "|(?:.*:.*@)" + ")" + "(.*)"); + + public IntentUtils(BrowserController controller) { + mController = controller; + mActivity = mController.getActivity(); + } + + public boolean startActivityForUrl(WebView tab, String url) { + Intent intent; + try { + intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME); + } catch (URISyntaxException ex) { + Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage()); + return false; + } + + if (mActivity.getPackageManager().resolveActivity(intent, 0) == null) { + String packagename = intent.getPackage(); + if (packagename != null) { + intent = new Intent(Intent.ACTION_VIEW, + Uri.parse("market://search?q=pname:" + packagename)); + intent.addCategory(Intent.CATEGORY_BROWSABLE); + mActivity.startActivity(intent); + return true; + } else { + return false; + } + } + intent.addCategory(Intent.CATEGORY_BROWSABLE); + intent.setComponent(null); + if (tab != null) { + intent.putExtra(mActivity.getPackageName() + ".Origin", 1); + } + + Matcher m = ACCEPTED_URI_SCHEMA.matcher(url); + if (m.matches() && !isSpecializedHandlerAvailable(intent)) { + return false; + } + try { + if (mActivity.startActivityIfNeeded(intent, -1)) { + return true; + } + } catch (ActivityNotFoundException ex) { + } + return false; + } + + /** + * Search for intent handlers that are specific to this URL aka, specialized + * apps like google maps or youtube + */ + private boolean isSpecializedHandlerAvailable(Intent intent) { + PackageManager pm = mActivity.getPackageManager(); + List handlers = pm.queryIntentActivities(intent, + PackageManager.GET_RESOLVED_FILTER); + if (handlers == null || handlers.size() == 0) { + return false; + } + for (ResolveInfo resolveInfo : handlers) { + IntentFilter filter = resolveInfo.filter; + if (filter == null) { + // No intent filter matches this intent? + // Error on the side of staying in the browser, ignore + continue; + } + if (filter.countDataAuthorities() == 0 + || filter.countDataPaths() == 0) { + // Generic handler, skip + continue; + } + return true; + } + return false; + } +} diff --git a/src/acr/browser/lightning/LightningView.java b/src/acr/browser/lightning/LightningView.java index 42cb6c4..3b96834 100644 --- a/src/acr/browser/lightning/LightningView.java +++ b/src/acr/browser/lightning/LightningView.java @@ -67,7 +67,6 @@ public class LightningView { private Activity mActivity; private WebSettings mSettings; private static int API = android.os.Build.VERSION.SDK_INT; - private static String mPackageName; private static String mHomepage; private static String mDefaultUserAgent; private static Bitmap mWebpageBitmap; @@ -76,16 +75,18 @@ public class LightningView { private static AdBlock mAdBlock; private CookieManager mCookieManager; private boolean isForgroundTab = false; + private IntentUtils mIntentUtils = null; @SuppressLint("NewApi") public LightningView(Activity activity, String url, CookieManager cookieManager) { + mActivity = activity; mCookieManager = cookieManager; mWebView = new WebView(activity); mTitle = new Title(activity); mAdBlock = new AdBlock(activity); - mPackageName = activity.getPackageName(); + activity.getPackageName(); mWebpageBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.ic_webpage); @@ -95,6 +96,7 @@ public class LightningView { throw new ClassCastException(activity.toString() + " must implement BrowserController"); } + mIntentUtils = new IntentUtils(mBrowserController); mWebView.setDrawingCacheBackgroundColor(0x00000000); mWebView.setFocusableInTouchMode(true); mWebView.setFocusable(true); @@ -488,6 +490,10 @@ public class LightningView { } } + public Activity getActivity() { + return mActivity; + } + public synchronized void onDestroy() { if (mWebView != null) { mWebView.stopLoading(); @@ -686,7 +692,7 @@ public class LightningView { return null; // let webkit handle it } } catch (Exception e) { - Log.e(Constants.LOGTAG, "Error filtering stream", e); + Log.e(Constants.TAG, "Error filtering stream", e); ByteArrayInputStream EMPTY = new ByteArrayInputStream( "".getBytes()); WebResourceResponse response = new WebResourceResponse( @@ -701,7 +707,13 @@ public class LightningView { if (view.isShown()) { view.invalidate(); } - mTitle.setTitle(view.getTitle()); + if (view.getTitle() == null) { + mTitle.setTitle(mActivity.getString(R.string.untitled)); + } else if (view.getTitle().length() > 0) { + mTitle.setTitle(view.getTitle()); + } else { + mTitle.setTitle(mActivity.getString(R.string.untitled)); + } mBrowserController.update(); } @@ -748,7 +760,7 @@ public class LightningView { String user = name.getText().toString(); String pass = password.getText().toString(); handler.proceed(user.trim(), pass.trim()); - Log.i(Constants.LOGTAG, "Request Login"); + Log.i(Constants.TAG, "Request Login"); } }) @@ -842,46 +854,16 @@ public class LightningView { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (url.startsWith("market://") - || url.startsWith("http://play.google.com/store/apps") - || url.startsWith("https://play.google.com/store/apps")) { - Intent urlIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse(url)); - urlIntent.putExtra(mPackageName + ".Origin", 1); - mActivity.startActivity(urlIntent); - return true; - } else if (url.startsWith("http://www.youtube.com") - || url.startsWith("https://www.youtube.com") - || url.startsWith("http://m.youtube.com") - || url.startsWith("https://m.youtube.com")) { - Intent urlIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse(url)); - urlIntent.putExtra(mPackageName + ".Origin", 1); - mActivity.startActivity(urlIntent); - return true; - } else if (url.startsWith("http://maps.google.com") - || url.startsWith("https://maps.google.com")) { - Intent urlIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse(url)); - urlIntent.putExtra(mPackageName + ".Origin", 1); - mActivity.startActivity(urlIntent); - return true; - } else if (url.contains("tel:") || TextUtils.isDigitsOnly(url)) { - mActivity.startActivity(new Intent(Intent.ACTION_DIAL, Uri - .parse(url))); - return true; - } else if (url.contains("mailto:")) { + if (url.startsWith("about:")) { + return super.shouldOverrideUrlLoading(view, url); + } + if (url.contains("mailto:")) { MailTo mailTo = MailTo.parse(url); Intent i = Utils.newEmailIntent(mActivity, mailTo.getTo(), mailTo.getSubject(), mailTo.getBody(), mailTo.getCc()); mActivity.startActivity(i); view.reload(); return true; - } else if (url.startsWith("magnet:?")) { - Intent urlIntent = new Intent(Intent.ACTION_VIEW, - Uri.parse(url)); - urlIntent.putExtra(mPackageName + ".Origin", 1); - mActivity.startActivity(urlIntent); } else if (url.startsWith("intent://")) { Intent intent = null; try { @@ -893,12 +875,12 @@ public class LightningView { try { mActivity.startActivity(intent); } catch (ActivityNotFoundException e) { - Log.e(Constants.LOGTAG, "ActivityNotFoundException"); + Log.e(Constants.TAG, "ActivityNotFoundException"); } return true; } } - return super.shouldOverrideUrlLoading(view, url); + return mIntentUtils.startActivityForUrl(mWebView, url); } } @@ -925,7 +907,11 @@ public class LightningView { @Override public void onReceivedTitle(WebView view, String title) { - mTitle.setTitle(title); + if (title.length() > 0) { + mTitle.setTitle(title); + } else { + mTitle.setTitle(mActivity.getString(R.string.untitled)); + } mBrowserController.update(); mBrowserController.updateHistory(title, view.getUrl()); }