diff options
| -rw-r--r-- | api/current.txt | 17 | ||||
| -rw-r--r-- | core/java/android/content/ContentProvider.java | 7 | ||||
| -rw-r--r-- | core/java/android/hardware/Sensor.java | 82 | ||||
| -rw-r--r-- | core/java/android/hardware/SensorEvent.java | 122 | ||||
| -rw-r--r-- | core/java/android/hardware/SensorManager.java | 89 | ||||
| -rw-r--r-- | core/java/android/hardware/SystemSensorManager.java | 309 | ||||
| -rw-r--r-- | core/java/android/hardware/TriggerEvent.java | 62 | ||||
| -rw-r--r-- | core/java/android/hardware/TriggerEventListener.java | 78 | ||||
| -rw-r--r-- | core/java/android/net/DhcpStateMachine.java | 3 | ||||
| -rw-r--r-- | core/java/android/net/LinkProperties.java | 18 | ||||
| -rw-r--r-- | core/jni/android_hardware_SensorManager.cpp | 20 | ||||
| -rw-r--r-- | libs/hwui/DisplayListOp.h | 10 | ||||
| -rw-r--r-- | libs/hwui/Matrix.h | 8 | ||||
| -rw-r--r-- | libs/hwui/font/Font.cpp | 14 | ||||
| -rw-r--r-- | policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java | 4 |
15 files changed, 276 insertions, 567 deletions
diff --git a/api/current.txt b/api/current.txt index be104a0..1668170 100644 --- a/api/current.txt +++ b/api/current.txt @@ -10045,20 +10045,16 @@ package android.hardware { field public static final int TYPE_ACCELEROMETER = 1; // 0x1 field public static final int TYPE_ALL = -1; // 0xffffffff field public static final int TYPE_AMBIENT_TEMPERATURE = 13; // 0xd - field public static final int TYPE_GAME_ROTATION_VECTOR = 15; // 0xf field public static final int TYPE_GRAVITY = 9; // 0x9 field public static final int TYPE_GYROSCOPE = 4; // 0x4 - field public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; // 0x10 field public static final int TYPE_LIGHT = 5; // 0x5 field public static final int TYPE_LINEAR_ACCELERATION = 10; // 0xa field public static final int TYPE_MAGNETIC_FIELD = 2; // 0x2 - field public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; // 0xe field public static final deprecated int TYPE_ORIENTATION = 3; // 0x3 field public static final int TYPE_PRESSURE = 6; // 0x6 field public static final int TYPE_PROXIMITY = 8; // 0x8 field public static final int TYPE_RELATIVE_HUMIDITY = 12; // 0xc field public static final int TYPE_ROTATION_VECTOR = 11; // 0xb - field public static final int TYPE_SIGNIFICANT_MOTION = 17; // 0x11 field public static final deprecated int TYPE_TEMPERATURE = 7; // 0x7 } @@ -10080,7 +10076,6 @@ package android.hardware { } public abstract class SensorManager { - method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor); method public static float getAltitude(float, float); method public static void getAngleChange(float[], float[], float[]); method public android.hardware.Sensor getDefaultSensor(int); @@ -10096,7 +10091,6 @@ package android.hardware { method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int); method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler); method public static boolean remapCoordinateSystem(float[], int, int, float[]); - method public boolean requestTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor); method public deprecated void unregisterListener(android.hardware.SensorListener); method public deprecated void unregisterListener(android.hardware.SensorListener, int); method public void unregisterListener(android.hardware.SensorEventListener, android.hardware.Sensor); @@ -10160,17 +10154,6 @@ package android.hardware { field public static final float STANDARD_GRAVITY = 9.80665f; } - public final class TriggerEvent { - field public android.hardware.Sensor sensor; - field public long timestamp; - field public final float[] values; - } - - public abstract class TriggerEventListener { - ctor public TriggerEventListener(); - method public abstract void onTrigger(android.hardware.TriggerEvent); - } - } package android.hardware.display { diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 8aef405..4968268 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -1256,6 +1256,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 { * interfaces that are cheaper and/or unnatural for a table-like * model. * + * <p class="note"><strong>WARNING:</strong> The framework does no permission checking + * on this entry into the content provider besides the basic ability for the application + * to get access to the provider at all. For example, it has no idea whether the call + * being executed may read or write data in the provider, so can't enforce those + * individual permissions. Any implementation of this method <strong>must</strong> + * do its own permission checks on incoming calls to make sure they are allowed.</p> + * * @param method method name to call. Opaque to framework, but should not be {@code null}. * @param arg provider-defined String argument. May be {@code null}. * @param extras provider-defined Bundle argument. May be {@code null}. diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java index af4c074..41384d2 100644 --- a/core/java/android/hardware/Sensor.java +++ b/core/java/android/hardware/Sensor.java @@ -114,90 +114,11 @@ public final class Sensor { /** A constant describing an ambient temperature sensor type */ public static final int TYPE_AMBIENT_TEMPERATURE = 13; - /** - * A constant describing a magnetic field uncalibrated sensor type. See - * {@link android.hardware.SensorEvent#values SensorEvent.values} for more - * details. - * <p> - * No periodic calibration is performed (ie: there are no discontinuities - * in the data stream while using this sensor). Assumptions that the - * magnetic field is due to the Earth's poles is avoided. Factory calibration - * and temperature compensation is still performed. - * </p> - */ - public static final int TYPE_MAGNETIC_FIELD_UNCALIBRATED = 14; - - /** - * Identical to {@link #TYPE_ROTATION_VECTOR} except that it doesn't - * use the geomagnetic field. Therefore the Y axis doesn't - * point north, but instead to some other reference, that reference is - * allowed to drift by the same order of magnitude as the gyroscope - * drift around the Z axis. - * <p> - * In the ideal case, a phone rotated and returning to the same real-world - * orientation should report the same game rotation vector - * (without using the earth's geomagnetic field). However, the orientation - * may drift somewhat over time. - * </p> - */ - - public static final int TYPE_GAME_ROTATION_VECTOR = 15; - - /** - * A constant describing a gyroscope uncalibrated sensor type. See - * {@link android.hardware.SensorEvent#values SensorEvent.values} for more - * details. - * <p> - * No gyro-drift compensation is performed. - * Factory calibration and temperature compensation is still applied - * to the rate of rotation (angular speeds). - * </p> - */ - public static final int TYPE_GYROSCOPE_UNCALIBRATED = 16; - - /** - * A constant describing the significant motion trigger sensor. - * See {@link android.hardware.SensorEvent#values} for more details. - * <p> - * It triggers when an event occurs and then automatically disables - * itself. The sensor continues to operate while the device is asleep - * and will automatically wake the device to notify when significant - * motion is detected. The application does not need to hold any wake - * locks for this sensor to trigger. - * </p> - */ - public static final int TYPE_SIGNIFICANT_MOTION = 17; - - /** + /** * A constant describing all sensor types. */ public static final int TYPE_ALL = -1; - /* Reporting mode constants for sensors. Each sensor will have exactly one - reporting mode associated with it. */ - // Events are reported at a constant rate. - static int REPORTING_MODE_CONTINUOUS = 1; - - // Events are reported only when the value changes. - static int REPORTING_MODE_ON_CHANGE = 2; - - // Upon detection of an event, the sensor deactivates itself and then sends a single event. - static int REPORTING_MODE_ONE_SHOT = 3; - - // Note: This needs to be updated, whenever a new sensor is added. - private static int[] sSensorReportingModes = { - REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, - REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, - REPORTING_MODE_ON_CHANGE, REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, - REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ON_CHANGE, - REPORTING_MODE_ON_CHANGE, REPORTING_MODE_CONTINUOUS, REPORTING_MODE_CONTINUOUS, - REPORTING_MODE_CONTINUOUS, REPORTING_MODE_ONE_SHOT }; - - static int getReportingMode(Sensor sensor) { - // mType starts from offset 1. - return sSensorReportingModes[sensor.mType - 1]; - } - /* Some of these fields are set only by the native bindings in * SensorManager. */ @@ -211,6 +132,7 @@ public final class Sensor { private float mPower; private int mMinDelay; + Sensor() { } diff --git a/core/java/android/hardware/SensorEvent.java b/core/java/android/hardware/SensorEvent.java index 84c9131..51a17c1 100644 --- a/core/java/android/hardware/SensorEvent.java +++ b/core/java/android/hardware/SensorEvent.java @@ -17,9 +17,11 @@ package android.hardware; /** + * <p> * This class represents a {@link android.hardware.Sensor Sensor} event and * holds informations such as the sensor's type, the time-stamp, accuracy and of * course the sensor's {@link SensorEvent#values data}. + * </p> * * <p> * <u>Definition of the coordinate system used by the SensorEvent API.</u> @@ -65,9 +67,15 @@ public class SensorEvent { * Sensor.TYPE_ACCELEROMETER}:</h4> All values are in SI units (m/s^2) * * <ul> - * <li> values[0]: Acceleration minus Gx on the x-axis </li> - * <li> values[1]: Acceleration minus Gy on the y-axis </li> - * <li> values[2]: Acceleration minus Gz on the z-axis </li> + * <p> + * values[0]: Acceleration minus Gx on the x-axis + * </p> + * <p> + * values[1]: Acceleration minus Gy on the y-axis + * </p> + * <p> + * values[2]: Acceleration minus Gz on the z-axis + * </p> * </ul> * * <p> @@ -157,9 +165,15 @@ public class SensorEvent { * definition of positive rotation and does not agree with the definition of * roll given earlier. * <ul> - * <li> values[0]: Angular speed around the x-axis </li> - * <li> values[1]: Angular speed around the y-axis </li> - * <li> values[2]: Angular speed around the z-axis </li> + * <p> + * values[0]: Angular speed around the x-axis + * </p> + * <p> + * values[1]: Angular speed around the y-axis + * </p> + * <p> + * values[2]: Angular speed around the z-axis + * </p> * </ul> * <p> * Typically the output of the gyroscope is integrated over time to @@ -219,19 +233,22 @@ public class SensorEvent { * </p> * <h4>{@link android.hardware.Sensor#TYPE_LIGHT Sensor.TYPE_LIGHT}:</h4> * <ul> - * <li>values[0]: Ambient light level in SI lux units </li> + * <p> + * values[0]: Ambient light level in SI lux units * </ul> * * <h4>{@link android.hardware.Sensor#TYPE_PRESSURE Sensor.TYPE_PRESSURE}:</h4> * <ul> - * <li>values[0]: Atmospheric pressure in hPa (millibar) </li> + * <p> + * values[0]: Atmospheric pressure in hPa (millibar) * </ul> * * <h4>{@link android.hardware.Sensor#TYPE_PROXIMITY Sensor.TYPE_PROXIMITY}: * </h4> * * <ul> - * <li>values[0]: Proximity sensor distance measured in centimeters </li> + * <p> + * values[0]: Proximity sensor distance measured in centimeters * </ul> * * <p> @@ -287,23 +304,39 @@ public class SensorEvent { * </p> * * <ul> - * <li> values[0]: x*sin(θ/2) </li> - * <li> values[1]: y*sin(θ/2) </li> - * <li> values[2]: z*sin(θ/2) </li> - * <li> values[3]: cos(θ/2) <i>(optional: only if value.length = 4)</i> </li> + * <p> + * values[0]: x*sin(θ/2) + * </p> + * <p> + * values[1]: y*sin(θ/2) + * </p> + * <p> + * values[2]: z*sin(θ/2) + * </p> + * <p> + * values[3]: cos(θ/2) <i>(optional: only if value.length = 4)</i> + * </p> * </ul> * * <h4>{@link android.hardware.Sensor#TYPE_ORIENTATION * Sensor.TYPE_ORIENTATION}:</h4> All values are angles in degrees. * * <ul> - * <li> values[0]: Azimuth, angle between the magnetic north direction and the + * <p> + * values[0]: Azimuth, angle between the magnetic north direction and the * y-axis, around the z-axis (0 to 359). 0=North, 90=East, 180=South, - * 270=West </li> - * <li> values[1]: Pitch, rotation around x-axis (-180 to 180), with positive - * values when the z-axis moves <b>toward</b> the y-axis. </li> - * <li> values[2]: Roll, rotation around y-axis (-90 to 90), with positive values - * when the x-axis moves <b>toward</b> the z-axis. </li> + * 270=West + * </p> + * + * <p> + * values[1]: Pitch, rotation around x-axis (-180 to 180), with positive + * values when the z-axis moves <b>toward</b> the y-axis. + * </p> + * + * <p> + * values[2]: Roll, rotation around y-axis (-90 to 90), with positive values + * when the x-axis moves <b>toward</b> the z-axis. + * </p> * </ul> * * <p> @@ -331,7 +364,9 @@ public class SensorEvent { * <h4>{@link android.hardware.Sensor#TYPE_RELATIVE_HUMIDITY * Sensor.TYPE_RELATIVE_HUMIDITY}:</h4> * <ul> - * <li> values[0]: Relative ambient air humidity in percent </li> + * <p> + * values[0]: Relative ambient air humidity in percent + * </p> * </ul> * <p> * When relative ambient air humidity and ambient temperature are @@ -388,58 +423,21 @@ public class SensorEvent { * </h4> * * <ul> - * <li> values[0]: ambient (room) temperature in degree Celsius.</li> + * <p> + * values[0]: ambient (room) temperature in degree Celsius. * </ul> * * @see SensorEvent * @see GeomagneticField - * - * <h4>{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED} </h4> - * All values are in micro-Tesla (uT) and measure the ambient magnetic field - * in the X, Y and Z axis. - * <p> - * No periodic calibration is performed (ie: there are no discontinuities - * in the data stream while using this sensor). Assumptions that the the - * magnetic field is due to the Earth's poles is avoided. Factory calibration - * and temperature compensation is still performed. - * </p> - * - * <h4> {@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED} </h4> - * All values are in radians/second and measure the rate of rotation - * around the X, Y and Z axis. An estimation of the drift on each axis is - * reported as well. - * <p> - * No gyro-drift compensation is performed. Factory calibration and temperature - * compensation is still applied to the rate of rotation (angular speeds). - * </p> - * <p> - * The coordinate system is the same as is used for the - * {@link android.hardware.Sensor#TYPE_ACCELEROMETER} - * Rotation is positive in the counter-clockwise direction (right-hand rule). - * That is, an observer looking from some positive location on the x, y or z axis - * at a device positioned on the origin would report positive rotation if the device - * appeared to be rotating counter clockwise. - * The range would at least be 17.45 rad/s (ie: ~1000 deg/s). - * <ul> - * <li> values[0] : angular speed (w/o drift compensation) around the X axis in rad/s </li> - * <li> values[1] : angular speed (w/o drift compensation) around the Y axis in rad/s </li> - * <li> values[2] : angular speed (w/o drift compensation) around the Z axis in rad/s </li> - * <li> values[3] : estimated drift around X axis in rad/s </li> - * <li> values[4] : estimated drift around Y axis in rad/s </li> - * <li> values[5] : estimated drift around Z axis in rad/s </li> - * </ul> - * </p> - * <h4></h4> - * <h4> Pro Tip: Always use the length of the values array while performing operations - * on it. In earlier versions, this used to be always 3 which has changed now. </h4> */ + public final float[] values; /** * The sensor that generated this event. See * {@link android.hardware.SensorManager SensorManager} for details. */ - public Sensor sensor; + public Sensor sensor; /** * The accuracy of this event. See {@link android.hardware.SensorManager @@ -447,11 +445,13 @@ public class SensorEvent { */ public int accuracy; + /** * The time in nanosecond at which the event happened */ public long timestamp; + SensorEvent(int size) { values = new float[size]; } diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java index ce7bc7e..c0d2fae 100644 --- a/core/java/android/hardware/SensorManager.java +++ b/core/java/android/hardware/SensorManager.java @@ -38,11 +38,7 @@ import java.util.List; * hours. Note that the system will <i>not</i> disable sensors automatically when * the screen turns off. * </p> - * <p class="note"> - * Note: Don't use this mechanism with a Trigger Sensor, have a look - * at {@link TriggerEventListener}. {@link Sensor#TYPE_SIGNIFICANT_MOTION} - * is an example of a trigger sensor. - * </p> + * * <pre class="prettyprint"> * public class SensorActivity extends Activity, implements SensorEventListener { * private final SensorManager mSensorManager; @@ -519,12 +515,6 @@ public abstract class SensorManager { /** * Unregisters a listener for the sensors with which it is registered. * - * <p class="note"></p> - * Note: Don't use this method with a one shot trigger sensor such as - * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. - * Use {@link #cancelTriggerSensor(TriggerEventListener, Sensor)} instead. - * </p> - * * @param listener * a SensorEventListener object * @@ -534,7 +524,6 @@ public abstract class SensorManager { * @see #unregisterListener(SensorEventListener) * @see #registerListener(SensorEventListener, Sensor, int) * - * @throws IllegalArgumentException when sensor is a trigger sensor. */ public void unregisterListener(SensorEventListener listener, Sensor sensor) { if (listener == null || sensor == null) { @@ -569,12 +558,6 @@ public abstract class SensorManager { * Registers a {@link android.hardware.SensorEventListener * SensorEventListener} for the given sensor. * - * <p class="note"></p> - * Note: Don't use this method with a one shot trigger sensor such as - * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. - * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. - * </p> - * * @param listener * A {@link android.hardware.SensorEventListener SensorEventListener} * object. @@ -598,7 +581,6 @@ public abstract class SensorManager { * @see #unregisterListener(SensorEventListener) * @see #unregisterListener(SensorEventListener, Sensor) * - * @throws IllegalArgumentException when sensor is null or a trigger sensor */ public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate) { return registerListener(listener, sensor, rate, null); @@ -608,12 +590,6 @@ public abstract class SensorManager { * Registers a {@link android.hardware.SensorEventListener * SensorEventListener} for the given sensor. * - * <p class="note"></p> - * Note: Don't use this method with a one shot trigger sensor such as - * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. - * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. - * </p> - * * @param listener * A {@link android.hardware.SensorEventListener SensorEventListener} * object. @@ -641,7 +617,6 @@ public abstract class SensorManager { * @see #unregisterListener(SensorEventListener) * @see #unregisterListener(SensorEventListener, Sensor) * - * @throws IllegalArgumentException when sensor is null or a trigger sensor */ public boolean registerListener(SensorEventListener listener, Sensor sensor, int rate, Handler handler) { @@ -1329,68 +1304,6 @@ public abstract class SensorManager { Q[3] = rv[2]; } - /** - * Requests receiving trigger events for a trigger sensor. - * - * <p> - * When the sensor detects a trigger event condition, such as significant motion in - * the case of the {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the provided trigger listener - * will be invoked once and then its request to receive trigger events will be canceled. - * To continue receiving trigger events, the application must request to receive trigger - * events again. - * </p> - * - * @param listener The listener on which the - * {@link TriggerEventListener#onTrigger(TriggerEvent)} will be delivered. - * @param sensor The sensor to be enabled. - * - * @return true if the sensor was successfully enabled. - * - * @throws IllegalArgumentException when sensor is null or not a trigger sensor. - */ - public boolean requestTriggerSensor(TriggerEventListener listener, Sensor sensor) { - return requestTriggerSensorImpl(listener, sensor); - } - - /** - * @hide - */ - protected abstract boolean requestTriggerSensorImpl(TriggerEventListener listener, - Sensor sensor); - - /** - * Cancels receiving trigger events for a trigger sensor. - * - * <p> - * Note that a Trigger sensor will be auto disabled if - * {@link TriggerEventListener#onTrigger(TriggerEvent)} has triggered. - * This method is provided in case the user wants to explicitly cancel the request - * to receive trigger events. - * </p> - * - * @param listener The listener on which the - * {@link TriggerEventListener#onTrigger(TriggerEvent)} - * is delivered.It should be the same as the one used - * in {@link #requestTriggerSensor(TriggerEventListener, Sensor)} - * @param sensor The sensor for which the trigger request should be canceled. - * If null, it cancels receiving trigger for all sensors associated - * with the listener. - * - * @return true if successfully canceled. - * - * @throws IllegalArgumentException when sensor is a trigger sensor. - */ - public boolean cancelTriggerSensor(TriggerEventListener listener, Sensor sensor) { - return cancelTriggerSensorImpl(listener, sensor); - } - - /** - * @hide - */ - protected abstract boolean cancelTriggerSensorImpl(TriggerEventListener listener, - Sensor sensor); - - private LegacySensorManager getLegacySensorManager() { synchronized (mSensorListByType) { if (mLegacySensorManager == null) { diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 893d701..9591631 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -16,19 +16,18 @@ package android.hardware; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import dalvik.system.CloseGuard; + import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; -import android.util.Log; -import android.util.Pools; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; -import dalvik.system.CloseGuard; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; /** * Sensor manager implementation that communicates with the built-in @@ -46,21 +45,22 @@ public class SystemSensorManager extends SensorManager { private static final SparseArray<Sensor> sHandleToSensor = new SparseArray<Sensor>(); // Listener list - private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners = - new HashMap<SensorEventListener, SensorEventQueue>(); - private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners = - new HashMap<TriggerEventListener, TriggerEventQueue>(); + private final ArrayList<SensorEventListenerSensorPair> mListenerDelegates = new ArrayList<SensorEventListenerSensorPair>(); - private static final int MAX_EVENTS = 16; - private static Pools.SynchronizedPool<SensorEvent> sSensorEventPool; - private static Pools.SynchronizedPool<TriggerEvent> sTriggerEventPool; + // Common pool of sensor events. + private static SensorEventPool sPool; // Looper associated with the context in which this instance was created. private final Looper mMainLooper; + // maps a SensorEventListener to a SensorEventQueue + private final Hashtable<SensorEventListener, SensorEventQueue> mSensorEventQueueMap; + /** {@hide} */ public SystemSensorManager(Looper mainLooper) { mMainLooper = mainLooper; + mSensorEventQueueMap = new Hashtable<SensorEventListener, SensorEventQueue>(); + synchronized(sSensorModuleLock) { if (!sSensorModuleInitialized) { sSensorModuleInitialized = true; @@ -81,10 +81,7 @@ public class SystemSensorManager extends SensorManager { } } while (i>0); - sSensorEventPool = new Pools.SynchronizedPool<SensorEvent>( - Math.max(sFullSensorsList.size()*2, 1)); - sTriggerEventPool = new Pools.SynchronizedPool<TriggerEvent>( - Math.max(sFullSensorsList.size()*2, 1)); + sPool = new SensorEventPool( sFullSensorsList.size()*2 ); } } } @@ -105,133 +102,128 @@ public class SystemSensorManager extends SensorManager { // Invariants to preserve: // - one Looper per SensorEventListener // - one Looper per SensorEventQueue - // We map SensorEventListener to a SensorEventQueue, which holds the looper - if (sensor == null) throw new IllegalArgumentException("sensor cannot be null"); - - // Trigger Sensors should use the requestTriggerSensor call. - if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) return false; + // We map SensorEventListeners to a SensorEventQueue, which holds the looper + + if (sensor == null) throw new NullPointerException("sensor cannot be null"); + + boolean result; + synchronized (mSensorEventQueueMap) { + // check if we already have this SensorEventListener, Sensor pair + // registered -- if so, we ignore the register. This is not ideal + // but this is what the implementation has always been doing. + for (SensorEventListenerSensorPair l : mListenerDelegates) { + if (l.isSameListenerSensorPair(listener, sensor)) { + // already added, just return silently. + return true; + } + } - synchronized (mSensorListeners) { - SensorEventQueue queue = mSensorListeners.get(listener); - if (queue == null) { + // now find the SensorEventQueue associated to this listener + SensorEventQueue queue = mSensorEventQueueMap.get(listener); + if (queue != null) { + result = queue.addSensor(sensor, delay); + if (result) { + // create a new ListenerDelegate for this pair + mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor)); + } + } else { Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; - queue = new SensorEventQueue(listener, looper); - if (!queue.addSensor(sensor, delay)) { + queue = new SensorEventQueue(listener, looper.getQueue()); + result = queue.addSensor(sensor, delay); + if (result) { + // create a new ListenerDelegate for this pair + mListenerDelegates.add(new SensorEventListenerSensorPair(listener, sensor)); + mSensorEventQueueMap.put(listener, queue); + } else { queue.dispose(); - return false; } - mSensorListeners.put(listener, queue); - return true; - } else { - return queue.addSensor(sensor, delay); } } + return result; } /** @hide */ @Override protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { - // Trigger Sensors should use the cancelTriggerSensor call. - if (sensor != null && Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) { - return; - } + synchronized (mSensorEventQueueMap) { + + // remove this listener/sensor from our list + final ArrayList<SensorEventListenerSensorPair> copy = + new ArrayList<SensorEventListenerSensorPair>(mListenerDelegates); + int lastIndex = copy.size()-1; + for (int i=lastIndex ; i>= 0 ; i--) { + if (copy.get(i).isSameListenerSensorPair(listener, sensor)) { + mListenerDelegates.remove(i); + } + } - synchronized (mSensorListeners) { - SensorEventQueue queue = mSensorListeners.get(listener); + // find the SensorEventQueue associated to this SensorEventListener + SensorEventQueue queue = mSensorEventQueueMap.get(listener); if (queue != null) { - boolean result; - if (sensor == null) { - result = queue.removeAllSensors(); + if (sensor != null) { + queue.removeSensor(sensor); } else { - result = queue.removeSensor(sensor); + queue.removeAllSensors(); } - if (result && !queue.hasSensors()) { - mSensorListeners.remove(listener); + if (!queue.hasSensors()) { + mSensorEventQueueMap.remove(listener); queue.dispose(); } } } } - /** @hide */ - @Override - protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { - if (sensor == null) throw new IllegalArgumentException("sensor cannot be null"); - - if (Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) return false; - synchronized (mTriggerListeners) { - TriggerEventQueue queue = mTriggerListeners.get(listener); - if (queue == null) { - queue = new TriggerEventQueue(listener, mMainLooper, this); - if (!queue.addSensor(sensor, 0)) { - queue.dispose(); - return false; - } - mTriggerListeners.put(listener, queue); - return true; - } else { - return queue.addSensor(sensor, 0); - } - } - } - - /** @hide */ - @Override - protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { - if (sensor != null && Sensor.getReportingMode(sensor) != Sensor.REPORTING_MODE_ONE_SHOT) { - return false; + /* + * ListenerDelegate is essentially a SensorEventListener, Sensor pair + * and is associated with a single SensorEventQueue. + */ + private static final class SensorEventListenerSensorPair { + private final SensorEventListener mSensorEventListener; + private final Sensor mSensor; + public SensorEventListenerSensorPair(SensorEventListener listener, Sensor sensor) { + mSensorEventListener = listener; + mSensor = sensor; } - synchronized (mTriggerListeners) { - TriggerEventQueue queue = mTriggerListeners.get(listener); - if (queue != null) { - boolean result; - if (sensor == null) { - result = queue.removeAllSensors(); - } else { - result = queue.removeSensor(sensor); - } - if (result && !queue.hasSensors()) { - mTriggerListeners.remove(listener); - queue.dispose(); - } - return result; + public boolean isSameListenerSensorPair(SensorEventListener listener, Sensor sensor) { + // if sensor is null, we match only on the listener + if (sensor != null) { + return (listener == mSensorEventListener) && + (sensor.getHandle() == mSensor.getHandle()); + } else { + return (listener == mSensorEventListener); } - return false; } } /* - * BaseEventQueue is the communication channel with the sensor service, - * SensorEventQueue, TriggerEventQueue are subclases and there is one-to-one mapping between - * the queues and the listeners. + * SensorEventQueue is the communication channel with the sensor service, + * there is a one-to-one mapping between SensorEventQueue and + * SensorEventListener. */ - private static abstract class BaseEventQueue { - private native int nativeInitBaseEventQueue(BaseEventQueue eventQ, MessageQueue msgQ, - float[] scratch); + private static final class SensorEventQueue { + private static native int nativeInitSensorEventQueue(SensorEventQueue eventQ, MessageQueue msgQ, float[] scratch); private static native int nativeEnableSensor(int eventQ, int handle, int us); private static native int nativeDisableSensor(int eventQ, int handle); private static native void nativeDestroySensorEventQueue(int eventQ); private int nSensorEventQueue; + private final SensorEventListener mListener; private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); - protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); - protected final SparseBooleanArray mFirstEvent = new SparseBooleanArray(); + private final SparseIntArray mSensorAccuracies = new SparseIntArray(); + private final SparseBooleanArray mFirstEvent = new SparseBooleanArray(); private final CloseGuard mCloseGuard = CloseGuard.get(); private final float[] mScratch = new float[16]; - BaseEventQueue(Looper looper) { - nSensorEventQueue = nativeInitBaseEventQueue(this, looper.getQueue(), mScratch); + public SensorEventQueue(SensorEventListener listener, MessageQueue msgQ) { + nSensorEventQueue = nativeInitSensorEventQueue(this, msgQ, mScratch); + mListener = listener; mCloseGuard.open("dispose"); } - public void dispose() { dispose(false); } public boolean addSensor(Sensor sensor, int delay) { - // Check if already present. - if (mActiveSensors.get(sensor.getHandle())) return false; - if (enableSensor(sensor, delay) == 0) { mActiveSensors.put(sensor.getHandle(), true); return true; @@ -239,7 +231,7 @@ public class SystemSensorManager extends SensorManager { return false; } - public boolean removeAllSensors() { + public void removeAllSensors() { for (int i=0 ; i<mActiveSensors.size(); i++) { if (mActiveSensors.valueAt(i) == true) { int handle = mActiveSensors.keyAt(i); @@ -252,24 +244,21 @@ public class SystemSensorManager extends SensorManager { } } } - return true; } - public boolean removeSensor(Sensor sensor) { + public void removeSensor(Sensor sensor) { final int handle = sensor.getHandle(); if (mActiveSensors.get(handle)) { disableSensor(sensor); mActiveSensors.put(sensor.getHandle(), false); - return true; } - return false; } public boolean hasSensors() { // no more sensors are set return mActiveSensors.indexOfValue(true) >= 0; } - + @Override protected void finalize() throws Throwable { try { @@ -302,30 +291,17 @@ public class SystemSensorManager extends SensorManager { if (sensor == null) throw new NullPointerException(); return nativeDisableSensor(nSensorEventQueue, sensor.getHandle()); } - protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, - long timestamp); - } - - static final class SensorEventQueue extends BaseEventQueue { - private final SensorEventListener mListener; - - public SensorEventQueue(SensorEventListener listener, Looper looper) { - super(looper); - mListener = listener; - } // Called from native code. @SuppressWarnings("unused") - @Override - protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, - long timestamp) { - final Sensor sensor = sHandleToSensor.get(handle); - SensorEvent t = sSensorEventPool.acquire(); - if (t == null) t = new SensorEvent(MAX_EVENTS); + private void dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp) { + // this is always called on the same thread. + final SensorEvent t = sPool.getFromPool(); try { - // Copy the entire values array. - // Any changes in length will be handled at the native layer. - System.arraycopy(values, 0, t.values, 0, t.values.length); + final Sensor sensor = sHandleToSensor.get(handle); + final SensorEventListener listener = mListener; + // FIXME: handle more than 3 values + System.arraycopy(values, 0, t.values, 0, 3); t.timestamp = timestamp; t.accuracy = inAccuracy; t.sensor = sensor; @@ -337,57 +313,72 @@ public class SystemSensorManager extends SensorManager { final int accuracy = mSensorAccuracies.get(handle); if ((t.accuracy >= 0) && (accuracy != t.accuracy)) { mSensorAccuracies.put(handle, t.accuracy); - mListener.onAccuracyChanged(t.sensor, t.accuracy); + listener.onAccuracyChanged(t.sensor, t.accuracy); } break; default: // For other sensors, just report the accuracy once if (mFirstEvent.get(handle) == false) { mFirstEvent.put(handle, true); - mListener.onAccuracyChanged( + listener.onAccuracyChanged( t.sensor, SENSOR_STATUS_ACCURACY_HIGH); } break; } - mListener.onSensorChanged(t); + listener.onSensorChanged(t); } finally { - sSensorEventPool.release(t); + sPool.returnToPool(t); } } } - static final class TriggerEventQueue extends BaseEventQueue { - private final TriggerEventListener mListener; - private SensorManager mManager; - - public TriggerEventQueue(TriggerEventListener listener, Looper looper, - SensorManager manager) { - super(looper); - mListener = listener; - mManager = manager; + /* + * A dumb pool of SensorEvent + */ + private static final class SensorEventPool { + private final int mPoolSize; + private final SensorEvent mPool[]; + private int mNumItemsInPool; + + private SensorEvent createSensorEvent() { + // maximal size for all legacy events is 3 + return new SensorEvent(3); } - // Called from native code. - @SuppressWarnings("unused") - @Override - protected void dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp) { - final Sensor sensor = sHandleToSensor.get(handle); - TriggerEvent t = sTriggerEventPool.acquire(); - if (t == null) t = new TriggerEvent(MAX_EVENTS); - - try { - // Copy the entire values array. - // Any changes in length will be handled at the native layer. - System.arraycopy(values, 0, t.values, 0, t.values.length); - t.timestamp = timestamp; - t.sensor = sensor; + SensorEventPool(int poolSize) { + mPoolSize = poolSize; + mNumItemsInPool = poolSize; + mPool = new SensorEvent[poolSize]; + } - // A trigger sensor should be auto disabled. - mManager.cancelTriggerSensorImpl(mListener, sensor); + SensorEvent getFromPool() { + SensorEvent t = null; + synchronized (this) { + if (mNumItemsInPool > 0) { + // remove the "top" item from the pool + final int index = mPoolSize - mNumItemsInPool; + t = mPool[index]; + mPool[index] = null; + mNumItemsInPool--; + } + } + if (t == null) { + // the pool was empty or this item was removed from the pool for + // the first time. In any case, we need to create a new item. + t = createSensorEvent(); + } + return t; + } - mListener.onTrigger(t); - } finally { - sTriggerEventPool.release(t); + void returnToPool(SensorEvent t) { + synchronized (this) { + // is there space left in the pool? + if (mNumItemsInPool < mPoolSize) { + // if so, return the item to the pool + mNumItemsInPool++; + final int index = mPoolSize - mNumItemsInPool; + mPool[index] = t; + } } } } diff --git a/core/java/android/hardware/TriggerEvent.java b/core/java/android/hardware/TriggerEvent.java deleted file mode 100644 index bdd39f3..0000000 --- a/core/java/android/hardware/TriggerEvent.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware; - -/** - * This class represents a Trigger Event - the event - * associated with a Trigger Sensor. When the sensor detects a trigger - * event condition, such as significant motion in the case of the - * {@link Sensor#TYPE_SIGNIFICANT_MOTION}, the {@link TriggerEventListener} - * is called with the TriggerEvent. The sensor is automatically canceled - * after the trigger. - * <p> - * This class holds information such as the value of the sensor - * when the trigger happened, the timestamp along with detailed - * information regarding the Sensor itself. - * </p> - * @see android.hardware.SensorManager - * @see android.hardware.TriggerEvent - * @see android.hardware.Sensor - */ -public final class TriggerEvent { - /** - * <p> - * The length and contents of the {@link #values values} array depends on - * which {@link android.hardware.Sensor sensor} type is being monitored (see - * also {@link SensorEvent} for a definition of the coordinate system used). - * </p> - * <h4> {@link Sensor#TYPE_SIGNIFICANT_MOTION} </h4> - * The value field is of length 1. value[0] = 1.0 when the sensor triggers. - * 1.0 is the only allowed value. - */ - public final float[] values; - - /** - * The sensor that generated this event. See - * {@link android.hardware.SensorManager SensorManager} for details. - */ - public Sensor sensor; - - /** - * The time in nanosecond at which the event happened - */ - public long timestamp; - - TriggerEvent(int size) { - values = new float[size]; - } -} diff --git a/core/java/android/hardware/TriggerEventListener.java b/core/java/android/hardware/TriggerEventListener.java deleted file mode 100644 index 76b2796..0000000 --- a/core/java/android/hardware/TriggerEventListener.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.hardware; - -/** - * This class is the listener used to handle Trigger Sensors. - * Trigger Sensors are sensors that trigger an event and are automatically - * disabled. {@link Sensor#TYPE_SIGNIFICANT_MOTION} is one such example. - * <p> - * SensorManager lets you access the device's {@link android.hardware.Sensor - * sensors}. Get an instance of this class by calling - * {@link android.content.Context#getSystemService(java.lang.String) - * Context.getSystemService()} with the argument - * {@link android.content.Context#SENSOR_SERVICE}. - * Usage details are explained in the example below. - * </p> - * - * <pre class="prettyprint"> - * class TriggerListener extends TriggerEventListener { - * public void onTrigger(TriggerEvent event) { - * // Do Work. - * - * // As it is a one shot sensor, it will be canceled automatically. - * // SensorManager.requestTriggerSensor(this, mSigMotion); needs to - * // be called again, if needed. - * } - * } - * public class SensorActivity extends Activity { - * private final SensorManager mSensorManager; - * private final Sensor mSigMotion; - * private final TriggerEventListener mListener = new TriggerEventListener(); - * - * public SensorActivity() { - * mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); - * mSigMotion = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); - * } - * - * protected void onResume() { - * super.onResume(); - * mSensorManager.requestTriggerSensor(mListener, mSigMotion); - * } - * - * protected void onPause() { - * super.onPause(); - * // Call disable to ensure that the trigger request has been canceled. - * mSensorManager.cancelTriggerSensor(mListener, mSigMotion); - * } - * - * } - * </pre> - * - * @see TriggerEvent - * @see Sensor - */ -public abstract class TriggerEventListener { - /** - * The method that will be called when the sensor - * is triggered. Override this method in your implementation - * of this class. - * - * @param event The details of the event. - */ - public abstract void onTrigger(TriggerEvent event); -} diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java index fd22b10..f140282 100644 --- a/core/java/android/net/DhcpStateMachine.java +++ b/core/java/android/net/DhcpStateMachine.java @@ -77,7 +77,7 @@ public class DhcpStateMachine extends StateMachine { RENEW }; - private String mInterfaceName; + private final String mInterfaceName; private boolean mRegisteredForPreDhcpNotification = false; private static final int BASE = Protocol.BASE_DHCP; @@ -349,6 +349,7 @@ public class DhcpStateMachine extends StateMachine { private boolean runDhcp(DhcpAction dhcpAction) { boolean success = false; DhcpResults dhcpResults = new DhcpResults(); + dhcpResults.linkProperties.mLogMe = true; if (dhcpAction == DhcpAction.START) { /* Stop any existing DHCP daemon before starting new */ diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index 5d13a18..9292e5f 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -20,6 +20,7 @@ import android.net.ProxyProperties; import android.os.Parcelable; import android.os.Parcel; import android.text.TextUtils; +import android.util.Log; import java.net.InetAddress; import java.net.UnknownHostException; @@ -57,6 +58,7 @@ public class LinkProperties implements Parcelable { private String mDomains; private Collection<RouteInfo> mRoutes = new ArrayList<RouteInfo>(); private ProxyProperties mHttpProxy; + public boolean mLogMe; public static class CompareResult<T> { public Collection<T> removed = new ArrayList<T>(); @@ -75,6 +77,7 @@ public class LinkProperties implements Parcelable { public LinkProperties() { clear(); + mLogMe = false; } // copy constructor instead of clone @@ -91,6 +94,14 @@ public class LinkProperties implements Parcelable { } public void setInterfaceName(String iface) { + if (mLogMe) { + Log.d("LinkProperties", "setInterfaceName from " + mIfaceName + + " to " + iface); + for (StackTraceElement e : Thread.currentThread().getStackTrace()) { + Log.d("LinkProperties", " " + e.toString()); + } + } + mIfaceName = iface; ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size()); for (RouteInfo route : mRoutes) { @@ -166,6 +177,13 @@ public class LinkProperties implements Parcelable { } public void clear() { + if (mLogMe) { + Log.d("LinkProperties", "clear from " + mIfaceName); + for (StackTraceElement e : Thread.currentThread().getStackTrace()) { + Log.d("LinkProperties", " " + e.toString()); + } + } + mIfaceName = null; mLinkAddresses.clear(); mDnses.clear(); diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp index 6374494..3083cb1 100644 --- a/core/jni/android_hardware_SensorManager.cpp +++ b/core/jni/android_hardware_SensorManager.cpp @@ -31,7 +31,7 @@ static struct { jclass clazz; jmethodID dispatchSensorEvent; -} gBaseEventQueueClassInfo; +} gSensorEventQueueClassInfo; namespace android { @@ -145,7 +145,7 @@ private: env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data); env->CallVoidMethod(mReceiverObject, - gBaseEventQueueClassInfo.dispatchSensorEvent, + gSensorEventQueueClassInfo.dispatchSensorEvent, buffer[i].sensor, mScratch, buffer[i].vector.status, @@ -209,9 +209,9 @@ static JNINativeMethod gSystemSensorManagerMethods[] = { (void*)nativeGetNextSensor }, }; -static JNINativeMethod gBaseEventQueueMethods[] = { - {"nativeInitBaseEventQueue", - "(Landroid/hardware/SystemSensorManager$BaseEventQueue;Landroid/os/MessageQueue;[F)I", +static JNINativeMethod gSensorEventQueueMethods[] = { + {"nativeInitSensorEventQueue", + "(Landroid/hardware/SystemSensorManager$SensorEventQueue;Landroid/os/MessageQueue;[F)I", (void*)nativeInitSensorEventQueue }, {"nativeEnableSensor", @@ -245,13 +245,13 @@ int register_android_hardware_SensorManager(JNIEnv *env) jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager", gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods)); - jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue", - gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods)); + jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$SensorEventQueue", + gSensorEventQueueMethods, NELEM(gSensorEventQueueMethods)); - FIND_CLASS(gBaseEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$BaseEventQueue"); + FIND_CLASS(gSensorEventQueueClassInfo.clazz, "android/hardware/SystemSensorManager$SensorEventQueue"); - GET_METHOD_ID(gBaseEventQueueClassInfo.dispatchSensorEvent, - gBaseEventQueueClassInfo.clazz, + GET_METHOD_ID(gSensorEventQueueClassInfo.dispatchSensorEvent, + gSensorEventQueueClassInfo.clazz, "dispatchSensorEvent", "(I[FIJ)V"); return 0; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 105f45f..4e6b552 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1169,6 +1169,7 @@ public: break; } mLocalBounds.set(x, mY + metrics.fTop, x + length, mY + metrics.fBottom); + memset(&mPrecacheTransform.data[0], 0xff, 16 * sizeof(float)); } /* @@ -1179,9 +1180,11 @@ public: virtual void onDrawOpDeferred(OpenGLRenderer& renderer) { SkPaint* paint = getPaint(renderer); FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint); - const bool pureTranslate = state.mMatrix.isPureTranslate(); - const mat4 transform = renderer.findBestFontTransform(state.mMatrix); - fontRenderer.precache(paint, mText, mCount, transform); + const mat4& transform = renderer.findBestFontTransform(state.mMatrix); + if (mPrecacheTransform != transform) { + fontRenderer.precache(paint, mText, mCount, transform); + mPrecacheTransform = transform; + } } virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level, @@ -1210,6 +1213,7 @@ private: float mY; const float* mPositions; float mLength; + mat4 mPrecacheTransform; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index 7b7357e..75e280c 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -93,6 +93,14 @@ public: return *this; } + friend bool operator==(const Matrix4& a, const Matrix4& b) { + return !memcmp(&a.data[0], &b.data[0], 16 * sizeof(float)); + } + + friend bool operator!=(const Matrix4& a, const Matrix4& b) { + return !(a == b); + } + void loadIdentity(); void load(const float* v); diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp index c932087..02c1aa1 100644 --- a/libs/hwui/font/Font.cpp +++ b/libs/hwui/font/Font.cpp @@ -15,10 +15,12 @@ */ #define LOG_TAG "OpenGLRenderer" +#define ATRACE_TAG ATRACE_TAG_VIEW #include <cutils/compiler.h> #include <utils/JenkinsHash.h> +#include <utils/Trace.h> #include <SkGlyph.h> #include <SkUtils.h> @@ -261,11 +263,8 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float } CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) { - CachedGlyphInfo* cachedGlyph = NULL; - ssize_t index = mCachedGlyphs.indexOfKey(textUnit); - if (index >= 0) { - cachedGlyph = mCachedGlyphs.valueAt(index); - + CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(textUnit); + if (cachedGlyph) { // Is the glyph still in texture cache? if (!cachedGlyph->mIsValid) { const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit, @@ -346,11 +345,13 @@ void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t le } void Font::precache(SkPaint* paint, const char* text, int numGlyphs) { + ATRACE_NAME("precacheText"); + if (numGlyphs == 0 || text == NULL) { return; } - int glyphsCount = 0; + int glyphsCount = 0; while (glyphsCount < numGlyphs) { glyph_t glyph = GET_GLYPH(text); @@ -360,7 +361,6 @@ void Font::precache(SkPaint* paint, const char* text, int numGlyphs) { } CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph, true); - glyphsCount++; } } diff --git a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java b/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java index cd7324c..c68bab5 100644 --- a/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java +++ b/policy/src/com/android/internal/policy/impl/keyguard/EmergencyButton.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.os.PowerManager; import android.os.SystemClock; +import android.os.UserHandle; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.view.View; @@ -104,7 +105,8 @@ public class EmergencyButton extends Button { Intent intent = new Intent(ACTION_EMERGENCY_DIAL); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - getContext().startActivity(intent); + getContext().startActivityAsUser(intent, + new UserHandle(mLockPatternUtils.getCurrentUser())); } } |
