blob: a98408c6c0e5c1f070a61cd188128bb0860b1146 [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.browser;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Browser;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebIconDatabase;
import android.webkit.WebIconDatabase.IconListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import java.util.HashMap;
import java.util.Vector;
interface BookmarksHistoryCallbacks {
public void onUrlSelected(String url, boolean newWindow);
public void onRemoveParentChildRelationShips();
}
public class CombinedBookmarkHistoryActivity extends Activity
implements BookmarksHistoryCallbacks, OnItemClickListener {
final static String NEWTAB_MODE = "newtab_mode";
final static String EXTRA_OPEN_NEW_WINDOW = "new_window";
final static String STARTING_FRAGMENT = "fragment";
final static String EVT_X = "evt_x";
final static String EVT_Y = "evt_y";
final static String EXTRA_TOP = "top";
final static String EXTRA_HEIGHT = "height";
final static int FRAGMENT_ID_BOOKMARKS = 1;
final static int FRAGMENT_ID_HISTORY = 2;
/**
* Used to inform BrowserActivity to remove the parent/child relationships
* from all the tabs.
*/
private String mExtraData;
/**
* Intent to be passed to calling Activity when finished. Keep a pointer to
* it locally so mExtraData can be added.
*/
private Intent mResultData;
/**
* Result code to pass back to calling Activity when finished.
*/
private int mResultCode;
/**
* Flag to inform the browser to force the result to open in a new tab.
*/
private boolean mNewTabMode;
private int mRequestedTop;
private int mRequestedHeight;
long mCurrentFragment;
static class IconListenerSet implements IconListener {
// Used to store favicons as we get them from the database
// FIXME: We use a different method to get the Favicons in
// BrowserBookmarksAdapter. They should probably be unified.
private HashMap<String, Bitmap> mUrlsToIcons;
private Vector<IconListener> mListeners;
public IconListenerSet() {
mUrlsToIcons = new HashMap<String, Bitmap>();
mListeners = new Vector<IconListener>();
}
@Override
public void onReceivedIcon(String url, Bitmap icon) {
mUrlsToIcons.put(url, icon);
for (IconListener listener : mListeners) {
listener.onReceivedIcon(url, icon);
}
}
public void addListener(IconListener listener) {
mListeners.add(listener);
}
public void removeListener(IconListener listener) {
mListeners.remove(listener);
}
public Bitmap getFavicon(String url) {
return mUrlsToIcons.get(url);
}
}
private static IconListenerSet sIconListenerSet;
static IconListenerSet getIconListenerSet() {
if (null == sIconListenerSet) {
sIconListenerSet = new IconListenerSet();
}
return sIconListenerSet;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bookmarks_history);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
ListView list = (ListView) findViewById(android.R.id.list);
list.setOnItemClickListener(this);
MatrixCursor cursor = new MatrixCursor(new String[] { "name", "_id" });
cursor.newRow().add(getString(R.string.bookmarks)).add(FRAGMENT_ID_BOOKMARKS);
cursor.newRow().add(getString(R.string.history)).add(FRAGMENT_ID_HISTORY);
list.setAdapter(new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor,
new String[] { "name" }, new int[] { android.R.id.text1 }));
int startingFragment = FRAGMENT_ID_BOOKMARKS;
Bundle extras = getIntent().getExtras();
if (extras != null) {
mNewTabMode = extras.getBoolean(NEWTAB_MODE);
mRequestedTop = extras.getInt(EXTRA_TOP, -1);
mRequestedHeight = extras.getInt(EXTRA_HEIGHT, -1);
startingFragment = extras.getInt(STARTING_FRAGMENT, FRAGMENT_ID_BOOKMARKS);
}
// Start up the default fragment
loadFragment(startingFragment);
// XXX: Must do this before launching the AsyncTask to avoid a
// potential crash if the icon database has not been created.
WebIconDatabase.getInstance();
// Do this every time we launch the activity in case a new favicon was
// added to the webkit db.
(new AsyncTask<Void, Void, Void>() {
@Override
public Void doInBackground(Void... v) {
Browser.requestAllIcons(getContentResolver(),
Browser.BookmarkColumns.FAVICON + " is NULL", getIconListenerSet());
return null;
}
}).execute();
}
@Override
public void onAttachedToWindow() {
if (mRequestedTop > -1) {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.x = 0;
lp.y = mRequestedTop;
lp.height = mRequestedHeight;
lp.gravity = Gravity.TOP | Gravity.LEFT;
getWindow().setAttributes(lp);
}
}
@Override
public boolean onTouchEvent(MotionEvent evt) {
if (((evt.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) && (evt.getY() < 0)) {
Intent result = new Intent();
result.putExtra(EVT_X, evt.getRawX());
result.putExtra(EVT_Y, evt.getRawY());
setResultFromChild(Activity.RESULT_CANCELED, result);
finish();
return true;
}
return super.onTouchEvent(evt);
}
private void loadFragment(int id) {
String fragmentClassName;
switch (id) {
case FRAGMENT_ID_BOOKMARKS:
fragmentClassName = BrowserBookmarksPage.class.getName();
break;
case FRAGMENT_ID_HISTORY:
fragmentClassName = BrowserHistoryPage.class.getName();
break;
default:
throw new IllegalArgumentException();
}
mCurrentFragment = id;
FragmentManager fm = getFragmentManager();
FragmentTransaction transaction = fm.openTransaction();
Fragment frag = Fragment.instantiate(this, fragmentClassName, getIntent().getExtras());
transaction.replace(R.id.fragment, frag);
transaction.commit();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (id == mCurrentFragment) return;
loadFragment((int) id);
}
/**
* Store extra data in the Intent to return to the calling Activity to tell
* it to clear the parent/child relationships from all tabs.
*/
@Override
public void onRemoveParentChildRelationShips() {
mExtraData = BrowserSettings.PREF_CLEAR_HISTORY;
}
/**
* Custom setResult() method so that the Intent can have extra data attached
* if necessary.
* @param resultCode Uses same codes as Activity.setResult
* @param data Intent returned to onActivityResult.
*/
private void setResultFromChild(int resultCode, Intent data) {
mResultCode = resultCode;
mResultData = data;
}
@Override
public void finish() {
if (mExtraData != null) {
mResultCode = RESULT_OK;
if (mResultData == null) mResultData = new Intent();
mResultData.putExtra(Intent.EXTRA_TEXT, mExtraData);
}
if (mNewTabMode) {
if (mResultData == null) mResultData = new Intent();
mResultData.putExtra(NEWTAB_MODE, true);
}
setResult(mResultCode, mResultData);
super.finish();
}
/**
* Report back to the calling activity to load a site.
* @param url Site to load.
* @param newWindow True if the URL should be loaded in a new window
*/
@Override
public void onUrlSelected(String url, boolean newWindow) {
Intent intent = new Intent().setAction(url);
if (newWindow) {
intent.putExtra(EXTRA_OPEN_NEW_WINDOW, true);
}
setResultFromChild(RESULT_OK, intent);
finish();
}
}