From 1320fdc1a4a377b642299e843c3da12be44e2878 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 4 Oct 2016 14:41:13 -0400 Subject: [PATCH 01/37] Bug 1307522 - Delete a bunch of classes and related goop no longer used now that JPZ is gone. r=snorp MozReview-Commit-ID: Jq6xJEO0u9x --HG-- extra : rebase_source : 3ae338de85676c8c846b393661ce319f3dde86c3 --- mobile/android/base/moz.build | 6 - .../main/java/org/mozilla/gecko/gfx/Axis.java | 532 ------------ .../gecko/gfx/DisplayPortCalculator.java | 771 ------------------ .../mozilla/gecko/gfx/DisplayPortMetrics.java | 78 -- .../mozilla/gecko/gfx/DrawTimingQueue.java | 94 --- .../mozilla/gecko/gfx/GeckoLayerClient.java | 73 +- .../org/mozilla/gecko/gfx/PanZoomTarget.java | 2 - .../gecko/gfx/SimpleScaleGestureDetector.java | 322 -------- .../gecko/gfx/SubdocumentScrollHelper.java | 141 ---- widget/android/GeneratedJNIWrappers.cpp | 27 - widget/android/GeneratedJNIWrappers.h | 74 -- 11 files changed, 4 insertions(+), 2116 deletions(-) delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/Axis.java delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java delete mode 100644 mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index df1ced354d38..b8409107898c 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -236,13 +236,9 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x 'GeckoViewChrome.java', 'GeckoViewContent.java', 'GeckoViewFragment.java', - 'gfx/Axis.java', 'gfx/BitmapUtils.java', 'gfx/BufferedImage.java', 'gfx/BufferedImageGLInfo.java', - 'gfx/DisplayPortCalculator.java', - 'gfx/DisplayPortMetrics.java', - 'gfx/DrawTimingQueue.java', 'gfx/DynamicToolbarAnimator.java', 'gfx/FloatSize.java', 'gfx/FullScreenState.java', @@ -261,9 +257,7 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x 'gfx/ProgressiveUpdateData.java', 'gfx/RectUtils.java', 'gfx/RenderTask.java', - 'gfx/SimpleScaleGestureDetector.java', 'gfx/StackScroller.java', - 'gfx/SubdocumentScrollHelper.java', 'gfx/SurfaceTextureListener.java', 'gfx/ViewTransform.java', 'InputConnectionListener.java', diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/Axis.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/Axis.java deleted file mode 100644 index 39db5a9ce5c9..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/Axis.java +++ /dev/null @@ -1,532 +0,0 @@ -/* -*- 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.gfx; - -import java.util.HashMap; -import java.util.Map; - -import org.mozilla.gecko.GeckoAppShell; -import org.mozilla.gecko.PrefsHelper; -import org.mozilla.gecko.util.FloatUtils; - -import android.os.SystemClock; -import android.util.Log; -import android.view.View; - -/** - * This class represents the physics for one axis of movement (i.e. either - * horizontal or vertical). It tracks the different properties of movement - * like displacement, velocity, viewport dimensions, etc. pertaining to - * a particular axis. - */ -abstract class Axis { - private static final String LOGTAG = "GeckoAxis"; - - private static final String PREF_SCROLLING_FRICTION_SLOW = "ui.scrolling.friction_slow"; - private static final String PREF_SCROLLING_FRICTION_FAST = "ui.scrolling.friction_fast"; - private static final String PREF_SCROLLING_MAX_EVENT_ACCELERATION = "ui.scrolling.max_event_acceleration"; - private static final String PREF_SCROLLING_OVERSCROLL_DECEL_RATE = "ui.scrolling.overscroll_decel_rate"; - private static final String PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT = "ui.scrolling.overscroll_snap_limit"; - private static final String PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE = "ui.scrolling.min_scrollable_distance"; - private static final String PREF_FLING_ACCEL_INTERVAL = "ui.scrolling.fling_accel_interval"; - private static final String PREF_FLING_ACCEL_BASE_MULTIPLIER = "ui.scrolling.fling_accel_base_multiplier"; - private static final String PREF_FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER = "ui.scrolling.fling_accel_supplemental_multiplier"; - private static final String PREF_FLING_CURVE_FUNCTION_X1 = "ui.scrolling.fling_curve_function_x1"; - private static final String PREF_FLING_CURVE_FUNCTION_Y1 = "ui.scrolling.fling_curve_function_y1"; - private static final String PREF_FLING_CURVE_FUNCTION_X2 = "ui.scrolling.fling_curve_function_x2"; - private static final String PREF_FLING_CURVE_FUNCTION_Y2 = "ui.scrolling.fling_curve_function_y2"; - private static final String PREF_FLING_CURVE_THRESHOLD_VELOCITY = "ui.scrolling.fling_curve_threshold_velocity"; - private static final String PREF_FLING_CURVE_MAXIMUM_VELOCITY = "ui.scrolling.fling_curve_max_velocity"; - private static final String PREF_FLING_CURVE_NEWTON_ITERATIONS = "ui.scrolling.fling_curve_newton_iterations"; - - // This fraction of velocity remains after every animation frame when the velocity is low. - private static float FRICTION_SLOW; - // This fraction of velocity remains after every animation frame when the velocity is high. - private static float FRICTION_FAST; - // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST - // to FRICTION_SLOW. - private static float VELOCITY_THRESHOLD; - // The maximum velocity change factor between events, per ms, in %. - // Direction changes are excluded. - private static float MAX_EVENT_ACCELERATION; - - // The rate of deceleration when the surface has overscrolled. - private static float OVERSCROLL_DECEL_RATE; - // The percentage of the surface which can be overscrolled before it must snap back. - private static float SNAP_LIMIT; - - // The minimum amount of space that must be present for an axis to be considered scrollable, - // in pixels. - private static float MIN_SCROLLABLE_DISTANCE; - - // The interval within which if two flings are done then scrolling effect is accelerated. - private static long FLING_ACCEL_INTERVAL; - - // The multiplication constant of the base velocity in case of accelerated scrolling. - private static float FLING_ACCEL_BASE_MULTIPLIER; - - // The multiplication constant of the supplemental velocity in case of accelerated scrolling. - private static float FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER; - - // x co-ordinate of the second bezier control point - private static float FLING_CURVE_FUNCTION_X1; - - // y co-ordinate of the second bezier control point - private static float FLING_CURVE_FUNCTION_Y1; - - // x co-ordinate of the third bezier control point - private static float FLING_CURVE_FUNCTION_X2; - - // y co-ordinate of the third bezier control point - private static float FLING_CURVE_FUNCTION_Y2; - - // Minimum velocity for curve to be implemented i.e fling curving - private static float FLING_CURVE_THRESHOLD_VELOCITY; - - // Maximum permitted velocity - private static float FLING_CURVE_MAXIMUM_VELOCITY; - - // Number of iterations in the Newton-Raphson method - private static int FLING_CURVE_NEWTON_ITERATIONS; - - private static float getFloatPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (value == null || value < 0 ? defaultValue : value) / 1000f; - } - - private static int getIntPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (value == null || value < 0 ? defaultValue : value); - } - - static void initPrefs() { - final String[] prefs = { PREF_SCROLLING_FRICTION_FAST, - PREF_SCROLLING_FRICTION_SLOW, - PREF_SCROLLING_MAX_EVENT_ACCELERATION, - PREF_SCROLLING_OVERSCROLL_DECEL_RATE, - PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, - PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE, - PREF_FLING_ACCEL_INTERVAL, - PREF_FLING_ACCEL_BASE_MULTIPLIER, - PREF_FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER, - PREF_FLING_CURVE_FUNCTION_X1, - PREF_FLING_CURVE_FUNCTION_Y1, - PREF_FLING_CURVE_FUNCTION_X2, - PREF_FLING_CURVE_FUNCTION_Y2, - PREF_FLING_CURVE_THRESHOLD_VELOCITY, - PREF_FLING_CURVE_MAXIMUM_VELOCITY, - PREF_FLING_CURVE_NEWTON_ITERATIONS }; - - PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() { - Map mPrefs = new HashMap(); - - @Override public void prefValue(String name, int value) { - mPrefs.put(name, value); - } - - @Override public void finish() { - setPrefs(mPrefs); - } - }); - } - - static final float MS_PER_FRAME = 1000.0f / 60.0f; - static final long NS_PER_FRAME = Math.round(1000000000f / 60f); - private static final float FRAMERATE_MULTIPLIER = (1000f / 60f) / MS_PER_FRAME; - private static final int FLING_VELOCITY_POINTS = 8; - - // The values we use for friction are based on a 16.6ms frame, adjust them to currentNsPerFrame: - static float getFrameAdjustedFriction(float baseFriction, long currentNsPerFrame) { - float framerateMultiplier = (float)currentNsPerFrame / NS_PER_FRAME; - return (float)Math.pow(Math.E, (Math.log(baseFriction) / framerateMultiplier)); - } - - static void setPrefs(Map prefs) { - FRICTION_SLOW = getFloatPref(prefs, PREF_SCROLLING_FRICTION_SLOW, 850); - FRICTION_FAST = getFloatPref(prefs, PREF_SCROLLING_FRICTION_FAST, 970); - VELOCITY_THRESHOLD = 10 / FRAMERATE_MULTIPLIER; - MAX_EVENT_ACCELERATION = getFloatPref(prefs, PREF_SCROLLING_MAX_EVENT_ACCELERATION, GeckoAppShell.getDpi() > 300 ? 100 : 40); - OVERSCROLL_DECEL_RATE = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_DECEL_RATE, 40); - SNAP_LIMIT = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, 300); - MIN_SCROLLABLE_DISTANCE = getFloatPref(prefs, PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE, 500); - FLING_ACCEL_INTERVAL = getIntPref(prefs, PREF_FLING_ACCEL_INTERVAL, 500); - FLING_ACCEL_BASE_MULTIPLIER = getFloatPref(prefs, PREF_FLING_ACCEL_BASE_MULTIPLIER, 1000); - FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER = getFloatPref(prefs, PREF_FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER, 1000); - FLING_CURVE_FUNCTION_X1 = getFloatPref(prefs, PREF_FLING_CURVE_FUNCTION_X1, 410); - FLING_CURVE_FUNCTION_Y1 = getFloatPref(prefs, PREF_FLING_CURVE_FUNCTION_Y1, 0); - FLING_CURVE_FUNCTION_X2 = getFloatPref(prefs, PREF_FLING_CURVE_FUNCTION_X2, 800); - FLING_CURVE_FUNCTION_Y2 = getFloatPref(prefs, PREF_FLING_CURVE_FUNCTION_Y2, 1000); - FLING_CURVE_THRESHOLD_VELOCITY = getFloatPref(prefs, PREF_FLING_CURVE_THRESHOLD_VELOCITY, 30); - FLING_CURVE_MAXIMUM_VELOCITY = getFloatPref(prefs, PREF_FLING_CURVE_MAXIMUM_VELOCITY, 70); - FLING_CURVE_NEWTON_ITERATIONS = getIntPref(prefs, PREF_FLING_CURVE_NEWTON_ITERATIONS, 5); - - Log.i(LOGTAG, "Prefs: " + FRICTION_SLOW + "," + FRICTION_FAST + "," + VELOCITY_THRESHOLD + "," - + MAX_EVENT_ACCELERATION + "," + OVERSCROLL_DECEL_RATE + "," + SNAP_LIMIT + "," + MIN_SCROLLABLE_DISTANCE); - } - - static { - // set the scrolling parameters to default values on startup - setPrefs(null); - } - - private enum FlingStates { - STOPPED, - PANNING, - FLINGING, - } - - private enum Overscroll { - NONE, - MINUS, // Overscrolled in the negative direction - PLUS, // Overscrolled in the positive direction - BOTH, // Overscrolled in both directions (page is zoomed to smaller than screen) - } - - private final SubdocumentScrollHelper mSubscroller; - - private int mOverscrollMode; /* Default to only overscrolling if we're allowed to scroll in a direction */ - private float mFirstTouchPos; /* Position of the first touch event on the current drag. */ - private float mTouchPos; /* Position of the most recent touch event on the current drag. */ - private float mLastTouchPos; /* Position of the touch event before touchPos. */ - private float mVelocity; /* Velocity in this direction; pixels per animation frame. */ - private final float[] mRecentVelocities; /* Circular buffer of recent velocities since last touch start. */ - private int mRecentVelocityCount; /* Number of values put into mRecentVelocities (unbounded). */ - private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */ - private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */ - private float mDisplacement; - private long mLastFlingTime; - private float mLastFlingVelocity; - - private FlingStates mFlingState = FlingStates.STOPPED; /* The fling state we're in on this axis. */ - - protected abstract float getOrigin(); - protected abstract float getViewportLength(); - protected abstract float getPageStart(); - protected abstract float getPageLength(); - protected abstract float getVisibleEndOfLayerView(); - - Axis(SubdocumentScrollHelper subscroller) { - mSubscroller = subscroller; - mOverscrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS; - mRecentVelocities = new float[FLING_VELOCITY_POINTS]; - } - - // Implementors can override these to show effects when the axis overscrolls - protected void overscrollFling(float velocity) { } - protected void overscrollPan(float displacement) { } - - public void setOverScrollMode(int overscrollMode) { - mOverscrollMode = overscrollMode; - } - - public int getOverScrollMode() { - return mOverscrollMode; - } - - private float getViewportEnd() { - return getOrigin() + getViewportLength(); - } - - private float getPageEnd() { - return getPageStart() + getPageLength(); - } - - void startTouch(float pos) { - mVelocity = 0.0f; - mScrollingDisabled = false; - mFirstTouchPos = mTouchPos = mLastTouchPos = pos; - mRecentVelocityCount = 0; - } - - float panDistance(float currentPos) { - return currentPos - mFirstTouchPos; - } - - void setScrollingDisabled(boolean disabled) { - mScrollingDisabled = disabled; - } - - void saveTouchPos() { - mLastTouchPos = mTouchPos; - } - - // Calculates and return the slope of the curve at given parameter t - float getSlope(float t) { - float y1 = FLING_CURVE_FUNCTION_Y1; - float y2 = FLING_CURVE_FUNCTION_Y2; - - return (3 * y1) - + t * (6 * y2 - 12 * y1) - + t * t * (9 * y1 - 9 * y2 + 3); - } - - // Calculates and returns the value of the bezier curve with the given parameter t and control points p1 and p2 - float cubicBezier(float p1, float p2, float t) { - return (3 * t * (1 - t) * (1 - t) * p1) - + (3 * t * t * (1 - t) * p2) - + (t * t * t); - } - - // Responsible for mapping the physical velocity to a the velocity obtained after applying bezier curve (with control points (X1,Y1) and (X2,Y2)) - float flingCurve(float By) { - int ni = FLING_CURVE_NEWTON_ITERATIONS; - float[] guess = new float[ni]; - float y1 = FLING_CURVE_FUNCTION_Y1; - float y2 = FLING_CURVE_FUNCTION_Y2; - guess[0] = By; - - for (int i = 1; i < ni; i++) { - guess[i] = guess[i - 1] - (cubicBezier(y1, y2, guess[i - 1]) - By) / getSlope(guess[i - 1]); - } - // guess[4] is the final approximate root the cubic equation. - float t = guess[4]; - - float x1 = FLING_CURVE_FUNCTION_X1; - float x2 = FLING_CURVE_FUNCTION_X2; - return cubicBezier(x1, x2, t); - } - - void updateWithTouchAt(float pos, float timeDelta) { - float curveVelocityThreshold = FLING_CURVE_THRESHOLD_VELOCITY * GeckoAppShell.getDpi() * MS_PER_FRAME; - float maxVelocity = FLING_CURVE_MAXIMUM_VELOCITY * GeckoAppShell.getDpi() * MS_PER_FRAME; - - float newVelocity = (mTouchPos - pos) / timeDelta * MS_PER_FRAME; - - if (Math.abs(newVelocity) > curveVelocityThreshold && Math.abs(newVelocity) < maxVelocity) { - float sign = Math.signum(newVelocity); - newVelocity = newVelocity * sign; - float scale = maxVelocity - curveVelocityThreshold; - float functInp = (newVelocity - curveVelocityThreshold) / scale; - float functOut = flingCurve(functInp); - newVelocity = functOut * scale + curveVelocityThreshold; - newVelocity = newVelocity * sign; - } - - mRecentVelocities[mRecentVelocityCount % FLING_VELOCITY_POINTS] = newVelocity; - mRecentVelocityCount++; - - // If there's a direction change, or current velocity is very low, - // allow setting of the velocity outright. Otherwise, use the current - // velocity and a maximum change factor to set the new velocity. - boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f / FRAMERATE_MULTIPLIER; - boolean directionChange = (mVelocity > 0) != (newVelocity > 0); - if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) { - mVelocity = newVelocity; - } else { - float maxChange = Math.abs(mVelocity * timeDelta * MAX_EVENT_ACCELERATION); - mVelocity = Math.min(mVelocity + maxChange, Math.max(mVelocity - maxChange, newVelocity)); - } - - mTouchPos = pos; - } - - boolean overscrolled() { - return getOverscroll() != Overscroll.NONE; - } - - private Overscroll getOverscroll() { - boolean minus = (getOrigin() < getPageStart()); - boolean plus = (getViewportEnd() > getPageEnd()); - if (minus && plus) { - return Overscroll.BOTH; - } else if (minus) { - return Overscroll.MINUS; - } else if (plus) { - return Overscroll.PLUS; - } else { - return Overscroll.NONE; - } - } - - // Returns the amount that the page has been overscrolled. If the page hasn't been - // overscrolled on this axis, returns 0. - private float getExcess() { - switch (getOverscroll()) { - case MINUS: return getPageStart() - getOrigin(); - case PLUS: return getViewportEnd() - getPageEnd(); - case BOTH: return (getViewportEnd() - getPageEnd()) + (getPageStart() - getOrigin()); - default: return 0.0f; - } - } - - /* - * Returns true if the page is zoomed in to some degree along this axis such that scrolling is - * possible and this axis has not been scroll locked while panning. Otherwise, returns false. - */ - boolean scrollable() { - // If we're scrolling a subdocument, ignore the viewport length restrictions (since those - // apply to the top-level document) and only take into account axis locking. - if (mSubscroller.scrolling()) { - return !mScrollingDisabled; - } - - // if we are axis locked, return false - if (mScrollingDisabled) { - return false; - } - - // there is scrollable space, and we're not disabled, or the document fits the viewport - // but we always allow overscroll anyway - return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE || - getOverScrollMode() == View.OVER_SCROLL_ALWAYS; - } - - /* - * Returns the resistance, as a multiplier, that should be taken into account when - * tracking or pinching. - */ - float getEdgeResistance(boolean forPinching) { - float excess = getExcess(); - if (excess > 0.0f && (getOverscroll() == Overscroll.BOTH || !forPinching)) { - // excess can be greater than viewport length, but the resistance - // must never drop below 0.0 - return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength()); - } - return 1.0f; - } - - /* Returns the velocity. If the axis is locked, returns 0. */ - float getRealVelocity() { - return scrollable() ? mVelocity : 0f; - } - - void startPan() { - mFlingState = FlingStates.PANNING; - } - - private float calculateFlingVelocity() { - int usablePoints = Math.min(mRecentVelocityCount, FLING_VELOCITY_POINTS); - if (usablePoints <= 1) { - return mVelocity; - } - float average = 0; - for (int i = 0; i < usablePoints; i++) { - average += mRecentVelocities[i]; - } - return average / usablePoints; - } - - float accelerate(float velocity, float lastFlingVelocity) { - return (FLING_ACCEL_BASE_MULTIPLIER * velocity + FLING_ACCEL_SUPPLEMENTAL_MULTIPLIER * lastFlingVelocity); - } - - void startFling(boolean stopped) { - mDisableSnap = mSubscroller.scrolling(); - - if (stopped) { - mFlingState = FlingStates.STOPPED; - } else { - long now = SystemClock.uptimeMillis(); - mVelocity = calculateFlingVelocity(); - - if ((now - mLastFlingTime < FLING_ACCEL_INTERVAL) && Math.signum(mVelocity) == Math.signum(mLastFlingVelocity)) { - mVelocity = accelerate(mVelocity, mLastFlingVelocity); - } - mFlingState = FlingStates.FLINGING; - mLastFlingVelocity = mVelocity; - mLastFlingTime = now; - } - } - - /* Advances a fling animation by one step. */ - boolean advanceFling(long realNsPerFrame) { - if (mFlingState != FlingStates.FLINGING) { - return false; - } - if (mSubscroller.scrolling() && !mSubscroller.lastScrollSucceeded()) { - // if the subdocument stopped scrolling, it's because it reached the end - // of the subdocument. we don't do overscroll on subdocuments, so there's - // no point in continuing this fling. - return false; - } - - float excess = getExcess(); - Overscroll overscroll = getOverscroll(); - boolean decreasingOverscroll = false; - if ((overscroll == Overscroll.MINUS && mVelocity > 0) || - (overscroll == Overscroll.PLUS && mVelocity < 0)) - { - decreasingOverscroll = true; - } - - if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f) || decreasingOverscroll) { - // If we aren't overscrolled, just apply friction. - if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) { - mVelocity *= getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame); - } else { - float t = mVelocity / VELOCITY_THRESHOLD; - mVelocity *= FloatUtils.interpolate(getFrameAdjustedFriction(FRICTION_SLOW, realNsPerFrame), - getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame), t); - } - } else { - // Otherwise, decrease the velocity linearly. - float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT); - float overscrollDecelRate = getFrameAdjustedFriction(OVERSCROLL_DECEL_RATE, realNsPerFrame); - if (overscroll == Overscroll.MINUS) { - mVelocity = Math.min((mVelocity + overscrollDecelRate) * elasticity, 0.0f); - } else { // must be Overscroll.PLUS - mVelocity = Math.max((mVelocity - overscrollDecelRate) * elasticity, 0.0f); - } - } - - return true; - } - - void stopFling() { - mVelocity = 0.0f; - mFlingState = FlingStates.STOPPED; - } - - // Performs displacement of the viewport position according to the current velocity. - void displace() { - // if this isn't scrollable just return - if (!scrollable()) - return; - - if (mFlingState == FlingStates.PANNING) - mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance(false); - else - mDisplacement += mVelocity * getEdgeResistance(false); - - // if overscroll is disabled and we're trying to overscroll, reset the displacement - // to remove any excess. Using getExcess alone isn't enough here since it relies on - // getOverscroll which doesn't take into account any new displacment being applied. - // If we using a subscroller, we don't want to alter the scrolling being done - if (getOverScrollMode() == View.OVER_SCROLL_NEVER && !mSubscroller.scrolling()) { - float originalDisplacement = mDisplacement; - - if (mDisplacement + getOrigin() < getPageStart()) { - mDisplacement = getPageStart() - getOrigin(); - } else if (mDisplacement + getOrigin() + getVisibleEndOfLayerView() > getPageEnd()) { - mDisplacement = getPageEnd() - getOrigin() - getVisibleEndOfLayerView(); - } - - // Return the amount of overscroll so that the overscroll controller can draw it for us - if (originalDisplacement != mDisplacement) { - if (mFlingState == FlingStates.FLINGING) { - overscrollFling(mVelocity / MS_PER_FRAME * 1000); - stopFling(); - } else if (mFlingState == FlingStates.PANNING) { - overscrollPan(originalDisplacement - mDisplacement); - } - } - } - } - - float resetDisplacement() { - float d = mDisplacement; - mDisplacement = 0.0f; - return d; - } - - void setAutoscrollVelocity(float velocity) { - if (mFlingState != FlingStates.STOPPED) { - Log.e(LOGTAG, "Setting autoscroll velocity while in a fling is not allowed!"); - return; - } - mVelocity = velocity; - } -} diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java deleted file mode 100644 index ed9b997db9a2..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java +++ /dev/null @@ -1,771 +0,0 @@ -/* -*- 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.gfx; - -import org.mozilla.gecko.GeckoAppShell; -import org.mozilla.gecko.PrefsHelper; -import org.mozilla.gecko.util.FloatUtils; - -import org.json.JSONArray; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.Log; - -import java.util.HashMap; -import java.util.Map; - -final class DisplayPortCalculator { - private static final String LOGTAG = "GeckoDisplayPort"; - private static final PointF ZERO_VELOCITY = new PointF(0, 0); - - private static final String PREF_DISPLAYPORT_STRATEGY = "gfx.displayport.strategy"; - private static final String PREF_DISPLAYPORT_FM_MULTIPLIER = "gfx.displayport.strategy_fm.multiplier"; - private static final String PREF_DISPLAYPORT_FM_DANGER_X = "gfx.displayport.strategy_fm.danger_x"; - private static final String PREF_DISPLAYPORT_FM_DANGER_Y = "gfx.displayport.strategy_fm.danger_y"; - private static final String PREF_DISPLAYPORT_VB_MULTIPLIER = "gfx.displayport.strategy_vb.multiplier"; - private static final String PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_vb.threshold"; - private static final String PREF_DISPLAYPORT_VB_REVERSE_BUFFER = "gfx.displayport.strategy_vb.reverse_buffer"; - private static final String PREF_DISPLAYPORT_VB_DANGER_X_BASE = "gfx.displayport.strategy_vb.danger_x_base"; - private static final String PREF_DISPLAYPORT_VB_DANGER_Y_BASE = "gfx.displayport.strategy_vb.danger_y_base"; - private static final String PREF_DISPLAYPORT_VB_DANGER_X_INCR = "gfx.displayport.strategy_vb.danger_x_incr"; - private static final String PREF_DISPLAYPORT_VB_DANGER_Y_INCR = "gfx.displayport.strategy_vb.danger_y_incr"; - private static final String PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_pb.threshold"; - - private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy(null); - - static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - return sStrategy.calculate(metrics, (velocity == null ? ZERO_VELOCITY : velocity)); - } - - static boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - if (displayPort == null) { - return true; - } - return sStrategy.aboutToCheckerboard(metrics, (velocity == null ? ZERO_VELOCITY : velocity), displayPort); - } - - static boolean drawTimeUpdate(long millis, int pixels) { - return sStrategy.drawTimeUpdate(millis, pixels); - } - - static void resetPageState() { - sStrategy.resetPageState(); - } - - static void initPrefs() { - final String[] prefs = { PREF_DISPLAYPORT_STRATEGY, - PREF_DISPLAYPORT_FM_MULTIPLIER, - PREF_DISPLAYPORT_FM_DANGER_X, - PREF_DISPLAYPORT_FM_DANGER_Y, - PREF_DISPLAYPORT_VB_MULTIPLIER, - PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD, - PREF_DISPLAYPORT_VB_REVERSE_BUFFER, - PREF_DISPLAYPORT_VB_DANGER_X_BASE, - PREF_DISPLAYPORT_VB_DANGER_Y_BASE, - PREF_DISPLAYPORT_VB_DANGER_X_INCR, - PREF_DISPLAYPORT_VB_DANGER_Y_INCR, - PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD }; - - PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() { - private final Map mValues = new HashMap(); - - @Override public void prefValue(String pref, int value) { - mValues.put(pref, value); - } - - @Override public void finish() { - setStrategy(mValues); - } - }); - } - - /** - * Set the active strategy to use. - * See the gfx.displayport.strategy pref in mobile/android/app/mobile.js to see the - * mapping between ints and strategies. - */ - static boolean setStrategy(Map prefs) { - Integer strategy = prefs.get(PREF_DISPLAYPORT_STRATEGY); - if (strategy == null) { - return false; - } - - switch (strategy) { - case 0: - sStrategy = new FixedMarginStrategy(prefs); - break; - case 1: - sStrategy = new VelocityBiasStrategy(prefs); - break; - case 2: - sStrategy = new DynamicResolutionStrategy(prefs); - break; - case 3: - sStrategy = new NoMarginStrategy(prefs); - break; - case 4: - sStrategy = new PredictionBiasStrategy(prefs); - break; - default: - Log.e(LOGTAG, "Invalid strategy index specified"); - return false; - } - Log.i(LOGTAG, "Set strategy " + sStrategy.toString()); - return true; - } - - private static float getFloatPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (value == null || value < 0 ? defaultValue : value) / 1000f; - } - - private static abstract class DisplayPortStrategy { - /** Calculates a displayport given a viewport and panning velocity. */ - public abstract DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity); - /** Returns true if a checkerboard is about to be visible and we should not throttle drawing. */ - public abstract boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort); - /** Notify the strategy of a new recorded draw time. Return false to turn off draw time recording. */ - public boolean drawTimeUpdate(long millis, int pixels) { return false; } - /** Reset any page-specific state stored, as the page being displayed has changed. */ - public void resetPageState() {} - } - - /** - * Return the dimensions for a rect that has area (width*height) that does not exceed the page size in the - * given metrics object. The area in the returned FloatSize may be less than width*height if the page is - * small, but it will never be larger than width*height. - * Note that this process may change the relative aspect ratio of the given dimensions. - */ - private static FloatSize reshapeForPage(float width, float height, ImmutableViewportMetrics metrics) { - // figure out how much of the desired buffer amount we can actually use on the horizontal axis - float usableWidth = Math.min(width, metrics.getPageWidth()); - // if we reduced the buffer amount on the horizontal axis, we should take that saved memory and - // use it on the vertical axis - float extraUsableHeight = (float)Math.floor(((width - usableWidth) * height) / usableWidth); - float usableHeight = Math.min(height + extraUsableHeight, metrics.getPageHeight()); - if (usableHeight < height && usableWidth == width) { - // and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal - float extraUsableWidth = (float)Math.floor(((height - usableHeight) * width) / usableHeight); - usableWidth = Math.min(width + extraUsableWidth, metrics.getPageWidth()); - } - return new FloatSize(usableWidth, usableHeight); - } - - /** - * Expand the given rect in all directions by a "danger zone". The size of the danger zone on an axis - * is the size of the view on that axis multiplied by the given multiplier. The expanded rect is then - * clamped to page bounds and returned. - */ - private static RectF expandByDangerZone(RectF rect, float dangerZoneXMultiplier, float dangerZoneYMultiplier, ImmutableViewportMetrics metrics) { - // calculate the danger zone amounts in pixels - float dangerZoneX = metrics.getWidth() * dangerZoneXMultiplier; - float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier; - rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY); - // clamp to page bounds - return clampToPageBounds(rect, metrics); - } - - /** - * Calculate the display port by expanding the viewport by the specified - * margins, then clamping to the page size. - */ - private static DisplayPortMetrics getPageClampedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) { - float left = metrics.viewportRectLeft - margins.left; - float top = metrics.viewportRectTop - margins.top; - float right = metrics.viewportRectRight() + margins.right; - float bottom = metrics.viewportRectBottom() + margins.bottom; - left = Math.max(metrics.pageRectLeft, left); - top = Math.max(metrics.pageRectTop, top); - right = Math.min(metrics.pageRectRight, right); - bottom = Math.min(metrics.pageRectBottom, bottom); - - return new DisplayPortMetrics(left, top, right, bottom, zoom); - } - - /** - * Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect - * does not exceed the page bounds. This code will maintain the total margin amount for a given axis; - * it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to - * metrics.getPageWidth(); and the same for the y axis. - */ - private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) { - // check how much we're overflowing in each direction. note that at most one of leftOverflow - // and rightOverflow can be greater than zero, and at most one of topOverflow and bottomOverflow - // can be greater than zero, because of the assumption described in the method javadoc. - float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left); - float rightOverflow = (metrics.viewportRectRight() + margins.right) - metrics.pageRectRight; - float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top); - float bottomOverflow = (metrics.viewportRectBottom() + margins.bottom) - metrics.pageRectBottom; - - // if the margins overflow the page bounds, shift them to other side on the same axis - if (leftOverflow > 0) { - margins.left -= leftOverflow; - margins.right += leftOverflow; - } else if (rightOverflow > 0) { - margins.right -= rightOverflow; - margins.left += rightOverflow; - } - if (topOverflow > 0) { - margins.top -= topOverflow; - margins.bottom += topOverflow; - } else if (bottomOverflow > 0) { - margins.bottom -= bottomOverflow; - margins.top += bottomOverflow; - } - return margins; - } - - /** - * Clamp the given rect to the page bounds and return it. - */ - private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) { - if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop; - if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft; - if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight; - if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom; - return rect; - } - - /** - * This class implements the variation where we basically don't bother with a a display port. - */ - private static class NoMarginStrategy extends DisplayPortStrategy { - NoMarginStrategy(Map prefs) { - // no prefs in this strategy - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - return new DisplayPortMetrics(metrics.viewportRectLeft, - metrics.viewportRectTop, - metrics.viewportRectRight(), - metrics.viewportRectBottom(), - metrics.zoomFactor); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - return true; - } - - @Override - public String toString() { - return "NoMarginStrategy"; - } - } - - /** - * This class implements the variation where we use a fixed-size margin on the display port. - * The margin is always 300 pixels in all directions, except when we are (a) approaching a page - * boundary, and/or (b) if we are limited by the page size. In these cases we try to maintain - * the area of the display port by (a) shifting the buffer to the other side on the same axis, - * and/or (b) increasing the buffer on the other axis to compensate for the reduced buffer on - * one axis. - */ - private static class FixedMarginStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private final float SIZE_MULTIPLIER; - - // If the visible rect is within the danger zone (measured as a fraction of the view size - // from the edge of the displayport) we start redrawing to minimize checkerboarding. - private final float DANGER_ZONE_X_MULTIPLIER; - private final float DANGER_ZONE_Y_MULTIPLIER; - - FixedMarginStrategy(Map prefs) { - SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_MULTIPLIER, 2000); - DANGER_ZONE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_X, 100); - DANGER_ZONE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_Y, 200); - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). we simultaneously need to make - // the display port as large as possible so that we redraw less. reshape the display - // port dimensions to accomplish this. - FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - float horizontalBuffer = usableSize.width - metrics.getWidth(); - float verticalBuffer = usableSize.height - metrics.getHeight(); - - // and now calculate the display port margins based on how much buffer we've decided to use and - // the page bounds, ensuring we use all of the available buffer amounts on one side or the other - // on any given axis. (i.e. if we're scrolled to the top of the page, the vertical buffer is - // entirely below the visible viewport, but if we're halfway down the page, the vertical buffer - // is split). - RectF margins = new RectF(); - margins.left = horizontalBuffer / 2.0f; - margins.right = horizontalBuffer - margins.left; - margins.top = verticalBuffer / 2.0f; - margins.bottom = verticalBuffer - margins.top; - margins = shiftMarginsForPageBounds(margins, metrics); - - return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // Increase the size of the viewport based on the danger zone multiplier (and clamp to page - // boundaries), and intersect it with the current displayport to determine whether we're - // close to checkerboarding. - RectF adjustedViewport = expandByDangerZone(metrics.getViewport(), DANGER_ZONE_X_MULTIPLIER, DANGER_ZONE_Y_MULTIPLIER, metrics); - return !displayPort.contains(adjustedViewport); - } - - @Override - public String toString() { - return "FixedMarginStrategy mult=" + SIZE_MULTIPLIER + ", dangerX=" + DANGER_ZONE_X_MULTIPLIER + ", dangerY=" + DANGER_ZONE_Y_MULTIPLIER; - } - } - - /** - * This class implements the variation with a small fixed-size margin with velocity bias. - * In this variation, the default margins are pretty small relative to the view size, but - * they are affected by the panning velocity. Specifically, if we are panning on one axis, - * we remove the margins on the other axis because we are likely axis-locked. Also once - * we are panning in one direction above a certain threshold velocity, we shift the buffer - * so that it is almost entirely in the direction of the pan, with a little bit in the - * reverse direction. - */ - private static class VelocityBiasStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private final float SIZE_MULTIPLIER; - // The velocity above which we apply the velocity bias - private final float VELOCITY_THRESHOLD; - // How much of the buffer to keep in the reverse direction of the velocity - private final float REVERSE_BUFFER; - // If the visible rect is within the danger zone we start redrawing to minimize - // checkerboarding. the danger zone amount is a linear function of the form: - // viewportsize * (base + velocity * incr) - // where base and incr are configurable values. - private final float DANGER_ZONE_BASE_X_MULTIPLIER; - private final float DANGER_ZONE_BASE_Y_MULTIPLIER; - private final float DANGER_ZONE_INCR_X_MULTIPLIER; - private final float DANGER_ZONE_INCR_Y_MULTIPLIER; - - VelocityBiasStrategy(Map prefs) { - SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_MULTIPLIER, 2000); - VELOCITY_THRESHOLD = GeckoAppShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD, 32); - REVERSE_BUFFER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_REVERSE_BUFFER, 200); - DANGER_ZONE_BASE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_BASE, 1000); - DANGER_ZONE_BASE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_BASE, 1000); - DANGER_ZONE_INCR_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_INCR, 0); - DANGER_ZONE_INCR_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_INCR, 0); - } - - /** - * Split the given amounts into margins based on the VELOCITY_THRESHOLD and REVERSE_BUFFER values. - * If the velocity is above the VELOCITY_THRESHOLD on an axis, split the amount into REVERSE_BUFFER - * and 1.0 - REVERSE_BUFFER fractions. The REVERSE_BUFFER fraction is set as the margin in the - * direction opposite to the velocity, and the remaining fraction is set as the margin in the direction - * of the velocity. If the velocity is lower than VELOCITY_THRESHOLD, split the amount evenly into the - * two margins on that axis. - */ - private RectF velocityBiasedMargins(float xAmount, float yAmount, PointF velocity) { - RectF margins = new RectF(); - - if (velocity.x > VELOCITY_THRESHOLD) { - margins.left = xAmount * REVERSE_BUFFER; - } else if (velocity.x < -VELOCITY_THRESHOLD) { - margins.left = xAmount * (1.0f - REVERSE_BUFFER); - } else { - margins.left = xAmount / 2.0f; - } - margins.right = xAmount - margins.left; - - if (velocity.y > VELOCITY_THRESHOLD) { - margins.top = yAmount * REVERSE_BUFFER; - } else if (velocity.y < -VELOCITY_THRESHOLD) { - margins.top = yAmount * (1.0f - REVERSE_BUFFER); - } else { - margins.top = yAmount / 2.0f; - } - margins.bottom = yAmount - margins.top; - - return margins; - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // but if we're panning on one axis, set the margins for the other axis to zero since we are likely - // axis locked and won't be displaying that extra area. - if (Math.abs(velocity.x) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.y, 0)) { - displayPortHeight = metrics.getHeight(); - } else if (Math.abs(velocity.y) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.x, 0)) { - displayPortWidth = metrics.getWidth(); - } - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). - displayPortWidth = Math.min(displayPortWidth, metrics.getPageWidth()); - displayPortHeight = Math.min(displayPortHeight, metrics.getPageHeight()); - float horizontalBuffer = displayPortWidth - metrics.getWidth(); - float verticalBuffer = displayPortHeight - metrics.getHeight(); - - // split the buffer amounts into margins based on velocity, and shift it to - // take into account the page bounds - RectF margins = velocityBiasedMargins(horizontalBuffer, verticalBuffer, velocity); - margins = shiftMarginsForPageBounds(margins, metrics); - - return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // calculate the danger zone amounts based on the prefs - float dangerZoneX = metrics.getWidth() * (DANGER_ZONE_BASE_X_MULTIPLIER + (velocity.x * DANGER_ZONE_INCR_X_MULTIPLIER)); - float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER)); - // clamp it such that when added to the viewport, they don't exceed page size. - // this is a prerequisite to calling shiftMarginsForPageBounds as we do below. - dangerZoneX = Math.min(dangerZoneX, metrics.getPageWidth() - metrics.getWidth()); - dangerZoneY = Math.min(dangerZoneY, metrics.getPageHeight() - metrics.getHeight()); - - // split the danger zone into margins based on velocity, and ensure it doesn't exceed - // page bounds. - RectF dangerMargins = velocityBiasedMargins(dangerZoneX, dangerZoneY, velocity); - dangerMargins = shiftMarginsForPageBounds(dangerMargins, metrics); - - // we're about to checkerboard if the current viewport area + the danger zone margins - // fall out of the current displayport anywhere. - RectF adjustedViewport = new RectF( - metrics.viewportRectLeft - dangerMargins.left, - metrics.viewportRectTop - dangerMargins.top, - metrics.viewportRectRight() + dangerMargins.right, - metrics.viewportRectBottom() + dangerMargins.bottom); - return !displayPort.contains(adjustedViewport); - } - - @Override - public String toString() { - return "VelocityBiasStrategy mult=" + SIZE_MULTIPLIER + ", threshold=" + VELOCITY_THRESHOLD + ", reverse=" + REVERSE_BUFFER - + ", dangerBaseX=" + DANGER_ZONE_BASE_X_MULTIPLIER + ", dangerBaseY=" + DANGER_ZONE_BASE_Y_MULTIPLIER - + ", dangerIncrX=" + DANGER_ZONE_INCR_Y_MULTIPLIER + ", dangerIncrY=" + DANGER_ZONE_INCR_Y_MULTIPLIER; - } - } - - /** - * This class implements the variation where we draw more of the page at low resolution while panning. - * In this variation, as we pan faster, we increase the page area we are drawing, but reduce the draw - * resolution to compensate. This results in the same device-pixel area drawn; the compositor then - * scales this up to the viewport zoom level. This results in a large area of the page drawn but it - * looks blurry. The assumption is that drawing extra that we never display is better than checkerboarding, - * where we draw less but never even show it on the screen. - */ - private static class DynamicResolutionStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private static final float SIZE_MULTIPLIER = 1.5f; - - // The velocity above which we start zooming out the display port to keep up - // with the panning. - private static final float VELOCITY_EXPANSION_THRESHOLD = GeckoAppShell.getDpi() / 16f; - - // How much we increase the display port based on velocity. Assuming no friction and - // splitting (see below), this should be be the number of frames (@60fps) between us - // calculating the display port and the draw of the *next* display port getting composited - // and displayed on the screen. This is because the timeline looks like this: - // Java: pan pan pan pan pan pan ! pan pan pan pan pan pan ! - // Gecko: \-> draw -> composite / \-> draw -> composite / - // The display port calculated on the first "pan" gets composited to the screen at the - // first exclamation mark, and remains on the screen until the second exclamation mark. - // In order to avoid checkerboarding, that display port must be able to contain all of - // the panning until the second exclamation mark, which encompasses two entire draw/composite - // cycles. - // If we take into account friction, our velocity multiplier should be reduced as the - // amount of pan will decrease each time. If we take into account display port splitting, - // it should be increased as the splitting means some of the display port will be used to - // draw in the opposite direction of the velocity. For now I'm assuming these two cancel - // each other out. - private static final float VELOCITY_MULTIPLIER = 60.0f; - - // The following constants adjust how biased the display port is in the direction of panning. - // When panning fast (above the FAST_THRESHOLD) we use the fast split factor to split the - // display port "buffer" area, otherwise we use the slow split factor. This is based on the - // assumption that if the user is panning fast, they are less likely to reverse directions - // and go backwards, so we should spend more of our display port buffer in the direction of - // panning. - private static final float VELOCITY_FAST_THRESHOLD = VELOCITY_EXPANSION_THRESHOLD * 2.0f; - private static final float FAST_SPLIT_FACTOR = 0.95f; - private static final float SLOW_SPLIT_FACTOR = 0.8f; - - // The following constants are used for viewport prediction; we use them to estimate where - // the viewport will be soon and whether or not we should trigger a draw right now. "soon" - // in the previous sentence really refers to the amount of time it would take to draw and - // composite from the point at which we do the calculation, and that is not really a known - // quantity. The velocity multiplier is how much we multiply the velocity by; it has the - // same caveats as the VELOCITY_MULTIPLIER above except that it only needs to take into account - // one draw/composite cycle instead of two. The danger zone multiplier is a multiplier of the - // viewport size that we use as an extra "danger zone" around the viewport; if this danger - // zone falls outside the display port then we are approaching the point at which we will - // checkerboard, and hence should start drawing. Note that if DANGER_ZONE_MULTIPLIER is - // greater than (SIZE_MULTIPLIER - 1.0f), then at zero velocity we will always be in the - // danger zone, and thus will be constantly drawing. - private static final float PREDICTION_VELOCITY_MULTIPLIER = 30.0f; - private static final float DANGER_ZONE_MULTIPLIER = 0.20f; // must be less than (SIZE_MULTIPLIER - 1.0f) - - DynamicResolutionStrategy(Map prefs) { - // ignore prefs for now - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // for resolution calculation purposes, we need to know what the adjusted display port dimensions - // would be if we had zero velocity, so calculate that here before we increase the display port - // based on velocity. - FloatSize reshapedSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - - // increase displayPortWidth and displayPortHeight based on the velocity, but maintaining their - // relative aspect ratio. - if (velocity.length() > VELOCITY_EXPANSION_THRESHOLD) { - float velocityFactor = Math.max(Math.abs(velocity.x) / displayPortWidth, - Math.abs(velocity.y) / displayPortHeight); - velocityFactor *= VELOCITY_MULTIPLIER; - - displayPortWidth += (displayPortWidth * velocityFactor); - displayPortHeight += (displayPortHeight * velocityFactor); - } - - // at this point, displayPortWidth and displayPortHeight are how much of the page (in device pixels) - // we want to be rendered by Gecko. Note here "device pixels" is equivalent to CSS pixels multiplied - // by metrics.zoomFactor - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). we simultaneously need to make - // the display port as large as possible so that we redraw less. reshape the display - // port dimensions to accomplish this. this may change the aspect ratio of the display port, - // but we are assuming that this is desirable because the advantages from pre-drawing will - // outweigh the disadvantages from any buffer reallocations that might occur. - FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - float horizontalBuffer = usableSize.width - metrics.getWidth(); - float verticalBuffer = usableSize.height - metrics.getHeight(); - - // at this point, horizontalBuffer and verticalBuffer are the dimensions of the buffer area we have. - // the buffer area is the off-screen area that is part of the display port and will be pre-drawn in case - // the user scrolls there. we now need to split the buffer area on each axis so that we know - // what the exact margins on each side will be. first we split the buffer amount based on the direction - // we're moving, so that we have a larger buffer in the direction of travel. - RectF margins = new RectF(); - margins.left = splitBufferByVelocity(horizontalBuffer, velocity.x); - margins.right = horizontalBuffer - margins.left; - margins.top = splitBufferByVelocity(verticalBuffer, velocity.y); - margins.bottom = verticalBuffer - margins.top; - - // then, we account for running into the page bounds - so that if we hit the top of the page, we need - // to drop the top margin and move that amount to the bottom margin. - margins = shiftMarginsForPageBounds(margins, metrics); - - // finally, we calculate the resolution we want to render the display port area at. We do this - // so that as we expand the display port area (because of velocity), we reduce the resolution of - // the painted area so as to maintain the size of the buffer Gecko is painting into. we calculate - // the reduction in resolution by comparing the display port size with and without the velocity - // changes applied. - // this effectively means that as we pan faster and faster, the display port grows, but we paint - // at lower resolutions. this paints more area to reduce checkerboard at the cost of increasing - // compositor-scaling and blurriness. Once we stop panning, the blurriness must be entirely gone. - // Note that usable* could be less than base* if we are pinch-zoomed out into overscroll, so we - // clamp it to make sure this doesn't increase our display resolution past metrics.zoomFactor. - float scaleFactor = Math.min(reshapedSize.width / usableSize.width, reshapedSize.height / usableSize.height); - float displayResolution = metrics.zoomFactor * Math.min(1.0f, scaleFactor); - - DisplayPortMetrics dpMetrics = new DisplayPortMetrics( - metrics.viewportRectLeft - margins.left, - metrics.viewportRectTop - margins.top, - metrics.viewportRectRight() + margins.right, - metrics.viewportRectBottom() + margins.bottom, - displayResolution); - return dpMetrics; - } - - /** - * Split the given buffer amount into two based on the velocity. - * Given an amount of total usable buffer on an axis, this will - * return the amount that should be used on the left/top side of - * the axis (the side which a negative velocity vector corresponds - * to). - */ - private float splitBufferByVelocity(float amount, float velocity) { - // if no velocity, so split evenly - if (FloatUtils.fuzzyEquals(velocity, 0)) { - return amount / 2.0f; - } - // if we're moving quickly, assign more of the amount in that direction - // since is is less likely that we will reverse direction immediately - if (velocity < -VELOCITY_FAST_THRESHOLD) { - return amount * FAST_SPLIT_FACTOR; - } - if (velocity > VELOCITY_FAST_THRESHOLD) { - return amount * (1.0f - FAST_SPLIT_FACTOR); - } - // if we're moving slowly, then assign less of the amount in that direction - if (velocity < 0) { - return amount * SLOW_SPLIT_FACTOR; - } else { - return amount * (1.0f - SLOW_SPLIT_FACTOR); - } - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // Expand the viewport based on our velocity (and clamp it to page boundaries). - // Then intersect it with the last-requested displayport to determine whether we're - // close to checkerboarding. - - RectF predictedViewport = metrics.getViewport(); - - // first we expand the viewport in the direction we're moving based on some - // multiple of the current velocity. - if (velocity.length() > 0) { - if (velocity.x < 0) { - predictedViewport.left += velocity.x * PREDICTION_VELOCITY_MULTIPLIER; - } else if (velocity.x > 0) { - predictedViewport.right += velocity.x * PREDICTION_VELOCITY_MULTIPLIER; - } - - if (velocity.y < 0) { - predictedViewport.top += velocity.y * PREDICTION_VELOCITY_MULTIPLIER; - } else if (velocity.y > 0) { - predictedViewport.bottom += velocity.y * PREDICTION_VELOCITY_MULTIPLIER; - } - } - - // then we expand the viewport evenly in all directions just to have an extra - // safety zone. this also clamps it to page bounds. - predictedViewport = expandByDangerZone(predictedViewport, DANGER_ZONE_MULTIPLIER, DANGER_ZONE_MULTIPLIER, metrics); - return !displayPort.contains(predictedViewport); - } - - @Override - public String toString() { - return "DynamicResolutionStrategy"; - } - } - - /** - * This class implements the variation where we use the draw time to predict where we will be when - * a draw completes, and draw that instead of where we are now. In this variation, when our panning - * speed drops below a certain threshold, we draw 9 viewports' worth of content so that the user can - * pan in any direction without encountering checkerboarding. - * Once the user is panning, we modify the displayport to encompass an area range of where we think - * the user will be when the draw completes. This heuristic relies on both the estimated draw time - * the panning velocity; unexpected changes in either of these values will cause the heuristic to - * fail and show checkerboard. - */ - private static class PredictionBiasStrategy extends DisplayPortStrategy { - private static float VELOCITY_THRESHOLD; - - private int mPixelArea; // area of the viewport, used in draw time calculations - private int mMinFramesToDraw; // minimum number of frames we take to draw - private int mMaxFramesToDraw; // maximum number of frames we take to draw - - PredictionBiasStrategy(Map prefs) { - VELOCITY_THRESHOLD = GeckoAppShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD, 16); - resetPageState(); - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float width = metrics.getWidth(); - float height = metrics.getHeight(); - mPixelArea = (int)(width * height); - - if (velocity.length() < VELOCITY_THRESHOLD) { - // if we're going slow, expand the displayport to 9x viewport size - RectF margins = new RectF(width, height, width, height); - return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - // figure out how far we expect to be - float minDx = velocity.x * mMinFramesToDraw; - float minDy = velocity.y * mMinFramesToDraw; - float maxDx = velocity.x * mMaxFramesToDraw; - float maxDy = velocity.y * mMaxFramesToDraw; - - // figure out how many pixels we will be drawing when we draw the above-calculated range. - // this will be larger than the viewport area. - float pixelsToDraw = (width + Math.abs(maxDx - minDx)) * (height + Math.abs(maxDy - minDy)); - // adjust how far we will get because of the time spent drawing all these extra pixels. this - // will again increase the number of pixels drawn so really we could keep iterating this over - // and over, but once seems enough for now. - maxDx = maxDx * pixelsToDraw / mPixelArea; - maxDy = maxDy * pixelsToDraw / mPixelArea; - - // and finally generate the displayport. the min/max stuff takes care of - // negative velocities as well as positive. - RectF margins = new RectF( - -Math.min(minDx, maxDx), - -Math.min(minDy, maxDy), - Math.max(minDx, maxDx), - Math.max(minDy, maxDy)); - return getPageClampedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // the code below is the same as in calculate() but is awkward to refactor since it has multiple outputs. - // refer to the comments in calculate() to understand what this is doing. - float minDx = velocity.x * mMinFramesToDraw; - float minDy = velocity.y * mMinFramesToDraw; - float maxDx = velocity.x * mMaxFramesToDraw; - float maxDy = velocity.y * mMaxFramesToDraw; - float pixelsToDraw = (metrics.getWidth() + Math.abs(maxDx - minDx)) * (metrics.getHeight() + Math.abs(maxDy - minDy)); - maxDx = maxDx * pixelsToDraw / mPixelArea; - maxDy = maxDy * pixelsToDraw / mPixelArea; - - // now that we have an idea of how far we will be when the draw completes, take the farthest - // end of that range and see if it falls outside the displayport bounds. if it does, allow - // the draw to go through - RectF predictedViewport = metrics.getViewport(); - predictedViewport.left += maxDx; - predictedViewport.top += maxDy; - predictedViewport.right += maxDx; - predictedViewport.bottom += maxDy; - - predictedViewport = clampToPageBounds(predictedViewport, metrics); - return !displayPort.contains(predictedViewport); - } - - @Override - public boolean drawTimeUpdate(long millis, int pixels) { - // calculate the number of frames it took to draw a viewport-sized area - float normalizedTime = (float)mPixelArea * millis / pixels; - int normalizedFrames = (int) Math.ceil(normalizedTime * 60f / 1000f); - // broaden our range on how long it takes to draw if the draw falls outside - // the range. this allows it to grow gradually. this heuristic may need to - // be tweaked into more of a floating window average or something. - if (normalizedFrames <= mMinFramesToDraw) { - mMinFramesToDraw--; - } else if (normalizedFrames > mMaxFramesToDraw) { - mMaxFramesToDraw++; - } else { - return true; - } - Log.d(LOGTAG, "Widened draw range to [" + mMinFramesToDraw + ", " + mMaxFramesToDraw + "]"); - return true; - } - - @Override - public void resetPageState() { - mMinFramesToDraw = 0; - mMaxFramesToDraw = 2; - } - - @Override - public String toString() { - return "PredictionBiasStrategy threshold=" + VELOCITY_THRESHOLD; - } - } -} diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java deleted file mode 100644 index 0138d849c73f..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- 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.gfx; - -import org.mozilla.gecko.annotation.WrapForJNI; -import org.mozilla.gecko.util.FloatUtils; - -import android.graphics.RectF; - -/* - * This class keeps track of the area we request Gecko to paint, as well - * as the resolution of the paint. The area may be different from the visible - * area of the page, and the resolution may be different from the resolution - * used in the compositor to render the page. This is so that we can ask Gecko - * to paint a much larger area without using extra memory, and then render some - * subsection of that with compositor scaling. - */ -public final class DisplayPortMetrics { - @WrapForJNI(calledFrom = "gecko") - public final float resolution; - @WrapForJNI(calledFrom = "gecko") - private final RectF mPosition; - - public DisplayPortMetrics() { - this(0, 0, 0, 0, 1); - } - - @WrapForJNI(calledFrom = "gecko") - public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) { - this.resolution = resolution; - mPosition = new RectF(left, top, right, bottom); - } - - public float getLeft() { - return mPosition.left; - } - - public float getTop() { - return mPosition.top; - } - - public float getRight() { - return mPosition.right; - } - - public float getBottom() { - return mPosition.bottom; - } - - public boolean contains(RectF rect) { - return mPosition.contains(rect); - } - - public boolean fuzzyEquals(DisplayPortMetrics metrics) { - return RectUtils.fuzzyEquals(mPosition, metrics.mPosition) - && FloatUtils.fuzzyEquals(resolution, metrics.resolution); - } - - public String toJSON() { - StringBuilder sb = new StringBuilder(256); - sb.append("{ \"left\": ").append(mPosition.left) - .append(", \"top\": ").append(mPosition.top) - .append(", \"right\": ").append(mPosition.right) - .append(", \"bottom\": ").append(mPosition.bottom) - .append(", \"resolution\": ").append(resolution) - .append('}'); - return sb.toString(); - } - - @Override - public String toString() { - return "DisplayPortMetrics v=(" + mPosition.left + "," + mPosition.top + "," + mPosition.right + "," - + mPosition.bottom + ") z=" + resolution; - } -} diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java deleted file mode 100644 index c6c676b0cd6a..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- 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.gfx; - -import android.os.SystemClock; - -/** - * A custom-built data structure to assist with measuring draw times. - * - * This class maintains a fixed-size circular buffer of DisplayPortMetrics - * objects and associated timestamps. It provides only three operations, which - * is all we require for our purposes of measuring draw times. Note - * in particular that the class is designed so that even though it is - * accessed from multiple threads, it does not require synchronization; - * any concurrency errors that result from this are handled gracefully. - * - * Assuming an unrolled buffer so that mTail is greater than mHead, the data - * stored in the buffer at entries [mHead, mTail) will never be modified, and - * so are "safe" to read. If this reading is done on the same thread that - * owns mHead, then reading the range [mHead, mTail) is guaranteed to be safe - * since the range itself will not shrink. - */ -final class DrawTimingQueue { - private static final String LOGTAG = "GeckoDrawTimingQueue"; - private static final int BUFFER_SIZE = 16; - - private final DisplayPortMetrics[] mMetrics; - private final long[] mTimestamps; - - private int mHead; - private int mTail; - - DrawTimingQueue() { - mMetrics = new DisplayPortMetrics[BUFFER_SIZE]; - mTimestamps = new long[BUFFER_SIZE]; - mHead = BUFFER_SIZE - 1; - } - - /** - * Add a new entry to the tail of the queue. If the buffer is full, - * do nothing. This must only be called from the Java UI thread. - */ - boolean add(DisplayPortMetrics metrics) { - if (mHead == mTail) { - return false; - } - mMetrics[mTail] = metrics; - mTimestamps[mTail] = SystemClock.uptimeMillis(); - mTail = (mTail + 1) % BUFFER_SIZE; - return true; - } - - /** - * Find the timestamp associated with the given metrics, AND remove - * all metrics objects from the start of the queue up to and including - * the one provided. Note that because of draw coalescing, the metrics - * object passed in here may not be the one at the head of the queue, - * and so we must iterate our way through the list to find it. - * This must only be called from the compositor thread. - */ - long findTimeFor(DisplayPortMetrics metrics) { - // keep a copy of the tail pointer so that we ignore new items - // added to the queue while we are searching. this is fine because - // the one we are looking for will either have been added already - // or will not be in the queue at all. - int tail = mTail; - // walk through the "safe" range from mHead to tail; these entries - // will not be modified unless we change mHead. - int i = (mHead + 1) % BUFFER_SIZE; - while (i != tail) { - if (mMetrics[i].fuzzyEquals(metrics)) { - // found it, copy out the timestamp to a local var BEFORE - // changing mHead or add could clobber the timestamp. - long timestamp = mTimestamps[i]; - mHead = i; - return timestamp; - } - i = (i + 1) % BUFFER_SIZE; - } - return -1; - } - - /** - * Reset the buffer to empty. - * This must only be called from the compositor thread. - */ - void reset() { - // we can only modify mHead on this thread. - mHead = (mTail + BUFFER_SIZE - 1) % BUFFER_SIZE; - } -} diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 41927a93e6ee..7fb2637ca7bc 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -39,20 +39,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget private final Context mContext; private IntSize mScreenSize; private IntSize mWindowSize; - private DisplayPortMetrics mDisplayPort; - - private boolean mRecordDrawTimes; - private final DrawTimingQueue mDrawTimingQueue; - - /* The Gecko viewport as per the UI thread. Must be touched only on the UI thread. - * If any events being sent to Gecko that are relative to the Gecko viewport position, - * they must (a) be relative to this viewport, and (b) be sent on the UI thread to - * avoid races. As long as these two conditions are satisfied, and the events being - * sent to Gecko are processed in FIFO order, the events will properly be relative - * to the Gecko viewport position. Note that if Gecko updates its viewport independently, - * we get notified synchronously and also update this on the UI thread. - */ - private ImmutableViewportMetrics mGeckoViewport; /* * The viewport metrics being used to draw the current frame. This is only @@ -65,12 +51,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget /* Used as temporaries by syncViewportInfo */ private final ViewTransform mCurrentViewTransform; - /* Used as the return value of progressiveUpdateCallback */ - private final ProgressiveUpdateData mProgressiveUpdateData; - private DisplayPortMetrics mProgressiveUpdateDisplayPort; - private boolean mLastProgressiveUpdateWasLowPrecision; - private boolean mProgressiveUpdateWasInDanger; - private boolean mForceRedraw; /* The current viewport metrics. @@ -113,12 +93,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mContext = context; mScreenSize = new IntSize(0, 0); mWindowSize = new IntSize(0, 0); - mDisplayPort = new DisplayPortMetrics(); - mRecordDrawTimes = true; - mDrawTimingQueue = new DrawTimingQueue(); mCurrentViewTransform = new ViewTransform(0, 0, 1); - mProgressiveUpdateData = new ProgressiveUpdateData(); - mProgressiveUpdateDisplayPort = new DisplayPortMetrics(); mForceRedraw = true; DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); @@ -157,8 +132,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget sendResizeEventIfNecessary(true, null); - DisplayPortCalculator.initPrefs(); - // Gecko being ready is one of the two conditions (along with having an available // surface) that cause us to create the compositor. So here, now that we know gecko // is ready, call updateCompositor() to see if we can actually do the creation. @@ -342,16 +315,9 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget .setZoomFactor(zoom) .setPageRect(pageRect, cssPageRect); // Since we have switched to displaying a different document, we need to update any - // viewport-related state we have lying around. This includes mGeckoViewport and - // mViewportMetrics. Usually this information is updated via handleViewportMessage + // viewport-related state we have lying around (i.e. mViewportMetrics). + // Usually this information is updated via handleViewportMessage // while we remain on the same document. - post(new Runnable() { - @Override - public void run() { - mGeckoViewport = newMetrics; - } - }); - setViewportMetrics(newMetrics); // Indicate that the document is about to be composited so the @@ -360,8 +326,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mView.setPaintState(LayerView.PAINT_BEFORE_FIRST); } } - DisplayPortCalculator.resetPageState(); - mDrawTimingQueue.reset(); mContentDocumentIsDisplayed = true; } @@ -406,19 +370,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget } mToolbarAnimator.populateViewTransform(mCurrentViewTransform, mFrameMetrics); - if (layersUpdated && mRecordDrawTimes) { - // If we got a layers update, that means a draw finished. Check to see if the area drawn matches - // one of our requested displayports; if it does calculate the draw time and notify the - // DisplayPortCalculator - DisplayPortMetrics drawn = new DisplayPortMetrics(x, y, x + width, y + height, resolution); - long time = mDrawTimingQueue.findTimeFor(drawn); - if (time >= 0) { - long now = SystemClock.uptimeMillis(); - time = now - time; - mRecordDrawTimes = DisplayPortCalculator.drawTimeUpdate(time, width * height); - } - } - if (layersUpdated) { for (DrawListener listener : mDrawListeners) { listener.drawFinished(); @@ -678,7 +629,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget } } - private void geometryChanged(DisplayPortMetrics displayPort) { + private void geometryChanged() { /* Let Gecko know if the screensize has changed */ sendResizeEventIfNecessary(false, null); } @@ -711,13 +662,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget /** Implementation of PanZoomTarget */ @Override public void setAnimationTarget(ImmutableViewportMetrics metrics) { - if (mGeckoIsReady) { - // We know what the final viewport of the animation is going to be, so - // immediately request a draw of that area by setting the display port - // accordingly. This way we should have the content pre-rendered by the - // time the animation is done. - DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null); - } } /** Implementation of PanZoomTarget @@ -751,7 +695,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mView.requestRender(); if (notifyGecko && mGeckoIsReady) { - geometryChanged(null); + geometryChanged(); } } @@ -790,15 +734,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget mToolbarAnimator.onPanZoomStopped(); } - /** Implementation of PanZoomTarget */ - @Override - public void forceRedraw(DisplayPortMetrics displayPort) { - mForceRedraw = true; - if (mGeckoIsReady) { - geometryChanged(displayPort); - } - } - /** Implementation of PanZoomTarget */ @Override public boolean post(Runnable action) { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java index 2905828e7d53..54f6ce942107 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java @@ -17,8 +17,6 @@ public interface PanZoomTarget { public void setViewportMetrics(ImmutableViewportMetrics viewport); public void scrollBy(float dx, float dy); public void panZoomStopped(); - /** This triggers an (asynchronous) viewport update/redraw. */ - public void forceRedraw(DisplayPortMetrics displayPort); public boolean isGeckoReady(); public boolean post(Runnable action); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java deleted file mode 100644 index 27e8e1532977..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java +++ /dev/null @@ -1,322 +0,0 @@ -/* -*- 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.gfx; - -import org.json.JSONException; - -import android.graphics.PointF; -import android.util.Log; -import android.view.MotionEvent; - -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Stack; - -/** - * A less buggy, and smoother, replacement for the built-in Android ScaleGestureDetector. - * - * This gesture detector is more reliable than the built-in ScaleGestureDetector because: - * - * - It doesn't assume that pointer IDs are numbered 0 and 1. - * - * - It doesn't attempt to correct for "slop" when resting one's hand on the device. On some - * devices (e.g. the Droid X) this can cause the ScaleGestureDetector to lose track of how many - * pointers are down, with disastrous results (bug 706684). - * - * - Cancelling a zoom into a pan is handled correctly. - * - * - Starting with three or more fingers down, releasing fingers so that only two are down, and - * then performing a scale gesture is handled correctly. - * - * - It doesn't take pressure into account, which results in smoother scaling. - */ -class SimpleScaleGestureDetector { - private static final String LOGTAG = "GeckoSimpleScaleGestureDetector"; - - private final SimpleScaleGestureListener mListener; - private long mLastEventTime; - private boolean mScaleResult; - - /* Information about all pointers that are down. */ - private final LinkedList mPointerInfo; - - /** Creates a new gesture detector with the given listener. */ - SimpleScaleGestureDetector(SimpleScaleGestureListener listener) { - mListener = listener; - mPointerInfo = new LinkedList(); - } - - /** Forward touch events to this function. */ - public void onTouchEvent(MotionEvent event) { - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - // If we get ACTION_DOWN while still tracking any pointers, - // something is wrong. Cancel the current gesture and start over. - if (getPointersDown() > 0) - onTouchEnd(event); - onTouchStart(event); - break; - case MotionEvent.ACTION_POINTER_DOWN: - onTouchStart(event); - break; - case MotionEvent.ACTION_MOVE: - onTouchMove(event); - break; - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - onTouchEnd(event); - break; - } - } - - private int getPointersDown() { - return mPointerInfo.size(); - } - - private int getActionIndex(MotionEvent event) { - return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) - >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - - private void onTouchStart(MotionEvent event) { - mLastEventTime = event.getEventTime(); - mPointerInfo.addFirst(PointerInfo.create(event, getActionIndex(event))); - if (getPointersDown() == 2) { - sendScaleGesture(EventType.BEGIN); - } - } - - private void onTouchMove(MotionEvent event) { - mLastEventTime = event.getEventTime(); - for (int i = 0; i < event.getPointerCount(); i++) { - PointerInfo pointerInfo = pointerInfoForEventIndex(event, i); - if (pointerInfo != null) { - pointerInfo.populate(event, i); - } - } - - if (getPointersDown() == 2) { - sendScaleGesture(EventType.CONTINUE); - } - } - - private void onTouchEnd(MotionEvent event) { - mLastEventTime = event.getEventTime(); - - int action = event.getAction() & MotionEvent.ACTION_MASK; - boolean isCancel = (action == MotionEvent.ACTION_CANCEL || - action == MotionEvent.ACTION_DOWN); - - int id = event.getPointerId(getActionIndex(event)); - ListIterator iterator = mPointerInfo.listIterator(); - while (iterator.hasNext()) { - PointerInfo pointerInfo = iterator.next(); - if (!(isCancel || pointerInfo.getId() == id)) { - continue; - } - - // One of the pointers we were tracking was lifted. Remove its info object from the - // list, recycle it to avoid GC pauses, and send an onScaleEnd() notification if this - // ended the gesture. - iterator.remove(); - pointerInfo.recycle(); - if (getPointersDown() == 1) { - sendScaleGesture(EventType.END); - } - } - } - - /** - * Returns the X coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusX() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().x; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().x + pointerB.getCurrent().x) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusX()!"); - return 0.0f; - } - - /** - * Returns the Y coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusY() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().y; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().y + pointerB.getCurrent().y) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusY()!"); - return 0.0f; - } - - /** Returns the most recent distance between the two pointers. */ - public float getCurrentSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getCurrentSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return PointUtils.distance(pointerA.getCurrent(), pointerB.getCurrent()); - } - - /** Returns the second most recent distance between the two pointers. */ - public float getPreviousSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getPreviousSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - PointF a = pointerA.getPrevious(), b = pointerB.getPrevious(); - if (a == null || b == null) { - a = pointerA.getCurrent(); - b = pointerB.getCurrent(); - } - - return PointUtils.distance(a, b); - } - - /** Returns the time of the last event related to the gesture. */ - public long getEventTime() { - return mLastEventTime; - } - - /** Returns true if the scale gesture is in progress and false otherwise. */ - public boolean isInProgress() { - return getPointersDown() == 2; - } - - /* Sends the requested scale gesture notification to the listener. */ - private void sendScaleGesture(EventType eventType) { - switch (eventType) { - case BEGIN: - mScaleResult = mListener.onScaleBegin(this); - break; - case CONTINUE: - if (mScaleResult) { - mListener.onScale(this); - } - break; - case END: - if (mScaleResult) { - mListener.onScaleEnd(this); - } - break; - } - } - - /* - * Returns the pointer info corresponding to the given pointer index, or null if the pointer - * isn't one that's being tracked. - */ - private PointerInfo pointerInfoForEventIndex(MotionEvent event, int index) { - int id = event.getPointerId(index); - for (PointerInfo pointerInfo : mPointerInfo) { - if (pointerInfo.getId() == id) { - return pointerInfo; - } - } - return null; - } - - private enum EventType { - BEGIN, - CONTINUE, - END, - } - - /* Encapsulates information about one of the two fingers involved in the gesture. */ - private static class PointerInfo { - /* A free list that recycles pointer info objects, to reduce GC pauses. */ - private static Stack sPointerInfoFreeList; - - private int mId; - private PointF mCurrent, mPrevious; - - private PointerInfo() { - // External users should use create() instead. - } - - /* Creates or recycles a new PointerInfo instance from an event and a pointer index. */ - public static PointerInfo create(MotionEvent event, int index) { - if (sPointerInfoFreeList == null) { - sPointerInfoFreeList = new Stack(); - } - - PointerInfo pointerInfo; - if (sPointerInfoFreeList.empty()) { - pointerInfo = new PointerInfo(); - } else { - pointerInfo = sPointerInfoFreeList.pop(); - } - - pointerInfo.populate(event, index); - return pointerInfo; - } - - /* - * Fills in the fields of this instance from the given motion event and pointer index - * within that event. - */ - public void populate(MotionEvent event, int index) { - mId = event.getPointerId(index); - mPrevious = mCurrent; - mCurrent = new PointF(event.getX(index), event.getY(index)); - } - - public void recycle() { - mId = -1; - mPrevious = mCurrent = null; - sPointerInfoFreeList.push(this); - } - - public int getId() { return mId; } - public PointF getCurrent() { return mCurrent; } - public PointF getPrevious() { return mPrevious; } - - @Override - public String toString() { - if (mId == -1) { - return "(up)"; - } - - try { - String prevString; - if (mPrevious == null) { - prevString = "n/a"; - } else { - prevString = PointUtils.toJSON(mPrevious).toString(); - } - - // The current position should always be non-null. - String currentString = PointUtils.toJSON(mCurrent).toString(); - return "id=" + mId + " cur=" + currentString + " prev=" + prevString; - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - public static interface SimpleScaleGestureListener { - public boolean onScale(SimpleScaleGestureDetector detector); - public boolean onScaleBegin(SimpleScaleGestureDetector detector); - public void onScaleEnd(SimpleScaleGestureDetector detector); - } -} - diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java deleted file mode 100644 index 20f4826f62cd..000000000000 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- 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.gfx; - -import org.mozilla.gecko.GeckoAppShell; -import org.mozilla.gecko.EventDispatcher; -import org.mozilla.gecko.util.GeckoEventListener; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.graphics.PointF; -import android.os.Handler; -import android.util.Log; - -class SubdocumentScrollHelper implements GeckoEventListener { - private static final String LOGTAG = "GeckoSubdocScroll"; - - private static final String MESSAGE_PANNING_OVERRIDE = "Panning:Override"; - private static final String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride"; - private static final String MESSAGE_SCROLL = "Gesture:Scroll"; - private static final String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck"; - - private final Handler mUiHandler; - private final EventDispatcher mEventDispatcher; - - /* This is the amount of displacement we have accepted but not yet sent to JS; this is - * only valid when mOverrideScrollPending is true. */ - private final PointF mPendingDisplacement; - - /* When this is true, we're sending scroll events to JS to scroll the active subdocument. */ - private boolean mOverridePanning; - - /* When this is true, we have received an ack for the last scroll event we sent to JS, and - * are ready to send the next scroll event. Note we only ever have one scroll event inflight - * at a time. */ - private boolean mOverrideScrollAck; - - /* When this is true, we have a pending scroll that we need to send to JS; we were unable - * to send it when it was initially requested because mOverrideScrollAck was not true. */ - private boolean mOverrideScrollPending; - - /* When this is true, the last scroll event we sent actually did some amount of scrolling on - * the subdocument; we use this to decide when we have reached the end of the subdocument. */ - private boolean mScrollSucceeded; - - SubdocumentScrollHelper(EventDispatcher eventDispatcher) { - // mUiHandler will be bound to the UI thread since that's where this constructor runs - mUiHandler = new Handler(); - mPendingDisplacement = new PointF(); - - mEventDispatcher = eventDispatcher; - mEventDispatcher.registerGeckoThreadListener(this, - MESSAGE_PANNING_OVERRIDE, - MESSAGE_CANCEL_OVERRIDE, - MESSAGE_SCROLL_ACK); - } - - void destroy() { - mEventDispatcher.unregisterGeckoThreadListener(this, - MESSAGE_PANNING_OVERRIDE, - MESSAGE_CANCEL_OVERRIDE, - MESSAGE_SCROLL_ACK); - } - - boolean scrollBy(PointF displacement) { - if (! mOverridePanning) { - return false; - } - - if (! mOverrideScrollAck) { - mOverrideScrollPending = true; - mPendingDisplacement.x += displacement.x; - mPendingDisplacement.y += displacement.y; - return true; - } - - JSONObject json = new JSONObject(); - try { - json.put("x", displacement.x); - json.put("y", displacement.y); - } catch (JSONException e) { - Log.e(LOGTAG, "Error forming subwindow scroll message: ", e); - } - GeckoAppShell.notifyObservers(MESSAGE_SCROLL, json.toString()); - - mOverrideScrollAck = false; - mOverrideScrollPending = false; - // clear the |mPendingDisplacement| after serializing |displacement| to - // JSON because they might be the same object - mPendingDisplacement.x = 0; - mPendingDisplacement.y = 0; - - return true; - } - - void cancel() { - mOverridePanning = false; - } - - boolean scrolling() { - return mOverridePanning; - } - - boolean lastScrollSucceeded() { - return mScrollSucceeded; - } - - // GeckoEventListener implementation - - @Override - public void handleMessage(final String event, final JSONObject message) { - // This comes in on the Gecko thread; hand off the handling to the UI thread. - mUiHandler.post(new Runnable() { - @Override - public void run() { - try { - if (MESSAGE_PANNING_OVERRIDE.equals(event)) { - mOverridePanning = true; - mOverrideScrollAck = true; - mOverrideScrollPending = false; - mScrollSucceeded = true; - } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) { - mOverridePanning = false; - } else if (MESSAGE_SCROLL_ACK.equals(event)) { - mOverrideScrollAck = true; - mScrollSucceeded = message.getBoolean("scrolled"); - if (mOverridePanning && mOverrideScrollPending) { - scrollBy(mPendingDisplacement); - } - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message", e); - } - } - }); - } -} diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp index 780afffc83dd..240428f9ddba 100644 --- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -1092,33 +1092,6 @@ auto SurfaceTextureListener::New() -> SurfaceTextureListener::LocalRef constexpr char SurfaceTextureListener::OnFrameAvailable_t::name[]; constexpr char SurfaceTextureListener::OnFrameAvailable_t::signature[]; -const char DisplayPortMetrics::name[] = - "org/mozilla/gecko/gfx/DisplayPortMetrics"; - -constexpr char DisplayPortMetrics::New_t::name[]; -constexpr char DisplayPortMetrics::New_t::signature[]; - -auto DisplayPortMetrics::New(float a0, float a1, float a2, float a3, float a4) -> DisplayPortMetrics::LocalRef -{ - return mozilla::jni::Constructor::Call(DisplayPortMetrics::Context(), nullptr, a0, a1, a2, a3, a4); -} - -constexpr char DisplayPortMetrics::MPosition_t::name[]; -constexpr char DisplayPortMetrics::MPosition_t::signature[]; - -auto DisplayPortMetrics::MPosition() const -> mozilla::jni::Object::LocalRef -{ - return mozilla::jni::Field::Get(DisplayPortMetrics::mCtx, nullptr); -} - -constexpr char DisplayPortMetrics::Resolution_t::name[]; -constexpr char DisplayPortMetrics::Resolution_t::signature[]; - -auto DisplayPortMetrics::Resolution() const -> float -{ - return mozilla::jni::Field::Get(DisplayPortMetrics::mCtx, nullptr); -} - const char GeckoLayerClient::name[] = "org/mozilla/gecko/gfx/GeckoLayerClient"; diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h index 88ec68d3525f..108caa032e02 100644 --- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -3514,80 +3514,6 @@ public: template class Natives; }; -class DisplayPortMetrics : public mozilla::jni::ObjectBase -{ -public: - static const char name[]; - - explicit DisplayPortMetrics(const Context& ctx) : ObjectBase(ctx) {} - - struct New_t { - typedef DisplayPortMetrics Owner; - typedef DisplayPortMetrics::LocalRef ReturnType; - typedef DisplayPortMetrics::Param SetterType; - typedef mozilla::jni::Args< - float, - float, - float, - float, - float> Args; - static constexpr char name[] = ""; - static constexpr char signature[] = - "(FFFFF)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::GECKO; - static const mozilla::jni::DispatchTarget dispatchTarget = - mozilla::jni::DispatchTarget::CURRENT; - }; - - static auto New(float, float, float, float, float) -> DisplayPortMetrics::LocalRef; - - struct MPosition_t { - typedef DisplayPortMetrics Owner; - typedef mozilla::jni::Object::LocalRef ReturnType; - typedef mozilla::jni::Object::Param SetterType; - typedef mozilla::jni::Args<> Args; - static constexpr char name[] = "mPosition"; - static constexpr char signature[] = - "Landroid/graphics/RectF;"; - static const bool isStatic = false; - 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; - }; - - auto MPosition() const -> mozilla::jni::Object::LocalRef; - - struct Resolution_t { - typedef DisplayPortMetrics Owner; - typedef float ReturnType; - typedef float SetterType; - typedef mozilla::jni::Args<> Args; - static constexpr char name[] = "resolution"; - static constexpr char signature[] = - "F"; - static const bool isStatic = false; - 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; - }; - - auto Resolution() const -> float; - - static const mozilla::jni::CallingThread callingThread = - mozilla::jni::CallingThread::GECKO; - -}; - class GeckoLayerClient : public mozilla::jni::ObjectBase { public: From 1929c7c930de943544943bd386b534205a090874 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 4 Oct 2016 14:41:15 -0400 Subject: [PATCH 02/37] Bug 1307522 - Remove a bunch of unnecessary methods from the PanZoomTarget interface now that JPZ is gone. r=snorp MozReview-Commit-ID: CPIDkGX3jhr --HG-- extra : rebase_source : 158f4b5a744d54fa5914589a86db8d2be4786ce9 --- .../mozilla/gecko/gfx/GeckoLayerClient.java | 79 ++----------------- .../java/org/mozilla/gecko/gfx/LayerView.java | 4 - .../org/mozilla/gecko/gfx/PanZoomTarget.java | 14 ---- 3 files changed, 7 insertions(+), 90 deletions(-) diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java index 7fb2637ca7bc..df8a0aee067b 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -267,7 +267,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget // Page size is owned by the layer client, so no need to notify it of // this change. - post(new Runnable() { + mView.post(new Runnable() { @Override public void run() { mView.requestRender(); @@ -318,7 +318,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget // viewport-related state we have lying around (i.e. mViewportMetrics). // Usually this information is updated via handleViewportMessage // while we remain on the same document. - setViewportMetrics(newMetrics); + setViewportMetrics(newMetrics, true); // Indicate that the document is about to be composited so the // LayerView background can be removed. @@ -641,37 +641,10 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget setViewportSize(viewportSize.width, viewportSize.height, null); } - /** Implementation of PanZoomTarget */ - @Override - public ImmutableViewportMetrics getViewportMetrics() { + ImmutableViewportMetrics getViewportMetrics() { return mViewportMetrics; } - /** Implementation of PanZoomTarget */ - @Override - public FullScreenState getFullScreenState() { - return mView.getFullScreenState(); - } - - /** Implementation of PanZoomTarget */ - @Override - public PointF getVisibleEndOfLayerView() { - return mToolbarAnimator.getVisibleEndOfLayerView(); - } - - /** Implementation of PanZoomTarget */ - @Override - public void setAnimationTarget(ImmutableViewportMetrics metrics) { - } - - /** Implementation of PanZoomTarget - * You must hold the monitor while calling this. - */ - @Override - public void setViewportMetrics(ImmutableViewportMetrics metrics) { - setViewportMetrics(metrics, true); - } - /* * You must hold the monitor while calling this. */ @@ -712,61 +685,24 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget viewportMetricsChanged(notifyGecko); } - /** Implementation of PanZoomTarget - * Scroll the viewport by a certain amount. This will take viewport margins - * and margin animation into account. If margins are currently animating, - * this will just go ahead and modify the viewport origin, otherwise the - * delta will be applied to the margins and the remainder will be applied to - * the viewport origin. - * - * You must hold the monitor while calling this. - */ - @Override - public void scrollBy(float dx, float dy) { - // Set mViewportMetrics manually so the margin changes take. - mViewportMetrics = mViewportMetrics.offsetViewportBy(dx, dy); - viewportMetricsChanged(true); - } - /** Implementation of PanZoomTarget */ @Override public void panZoomStopped() { mToolbarAnimator.onPanZoomStopped(); } - /** Implementation of PanZoomTarget */ - @Override - public boolean post(Runnable action) { - return mView.post(action); - } - - /** Implementation of PanZoomTarget */ - @Override - public void postRenderTask(RenderTask task) { - mView.postRenderTask(task); - } - - /** Implementation of PanZoomTarget */ - @Override - public void removeRenderTask(RenderTask task) { - mView.removeRenderTask(task); - } - - /** Implementation of PanZoomTarget */ - @Override - public Object getLock() { + Object getLock() { return this; } - /** Implementation of PanZoomTarget + /** * Converts a point from layer view coordinates to layer coordinates. In other words, given a * point measured in pixels from the top left corner of the layer view, returns the point in * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the * events being sent to Gecko are processed in FIFO order, this calculation should always be * correct. */ - @Override - public PointF convertViewPointToLayerPoint(PointF viewPoint) { + PointF convertViewPointToLayerPoint(PointF viewPoint) { if (!mGeckoIsReady) { return null; } @@ -790,8 +726,7 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget return layerPoint; } - @Override - public Matrix getMatrixForLayerRectToViewRect() { + Matrix getMatrixForLayerRectToViewRect() { if (!mGeckoIsReady) { return null; } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java index e5b08e60d48d..38adea1e4684 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java @@ -676,10 +676,6 @@ public class LayerView extends FrameLayout { return mFullScreenState != FullScreenState.NONE; } - public FullScreenState getFullScreenState() { - return mFullScreenState; - } - public void setMaxTranslation(float aMaxTranslation) { mToolbarAnimator.setMaxTranslation(aMaxTranslation); } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java index 54f6ce942107..0896674fc801 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java @@ -9,21 +9,7 @@ import android.graphics.Matrix; import android.graphics.PointF; public interface PanZoomTarget { - public ImmutableViewportMetrics getViewportMetrics(); - public FullScreenState getFullScreenState(); - public PointF getVisibleEndOfLayerView(); - - public void setAnimationTarget(ImmutableViewportMetrics viewport); - public void setViewportMetrics(ImmutableViewportMetrics viewport); - public void scrollBy(float dx, float dy); public void panZoomStopped(); - public boolean isGeckoReady(); - public boolean post(Runnable action); - public void postRenderTask(RenderTask task); - public void removeRenderTask(RenderTask task); - public Object getLock(); - public PointF convertViewPointToLayerPoint(PointF viewPoint); - public Matrix getMatrixForLayerRectToViewRect(); public void setScrollingRootContent(boolean isRootContent); } From e2dea2817b24b2cf623d419099526a263005fe28 Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Mon, 3 Oct 2016 16:57:36 -0400 Subject: [PATCH 03/37] Bug 1307228: Remove a warning that doesn't help. r=dvander MozReview-Commit-ID: HvxPaYGhgwa --HG-- extra : rebase_source : 32a87d99f95d875ef7006411a8d7f3303886ea36 --- gfx/thebes/gfxWindowsPlatform.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index f44a26cd8812..f12a6270f5d4 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1996,8 +1996,6 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray& aB if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) { aBackends.AppendElement(LayersBackend::LAYERS_D3D11); - } else { - NS_WARNING("Direct3D 11-accelerated layers are not supported on this system."); } if (gfxConfig::IsEnabled(Feature::D3D9_COMPOSITING) && !gfxPrefs::LayersPreferD3D9()) { From ee56723139c603b26c887c74f9b4ee0563b80f47 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Tue, 20 Sep 2016 15:36:25 -0700 Subject: [PATCH 04/37] bug 1304188 - introduce X509.jsm r=Cykesiopka,jcj This is mostly a preliminary review request, although I think everything that should be done in this bug is present. This intentionally does not include support for decoding extensions or subject public keys. MozReview-Commit-ID: 4ewu66Xx411 --HG-- extra : rebase_source : 6105cf16e46d5d2cc9355cf38f8d0098a8a40462 --- security/manager/ssl/X509.jsm | 632 +++++++++++++++++++ security/manager/ssl/moz.build | 1 + security/manager/ssl/tests/unit/test_x509.js | 83 +++ security/manager/ssl/tests/unit/xpcshell.ini | 1 + 4 files changed, 717 insertions(+) create mode 100644 security/manager/ssl/X509.jsm create mode 100644 security/manager/ssl/tests/unit/test_x509.js diff --git a/security/manager/ssl/X509.jsm b/security/manager/ssl/X509.jsm new file mode 100644 index 000000000000..be107454e115 --- /dev/null +++ b/security/manager/ssl/X509.jsm @@ -0,0 +1,632 @@ +/* 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/. */ + +"use strict"; + +const Cu = Components.utils; +var { DER } = Cu.import("resource://gre/modules/psm/DER.jsm", {}); + +const ERROR_UNSUPPORTED_ASN1 = "unsupported asn.1"; +const ERROR_TIME_NOT_VALID = "Time not valid"; +const ERROR_LIBRARY_FAILURE = "library failure"; + +const X509v3 = 2; + +/** + * Helper function to read a NULL tag from the given DER. + * @param {DER} der a DER object to read a NULL from + * @return {NULL} an object representing an ASN.1 NULL + */ +function readNULL(der) { + return new NULL(der.readTagAndGetContents(DER.NULL)); +} + +/** + * Class representing an ASN.1 NULL. When encoded as DER, the only valid value + * is 05 00, and thus the contents should always be an empty array. + */ +class NULL { + /** + * @param {Number[]} bytes the contents of the NULL tag (should be empty) + */ + constructor(bytes) { + // Lint TODO: bytes should be an empty array + this._contents = bytes; + } +} + +/** + * Helper function to read an OBJECT IDENTIFIER from the given DER. + * @param {DER} der the DER to read an OBJECT IDENTIFIER from + * @return {OID} the value of the OBJECT IDENTIFIER + */ +function readOID(der) { + return new OID(der.readTagAndGetContents(DER.OBJECT_IDENTIFIER)); +} + +/** Class representing an ASN.1 OBJECT IDENTIFIER */ +class OID { + /** + * @param {Number[]} bytes the encoded contents of the OBJECT IDENTIFIER + * (not including the ASN.1 tag or length bytes) + */ + constructor(bytes) { + this._values = []; + // First octet has value 40 * value1 + value2 + // Lint TODO: validate that value1 is one of {0, 1, 2} + // Lint TODO: validate that value2 is in [0, 39] if value1 is 0 or 1 + let value1 = Math.floor(bytes[0] / 40); + let value2 = bytes[0] - 40 * value1; + this._values.push(value1); + this._values.push(value2); + bytes.shift(); + let accumulator = 0; + // Lint TODO: prevent overflow here + while (bytes.length > 0) { + let value = bytes.shift(); + accumulator *= 128; + if (value > 128) { + accumulator += (value - 128); + } else { + accumulator += value; + this._values.push(accumulator); + accumulator = 0; + } + } + } +} + +/** + * Class that serves as an abstract base class for more specific classes that + * represent datatypes from RFC 5280 and others. Given an array of bytes + * representing the DER encoding of such types, this framework simplifies the + * process of making a new DER object, attempting to parse the given bytes, and + * catching and stashing thrown exceptions. Subclasses are to implement + * parseOverride, which should read from this._der to fill out the structure's + * values. + */ +class DecodedDER { + constructor() { + this._der = null; + this._error = null; + } + + /** + * Returns the first exception encountered when decoding or null if none has + * been encountered. + * @return {Error} the first exception encountered when decoding or null + */ + get error() { + return this._error; + } + + /** + * Does the actual work of parsing the data. To be overridden by subclasses. + * If an implementation of parseOverride throws an exception, parse will catch + * that exception and stash it in the error property. This enables parent + * levels in a nested decoding hierarchy to continue to decode as much as + * possible. + */ + parseOverride() { + throw new Error(ERROR_LIBRARY_FAILURE); + } + + /** + * Public interface to be called to parse all data. Calls parseOverride inside + * a try/catch block. If an exception is thrown, stashes the error, which can + * be obtained via the error getter (above). + * @param {Number[]} bytes encoded DER to be decoded + */ + parse(bytes) { + this._der = new DER.DER(bytes); + try { + this.parseOverride(); + } catch (e) { + this._error = e; + } + } +} + +/** + * Helper function for reading the next SEQUENCE out of a DER and creating a new + * DER out of the resulting bytes. + * @param {DER} der the underlying DER object + * @return {DER} the contents of the SEQUENCE + */ +function readSEQUENCEAndMakeDER(der) { + return new DER.DER(der.readTagAndGetContents(DER.SEQUENCE)); +} + +/** + * Helper function for reading the next item identified by tag out of a DER and + * creating a new DER out of the resulting bytes. + * @param {DER} der the underlying DER object + * @param {Number} tag the expected next tag in the DER + * @return {DER} the contents of the tag + */ +function readTagAndMakeDER(der, tag) { + return new DER.DER(der.readTagAndGetContents(tag)); +} + +// Certificate ::= SEQUENCE { +// tbsCertificate TBSCertificate, +// signatureAlgorithm AlgorithmIdentifier, +// signatureValue BIT STRING } +class Certificate extends DecodedDER { + constructor() { + super(); + this._tbsCertificate = new TBSCertificate(); + this._signatureAlgorithm = new AlgorithmIdentifier(); + this._signatureValue = []; + } + + get tbsCertificate() { + return this._tbsCertificate; + } + + get signatureAlgorithm() { + return this._signatureAlgorithm; + } + + get signatureValue() { + return this._signatureValue; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._tbsCertificate.parse(contents.readTLV()); + this._signatureAlgorithm.parse(contents.readTLV()); + + let signatureValue = contents.readBIT_STRING(); + if (signatureValue.unusedBits != 0) { + throw new Error(ERROR_UNSUPPORTED_ASN1); + } + this._signatureValue = signatureValue.contents; + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// TBSCertificate ::= SEQUENCE { +// version [0] EXPLICIT Version DEFAULT v1, +// serialNumber CertificateSerialNumber, +// signature AlgorithmIdentifier, +// issuer Name, +// validity Validity, +// subject Name, +// subjectPublicKeyInfo SubjectPublicKeyInfo, +// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// extensions [3] EXPLICIT Extensions OPTIONAL +// -- If present, version MUST be v3 +// } +class TBSCertificate extends DecodedDER { + constructor() { + super(); + this._version = null; + this._serialNumber = []; + this._signature = new AlgorithmIdentifier(); + this._issuer = new Name(); + this._validity = new Validity(); + this._subject = new Name(); + this._subjectPublicKeyInfo = new SubjectPublicKeyInfo(); + this._extensions = []; + } + + get version() { + return this._version; + } + + get serialNumber() { + return this._serialNumber; + } + + get signature() { + return this._signature; + } + + get issuer() { + return this._issuer; + } + + get validity() { + return this._validity; + } + + get subject() { + return this._subject; + } + + get subjectPublicKeyInfo() { + return this._subjectPublicKeyInfo; + } + + get extensions() { + return this._extensions; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + + let versionTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 0; + if (!contents.peekTag(versionTag)) { + this._version = 1; + } else { + let versionContents = readTagAndMakeDER(contents, versionTag); + let versionBytes = versionContents.readTagAndGetContents(DER.INTEGER); + if (versionBytes.length == 1 && versionBytes[0] == X509v3) { + this._version = 3; + } else { + // Lint TODO: warn about non-v3 certificates (this INTEGER could take up + // multiple bytes, be negative, and so on). + this._version = versionBytes; + } + versionContents.assertAtEnd(); + } + + let serialNumberBytes = contents.readTagAndGetContents(DER.INTEGER); + this._serialNumber = serialNumberBytes; + this._signature.parse(contents.readTLV()); + this._issuer.parse(contents.readTLV()); + this._validity.parse(contents.readTLV()); + this._subject.parse(contents.readTLV()); + this._subjectPublicKeyInfo.parse(contents.readTLV()); + + // Lint TODO: warn about unsupported features + let issuerUniqueIDTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 1; + if (contents.peekTag(issuerUniqueIDTag)) { + contents.readTagAndGetContents(issuerUniqueIDTag); + } + let subjectUniqueIDTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 2; + if (contents.peekTag(subjectUniqueIDTag)) { + contents.readTagAndGetContents(subjectUniqueIDTag); + } + + let extensionsTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 3; + if (contents.peekTag(extensionsTag)) { + let extensionsSequence = readTagAndMakeDER(contents, extensionsTag); + let extensionsContents = readSEQUENCEAndMakeDER(extensionsSequence); + while (!extensionsContents.atEnd()) { + // TODO: parse extensions + this._extensions.push(extensionsContents.readTLV()); + } + extensionsContents.assertAtEnd(); + extensionsSequence.assertAtEnd(); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// AlgorithmIdentifier ::= SEQUENCE { +// algorithm OBJECT IDENTIFIER, +// parameters ANY DEFINED BY algorithm OPTIONAL } +class AlgorithmIdentifier extends DecodedDER { + constructor() { + super(); + this._algorithm = null; + this._parameters = null; + } + + get algorithm() { + return this._algorithm; + } + + get parameters() { + return this._parameters; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._algorithm = readOID(contents); + if (!contents.atEnd()) { + if (contents.peekTag(DER.NULL)) { + this._parameters = readNULL(contents); + } else if (contents.peekTag(DER.OBJECT_IDENTIFIER)) { + this._parameters = readOID(contents); + } + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// Name ::= CHOICE { -- only one possibility for now -- +// rdnSequence RDNSequence } +// +// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName +class Name extends DecodedDER { + constructor() { + super(); + this._rdns = []; + } + + get rdns() { + return this._rdns; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + while (!contents.atEnd()) { + let rdn = new RelativeDistinguishedName(); + rdn.parse(contents.readTLV()); + this._rdns.push(rdn); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// RelativeDistinguishedName ::= +// SET SIZE (1..MAX) OF AttributeTypeAndValue +class RelativeDistinguishedName extends DecodedDER { + constructor() { + super(); + this._avas = []; + } + + get avas() { + return this._avas; + } + + parseOverride() { + let contents = readTagAndMakeDER(this._der, DER.SET); + // Lint TODO: enforce SET SIZE restrictions + while (!contents.atEnd()) { + let ava = new AttributeTypeAndValue(); + ava.parse(contents.readTLV()); + this._avas.push(ava); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// AttributeTypeAndValue ::= SEQUENCE { +// type AttributeType, +// value AttributeValue } +// +// AttributeType ::= OBJECT IDENTIFIER +// +// AttributeValue ::= ANY -- DEFINED BY AttributeType +class AttributeTypeAndValue extends DecodedDER { + constructor() { + super(); + this._type = null; + this._value = new DirectoryString(); + } + + get type() { + return this._type; + } + + get value() { + return this._value; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._type = readOID(contents); + // We don't support universalString or bmpString. + // IA5String is supported because it is valid if `type == id-emailaddress`. + // Lint TODO: validate that the type of string is valid given `type`. + this._value.parse(contents.readTLVChoice([ DER.UTF8String, + DER.PrintableString, + DER.TeletexString, + DER.IA5String ])); + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// DirectoryString ::= CHOICE { +// teletexString TeletexString (SIZE (1..MAX)), +// printableString PrintableString (SIZE (1..MAX)), +// universalString UniversalString (SIZE (1..MAX)), +// utf8String UTF8String (SIZE (1..MAX)), +// bmpString BMPString (SIZE (1..MAX)) } +class DirectoryString extends DecodedDER { + constructor() { + super(); + this._type = null; + this._value = null; + } + + get type() { + return this._type; + } + + get value() { + return this._value; + } + + parseOverride() { + if (this._der.peekTag(DER.UTF8String)) { + this._type = DER.UTF8String; + } else if (this._der.peekTag(DER.PrintableString)) { + this._type = DER.PrintableString; + } else if (this._der.peekTag(DER.TeletexString)) { + this._type = DER.TeletexString; + } else if (this._der.peekTag(DER.IA5String)) { + this._type = DER.IA5String; + } + // Lint TODO: validate that the contents are actually valid for the type + this._value = this._der.readTagAndGetContents(this._type); + this._der.assertAtEnd(); + } +} + +// Time ::= CHOICE { +// utcTime UTCTime, +// generalTime GeneralizedTime } +class Time extends DecodedDER { + constructor() { + super(); + this._type = null; + this._time = null; + } + + get time() { + return this._time; + } + + parseOverride() { + if (this._der.peekTag(DER.UTCTime)) { + this._type = DER.UTCTime; + } else if (this._der.peekTag(DER.GeneralizedTime)) { + this._type = DER.GeneralizedTime; + } + let contents = readTagAndMakeDER(this._der, this._type); + let year; + // Lint TODO: validate that the appropriate one of {UTCTime,GeneralizedTime} + // is used according to RFC 5280 and what the value of the date is. + // TODO TODO: explain this better (just quote the rfc). + if (this._type == DER.UTCTime) { + // UTCTime is YYMMDDHHMMSSZ in RFC 5280. If YY is greater than or equal + // to 50, the year is 19YY. Otherwise, it is 20YY. + let y1 = this._validateDigit(contents.readByte()); + let y2 = this._validateDigit(contents.readByte()); + let yy = y1 * 10 + y2; + if (yy >= 50) { + year = 1900 + yy; + } else { + year = 2000 + yy; + } + } else { + // GeneralizedTime is YYYYMMDDHHMMSSZ in RFC 5280. + year = 0; + for (let i = 0; i < 4; i++) { + let y = this._validateDigit(contents.readByte()); + year = year * 10 + y; + } + } + + let m1 = this._validateDigit(contents.readByte()); + let m2 = this._validateDigit(contents.readByte()); + let month = m1 * 10 + m2; + if (month == 0 || month > 12) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let d1 = this._validateDigit(contents.readByte()); + let d2 = this._validateDigit(contents.readByte()); + let day = d1 * 10 + d2; + if (day == 0 || day > 31) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let h1 = this._validateDigit(contents.readByte()); + let h2 = this._validateDigit(contents.readByte()); + let hour = h1 * 10 + h2; + if (hour > 23) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let min1 = this._validateDigit(contents.readByte()); + let min2 = this._validateDigit(contents.readByte()); + let minute = min1 * 10 + min2; + if (minute > 59) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let s1 = this._validateDigit(contents.readByte()); + let s2 = this._validateDigit(contents.readByte()); + let second = s1 * 10 + s2; + if (second > 60) { // leap-seconds mean this can be as much as 60 + throw new Error(ERROR_TIME_NOT_VALID); + } + + let z = contents.readByte(); + if (z != "Z".charCodeAt(0)) { + throw new Error(ERROR_TIME_NOT_VALID); + } + // Lint TODO: verify that the Time doesn't specify a nonsensical + // month/day/etc. + // months are zero-indexed in JS + this._time = new Date(Date.UTC(year, month - 1, day, hour, minute, + second)); + + contents.assertAtEnd(); + this._der.assertAtEnd(); + } + + /** + * Takes a byte that is supposed to be in the ASCII range for "0" to "9". + * Validates the range and then converts it to the range 0 to 9. + * @param {Number} the digit in question (as ASCII in the range ["0", "9"]) + * @return {Number} the numerical value of the digit (in the range [0, 9]) + */ + _validateDigit(d) { + if (d < "0".charCodeAt(0) || d > "9".charCodeAt(0)) { + throw new Error(ERROR_TIME_NOT_VALID); + } + return d - "0".charCodeAt(0); + } +} + +// Validity ::= SEQUENCE { +// notBefore Time, +// notAfter Time } +class Validity extends DecodedDER { + constructor() { + super(); + this._notBefore = new Time(); + this._notAfter = new Time(); + } + + get notBefore() { + return this._notBefore; + } + + get notAfter() { + return this._notAfter; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._notBefore.parse(contents.readTLVChoice( + [DER.UTCTime, DER.GeneralizedTime])); + this._notAfter.parse(contents.readTLVChoice( + [DER.UTCTime, DER.GeneralizedTime])); + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// SubjectPublicKeyInfo ::= SEQUENCE { +// algorithm AlgorithmIdentifier, +// subjectPublicKey BIT STRING } +class SubjectPublicKeyInfo extends DecodedDER { + constructor() { + super(); + this._algorithm = new AlgorithmIdentifier(); + this._subjectPublicKey = null; + } + + get algorithm() { + return this._algorithm; + } + + get subjectPublicKey() { + return this._subjectPublicKey; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._algorithm.parse(contents.readTLV()); + let subjectPublicKeyBitString = contents.readBIT_STRING(); + if (subjectPublicKeyBitString.unusedBits != 0) { + throw new Error(ERROR_UNSUPPORTED_ASN1); + } + this._subjectPublicKey = subjectPublicKeyBitString.contents; + + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +this.X509 = { Certificate }; +this.EXPORTED_SYMBOLS = ["X509"]; diff --git a/security/manager/ssl/moz.build b/security/manager/ssl/moz.build index bf88ef5d59e8..19e1b4f4b141 100644 --- a/security/manager/ssl/moz.build +++ b/security/manager/ssl/moz.build @@ -55,6 +55,7 @@ XPIDL_MODULE = 'pipnss' EXTRA_JS_MODULES.psm += [ 'DER.jsm', + 'X509.jsm', ] EXPORTS += [ diff --git a/security/manager/ssl/tests/unit/test_x509.js b/security/manager/ssl/tests/unit/test_x509.js new file mode 100644 index 000000000000..a7ece856a1c1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_x509.js @@ -0,0 +1,83 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests X509.jsm functionality. + +var { X509 } = Cu.import("resource://gre/modules/psm/X509.jsm", {}); + +function stringToBytes(s) { + let b = []; + for (let i = 0; i < s.length; i++) { + b.push(s.charCodeAt(i)); + } + return b; +} + +function readPEMToBytes(filename) { + return stringToBytes(atob(pemToBase64(readFile(do_get_file(filename))))); +} + +function run_test() { + let certificate = new X509.Certificate(); + certificate.parse(readPEMToBytes("bad_certs/default-ee.pem")); + + equal(certificate.tbsCertificate.version, 3, + "default-ee.pem should be x509v3"); + + // serialNumber + deepEqual(certificate.tbsCertificate.serialNumber, + [ 0x1b, 0x27, 0x62, 0x4d, 0xc3, 0x70, 0xbf, 0x3d, 0xb6, 0x66, + 0x98, 0x33, 0xd8, 0x3c, 0x74, 0xd9, 0xee, 0x2c, 0x56, 0xc1 ], + "default-ee.pem should have expected serialNumber"); + + deepEqual(certificate.tbsCertificate.signature.algorithm._values, + [ 1, 2, 840, 113549, 1, 1, 11 ], // sha256WithRSAEncryption + "default-ee.pem should have sha256WithRSAEncryption signature"); + // TODO: there should actually be an explicit encoded NULL here, but it looks + // like pycert doesn't include it. + deepEqual(certificate.tbsCertificate.signature.parameters, null, + "default-ee.pem should have NULL parameters for signature"); + + equal(certificate.tbsCertificate.issuer.rdns.length, 1, + "default-ee.pem should have one RDN in issuer"); + equal(certificate.tbsCertificate.issuer.rdns[0].avas.length, 1, + "default-ee.pem should have one AVA in RDN in issuer"); + deepEqual(certificate.tbsCertificate.issuer.rdns[0].avas[0].value.value, + stringToBytes("Test CA"), + "default-ee.pem should have issuer 'Test CA'"); + + equal(certificate.tbsCertificate.validity.notBefore.time.getTime(), + Date.parse("2014-11-27T00:00:00.000Z"), + "default-ee.pem should have the correct value for notBefore"); + equal(certificate.tbsCertificate.validity.notAfter.time.getTime(), + Date.parse("2017-02-04T00:00:00.000Z"), + "default-ee.pem should have the correct value for notAfter"); + + equal(certificate.tbsCertificate.subject.rdns.length, 1, + "default-ee.pem should have one RDN in subject"); + equal(certificate.tbsCertificate.subject.rdns[0].avas.length, 1, + "default-ee.pem should have one AVA in RDN in subject"); + deepEqual(certificate.tbsCertificate.subject.rdns[0].avas[0].value.value, + stringToBytes("Test End-entity"), + "default-ee.pem should have subject 'Test End-entity'"); + + deepEqual(certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm._values, + [ 1, 2, 840, 113549, 1, 1, 1 ], // rsaEncryption + "default-ee.pem should have a spki algorithm of rsaEncryption"); + + equal(certificate.tbsCertificate.extensions.length, 2, + "default-ee.pem should have two extensions"); + + deepEqual(certificate.signatureAlgorithm.algorithm._values, + [ 1, 2, 840, 113549, 1, 1, 11 ], // sha256WithRSAEncryption + "default-ee.pem should have sha256WithRSAEncryption signatureAlgorithm"); + // TODO: there should actually be an explicit encoded NULL here, but it looks + // like pycert doesn't include it. + deepEqual(certificate.signatureAlgorithm.parameters, null, + "default-ee.pem should have NULL parameters for signatureAlgorithm"); + + equal(certificate.signatureValue.length, 2048 / 8, + "length of signature on default-ee.pem should be 2048 bits"); +} diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini index 6ed01a50cf66..ad3da3d264de 100644 --- a/security/manager/ssl/tests/unit/xpcshell.ini +++ b/security/manager/ssl/tests/unit/xpcshell.ini @@ -151,6 +151,7 @@ skip-if = toolkit == 'android' || toolkit == 'gonk' [test_sts_preloadlist_selfdestruct.js] [test_validity.js] run-sequentially = hardcoded ports +[test_x509.js] # The TLS error reporting functionality lives in /toolkit but needs tlsserver [test_toolkit_securityreporter.js] From a6bda7e13ac45a6c1e48027830b46c505135b42e Mon Sep 17 00:00:00 2001 From: "Nils Ohlmeier [:drno]" Date: Mon, 3 Oct 2016 16:31:13 -0700 Subject: [PATCH 05/37] Bug 1307300: s/endOfTrickelSdp/endOfTrickleSdp. r=mjf MozReview-Commit-ID: 9a0U0JHWFSD --HG-- extra : rebase_source : ff79b155961c878a22a6d00f8e317eb28bc4d34b --- dom/media/tests/mochitest/templates.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/tests/mochitest/templates.js b/dom/media/tests/mochitest/templates.js index 1beaf1117a68..3a8e0dd4963a 100644 --- a/dom/media/tests/mochitest/templates.js +++ b/dom/media/tests/mochitest/templates.js @@ -476,7 +476,7 @@ var commandsPeerConnectionOfferAnswer = [ } }, function PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) { - if (test.pcRemote.endOfTrickelSdp) { + if (test.pcRemote.endOfTrickleSdp) { /* In case the endOfTrickleSdp promise is resolved already it will win the * race because it gets evaluated first. But if endOfTrickleSdp is still * pending the rejection will win the race. */ From c0e826b751ed760cd883dc75a8e785ec6079ec49 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Mon, 3 Oct 2016 01:48:46 -0700 Subject: [PATCH 06/37] Bug 1024734 - Wait correctly for project import in test_import.html. r=jryans MozReview-Commit-ID: 5YWIITCzbic --HG-- extra : rebase_source : c31c1d39b6b5aaf01b5cc44e27742a794cd6a36a --- devtools/client/webide/test/test_import.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/devtools/client/webide/test/test_import.html b/devtools/client/webide/test/test_import.html index df202bd99360..830198ccab7d 100644 --- a/devtools/client/webide/test/test_import.html +++ b/devtools/client/webide/test/test_import.html @@ -29,8 +29,11 @@ info("to call importPackagedApp(" + packagedAppLocation + ")"); ok(!win.UI._busyPromise, "UI is not busy"); + let onValidated = waitForUpdate(win, "project-validated"); + let onDetails = waitForUpdate(win, "details"); yield winProject.projectList.importPackagedApp(packagedAppLocation); - yield waitForUpdate(win, "project-validated"); + yield onValidated; + yield onDetails; let project = win.AppManager.selectedProject; is(project.location, packagedAppLocation, "Location is valid"); From bf4bb1107af5435e4f34742e687a6494618bb7fa Mon Sep 17 00:00:00 2001 From: Eric Rahm Date: Tue, 4 Oct 2016 14:28:48 -0700 Subject: [PATCH 07/37] Bug 1280726 - Just wait for cleared in browser_bug664688_sandbox_update_after_navigation. r=bgrins MozReview-Commit-ID: 40vc67B2Jr0 --HG-- extra : rebase_source : 4bfb29935221f079cf48898f88885499c0dc84c9 --- .../browser_bug664688_sandbox_update_after_navigation.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/devtools/client/webconsole/test/browser_bug664688_sandbox_update_after_navigation.js b/devtools/client/webconsole/test/browser_bug664688_sandbox_update_after_navigation.js index fca17acf9df0..1aacb61c14b4 100644 --- a/devtools/client/webconsole/test/browser_bug664688_sandbox_update_after_navigation.js +++ b/devtools/client/webconsole/test/browser_bug664688_sandbox_update_after_navigation.js @@ -79,14 +79,6 @@ add_task(function* () { gBrowser.goBack(); - info("Waiting for page to navigate"); - yield waitForSuccess({ - name: "go back", - validator: function () { - return content.location.href == TEST_URI1; - }, - }); - info("Waiting for messages to be cleared due to navigation"); yield cleared; From a12afd68fadc542407cc8f628ffa33cf524fb751 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 4 Oct 2016 14:57:00 +0900 Subject: [PATCH 08/37] Bug 1297471 - Move --enable-ctypes to js/moz.configure. r=chmanchester --HG-- rename : build/moz.configure/ffi.configure => js/ffi.configure extra : rebase_source : 99a3956456fb4c39c1f1ad9b7d0f7aaf2c7529ca --- {build/moz.configure => js}/ffi.configure | 0 js/moz.configure | 31 +++++++++++++++++++++++ moz.configure | 29 --------------------- 3 files changed, 31 insertions(+), 29 deletions(-) rename {build/moz.configure => js}/ffi.configure (100%) diff --git a/build/moz.configure/ffi.configure b/js/ffi.configure similarity index 100% rename from build/moz.configure/ffi.configure rename to js/ffi.configure diff --git a/js/moz.configure b/js/moz.configure index 77838bd97f86..64271ea464ef 100644 --- a/js/moz.configure +++ b/js/moz.configure @@ -205,3 +205,34 @@ def more_deterministic(value): return True set_define('JS_MORE_DETERMINISTIC', more_deterministic) + + +# CTypes +# ======================================================= +@depends(building_js, '--help') +def ctypes_default(building_js, _): + return not building_js + +js_option('--enable-ctypes', help='Enable js-ctypes', + default=ctypes_default) + +build_ctypes = depends_if('--enable-ctypes')(lambda _: True) + +set_config('BUILD_CTYPES', build_ctypes) +set_define('BUILD_CTYPES', build_ctypes) +add_old_configure_assignment('BUILD_CTYPES', build_ctypes) + +@depends(build_ctypes, building_js) +def js_has_ctypes(ctypes, js): + if ctypes and js: + return True + +set_config('JS_HAS_CTYPES', js_has_ctypes) +set_define('JS_HAS_CTYPES', js_has_ctypes) +add_old_configure_assignment('JS_HAS_CTYPES', js_has_ctypes) + +@depends('--enable-ctypes', '--enable-compile-environment', '--help') +def ctypes_and_compile_environment(ctypes, compile_environment, _): + return ctypes and compile_environment + +include_when('ffi.configure', when=ctypes_and_compile_environment) diff --git a/moz.configure b/moz.configure index 79e6927d6d71..ac91626ea5df 100644 --- a/moz.configure +++ b/moz.configure @@ -104,35 +104,6 @@ include_when('build/moz.configure/warnings.configure', include(include_project_configure) -@depends(building_js, '--help') -def ctypes_default(building_js, _): - return not building_js - -js_option('--enable-ctypes', help='Enable js-ctypes', - default=ctypes_default) - -build_ctypes = depends_if('--enable-ctypes')(lambda _: True) - -set_config('BUILD_CTYPES', build_ctypes) -set_define('BUILD_CTYPES', build_ctypes) -add_old_configure_assignment('BUILD_CTYPES', build_ctypes) - -@depends(build_ctypes, building_js) -def js_has_ctypes(ctypes, js): - if ctypes and js: - return True - -set_config('JS_HAS_CTYPES', js_has_ctypes) -set_define('JS_HAS_CTYPES', js_has_ctypes) -add_old_configure_assignment('JS_HAS_CTYPES', js_has_ctypes) - -@depends('--enable-ctypes', '--enable-compile-environment', '--help') -def ctypes_and_compile_environment(ctypes, compile_environment, _): - return ctypes and compile_environment - -include_when('build/moz.configure/ffi.configure', - when=ctypes_and_compile_environment) - @dependable @imports(_from='mozbuild.backend', _import='backends') def build_backends_choices(): From 09e520c6742bb5fe74aba585ac7121c16a9336f3 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 4 Oct 2016 15:33:37 +0900 Subject: [PATCH 09/37] Bug 1307355 - Add an implicit dependency on --enable-compile-environment to pkg_check_modules. r=chmanchester --HG-- extra : rebase_source : bd16320895f54d42c8207722a4a4c366d1332170 --- build/moz.configure/init.configure | 5 --- build/moz.configure/pkg.configure | 16 +++++-- moz.configure | 5 +++ .../test/configure/test_checks_configure.py | 43 +++++++++++-------- 4 files changed, 44 insertions(+), 25 deletions(-) diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure index 4f42fdc134f1..99bd5e75dd9e 100644 --- a/build/moz.configure/init.configure +++ b/build/moz.configure/init.configure @@ -803,11 +803,6 @@ def js_option(*args, **kwargs): add_old_configure_arg(js_option) -include('pkg.configure') -# Make this assignment here rather than in pkg.configure to avoid -# requiring this file in unit tests. -add_old_configure_assignment('PKG_CONFIG', pkg_config) - # Bug 1278542: This function is a workaround to resolve # |android_ndk_include|'s dependency on 'gonkdir.' The # actual implementation is located in b2g/moz.configure. diff --git a/build/moz.configure/pkg.configure b/build/moz.configure/pkg.configure index b9332ace5513..44e1f934ae13 100644 --- a/build/moz.configure/pkg.configure +++ b/build/moz.configure/pkg.configure @@ -4,7 +4,12 @@ # 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/. -pkg_config = check_prog('PKG_CONFIG', ('pkg-config',), allow_missing=True) +@depends('--enable-compile-environment') +def pkg_config(compile_env): + if compile_env: + return ('pkg-config',) + +pkg_config = check_prog('PKG_CONFIG', pkg_config, allow_missing=True) @depends_if(pkg_config) @checking('for pkg-config version') @@ -31,7 +36,12 @@ def pkg_check_modules(var, package_desc, when=always, package_desc = ' '.join(package_desc) package_desc = dependable(package_desc) - @depends_when(pkg_config, pkg_config_version, when=when) + @depends(when, '--enable-compile-environment') + def when_and_compile_environment(when, compile_environment): + return when and compile_environment + + @depends_when(pkg_config, pkg_config_version, + when=when_and_compile_environment) def check_pkg_config(pkg_config, version): min_version = '0.9.0' if pkg_config is None: @@ -42,7 +52,7 @@ def pkg_check_modules(var, package_desc, when=always, die("*** Your version of pkg-config is too old. You need version %s or newer.", min_version) - @depends_when(pkg_config, package_desc, when=when) + @depends_when(pkg_config, package_desc, when=when_and_compile_environment) @imports('subprocess') @imports('sys') @imports(_from='mozbuild.configure.util', _import='LineIO') diff --git a/moz.configure b/moz.configure index ac91626ea5df..591e90d2a46a 100644 --- a/moz.configure +++ b/moz.configure @@ -93,6 +93,11 @@ js_option('--enable-debug', add_old_configure_assignment('MOZ_DEBUG', depends('--enable-debug')(lambda v: bool(v))) +include('build/moz.configure/pkg.configure') +# Make this assignment here rather than in pkg.configure to avoid +# requiring this file in unit tests. +add_old_configure_assignment('PKG_CONFIG', pkg_config) + include_when('build/moz.configure/toolchain.configure', when='--enable-compile-environment') include_when('build/moz.configure/memory.configure', diff --git a/python/mozbuild/mozbuild/test/configure/test_checks_configure.py b/python/mozbuild/mozbuild/test/configure/test_checks_configure.py index ae9422b3fe1d..696bf56f6221 100644 --- a/python/mozbuild/mozbuild/test/configure/test_checks_configure.py +++ b/python/mozbuild/mozbuild/test/configure/test_checks_configure.py @@ -701,13 +701,21 @@ class TestChecksConfigure(unittest.TestCase): return 0, mock_pkg_config_version, '' self.fail("Unexpected arguments to mock_pkg_config: %s" % args) + def get_result(cmd, args=[], extra_paths=None): + return self.get_result(textwrap.dedent('''\ + option('--disable-compile-environment', help='compile env') + include('%(topsrcdir)s/build/moz.configure/util.configure') + include('%(topsrcdir)s/build/moz.configure/checks.configure') + include('%(topsrcdir)s/build/moz.configure/pkg.configure') + ''' % {'topsrcdir': topsrcdir}) + cmd, args=args, extra_paths=extra_paths, + includes=()) + extra_paths = { mock_pkg_config_path: mock_pkg_config, } includes = ('util.configure', 'checks.configure', 'pkg.configure') - config, output, status = self.get_result("pkg_check_modules('MOZ_VALID', 'valid')", - includes=includes) + config, output, status = get_result("pkg_check_modules('MOZ_VALID', 'valid')") self.assertEqual(status, 1) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... not found @@ -717,9 +725,8 @@ class TestChecksConfigure(unittest.TestCase): ''')) - config, output, status = self.get_result("pkg_check_modules('MOZ_VALID', 'valid')", - extra_paths=extra_paths, - includes=includes) + config, output, status = get_result("pkg_check_modules('MOZ_VALID', 'valid')", + extra_paths=extra_paths) self.assertEqual(status, 0) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... %s @@ -734,9 +741,8 @@ class TestChecksConfigure(unittest.TestCase): 'MOZ_VALID_LIBS': ('-lvalid',), }) - config, output, status = self.get_result("pkg_check_modules('MOZ_UKNOWN', 'unknown')", - extra_paths=extra_paths, - includes=includes) + config, output, status = get_result("pkg_check_modules('MOZ_UKNOWN', 'unknown')", + extra_paths=extra_paths) self.assertEqual(status, 1) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... %s @@ -751,9 +757,8 @@ class TestChecksConfigure(unittest.TestCase): 'PKG_CONFIG': mock_pkg_config_path, }) - config, output, status = self.get_result("pkg_check_modules('MOZ_NEW', 'new > 1.1')", - extra_paths=extra_paths, - includes=includes) + config, output, status = get_result("pkg_check_modules('MOZ_NEW', 'new > 1.1')", + extra_paths=extra_paths) self.assertEqual(status, 1) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... %s @@ -774,9 +779,7 @@ class TestChecksConfigure(unittest.TestCase): log.info('Module not found.') ''') - config, output, status = self.get_result(cmd, - extra_paths=extra_paths, - includes=includes) + config, output, status = get_result(cmd, extra_paths=extra_paths) self.assertEqual(status, 0) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... %s @@ -789,6 +792,13 @@ class TestChecksConfigure(unittest.TestCase): 'PKG_CONFIG': mock_pkg_config_path, }) + config, output, status = get_result(cmd, + args=['--disable-compile-environment'], + extra_paths=extra_paths) + self.assertEqual(status, 0) + self.assertEqual(output, 'Module not found.\n') + self.assertEqual(config, {}) + def mock_old_pkg_config(_, args): if args[0] == '--version': return 0, '0.8.10', '' @@ -798,9 +808,8 @@ class TestChecksConfigure(unittest.TestCase): mock_pkg_config_path: mock_old_pkg_config, } - config, output, status = self.get_result("pkg_check_modules('MOZ_VALID', 'valid')", - extra_paths=extra_paths, - includes=includes) + config, output, status = get_result("pkg_check_modules('MOZ_VALID', 'valid')", + extra_paths=extra_paths) self.assertEqual(status, 1) self.assertEqual(output, textwrap.dedent('''\ checking for pkg_config... %s From cf9b7daba78d3937a7819640f0eeac1a12d7affa Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 19 Jul 2016 14:54:37 +0900 Subject: [PATCH 10/37] Bug 1287671 - Simplify jscpucfg.h. r=njn Endianness is figured out in mfbt/EndianUtils.h, which can be reused. Apart from endianness, jscpucfg.h is defining JS_HAVE_LONG_LONG, which isn't used anywhere, defines a macro for the Watcom C/C++ compiler, and tries to figure out stack growth direction. The first is obviously unnecessary. The second is not useful now that building JS requires a C++11-capable compiler, which the Watcom C/C++ compiler isn't. The latter, however, is still relevant, but the check based on sys/isa_def.h is, afaict, only relevant on HP-UX on PA-RISC, which is already covered by the check for __hppa. Consequently, the various checks setting JS_HAVE_header_H defines can all be removed. --HG-- extra : rebase_source : 6ceb4f4b8059271b411b919977d507f41f0497f0 --- js/src/js-config.h.in | 12 ----- js/src/jscpucfg.h | 112 ++-------------------------------------- js/src/old-configure.in | 15 ------ 3 files changed, 5 insertions(+), 134 deletions(-) diff --git a/js/src/js-config.h.in b/js/src/js-config.h.in index f86b2d800c01..f2ce93e12212 100644 --- a/js/src/js-config.h.in +++ b/js/src/js-config.h.in @@ -48,18 +48,6 @@ /* Define to 1 to perform extra assertions and heap poisoning. */ #undef JS_CRASH_DIAGNOSTICS -/* Define to 1 if the header is present and - useable. See jscpucfg.h. */ -#undef JS_HAVE_ENDIAN_H - -/* Define to 1 if the header is present and - useable. See jscpucfg.h. */ -#undef JS_HAVE_MACHINE_ENDIAN_H - -/* Define to 1 if the header is present and - useable. See jscpucfg.h. */ -#undef JS_HAVE_SYS_ISA_DEFS_H - /* Define to 1 if SpiderMonkey is in NUNBOX32 mode. */ #undef JS_NUNBOX32 diff --git a/js/src/jscpucfg.h b/js/src/jscpucfg.h index a641e523ba99..660187ca60cf 100644 --- a/js/src/jscpucfg.h +++ b/js/src/jscpucfg.h @@ -7,117 +7,15 @@ #ifndef jscpucfg_h #define jscpucfg_h -#define JS_HAVE_LONG_LONG - -#if defined(_WIN64) - -# if defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_) -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# else /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */ -# error "CPU type is unknown" -# endif /* !(defined(_M_X64) || defined(_M_AMD64) || defined(_AMD64_)) */ - -#elif defined(_WIN32) - -# ifdef __WATCOMC__ -# define HAVE_VA_LIST_AS_ARRAY 1 -# endif +#include "mozilla/EndianUtils.h" +#if defined(MOZ_LITTLE_ENDIAN) # define IS_LITTLE_ENDIAN 1 # undef IS_BIG_ENDIAN - -#elif defined(__APPLE__) || defined(__powerpc__) || defined(__ppc__) -# if __LITTLE_ENDIAN__ -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# elif __BIG_ENDIAN__ -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -# endif - -#elif defined(JS_HAVE_ENDIAN_H) -# include - -/* - * Historically, OSes providing only defined - * __BYTE_ORDER to either __LITTLE_ENDIAN or __BIG_ENDIAN. - * The Austin group decided to standardise in - * POSIX around 2011, expecting it to provide a BYTE_ORDER - * #define set to either LITTLE_ENDIAN or BIG_ENDIAN. We - * should try to cope with both possibilities here. - */ - -# if defined(__BYTE_ORDER) || defined(BYTE_ORDER) -# if defined(__BYTE_ORDER) -# if __BYTE_ORDER == __LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# elif __BYTE_ORDER == __BIG_ENDIAN -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -# endif -# endif -# if defined(BYTE_ORDER) -# if BYTE_ORDER == LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# elif BYTE_ORDER == BIG_ENDIAN -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -# endif -# endif -# else /* !defined(__BYTE_ORDER) */ -# error "endian.h does not define __BYTE_ORDER nor BYTE_ORDER. Cannot determine endianness." -# endif - -/* BSDs */ -#elif defined(JS_HAVE_MACHINE_ENDIAN_H) -# include -# include - -# if defined(_BYTE_ORDER) -# if _BYTE_ORDER == _LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# elif _BYTE_ORDER == _BIG_ENDIAN -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -# endif -# else /* !defined(_BYTE_ORDER) */ -# error "machine/endian.h does not define _BYTE_ORDER. Cannot determine endianness." -# endif - -#elif defined(JS_HAVE_SYS_ISA_DEFS_H) -# include - -# if defined(_BIG_ENDIAN) -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -# elif defined(_LITTLE_ENDIAN) -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -# else /* !defined(_LITTLE_ENDIAN) */ -# error "sys/isa_defs.h does not define _BIG_ENDIAN or _LITTLE_ENDIAN. Cannot determine endianness." -# endif -# if !defined(JS_STACK_GROWTH_DIRECTION) -# if defined(_STACK_GROWS_UPWARD) -# define JS_STACK_GROWTH_DIRECTION (1) -# elif defined(_STACK_GROWS_DOWNWARD) -# define JS_STACK_GROWTH_DIRECTION (-1) -# endif -# endif - -#elif defined(__sparc) || defined(__sparc__) || \ - defined(_POWER) || defined(__hppa) || \ - defined(_MIPSEB) || defined(_BIG_ENDIAN) -/* IA64 running HP-UX will have _BIG_ENDIAN defined. - * IA64 running Linux will have endian.h and be handled above. - */ -# undef IS_LITTLE_ENDIAN +#elif defined(MOZ_BIG_ENDIAN) +# undef IS_LITTLE_ENDIAN # define IS_BIG_ENDIAN 1 - -#else /* !defined(__sparc) && !defined(__sparc__) && ... */ +#else # error "Cannot determine endianness of your platform. Please add support to jscpucfg.h." #endif diff --git a/js/src/old-configure.in b/js/src/old-configure.in index 8fb4c96f01e8..712a1cf858fb 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -999,21 +999,6 @@ else AC_MSG_RESULT(no) fi -MOZ_CHECK_HEADERS(endian.h) -if test "$ac_cv_header_endian_h" = yes; then - AC_DEFINE(JS_HAVE_ENDIAN_H) -fi - -MOZ_CHECK_HEADERS([machine/endian.h],[],[],[#include ]) -if test "$ac_cv_header_machine_endian_h" = yes; then - AC_DEFINE(JS_HAVE_MACHINE_ENDIAN_H) -fi - -MOZ_CHECK_HEADERS(sys/isa_defs.h) -if test "$ac_cv_header_sys_isa_defs_h" = yes; then - AC_DEFINE(JS_HAVE_SYS_ISA_DEFS_H) -fi - AC_LANG_CPLUSPLUS MOZ_CXX11 From 4b533dfa0bd2fc2f30eccf7496ab04cbc2b44d8c Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 4 Oct 2016 15:31:45 +0900 Subject: [PATCH 11/37] Bug 1287671 - Replace IS_{LITTLE|BIG}_ENDIAN with MOZ_{LITTLE|BIG}_ENDIAN in js/. r=njn --HG-- extra : rebase_source : 41bcac276e0c7d4049e6ce3b914f9105d3b85b55 --- js/public/Value.h | 6 +++--- js/src/jit/Lowering.cpp | 2 +- js/src/jit/MacroAssembler.h | 2 +- js/src/jsatom.cpp | 4 ++-- js/src/jscpucfg.h | 10 ---------- js/src/jsdtoa.cpp | 2 +- js/src/vm/TypedArrayObject.cpp | 2 +- 7 files changed, 9 insertions(+), 19 deletions(-) diff --git a/js/public/Value.h b/js/public/Value.h index 7d0b2abd6d65..cc4879110887 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -237,7 +237,7 @@ typedef enum JSWhyMagic JS_WHY_MAGIC_COUNT } JSWhyMagic; -#if defined(IS_LITTLE_ENDIAN) +#if MOZ_LITTLE_ENDIAN # if defined(JS_NUNBOX32) typedef union jsval_layout { @@ -285,7 +285,7 @@ typedef union jsval_layout uintptr_t asUIntPtr; } JSVAL_ALIGNMENT jsval_layout; # endif /* JS_PUNBOX64 */ -#else /* defined(IS_LITTLE_ENDIAN) */ +#else /* MOZ_LITTLE_ENDIAN */ # if defined(JS_NUNBOX32) typedef union jsval_layout { @@ -331,7 +331,7 @@ typedef union jsval_layout uintptr_t asUIntPtr; } JSVAL_ALIGNMENT jsval_layout; # endif /* JS_PUNBOX64 */ -#endif /* defined(IS_LITTLE_ENDIAN) */ +#endif /* MOZ_LITTLE_ENDIAN */ JS_STATIC_ASSERT(sizeof(jsval_layout) == 8); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 2f48af4fa294..9bc73ea31977 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -66,7 +66,7 @@ LIRGenerator::visitParameter(MParameter* param) offset *= sizeof(Value); #if defined(JS_NUNBOX32) -# if defined(IS_BIG_ENDIAN) +# if MOZ_BIG_ENDIAN ins->getDef(0)->setOutput(LArgument(offset)); ins->getDef(1)->setOutput(LArgument(offset + 4)); # else diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 0761332d629e..f8e61890d36d 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -179,7 +179,7 @@ using mozilla::FloatingPoint; # define PER_SHARED_ARCH DEFINED_ON(ALL_SHARED_ARCH) -#ifdef IS_LITTLE_ENDIAN +#if MOZ_LITTLE_ENDIAN #define IMM32_16ADJ(X) X << 16 #else #define IMM32_16ADJ(X) X diff --git a/js/src/jsatom.cpp b/js/src/jsatom.cpp index 9ef03ddf904b..895b7d03ecbe 100644 --- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -568,7 +568,7 @@ js::XDRAtom(XDRState* xdr, MutableHandleAtom atomp) const Latin1Char* chars = reinterpret_cast(xdr->buf.read(length)); atom = AtomizeChars(cx, chars, length); } else { -#if IS_LITTLE_ENDIAN +#if MOZ_LITTLE_ENDIAN /* Directly access the little endian chars in the XDR buffer. */ const char16_t* chars = reinterpret_cast(xdr->buf.read(length * sizeof(char16_t))); atom = AtomizeChars(cx, chars, length); @@ -596,7 +596,7 @@ js::XDRAtom(XDRState* xdr, MutableHandleAtom atomp) atom = AtomizeChars(cx, chars, length); if (chars != stackChars) js_free(chars); -#endif /* !IS_LITTLE_ENDIAN */ +#endif /* !MOZ_LITTLE_ENDIAN */ } if (!atom) diff --git a/js/src/jscpucfg.h b/js/src/jscpucfg.h index 660187ca60cf..80fdf6bb88b5 100644 --- a/js/src/jscpucfg.h +++ b/js/src/jscpucfg.h @@ -9,16 +9,6 @@ #include "mozilla/EndianUtils.h" -#if defined(MOZ_LITTLE_ENDIAN) -# define IS_LITTLE_ENDIAN 1 -# undef IS_BIG_ENDIAN -#elif defined(MOZ_BIG_ENDIAN) -# undef IS_LITTLE_ENDIAN -# define IS_BIG_ENDIAN 1 -#else -# error "Cannot determine endianness of your platform. Please add support to jscpucfg.h." -#endif - #ifndef JS_STACK_GROWTH_DIRECTION # ifdef __hppa # define JS_STACK_GROWTH_DIRECTION (1) diff --git a/js/src/jsdtoa.cpp b/js/src/jsdtoa.cpp index 6d0d950b474e..69f50b1df04a 100644 --- a/js/src/jsdtoa.cpp +++ b/js/src/jsdtoa.cpp @@ -16,7 +16,7 @@ using namespace js; -#ifdef IS_LITTLE_ENDIAN +#if MOZ_LITTLE_ENDIAN #define IEEE_8087 #else #define IEEE_MC68k diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 954b4081b15b..4f5dbf84d3ad 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1784,7 +1784,7 @@ DataViewObject::getDataPointer(JSContext* cx, Handle obj, doubl static inline bool needToSwapBytes(bool littleEndian) { -#if IS_LITTLE_ENDIAN +#if MOZ_LITTLE_ENDIAN return !littleEndian; #else return littleEndian; From 0eaf8d3e06d3846fc631c3af407cda8037149405 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Mon, 3 Oct 2016 17:18:38 +0800 Subject: [PATCH 12/37] Bug 1307063. Move MDSM::MaybeFinishDecodeFirstFrame() into DecodingFirstFrameState. r=kikuo MozReview-Commit-ID: LVLjImUQf26 --HG-- extra : rebase_source : 1990080c2888b2e384f74c24246ffc93f70fc3f8 --- dom/media/MediaDecoderStateMachine.cpp | 47 +++++++++++++------------- dom/media/MediaDecoderStateMachine.h | 4 --- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 23edfe0b00cb..986c99724b61 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -428,22 +428,43 @@ public: bool HandleAudioDecoded(MediaData* aAudio) override { mMaster->Push(aAudio, MediaData::AUDIO_DATA); - mMaster->MaybeFinishDecodeFirstFrame(); + MaybeFinishDecodeFirstFrame(); return true; } bool HandleVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStart) override { mMaster->Push(aVideo, MediaData::VIDEO_DATA); - mMaster->MaybeFinishDecodeFirstFrame(); + MaybeFinishDecodeFirstFrame(); return true; } bool HandleEndOfStream() override { - mMaster->MaybeFinishDecodeFirstFrame(); + MaybeFinishDecodeFirstFrame(); return true; } + +private: + // Notify FirstFrameLoaded if having decoded first frames and + // transition to SEEKING if there is any pending seek, or DECODING otherwise. + void MaybeFinishDecodeFirstFrame() + { + MOZ_ASSERT(!mMaster->mSentFirstFrameLoadedEvent); + + if ((mMaster->IsAudioDecoding() && mMaster->AudioQueue().GetSize() == 0) || + (mMaster->IsVideoDecoding() && mMaster->VideoQueue().GetSize() == 0)) { + return; + } + + mMaster->FinishDecodeFirstFrame(); + + if (mMaster->mQueuedSeek.Exists()) { + mMaster->InitiateSeek(Move(mMaster->mQueuedSeek)); + } else { + SetState(DECODER_STATE_DECODING); + } + } }; class MediaDecoderStateMachine::DecodingState @@ -1249,26 +1270,6 @@ MediaDecoderStateMachine::OnNotDecoded(MediaData::Type aType, mStateObj->HandleEndOfStream(); } -void -MediaDecoderStateMachine::MaybeFinishDecodeFirstFrame() -{ - MOZ_ASSERT(OnTaskQueue()); - MOZ_ASSERT(!mSentFirstFrameLoadedEvent); - - if ((IsAudioDecoding() && AudioQueue().GetSize() == 0) || - (IsVideoDecoding() && VideoQueue().GetSize() == 0)) { - return; - } - - FinishDecodeFirstFrame(); - - if (mQueuedSeek.Exists()) { - InitiateSeek(Move(mQueuedSeek)); - } else { - SetState(DECODER_STATE_DECODING); - } -} - void MediaDecoderStateMachine::OnVideoDecoded(MediaData* aVideo, TimeStamp aDecodeStartTime) diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 8626551df72b..cd4d587961f8 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -533,10 +533,6 @@ protected: // must be held when calling this. Called on the decode thread. int64_t GetDecodedAudioDuration(); - // Notify FirstFrameLoaded if having decoded first frames and - // transition to SEEKING if there is any pending seek, or DECODING otherwise. - void MaybeFinishDecodeFirstFrame(); - void FinishDecodeFirstFrame(); // Completes the seek operation, moves onto the next appropriate state. From 79e4f601c0f3670a784e361a5544997fb24dd803 Mon Sep 17 00:00:00 2001 From: Kaku Kuo Date: Tue, 4 Oct 2016 16:10:13 +0800 Subject: [PATCH 13/37] Bug 1306945 - remove the check of mPlayState in the MDSM::VisibilityChanged(); r=jwwang,kamidphish MozReview-Commit-ID: JBJJ7dPt64i --HG-- extra : rebase_source : 27b738832ffda283d931f5f5d27b43ed9f2f5d3a --- dom/media/MediaDecoderStateMachine.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 986c99724b61..8dea265aad85 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -1842,11 +1842,6 @@ void MediaDecoderStateMachine::VisibilityChanged() return; } - // If not playing then there's nothing to do. - if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING) { - return; - } - // Start timer to trigger suspended decoding state when going invisible. if (!mIsVisible) { TimeStamp target = TimeStamp::Now() + SuspendBackgroundVideoDelay(); From a312732ab68155cb5f3b85eb405853eca8b2bc44 Mon Sep 17 00:00:00 2001 From: Chun-Min Chang Date: Tue, 4 Oct 2016 13:27:32 +0800 Subject: [PATCH 14/37] Bug 1306536 - Don't set displayURI when it's set to false; r=mconley MozReview-Commit-ID: DI52QqsS3BE --HG-- extra : rebase_source : b637dd7ac8d802197c7b6629e1c16ea597971810 --- browser/modules/PermissionUI.jsm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/browser/modules/PermissionUI.jsm b/browser/modules/PermissionUI.jsm index c0f6ba4aa2cf..31fdbbb4cdcf 100644 --- a/browser/modules/PermissionUI.jsm +++ b/browser/modules/PermissionUI.jsm @@ -133,8 +133,9 @@ this.PermissionPromptPrototype = { * PopupNotification when it is shown. See the documentation * for PopupNotification for more details. * - * Note that prompt() will automatically set displayURI to - * be the URI of the requesting pricipal. + * Note that prompt() will automatically set displayURI to + * be the URI of the requesting pricipal, unless the displayURI is exactly + * set to false. */ get popupOptions() { return {}; @@ -329,7 +330,10 @@ this.PermissionPromptPrototype = { let secondaryActions = popupNotificationActions.splice(1); let options = this.popupOptions; - options.displayURI = this.principal.URI; + + if (!options.hasOwnProperty('displayURI') || options.displayURI) { + options.displayURI = this.principal.URI; + } this.onBeforeShow(); chromeWin.PopupNotifications.show(this.browser, From 069e307afb67d828cb8e1d4da135597004d5dcbb Mon Sep 17 00:00:00 2001 From: Chun-Min Chang Date: Wed, 5 Oct 2016 10:40:23 +0800 Subject: [PATCH 15/37] Bug 1306536 - Test; r=mconley MozReview-Commit-ID: CqPEbcfFMqF --HG-- extra : rebase_source : 278543e3b266a285d50628b9554b626b5eae6b1d --- browser/modules/test/browser_PermissionUI.js | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/browser/modules/test/browser_PermissionUI.js b/browser/modules/test/browser_PermissionUI.js index 297db3d31780..006bc5e66401 100644 --- a/browser/modules/test/browser_PermissionUI.js +++ b/browser/modules/test/browser_PermissionUI.js @@ -157,6 +157,55 @@ add_task(function* test_permission_prompt_for_request() { }); }); +/** + * Tests that if the PermissionPrompt sets displayURI to false in popupOptions, + * then there is no URI shown on the popupnotification. + */ +add_task(function* test_permission_prompt_for_popupOptions() { + yield BrowserTestUtils.withNewTab({ + gBrowser, + url: "http://example.com/", + }, function*(browser) { + const kTestNotificationID = "test-notification"; + const kTestMessage = "Test message"; + let mainAction = { + label: "Main", + accessKey: "M", + }; + let secondaryAction = { + label: "Secondary", + accessKey: "S", + }; + + let mockRequest = makeMockPermissionRequest(browser); + let TestPrompt = { + __proto__: PermissionUI.PermissionPromptForRequestPrototype, + request: mockRequest, + notificationID: kTestNotificationID, + message: kTestMessage, + promptActions: [mainAction, secondaryAction], + popupOptions: { + displayURI: false, + }, + }; + + let shownPromise = + BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); + TestPrompt.prompt(); + yield shownPromise; + let notification = + PopupNotifications.getNotification(kTestNotificationID, browser); + + Assert.ok(!notification.options.displayURI, + "Should not show the URI of the requesting page"); + + let removePromise = + BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popuphidden"); + notification.remove(); + yield removePromise; + }); +}); + /** * Tests that if the PermissionPrompt has the permissionKey * set that permissions can be set properly by the user. Also From eeb751d4119facdf73848cfafefba5b9f8209d23 Mon Sep 17 00:00:00 2001 From: "Fischer.json" Date: Tue, 20 Sep 2016 15:45:15 +0800 Subject: [PATCH 16/37] Bug 1130447 - Hide the password manager timeLastUsed column by default. r=MattN MozReview-Commit-ID: LxKnIfBhtQh --HG-- extra : rebase_source : edbb41cc39c29523c65e00f21dc632a0aa2116a7 --- toolkit/components/passwordmgr/content/passwordManager.xul | 4 +++- .../passwordmgr/test/browser/browser_passwordmgr_fields.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/toolkit/components/passwordmgr/content/passwordManager.xul b/toolkit/components/passwordmgr/content/passwordManager.xul index 37601bf3d17b..d248283b67ba 100644 --- a/toolkit/components/passwordmgr/content/passwordManager.xul +++ b/toolkit/components/passwordmgr/content/passwordManager.xul @@ -14,6 +14,7 @@ onload="Startup();" onunload="Shutdown();" title="&savedLogins.title;" + style="width: 45em;" persist="width height screenX screenY"> From e3bfff82b53ecfb38cc94b1512af8b4aae241341 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Tue, 4 Oct 2016 15:03:30 +0800 Subject: [PATCH 28/37] Bug 1307356 - Move MDSM::DecodeFirstFrame() into DecodingFirstFrameState. r=kikuo MozReview-Commit-ID: 9zL76KjBhF7 --HG-- extra : rebase_source : fa9e3a22bb9f13ad33275ce7258d21b7d5e13443 --- dom/media/MediaDecoderStateMachine.cpp | 40 +++++++++++--------------- dom/media/MediaDecoderStateMachine.h | 3 -- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 36a2a9b8c95e..d54209977bf0 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -439,7 +439,22 @@ public: void Enter() override { - mMaster->DecodeFirstFrame(); + // Handle pending seek. + if (mMaster->mQueuedSeek.Exists() && + (mMaster->mSentFirstFrameLoadedEvent || + Reader()->ForceZeroStartTime())) { + mMaster->InitiateSeek(Move(mMaster->mQueuedSeek)); + return; + } + + // Transition to DECODING if we've decoded first frames. + if (mMaster->mSentFirstFrameLoadedEvent) { + SetState(DECODER_STATE_DECODING); + return; + } + + // Dispatch tasks to decode first frames. + mMaster->DispatchDecodeTasksIfNeeded(); } State GetState() const override @@ -1885,29 +1900,6 @@ MediaDecoderStateMachine::Shutdown() ->CompletionPromise(); } -void -MediaDecoderStateMachine::DecodeFirstFrame() -{ - MOZ_ASSERT(OnTaskQueue()); - MOZ_ASSERT(mState == DECODER_STATE_DECODING_FIRSTFRAME); - - // Handle pending seek. - if (mQueuedSeek.Exists() && - (mSentFirstFrameLoadedEvent || mReader->ForceZeroStartTime())) { - InitiateSeek(Move(mQueuedSeek)); - return; - } - - // Transition to DECODING if we've decoded first frames. - if (mSentFirstFrameLoadedEvent) { - SetState(DECODER_STATE_DECODING); - return; - } - - // Dispatch tasks to decode first frames. - DispatchDecodeTasksIfNeeded(); -} - void MediaDecoderStateMachine::PlayStateChanged() { MOZ_ASSERT(OnTaskQueue()); diff --git a/dom/media/MediaDecoderStateMachine.h b/dom/media/MediaDecoderStateMachine.h index 9037ed0e8a11..fa0f48af4389 100644 --- a/dom/media/MediaDecoderStateMachine.h +++ b/dom/media/MediaDecoderStateMachine.h @@ -472,9 +472,6 @@ protected: // If we don't, switch to buffering mode. void MaybeStartBuffering(); - // The entry action of DECODER_STATE_DECODING_FIRSTFRAME. - void DecodeFirstFrame(); - // Moves the decoder into the shutdown state, and dispatches an error // event to the media element. This begins shutting down the decoder. // The decoder monitor must be held. This is only called on the From 63a89783cc8977f7c9dca46396c29677991f8500 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Thu, 8 Sep 2016 10:20:24 +0200 Subject: [PATCH 29/37] Bug 1301715 - Extract website metadata and make it available. r=ahunt This patch introduces WebsiteMetadata.jsm which imports fathom and page-metadata-parser. The code has been slightly modified to not depend on more node libraries. On DOMContentLoaded the module will extract the metadata asynchronously and send it with a 'Website:Metadata' event. MozReview-Commit-ID: LxhYOTvvdsF --HG-- extra : rebase_source : e31286bd7268ad62d55f1a5318cde79442e9acba --- mobile/android/chrome/content/browser.js | 5 + mobile/android/modules/WebsiteMetadata.jsm | 468 +++++++++++++++++++++ mobile/android/modules/moz.build | 1 + 3 files changed, 474 insertions(+) create mode 100644 mobile/android/modules/WebsiteMetadata.jsm diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 88fcc8d31d61..a2bd6efac1a5 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -116,6 +116,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "Snackbars", "resource://gre/modules/Sna XPCOMUtils.defineLazyModuleGetter(this, "RuntimePermissions", "resource://gre/modules/RuntimePermissions.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "WebsiteMetadata", "resource://gre/modules/WebsiteMetadata.jsm"); + XPCOMUtils.defineLazyServiceGetter(this, "FontEnumerator", "@mozilla.org/gfx/fontenumerator;1", "nsIFontEnumerator"); @@ -3930,6 +3932,9 @@ Tab.prototype = { this.browser.addEventListener("pagehide", listener, true); } + + WebsiteMetadata.parseAsynchronously(this.browser.contentDocument); + break; } diff --git a/mobile/android/modules/WebsiteMetadata.jsm b/mobile/android/modules/WebsiteMetadata.jsm new file mode 100644 index 000000000000..f0d33aa75078 --- /dev/null +++ b/mobile/android/modules/WebsiteMetadata.jsm @@ -0,0 +1,468 @@ +/* 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/. */ + +'use strict'; + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +this.EXPORTED_SYMBOLS = ["WebsiteMetadata"]; + +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "Messaging", "resource://gre/modules/Messaging.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); + +var WebsiteMetadata = { + /** + * Asynchronously parse the document extract metadata. A 'Website:Metadata' event with the metadata + * will be sent. + */ + parseAsynchronously: function(doc) { + Task.spawn(function() { + let metadata = getMetadata(doc, doc.location.href); + + let msg = { + type: 'Website:Metadata', + location: doc.location.href, + metadata: metadata, + }; + + Messaging.sendRequest(msg); + }); + } +}; + +// ################################################################################################# +// # Modified version of makeUrlAbsolute() to not import url parser library (and dependencies) +// ################################################################################################# + +function makeUrlAbsolute(context, relative) { + var a = context.doc.createElement('a'); + a.href = relative; + return a.href; +} + +// ################################################################################################# +// # page-metadata-parser +// # https://github.com/mozilla/page-metadata-parser/ +// # 61c58cbd0f0bf2153df832a388a79c66b288b98c +// ################################################################################################# + +function buildRuleset(name, rules, processors) { + const reversedRules = Array.from(rules).reverse(); + const builtRuleset = ruleset(...reversedRules.map(([query, handler], order) => rule( + dom(query), + node => [{ + score: order, + flavor: name, + notes: handler(node), + }] + ))); + + return (doc, context) => { + const kb = builtRuleset.score(doc); + const maxNode = kb.max(name); + + if (maxNode) { + let value = maxNode.flavors.get(name); + + if (processors) { + processors.forEach(processor => { + value = processor(value, context); + }); + } + + if (value) { + if (value.trim) { + return value.trim(); + } + return value; + } + } + }; +} + +const metadataRules = { + description: { + rules: [ + ['meta[property="og:description"]', node => node.element.getAttribute('content')], + ['meta[name="description"]', node => node.element.getAttribute('content')], + ], + }, + + icon_url: { + rules: [ + ['link[rel="apple-touch-icon"]', node => node.element.getAttribute('href')], + ['link[rel="apple-touch-icon-precomposed"]', node => node.element.getAttribute('href')], + ['link[rel="icon"]', node => node.element.getAttribute('href')], + ['link[rel="fluid-icon"]', node => node.element.getAttribute('href')], + ['link[rel="shortcut icon"]', node => node.element.getAttribute('href')], + ['link[rel="Shortcut Icon"]', node => node.element.getAttribute('href')], + ['link[rel="mask-icon"]', node => node.element.getAttribute('href')], + ], + processors: [ + (icon_url, context) => makeUrlAbsolute(context, icon_url) + ] + }, + + image_url: { + rules: [ + ['meta[property="og:image:secure_url"]', node => node.element.getAttribute('content')], + ['meta[property="og:image:url"]', node => node.element.getAttribute('content')], + ['meta[property="og:image"]', node => node.element.getAttribute('content')], + ['meta[property="twitter:image"]', node => node.element.getAttribute('content')], + ['meta[name="thumbnail"]', node => node.element.getAttribute('content')], + ], + processors: [ + (image_url, context) => makeUrlAbsolute(context, image_url) + ], + }, + + keywords: { + rules: [ + ['meta[name="keywords"]', node => node.element.getAttribute('content')], + ], + processors: [ + (keywords) => keywords.split(',').map((keyword) => keyword.trim()), + ] + }, + + title: { + rules: [ + ['meta[property="og:title"]', node => node.element.getAttribute('content')], + ['meta[property="twitter:title"]', node => node.element.getAttribute('content')], + ['meta[name="hdl"]', node => node.element.getAttribute('content')], + ['title', node => node.element.text], + ], + }, + + type: { + rules: [ + ['meta[property="og:type"]', node => node.element.getAttribute('content')], + ], + }, + + url: { + rules: [ + ['meta[property="og:url"]', node => node.element.getAttribute('content')], + ['link[rel="canonical"]', node => node.element.getAttribute('href')], + ], + }, +}; + +function getMetadata(doc, url, rules) { + const metadata = {}; + const context = {url,doc}; + const ruleSet = rules || metadataRules; + + Object.keys(ruleSet).map(metadataKey => { + const metadataRule = ruleSet[metadataKey]; + + if(Array.isArray(metadataRule.rules)) { + const builtRule = buildRuleset(metadataKey, metadataRule.rules, metadataRule.processors); + metadata[metadataKey] = builtRule(doc, context); + } else { + metadata[metadataKey] = getMetadata(doc, url, metadataRule); + } + }); + + return metadata; +} + +// ################################################################################################# +// # Fathom dependencies resolved +// ################################################################################################# + +// const {forEach} = require('wu'); +function forEach(fn, obj) { + for (let x of obj) { + fn(x); + } +} + +function best(iterable, by, isBetter) { + let bestSoFar, bestKeySoFar; + let isFirst = true; + forEach( + function (item) { + const key = by(item); + if (isBetter(key, bestKeySoFar) || isFirst) { + bestSoFar = item; + bestKeySoFar = key; + isFirst = false; + } + }, + iterable); + if (isFirst) { + throw new Error('Tried to call best() on empty iterable'); + } + return bestSoFar; +} + +// const {max} = require('./utils'); +function max(iterable, by = identity) { + return best(iterable, by, (a, b) => a > b); +} + +// ################################################################################################# +// # Fathom +// # https://github.com/mozilla/fathom +// # cac59e470816f17fc1efd4a34437b585e3e451cd +// ################################################################################################# + +// Get a key of a map, first setting it to a default value if it's missing. +function getDefault(map, key, defaultMaker) { + if (map.has(key)) { + return map.get(key); + } + const defaultValue = defaultMaker(); + map.set(key, defaultValue); + return defaultValue; +} + + +// Construct a filtration network of rules. +function ruleset(...rules) { + const rulesByInputFlavor = new Map(); // [someInputFlavor: [rule, ...]] + + // File each rule under its input flavor: + forEach(rule => getDefault(rulesByInputFlavor, rule.source.inputFlavor, () => []).push(rule), + rules); + + return { + // Iterate over a DOM tree or subtree, building up a knowledgebase, a + // data structure holding scores and annotations for interesting + // elements. Return the knowledgebase. + // + // This is the "rank" portion of the rank-and-yank algorithm. + score: function (tree) { + const kb = knowledgebase(); + + // Introduce the whole DOM into the KB as flavor 'dom' to get + // things started: + const nonterminals = [[{tree}, 'dom']]; // [[node, flavor], [node, flavor], ...] + + // While there are new facts, run the applicable rules over them to + // generate even newer facts. Repeat until everything's fully + // digested. Rules run in no particular guaranteed order. + while (nonterminals.length) { + const [inNode, inFlavor] = nonterminals.pop(); + for (let rule of getDefault(rulesByInputFlavor, inFlavor, () => [])) { + const outFacts = resultsOf(rule, inNode, inFlavor, kb); + for (let fact of outFacts) { + const outNode = kb.nodeForElement(fact.element); + + // No matter whether or not this flavor has been + // emitted before for this node, we multiply the score. + // We want to be able to add rules that refine the + // scoring of a node, without having to rewire the path + // of flavors that winds through the ruleset. + // + // 1 score per Node is plenty. That simplifies our + // data, our rankers, our flavor system (since we don't + // need to represent score axes), and our engine. If + // somebody wants more score axes, they can fake it + // themselves with notes, thus paying only for what + // they eat. (We can even provide functions that help + // with that.) Most rulesets will probably be concerned + // with scoring only 1 thing at a time anyway. So, + // rankers return a score multiplier + 0 or more new + // flavors with optional notes. Facts can never be + // deleted from the KB by rankers (or order would start + // to matter); after all, they're *facts*. + outNode.score *= fact.score; + + // Add a new annotation to a node--but only if there + // wasn't already one of the given flavor already + // there; otherwise there's no point. + // + // You might argue that we might want to modify an + // existing note here, but that would be a bad + // idea. Notes of a given flavor should be + // considered immutable once laid down. Otherwise, the + // order of execution of same-flavored rules could + // matter, hurting pluggability. Emit a new flavor and + // a new note if you want to do that. + // + // Also, choosing not to add a new fact to nonterminals + // when we're not adding a new flavor saves the work of + // running the rules against it, which would be + // entirely redundant and perform no new work (unless + // the rankers were nondeterministic, but don't do + // that). + if (!outNode.flavors.has(fact.flavor)) { + outNode.flavors.set(fact.flavor, fact.notes); + kb.indexNodeByFlavor(outNode, fact.flavor); // TODO: better encapsulation rather than indexing explicitly + nonterminals.push([outNode, fact.flavor]); + } + } + } + } + return kb; + } + }; +} + + +// Construct a container for storing and querying facts, where a fact has a +// flavor (used to dispatch further rules upon), a corresponding DOM element, a +// score, and some other arbitrary notes opaque to fathom. +function knowledgebase() { + const nodesByFlavor = new Map(); // Map{'texty' -> [NodeA], + // 'spiffy' -> [NodeA, NodeB]} + // NodeA = {element: , + // + // // Global nodewide score. Add + // // custom ones with notes if + // // you want. + // score: 8, + // + // // Flavors is a map of flavor names to notes: + // flavors: Map{'texty' -> {ownText: 'blah', + // someOtherNote: 'foo', + // someCustomScore: 10}, + // // This is an empty note: + // 'fluffy' -> undefined}} + const nodesByElement = new Map(); + + return { + // Return the "node" (our own data structure that we control) that + // corresponds to a given DOM element, creating one if necessary. + nodeForElement: function (element) { + return getDefault(nodesByElement, + element, + () => ({element, + score: 1, + flavors: new Map()})); + }, + + // Return the highest-scored node of the given flavor, undefined if + // there is none. + max: function (flavor) { + const nodes = nodesByFlavor.get(flavor); + return nodes === undefined ? undefined : max(nodes, node => node.score); + }, + + // Let the KB know that a new flavor has been added to an element. + indexNodeByFlavor: function (node, flavor) { + getDefault(nodesByFlavor, flavor, () => []).push(node); + }, + + nodesOfFlavor: function (flavor) { + return getDefault(nodesByFlavor, flavor, () => []); + } + }; +} + + +// Apply a rule (as returned by a call to rule()) to a fact, and return the +// new facts that result. +function resultsOf(rule, node, flavor, kb) { + // If more types of rule pop up someday, do fancier dispatching here. + return rule.source.flavor === 'flavor' ? resultsOfFlavorRule(rule, node, flavor) : resultsOfDomRule(rule, node, kb); +} + + +// Pull the DOM tree off the special property of the root "dom" fact, and query +// against it. +function *resultsOfDomRule(rule, specialDomNode, kb) { + // Use the special "tree" property of the special starting node: + const matches = specialDomNode.tree.querySelectorAll(rule.source.selector); + + for (let i = 0; i < matches.length; i++) { // matches is a NodeList, which doesn't conform to iterator protocol + const element = matches[i]; + const newFacts = explicitFacts(rule.ranker(kb.nodeForElement(element))); + for (let fact of newFacts) { + if (fact.element === undefined) { + fact.element = element; + } + if (fact.flavor === undefined) { + throw new Error('Rankers of dom() rules must return a flavor in each fact. Otherwise, there is no way for that fact to be used later.'); + } + yield fact; + } + } +} + + +function *resultsOfFlavorRule(rule, node, flavor) { + const newFacts = explicitFacts(rule.ranker(node)); + + for (let fact of newFacts) { + // If the ranker didn't specify a different element, assume it's + // talking about the one we passed in: + if (fact.element === undefined) { + fact.element = node.element; + } + if (fact.flavor === undefined) { + fact.flavor = flavor; + } + yield fact; + } +} + + +// Take the possibly abbreviated output of a ranker function, and make it +// explicitly an iterable with a defined score. +// +// Rankers can return undefined, which means "no facts", a single fact, or an +// array of facts. +function *explicitFacts(rankerResult) { + const array = (rankerResult === undefined) ? [] : (Array.isArray(rankerResult) ? rankerResult : [rankerResult]); + for (let fact of array) { + if (fact.score === undefined) { + fact.score = 1; + } + yield fact; + } +} + + +// TODO: For the moment, a lot of responsibility is on the rankers to return a +// pretty big data structure of up to 4 properties. This is a bit verbose for +// an arrow function (as I hope we can use most of the time) and the usual case +// will probably be returning just a score multiplier. Make that case more +// concise. + +// TODO: It is likely that rankers should receive the notes of their input type +// as a 2nd arg, for brevity. + + +// Return a condition that uses a DOM selector to find its matches from the +// original DOM tree. +// +// For consistency, Nodes will still be delivered to the transformers, but +// they'll have empty flavors and score = 1. +// +// Condition constructors like dom() and flavor() build stupid, introspectable +// objects that the query engine can read. They don't actually do the query +// themselves. That way, the query planner can be smarter than them, figuring +// out which indices to use based on all of them. (We'll probably keep a heap +// by each dimension's score and a hash by flavor name, for starters.) Someday, +// fancy things like this may be possible: rule(and(tag('p'), klass('snork')), +// ...) +function dom(selector) { + return { + flavor: 'dom', + inputFlavor: 'dom', + selector + }; +} + + +// Return a condition that discriminates on nodes of the knowledgebase by flavor. +function flavor(inputFlavor) { + return { + flavor: 'flavor', + inputFlavor + }; +} + + +function rule(source, ranker) { + return { + source, + ranker + }; +} diff --git a/mobile/android/modules/moz.build b/mobile/android/modules/moz.build index 045971fc6ccc..479ff1f3f552 100644 --- a/mobile/android/modules/moz.build +++ b/mobile/android/modules/moz.build @@ -29,4 +29,5 @@ EXTRA_JS_MODULES += [ 'Snackbars.jsm', 'SSLExceptions.jsm', 'TabMirror.jsm', + 'WebsiteMetadata.jsm' ] From 2e775e23a63b55b723916db77d1e2c17d53d629b Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Thu, 8 Sep 2016 10:20:44 +0200 Subject: [PATCH 30/37] Bug 1301715 - BrowserApp: Receive metadata from event. r=ahunt MozReview-Commit-ID: 7rND7R09Pj6 --HG-- extra : rebase_source : cbc2d1dedfcac4177d683eaa038a02f598f88ea2 --- .../base/java/org/mozilla/gecko/BrowserApp.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index fccf96dccd8b..ba1ff6befa97 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -749,7 +749,8 @@ public class BrowserApp extends GeckoApp "Sanitize:ClearSyncedTabs", "Settings:Show", "Telemetry:Gather", - "Updater:Launch"); + "Updater:Launch", + "Website:Metadata"); final GeckoProfile profile = getProfile(); @@ -1490,7 +1491,8 @@ public class BrowserApp extends GeckoApp "Sanitize:ClearSyncedTabs", "Settings:Show", "Telemetry:Gather", - "Updater:Launch"); + "Updater:Launch", + "Website:Metadata"); if (AppConstants.MOZ_ANDROID_BEAM) { NfcAdapter nfc = NfcAdapter.getDefaultAdapter(this); @@ -1930,6 +1932,13 @@ public class BrowserApp extends GeckoApp } break; + case "Website:Metadata": + final NativeJSObject metadata = message.getObject("metadata"); + final String location = message.getString("location"); + + // TODO: Store metadata (Bug 1301717) + break; + default: super.handleMessage(event, message, callback); break; From 8a899e5b22cbe745fedaf2428de5bf5f52a16a90 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Fri, 30 Sep 2016 11:58:25 -0400 Subject: [PATCH 31/37] Bug 1301715 - Only extract metadata if the Activity Stream or Nightly flag is enabled. r=ahunt MozReview-Commit-ID: 7Ic8v1M6AAy --HG-- extra : rebase_source : aec2ce74749b19abf21f5f1f1ed098af60eaf3af --- mobile/android/chrome/content/browser.js | 4 +++- toolkit/modules/AppConstants.jsm | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index a2bd6efac1a5..a9a7c3d13f05 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -3933,7 +3933,9 @@ Tab.prototype = { this.browser.addEventListener("pagehide", listener, true); } - WebsiteMetadata.parseAsynchronously(this.browser.contentDocument); + if (AppConstants.NIGHTLY_BUILD || AppConstants.MOZ_ANDROID_ACTIVITY_STREAM) { + WebsiteMetadata.parseAsynchronously(this.browser.contentDocument); + } break; } diff --git a/toolkit/modules/AppConstants.jsm b/toolkit/modules/AppConstants.jsm index 1549bb7cac46..ebbd143b4ddd 100644 --- a/toolkit/modules/AppConstants.jsm +++ b/toolkit/modules/AppConstants.jsm @@ -295,6 +295,13 @@ this.AppConstants = Object.freeze({ false, #endif + MOZ_ANDROID_ACTIVITY_STREAM: +#ifdef MOZ_ANDROID_ACTIVITY_STREAM + true, +#else + false, +#endif + DLL_PREFIX: "@DLL_PREFIX@", DLL_SUFFIX: "@DLL_SUFFIX@", From d57c05a9ea923ff54308c29bec1dd6beca090b93 Mon Sep 17 00:00:00 2001 From: "Tushar Saini (:shatur)" Date: Thu, 22 Sep 2016 21:20:23 +0530 Subject: [PATCH 32/37] Bug 1261041 - Remove feature11Plus-feature15Plus flags. r=sebastian MozReview-Commit-ID: J4uXtUrjuKr --HG-- extra : rebase_source : e21e02831ddc3c32a2d0be508b217e8c7b08cb12 --- mobile/android/base/AppConstants.java.in | 9 +- .../java/org/mozilla/gecko/BrowserApp.java | 122 +++++++----------- .../org/mozilla/gecko/DoorHangerPopup.java | 7 +- .../base/java/org/mozilla/gecko/GeckoApp.java | 33 +---- .../java/org/mozilla/gecko/IntentHelper.java | 4 - .../org/mozilla/gecko/ScreenshotObserver.java | 8 -- .../base/java/org/mozilla/gecko/Tabs.java | 3 +- .../gecko/animation/PropertyAnimator.java | 2 +- .../db/AbstractTransactionalProvider.java | 2 +- .../java/org/mozilla/gecko/db/DBUtils.java | 17 +-- .../gecko/db/SQLiteBridgeContentProvider.java | 5 +- .../org/mozilla/gecko/home/HomePager.java | 2 +- .../mozilla/gecko/lwt/LightweightTheme.java | 9 +- .../mozilla/gecko/menu/GeckoMenuInflater.java | 4 +- .../org/mozilla/gecko/menu/MenuPanel.java | 4 +- .../ui/SendTabDeviceListArrayAdapter.java | 8 +- .../preferences/GeckoPreferenceFragment.java | 5 +- .../gecko/preferences/GeckoPreferences.java | 42 +++--- .../gecko/preferences/SyncPreference.java | 8 -- .../mozilla/gecko/prompts/IconGridInput.java | 2 +- .../gecko/tabqueue/TabQueueHelper.java | 2 +- .../mozilla/gecko/tabs/TabsGridLayout.java | 4 +- .../mozilla/gecko/toolbar/BrowserToolbar.java | 4 +- .../mozilla/gecko/toolbar/CanvasDelegate.java | 16 +-- .../gecko/toolbar/SiteIdentityPopup.java | 8 +- .../gecko/toolbar/ToolbarEditText.java | 3 +- .../mozilla/gecko/widget/DateTimePicker.java | 109 ++++++---------- .../gecko/widget/RoundedCornerLayout.java | 2 +- .../org/mozilla/gecko/GeckoAccessibility.java | 16 +-- .../java/org/mozilla/gecko/GeckoAppShell.java | 18 +-- .../java/org/mozilla/gecko/GeckoEditable.java | 6 +- .../mozilla/gecko/GeckoInputConnection.java | 8 +- .../java/org/mozilla/gecko/gfx/LayerView.java | 6 +- .../org/mozilla/gecko/util/Clipboard.java | 54 +++----- .../org/mozilla/gecko/util/StringUtils.java | 34 +---- .../org/mozilla/gecko/util/WindowUtils.java | 5 +- .../mozilla/search/PostSearchFragment.java | 4 +- .../background/common/GlobalConstants.java | 21 +-- .../activities/FxAccountStatusActivity.java | 10 +- .../activities/FxAccountStatusFragment.java | 6 - .../PicassoPreferenceIconTarget.java | 13 -- 41 files changed, 176 insertions(+), 469 deletions(-) diff --git a/mobile/android/base/AppConstants.java.in b/mobile/android/base/AppConstants.java.in index a9229599f06f..6fd2532fd661 100644 --- a/mobile/android/base/AppConstants.java.in +++ b/mobile/android/base/AppConstants.java.in @@ -51,11 +51,6 @@ public class AppConstants { * If MIN_SDK_VERSION is greater than or equal to the number, there * is no need to do the runtime check. */ - public static final boolean feature10Plus = MIN_SDK_VERSION >= 10 || (MAX_SDK_VERSION >= 10 && Build.VERSION.SDK_INT >= 10); - public static final boolean feature11Plus = MIN_SDK_VERSION >= 11 || (MAX_SDK_VERSION >= 11 && Build.VERSION.SDK_INT >= 11); - public static final boolean feature12Plus = MIN_SDK_VERSION >= 12 || (MAX_SDK_VERSION >= 12 && Build.VERSION.SDK_INT >= 12); - public static final boolean feature14Plus = MIN_SDK_VERSION >= 14 || (MAX_SDK_VERSION >= 14 && Build.VERSION.SDK_INT >= 14); - public static final boolean feature15Plus = MIN_SDK_VERSION >= 15 || (MAX_SDK_VERSION >= 15 && Build.VERSION.SDK_INT >= 15); public static final boolean feature16Plus = MIN_SDK_VERSION >= 16 || (MAX_SDK_VERSION >= 16 && Build.VERSION.SDK_INT >= 16); public static final boolean feature17Plus = MIN_SDK_VERSION >= 17 || (MAX_SDK_VERSION >= 17 && Build.VERSION.SDK_INT >= 17); public static final boolean feature19Plus = MIN_SDK_VERSION >= 19 || (MAX_SDK_VERSION >= 19 && Build.VERSION.SDK_INT >= 19); @@ -238,7 +233,7 @@ public class AppConstants { // it if this APK doesn't include API14 support. public static final boolean MOZ_ANDROID_BEAM = //#ifdef MOZ_ANDROID_BEAM - Versions.feature14Plus; + true; //#else false; //#endif @@ -285,7 +280,7 @@ public class AppConstants { public static final boolean ANDROID_DOWNLOADS_INTEGRATION = //#ifdef MOZ_ANDROID_DOWNLOADS_INTEGRATION - AppConstants.Versions.feature12Plus; + true; //#else false; //#endif diff --git a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java index ba1ff6befa97..45a9b47b239d 100644 --- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java @@ -515,7 +515,7 @@ public class BrowserApp extends GeckoApp // Check if this was a shortcut. Meta keys exists only on 11+. final Tab tab = Tabs.getInstance().getSelectedTab(); - if (Versions.feature11Plus && tab != null && event.isCtrlPressed()) { + if (tab != null && event.isCtrlPressed()) { switch (keyCode) { case KeyEvent.KEYCODE_LEFT_BRACKET: tab.doBack(); @@ -2770,10 +2770,6 @@ public class BrowserApp extends GeckoApp mMenu.clear(); onCreateOptionsMenu(mMenu); } - - if (!Versions.feature14Plus) { - conditionallyNotifyEOL(); - } } @Override @@ -3189,12 +3185,8 @@ public class BrowserApp extends GeckoApp destination = menu; } else if (info.parent == GECKO_TOOLS_MENU) { // The tools menu only exists in our -v11 resources. - if (Versions.feature11Plus) { - final MenuItem tools = menu.findItem(R.id.tools); - destination = tools != null ? tools.getSubMenu() : menu; - } else { - destination = menu; - } + final MenuItem tools = menu.findItem(R.id.tools); + destination = tools != null ? tools.getSubMenu() : menu; } else { final MenuItem parent = menu.findItem(info.parent); if (parent == null) { @@ -3319,13 +3311,11 @@ public class BrowserApp extends GeckoApp } // Action providers are available only ICS+. - if (Versions.feature14Plus) { - GeckoMenuItem share = (GeckoMenuItem) mMenu.findItem(R.id.share); + GeckoMenuItem share = (GeckoMenuItem) mMenu.findItem(R.id.share); - GeckoActionProvider provider = GeckoActionProvider.getForType(GeckoActionProvider.DEFAULT_MIME_TYPE, this); + GeckoActionProvider provider = GeckoActionProvider.getForType(GeckoActionProvider.DEFAULT_MIME_TYPE, this); - share.setActionProvider(provider); - } + share.setActionProvider(provider); return true; } @@ -3454,10 +3444,7 @@ public class BrowserApp extends GeckoApp // NOTE: Use MenuUtils.safeSetEnabled because some actions might // be on the BrowserToolbar context menu. - if (Versions.feature11Plus) { - // There is no page menu prior to v11 resources. - MenuUtils.safeSetEnabled(aMenu, R.id.page, false); - } + MenuUtils.safeSetEnabled(aMenu, R.id.page, false); MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, false); MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, false); MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, false); @@ -3478,10 +3465,8 @@ public class BrowserApp extends GeckoApp bookmark.setChecked(tab.isBookmark()); bookmark.setTitle(resolveBookmarkTitleID(tab.isBookmark())); - if (Versions.feature11Plus) { - // We don't use icons on GB builds so not resolving icons might conserve resources. - bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark())); - } + // We don't use icons on GB builds so not resolving icons might conserve resources. + bookmark.setIcon(resolveBookmarkIconID(tab.isBookmark())); back.setEnabled(tab.canDoBack()); forward.setEnabled(tab.canDoForward()); @@ -3535,63 +3520,58 @@ public class BrowserApp extends GeckoApp // NOTE: Use MenuUtils.safeSetEnabled because some actions might // be on the BrowserToolbar context menu. - if (Versions.feature11Plus) { - MenuUtils.safeSetEnabled(aMenu, R.id.page, !isAboutHome(tab)); - } + MenuUtils.safeSetEnabled(aMenu, R.id.page, !isAboutHome(tab)); MenuUtils.safeSetEnabled(aMenu, R.id.subscribe, tab.hasFeeds()); MenuUtils.safeSetEnabled(aMenu, R.id.add_search_engine, tab.hasOpenSearch()); MenuUtils.safeSetEnabled(aMenu, R.id.add_to_launcher, !isAboutHome(tab)); - // Action providers are available only ICS+. - if (Versions.feature14Plus) { - // This provider also applies to the quick share menu item. - final GeckoActionProvider provider = ((GeckoMenuItem) share).getGeckoActionProvider(); - if (provider != null) { - Intent shareIntent = provider.getIntent(); + // This provider also applies to the quick share menu item. + final GeckoActionProvider provider = ((GeckoMenuItem) share).getGeckoActionProvider(); + if (provider != null) { + Intent shareIntent = provider.getIntent(); - // For efficiency, the provider's intent is only set once - if (shareIntent == null) { - shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - provider.setIntent(shareIntent); - } + // For efficiency, the provider's intent is only set once + if (shareIntent == null) { + shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + provider.setIntent(shareIntent); + } - // Replace the existing intent's extras - shareIntent.putExtra(Intent.EXTRA_TEXT, url); - shareIntent.putExtra(Intent.EXTRA_SUBJECT, tab.getDisplayTitle()); - shareIntent.putExtra(Intent.EXTRA_TITLE, tab.getDisplayTitle()); - shareIntent.putExtra(ShareDialog.INTENT_EXTRA_DEVICES_ONLY, true); + // Replace the existing intent's extras + shareIntent.putExtra(Intent.EXTRA_TEXT, url); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, tab.getDisplayTitle()); + shareIntent.putExtra(Intent.EXTRA_TITLE, tab.getDisplayTitle()); + shareIntent.putExtra(ShareDialog.INTENT_EXTRA_DEVICES_ONLY, true); - // Clear the existing thumbnail extras so we don't share an old thumbnail. - shareIntent.removeExtra("share_screenshot_uri"); + // Clear the existing thumbnail extras so we don't share an old thumbnail. + shareIntent.removeExtra("share_screenshot_uri"); - // Include the thumbnail of the page being shared. - BitmapDrawable drawable = tab.getThumbnail(); - if (drawable != null) { - Bitmap thumbnail = drawable.getBitmap(); + // Include the thumbnail of the page being shared. + BitmapDrawable drawable = tab.getThumbnail(); + if (drawable != null) { + Bitmap thumbnail = drawable.getBitmap(); - // Kobo uses a custom intent extra for sharing thumbnails. - if (Build.MANUFACTURER.equals("Kobo") && thumbnail != null) { - File cacheDir = getExternalCacheDir(); + // Kobo uses a custom intent extra for sharing thumbnails. + if (Build.MANUFACTURER.equals("Kobo") && thumbnail != null) { + File cacheDir = getExternalCacheDir(); - if (cacheDir != null) { - File outFile = new File(cacheDir, "thumbnail.png"); + if (cacheDir != null) { + File outFile = new File(cacheDir, "thumbnail.png"); + try { + final java.io.FileOutputStream out = new java.io.FileOutputStream(outFile); try { - final java.io.FileOutputStream out = new java.io.FileOutputStream(outFile); + thumbnail.compress(Bitmap.CompressFormat.PNG, 90, out); + } finally { try { - thumbnail.compress(Bitmap.CompressFormat.PNG, 90, out); - } finally { - try { - out.close(); - } catch (final IOException e) { /* Nothing to do here. */ } - } - } catch (FileNotFoundException e) { - Log.e(LOGTAG, "File not found", e); + out.close(); + } catch (final IOException e) { /* Nothing to do here. */ } } - - shareIntent.putExtra("share_screenshot_uri", Uri.parse(outFile.getPath())); + } catch (FileNotFoundException e) { + Log.e(LOGTAG, "File not found", e); } + + shareIntent.putExtra("share_screenshot_uri", Uri.parse(outFile.getPath())); } } } @@ -3680,18 +3660,12 @@ public class BrowserApp extends GeckoApp Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, TelemetryContract.Method.MENU, extra); tab.removeBookmark(); item.setTitle(resolveBookmarkTitleID(false)); - if (Versions.feature11Plus) { - // We don't use icons on GB builds so not resolving icons might conserve resources. - item.setIcon(resolveBookmarkIconID(false)); - } + item.setIcon(resolveBookmarkIconID(false)); } else { Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.MENU, extra); tab.addBookmark(); item.setTitle(resolveBookmarkTitleID(true)); - if (Versions.feature11Plus) { - // We don't use icons on GB builds so not resolving icons might conserve resources. - item.setIcon(resolveBookmarkIconID(true)); - } + item.setIcon(resolveBookmarkIconID(true)); } } return true; diff --git a/mobile/android/base/java/org/mozilla/gecko/DoorHangerPopup.java b/mobile/android/base/java/org/mozilla/gecko/DoorHangerPopup.java index f2a818f06d02..9aa3f96a4415 100644 --- a/mobile/android/base/java/org/mozilla/gecko/DoorHangerPopup.java +++ b/mobile/android/base/java/org/mozilla/gecko/DoorHangerPopup.java @@ -323,12 +323,7 @@ public class DoorHangerPopup extends AnchoredPopup return; } - // Make the popup focusable for accessibility. This gets done here - // so the node can be accessibility focused, but on pre-ICS devices this - // causes crashes, so it is done after the popup is shown. - if (Versions.feature14Plus) { - setFocusable(true); - } + setFocusable(true); show(); } diff --git a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java index 025321c5bfbd..855a6443af69 100644 --- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -385,9 +385,7 @@ public abstract class GeckoApp onPrepareOptionsMenu(mMenu); - if (Versions.feature11Plus) { - super.invalidateOptionsMenu(); - } + super.invalidateOptionsMenu(); } @Override @@ -852,22 +850,10 @@ public abstract class GeckoApp dialog.getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { - if (Versions.feature11Plus) { - if (listView.getCheckedItemCount() == 0) { - clearButton.setEnabled(false); - } else { - clearButton.setEnabled(true); - } - } else { - final SparseBooleanArray items = listView.getCheckedItemPositions(); - for (int j = 0; j < items.size(); j++) { - if (items.valueAt(j) == true) { - clearButton.setEnabled(true); - return; - } - } - + if (listView.getCheckedItemCount() == 0) { clearButton.setEnabled(false); + } else { + clearButton.setEnabled(true); } } }); @@ -1890,9 +1876,7 @@ public abstract class GeckoApp // Try to make it fully transparent. if (mCameraView instanceof SurfaceView) { - if (Versions.feature11Plus) { - mCameraView.setAlpha(0.0f); - } + mCameraView.setAlpha(0.0f); ViewGroup mCameraLayout = (ViewGroup) findViewById(R.id.camera_layout); // Some phones (eg. nexus S) need at least a 8x16 preview size mCameraLayout.addView(mCameraView, @@ -2129,13 +2113,6 @@ public abstract class GeckoApp refreshChrome(); } - if (!Versions.feature14Plus) { - // Update accessibility settings in case it has been changed by the - // user. On API14+, this is handled in LayerView by registering an - // accessibility state change listener. - GeckoAccessibility.updateAccessibilitySettings(this); - } - if (mAppStateListeners != null) { for (GeckoAppShell.AppStateListener listener : mAppStateListeners) { listener.onResume(); diff --git a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java index 3f0645f80471..efe9576d7d19 100644 --- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java +++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java @@ -372,10 +372,6 @@ public final class IntentHelper implements GeckoEventListener, // We create a separate method to better encapsulate the @TargetApi use. @TargetApi(15) private static void nullIntentSelector(final Intent intent) { - if (!AppConstants.Versions.feature15Plus) { - return; - } - intent.setSelector(null); } diff --git a/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java b/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java index 33fd739dabda..64f101e51504 100644 --- a/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java +++ b/mobile/android/base/java/org/mozilla/gecko/ScreenshotObserver.java @@ -56,10 +56,6 @@ public class ScreenshotObserver { * have been granted by the user. Calling this method will not prompt for permissions. */ public void start() { - if (!Versions.feature14Plus) { - return; - } - Permissions.from(context) .withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE) .doNotPrompt() @@ -83,10 +79,6 @@ public class ScreenshotObserver { } public void stop() { - if (!Versions.feature14Plus) { - return; - } - if (mediaObserver == null) { return; } diff --git a/mobile/android/base/java/org/mozilla/gecko/Tabs.java b/mobile/android/base/java/org/mozilla/gecko/Tabs.java index 75784aff048c..dc22a009259c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java +++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java @@ -866,8 +866,7 @@ public class Tabs implements GeckoEventListener { needsNewTab = (flags & LOADURL_NEW_TAB) != 0; } else { // If you modify this code, be careful that intent != null. - final boolean extraCreateNewTab = (Versions.feature12Plus) ? - intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false) : false; + final boolean extraCreateNewTab = intent.getBooleanExtra(Browser.EXTRA_CREATE_NEW_TAB, false); final Tab applicationTab = getTabForApplicationId(applicationId); if (applicationTab == null || extraCreateNewTab) { needsNewTab = true; diff --git a/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java b/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java index 2d8207c972f1..dc2403bbd18e 100644 --- a/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java +++ b/mobile/android/base/java/org/mozilla/gecko/animation/PropertyAnimator.java @@ -173,7 +173,7 @@ public class PropertyAnimator implements Runnable { // in the current view tree. OnPreDrawListener seems broken // on pre-Honeycomb devices, start animation immediatelly // in this case. - if (Versions.feature11Plus && treeObserver != null && treeObserver.isAlive()) { + if (treeObserver != null && treeObserver.isAlive()) { treeObserver.addOnPreDrawListener(preDrawListener); } else { mFramePoster.postFirstAnimationFrame(); diff --git a/mobile/android/base/java/org/mozilla/gecko/db/AbstractTransactionalProvider.java b/mobile/android/base/java/org/mozilla/gecko/db/AbstractTransactionalProvider.java index fb0b037b4e78..962081e93d9e 100644 --- a/mobile/android/base/java/org/mozilla/gecko/db/AbstractTransactionalProvider.java +++ b/mobile/android/base/java/org/mozilla/gecko/db/AbstractTransactionalProvider.java @@ -95,7 +95,7 @@ public abstract class AbstractTransactionalProvider extends ContentProvider { */ @SuppressWarnings("static-method") protected boolean shouldUseTransactions() { - return Versions.feature11Plus; + return true; } private boolean isInBatch() { diff --git a/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java b/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java index 499876fbebe0..cfa2f870fb96 100644 --- a/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java +++ b/mobile/android/base/java/org/mozilla/gecko/db/DBUtils.java @@ -409,21 +409,8 @@ public class DBUtils { statement.execute(); return 0; } - - if (AppConstants.Versions.feature11Plus) { - // This is a separate method so we can annotate it with @TargetApi. - return executeStatementReturningChangedRows(statement); - } else { - statement.execute(); - final Cursor cursor = db.rawQuery("SELECT changes()", null); - try { - cursor.moveToFirst(); - return cursor.getInt(0); - } finally { - cursor.close(); - } - - } + // This is a separate method so we can annotate it with @TargetApi. + return executeStatementReturningChangedRows(statement); } finally { statement.close(); } diff --git a/mobile/android/base/java/org/mozilla/gecko/db/SQLiteBridgeContentProvider.java b/mobile/android/base/java/org/mozilla/gecko/db/SQLiteBridgeContentProvider.java index b7e841424284..d48604f03610 100644 --- a/mobile/android/base/java/org/mozilla/gecko/db/SQLiteBridgeContentProvider.java +++ b/mobile/android/base/java/org/mozilla/gecko/db/SQLiteBridgeContentProvider.java @@ -98,10 +98,7 @@ public abstract class SQLiteBridgeContentProvider extends ContentProvider { } mDatabasePerProfile = null; } - - if (AppConstants.Versions.feature11Plus) { - super.shutdown(); - } + super.shutdown(); } @Override diff --git a/mobile/android/base/java/org/mozilla/gecko/home/HomePager.java b/mobile/android/base/java/org/mozilla/gecko/home/HomePager.java index 4a2ff4b03124..4915f0c919fc 100644 --- a/mobile/android/base/java/org/mozilla/gecko/home/HomePager.java +++ b/mobile/android/base/java/org/mozilla/gecko/home/HomePager.java @@ -213,7 +213,7 @@ public class HomePager extends ViewPager implements HomeScreen { } // Only animate on post-HC devices, when a non-null animator is given - final boolean shouldAnimate = Versions.feature11Plus && animator != null; + final boolean shouldAnimate = animator != null; final HomeAdapter adapter = new HomeAdapter(mContext, fm); adapter.setOnAddPanelListener(mAddPanelListener); diff --git a/mobile/android/base/java/org/mozilla/gecko/lwt/LightweightTheme.java b/mobile/android/base/java/org/mozilla/gecko/lwt/LightweightTheme.java index 34eb0f6fe5cf..0f27c1febc15 100644 --- a/mobile/android/base/java/org/mozilla/gecko/lwt/LightweightTheme.java +++ b/mobile/android/base/java/org/mozilla/gecko/lwt/LightweightTheme.java @@ -357,13 +357,8 @@ public class LightweightTheme implements GeckoEventListener { ViewParent parent; View curView = view; do { - if (Versions.feature11Plus) { - offsetX += (int) curView.getTranslationX() - curView.getScrollX(); - offsetY += (int) curView.getTranslationY() - curView.getScrollY(); - } else { - offsetX -= curView.getScrollX(); - offsetY -= curView.getScrollY(); - } + offsetX += (int) curView.getTranslationX() - curView.getScrollX(); + offsetY += (int) curView.getTranslationY() - curView.getScrollY(); parent = curView.getParent(); diff --git a/mobile/android/base/java/org/mozilla/gecko/menu/GeckoMenuInflater.java b/mobile/android/base/java/org/mozilla/gecko/menu/GeckoMenuInflater.java index 9741865c2fa2..dfcb31c5fb44 100644 --- a/mobile/android/base/java/org/mozilla/gecko/menu/GeckoMenuInflater.java +++ b/mobile/android/base/java/org/mozilla/gecko/menu/GeckoMenuInflater.java @@ -152,9 +152,7 @@ public class GeckoMenuInflater extends MenuInflater { .setCheckable(item.checkable) .setIcon(item.iconRes); - if (Versions.feature11Plus) { - menuItem.setShowAsAction(item.showAsAction); - } + menuItem.setShowAsAction(item.showAsAction); if (geckoItem != null) { // We don't need to allow presenter updates during inflation, diff --git a/mobile/android/base/java/org/mozilla/gecko/menu/MenuPanel.java b/mobile/android/base/java/org/mozilla/gecko/menu/MenuPanel.java index 433352d4bda5..ce4da8b7fca1 100644 --- a/mobile/android/base/java/org/mozilla/gecko/menu/MenuPanel.java +++ b/mobile/android/base/java/org/mozilla/gecko/menu/MenuPanel.java @@ -29,9 +29,7 @@ public class MenuPanel extends LinearLayout { @Override public boolean dispatchPopulateAccessibilityEvent (AccessibilityEvent event) { - if (Versions.feature14Plus) { - onPopulateAccessibilityEvent(event); - } + onPopulateAccessibilityEvent(event); return true; } diff --git a/mobile/android/base/java/org/mozilla/gecko/overlays/ui/SendTabDeviceListArrayAdapter.java b/mobile/android/base/java/org/mozilla/gecko/overlays/ui/SendTabDeviceListArrayAdapter.java index a52dd268ef97..08e9c59f55d6 100644 --- a/mobile/android/base/java/org/mozilla/gecko/overlays/ui/SendTabDeviceListArrayAdapter.java +++ b/mobile/android/base/java/org/mozilla/gecko/overlays/ui/SendTabDeviceListArrayAdapter.java @@ -71,13 +71,7 @@ public class SendTabDeviceListArrayAdapter extends ArrayAdapter { clear(); setNotifyOnChange(false); // So we don't notify for each add. - if (AppConstants.Versions.feature11Plus) { - addAll(records); - } else { - for (RemoteClient record : records) { - add(record); - } - } + addAll(records); notifyDataSetChanged(); } diff --git a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferenceFragment.java b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferenceFragment.java index a23f8a2e04ed..6be9e6ea5044 100644 --- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferenceFragment.java +++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferenceFragment.java @@ -166,7 +166,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment { } final GeckoPreferences activity = (GeckoPreferences) getActivity(); - if (Versions.feature11Plus && activity.isMultiPane()) { + if (activity.isMultiPane()) { // In a multi-pane activity, the title is "Settings", and the action // bar is along the top of the screen. We don't want to change those. activity.showBreadCrumbs(newTitle, newTitle); @@ -237,8 +237,7 @@ public class GeckoPreferenceFragment extends PreferenceFragment { // The resource was invalid. Use the default resource. Log.e(LOGTAG, "Failed to find resource: " + resourceName + ". Displaying default settings."); - boolean isMultiPane = Versions.feature11Plus && - ((GeckoPreferences) activity).isMultiPane(); + boolean isMultiPane = ((GeckoPreferences) activity).isMultiPane(); resid = isMultiPane ? R.xml.preferences_general_tablet : R.xml.preferences; } diff --git a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java index abb9947c9be1..9f5db6cd0276 100644 --- a/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java +++ b/mobile/android/base/java/org/mozilla/gecko/preferences/GeckoPreferences.java @@ -222,13 +222,11 @@ OnSharedPreferenceChangeListener } } private void updateActionBarTitle(int title) { - if (Versions.feature14Plus) { - final String newTitle = getString(title); - if (newTitle != null) { - Log.v(LOGTAG, "Setting action bar title to " + newTitle); + final String newTitle = getString(title); + if (newTitle != null) { + Log.v(LOGTAG, "Setting action bar title to " + newTitle); - setTitle(newTitle); - } + setTitle(newTitle); } } @@ -341,11 +339,9 @@ OnSharedPreferenceChangeListener // the correct Fragment resource. // Note: this seems to only be required for non-multipane devices, multipane // manages to automatically select the correct fragments. - if (Versions.feature11Plus) { - if (!getIntent().hasExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT)) { - // Set up the default fragment if there is no explicit fragment to show. - setupTopLevelFragmentIntent(); - } + if (!getIntent().hasExtra(PreferenceActivity.EXTRA_SHOW_FRAGMENT)) { + // Set up the default fragment if there is no explicit fragment to show. + setupTopLevelFragmentIntent(); } // We must call this before setTitle to avoid crashes. Most devices don't seem to care @@ -354,7 +350,7 @@ OnSharedPreferenceChangeListener // likely other strange devices (other Asus devices, some Samsungs) could do the same. super.onCreate(savedInstanceState); - if (Versions.feature11Plus && onIsMultiPane()) { + if (onIsMultiPane()) { // So that Android doesn't put the fragment title (or nothing at // all) in the action bar. updateActionBarTitle(R.string.settings_title); @@ -521,11 +517,9 @@ OnSharedPreferenceChangeListener @Override public void onPause() { // Symmetric with onResume. - if (Versions.feature11Plus) { - if (isMultiPane()) { - SharedPreferences prefs = GeckoSharedPrefs.forApp(this); - prefs.unregisterOnSharedPreferenceChangeListener(this); - } + if (isMultiPane()) { + SharedPreferences prefs = GeckoSharedPrefs.forApp(this); + prefs.unregisterOnSharedPreferenceChangeListener(this); } super.onPause(); @@ -543,14 +537,12 @@ OnSharedPreferenceChangeListener ((GeckoApplication) getApplication()).onActivityResume(this); } - if (Versions.feature11Plus) { - // Watch prefs, otherwise we don't reliably get told when they change. - // See documentation for onSharedPreferenceChange for more. - // Inexplicably only needed on tablet. - if (isMultiPane()) { - SharedPreferences prefs = GeckoSharedPrefs.forApp(this); - prefs.registerOnSharedPreferenceChangeListener(this); - } + // Watch prefs, otherwise we don't reliably get told when they change. + // See documentation for onSharedPreferenceChange for more. + // Inexplicably only needed on tablet. + if (isMultiPane()) { + SharedPreferences prefs = GeckoSharedPrefs.forApp(this); + prefs.registerOnSharedPreferenceChangeListener(this); } } diff --git a/mobile/android/base/java/org/mozilla/gecko/preferences/SyncPreference.java b/mobile/android/base/java/org/mozilla/gecko/preferences/SyncPreference.java index 2d08e8d50047..5a1cd9b1503f 100644 --- a/mobile/android/base/java/org/mozilla/gecko/preferences/SyncPreference.java +++ b/mobile/android/base/java/org/mozilla/gecko/preferences/SyncPreference.java @@ -52,13 +52,10 @@ class SyncPreference extends Preference { public void run() { setTitle(R.string.pref_sync); setSummary(R.string.pref_sync_summary); - if (AppConstants.Versions.feature11Plus) { // Cancel any pending task. Picasso.with(mContext).cancelRequest(profileAvatarTarget); // Clear previously set icon. setIcon(R.drawable.sync_avatar_default); - } - } }); return; @@ -73,11 +70,6 @@ class SyncPreference extends Preference { } }); - // Updating icons from Java is not supported prior to API 11. - if (!AppConstants.Versions.feature11Plus) { - return; - } - final ExtendedJSONObject profileJSON = fxAccount.getProfileJSON(); if (profileJSON == null) { return; diff --git a/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java b/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java index a2868c8b8088..2cafec63664a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java +++ b/mobile/android/base/java/org/mozilla/gecko/prompts/IconGridInput.java @@ -85,7 +85,7 @@ public class IconGridInput extends PromptInput implements OnItemClickListener { // Despite what the docs say, setItemChecked was not moved into the AbsListView class until sometime between // Android 2.3.7 and Android 4.0.3. For other versions the item won't be visually highlighted, BUT we really only // mSelected will still be set so that we default to its behavior. - if (Versions.feature11Plus && mSelected > -1) { + if (mSelected > -1) { view.setItemChecked(mSelected, true); } diff --git a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java index 9078801e04b1..667eb8f6c412 100644 --- a/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java +++ b/mobile/android/base/java/org/mozilla/gecko/tabqueue/TabQueueHelper.java @@ -38,7 +38,7 @@ public class TabQueueHelper { private static final String LOGTAG = "Gecko" + TabQueueHelper.class.getSimpleName(); // Disable Tab Queue for API level 10 (GB) - Bug 1206055 - public static final boolean TAB_QUEUE_ENABLED = AppConstants.Versions.feature11Plus; + public static final boolean TAB_QUEUE_ENABLED = true; public static final String FILE_NAME = "tab_queue_url_list.json"; public static final String LOAD_URLS_ACTION = "TAB_QUEUE_LOAD_URLS_ACTION"; diff --git a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java index 3573b5f346b5..af380c610b98 100644 --- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java +++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsGridLayout.java @@ -294,9 +294,7 @@ class TabsGridLayout extends GridView ((TabsLayoutItemView) tabView).setChecked(checked); } // setItemChecked doesn't exist until API 11, despite what the API docs say! - if (AppConstants.Versions.feature11Plus) { - setItemChecked(i, checked); - } + setItemChecked(i, checked); } } }); diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java index cf5d203d8c4b..3e5f7411f64c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java @@ -191,9 +191,7 @@ public abstract class BrowserToolbar extends ThemedRelativeLayout tabsButton = (ThemedImageButton) findViewById(R.id.tabs); tabsCounter = (TabCounter) findViewById(R.id.tabs_counter); - if (Versions.feature11Plus) { - tabsCounter.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } + tabsCounter.setLayerType(View.LAYER_TYPE_SOFTWARE, null); menuButton = (ThemedFrameLayout) findViewById(R.id.menu); menuIcon = (ThemedImageView) findViewById(R.id.menu_icon); diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/CanvasDelegate.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/CanvasDelegate.java index 7cc959f17b49..55567fba300a 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/CanvasDelegate.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/CanvasDelegate.java @@ -48,20 +48,8 @@ class CanvasDelegate { if (path != null && !path.isEmpty()) { // ICS added double-buffering, which made it easier for drawing the Path directly over the DST. // In pre-ICS, drawPath() doesn't seem to use ARGB_8888 mode for performance, hence transparency is not preserved. - if (Versions.feature14Plus) { - mPaint.setXfermode(mMode); - canvas.drawPath(path, mPaint); - } else { - // Allocate a bitmap and draw the masking/clipping path. - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - (new Canvas(bitmap)).drawPath(path, mPaint); - - mPaint.setXfermode(mMode); - canvas.drawBitmap(bitmap, 0, 0, mPaint); - bitmap.recycle(); - - mPaint.setXfermode(null); - } + mPaint.setXfermode(mMode); + canvas.drawPath(path, mPaint); } // Restore the canvas. diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java index 26f6d91233f0..14230a2ecb68 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java @@ -228,11 +228,9 @@ public class SiteIdentityPopup extends AnchoredPopup implements GeckoEventListen } else { password = login.getString("password"); } - if (AppConstants.Versions.feature11Plus) { - manager.setPrimaryClip(ClipData.newPlainText("password", password)); - } else { - manager.setText(password); - } + + manager.setPrimaryClip(ClipData.newPlainText("password", password)); + SnackbarBuilder.builder(activity) .message(R.string.doorhanger_login_select_toast_copy) .duration(Snackbar.LENGTH_SHORT) diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java index da8b696c2657..b385f815a3a5 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java @@ -618,8 +618,7 @@ public class ToolbarEditText extends CustomEditText } if ((keyCode == KeyEvent.KEYCODE_DEL || - (Versions.feature11Plus && - keyCode == KeyEvent.KEYCODE_FORWARD_DEL)) && + (keyCode == KeyEvent.KEYCODE_FORWARD_DEL)) && removeAutocomplete(getText())) { // Delete autocomplete text when backspacing or forward deleting. return true; diff --git a/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java b/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java index 911c137d0581..67f1bcd1d81c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java +++ b/mobile/android/base/java/org/mozilla/gecko/widget/DateTimePicker.java @@ -101,82 +101,45 @@ public class DateTimePicker extends FrameLayout { public void onValueChange(NumberPicker picker, int oldVal, int newVal) { updateInputState(); mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis()); - final boolean newBehavior = Versions.feature11Plus; - if (newBehavior) { - if (DEBUG) { - Log.d(LOGTAG, "SDK version > 10, using new behavior"); - } + if (DEBUG) { + Log.d(LOGTAG, "SDK version > 10, using new behavior"); + } - // The native date picker widget on these SDKs increments - // the next field when one field reaches the maximum. - if (picker == mDaySpinner && mDayEnabled) { - int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH); - int old = mTempDate.get(Calendar.DAY_OF_MONTH); - setTempDate(Calendar.DAY_OF_MONTH, old, newVal, 1, maxDayOfMonth); - } else if (picker == mMonthSpinner && mMonthEnabled) { - int old = mTempDate.get(Calendar.MONTH); - setTempDate(Calendar.MONTH, old, newVal, Calendar.JANUARY, Calendar.DECEMBER); - } else if (picker == mWeekSpinner) { - int old = mTempDate.get(Calendar.WEEK_OF_YEAR); - int maxWeekOfYear = mTempDate.getActualMaximum(Calendar.WEEK_OF_YEAR); - setTempDate(Calendar.WEEK_OF_YEAR, old, newVal, 0, maxWeekOfYear); - } else if (picker == mYearSpinner && mYearEnabled) { - int month = mTempDate.get(Calendar.MONTH); - mTempDate.set(Calendar.YEAR, newVal); - // Changing the year shouldn't change the month. (in case of non-leap year a Feb 29) - // change the day instead; - if (month != mTempDate.get(Calendar.MONTH)) { - mTempDate.set(Calendar.MONTH, month); - mTempDate.set(Calendar.DAY_OF_MONTH, - mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - } else if (picker == mHourSpinner && mHourEnabled) { - if (mIs12HourMode) { - setTempDate(Calendar.HOUR, oldVal, newVal, 1, 12); - } else { - setTempDate(Calendar.HOUR_OF_DAY, oldVal, newVal, 0, 23); - } - } else if (picker == mMinuteSpinner && mMinuteEnabled) { - setTempDate(Calendar.MINUTE, oldVal, newVal, 0, 59); - } else if (picker == mAMPMSpinner && mHourEnabled) { - mTempDate.set(Calendar.AM_PM, newVal); - } else { - throw new IllegalArgumentException(); + // The native date picker widget on these SDKs increments + // the next field when one field reaches the maximum. + if (picker == mDaySpinner && mDayEnabled) { + int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH); + int old = mTempDate.get(Calendar.DAY_OF_MONTH); + setTempDate(Calendar.DAY_OF_MONTH, old, newVal, 1, maxDayOfMonth); + } else if (picker == mMonthSpinner && mMonthEnabled) { + int old = mTempDate.get(Calendar.MONTH); + setTempDate(Calendar.MONTH, old, newVal, Calendar.JANUARY, Calendar.DECEMBER); + } else if (picker == mWeekSpinner) { + int old = mTempDate.get(Calendar.WEEK_OF_YEAR); + int maxWeekOfYear = mTempDate.getActualMaximum(Calendar.WEEK_OF_YEAR); + setTempDate(Calendar.WEEK_OF_YEAR, old, newVal, 0, maxWeekOfYear); + } else if (picker == mYearSpinner && mYearEnabled) { + int month = mTempDate.get(Calendar.MONTH); + mTempDate.set(Calendar.YEAR, newVal); + // Changing the year shouldn't change the month. (in case of non-leap year a Feb 29) + // change the day instead; + if (month != mTempDate.get(Calendar.MONTH)) { + mTempDate.set(Calendar.MONTH, month); + mTempDate.set(Calendar.DAY_OF_MONTH, + mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH)); } + } else if (picker == mHourSpinner && mHourEnabled) { + if (mIs12HourMode) { + setTempDate(Calendar.HOUR, oldVal, newVal, 1, 12); + } else { + setTempDate(Calendar.HOUR_OF_DAY, oldVal, newVal, 0, 23); + } + } else if (picker == mMinuteSpinner && mMinuteEnabled) { + setTempDate(Calendar.MINUTE, oldVal, newVal, 0, 59); + } else if (picker == mAMPMSpinner && mHourEnabled) { + mTempDate.set(Calendar.AM_PM, newVal); } else { - if (DEBUG) Log.d(LOGTAG, "Sdk version < 10, using old behavior"); - if (picker == mDaySpinner && mDayEnabled) { - mTempDate.set(Calendar.DAY_OF_MONTH, newVal); - } else if (picker == mMonthSpinner && mMonthEnabled) { - mTempDate.set(Calendar.MONTH, newVal); - if (mTempDate.get(Calendar.MONTH) == newVal + 1) { - mTempDate.set(Calendar.MONTH, newVal); - mTempDate.set(Calendar.DAY_OF_MONTH, - mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - } else if (picker == mWeekSpinner) { - mTempDate.set(Calendar.WEEK_OF_YEAR, newVal); - } else if (picker == mYearSpinner && mYearEnabled) { - int month = mTempDate.get(Calendar.MONTH); - mTempDate.set(Calendar.YEAR, newVal); - if (month != mTempDate.get(Calendar.MONTH)) { - mTempDate.set(Calendar.MONTH, month); - mTempDate.set(Calendar.DAY_OF_MONTH, - mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH)); - } - } else if (picker == mHourSpinner && mHourEnabled) { - if (mIs12HourMode) { - mTempDate.set(Calendar.HOUR, newVal); - } else { - mTempDate.set(Calendar.HOUR_OF_DAY, newVal); - } - } else if (picker == mMinuteSpinner && mMinuteEnabled) { - mTempDate.set(Calendar.MINUTE, newVal); - } else if (picker == mAMPMSpinner && mHourEnabled) { - mTempDate.set(Calendar.AM_PM, newVal); - } else { - throw new IllegalArgumentException(); - } + throw new IllegalArgumentException(); } setDate(mTempDate); if (mDayEnabled) { diff --git a/mobile/android/base/java/org/mozilla/gecko/widget/RoundedCornerLayout.java b/mobile/android/base/java/org/mozilla/gecko/widget/RoundedCornerLayout.java index 494633b2c5fe..a102981eed07 100644 --- a/mobile/android/base/java/org/mozilla/gecko/widget/RoundedCornerLayout.java +++ b/mobile/android/base/java/org/mozilla/gecko/widget/RoundedCornerLayout.java @@ -41,7 +41,7 @@ public class RoundedCornerLayout extends LinearLayout { private void init(Context context) { // Bug 1201081 - clipPath with hardware acceleration crashes on r11-18. - cannotClipPath = AppConstants.Versions.feature11Plus && !AppConstants.Versions.feature19Plus; + cannotClipPath = !AppConstants.Versions.feature19Plus; final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java index d49ca599b69b..8d4c0fb2a1be 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAccessibility.java @@ -93,16 +93,12 @@ public class GeckoAccessibility { event.setItemCount(message.optInt("itemCount", -1)); event.setCurrentItemIndex(message.optInt("currentItemIndex", -1)); event.setBeforeText(message.optString("beforeText")); - if (Versions.feature14Plus) { - event.setToIndex(message.optInt("toIndex", -1)); - event.setScrollable(message.optBoolean("scrollable")); - event.setScrollX(message.optInt("scrollX", -1)); - event.setScrollY(message.optInt("scrollY", -1)); - } - if (Versions.feature15Plus) { - event.setMaxScrollX(message.optInt("maxScrollX", -1)); - event.setMaxScrollY(message.optInt("maxScrollY", -1)); - } + event.setToIndex(message.optInt("toIndex", -1)); + event.setScrollable(message.optBoolean("scrollable")); + event.setScrollX(message.optInt("scrollX", -1)); + event.setScrollY(message.optInt("scrollY", -1)); + event.setMaxScrollX(message.optInt("maxScrollX", -1)); + event.setMaxScrollY(message.optInt("maxScrollY", -1)); } private static void sendDirectAccessibilityEvent(int eventType, JSONObject message) { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java index f7132cbb4bb2..01deb50fa1bc 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoAppShell.java @@ -824,21 +824,9 @@ public class GeckoAppShell @JNITarget static public int getPreferredIconSize() { - if (Versions.feature11Plus) { - ActivityManager am = (ActivityManager) - getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); - return am.getLauncherLargeIconSize(); - } else { - switch (getDpi()) { - case DisplayMetrics.DENSITY_MEDIUM: - return 48; - case DisplayMetrics.DENSITY_XHIGH: - return 96; - case DisplayMetrics.DENSITY_HIGH: - default: - return 72; - } - } + ActivityManager am = (ActivityManager) + getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); + return am.getLauncherLargeIconSize(); } @WrapForJNI(calledFrom = "gecko") diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java index 49866802af7f..775568f671e3 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoEditable.java @@ -614,10 +614,8 @@ final class GeckoEditable extends JNIObject float tpUnderlineThickness = 0.0f; // These TextPaint fields only exist on Android ICS+ and are not in the SDK. - if (Versions.feature14Plus) { - tpUnderlineColor = (Integer)getField(tp, "underlineColor", 0); - tpUnderlineThickness = (Float)getField(tp, "underlineThickness", 0.0f); - } + tpUnderlineColor = (Integer)getField(tp, "underlineColor", 0); + tpUnderlineThickness = (Float)getField(tp, "underlineThickness", 0.0f); if (tpUnderlineColor != 0) { rangeStyles |= IME_RANGE_UNDERLINE | IME_RANGE_LINECOLOR; rangeLineColor = tpUnderlineColor; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java index 6b4ee495acb9..f39b8492cffa 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoInputConnection.java @@ -994,10 +994,10 @@ class GeckoInputConnection if (typeHint != null && (typeHint.equalsIgnoreCase("date") || typeHint.equalsIgnoreCase("time") || - (Versions.feature11Plus && (typeHint.equalsIgnoreCase("datetime") || - typeHint.equalsIgnoreCase("month") || - typeHint.equalsIgnoreCase("week") || - typeHint.equalsIgnoreCase("datetime-local"))))) { + typeHint.equalsIgnoreCase("datetime") || + typeHint.equalsIgnoreCase("month") || + typeHint.equalsIgnoreCase("week") || + typeHint.equalsIgnoreCase("datetime-local"))) { state = IME_STATE_DISABLED; } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java index 38adea1e4684..56da085aa8c9 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java @@ -160,11 +160,7 @@ public class LayerView extends FrameLayout { mPaintState = PAINT_START; mFullScreenState = FullScreenState.NONE; - if (Versions.feature14Plus) { - mOverscroll = new OverscrollEdgeEffect(this); - } else { - mOverscroll = null; - } + mOverscroll = new OverscrollEdgeEffect(this); } public LayerView(Context context) { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java index 8158b7661617..02b07674f15a 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/Clipboard.java @@ -63,26 +63,19 @@ public final class Clipboard { public static void setText(final CharSequence text) { ThreadUtils.postToBackgroundThread(new Runnable() { @Override - @SuppressWarnings("deprecation") public void run() { // In API Level 11 and above, CLIPBOARD_SERVICE returns android.content.ClipboardManager, // which is a subclass of android.text.ClipboardManager. - if (Versions.feature11Plus) { - final android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - final ClipData clip = ClipData.newPlainText("Text", text); - try { - cm.setPrimaryClip(clip); - } catch (NullPointerException e) { - // Bug 776223: This is a Samsung clipboard bug. setPrimaryClip() can throw - // a NullPointerException if Samsung's /data/clipboard directory is full. - // Fortunately, the text is still successfully copied to the clipboard. - } - return; + final android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); + final ClipData clip = ClipData.newPlainText("Text", text); + try { + cm.setPrimaryClip(clip); + } catch (NullPointerException e) { + // Bug 776223: This is a Samsung clipboard bug. setPrimaryClip() can throw + // a NullPointerException if Samsung's /data/clipboard directory is full. + // Fortunately, the text is still successfully copied to the clipboard. } - - // Deprecated. - android.text.ClipboardManager cm = (android.text.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - cm.setText(text); + return; } }); } @@ -92,14 +85,8 @@ public final class Clipboard { */ @WrapForJNI(calledFrom = "gecko") public static boolean hasText() { - if (Versions.feature11Plus) { - android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - return cm.hasPrimaryClip(); - } - - // Deprecated. - android.text.ClipboardManager cm = (android.text.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - return cm.hasText(); + android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); + return cm.hasPrimaryClip(); } /** @@ -117,19 +104,12 @@ public final class Clipboard { */ @SuppressWarnings("deprecation") static String getClipboardTextImpl() { - if (Versions.feature11Plus) { - android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - if (cm.hasPrimaryClip()) { - ClipData clip = cm.getPrimaryClip(); - if (clip != null) { - ClipData.Item item = clip.getItemAt(0); - return item.coerceToText(mContext).toString(); - } - } - } else { - android.text.ClipboardManager cm = (android.text.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); - if (cm.hasText()) { - return cm.getText().toString(); + android.content.ClipboardManager cm = (android.content.ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); + if (cm.hasPrimaryClip()) { + ClipData clip = cm.getPrimaryClip(); + if (clip != null) { + ClipData.Item item = clip.getItemAt(0); + return item.coerceToText(mContext).toString(); } } return null; diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java index 2c2142ef4dd1..3e83d079c04d 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/StringUtils.java @@ -235,39 +235,7 @@ public class StringUtils { * @return a set of decoded names */ public static Set getQueryParameterNames(Uri uri) { - if (Versions.feature11Plus) { - return uri.getQueryParameterNames(); - } - - // Logic below copied from Uri.java included with Android 5.0.0. - if (uri.isOpaque()) { - throw new UnsupportedOperationException("This isn't a hierarchical URI."); - } - - String query = uri.getEncodedQuery(); - if (query == null) { - return Collections.emptySet(); - } - - Set names = new LinkedHashSet(); - int start = 0; - do { - int next = query.indexOf('&', start); - int end = (next == -1) ? query.length() : next; - - int separator = query.indexOf('=', start); - if (separator > end || separator == -1) { - separator = end; - } - - String name = query.substring(start, separator); - names.add(Uri.decode(name)); - - // Move start to end of name. - start = end + 1; - } while (start < query.length()); - - return Collections.unmodifiableSet(names); + return uri.getQueryParameterNames(); } public static String safeSubstring(@NonNull final String str, final int start, final int end) { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java index 315ab46ac763..5298f846af0f 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/util/WindowUtils.java @@ -37,7 +37,7 @@ public class WindowUtils { display.getRealMetrics(realMetrics); return Math.max(realMetrics.widthPixels, realMetrics.heightPixels); - } else if (Versions.feature14Plus) { + } else { int tempWidth; int tempHeight; try { @@ -54,9 +54,6 @@ public class WindowUtils { return Math.max(tempWidth, tempHeight); - } else { - // This should be close, as lower API devices should not have window navigation bars. - return Math.max(display.getWidth(), display.getHeight()); } } } diff --git a/mobile/android/search/java/org/mozilla/search/PostSearchFragment.java b/mobile/android/search/java/org/mozilla/search/PostSearchFragment.java index 9343c6a24440..8a26c49dd24a 100644 --- a/mobile/android/search/java/org/mozilla/search/PostSearchFragment.java +++ b/mobile/android/search/java/org/mozilla/search/PostSearchFragment.java @@ -152,9 +152,7 @@ public class PostSearchFragment extends Fragment { i.addCategory(Intent.CATEGORY_BROWSABLE); i.setComponent(null); - if (AppConstants.Versions.feature15Plus) { - i.setSelector(null); - } + i.setSelector(null); startActivity(i); return true; diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/background/common/GlobalConstants.java b/mobile/android/services/src/main/java/org/mozilla/gecko/background/common/GlobalConstants.java index d17139dfb665..d661e62dc7d0 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/background/common/GlobalConstants.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/background/common/GlobalConstants.java @@ -54,34 +54,19 @@ public class GlobalConstants { "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", // 20+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", // 20+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", // 11+ - + // For Sync 1.1. "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", // 9+ "TLS_RSA_WITH_AES_128_CBC_SHA", // 9+ }; - } else if (Versions.feature11Plus) { + } else { DEFAULT_CIPHER_SUITES = new String[] { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", // 11+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", // 11+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", // 11+ - - // For Sync 1.1. - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", // 9+ - "TLS_RSA_WITH_AES_128_CBC_SHA", // 9+ - }; - } else { // 9+ - // Fall back to the only half-decent cipher suites supported on Gingerbread. - // N.B., there appears to be *no overlap* between the ELB 2015-05 default - // suites and Gingerbread. A custom configuration is needed if moving beyond - // the 2015-03 defaults. - DEFAULT_CIPHER_SUITES = new String[] - { - // This is for Sync 1.5 on ELB 2015-03. - "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", - "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - // This is for Sync 1.1. + // For Sync 1.1. "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", // 9+ "TLS_RSA_WITH_AES_128_CBC_SHA", // 9+ }; diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java index cc28ad460cb8..4bb929f0ae7b 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusActivity.java @@ -143,13 +143,9 @@ public class FxAccountStatusActivity extends LocaleAwareAppCompatActivity { * See http://stackoverflow.com/questions/14910536/android-dialog-theme-makes-icon-too-light/14910945#14910945. */ final int icon; - if (AppConstants.Versions.feature11Plus) { - final TypedValue typedValue = new TypedValue(); - activity.getTheme().resolveAttribute(android.R.attr.alertDialogIcon, typedValue, true); - icon = typedValue.resourceId; - } else { - icon = android.R.drawable.ic_dialog_alert; - } + final TypedValue typedValue = new TypedValue(); + activity.getTheme().resolveAttribute(android.R.attr.alertDialogIcon, typedValue, true); + icon = typedValue.resourceId; final AlertDialog dialog = new AlertDialog.Builder(activity) .setTitle(R.string.fxaccount_remove_account_dialog_title) diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java index 876fe0a1cf1a..a30b92e5f363 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/FxAccountStatusFragment.java @@ -623,12 +623,6 @@ public class FxAccountStatusFragment profilePreference.setTitle(fxAccount.getEmail()); } - // Icon update from java is not supported prior to API 11, skip the avatar image fetch and update for older device. - if (!AppConstants.Versions.feature11Plus) { - Logger.info(LOG_TAG, "Skipping profile image fetch for older pre-API 11 devices."); - return; - } - // Avatar URI empty, skip profile image fetch. final String avatarURI = profileJSON.getString(FxAccountConstants.KEY_PROFILE_JSON_AVATAR); if (TextUtils.isEmpty(avatarURI)) { diff --git a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/PicassoPreferenceIconTarget.java b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/PicassoPreferenceIconTarget.java index bc15f085ae8e..f71d3ed1cd43 100644 --- a/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/PicassoPreferenceIconTarget.java +++ b/mobile/android/services/src/main/java/org/mozilla/gecko/fxa/activities/PicassoPreferenceIconTarget.java @@ -38,11 +38,6 @@ public class PicassoPreferenceIconTarget implements Target { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { - // Updating icons from Java is not supported prior to API 11. - if (!AppConstants.Versions.feature11Plus) { - return; - } - final Drawable drawable; if (cornerRadius > 0) { final RoundedBitmapDrawable roundedBitmapDrawable; @@ -58,19 +53,11 @@ public class PicassoPreferenceIconTarget implements Target { @Override public void onBitmapFailed(Drawable errorDrawable) { - // Updating icons from Java is not supported prior to API 11. - if (!AppConstants.Versions.feature11Plus) { - return; - } preference.setIcon(errorDrawable); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { - // Updating icons from Java is not supported prior to API 11. - if (!AppConstants.Versions.feature11Plus) { - return; - } preference.setIcon(placeHolderDrawable); } } From 9c31ea2777f18a1a561a3c8daf6263301290367a Mon Sep 17 00:00:00 2001 From: Wei-Cheng Pan Date: Mon, 3 Oct 2016 14:53:30 +0800 Subject: [PATCH 33/37] Bug 1307052 - Use MOZ_MUST_USE in netwerk/protocol/about r=valentin MozReview-Commit-ID: 7G0vF9Jt7Hj --HG-- extra : rebase_source : 03cb108736d9922e9569f718cf7ad3027ae60b2a --- netwerk/protocol/about/nsAboutBloat.h | 2 +- netwerk/protocol/about/nsAboutCache.cpp | 20 ++++++++++++++---- netwerk/protocol/about/nsAboutCache.h | 14 ++++++------- netwerk/protocol/about/nsAboutCacheEntry.h | 21 ++++++++++--------- netwerk/protocol/about/nsAboutProtocolUtils.h | 2 +- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/netwerk/protocol/about/nsAboutBloat.h b/netwerk/protocol/about/nsAboutBloat.h index 4d9000c9d787..7cadd266f1da 100644 --- a/netwerk/protocol/about/nsAboutBloat.h +++ b/netwerk/protocol/about/nsAboutBloat.h @@ -17,7 +17,7 @@ public: nsAboutBloat() {} - static nsresult + static MOZ_MUST_USE nsresult Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); private: diff --git a/netwerk/protocol/about/nsAboutCache.cpp b/netwerk/protocol/about/nsAboutCache.cpp index 1247e4813141..f983a520eff3 100644 --- a/netwerk/protocol/about/nsAboutCache.cpp +++ b/netwerk/protocol/about/nsAboutCache.cpp @@ -128,7 +128,10 @@ nsAboutCache::Channel::Init(nsIURI* aURI, nsILoadInfo* aLoadInfo) mBuffer.AppendLiteral("\">Back to overview"); } - FlushBuffer(); + rv = FlushBuffer(); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to flush buffer"); + } return NS_OK; } @@ -245,7 +248,10 @@ nsAboutCache::Channel::FireVisitStorage() free(escaped); } - FlushBuffer(); + rv = FlushBuffer(); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to flush buffer"); + } // Simulate finish of a visit cycle, this tries the next storage // or closes the output stream (i.e. the UI loader will stop spinning) @@ -371,7 +377,10 @@ nsAboutCache::Channel::OnCacheStorageInfo(uint32_t aEntryCount, uint64_t aConsum // The entries header is added on encounter of the first entry mEntriesHeaderAdded = false; - FlushBuffer(); + nsresult rv = FlushBuffer(); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to flush buffer"); + } if (mOverview) { // OnCacheEntryVisitCompleted() is not called when we do not iterate @@ -528,7 +537,10 @@ nsAboutCache::Channel::OnCacheEntryVisitCompleted() // We are done! mBuffer.AppendLiteral("\n" "\n"); - FlushBuffer(); + nsresult rv = FlushBuffer(); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to flush buffer"); + } mStream->Close(); return NS_OK; diff --git a/netwerk/protocol/about/nsAboutCache.h b/netwerk/protocol/about/nsAboutCache.h index 1f404f357aaf..c2d1af85054b 100644 --- a/netwerk/protocol/about/nsAboutCache.h +++ b/netwerk/protocol/about/nsAboutCache.h @@ -48,10 +48,10 @@ public: nsAboutCache() {} - static nsresult + static MOZ_MUST_USE nsresult Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); - static nsresult + static MOZ_MUST_USE nsresult GetStorage(nsACString const & storageName, nsILoadContextInfo* loadInfo, nsICacheStorage **storage); @@ -74,13 +74,13 @@ protected: virtual ~Channel() {} public: - nsresult Init(nsIURI* aURI, nsILoadInfo* aLoadInfo); - nsresult ParseURI(nsIURI * uri, nsACString & storage); + MOZ_MUST_USE nsresult Init(nsIURI* aURI, nsILoadInfo* aLoadInfo); + MOZ_MUST_USE nsresult ParseURI(nsIURI * uri, nsACString & storage); // Finds a next storage we wish to visit (we use this method // even there is a specified storage name, which is the only // one in the list then.) Posts FireVisitStorage() when found. - nsresult VisitNextStorage(); + MOZ_MUST_USE nsresult VisitNextStorage(); // Helper method that calls VisitStorage() for the current storage. // When it fails, OnCacheEntryVisitCompleted is simulated to close // the output stream and thus the about:cache channel. @@ -88,13 +88,13 @@ protected: // Kiks the visit cycle for the given storage, names can be: // "disk", "memory", "appcache" // Note: any newly added storage type has to be manually handled here. - nsresult VisitStorage(nsACString const & storageName); + MOZ_MUST_USE nsresult VisitStorage(nsACString const & storageName); // Writes content of mBuffer to mStream and truncates // the buffer. It may fail when the input stream is closed by canceling // the input stream channel. It can be used to stop the cache iteration // process. - nsresult FlushBuffer(); + MOZ_MUST_USE nsresult FlushBuffer(); // Whether we are showing overview status of all available // storages. diff --git a/netwerk/protocol/about/nsAboutCacheEntry.h b/netwerk/protocol/about/nsAboutCacheEntry.h index 973b313312c3..44a78760be33 100644 --- a/netwerk/protocol/about/nsAboutCacheEntry.h +++ b/netwerk/protocol/about/nsAboutCacheEntry.h @@ -52,19 +52,20 @@ private: virtual ~Channel() {} public: - nsresult Init(nsIURI* uri, nsILoadInfo* aLoadInfo); + MOZ_MUST_USE nsresult Init(nsIURI* uri, nsILoadInfo* aLoadInfo); - nsresult GetContentStream(nsIURI *, nsIInputStream **); - nsresult OpenCacheEntry(nsIURI *); - nsresult OpenCacheEntry(); - nsresult WriteCacheEntryDescription(nsICacheEntry *); - nsresult WriteCacheEntryUnavailable(); - nsresult ParseURI(nsIURI *uri, nsACString &storageName, - nsILoadContextInfo **loadInfo, - nsCString &enahnceID, nsIURI **cacheUri); + MOZ_MUST_USE nsresult GetContentStream(nsIURI *, nsIInputStream **); + MOZ_MUST_USE nsresult OpenCacheEntry(nsIURI *); + MOZ_MUST_USE nsresult OpenCacheEntry(); + MOZ_MUST_USE nsresult WriteCacheEntryDescription(nsICacheEntry *); + MOZ_MUST_USE nsresult WriteCacheEntryUnavailable(); + MOZ_MUST_USE nsresult ParseURI(nsIURI *uri, nsACString &storageName, + nsILoadContextInfo **loadInfo, + nsCString &enahnceID, + nsIURI **cacheUri); void CloseContent(); - static nsresult + static MOZ_MUST_USE nsresult PrintCacheData(nsIInputStream *aInStream, void *aClosure, const char *aFromSegment, diff --git a/netwerk/protocol/about/nsAboutProtocolUtils.h b/netwerk/protocol/about/nsAboutProtocolUtils.h index 41ad8fdd1afe..c5946412b046 100644 --- a/netwerk/protocol/about/nsAboutProtocolUtils.h +++ b/netwerk/protocol/about/nsAboutProtocolUtils.h @@ -12,7 +12,7 @@ #include "nsServiceManagerUtils.h" #include "prtime.h" -inline nsresult +inline MOZ_MUST_USE nsresult NS_GetAboutModuleName(nsIURI *aAboutURI, nsCString& aModule) { #ifdef DEBUG From d82b36b981a3fcafada807bf57ca0e1fb14491e1 Mon Sep 17 00:00:00 2001 From: Wei-Cheng Pan Date: Mon, 3 Oct 2016 14:54:01 +0800 Subject: [PATCH 34/37] Bug 1307331 - Use MOZ_MUST_USE in netwerk/protocol/data r=valentin MozReview-Commit-ID: IikVyLjQN31 --HG-- extra : rebase_source : 574d28a6534c4a0e0ed92576896d9404e671fa7d --- netwerk/ipc/NeckoParent.cpp | 2 +- netwerk/protocol/data/DataChannelParent.h | 2 +- netwerk/protocol/data/nsDataChannel.h | 5 +++-- netwerk/protocol/data/nsDataHandler.h | 12 ++++++------ 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/netwerk/ipc/NeckoParent.cpp b/netwerk/ipc/NeckoParent.cpp index 595745cc8600..7a673f85d98a 100644 --- a/netwerk/ipc/NeckoParent.cpp +++ b/netwerk/ipc/NeckoParent.cpp @@ -415,7 +415,7 @@ NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor, const uint32_t& channelId) { DataChannelParent* p = static_cast(actor); - p->Init(channelId); + MOZ_DIAGNOSTIC_ASSERT(p->Init(channelId)); return true; } diff --git a/netwerk/protocol/data/DataChannelParent.h b/netwerk/protocol/data/DataChannelParent.h index e75fa737ed47..415672a44445 100644 --- a/netwerk/protocol/data/DataChannelParent.h +++ b/netwerk/protocol/data/DataChannelParent.h @@ -27,7 +27,7 @@ public: NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER - bool Init(const uint32_t& aArgs); + MOZ_MUST_USE bool Init(const uint32_t& aArgs); private: ~DataChannelParent(); diff --git a/netwerk/protocol/data/nsDataChannel.h b/netwerk/protocol/data/nsDataChannel.h index 20bf861fed5e..c986fba1e99d 100644 --- a/netwerk/protocol/data/nsDataChannel.h +++ b/netwerk/protocol/data/nsDataChannel.h @@ -20,8 +20,9 @@ public: } protected: - virtual nsresult OpenContentStream(bool async, nsIInputStream **result, - nsIChannel** channel); + virtual MOZ_MUST_USE nsresult OpenContentStream(bool async, + nsIInputStream **result, + nsIChannel** channel); }; #endif /* nsDataChannel_h___ */ diff --git a/netwerk/protocol/data/nsDataHandler.h b/netwerk/protocol/data/nsDataHandler.h index e46190c249e5..75f873e17418 100644 --- a/netwerk/protocol/data/nsDataHandler.h +++ b/netwerk/protocol/data/nsDataHandler.h @@ -24,18 +24,18 @@ public: nsDataHandler(); // Define a Create method to be used with a factory: - static nsresult + static MOZ_MUST_USE nsresult Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult); // Parse a data: URI and return the individual parts // (the given spec will temporarily be modified but will be returned // to the original before returning) // contentCharset and dataBuffer can be nullptr if they are not needed. - static nsresult ParseURI(nsCString& spec, - nsCString& contentType, - nsCString* contentCharset, - bool& isBase64, - nsCString* dataBuffer); + static MOZ_MUST_USE nsresult ParseURI(nsCString& spec, + nsCString& contentType, + nsCString* contentCharset, + bool& isBase64, + nsCString* dataBuffer); }; #endif /* nsDataHandler_h___ */ From bb8702d5d8d4929c768d0747c270e41ab3269e8f Mon Sep 17 00:00:00 2001 From: Wei-Cheng Pan Date: Mon, 3 Oct 2016 14:54:10 +0800 Subject: [PATCH 35/37] Bug 1307360 - Use MOZ_MUST_USE in netwerk/protocol/device r=valentin MozReview-Commit-ID: Kc7a7GksoZl --HG-- extra : rebase_source : 3c42b88d4780c21401a1e10c87d3e51b83faba5c --- netwerk/protocol/device/AndroidCaptureProvider.h | 2 +- netwerk/protocol/device/CameraStreamImpl.h | 2 +- netwerk/protocol/device/nsDeviceCaptureProvider.h | 6 +++--- netwerk/protocol/device/nsDeviceChannel.h | 8 ++++---- netwerk/protocol/device/nsDeviceProtocolHandler.h | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/netwerk/protocol/device/AndroidCaptureProvider.h b/netwerk/protocol/device/AndroidCaptureProvider.h index 099f3f4312a1..dd99ea54115b 100644 --- a/netwerk/protocol/device/AndroidCaptureProvider.h +++ b/netwerk/protocol/device/AndroidCaptureProvider.h @@ -25,7 +25,7 @@ class AndroidCaptureProvider final : public nsDeviceCaptureProvider { NS_DECL_THREADSAFE_ISUPPORTS - nsresult Init(nsACString& aContentType, nsCaptureParams* aParams, nsIInputStream** aStream) override; + MOZ_MUST_USE nsresult Init(nsACString& aContentType, nsCaptureParams* aParams, nsIInputStream** aStream) override; static AndroidCaptureProvider* sInstance; }; diff --git a/netwerk/protocol/device/CameraStreamImpl.h b/netwerk/protocol/device/CameraStreamImpl.h index f5ea97cb587e..93037caf66f2 100644 --- a/netwerk/protocol/device/CameraStreamImpl.h +++ b/netwerk/protocol/device/CameraStreamImpl.h @@ -37,7 +37,7 @@ public: return mCallback; } - bool Init(const nsCString& contentType, const uint32_t& camera, const uint32_t& width, const uint32_t& height, FrameCallback* callback); + MOZ_MUST_USE bool Init(const nsCString& contentType, const uint32_t& camera, const uint32_t& width, const uint32_t& height, FrameCallback* callback); void Close(); uint32_t GetWidth() { return mWidth; } diff --git a/netwerk/protocol/device/nsDeviceCaptureProvider.h b/netwerk/protocol/device/nsDeviceCaptureProvider.h index edfe378fcb50..024f6689d616 100644 --- a/netwerk/protocol/device/nsDeviceCaptureProvider.h +++ b/netwerk/protocol/device/nsDeviceCaptureProvider.h @@ -23,9 +23,9 @@ struct nsCaptureParams { class nsDeviceCaptureProvider : public nsISupports { public: - virtual nsresult Init(nsACString& aContentType, - nsCaptureParams* aParams, - nsIInputStream** aStream) = 0; + virtual MOZ_MUST_USE nsresult Init(nsACString& aContentType, + nsCaptureParams* aParams, + nsIInputStream** aStream) = 0; }; #endif diff --git a/netwerk/protocol/device/nsDeviceChannel.h b/netwerk/protocol/device/nsDeviceChannel.h index 6361dafd9a71..8c3e44793101 100644 --- a/netwerk/protocol/device/nsDeviceChannel.h +++ b/netwerk/protocol/device/nsDeviceChannel.h @@ -15,10 +15,10 @@ public: nsDeviceChannel(); - nsresult Init(nsIURI* uri); - nsresult OpenContentStream(bool aAsync, - nsIInputStream **aStream, - nsIChannel **aChannel) override; + MOZ_MUST_USE nsresult Init(nsIURI* uri); + MOZ_MUST_USE nsresult OpenContentStream(bool aAsync, + nsIInputStream **aStream, + nsIChannel **aChannel) override; protected: ~nsDeviceChannel(); diff --git a/netwerk/protocol/device/nsDeviceProtocolHandler.h b/netwerk/protocol/device/nsDeviceProtocolHandler.h index 006f70328cd7..dee9b4f8f0b7 100644 --- a/netwerk/protocol/device/nsDeviceProtocolHandler.h +++ b/netwerk/protocol/device/nsDeviceProtocolHandler.h @@ -26,7 +26,7 @@ public: nsDeviceProtocolHandler() {} - nsresult Init(); + MOZ_MUST_USE nsresult Init(); }; } // namespace net From afc64a42d6a2362c01b2c81d5a14c26ba3f3c485 Mon Sep 17 00:00:00 2001 From: Wei-Cheng Pan Date: Mon, 3 Oct 2016 14:54:40 +0800 Subject: [PATCH 36/37] Bug 1307364 - Use MOZ_MUST_USE in netwerk/protocol/file r=valentin MozReview-Commit-ID: 4EaTsMOpy0n --HG-- extra : rebase_source : 75a381c4cd9d6e90a3e366c5e59eb0167216589b --- netwerk/protocol/file/nsFileChannel.h | 10 ++++++---- netwerk/protocol/file/nsFileProtocolHandler.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/netwerk/protocol/file/nsFileChannel.h b/netwerk/protocol/file/nsFileChannel.h index 20504159bf2a..2f1f71ba3fba 100644 --- a/netwerk/protocol/file/nsFileChannel.h +++ b/netwerk/protocol/file/nsFileChannel.h @@ -29,11 +29,13 @@ protected: // method also returns a best guess at the content-type for the data stream. // NOTE: If the channel has a type hint set, contentType will be left // untouched. The caller should not use it in that case. - nsresult MakeFileInputStream(nsIFile *file, nsCOMPtr &stream, - nsCString &contentType, bool async); + MOZ_MUST_USE nsresult MakeFileInputStream(nsIFile *file, + nsCOMPtr &stream, + nsCString &contentType, bool async); - virtual nsresult OpenContentStream(bool async, nsIInputStream **result, - nsIChannel** channel) override; + virtual MOZ_MUST_USE nsresult OpenContentStream(bool async, + nsIInputStream **result, + nsIChannel** channel) override; private: nsCOMPtr mUploadStream; diff --git a/netwerk/protocol/file/nsFileProtocolHandler.h b/netwerk/protocol/file/nsFileProtocolHandler.h index 566d2650166c..211eb2873eaa 100644 --- a/netwerk/protocol/file/nsFileProtocolHandler.h +++ b/netwerk/protocol/file/nsFileProtocolHandler.h @@ -21,7 +21,7 @@ public: nsFileProtocolHandler(); - nsresult Init(); + MOZ_MUST_USE nsresult Init(); }; #endif // !nsFileProtocolHandler_h__ From badbea5392b3bf3cc1baf191d3f39c245c44a494 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Tue, 4 Oct 2016 22:48:49 -0400 Subject: [PATCH 37/37] Bug 1307481 - Part 1: Move Tooltip.js and HTMLTooltip.js into widgets/tooltip/ r=jdescottes --HG-- rename : devtools/client/shared/widgets/HTMLTooltip.js => devtools/client/shared/widgets/tooltip/HTMLTooltip.js rename : devtools/client/shared/widgets/Tooltip.js => devtools/client/shared/widgets/tooltip/Tooltip.js --- devtools/client/debugger/debugger-controller.js | 2 +- devtools/client/inspector/markup/markup.js | 2 +- devtools/client/inspector/shared/style-inspector-overlays.js | 2 +- devtools/client/netmonitor/netmonitor-view.js | 2 +- devtools/client/shadereditor/shadereditor.js | 2 +- devtools/client/shared/autocomplete-popup.js | 2 +- devtools/client/shared/test/browser_html_tooltip-01.js | 2 +- devtools/client/shared/test/browser_html_tooltip-02.js | 2 +- devtools/client/shared/test/browser_html_tooltip-03.js | 2 +- devtools/client/shared/test/browser_html_tooltip-04.js | 2 +- devtools/client/shared/test/browser_html_tooltip-05.js | 2 +- devtools/client/shared/test/browser_html_tooltip_arrow-01.js | 2 +- devtools/client/shared/test/browser_html_tooltip_arrow-02.js | 2 +- .../client/shared/test/browser_html_tooltip_consecutive-show.js | 2 +- devtools/client/shared/test/browser_html_tooltip_hover.js | 2 +- devtools/client/shared/test/browser_html_tooltip_offset.js | 2 +- devtools/client/shared/test/browser_html_tooltip_rtl.js | 2 +- .../client/shared/test/browser_html_tooltip_variable-height.js | 2 +- devtools/client/shared/test/browser_html_tooltip_width-auto.js | 2 +- devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js | 2 +- devtools/client/shared/widgets/moz.build | 2 -- devtools/client/shared/widgets/tooltip/CssDocsTooltip.js | 2 +- devtools/client/shared/widgets/{ => tooltip}/HTMLTooltip.js | 0 .../client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js | 2 +- devtools/client/shared/widgets/{ => tooltip}/Tooltip.js | 0 devtools/client/shared/widgets/tooltip/moz.build | 2 ++ devtools/client/themes/dark-theme.css | 2 +- devtools/client/themes/light-theme.css | 2 +- devtools/client/themes/tooltips.css | 2 +- 29 files changed, 27 insertions(+), 27 deletions(-) rename devtools/client/shared/widgets/{ => tooltip}/HTMLTooltip.js (100%) rename devtools/client/shared/widgets/{ => tooltip}/Tooltip.js (100%) diff --git a/devtools/client/debugger/debugger-controller.js b/devtools/client/debugger/debugger-controller.js index 4f301075ead6..386da446586d 100644 --- a/devtools/client/debugger/debugger-controller.js +++ b/devtools/client/debugger/debugger-controller.js @@ -144,7 +144,7 @@ var DevToolsUtils = require("devtools/shared/DevToolsUtils"); var promise = require("devtools/shared/deprecated-sync-thenables"); var Editor = require("devtools/client/sourceeditor/editor"); var DebuggerEditor = require("devtools/client/sourceeditor/debugger"); -var Tooltip = require("devtools/client/shared/widgets/Tooltip"); +var Tooltip = require("devtools/client/shared/widgets/tooltip/Tooltip"); var FastListWidget = require("devtools/client/shared/widgets/FastListWidget"); var {LocalizationHelper, ELLIPSIS} = require("devtools/shared/l10n"); var {PrefsHelper} = require("devtools/client/shared/prefs"); diff --git a/devtools/client/inspector/markup/markup.js b/devtools/client/inspector/markup/markup.js index 74fa79916e89..679bbc63dda7 100644 --- a/devtools/client/inspector/markup/markup.js +++ b/devtools/client/inspector/markup/markup.js @@ -37,7 +37,7 @@ const {HTMLEditor} = require("devtools/client/inspector/markup/html-editor"); const promise = require("promise"); const defer = require("devtools/shared/defer"); const Services = require("Services"); -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); const {setImageTooltip, setBrokenImageTooltip} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper"); const {setEventTooltip} = require("devtools/client/shared/widgets/tooltip/EventTooltipHelper"); diff --git a/devtools/client/inspector/shared/style-inspector-overlays.js b/devtools/client/inspector/shared/style-inspector-overlays.js index aa78f3b2ca0d..d045a514ccb1 100644 --- a/devtools/client/inspector/shared/style-inspector-overlays.js +++ b/devtools/client/inspector/shared/style-inspector-overlays.js @@ -13,7 +13,7 @@ // - etc. const {getColor} = require("devtools/client/shared/theme"); -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); const { getImageDimensions, setImageTooltip, diff --git a/devtools/client/netmonitor/netmonitor-view.js b/devtools/client/netmonitor/netmonitor-view.js index 1c699603e845..6d339d0c8c40 100644 --- a/devtools/client/netmonitor/netmonitor-view.js +++ b/devtools/client/netmonitor/netmonitor-view.js @@ -22,7 +22,7 @@ const {SideMenuWidget} = require("resource://devtools/client/shared/widgets/Side const {VariablesView} = require("resource://devtools/client/shared/widgets/VariablesView.jsm"); const {VariablesViewController} = require("resource://devtools/client/shared/widgets/VariablesViewController.jsm"); const {ToolSidebar} = require("devtools/client/framework/sidebar"); -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); const {setImageTooltip, getImageDimensions} = require("devtools/client/shared/widgets/tooltip/ImageTooltipHelper"); const { testing: isTesting } = require("devtools/shared/flags"); diff --git a/devtools/client/shadereditor/shadereditor.js b/devtools/client/shadereditor/shadereditor.js index 05ef8ec5742e..538a63ca2415 100644 --- a/devtools/client/shadereditor/shadereditor.js +++ b/devtools/client/shadereditor/shadereditor.js @@ -11,7 +11,7 @@ const {SideMenuWidget} = require("resource://devtools/client/shared/widgets/Side const promise = require("promise"); const Services = require("Services"); const EventEmitter = require("devtools/shared/event-emitter"); -const Tooltip = require("devtools/client/shared/widgets/Tooltip"); +const Tooltip = require("devtools/client/shared/widgets/tooltip/Tooltip"); const Editor = require("devtools/client/sourceeditor/editor"); const {LocalizationHelper} = require("devtools/shared/l10n"); const {Heritage, WidgetMethods, setNamedTimeout} = diff --git a/devtools/client/shared/autocomplete-popup.js b/devtools/client/shared/autocomplete-popup.js index 5cb5b93f7306..f4fb63fbc6ef 100644 --- a/devtools/client/shared/autocomplete-popup.js +++ b/devtools/client/shared/autocomplete-popup.js @@ -8,7 +8,7 @@ const HTML_NS = "http://www.w3.org/1999/xhtml"; const Services = require("Services"); const {gDevTools} = require("devtools/client/framework/devtools"); -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); const EventEmitter = require("devtools/shared/event-emitter"); let itemIdCounter = 0; diff --git a/devtools/client/shared/test/browser_html_tooltip-01.js b/devtools/client/shared/test/browser_html_tooltip-01.js index 1d5304e99ba2..bb56345c6bfc 100644 --- a/devtools/client/shared/test/browser_html_tooltip-01.js +++ b/devtools/client/shared/test/browser_html_tooltip-01.js @@ -22,7 +22,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip-02.js b/devtools/client/shared/test/browser_html_tooltip-02.js index 7b1eef529e4f..86a20f5f52a4 100644 --- a/devtools/client/shared/test/browser_html_tooltip-02.js +++ b/devtools/client/shared/test/browser_html_tooltip-02.js @@ -24,7 +24,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip-03.js b/devtools/client/shared/test/browser_html_tooltip-03.js index 39caeac9cd2c..d3419de2d03a 100644 --- a/devtools/client/shared/test/browser_html_tooltip-03.js +++ b/devtools/client/shared/test/browser_html_tooltip-03.js @@ -28,7 +28,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip-04.js b/devtools/client/shared/test/browser_html_tooltip-04.js index 3acd7a8a1f2f..dcf61e2d4a2d 100644 --- a/devtools/client/shared/test/browser_html_tooltip-04.js +++ b/devtools/client/shared/test/browser_html_tooltip-04.js @@ -26,7 +26,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); const TOOLTIP_HEIGHT = 30; diff --git a/devtools/client/shared/test/browser_html_tooltip-05.js b/devtools/client/shared/test/browser_html_tooltip-05.js index 2729cf9fb151..43aa7718b81e 100644 --- a/devtools/client/shared/test/browser_html_tooltip-05.js +++ b/devtools/client/shared/test/browser_html_tooltip-05.js @@ -23,7 +23,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); const TOOLTIP_HEIGHT = 200; diff --git a/devtools/client/shared/test/browser_html_tooltip_arrow-01.js b/devtools/client/shared/test/browser_html_tooltip_arrow-01.js index b6c77b0d9177..c8f137c7f255 100644 --- a/devtools/client/shared/test/browser_html_tooltip_arrow-01.js +++ b/devtools/client/shared/test/browser_html_tooltip_arrow-01.js @@ -46,7 +46,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip_arrow-02.js b/devtools/client/shared/test/browser_html_tooltip_arrow-02.js index 8feef273384c..2457c03580c4 100644 --- a/devtools/client/shared/test/browser_html_tooltip_arrow-02.js +++ b/devtools/client/shared/test/browser_html_tooltip_arrow-02.js @@ -40,7 +40,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js b/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js index 1b953913007a..1b76f980a1c4 100644 --- a/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js +++ b/devtools/client/shared/test/browser_html_tooltip_consecutive-show.js @@ -23,7 +23,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); function getTooltipContent(doc) { diff --git a/devtools/client/shared/test/browser_html_tooltip_hover.js b/devtools/client/shared/test/browser_html_tooltip_hover.js index 5349d4dee3ce..c329f0bb6bca 100644 --- a/devtools/client/shared/test/browser_html_tooltip_hover.js +++ b/devtools/client/shared/test/browser_html_tooltip_hover.js @@ -23,7 +23,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); add_task(function* () { diff --git a/devtools/client/shared/test/browser_html_tooltip_offset.js b/devtools/client/shared/test/browser_html_tooltip_offset.js index f85b2627fdec..d9d7471736c0 100644 --- a/devtools/client/shared/test/browser_html_tooltip_offset.js +++ b/devtools/client/shared/test/browser_html_tooltip_offset.js @@ -23,7 +23,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); add_task(function* () { diff --git a/devtools/client/shared/test/browser_html_tooltip_rtl.js b/devtools/client/shared/test/browser_html_tooltip_rtl.js index 83e66847cf32..41d326d6d0de 100644 --- a/devtools/client/shared/test/browser_html_tooltip_rtl.js +++ b/devtools/client/shared/test/browser_html_tooltip_rtl.js @@ -25,7 +25,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); const TOOLBOX_WIDTH = 500; diff --git a/devtools/client/shared/test/browser_html_tooltip_variable-height.js b/devtools/client/shared/test/browser_html_tooltip_variable-height.js index 3ee219307693..aff9099817d9 100644 --- a/devtools/client/shared/test/browser_html_tooltip_variable-height.js +++ b/devtools/client/shared/test/browser_html_tooltip_variable-height.js @@ -26,7 +26,7 @@ const CONTAINER_HEIGHT = 300; const CONTAINER_WIDTH = 200; const TOOLTIP_HEIGHT = 50; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); add_task(function* () { diff --git a/devtools/client/shared/test/browser_html_tooltip_width-auto.js b/devtools/client/shared/test/browser_html_tooltip_width-auto.js index 30ba11209e07..cc58395f902f 100644 --- a/devtools/client/shared/test/browser_html_tooltip_width-auto.js +++ b/devtools/client/shared/test/browser_html_tooltip_width-auto.js @@ -22,7 +22,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); let useXulWrapper; diff --git a/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js b/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js index 8714319a0782..508359f1103b 100644 --- a/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js +++ b/devtools/client/shared/test/browser_html_tooltip_xul-wrapper.js @@ -22,7 +22,7 @@ const TEST_URI = `data:text/xml;charset=UTF-8, `; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); loadHelperScript("helper_html_tooltip.js"); // The test toolbox will be 200px tall, the anchors are 50px tall, therefore, the maximum diff --git a/devtools/client/shared/widgets/moz.build b/devtools/client/shared/widgets/moz.build index fabefe840837..5a28d21ca5b8 100644 --- a/devtools/client/shared/widgets/moz.build +++ b/devtools/client/shared/widgets/moz.build @@ -20,7 +20,6 @@ DevToolsModules( 'FlameGraph.js', 'Graphs.js', 'GraphsWorker.js', - 'HTMLTooltip.js', 'LineGraphWidget.js', 'MdnDocsWidget.js', 'MountainGraphWidget.js', @@ -28,7 +27,6 @@ DevToolsModules( 'SimpleListWidget.jsm', 'Spectrum.js', 'TableWidget.js', - 'Tooltip.js', 'TreeWidget.js', 'VariablesView.jsm', 'VariablesViewController.jsm', diff --git a/devtools/client/shared/widgets/tooltip/CssDocsTooltip.js b/devtools/client/shared/widgets/tooltip/CssDocsTooltip.js index e09d83e37440..c7696c4110d8 100644 --- a/devtools/client/shared/widgets/tooltip/CssDocsTooltip.js +++ b/devtools/client/shared/widgets/tooltip/CssDocsTooltip.js @@ -4,7 +4,7 @@ "use strict"; -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); const {MdnDocsWidget} = require("devtools/client/shared/widgets/MdnDocsWidget"); const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts"); const XHTML_NS = "http://www.w3.org/1999/xhtml"; diff --git a/devtools/client/shared/widgets/HTMLTooltip.js b/devtools/client/shared/widgets/tooltip/HTMLTooltip.js similarity index 100% rename from devtools/client/shared/widgets/HTMLTooltip.js rename to devtools/client/shared/widgets/tooltip/HTMLTooltip.js diff --git a/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js b/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js index 3ace49d4b349..5a1566339c24 100644 --- a/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js +++ b/devtools/client/shared/widgets/tooltip/SwatchBasedEditorTooltip.js @@ -6,7 +6,7 @@ const EventEmitter = require("devtools/shared/event-emitter"); const {KeyShortcuts} = require("devtools/client/shared/key-shortcuts"); -const {HTMLTooltip} = require("devtools/client/shared/widgets/HTMLTooltip"); +const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip"); /** * Base class for all (color, gradient, ...)-swatch based value editors inside diff --git a/devtools/client/shared/widgets/Tooltip.js b/devtools/client/shared/widgets/tooltip/Tooltip.js similarity index 100% rename from devtools/client/shared/widgets/Tooltip.js rename to devtools/client/shared/widgets/tooltip/Tooltip.js diff --git a/devtools/client/shared/widgets/tooltip/moz.build b/devtools/client/shared/widgets/tooltip/moz.build index 33a6b2d25548..93172227a730 100644 --- a/devtools/client/shared/widgets/tooltip/moz.build +++ b/devtools/client/shared/widgets/tooltip/moz.build @@ -7,11 +7,13 @@ DevToolsModules( 'CssDocsTooltip.js', 'EventTooltipHelper.js', + 'HTMLTooltip.js', 'ImageTooltipHelper.js', 'SwatchBasedEditorTooltip.js', 'SwatchColorPickerTooltip.js', 'SwatchCubicBezierTooltip.js', 'SwatchFilterTooltip.js', + 'Tooltip.js', 'TooltipToggle.js', 'VariableContentHelper.js', ) diff --git a/devtools/client/themes/dark-theme.css b/devtools/client/themes/dark-theme.css index b042c6553206..f9bdc05d1c9f 100644 --- a/devtools/client/themes/dark-theme.css +++ b/devtools/client/themes/dark-theme.css @@ -306,7 +306,7 @@ div.CodeMirror span.eval-text { } } -/* XUL panel styling (see devtools/client/shared/widgets/Tooltip.js) */ +/* XUL panel styling (see devtools/client/shared/widgets/tooltip/Tooltip.js) */ .theme-tooltip-panel .panel-arrowcontent { padding: 5px; diff --git a/devtools/client/themes/light-theme.css b/devtools/client/themes/light-theme.css index bc566ce71626..a5f19edd1965 100644 --- a/devtools/client/themes/light-theme.css +++ b/devtools/client/themes/light-theme.css @@ -318,7 +318,7 @@ div.CodeMirror span.eval-text { } } -/* XUL panel styling (see devtools/client/shared/widgets/Tooltip.js) */ +/* XUL panel styling (see devtools/client/shared/widgets/tooltip/Tooltip.js) */ .theme-tooltip-panel .panel-arrowcontent { padding: 4px; diff --git a/devtools/client/themes/tooltips.css b/devtools/client/themes/tooltips.css index dbaa734bceae..81b450601de6 100644 --- a/devtools/client/themes/tooltips.css +++ b/devtools/client/themes/tooltips.css @@ -15,7 +15,7 @@ --bezier-grid-color: rgba(0, 0, 0, 0.05); } -/* Tooltip widget (see devtools/client/shared/widgets/Tooltip.js) */ +/* Tooltip widget (see devtools/client/shared/widgets/tooltip/Tooltip.js) */ .devtools-tooltip .panel-arrowcontent { padding: 4px;