/*
* Tint Browser for Android
*
* Copyright (C) 2012 - to infinity and beyond J. Devauchelle and contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 3 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package com.seal.ui.activities;
import java.util.Random;
import java.util.Set;
import android.app.ActionBar.OnMenuVisibilityListener;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebIconDatabase;
import android.widget.Toast;
import com.seal.R;
import com.seal.controllers.Controller;
import com.seal.model.DownloadItem;
import com.seal.providers.BookmarksWrapper;
import com.seal.ui.dialogs.YesNoRememberDialog;
import com.seal.ui.managers.UIFactory;
import com.seal.ui.managers.UIManager;
import com.seal.utils.ApplicationUtils;
import com.seal.utils.Constants;
public class SealBrowserActivity extends Activity {
public static final int ACTIVITY_BOOKMARKS = 0;
public static final int ACTIVITY_OPEN_FILE_CHOOSER = 1;
public static final int CONTEXT_MENU_OPEN = Menu.FIRST + 10;
public static final int CONTEXT_MENU_OPEN_IN_NEW_TAB = Menu.FIRST + 11;
public static final int CONTEXT_MENU_OPEN_IN_BACKGROUND = Menu.FIRST + 12;
public static final int CONTEXT_MENU_DOWNLOAD = Menu.FIRST + 13;
public static final int CONTEXT_MENU_COPY = Menu.FIRST + 14;
public static final int CONTEXT_MENU_SEND_MAIL = Menu.FIRST + 15;
public static final int CONTEXT_MENU_SHARE = Menu.FIRST + 16;
private OnSharedPreferenceChangeListener mPreferenceChangeListener;
private UIManager mUIManager;
private SharedPreferences prefs;
private BroadcastReceiver mDownloadsReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
onReceivedDownloadNotification(context, intent);
}
};
private BroadcastReceiver mPackagesReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Controller.getInstance().getAddonManager().unbindAddons();
Controller.getInstance().getAddonManager().bindAddons();
}
};
private IntentFilter mPackagesFilter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(UIFactory.getMainLayout(this));
mUIManager = UIFactory.createUIManager(this);
getActionBar().setHomeButtonEnabled(true);
getActionBar().addOnMenuVisibilityListener(new OnMenuVisibilityListener() {
@Override
public void onMenuVisibilityChanged(boolean isVisible) {
mUIManager.onMenuVisibilityChanged(isVisible);
}
});
Controller.getInstance().init(mUIManager, this);
Controller.getInstance().getAddonManager().bindAddons();
initializeWebIconDatabase();
mPreferenceChangeListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
mUIManager.onSharedPreferenceChanged(sharedPreferences, key);
// If the user changed the history size, reset the last history
// truncation date.
if (Constants.PREFERENCE_HISTORY_SIZE.equals(key)) {
Editor prefEditor = sharedPreferences.edit();
prefEditor.putLong(Constants.TECHNICAL_PREFERENCE_LAST_HISTORY_TRUNCATION, -1);
prefEditor.commit();
}
}
};
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(mPreferenceChangeListener);
mPackagesFilter = new IntentFilter();
mPackagesFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
mPackagesFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
mPackagesFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
mPackagesFilter.addCategory(Intent.CATEGORY_DEFAULT);
mPackagesFilter.addDataScheme("package");
registerReceiver(mPackagesReceiver, mPackagesFilter);
Intent startIntent = getIntent();
boolean firstRun = prefs.getBoolean(Constants.TECHNICAL_PREFERENCE_FIRST_RUN, true);
if (firstRun) {
Editor editor = prefs.edit();
editor.putBoolean(Constants.TECHNICAL_PREFERENCE_FIRST_RUN, false);
editor.putInt(Constants.TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE, ApplicationUtils.getApplicationVersionCode(this));
editor.commit();
BookmarksWrapper.fillDefaultBookmaks(getContentResolver(), getResources().getStringArray(R.array.DefaultBookmarksTitles), getResources()
.getStringArray(R.array.DefaultBookmarksUrls));
} else {
int currentVersionCode = ApplicationUtils.getApplicationVersionCode(this);
int savedVersionCode = prefs.getInt(Constants.TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE, -1);
if (currentVersionCode != savedVersionCode) {
Editor editor = prefs.edit();
editor.putInt(Constants.TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE, currentVersionCode);
editor.commit();
}
}
mUIManager.onNewIntent(startIntent);
if (prefs.contains(Constants.TECHNICAL_PREFERENCE_SAVED_TABS)) {
final Set<String> tabs = prefs.getStringSet(Constants.TECHNICAL_PREFERENCE_SAVED_TABS, null);
if ((tabs != null) && (!tabs.isEmpty())) {
String tabsRestoreMode = prefs.getString(Constants.PREFERENCE_RESTORE_TABS, "ASK");
if ("ASK".equals(tabsRestoreMode)) {
final YesNoRememberDialog dialog = new YesNoRememberDialog(this);
dialog.setTitle(R.string.RestoreTabsDialogTitle);
dialog.setMessage(R.string.RestoreTabsDialogMessage);
dialog.setPositiveButtonListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
if (dialog.isRememberChecked()) {
Editor editor = prefs.edit();
editor.putString(Constants.PREFERENCE_RESTORE_TABS, "ALWAYS");
editor.commit();
}
restoreTabs(tabs);
}
});
dialog.setNegativeButtonListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
if (dialog.isRememberChecked()) {
Editor editor = prefs.edit();
editor.putString(Constants.PREFERENCE_RESTORE_TABS, "NEVER");
editor.commit();
}
}
});
dialog.show();
} else if ("ALWAYS".equals(tabsRestoreMode)) {
restoreTabs(tabs);
}
}
Editor editor = prefs.edit();
editor.remove(Constants.TECHNICAL_PREFERENCE_SAVED_TABS);
editor.commit();
}
}
private void restoreTabs(Set<String> tabs) {
boolean first = true;
for (String url : tabs) {
if (first) {
mUIManager.loadUrl(url);
first = false;
} else {
mUIManager.addTab(url, !first, false, false);
}
}
}
public void toggleFullScreen() {
mUIManager.toggleFullScreen();
}
public void shareCurrentPage() {
mUIManager.shareCurrentPage();
}
public void goToBookMark() {
mUIManager.openBookmarksActivityForResult();
}
public void addBookMark() {
mUIManager.addBookmarkFromCurrentPage();
}
public void pageSearch() {
mUIManager.onKeySearch();
}
/*
* @Override public boolean onCreateOptionsMenu(final Menu menu) {
* getMenuInflater().inflate(UIFactory.getMainMenuLayout(this), menu);
* return true; }
*
* @Override public boolean onPrepareOptionsMenu(Menu menu) {
* super.onPrepareOptionsMenu(menu);
*
* BaseWebViewFragment currentFragment =
* mUIManager.getCurrentWebViewFragment();
*
* menu.setGroupEnabled(R.id.MainActivity_DisabledOnStartPageMenuGroup,
* currentFragment != null && !currentFragment.isStartPageShown());
*
* CustomWebView currentWebView = mUIManager.getCurrentWebView();
*
* boolean privateBrowsing = currentWebView != null &&
* currentWebView.isPrivateBrowsingEnabled();
*
* menu.findItem(R.id.MainActivity_MenuIncognitoTab).setChecked(privateBrowsing
* ); menu.findItem(R.id.MainActivity_MenuFullScreen).setChecked(mUIManager.
* isFullScreen());
*
* menu.removeGroup(R.id.MainActivity_AddonsMenuGroup);
*
* if (!privateBrowsing && (currentWebView != null)) { List<AddonMenuItem>
* contributedMenuItems =
* Controller.getInstance().getAddonManager().getContributedMainMenuItems
* (currentWebView); for (AddonMenuItem item : contributedMenuItems) {
* menu.add(R.id.MainActivity_AddonsMenuGroup, item.getAddon().getMenuId(),
* 0, item.getMenuItem()); } }
*
* return true; }
*
* @Override public boolean onOptionsItemSelected(MenuItem item) { Intent i;
*
* switch (item.getItemId()) { case R.id.MainActivity_MenuAddTab:
* mUIManager.addTab(true,
* PreferenceManager.getDefaultSharedPreferences(this
* ).getBoolean(Constants.PREFERENCE_INCOGNITO_BY_DEFAULT, false), false);
* return true;
*
* case R.id.MainActivity_MenuCloseTab: mUIManager.closeCurrentTab(); return
* true;
*
* case R.id.MainActivity_MenuIncognitoTab:
* mUIManager.togglePrivateBrowsing(); return true;
* default: if
* (Controller.getInstance().getAddonManager().onContributedMainMenuItemSelected
* (this, item.getItemId(), mUIManager.getCurrentWebView())) { return true;
* } else { return super.onOptionsItemSelected(item); } } }
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == ACTIVITY_BOOKMARKS) {
if (resultCode == RESULT_OK) {
if (intent != null) {
Bundle b = intent.getExtras();
if (b != null) {
if (b.getBoolean(Constants.EXTRA_NEW_TAB)) {
mUIManager.addTab(false,
PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.PREFERENCE_INCOGNITO_BY_DEFAULT, false), false);
}
mUIManager.loadUrl(b.getString(Constants.EXTRA_URL));
}
}
}
} else if (requestCode == ACTIVITY_OPEN_FILE_CHOOSER) {
if (mUIManager.getUploadMessage() == null) {
return;
}
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData();
mUIManager.getUploadMessage().onReceiveValue(result);
mUIManager.setUploadMessage(null);
}
mUIManager.onActivityResult(requestCode, resultCode, intent);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
mUIManager.onNewIntent(intent);
if (intent != null && !TextUtils.isEmpty(intent.getStringExtra("QRCODE_URL"))) {
mUIManager.loadUrl(intent.getStringExtra("QRCODE_URL"));
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (prefs.getBoolean(Constants.TOGGLE_MENU_STATUS, false)) {
mUIManager.onClosePopMenu();
return true;
}
if (mUIManager.onKeyBack()) {
return true;
} else {
moveTaskToBack(true);
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
if (prefs.getBoolean(Constants.TOGGLE_MENU_STATUS, false)) {
mUIManager.onClosePopMenu();
return true;
} else {
mUIManager.onShowPopMenu();
return true;
}
} else {
return super.onKeyDown(keyCode, event);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
@Override
protected void onPause() {
super.onPause();
mUIManager.onMainActivityPause();
unregisterReceiver(mDownloadsReceiver);
}
@Override
protected void onResume() {
super.onResume();
mUIManager.onMainActivityResume();
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
filter.addAction(DownloadManager.ACTION_NOTIFICATION_CLICKED);
registerReceiver(mDownloadsReceiver, filter);
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
mUIManager.saveTabs();
super.onStop();
}
@Override
protected void onDestroy() {
Controller.getInstance().getAddonManager().unbindAddons();
WebIconDatabase.getInstance().close();
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(mPreferenceChangeListener);
unregisterReceiver(mPackagesReceiver);
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Do nothing for now, as default implementation mess up with
// tabs/fragment management.
// In the future, save and restore tabs.
// super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Do nothing for now, as default implementation mess up with
// tabs/fragment management.
// In the future, save and restore tabs.
// super.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onActionModeFinished(ActionMode mode) {
super.onActionModeFinished(mode);
mUIManager.onActionModeFinished(mode);
}
@Override
public void onActionModeStarted(ActionMode mode) {
super.onActionModeStarted(mode);
mUIManager.onActionModeStarted(mode);
}
public UIManager getUIManager() {
return mUIManager;
}
/**
* Initialize the Web icons database.
*/
private void initializeWebIconDatabase() {
final WebIconDatabase db = WebIconDatabase.getInstance();
db.open(getDir("icons", 0).getPath());
}
private void showNotification(String notificationTitle, String title, String message) {
Intent notificationIntent = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
PendingIntent contentIntent = PendingIntent.getActivity(this.getApplicationContext(), 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this).setSmallIcon(android.R.drawable.stat_sys_download_done).setTicker(notificationTitle)
.setContentTitle(title).setContentText(message).setContentIntent(contentIntent).getNotification();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).notify(new Random().nextInt(), notification);
}
private void onReceivedDownloadNotification(Context context, Intent intent) {
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
DownloadItem item = Controller.getInstance().getDownloadItemById(id);
if (item != null) {
// This is one of our downloads.
final DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Query query = new Query();
query.setFilterById(id);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int localUriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
int reasonIndex = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int statusIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(statusIndex);
if (status == DownloadManager.STATUS_SUCCESSFUL) {
String localUri = cursor.getString(localUriIndex);
Toast.makeText(context, String.format(getString(R.string.DownloadComplete), localUri), Toast.LENGTH_SHORT).show();
Controller.getInstance().getDownloadsList().remove(item);
showNotification(getString(R.string.DownloadComplete), item.getFileName(), getString(R.string.DownloadComplete));
} else if (status == DownloadManager.STATUS_FAILED) {
int reason = cursor.getInt(reasonIndex);
String message;
switch (reason) {
case DownloadManager.ERROR_FILE_ERROR:
case DownloadManager.ERROR_DEVICE_NOT_FOUND:
case DownloadManager.ERROR_INSUFFICIENT_SPACE:
message = getString(R.string.DownloadErrorDisk);
break;
case DownloadManager.ERROR_HTTP_DATA_ERROR:
case DownloadManager.ERROR_UNHANDLED_HTTP_CODE:
message = getString(R.string.DownloadErrorHttp);
break;
case DownloadManager.ERROR_TOO_MANY_REDIRECTS:
message = getString(R.string.DownloadErrorRedirection);
break;
default:
message = getString(R.string.DownloadErrorUnknown);
break;
}
Toast.makeText(context, String.format(getString(R.string.DownloadFailedWithErrorMessage), message), Toast.LENGTH_SHORT).show();
Controller.getInstance().getDownloadsList().remove(item);
}
}
}
} else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())) {
Intent i = new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(i);
}
}
}