зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1297850) for robocop bustage a=backout CLOSED TREE
Backed out changeset e83c9eb279a9 (bug 1297850) Backed out changeset 979694026137 (bug 1297850)
This commit is contained in:
Родитель
9c03d71187
Коммит
1f49af4fc0
|
@ -795,6 +795,34 @@ ClientLayerManager::GetBackendName(nsAString& aName)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
FrameMetrics& aMetrics,
|
||||
bool aDrawingCritical)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
MOZ_ASSERT(aMetrics.IsScrollable());
|
||||
// This is derived from the code in
|
||||
// gfx/layers/ipc/CompositorBridgeParent.cpp::TransformShadowTree.
|
||||
CSSToLayerScale paintScale = aMetrics.LayersPixelsPerCSSPixel().ToScaleFactor();
|
||||
const CSSRect& metricsDisplayPort =
|
||||
(aDrawingCritical && !aMetrics.GetCriticalDisplayPort().IsEmpty()) ?
|
||||
aMetrics.GetCriticalDisplayPort() : aMetrics.GetDisplayPort();
|
||||
LayerRect displayPort = (metricsDisplayPort + aMetrics.GetScrollOffset()) * paintScale;
|
||||
|
||||
ParentLayerPoint scrollOffset;
|
||||
CSSToParentLayerScale zoom;
|
||||
bool ret = AndroidBridge::Bridge()->ProgressiveUpdateCallback(
|
||||
aHasPendingNewThebesContent, displayPort, paintScale.scale, aDrawingCritical,
|
||||
scrollOffset, zoom);
|
||||
aMetrics.SetScrollOffset(scrollOffset / zoom);
|
||||
aMetrics.SetZoom(CSSToParentLayerScale2D(zoom));
|
||||
return ret;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::AsyncPanZoomEnabled() const
|
||||
{
|
||||
|
|
|
@ -155,6 +155,22 @@ public:
|
|||
// Disable component alpha layers with the software compositor.
|
||||
virtual bool ShouldAvoidComponentAlphaLayers() override { return !IsCompositingCheap(); }
|
||||
|
||||
/**
|
||||
* Called for each iteration of a progressive tile update. Updates
|
||||
* aMetrics with the current scroll offset and scale being used to composite
|
||||
* the primary scrollable layer in this manager, to determine what area
|
||||
* intersects with the target composition bounds.
|
||||
* aDrawingCritical will be true if the current drawing operation is using
|
||||
* the critical displayport.
|
||||
* Returns true if the update should continue, or false if it should be
|
||||
* cancelled.
|
||||
* This is only called if gfxPlatform::UseProgressiveTilePainting() returns
|
||||
* true.
|
||||
*/
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
FrameMetrics& aMetrics,
|
||||
bool aDrawingCritical);
|
||||
|
||||
bool InConstruction() { return mPhase == PHASE_CONSTRUCTION; }
|
||||
#ifdef DEBUG
|
||||
bool InDrawing() { return mPhase == PHASE_DRAWING; }
|
||||
|
|
|
@ -367,6 +367,14 @@ public abstract class GeckoApp
|
|||
mFormAssistPopup.hide();
|
||||
break;
|
||||
|
||||
case LOADED:
|
||||
// Sync up the layer view and the tab if the tab is
|
||||
// currently displayed.
|
||||
LayerView layerView = mLayerView;
|
||||
if (layerView != null && Tabs.getInstance().isSelectedTab(tab))
|
||||
layerView.setBackgroundColor(tab.getBackgroundColor());
|
||||
break;
|
||||
|
||||
case DESKTOP_MODE_CHANGE:
|
||||
if (Tabs.getInstance().isSelectedTab(tab))
|
||||
invalidateOptionsMenu();
|
||||
|
|
|
@ -13,6 +13,11 @@ import org.mozilla.gecko.db.BrowserDB;
|
|||
public class PrivateTab extends Tab {
|
||||
public PrivateTab(Context context, int id, String url, boolean external, int parentId, String title) {
|
||||
super(context, id, url, external, parentId, title);
|
||||
|
||||
// Init background to private_toolbar_grey to ensure flicker-free
|
||||
// private tab creation. Page loads will reset it to white as expected.
|
||||
final int bgColor = ContextCompat.getColor(context, R.color.tabs_tray_grey_pressed);
|
||||
setBackgroundColor(bgColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -74,6 +74,7 @@ public class Tab {
|
|||
private ZoomConstraints mZoomConstraints;
|
||||
private boolean mIsRTL;
|
||||
private final ArrayList<View> mPluginViews;
|
||||
private int mBackgroundColor;
|
||||
private int mState;
|
||||
private Bitmap mThumbnailBitmap;
|
||||
private boolean mDesktopMode;
|
||||
|
@ -115,6 +116,8 @@ public class Tab {
|
|||
public static final int LOAD_PROGRESS_LOADED = 80;
|
||||
public static final int LOAD_PROGRESS_STOP = 100;
|
||||
|
||||
private static final int DEFAULT_BACKGROUND_COLOR = Color.WHITE;
|
||||
|
||||
public enum ErrorType {
|
||||
CERT_ERROR, // Pages with certificate problems
|
||||
BLOCKED, // Pages blocked for phishing or malware warnings
|
||||
|
@ -140,6 +143,11 @@ public class Tab {
|
|||
mState = shouldShowProgress(url) ? STATE_LOADING : STATE_SUCCESS;
|
||||
mLoadProgress = LOAD_PROGRESS_INIT;
|
||||
|
||||
// At startup, the background is set to a color specified by LayerView
|
||||
// when the LayerView is created. Shortly after, this background color
|
||||
// will be used before the tab's content is shown.
|
||||
mBackgroundColor = DEFAULT_BACKGROUND_COLOR;
|
||||
|
||||
updateBookmark();
|
||||
}
|
||||
|
||||
|
@ -690,6 +698,7 @@ public class Tab {
|
|||
setSiteLogins(null);
|
||||
setZoomConstraints(new ZoomConstraints(true));
|
||||
setHasTouchListeners(false);
|
||||
setBackgroundColor(DEFAULT_BACKGROUND_COLOR);
|
||||
setErrorType(ErrorType.NONE);
|
||||
setLoadProgressIfLoading(LOAD_PROGRESS_LOCATION_CHANGE);
|
||||
|
||||
|
@ -794,6 +803,38 @@ public class Tab {
|
|||
return mPluginViews.toArray(new View[mPluginViews.size()]);
|
||||
}
|
||||
|
||||
public int getBackgroundColor() {
|
||||
return mBackgroundColor;
|
||||
}
|
||||
|
||||
/** Sets a new color for the background. */
|
||||
public void setBackgroundColor(int color) {
|
||||
mBackgroundColor = color;
|
||||
}
|
||||
|
||||
/** Parses and sets a new color for the background. */
|
||||
public void setBackgroundColor(String newColor) {
|
||||
setBackgroundColor(parseColorFromGecko(newColor));
|
||||
}
|
||||
|
||||
// Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
|
||||
// cannot be parsed, returns white.
|
||||
private static int parseColorFromGecko(String string) {
|
||||
if (sColorPattern == null) {
|
||||
sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
|
||||
}
|
||||
|
||||
Matcher matcher = sColorPattern.matcher(string);
|
||||
if (!matcher.matches()) {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
int r = Integer.parseInt(matcher.group(1));
|
||||
int g = Integer.parseInt(matcher.group(2));
|
||||
int b = Integer.parseInt(matcher.group(3));
|
||||
return Color.rgb(r, g, b);
|
||||
}
|
||||
|
||||
public void setDesktopMode(boolean enabled) {
|
||||
mDesktopMode = enabled;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,7 @@ public class Tabs implements GeckoEventListener {
|
|||
"Content:StateChange",
|
||||
"Content:LoadError",
|
||||
"Content:PageShow",
|
||||
"DOMContentLoaded",
|
||||
"DOMTitleChanged",
|
||||
"Link:Favicon",
|
||||
"Link:Feed",
|
||||
|
@ -517,6 +518,18 @@ public class Tabs implements GeckoEventListener {
|
|||
tab.setLoadedFromCache(message.getBoolean("fromCache"));
|
||||
tab.updateUserRequested(message.getString("userRequested"));
|
||||
notifyListeners(tab, TabEvents.PAGE_SHOW);
|
||||
} else if (event.equals("DOMContentLoaded")) {
|
||||
tab.handleContentLoaded();
|
||||
String backgroundColor = message.getString("bgColor");
|
||||
if (backgroundColor != null) {
|
||||
tab.setBackgroundColor(backgroundColor);
|
||||
} else {
|
||||
// Default to white if no color is given
|
||||
tab.setBackgroundColor(Color.WHITE);
|
||||
}
|
||||
tab.setErrorType(message.optString("errorType"));
|
||||
tab.setMetadata(message.optJSONObject("metadata"));
|
||||
notifyListeners(tab, Tabs.TabEvents.LOADED);
|
||||
} else if (event.equals("DOMTitleChanged")) {
|
||||
tab.updateTitle(message.getString("title"));
|
||||
} else if (event.equals("Link:Favicon")) {
|
||||
|
|
|
@ -179,6 +179,10 @@ public class Prompt implements OnClickListener, OnCancelListener, OnItemClickLis
|
|||
|
||||
private void create(String title, String text, PromptListItem[] listItems, int choiceMode)
|
||||
throws IllegalStateException {
|
||||
final LayerView view = GeckoAppShell.getLayerView();
|
||||
if (view != null) {
|
||||
view.abortPanning();
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
|
|
|
@ -1143,6 +1143,20 @@ public class GeckoAppShell
|
|||
});
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
public static void notifyDefaultPrevented(final boolean defaultPrevented) {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LayerView view = getLayerView();
|
||||
PanZoomController controller = (view == null ? null : view.getPanZoomController());
|
||||
if (controller != null) {
|
||||
controller.notifyDefaultActionPrevented(defaultPrevented);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
public static boolean isNetworkLinkUp() {
|
||||
ConnectivityManager cm = (ConnectivityManager)
|
||||
|
|
|
@ -89,6 +89,8 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
* fields. */
|
||||
private volatile ImmutableViewportMetrics mViewportMetrics;
|
||||
|
||||
private ZoomConstraints mZoomConstraints;
|
||||
|
||||
private volatile boolean mGeckoIsReady;
|
||||
|
||||
private final PanZoomController mPanZoomController;
|
||||
|
@ -123,8 +125,11 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
mViewportMetrics = new ImmutableViewportMetrics(displayMetrics)
|
||||
.setViewportSize(view.getWidth(), view.getHeight());
|
||||
mZoomConstraints = new ZoomConstraints(false);
|
||||
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
if (tab != null) {
|
||||
mZoomConstraints = tab.getZoomConstraints();
|
||||
mViewportMetrics = mViewportMetrics.setIsRTL(tab.getIsRTL());
|
||||
}
|
||||
|
||||
|
@ -178,6 +183,24 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
mGeckoIsReady = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this client is fine with performing a redraw operation or false if it
|
||||
* would prefer that the action didn't take place.
|
||||
*/
|
||||
private boolean getRedrawHint() {
|
||||
if (mForceRedraw) {
|
||||
mForceRedraw = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mPanZoomController.getRedrawHint()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics,
|
||||
mPanZoomController.getVelocityVector(), mDisplayPort);
|
||||
}
|
||||
|
||||
public LayerView getView() {
|
||||
return mView;
|
||||
}
|
||||
|
@ -295,11 +318,24 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPanZoomController.pageRectUpdated();
|
||||
mView.requestRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Aborts any pan/zoom animation that is currently in progress. */
|
||||
private void abortPanZoomAnimation() {
|
||||
if (mPanZoomController != null) {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPanZoomController.abortAnimation();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The different types of Viewport messages handled. All viewport events
|
||||
* expect a display-port to be returned, but can handle one not being
|
||||
|
@ -310,6 +346,57 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
PAGE_SIZE // The viewport's page-size has changed
|
||||
}
|
||||
|
||||
/** Viewport message handler. */
|
||||
private DisplayPortMetrics handleViewportMessage(ImmutableViewportMetrics messageMetrics, ViewportMessageType type) {
|
||||
synchronized (getLock()) {
|
||||
ImmutableViewportMetrics newMetrics;
|
||||
ImmutableViewportMetrics oldMetrics = getViewportMetrics();
|
||||
|
||||
switch (type) {
|
||||
default:
|
||||
case UPDATE:
|
||||
// Keep the old viewport size
|
||||
newMetrics = messageMetrics.setViewportSize(oldMetrics.viewportRectWidth, oldMetrics.viewportRectHeight);
|
||||
if (mToolbarAnimator.isResizing()) {
|
||||
// If we're in the middle of a resize, we don't want to clobber
|
||||
// the scroll offset, so grab the one from the oldMetrics and
|
||||
// keep using that. We also don't want to abort animations,
|
||||
// because at that point we're guaranteed to not be animating
|
||||
// anyway, and calling abortPanZoomAnimation has a nasty
|
||||
// side-effect of clmaping and clobbering the metrics, which
|
||||
// we don't want here.
|
||||
newMetrics = newMetrics.setViewportOrigin(oldMetrics.viewportRectLeft, oldMetrics.viewportRectTop);
|
||||
break;
|
||||
}
|
||||
if (!oldMetrics.fuzzyEquals(newMetrics)) {
|
||||
abortPanZoomAnimation();
|
||||
}
|
||||
break;
|
||||
case PAGE_SIZE:
|
||||
// adjust the page dimensions to account for differences in zoom
|
||||
// between the rendered content (which is what Gecko tells us)
|
||||
// and our zoom level (which may have diverged).
|
||||
float scaleFactor = oldMetrics.zoomFactor / messageMetrics.zoomFactor;
|
||||
newMetrics = oldMetrics.setPageRect(RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect());
|
||||
break;
|
||||
}
|
||||
|
||||
// Update the Gecko-side viewport metrics. Make sure to do this
|
||||
// before modifying the metrics below.
|
||||
final ImmutableViewportMetrics geckoMetrics = newMetrics.clamp();
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mGeckoViewport = geckoMetrics;
|
||||
}
|
||||
});
|
||||
|
||||
setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE);
|
||||
mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null);
|
||||
}
|
||||
return mDisplayPort;
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
void contentDocumentChanged() {
|
||||
mContentDocumentIsDisplayed = false;
|
||||
|
@ -320,6 +407,112 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
return mContentDocumentIsDisplayed;
|
||||
}
|
||||
|
||||
// This is called on the Gecko thread to determine if we're still interested
|
||||
// in the update of this display-port to continue. We can return true here
|
||||
// to abort the current update and continue with any subsequent ones. This
|
||||
// is useful for slow-to-render pages when the display-port starts lagging
|
||||
// behind enough that continuing to draw it is wasted effort.
|
||||
@WrapForJNI
|
||||
public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent,
|
||||
float x, float y, float width, float height,
|
||||
float resolution, boolean lowPrecision) {
|
||||
// Reset the checkerboard risk flag when switching to low precision
|
||||
// rendering.
|
||||
if (lowPrecision && !mLastProgressiveUpdateWasLowPrecision) {
|
||||
// Skip low precision rendering until we're at risk of checkerboarding.
|
||||
if (!mProgressiveUpdateWasInDanger) {
|
||||
mProgressiveUpdateData.abort = true;
|
||||
return mProgressiveUpdateData;
|
||||
}
|
||||
mProgressiveUpdateWasInDanger = false;
|
||||
}
|
||||
mLastProgressiveUpdateWasLowPrecision = lowPrecision;
|
||||
|
||||
// Grab a local copy of the last display-port sent to Gecko and the
|
||||
// current viewport metrics to avoid races when accessing them.
|
||||
DisplayPortMetrics displayPort = mDisplayPort;
|
||||
ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
|
||||
mProgressiveUpdateData.setViewport(viewportMetrics);
|
||||
mProgressiveUpdateData.abort = false;
|
||||
|
||||
// Always abort updates if the resolution has changed. There's no use
|
||||
// in drawing at the incorrect resolution.
|
||||
if (!FloatUtils.fuzzyEquals(resolution, viewportMetrics.zoomFactor)) {
|
||||
Log.d(LOGTAG, "Aborting draw due to resolution change: " + resolution + " != " + viewportMetrics.zoomFactor);
|
||||
mProgressiveUpdateData.abort = true;
|
||||
return mProgressiveUpdateData;
|
||||
}
|
||||
|
||||
// Store the high precision displayport for comparison when doing low
|
||||
// precision updates.
|
||||
if (!lowPrecision) {
|
||||
if (!FloatUtils.fuzzyEquals(resolution, mProgressiveUpdateDisplayPort.resolution) ||
|
||||
!FloatUtils.fuzzyEquals(x, mProgressiveUpdateDisplayPort.getLeft()) ||
|
||||
!FloatUtils.fuzzyEquals(y, mProgressiveUpdateDisplayPort.getTop()) ||
|
||||
!FloatUtils.fuzzyEquals(x + width, mProgressiveUpdateDisplayPort.getRight()) ||
|
||||
!FloatUtils.fuzzyEquals(y + height, mProgressiveUpdateDisplayPort.getBottom())) {
|
||||
mProgressiveUpdateDisplayPort =
|
||||
new DisplayPortMetrics(x, y, x + width, y + height, resolution);
|
||||
}
|
||||
}
|
||||
|
||||
// If we're not doing low precision draws and we're about to
|
||||
// checkerboard, enable low precision drawing.
|
||||
if (!lowPrecision && !mProgressiveUpdateWasInDanger) {
|
||||
if (DisplayPortCalculator.aboutToCheckerboard(viewportMetrics,
|
||||
mPanZoomController.getVelocityVector(), mProgressiveUpdateDisplayPort)) {
|
||||
mProgressiveUpdateWasInDanger = true;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX All sorts of rounding happens inside Gecko that becomes hard to
|
||||
// account exactly for. Given we align the display-port to tile
|
||||
// boundaries (and so they rarely vary by sub-pixel amounts), just
|
||||
// check that values are within a couple of pixels of the
|
||||
// display-port bounds.
|
||||
|
||||
// Never abort drawing if we can't be sure we've sent a more recent
|
||||
// display-port. If we abort updating when we shouldn't, we can end up
|
||||
// with blank regions on the screen and we open up the risk of entering
|
||||
// an endless updating cycle.
|
||||
if (Math.abs(displayPort.getLeft() - mProgressiveUpdateDisplayPort.getLeft()) <= 2 &&
|
||||
Math.abs(displayPort.getTop() - mProgressiveUpdateDisplayPort.getTop()) <= 2 &&
|
||||
Math.abs(displayPort.getBottom() - mProgressiveUpdateDisplayPort.getBottom()) <= 2 &&
|
||||
Math.abs(displayPort.getRight() - mProgressiveUpdateDisplayPort.getRight()) <= 2) {
|
||||
return mProgressiveUpdateData;
|
||||
}
|
||||
|
||||
// Abort updates when the display-port no longer contains the visible
|
||||
// area of the page (that is, the viewport cropped by the page
|
||||
// boundaries).
|
||||
// XXX This makes the assumption that we never let the visible area of
|
||||
// the page fall outside of the display-port.
|
||||
if (Math.max(viewportMetrics.viewportRectLeft, viewportMetrics.pageRectLeft) + 1 < x ||
|
||||
Math.max(viewportMetrics.viewportRectTop, viewportMetrics.pageRectTop) + 1 < y ||
|
||||
Math.min(viewportMetrics.viewportRectRight(), viewportMetrics.pageRectRight) - 1 > x + width ||
|
||||
Math.min(viewportMetrics.viewportRectBottom(), viewportMetrics.pageRectBottom) - 1 > y + height) {
|
||||
Log.d(LOGTAG, "Aborting update due to viewport not in display-port");
|
||||
mProgressiveUpdateData.abort = true;
|
||||
|
||||
// Enable low-precision drawing, as we're likely to be in danger if
|
||||
// this situation has been encountered.
|
||||
mProgressiveUpdateWasInDanger = true;
|
||||
|
||||
return mProgressiveUpdateData;
|
||||
}
|
||||
|
||||
// Abort drawing stale low-precision content if there's a more recent
|
||||
// display-port in the pipeline.
|
||||
if (lowPrecision && !aHasPendingNewThebesContent) {
|
||||
mProgressiveUpdateData.abort = true;
|
||||
}
|
||||
return mProgressiveUpdateData;
|
||||
}
|
||||
|
||||
void setZoomConstraints(ZoomConstraints constraints) {
|
||||
mZoomConstraints = constraints;
|
||||
}
|
||||
|
||||
void setIsRTL(boolean aIsRTL) {
|
||||
synchronized (getLock()) {
|
||||
ImmutableViewportMetrics newMetrics = getViewportMetrics().setIsRTL(aIsRTL);
|
||||
|
@ -362,6 +555,20 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
|
||||
setViewportMetrics(newMetrics);
|
||||
|
||||
if (tab != null) {
|
||||
mView.setBackgroundColor(tab.getBackgroundColor());
|
||||
setZoomConstraints(tab.getZoomConstraints());
|
||||
}
|
||||
|
||||
// At this point, we have just switched to displaying a different document than we
|
||||
// we previously displaying. This means we need to abort any panning/zooming animations
|
||||
// that are in progress and send an updated display port request to browser.js as soon
|
||||
// as possible. The call to PanZoomController.abortAnimation accomplishes this by calling the
|
||||
// forceRedraw function, which sends the viewport to gecko. The display port request is
|
||||
// actually a full viewport update, which is fine because if browser.js has somehow moved to
|
||||
// be out of sync with this first-paint viewport, then we force them back in sync.
|
||||
abortPanZoomAnimation();
|
||||
|
||||
// Indicate that the document is about to be composited so the
|
||||
// LayerView background can be removed.
|
||||
if (mView.getPaintState() == LayerView.PAINT_START) {
|
||||
|
@ -705,6 +912,12 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
|||
return mViewportMetrics;
|
||||
}
|
||||
|
||||
/** Implementation of PanZoomTarget */
|
||||
@Override
|
||||
public ZoomConstraints getZoomConstraints() {
|
||||
return mZoomConstraints;
|
||||
}
|
||||
|
||||
/** Implementation of PanZoomTarget */
|
||||
@Override
|
||||
public FullScreenState getFullScreenState() {
|
||||
|
|
|
@ -55,6 +55,7 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
private LayerRenderer mRenderer;
|
||||
/* Must be a PAINT_xxx constant */
|
||||
private int mPaintState;
|
||||
private int mBackgroundColor;
|
||||
private FullScreenState mFullScreenState;
|
||||
|
||||
private SurfaceView mSurfaceView;
|
||||
|
@ -170,6 +171,7 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
super(context, attrs);
|
||||
|
||||
mPaintState = PAINT_START;
|
||||
mBackgroundColor = Color.WHITE;
|
||||
mFullScreenState = FullScreenState.NONE;
|
||||
|
||||
if (Versions.feature14Plus) {
|
||||
|
@ -375,6 +377,12 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
return mLayerClient.getViewportMetrics();
|
||||
}
|
||||
|
||||
public void abortPanning() {
|
||||
if (mPanZoomController != null) {
|
||||
mPanZoomController.abortPanning();
|
||||
}
|
||||
}
|
||||
|
||||
public PointF convertViewPointToLayerPoint(PointF viewPoint) {
|
||||
return mLayerClient.convertViewPointToLayerPoint(viewPoint);
|
||||
}
|
||||
|
@ -383,16 +391,43 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
return mLayerClient.getMatrixForLayerRectToViewRect();
|
||||
}
|
||||
|
||||
int getBackgroundColor() {
|
||||
return mBackgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBackgroundColor(int newColor) {
|
||||
mBackgroundColor = newColor;
|
||||
requestRender();
|
||||
}
|
||||
|
||||
void setSurfaceBackgroundColor(int newColor) {
|
||||
if (mSurfaceView != null) {
|
||||
mSurfaceView.setBackgroundColor(newColor);
|
||||
}
|
||||
}
|
||||
|
||||
public void setZoomConstraints(ZoomConstraints constraints) {
|
||||
mLayerClient.setZoomConstraints(constraints);
|
||||
}
|
||||
|
||||
public void setIsRTL(boolean aIsRTL) {
|
||||
mLayerClient.setIsRTL(aIsRTL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if (!mLayerClient.isGeckoReady()) {
|
||||
// If gecko isn't loaded yet, don't try sending events to the
|
||||
// native code because it's just going to crash
|
||||
return true;
|
||||
}
|
||||
if (mPanZoomController != null && mPanZoomController.onKeyEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void requestRender() {
|
||||
if (mCompositorCreated) {
|
||||
mCompositor.syncInvalidateAndScheduleComposite();
|
||||
|
@ -760,6 +795,7 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
|
|||
@Override
|
||||
public void onTabChanged(Tab tab, Tabs.TabEvents msg, String data) {
|
||||
if (msg == Tabs.TabEvents.VIEWPORT_CHANGE && Tabs.getInstance().isSelectedTab(tab) && mLayerClient != null) {
|
||||
setZoomConstraints(tab.getZoomConstraints());
|
||||
setIsRTL(tab.getIsRTL());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,11 +190,58 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyEvent(KeyEvent event) {
|
||||
// FIXME implement this
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionEventVelocity(final long aEventTime, final float aSpeedY) {
|
||||
handleMotionEventVelocity(aEventTime, aSpeedY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointF getVelocityVector() {
|
||||
// FIXME implement this
|
||||
return new PointF(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pageRectUpdated() {
|
||||
// no-op in APZC, I think
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abortPanning() {
|
||||
// no-op in APZC, I think
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyDefaultActionPrevented(boolean prevented) {
|
||||
// no-op: This could get called if accessibility is enabled and the events
|
||||
// are sent to Gecko directly without going through APZ. In this case
|
||||
// we just want to ignore this callback.
|
||||
}
|
||||
|
||||
@WrapForJNI(stubName = "AbortAnimation", calledFrom = "ui")
|
||||
private native void nativeAbortAnimation();
|
||||
|
||||
@Override // PanZoomController
|
||||
public void abortAnimation()
|
||||
{
|
||||
if (!mDestroyed) {
|
||||
nativeAbortAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // PanZoomController
|
||||
public boolean getRedrawHint()
|
||||
{
|
||||
// FIXME implement this
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override @WrapForJNI(calledFrom = "ui") // PanZoomController
|
||||
public void destroy() {
|
||||
if (mDestroyed || !mTarget.isGeckoReady()) {
|
||||
|
|
|
@ -14,6 +14,10 @@ import android.view.MotionEvent;
|
|||
import android.view.View;
|
||||
|
||||
public interface PanZoomController {
|
||||
// The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans
|
||||
// between the touch-down and touch-up of a click). In units of density-independent pixels.
|
||||
public static final float PAN_THRESHOLD = 1 / 16f * GeckoAppShell.getDpi();
|
||||
|
||||
// Threshold for sending touch move events to content
|
||||
public static final float CLICK_THRESHOLD = 1 / 50f * GeckoAppShell.getDpi();
|
||||
|
||||
|
@ -27,7 +31,16 @@ public interface PanZoomController {
|
|||
|
||||
public boolean onTouchEvent(MotionEvent event);
|
||||
public boolean onMotionEvent(MotionEvent event);
|
||||
public boolean onKeyEvent(KeyEvent event);
|
||||
public void onMotionEventVelocity(final long aEventTime, final float aSpeedY);
|
||||
public void notifyDefaultActionPrevented(boolean prevented);
|
||||
|
||||
public boolean getRedrawHint();
|
||||
public PointF getVelocityVector();
|
||||
|
||||
public void pageRectUpdated();
|
||||
public void abortPanning();
|
||||
public void abortAnimation();
|
||||
|
||||
public void setOverscrollHandler(final Overscroll controller);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.graphics.PointF;
|
|||
|
||||
public interface PanZoomTarget {
|
||||
public ImmutableViewportMetrics getViewportMetrics();
|
||||
public ZoomConstraints getZoomConstraints();
|
||||
public FullScreenState getFullScreenState();
|
||||
public PointF getVisibleEndOfLayerView();
|
||||
|
||||
|
|
|
@ -1402,6 +1402,33 @@ AndroidBridge::IsContentDocumentDisplayed()
|
|||
return mLayerClient->IsContentDocumentDisplayed();
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::ProgressiveUpdateCallback(bool aHasPendingNewThebesContent,
|
||||
const LayerRect& aDisplayPort, float aDisplayResolution,
|
||||
bool aDrawingCritical, ParentLayerPoint& aScrollOffset,
|
||||
CSSToParentLayerScale& aZoom)
|
||||
{
|
||||
if (!mLayerClient) {
|
||||
ALOG_BRIDGE("Exceptional Exit: %s", __PRETTY_FUNCTION__);
|
||||
return false;
|
||||
}
|
||||
|
||||
ProgressiveUpdateData::LocalRef progressiveUpdateData =
|
||||
mLayerClient->ProgressiveUpdateCallback(aHasPendingNewThebesContent,
|
||||
(float)aDisplayPort.x,
|
||||
(float)aDisplayPort.y,
|
||||
(float)aDisplayPort.width,
|
||||
(float)aDisplayPort.height,
|
||||
aDisplayResolution,
|
||||
!aDrawingCritical);
|
||||
|
||||
aScrollOffset.x = progressiveUpdateData->X();
|
||||
aScrollOffset.y = progressiveUpdateData->Y();
|
||||
aZoom.scale = progressiveUpdateData->Scale();
|
||||
|
||||
return progressiveUpdateData->Abort();
|
||||
}
|
||||
|
||||
class AndroidBridge::DelayedTask
|
||||
{
|
||||
using TimeStamp = mozilla::TimeStamp;
|
||||
|
|
|
@ -151,6 +151,9 @@ public:
|
|||
void ContentDocumentChanged();
|
||||
bool IsContentDocumentDisplayed();
|
||||
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const LayerRect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical,
|
||||
mozilla::ParentLayerPoint& aScrollOffset, mozilla::CSSToParentLayerScale& aZoom);
|
||||
|
||||
void SetLayerClient(java::GeckoLayerClient::Param jobj);
|
||||
const java::GeckoLayerClient::Ref& GetLayerClient() { return mLayerClient; }
|
||||
|
||||
|
|
|
@ -541,7 +541,7 @@ template<class Impl>
|
|||
class NativePanZoomController::Natives : public mozilla::jni::NativeImpl<NativePanZoomController, Impl>
|
||||
{
|
||||
public:
|
||||
static const JNINativeMethod methods[7];
|
||||
static const JNINativeMethod methods[8];
|
||||
};
|
||||
|
||||
template<class Impl>
|
||||
|
@ -571,6 +571,10 @@ const JNINativeMethod NativePanZoomController::Natives<Impl>::methods[] = {
|
|||
mozilla::jni::NativeStub<NativePanZoomController::HandleScrollEvent_t, Impl>
|
||||
::template Wrap<&Impl::HandleScrollEvent>),
|
||||
|
||||
mozilla::jni::MakeNativeMethod<NativePanZoomController::AbortAnimation_t>(
|
||||
mozilla::jni::NativeStub<NativePanZoomController::AbortAnimation_t, Impl>
|
||||
::template Wrap<&Impl::AbortAnimation>),
|
||||
|
||||
mozilla::jni::MakeNativeMethod<NativePanZoomController::SetIsLongpressEnabled_t>(
|
||||
mozilla::jni::NativeStub<NativePanZoomController::SetIsLongpressEnabled_t, Impl>
|
||||
::template Wrap<&Impl::SetIsLongpressEnabled>)
|
||||
|
|
|
@ -588,6 +588,14 @@ constexpr char GeckoAppShell::NotifyObservers_t::signature[];
|
|||
constexpr char GeckoAppShell::NotifyAlertListener_t::name[];
|
||||
constexpr char GeckoAppShell::NotifyAlertListener_t::signature[];
|
||||
|
||||
constexpr char GeckoAppShell::NotifyDefaultPrevented_t::name[];
|
||||
constexpr char GeckoAppShell::NotifyDefaultPrevented_t::signature[];
|
||||
|
||||
auto GeckoAppShell::NotifyDefaultPrevented(bool a0) -> void
|
||||
{
|
||||
return mozilla::jni::Method<NotifyDefaultPrevented_t>::Call(GeckoAppShell::Context(), nullptr, a0);
|
||||
}
|
||||
|
||||
constexpr char GeckoAppShell::NotifyUriVisited_t::name[];
|
||||
constexpr char GeckoAppShell::NotifyUriVisited_t::signature[];
|
||||
|
||||
|
@ -1300,6 +1308,14 @@ auto GeckoLayerClient::OnGeckoReady() const -> void
|
|||
return mozilla::jni::Method<OnGeckoReady_t>::Call(GeckoLayerClient::mCtx, nullptr);
|
||||
}
|
||||
|
||||
constexpr char GeckoLayerClient::ProgressiveUpdateCallback_t::name[];
|
||||
constexpr char GeckoLayerClient::ProgressiveUpdateCallback_t::signature[];
|
||||
|
||||
auto GeckoLayerClient::ProgressiveUpdateCallback(bool a0, float a1, float a2, float a3, float a4, float a5, bool a6) const -> mozilla::jni::Object::LocalRef
|
||||
{
|
||||
return mozilla::jni::Method<ProgressiveUpdateCallback_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
constexpr char GeckoLayerClient::SetFirstPaintViewport_t::name[];
|
||||
constexpr char GeckoLayerClient::SetFirstPaintViewport_t::signature[];
|
||||
|
||||
|
@ -1490,6 +1506,9 @@ constexpr char NativePanZoomController::HandleMouseEvent_t::signature[];
|
|||
constexpr char NativePanZoomController::HandleScrollEvent_t::name[];
|
||||
constexpr char NativePanZoomController::HandleScrollEvent_t::signature[];
|
||||
|
||||
constexpr char NativePanZoomController::AbortAnimation_t::name[];
|
||||
constexpr char NativePanZoomController::AbortAnimation_t::signature[];
|
||||
|
||||
constexpr char NativePanZoomController::SetIsLongpressEnabled_t::name[];
|
||||
constexpr char NativePanZoomController::SetIsLongpressEnabled_t::signature[];
|
||||
|
||||
|
|
|
@ -1571,6 +1571,26 @@ public:
|
|||
mozilla::jni::DispatchTarget::GECKO;
|
||||
};
|
||||
|
||||
struct NotifyDefaultPrevented_t {
|
||||
typedef GeckoAppShell Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
bool> Args;
|
||||
static constexpr char name[] = "notifyDefaultPrevented";
|
||||
static constexpr char signature[] =
|
||||
"(Z)V";
|
||||
static const bool isStatic = true;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::GECKO;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
static auto NotifyDefaultPrevented(bool) -> void;
|
||||
|
||||
struct NotifyUriVisited_t {
|
||||
typedef GeckoAppShell Owner;
|
||||
typedef void ReturnType;
|
||||
|
@ -4238,6 +4258,32 @@ public:
|
|||
|
||||
auto OnGeckoReady() const -> void;
|
||||
|
||||
struct ProgressiveUpdateCallback_t {
|
||||
typedef GeckoLayerClient Owner;
|
||||
typedef mozilla::jni::Object::LocalRef ReturnType;
|
||||
typedef mozilla::jni::Object::Param SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
bool,
|
||||
float,
|
||||
float,
|
||||
float,
|
||||
float,
|
||||
float,
|
||||
bool> Args;
|
||||
static constexpr char name[] = "progressiveUpdateCallback";
|
||||
static constexpr char signature[] =
|
||||
"(ZFFFFFZ)Lorg/mozilla/gecko/gfx/ProgressiveUpdateData;";
|
||||
static const bool isStatic = false;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::ANY;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
auto ProgressiveUpdateCallback(bool, float, float, float, float, float, bool) const -> mozilla::jni::Object::LocalRef;
|
||||
|
||||
struct SetFirstPaintViewport_t {
|
||||
typedef GeckoLayerClient Owner;
|
||||
typedef void ReturnType;
|
||||
|
@ -4934,6 +4980,23 @@ public:
|
|||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
struct AbortAnimation_t {
|
||||
typedef NativePanZoomController Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "nativeAbortAnimation";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = false;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::UI;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
struct SetIsLongpressEnabled_t {
|
||||
typedef NativePanZoomController Owner;
|
||||
typedef void ReturnType;
|
||||
|
|
|
@ -537,6 +537,25 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
void AbortAnimation()
|
||||
{
|
||||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||
|
||||
RefPtr<IAPZCTreeManager> controller;
|
||||
RefPtr<CompositorBridgeParent> compositor;
|
||||
|
||||
if (LockedWindowPtr window{mWindow}) {
|
||||
controller = window->mAPZC;
|
||||
compositor = window->GetCompositorBridgeParent();
|
||||
}
|
||||
|
||||
if (controller && compositor) {
|
||||
// TODO: Pass in correct values for presShellId and viewId.
|
||||
controller->CancelAnimation(ScrollableLayerGuid(
|
||||
compositor->RootLayerTreeId(), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void AdjustScrollForSurfaceShift(float aX, float aY)
|
||||
{
|
||||
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
|
||||
|
|
Загрузка…
Ссылка в новой задаче