mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-30 19:28:40 +09:00
pt 1 in reviving the android build (copied from pm 28a1, wish me luck)
This commit is contained in:
parent
efa9662725
commit
d7788a6d6d
4249 changed files with 468189 additions and 0 deletions
843
mobile/android/base/java/org/mozilla/gecko/Tab.java
Normal file
843
mobile/android/base/java/org/mozilla/gecko/Tab.java
Normal file
|
|
@ -0,0 +1,843 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.annotation.RobocopTarget;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.db.URLMetadata;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconDescriptor;
|
||||
import org.mozilla.gecko.icons.IconRequestBuilder;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.mozilla.gecko.reader.ReaderModeUtils;
|
||||
import org.mozilla.gecko.reader.ReadingListHelper;
|
||||
import org.mozilla.gecko.toolbar.BrowserToolbar.TabEditingState;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.widget.SiteLogins;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
public class Tab {
|
||||
private static final String LOGTAG = "GeckoTab";
|
||||
|
||||
private static Pattern sColorPattern;
|
||||
private final int mId;
|
||||
private final BrowserDB mDB;
|
||||
private long mLastUsed;
|
||||
private String mUrl;
|
||||
private String mBaseDomain;
|
||||
private String mUserRequested; // The original url requested. May be typed by the user or sent by an extneral app for example.
|
||||
private String mTitle;
|
||||
private Bitmap mFavicon;
|
||||
private String mFaviconUrl;
|
||||
private String mApplicationId; // Intended to be null after explicit user action.
|
||||
|
||||
private IconRequestBuilder mIconRequestBuilder;
|
||||
private Future<IconResponse> mRunningIconRequest;
|
||||
|
||||
private boolean mHasFeeds;
|
||||
private boolean mHasOpenSearch;
|
||||
private final SiteIdentity mSiteIdentity;
|
||||
private SiteLogins mSiteLogins;
|
||||
private BitmapDrawable mThumbnail;
|
||||
private final int mParentId;
|
||||
// Indicates the url was loaded from a source external to the app. This will be cleared
|
||||
// when the user explicitly loads a new url (e.g. clicking a link is not explicit).
|
||||
private final boolean mExternal;
|
||||
private boolean mBookmark;
|
||||
private int mFaviconLoadId;
|
||||
private String mContentType;
|
||||
private boolean mHasTouchListeners;
|
||||
private final ArrayList<View> mPluginViews;
|
||||
private int mState;
|
||||
private Bitmap mThumbnailBitmap;
|
||||
private boolean mDesktopMode;
|
||||
private boolean mEnteringReaderMode;
|
||||
private final Context mAppContext;
|
||||
private ErrorType mErrorType = ErrorType.NONE;
|
||||
private volatile int mLoadProgress;
|
||||
private volatile int mRecordingCount;
|
||||
private volatile boolean mIsAudioPlaying;
|
||||
private volatile boolean mIsMediaPlaying;
|
||||
private String mMostRecentHomePanel;
|
||||
private boolean mShouldShowToolbarWithoutAnimationOnFirstSelection;
|
||||
|
||||
/*
|
||||
* Bundle containing restore data for the panel referenced in mMostRecentHomePanel. This can be
|
||||
* e.g. the most recent folder for the bookmarks panel, or any other state that should be
|
||||
* persisted. This is then used e.g. when returning to homepanels via history.
|
||||
*/
|
||||
private Bundle mMostRecentHomePanelData;
|
||||
|
||||
private int mHistoryIndex;
|
||||
private int mHistorySize;
|
||||
private boolean mCanDoBack;
|
||||
private boolean mCanDoForward;
|
||||
|
||||
private boolean mIsEditing;
|
||||
private final TabEditingState mEditingState = new TabEditingState();
|
||||
|
||||
// Will be true when tab is loaded from cache while device was offline.
|
||||
private boolean mLoadedFromCache;
|
||||
|
||||
public static final int STATE_DELAYED = 0;
|
||||
public static final int STATE_LOADING = 1;
|
||||
public static final int STATE_SUCCESS = 2;
|
||||
public static final int STATE_ERROR = 3;
|
||||
|
||||
public static final int LOAD_PROGRESS_INIT = 10;
|
||||
public static final int LOAD_PROGRESS_START = 20;
|
||||
public static final int LOAD_PROGRESS_LOCATION_CHANGE = 60;
|
||||
public static final int LOAD_PROGRESS_LOADED = 80;
|
||||
public static final int LOAD_PROGRESS_STOP = 100;
|
||||
|
||||
public enum ErrorType {
|
||||
CERT_ERROR, // Pages with certificate problems
|
||||
BLOCKED, // Pages blocked for phishing or malware warnings
|
||||
NET_ERROR, // All other types of error
|
||||
NONE // Non error pages
|
||||
}
|
||||
|
||||
public Tab(Context context, int id, String url, boolean external, int parentId, String title) {
|
||||
mAppContext = context.getApplicationContext();
|
||||
mDB = BrowserDB.from(context);
|
||||
mId = id;
|
||||
mUrl = url;
|
||||
mBaseDomain = "";
|
||||
mUserRequested = "";
|
||||
mExternal = external;
|
||||
mParentId = parentId;
|
||||
mTitle = title == null ? "" : title;
|
||||
mSiteIdentity = new SiteIdentity();
|
||||
mHistoryIndex = -1;
|
||||
mContentType = "";
|
||||
mPluginViews = new ArrayList<View>();
|
||||
mState = shouldShowProgress(url) ? STATE_LOADING : STATE_SUCCESS;
|
||||
mLoadProgress = LOAD_PROGRESS_INIT;
|
||||
mIconRequestBuilder = Icons.with(mAppContext).pageUrl(mUrl);
|
||||
|
||||
updateBookmark();
|
||||
}
|
||||
|
||||
private ContentResolver getContentResolver() {
|
||||
return mAppContext.getContentResolver();
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.CLOSED);
|
||||
}
|
||||
|
||||
@RobocopTarget
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
|
||||
public synchronized void onChange() {
|
||||
mLastUsed = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public synchronized long getLastUsed() {
|
||||
return mLastUsed;
|
||||
}
|
||||
|
||||
public int getParentId() {
|
||||
return mParentId;
|
||||
}
|
||||
|
||||
// may be null if user-entered query hasn't yet been resolved to a URI
|
||||
public synchronized String getURL() {
|
||||
return mUrl;
|
||||
}
|
||||
|
||||
// mUserRequested should never be null, but it may be an empty string
|
||||
public synchronized String getUserRequested() {
|
||||
return mUserRequested;
|
||||
}
|
||||
|
||||
// mTitle should never be null, but it may be an empty string
|
||||
public synchronized String getTitle() {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
public String getDisplayTitle() {
|
||||
if (mTitle != null && mTitle.length() > 0) {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
return mUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base domain of the loaded uri. Note that if the page is
|
||||
* a Reader mode uri, the base domain returned is that of the original uri.
|
||||
*/
|
||||
public String getBaseDomain() {
|
||||
return mBaseDomain;
|
||||
}
|
||||
|
||||
public Bitmap getFavicon() {
|
||||
return mFavicon;
|
||||
}
|
||||
|
||||
protected String getApplicationId() {
|
||||
return mApplicationId;
|
||||
}
|
||||
|
||||
protected void setApplicationId(final String applicationId) {
|
||||
mApplicationId = applicationId;
|
||||
}
|
||||
|
||||
public BitmapDrawable getThumbnail() {
|
||||
return mThumbnail;
|
||||
}
|
||||
|
||||
public String getMostRecentHomePanel() {
|
||||
return mMostRecentHomePanel;
|
||||
}
|
||||
|
||||
public Bundle getMostRecentHomePanelData() {
|
||||
return mMostRecentHomePanelData;
|
||||
}
|
||||
|
||||
public void setMostRecentHomePanel(String panelId) {
|
||||
mMostRecentHomePanel = panelId;
|
||||
mMostRecentHomePanelData = null;
|
||||
}
|
||||
|
||||
public void setMostRecentHomePanelData(Bundle data) {
|
||||
mMostRecentHomePanelData = data;
|
||||
}
|
||||
|
||||
public Bitmap getThumbnailBitmap(int width, int height) {
|
||||
if (mThumbnailBitmap != null) {
|
||||
// Bug 787318 - Honeycomb has a bug with bitmap caching, we can't
|
||||
// reuse the bitmap there.
|
||||
boolean honeycomb = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
|
||||
&& Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB_MR2);
|
||||
boolean sizeChange = mThumbnailBitmap.getWidth() != width
|
||||
|| mThumbnailBitmap.getHeight() != height;
|
||||
if (honeycomb || sizeChange) {
|
||||
mThumbnailBitmap = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (mThumbnailBitmap == null) {
|
||||
Bitmap.Config config = (GeckoAppShell.getScreenDepth() == 24) ?
|
||||
Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
|
||||
mThumbnailBitmap = Bitmap.createBitmap(width, height, config);
|
||||
}
|
||||
|
||||
return mThumbnailBitmap;
|
||||
}
|
||||
|
||||
public void updateThumbnail(final Bitmap b, final ThumbnailHelper.CachePolicy cachePolicy) {
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (b != null) {
|
||||
try {
|
||||
mThumbnail = new BitmapDrawable(mAppContext.getResources(), b);
|
||||
if (mState == Tab.STATE_SUCCESS && cachePolicy == ThumbnailHelper.CachePolicy.STORE) {
|
||||
saveThumbnailToDB(mDB);
|
||||
} else {
|
||||
// If the page failed to load, or requested that we not cache info about it, clear any previous
|
||||
// thumbnails we've stored.
|
||||
clearThumbnailFromDB(mDB);
|
||||
}
|
||||
} catch (OutOfMemoryError oom) {
|
||||
Log.w(LOGTAG, "Unable to create/scale bitmap.", oom);
|
||||
mThumbnail = null;
|
||||
}
|
||||
} else {
|
||||
mThumbnail = null;
|
||||
}
|
||||
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.THUMBNAIL);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized String getFaviconURL() {
|
||||
return mFaviconUrl;
|
||||
}
|
||||
|
||||
public boolean hasFeeds() {
|
||||
return mHasFeeds;
|
||||
}
|
||||
|
||||
public boolean hasOpenSearch() {
|
||||
return mHasOpenSearch;
|
||||
}
|
||||
|
||||
public boolean hasLoadedFromCache() {
|
||||
return mLoadedFromCache;
|
||||
}
|
||||
|
||||
public SiteIdentity getSiteIdentity() {
|
||||
return mSiteIdentity;
|
||||
}
|
||||
|
||||
public void resetSiteIdentity() {
|
||||
if (mSiteIdentity != null) {
|
||||
mSiteIdentity.reset();
|
||||
Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.SECURITY_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
public SiteLogins getSiteLogins() {
|
||||
return mSiteLogins;
|
||||
}
|
||||
|
||||
public boolean isBookmark() {
|
||||
return mBookmark;
|
||||
}
|
||||
|
||||
public boolean isExternal() {
|
||||
return mExternal;
|
||||
}
|
||||
|
||||
public synchronized void updateURL(String url) {
|
||||
if (url != null && url.length() > 0) {
|
||||
mUrl = url;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateUserRequested(String userRequested) {
|
||||
mUserRequested = userRequested;
|
||||
}
|
||||
|
||||
public void setErrorType(String type) {
|
||||
if ("blocked".equals(type))
|
||||
setErrorType(ErrorType.BLOCKED);
|
||||
else if ("certerror".equals(type))
|
||||
setErrorType(ErrorType.CERT_ERROR);
|
||||
else if ("neterror".equals(type))
|
||||
setErrorType(ErrorType.NET_ERROR);
|
||||
else
|
||||
setErrorType(ErrorType.NONE);
|
||||
}
|
||||
|
||||
public void setErrorType(ErrorType type) {
|
||||
mErrorType = type;
|
||||
}
|
||||
|
||||
public void setMetadata(JSONObject metadata) {
|
||||
if (metadata == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ContentResolver cr = mAppContext.getContentResolver();
|
||||
final URLMetadata urlMetadata = mDB.getURLMetadata();
|
||||
|
||||
final Map<String, Object> data = urlMetadata.fromJSON(metadata);
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
urlMetadata.save(cr, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ErrorType getErrorType() {
|
||||
return mErrorType;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
mContentType = (contentType == null) ? "" : contentType;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return mContentType;
|
||||
}
|
||||
|
||||
public int getHistoryIndex() {
|
||||
return mHistoryIndex;
|
||||
}
|
||||
|
||||
public int getHistorySize() {
|
||||
return mHistorySize;
|
||||
}
|
||||
|
||||
public synchronized void updateTitle(String title) {
|
||||
// Keep the title unchanged while entering reader mode.
|
||||
if (mEnteringReaderMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there was a title, but it hasn't changed, do nothing.
|
||||
if (mTitle != null &&
|
||||
TextUtils.equals(mTitle, title)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mTitle = (title == null ? "" : title);
|
||||
Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.TITLE);
|
||||
}
|
||||
|
||||
public void setState(int state) {
|
||||
mState = state;
|
||||
|
||||
if (mState != Tab.STATE_LOADING)
|
||||
mEnteringReaderMode = false;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
return mState;
|
||||
}
|
||||
|
||||
public void setHasTouchListeners(boolean aValue) {
|
||||
mHasTouchListeners = aValue;
|
||||
}
|
||||
|
||||
public boolean getHasTouchListeners() {
|
||||
return mHasTouchListeners;
|
||||
}
|
||||
|
||||
public synchronized void addFavicon(String faviconURL, int faviconSize, String mimeType) {
|
||||
mIconRequestBuilder
|
||||
.icon(IconDescriptor.createFavicon(faviconURL, faviconSize, mimeType))
|
||||
.deferBuild();
|
||||
}
|
||||
|
||||
public synchronized void addTouchicon(String iconUrl, int faviconSize, String mimeType) {
|
||||
mIconRequestBuilder
|
||||
.icon(IconDescriptor.createTouchicon(iconUrl, faviconSize, mimeType))
|
||||
.deferBuild();
|
||||
}
|
||||
|
||||
public void loadFavicon() {
|
||||
// Static Favicons never change
|
||||
if (AboutPages.isBuiltinIconPage(mUrl) && mFavicon != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
mRunningIconRequest = mIconRequestBuilder
|
||||
.build()
|
||||
.execute(new IconCallback() {
|
||||
@Override
|
||||
public void onIconResponse(IconResponse response) {
|
||||
mFavicon = response.getBitmap();
|
||||
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.FAVICON);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void clearFavicon() {
|
||||
// Cancel any ongoing favicon load (if we never finished downloading the old favicon before
|
||||
// we changed page).
|
||||
if (mRunningIconRequest != null) {
|
||||
mRunningIconRequest.cancel(true);
|
||||
}
|
||||
|
||||
// Keep the favicon unchanged while entering reader mode
|
||||
if (mEnteringReaderMode)
|
||||
return;
|
||||
|
||||
mFavicon = null;
|
||||
mFaviconUrl = null;
|
||||
}
|
||||
|
||||
public void setHasFeeds(boolean hasFeeds) {
|
||||
mHasFeeds = hasFeeds;
|
||||
}
|
||||
|
||||
public void setHasOpenSearch(boolean hasOpenSearch) {
|
||||
mHasOpenSearch = hasOpenSearch;
|
||||
}
|
||||
|
||||
public void setLoadedFromCache(boolean loadedFromCache) {
|
||||
mLoadedFromCache = loadedFromCache;
|
||||
}
|
||||
|
||||
public void updateIdentityData(JSONObject identityData) {
|
||||
mSiteIdentity.update(identityData);
|
||||
}
|
||||
|
||||
public void setSiteLogins(SiteLogins siteLogins) {
|
||||
mSiteLogins = siteLogins;
|
||||
}
|
||||
|
||||
void updateBookmark() {
|
||||
if (getURL() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
final String pageUrl = ReaderModeUtils.stripAboutReaderUrl(url);
|
||||
|
||||
mBookmark = mDB.isBookmark(getContentResolver(), pageUrl);
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.MENU_UPDATED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void addBookmark() {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String pageUrl = ReaderModeUtils.stripAboutReaderUrl(getURL());
|
||||
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDB.addBookmark(getContentResolver(), mTitle, pageUrl);
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.BOOKMARK_ADDED);
|
||||
}
|
||||
});
|
||||
|
||||
if (AboutPages.isAboutReader(url)) {
|
||||
ReadingListHelper.cacheReaderItem(pageUrl, mId, mAppContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeBookmark() {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String pageUrl = ReaderModeUtils.stripAboutReaderUrl(getURL());
|
||||
|
||||
ThreadUtils.postToBackgroundThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDB.removeBookmarksWithURL(getContentResolver(), pageUrl);
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.BOOKMARK_REMOVED);
|
||||
}
|
||||
});
|
||||
|
||||
// We need to ensure we remove readercached items here - we could have switched out of readermode
|
||||
// before unbookmarking, so we don't necessarily have an about:reader URL here.
|
||||
ReadingListHelper.removeCachedReaderItem(pageUrl, mAppContext);
|
||||
}
|
||||
|
||||
public boolean isEnteringReaderMode() {
|
||||
return mEnteringReaderMode;
|
||||
}
|
||||
|
||||
public void doReload(boolean bypassCache) {
|
||||
GeckoAppShell.notifyObservers("Session:Reload", "{\"bypassCache\":" + String.valueOf(bypassCache) + "}");
|
||||
}
|
||||
|
||||
// Our version of nsSHistory::GetCanGoBack
|
||||
public boolean canDoBack() {
|
||||
return mCanDoBack;
|
||||
}
|
||||
|
||||
public boolean doBack() {
|
||||
if (!canDoBack())
|
||||
return false;
|
||||
|
||||
GeckoAppShell.notifyObservers("Session:Back", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
public void doStop() {
|
||||
GeckoAppShell.notifyObservers("Session:Stop", "");
|
||||
}
|
||||
|
||||
// Our version of nsSHistory::GetCanGoForward
|
||||
public boolean canDoForward() {
|
||||
return mCanDoForward;
|
||||
}
|
||||
|
||||
public boolean doForward() {
|
||||
if (!canDoForward())
|
||||
return false;
|
||||
|
||||
GeckoAppShell.notifyObservers("Session:Forward", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
void handleLocationChange(JSONObject message) throws JSONException {
|
||||
final String uri = message.getString("uri");
|
||||
final String oldUrl = getURL();
|
||||
final boolean sameDocument = message.getBoolean("sameDocument");
|
||||
mEnteringReaderMode = ReaderModeUtils.isEnteringReaderMode(oldUrl, uri);
|
||||
mHistoryIndex = message.getInt("historyIndex");
|
||||
mHistorySize = message.getInt("historySize");
|
||||
mCanDoBack = message.getBoolean("canGoBack");
|
||||
mCanDoForward = message.getBoolean("canGoForward");
|
||||
|
||||
if (!TextUtils.equals(oldUrl, uri)) {
|
||||
updateURL(uri);
|
||||
updateBookmark();
|
||||
if (!sameDocument) {
|
||||
// We can unconditionally clear the favicon and title here: we
|
||||
// already filtered both cases in which this was a (pseudo-)
|
||||
// spurious location change, so we're definitely loading a new
|
||||
// page.
|
||||
clearFavicon();
|
||||
|
||||
// Start to build a new request to load a favicon.
|
||||
mIconRequestBuilder = Icons.with(mAppContext)
|
||||
.pageUrl(uri);
|
||||
|
||||
// Load local static Favicons immediately
|
||||
if (AboutPages.isBuiltinIconPage(uri)) {
|
||||
loadFavicon();
|
||||
}
|
||||
|
||||
updateTitle(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (sameDocument) {
|
||||
// We can get a location change event for the same document with an anchor tag
|
||||
// Notify listeners so that buttons like back or forward will update themselves
|
||||
Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.LOCATION_CHANGE, oldUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
setContentType(message.getString("contentType"));
|
||||
updateUserRequested(message.getString("userRequested"));
|
||||
mBaseDomain = message.optString("baseDomain");
|
||||
|
||||
setHasFeeds(false);
|
||||
setHasOpenSearch(false);
|
||||
mSiteIdentity.reset();
|
||||
setSiteLogins(null);
|
||||
setHasTouchListeners(false);
|
||||
setErrorType(ErrorType.NONE);
|
||||
setLoadProgressIfLoading(LOAD_PROGRESS_LOCATION_CHANGE);
|
||||
|
||||
Tabs.getInstance().notifyListeners(this, Tabs.TabEvents.LOCATION_CHANGE, oldUrl);
|
||||
}
|
||||
|
||||
private static boolean shouldShowProgress(final String url) {
|
||||
return !AboutPages.isAboutPage(url);
|
||||
}
|
||||
|
||||
void handleDocumentStart(boolean restoring, String url) {
|
||||
setLoadProgress(LOAD_PROGRESS_START);
|
||||
setState((!restoring && shouldShowProgress(url)) ? STATE_LOADING : STATE_SUCCESS);
|
||||
mSiteIdentity.reset();
|
||||
}
|
||||
|
||||
void handleDocumentStop(boolean success) {
|
||||
setState(success ? STATE_SUCCESS : STATE_ERROR);
|
||||
|
||||
final String oldURL = getURL();
|
||||
final Tab tab = this;
|
||||
tab.setLoadProgress(LOAD_PROGRESS_STOP);
|
||||
|
||||
ThreadUtils.getBackgroundHandler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// tab.getURL() may return null
|
||||
if (!TextUtils.equals(oldURL, getURL()))
|
||||
return;
|
||||
|
||||
ThumbnailHelper.getInstance().getAndProcessThumbnailFor(tab);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
void handleContentLoaded() {
|
||||
setLoadProgressIfLoading(LOAD_PROGRESS_LOADED);
|
||||
}
|
||||
|
||||
protected void saveThumbnailToDB(final BrowserDB db) {
|
||||
final BitmapDrawable thumbnail = mThumbnail;
|
||||
if (thumbnail == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
db.updateThumbnailForUrl(getContentResolver(), url, thumbnail);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void loadThumbnailFromDB(final BrowserDB db) {
|
||||
try {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] thumbnail = db.getThumbnailForUrl(getContentResolver(), url);
|
||||
if (thumbnail == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bitmap bitmap = BitmapUtils.decodeByteArray(thumbnail);
|
||||
mThumbnail = new BitmapDrawable(mAppContext.getResources(), bitmap);
|
||||
|
||||
Tabs.getInstance().notifyListeners(Tab.this, Tabs.TabEvents.THUMBNAIL);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void clearThumbnailFromDB(final BrowserDB db) {
|
||||
try {
|
||||
final String url = getURL();
|
||||
if (url == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Passing in a null thumbnail will delete the stored thumbnail for this url
|
||||
db.updateThumbnailForUrl(getContentResolver(), url, null);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void addPluginView(View view) {
|
||||
mPluginViews.add(view);
|
||||
}
|
||||
|
||||
public void removePluginView(View view) {
|
||||
mPluginViews.remove(view);
|
||||
}
|
||||
|
||||
public View[] getPluginViews() {
|
||||
return mPluginViews.toArray(new View[mPluginViews.size()]);
|
||||
}
|
||||
|
||||
public void setDesktopMode(boolean enabled) {
|
||||
mDesktopMode = enabled;
|
||||
}
|
||||
|
||||
public boolean getDesktopMode() {
|
||||
return mDesktopMode;
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tab load progress to the given percentage.
|
||||
*
|
||||
* @param progressPercentage Percentage to set progress to (0-100)
|
||||
*/
|
||||
void setLoadProgress(int progressPercentage) {
|
||||
mLoadProgress = progressPercentage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tab load progress to the given percentage only if the tab is
|
||||
* currently loading.
|
||||
*
|
||||
* about:neterror can trigger a STOP before other page load events (bug
|
||||
* 976426), so any post-START events should make sure the page is loading
|
||||
* before updating progress.
|
||||
*
|
||||
* @param progressPercentage Percentage to set progress to (0-100)
|
||||
*/
|
||||
void setLoadProgressIfLoading(int progressPercentage) {
|
||||
if (getState() == STATE_LOADING) {
|
||||
setLoadProgress(progressPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tab load progress percentage.
|
||||
*
|
||||
* @return Current progress percentage
|
||||
*/
|
||||
public int getLoadProgress() {
|
||||
return mLoadProgress;
|
||||
}
|
||||
|
||||
public void setRecording(boolean isRecording) {
|
||||
if (isRecording) {
|
||||
mRecordingCount++;
|
||||
} else {
|
||||
mRecordingCount--;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRecording() {
|
||||
return mRecordingCount > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "MediaPlaying" is used for controling media control interface and
|
||||
* means the tab has playing media.
|
||||
*
|
||||
* @param isMediaPlaying the tab has any playing media or not
|
||||
*/
|
||||
public void setIsMediaPlaying(boolean isMediaPlaying) {
|
||||
mIsMediaPlaying = isMediaPlaying;
|
||||
}
|
||||
|
||||
public boolean isMediaPlaying() {
|
||||
return mIsMediaPlaying;
|
||||
}
|
||||
|
||||
/**
|
||||
* The "AudioPlaying" is used for showing the tab sound indicator and means
|
||||
* the tab has playing media and the media is audible.
|
||||
*
|
||||
* @param isAudioPlaying the tab has any audible playing media or not
|
||||
*/
|
||||
public void setIsAudioPlaying(boolean isAudioPlaying) {
|
||||
mIsAudioPlaying = isAudioPlaying;
|
||||
}
|
||||
|
||||
public boolean isAudioPlaying() {
|
||||
return mIsAudioPlaying;
|
||||
}
|
||||
|
||||
public boolean isEditing() {
|
||||
return mIsEditing;
|
||||
}
|
||||
|
||||
public void setIsEditing(final boolean isEditing) {
|
||||
this.mIsEditing = isEditing;
|
||||
}
|
||||
|
||||
public TabEditingState getEditingState() {
|
||||
return mEditingState;
|
||||
}
|
||||
|
||||
public void setShouldShowToolbarWithoutAnimationOnFirstSelection(final boolean shouldShowWithoutAnimation) {
|
||||
mShouldShowToolbarWithoutAnimationOnFirstSelection = shouldShowWithoutAnimation;
|
||||
}
|
||||
|
||||
public boolean getShouldShowToolbarWithoutAnimationOnFirstSelection() {
|
||||
return mShouldShowToolbarWithoutAnimationOnFirstSelection;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue