Merge "Setting MTU size for specific network" into klp-dev
diff --git a/api/current.txt b/api/current.txt
index a8b5efd..dc21e90 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -10693,10 +10693,6 @@
method public int getMinFrequency();
}
- public abstract interface FlushCompleteListener {
- method public abstract void onFlushCompleted(android.hardware.Sensor);
- }
-
public class GeomagneticField {
ctor public GeomagneticField(float, float, float, long);
method public float getDeclination();
@@ -10754,6 +10750,10 @@
method public abstract void onSensorChanged(android.hardware.SensorEvent);
}
+ public abstract interface SensorEventListener2 implements android.hardware.SensorEventListener {
+ method public abstract void onFlushCompleted(android.hardware.Sensor);
+ }
+
public abstract deprecated interface SensorListener {
method public abstract void onAccuracyChanged(int, int);
method public abstract void onSensorChanged(int, float[]);
@@ -10761,7 +10761,7 @@
public abstract class SensorManager {
method public boolean cancelTriggerSensor(android.hardware.TriggerEventListener, android.hardware.Sensor);
- method public boolean flush(android.hardware.Sensor);
+ method public boolean flush(android.hardware.SensorEventListener);
method public static float getAltitude(float, float);
method public static void getAngleChange(float[], float[], float[]);
method public android.hardware.Sensor getDefaultSensor(int);
@@ -10775,9 +10775,9 @@
method public deprecated boolean registerListener(android.hardware.SensorListener, int);
method public deprecated boolean registerListener(android.hardware.SensorListener, int, int);
method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int);
- method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.hardware.FlushCompleteListener);
+ method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int);
method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, android.os.Handler);
- method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, int, int, android.os.Handler, android.hardware.FlushCompleteListener);
+ method public boolean registerListener(android.hardware.SensorEventListener, android.hardware.Sensor, int, 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);
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index e7e4a0f..6f929f2 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -513,7 +513,7 @@
}
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothA2dp.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 5eb642c..5822e46 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -322,7 +322,8 @@
/**
* Broadcast Action: This intent is used to broadcast PAIRING REQUEST
- * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED} to
+ * receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PAIRING_REQUEST =
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 1962514..8ee955d 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -885,7 +885,7 @@
return false;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothHeadset.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index b1a084a..2e950fa 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -519,7 +519,7 @@
mServiceListener = null;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothHealth.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index f9c789c..844f432 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -458,7 +458,7 @@
return BluetoothProfile.PRIORITY_OFF;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
mService = IBluetoothInputDevice.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index fac8fd5..92a2f1e 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -142,7 +142,6 @@
try {
mService = null;
mContext.unbindService(mConnection);
- mConnection = null;
} catch (Exception re) {
Log.e(TAG,"",re);
}
@@ -370,7 +369,7 @@
return PRIORITY_OFF;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) log("Proxy object connected");
mService = IBluetoothMap.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 83d4329..b7a37f4 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -155,23 +155,34 @@
/*package*/ void close() {
if (VDBG) log("close()");
- if (mConnection != null) {
- mContext.unbindService(mConnection);
- mConnection = null;
+
+ IBluetoothManager mgr = mAdapter.getBluetoothManager();
+ if (mgr != null) {
+ try {
+ mgr.unregisterStateChangeCallback(mStateChangeCallback);
+ } catch (RemoteException re) {
+ Log.w(TAG,"Unable to unregister BluetoothStateChangeCallback",re);
+ }
+ }
+
+ synchronized (mConnection) {
+ if (mPanService != null) {
+ try {
+ mPanService = null;
+ mContext.unbindService(mConnection);
+ } catch (Exception re) {
+ Log.e(TAG,"",re);
+ }
+ }
}
mServiceListener = null;
- try {
- mAdapter.getBluetoothManager().unregisterStateChangeCallback(mStateChangeCallback);
- } catch (RemoteException re) {
- Log.w(TAG,"Unable to register BluetoothStateChangeCallback",re);
- }
}
protected void finalize() {
close();
}
- private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
+ final private IBluetoothStateChangeCallback mStateChangeCallback = new IBluetoothStateChangeCallback.Stub() {
@Override
public void onBluetoothStateChange(boolean on) throws RemoteException {
@@ -339,7 +350,7 @@
return false;
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "BluetoothPAN Proxy object connected");
mPanService = IBluetoothPan.Stub.asInterface(service);
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index c42251f..7f45652 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -197,7 +197,6 @@
try {
mService = null;
mContext.unbindService(mConnection);
- mConnection = null;
} catch (Exception re) {
Log.e(TAG,"",re);
}
@@ -300,7 +299,7 @@
}
}
- private ServiceConnection mConnection = new ServiceConnection() {
+ private final ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) log("Proxy object connected");
mService = IBluetoothPbap.Stub.asInterface(service);
diff --git a/core/java/android/hardware/FlushCompleteListener.java b/core/java/android/hardware/SensorEventListener2.java
similarity index 89%
rename from core/java/android/hardware/FlushCompleteListener.java
rename to core/java/android/hardware/SensorEventListener2.java
index fbdf4c8..4c3b429 100644
--- a/core/java/android/hardware/FlushCompleteListener.java
+++ b/core/java/android/hardware/SensorEventListener2.java
@@ -19,7 +19,7 @@
/**
* Used for receiving a notification when a flush() has been successfully completed.
*/
-public interface FlushCompleteListener {
+public interface SensorEventListener2 extends SensorEventListener {
/**
* Called after flush() is completed. This flush() could have been initiated by this application
* or some other application. All the events in the batch at the point when the flush was called
@@ -28,7 +28,7 @@
*
* @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
*
- * @see android.hardware.SensorManager#flush(Sensor)
+ * @see android.hardware.SensorManager#flush(SensorEventListener)
*/
public void onFlushCompleted(Sensor sensor);
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 8a4aa1d..b931313 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -533,8 +533,6 @@
*
* @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) {
@@ -601,7 +599,6 @@
* @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 rateUs) {
return registerListener(listener, sensor, rateUs, null);
@@ -638,7 +635,9 @@
* {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
*
* @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
- * that will receive the sensor events.
+ * that will receive the sensor events. If the application is interested in receiving
+ * flush complete notifications, it should register with
+ * {@link android.hardware.SensorEventListener SensorEventListener2} instead.
* @param sensor The {@link android.hardware.Sensor Sensor} to register to.
* @param rateUs The desired delay between two consecutive events in microseconds. This is only
* a hint to the system. Events may be received faster or slower than the specified
@@ -651,30 +650,23 @@
* large. If this is set to zero, batch mode is disabled and events are delivered in
* continuous mode as soon as they are available which is equivalent to calling
* {@link #registerListener(SensorEventListener, Sensor, int)}.
- * @param reservedFlags Always set to Zero.
- * @param flushCompleteListener A {@link android.hardware.FlushCompleteListener
- * FlushCompleteListener} object which is called when any application calls flush()
- * on this sensor and all the events in the batch at the time of calling flush() are
- * successfully delivered to the listeners.
- * @return true if batch mode is successfully enabled for this sensor, false otherwise.
+ * @return <code>true</code> if batch mode is successfully enabled for this sensor,
+ * <code>false</code> otherwise.
* @see #registerListener(SensorEventListener, Sensor, int)
* @see #unregisterListener(SensorEventListener)
- * @see #flush(Sensor)
- * @throws IllegalArgumentException when sensor or listener is null or a trigger sensor.
+ * @see #flush(SensorEventListener)
*/
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
- int maxBatchReportLatencyUs, int reservedFlags,
- FlushCompleteListener flushCompleteListener) {
+ int maxBatchReportLatencyUs) {
int delay = getDelay(rateUs);
- return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs,
- reservedFlags, flushCompleteListener);
+ return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs, 0);
}
/**
* Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
* sensor. Events are delivered in continuous mode as soon as they are available. To reduce the
- * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int, int,
- * FlushCompleteListener)} which enables batch mode for the sensor.
+ * battery usage, use {@link #registerListener(SensorEventListener, Sensor, int, int)} which
+ * enables batch mode for the sensor.
*
* <p class="note"></p>
* Note: Don't use this method with a one shot trigger sensor such as
@@ -706,67 +698,80 @@
* {@link android.hardware.SensorEvent sensor events} will be
* delivered to.
*
- * @return true if the sensor is supported and successfully enabled.
+ * @return <code>true</code> if the sensor is supported and successfully enabled.
*
* @see #registerListener(SensorEventListener, Sensor, int)
* @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 rateUs,
Handler handler) {
- if (listener == null || sensor == null) {
- return false;
- }
-
int delay = getDelay(rateUs);
- return registerListenerImpl(listener, sensor, delay, handler, 0, 0, null);
+ return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
/**
* Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
- * @param handler
- * The {@link android.os.Handler Handler} the
- * {@link android.hardware.SensorEvent sensor events} will be
- * delivered to.
+ * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
+ * that will receive the sensor events. If the application is interested in receiving
+ * flush complete notifications, it should register with
+ * {@link android.hardware.SensorEventListener SensorEventListener2} instead.
+ * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+ * @param rateUs The desired delay between two consecutive events in microseconds. This is only
+ * a hint to the system. Events may be received faster or slower than the specified
+ * rate. Usually events are received faster. Can be one of
+ * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+ * {@link #SENSOR_DELAY_GAME}, {@link #SENSOR_DELAY_FASTEST} or the delay in
+ * microseconds.
+ * @param maxBatchReportLatencyUs An event in the batch can be delayed by at most
+ * maxBatchReportLatency microseconds. More events can be batched if this value is
+ * large. If this is set to zero, batch mode is disabled and events are delivered in
+ * continuous mode as soon as they are available which is equivalent to calling
+ * {@link #registerListener(SensorEventListener, Sensor, int)}.
+ * @param handler The {@link android.os.Handler Handler} the
+ * {@link android.hardware.SensorEvent sensor events} will be delivered to.
*
- * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
+ * @return <code>true</code> if batch mode is successfully enabled for this sensor,
+ * <code>false</code> otherwise.
+ * @see #registerListener(SensorEventListener, Sensor, int, int)
*/
public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
- int maxBatchReportLatencyUs, int reservedFlags, Handler handler,
- FlushCompleteListener flushCompleteListener) {
+ int maxBatchReportLatencyUs, Handler handler) {
int delayUs = getDelay(rateUs);
- return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs,
- reservedFlags, flushCompleteListener);
+ return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs, 0);
}
/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
- int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
- FlushCompleteListener flushCompleteListener);
+ int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags);
/**
- * Flushes the batch FIFO of the given sensor. If there are events in the FIFO of this sensor,
- * they are returned as if the batch timeout has expired. Events are returned in the
- * usual way through the SensorEventListener. This call doesn't effect the batch timeout for
- * this sensor. This call is asynchronous and returns immediately. FlushCompleteListener is
- * called after all the events in the batch at the time of calling this method have been
- * delivered successfully.
- * @param sensor
- * The {@link android.hardware.Sensor Sensor} to flush.
- * @return true if the flush is initiated successfully. false if the sensor isn't active
- * i.e no application is registered for updates from this sensor.
- * @see #registerListener(SensorEventListener, Sensor, int, int, int, FlushCompleteListener)
- * @throws IllegalArgumentException when sensor is null or a trigger sensor.
+ * Flushes the batch FIFO of all the sensors registered for this listener. If there are events
+ * in the FIFO of the sensor, they are returned as if the batch timeout in the FIFO of the
+ * sensors had expired. Events are returned in the usual way through the SensorEventListener.
+ * This call doesn't affect the batch timeout for this sensor. This call is asynchronous and
+ * returns immediately.
+ * {@link android.hardware.SensorEventListener2#onFlushCompleted onFlushCompleted} is called
+ * after all the events in the batch at the time of calling this method have been delivered
+ * successfully. If the hardware doesn't support flush, it still returns true and a trivial
+ * flush complete event is sent after the current event for all the clients registered for this
+ * sensor.
+ *
+ * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object
+ * which was previously used in a registerListener call.
+ * @return <code>true</code> if the flush is initiated successfully on all the sensors
+ * registered for this listener, false if no sensor is previously registered for this
+ * listener or flush on one of the sensors fails.
+ * @see #registerListener(SensorEventListener, Sensor, int, int)
+ * @throws IllegalArgumentException when listener is null.
*/
- public boolean flush(Sensor sensor) {
- return flushImpl(sensor);
+ public boolean flush(SensorEventListener listener) {
+ return flushImpl(listener);
}
/** @hide */
- protected abstract boolean flushImpl(Sensor sensor);
+ protected abstract boolean flushImpl(SensorEventListener listener);
/**
* <p>
diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java
index 9747f0d..14f67c5 100644
--- a/core/java/android/hardware/SystemSensorManager.java
+++ b/core/java/android/hardware/SystemSensorManager.java
@@ -93,17 +93,20 @@
/** @hide */
@Override
protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
- int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags,
- FlushCompleteListener flushCompleteListener) {
- if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
- if (listener == null) throw new IllegalArgumentException("listener cannot be null");
- if (reservedFlags != 0) throw new IllegalArgumentException("reservedFlags should be zero");
- if (delayUs < 0) throw new IllegalArgumentException("rateUs should be positive");
- if (maxBatchReportLatencyUs < 0)
- throw new IllegalArgumentException("maxBatchReportLatencyUs should be positive");
+ int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
+ if (listener == null || sensor == null) {
+ Log.e(TAG, "sensor or listener is null");
+ return false;
+ }
// Trigger Sensors should use the requestTriggerSensor call.
- if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
- throw new IllegalArgumentException("Trigger Sensors cannot use registerListener");
+ if (Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT) {
+ Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
+ return false;
+ }
+ if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
+ Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
+ return false;
+ }
// Invariants to preserve:
// - one Looper per SensorEventListener
@@ -113,7 +116,7 @@
SensorEventQueue queue = mSensorListeners.get(listener);
if (queue == null) {
Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
- queue = new SensorEventQueue(listener, looper, this, flushCompleteListener);
+ queue = new SensorEventQueue(listener, looper, this);
if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs, reservedFlags)) {
queue.dispose();
return false;
@@ -200,16 +203,17 @@
}
}
- protected boolean flushImpl(Sensor sensor) {
- if (sensor == null) throw new IllegalArgumentException("sensor cannot be null");
- if(Sensor.getReportingMode(sensor) == Sensor.REPORTING_MODE_ONE_SHOT)
- throw new IllegalArgumentException("Trigger Sensors cannot call flush");
+ protected boolean flushImpl(SensorEventListener listener) {
+ if (listener == null) throw new IllegalArgumentException("listener cannot be null");
- FlushEventQueue queue = new FlushEventQueue(mMainLooper, this);
- if (queue.flushSensor(sensor) != 0) {
- return false;
+ synchronized (mSensorListeners) {
+ SensorEventQueue queue = mSensorListeners.get(listener);
+ if (queue == null) {
+ return false;
+ } else {
+ return (queue.flush() == 0);
+ }
}
- return true;
}
/*
@@ -224,7 +228,7 @@
int maxBatchReportLatencyUs, int reservedFlags);
private static native int nativeDisableSensor(int eventQ, int handle);
private static native void nativeDestroySensorEventQueue(int eventQ);
- private static native int nativeFlushSensor(int eventQ, int handle);
+ private static native int nativeFlushSensor(int eventQ);
private int nSensorEventQueue;
private final SparseBooleanArray mActiveSensors = new SparseBooleanArray();
protected final SparseIntArray mSensorAccuracies = new SparseIntArray();
@@ -291,10 +295,9 @@
return false;
}
- public int flushSensor(Sensor sensor) {
+ public int flush() {
if (nSensorEventQueue == 0) throw new NullPointerException();
- if (sensor == null) throw new NullPointerException();
- return nativeFlushSensor(nSensorEventQueue, sensor.getHandle());
+ return nativeFlushSensor(nSensorEventQueue);
}
public boolean hasSensors() {
@@ -347,14 +350,12 @@
static final class SensorEventQueue extends BaseEventQueue {
private final SensorEventListener mListener;
- private final FlushCompleteListener mFlushCompleteListener;
private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();
public SensorEventQueue(SensorEventListener listener, Looper looper,
- SystemSensorManager manager, FlushCompleteListener flushCompleteListener) {
+ SystemSensorManager manager) {
super(looper, manager);
mListener = listener;
- mFlushCompleteListener = flushCompleteListener;
}
public void addSensorEvent(Sensor sensor) {
@@ -408,9 +409,9 @@
@SuppressWarnings("unused")
protected void dispatchFlushCompleteEvent(int handle) {
- final Sensor sensor = sHandleToSensor.get(handle);
- if (mFlushCompleteListener != null) {
- mFlushCompleteListener.onFlushCompleted(sensor);
+ if (mListener instanceof SensorEventListener2) {
+ final Sensor sensor = sHandleToSensor.get(handle);
+ ((SensorEventListener2)mListener).onFlushCompleted(sensor);
}
return;
}
@@ -464,30 +465,4 @@
protected void dispatchFlushCompleteEvent(int handle) {
}
}
-
- static final class FlushEventQueue extends BaseEventQueue {
- public FlushEventQueue(Looper looper, SystemSensorManager manager) {
- super(looper, manager);
- }
-
- @SuppressWarnings("unused")
- @Override
- protected void dispatchSensorEvent(int handle, float[] values, int accuracy,
- long timestamp) {
- }
-
- @Override
- @SuppressWarnings("unused")
- protected void addSensorEvent(Sensor sensor) {
- }
-
- @Override
- @SuppressWarnings("unused")
- protected void removeSensorEvent(Sensor sensor) {
- }
-
- @SuppressWarnings("unused")
- protected void dispatchFlushCompleteEvent(int handle) {
- }
- }
}
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 648a4b3..78ac75f 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -178,7 +178,7 @@
// If PAC URL is present in either then they must be equal.
// Other parameters will only be for fall back.
if (!TextUtils.isEmpty(mPacFileUrl)) {
- return mPacFileUrl.equals(p.getPacFileUrl());
+ return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
}
if (!TextUtils.isEmpty(p.getPacFileUrl())) {
return false;
@@ -219,6 +219,7 @@
if (mPacFileUrl != null) {
dest.writeByte((byte)1);
dest.writeString(mPacFileUrl);
+ dest.writeInt(mPort);
return;
} else {
dest.writeByte((byte)0);
@@ -244,7 +245,9 @@
String host = null;
int port = 0;
if (in.readByte() != 0) {
- return new ProxyProperties(in.readString());
+ String url = in.readString();
+ int localPort = in.readInt();
+ return new ProxyProperties(url, localPort);
}
if (in.readByte() != 0) {
host = in.readString();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 23ed019..44e7ec1 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -160,8 +160,7 @@
public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) {
View actionView = item.getActionView();
if (actionView == null || item.hasCollapsibleActionView()) {
- // Don't recycle existing item views for action buttons; it interferes with transitions.
- actionView = super.getItemView(item, null, parent);
+ actionView = super.getItemView(item, convertView, parent);
}
actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
index ccedf63..071193c 100644
--- a/core/java/com/android/internal/widget/SubtitleView.java
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -180,7 +180,9 @@
mInnerPaddingX = (int) (size * INNER_PADDING_RATIO + 0.5f);
mHasMeasurements = false;
- forceLayout();
+
+ requestLayout();
+ invalidate();
}
}
@@ -189,7 +191,9 @@
mTextPaint.setTypeface(typeface);
mHasMeasurements = false;
- forceLayout();
+
+ requestLayout();
+ invalidate();
}
}
@@ -198,7 +202,9 @@
mAlignment = textAlignment;
mHasMeasurements = false;
- forceLayout();
+
+ requestLayout();
+ invalidate();
}
}
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 4290a6e..793d1bf 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -220,9 +220,9 @@
receiver->decStrong((void*)nativeInitSensorEventQueue);
}
-static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ, jint handle) {
+static jint nativeFlushSensor(JNIEnv *env, jclass clazz, jint eventQ) {
sp<Receiver> receiver(reinterpret_cast<Receiver *>(eventQ));
- return receiver->getSensorEventQueue()->flushSensor(handle);
+ return receiver->getSensorEventQueue()->flush();
}
//----------------------------------------------------------------------------
@@ -255,7 +255,7 @@
(void*)nativeDestroySensorEventQueue },
{"nativeFlushSensor",
- "(II)I",
+ "(I)I",
(void*)nativeFlushSensor },
};
diff --git a/core/res/res/drawable-hdpi/stat_sys_gps_on.png b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
index cb8a1e8..e0f7740 100644
--- a/core/res/res/drawable-hdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-hdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_gps_on.png b/core/res/res/drawable-ldpi/stat_sys_gps_on.png
index 8915c59..77776f5 100644
--- a/core/res/res/drawable-ldpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-ldpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_gps_on.png b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
index 2c98972..311a1de 100644
--- a/core/res/res/drawable-mdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-mdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_gps_on.png b/core/res/res/drawable-xhdpi/stat_sys_gps_on.png
index a7408d4..8a6edfb 100644
--- a/core/res/res/drawable-xhdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-xhdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png b/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png
index 81fb04a..063f614 100755
--- a/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png
+++ b/core/res/res/drawable-xxhdpi/stat_sys_gps_on.png
Binary files differ
diff --git a/docs/html/distribute/googleplay/spotlight/games.jd b/docs/html/distribute/googleplay/spotlight/games.jd
index 4e356db..1fbc03f 100644
--- a/docs/html/distribute/googleplay/spotlight/games.jd
+++ b/docs/html/distribute/googleplay/spotlight/games.jd
@@ -102,7 +102,7 @@
width: 78px;
float: left;
margin: 12px 20px 30px 20px;"
- src="//lh5.ggpht.com/l20dR2HYLV8vECoC35q_0NdfaAGTe4lZIFy_wCJRDqZjeQqSgneLRpXi3qOnnCaLXA=w124">
+ src="//lh4.ggpht.com/Q7mQJsdhulW4_s039R9aaRhQkGnyzLkhF00j5EnyhHOivijnyi7P7b5A8qG0xk1r-jQ=w124">
<div style="list-style: none;height:100%;
float: right;
diff --git a/docs/html/distribute/googleplay/spotlight/tablets.jd b/docs/html/distribute/googleplay/spotlight/tablets.jd
index cfea29a..7a98755 100644
--- a/docs/html/distribute/googleplay/spotlight/tablets.jd
+++ b/docs/html/distribute/googleplay/spotlight/tablets.jd
@@ -17,7 +17,90 @@
expand their offering to include Android tablets.</p>
-<div style="margin-bottom:2em;"><!-- START STORY -->
+<div style="margin-bottom:2em;" id="rememberthemilk"><!-- START STORY -->
+
+<h3>Remember The Milk: Lifting installs with tablet design</h3>
+
+ <img alt="" class="screenshot thumbnail" style="-webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px height:78px;
+ width: 78px;
+ float: left;
+ margin: 12px 20px 9px 20px;" src=
+ "//lh3.ggpht.com/xmnal18taauP2mjQFEhr1PhcItQ_W32IRuaD86IoL2U_4E-mfeKiliKtkISgOuA6Ln9n=w124">
+
+ <div style="list-style: none;height:100%;
+ float: right;
+ border-top: 1px solid #9C0;
+ width: 220px;
+ margin: 4px 20px;padding: .5em;">
+
+
+ <h5>About the app</h5>
+
+
+ <ul>
+ <li><a href="//play.google.com/store/apps/details?id=com.rememberthemilk.MobileRTM">Remember The Milk</a></li>
+ <li>A feature-packed to-do list app; never forget the milk (or anything else) again</li>
+ </ul>
+
+ <h5>Tablet Results</h5>
+
+ <ul>
+ <li>83% jump in tablet installs following update </li>
+ <li>Nexus 7 is most popular Android device for app </li>
+ <li>Single APK for phones and tablets</li>
+ </ul>
+
+ <div style="padding:.5em 0 0 1em;">
+ <a href="//play.google.com/store/apps/details?id=com.rememberthemilk.MobileRTM">
+ <img alt="Android app on Google Play"
+ src="//developer.android.com/images/brand/en_generic_rgb_wo_45.png" />
+ </a>
+
+ </div>
+ </div>
+
+ <div style="line-height:1.4em;">
+ <p style="margin-top:0;margin-bottom:12px;">When the Android tablet guidelines
+ came out in 2012, the team at Remember The Milk had already been thinking about
+ a redesign for their <a href="//play.google.com/store/apps/details?id=com.rememberthemilk.MobileRTM">feature-packed
+ to-do list app</a>. Omar Kilani, Co-founder of Remember The Milk, explains how
+ <a href="//blog.rememberthemilk.com/2013/04/the-all-new-remember-the-milk-for-android-and-tablets-too/">updating</a>
+ their app to meet the tablet guidelines lead to an 83% jump in tablet installs: </p>
+
+ <p>“We took this as an opportunity to think about how we were going to approach
+ Android tablets differently from a user experience perspective. The guidelines
+ were a helpful resource, and with the extra screen real estate tablets afford,
+ users have the opportunity to see all of their data in context and drill down
+ on more items. All of this is accomplished using a single APK on Play, even though
+ the phone and tablet versions each capture completely different use cases for us.”</p>
+
+ <p>“In the month after updating, we saw our tablet installs on Google Play jump 83%,
+ and the Nexus 7 is now the most popular Android device amongst our users. For us,
+ designing for tablets was an investment that has really paid off.”</p>
+
+ <p>The team also came out with a number of other goodies — including a new set of
+ widgets and richer notifications, and more ways to provide an immersive experience
+ for their users.</p>
+ </div>
+
+ <div style="clear:both;margin-top:30px;width:auto;">
+
+ <img src="{@docRoot}images/distribute/rememberthemilk.png">
+
+ <div style="width:600px;margin-top:0px;padding:0 90px;">
+ <p class="image-caption"><span style="font-weight:500;">Tablet redesign led to lift
+ in installs</span>: Following the redesign of the Android app, in part to meet the tablet
+ design criteria, Remember The Milk saw an 83% increase in tablet installs.</p>
+ </div>
+
+ </div>
+
+</div> <!-- END STORY -->
+
+
+<div style="margin-bottom:2em;" id="mint"><!-- START STORY -->
<h3>Mint: More screen real estate = more engagement</h3>
@@ -96,7 +179,7 @@
<div style="clear:both;margin-top:40px;width:auto;">
- <a href=""><img src="{@docRoot}images/distribute/mint.png"></a>
+ <img src="{@docRoot}images/distribute/mint.png">
<div style="width:600px;margin-top:0px;padding:0 90px;">
<p class="image-caption"><span style="font-weight:500;">Making the most of tablet screens</span>: Mint used the extra screen area on tablets to offer quick access to additional tools and information.</p>
@@ -184,7 +267,7 @@
<div style="clear:both;margin-top:40px;width:auto;">
- <a href=""><img src="{@docRoot}images/distribute/tinyvillage.png"></a>
+ <img src="{@docRoot}images/distribute/tinyvillage.png">
<div style="width:600px;margin-top:0px;padding:0 90px;">
<p class="image-caption"><span style="font-weight:500;">More monetization
@@ -268,7 +351,7 @@
<div style="clear:both;margin-top:40px;width:auto;">
- <a href=""><img src="{@docRoot}images/distribute/instapaper.png"></a>
+ <img src="{@docRoot}images/distribute/instapaper.png">
<div style="width:600px;margin-top:0px;padding:0 90px;">
<p class="image-caption"><span style="font-weight:500;">Popular with
diff --git a/docs/html/images/distribute/rememberthemilk.png b/docs/html/images/distribute/rememberthemilk.png
new file mode 100644
index 0000000..b170cf3
--- /dev/null
+++ b/docs/html/images/distribute/rememberthemilk.png
Binary files differ
diff --git a/docs/html/training/articles/security-tips.jd b/docs/html/training/articles/security-tips.jd
index 1ac56b9..54aebac 100644
--- a/docs/html/training/articles/security-tips.jd
+++ b/docs/html/training/articles/security-tips.jd
@@ -553,7 +553,7 @@
or an explicit intent to a specific application component.</p>
<p>Note that ordered broadcasts can be “consumed” by a recipient, so they
-may not be delivered to all applications. If you are sending an intent that muse be delivered
+may not be delivered to all applications. If you are sending an intent that must be delivered
to a specific receiver, then you must use an explicit intent that declares the receiver
by nameintent.</p>
diff --git a/packages/Keyguard/res/values-mcc262-mnc07/bools.xml b/packages/Keyguard/res/values-mcc262-mnc07/bools.xml
new file mode 100644
index 0000000..6cd4c55
--- /dev/null
+++ b/packages/Keyguard/res/values-mcc262-mnc07/bools.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <!-- Carriers in this locale are sensitive to capitalization of carrier text.
+ This makes the entire interface consistent by switching back to normal case. -->
+ <bool name="kg_use_all_caps">false</bool>
+</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
index 146c092..7d1f24f 100644
--- a/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
+++ b/packages/Keyguard/src/com/android/keyguard/CameraWidgetFrame.java
@@ -19,11 +19,13 @@
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
+import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -55,15 +57,17 @@
private final WindowManager mWindowManager;
private final Point mRenderedSize = new Point();
private final int[] mTmpLoc = new int[2];
- private final Rect mTmpRect = new Rect();
private long mLaunchCameraStart;
private boolean mActive;
private boolean mTransitioning;
private boolean mDown;
+ private final Rect mInsets = new Rect();
+
private FixedSizeFrameLayout mPreview;
private View mFullscreenPreview;
+ private View mFakeNavBar;
private final Runnable mTransitionToCameraRunnable = new Runnable() {
@Override
@@ -211,10 +215,11 @@
private void render() {
final View root = getRootView();
- final int width = root.getWidth();
- final int height = root.getHeight();
+ final int width = root.getWidth() - mInsets.right; // leave room
+ final int height = root.getHeight() - mInsets.bottom; // for bars
if (mRenderedSize.x == width && mRenderedSize.y == height) {
- if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s", width, height));
+ if (DEBUG) Log.d(TAG, String.format("Already rendered at size=%sx%s %d%%",
+ width, height, (int)(100*mPreview.getScaleX())));
return;
}
if (width == 0 || height == 0) {
@@ -246,8 +251,8 @@
mPreview.setTranslationY(pvTransY);
mRenderedSize.set(width, height);
- if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s instance=%s",
- width, height, instanceId()));
+ if (DEBUG) Log.d(TAG, String.format("Rendered camera widget size=%sx%s %d%% instance=%s",
+ width, height, (int)(100*mPreview.getScaleX()), instanceId()));
}
private void transitionToCamera() {
@@ -257,24 +262,34 @@
enableWindowExitAnimation(false);
+ final int navHeight = mInsets.bottom;
+ final int navWidth = mInsets.right;
+
mPreview.getLocationInWindow(mTmpLoc);
final float pvHeight = mPreview.getHeight() * mPreview.getScaleY();
final float pvCenter = mTmpLoc[1] + pvHeight / 2f;
final ViewGroup root = (ViewGroup) getRootView();
+
+ if (DEBUG) {
+ Log.d(TAG, "root = " + root.getLeft() + "," + root.getTop() + " "
+ + root.getWidth() + "x" + root.getHeight());
+ }
+
if (mFullscreenPreview == null) {
mFullscreenPreview = getPreviewWidget(mContext, mWidgetInfo);
mFullscreenPreview.setClickable(false);
- root.addView(mFullscreenPreview);
+ root.addView(mFullscreenPreview, new FrameLayout.LayoutParams(
+ root.getWidth() - navWidth,
+ root.getHeight() - navHeight));
}
- root.getWindowVisibleDisplayFrame(mTmpRect);
- final float fsHeight = mTmpRect.height();
- final float fsCenter = mTmpRect.top + fsHeight / 2;
+ final float fsHeight = root.getHeight() - navHeight;
+ final float fsCenter = root.getTop() + fsHeight / 2;
- final float fsScaleY = pvHeight / fsHeight;
+ final float fsScaleY = mPreview.getScaleY();
final float fsTransY = pvCenter - fsCenter;
- final float fsScaleX = mPreview.getScaleX();
+ final float fsScaleX = fsScaleY;
mPreview.setVisibility(View.GONE);
mFullscreenPreview.setVisibility(View.VISIBLE);
@@ -290,6 +305,36 @@
.setDuration(WIDGET_ANIMATION_DURATION)
.withEndAction(mPostTransitionToCameraEndAction)
.start();
+
+ if (navHeight > 0 || navWidth > 0) {
+ final boolean atBottom = navHeight > 0;
+ if (mFakeNavBar == null) {
+ mFakeNavBar = new View(mContext);
+ mFakeNavBar.setBackgroundColor(Color.BLACK);
+ root.addView(mFakeNavBar, new FrameLayout.LayoutParams(
+ atBottom ? FrameLayout.LayoutParams.MATCH_PARENT
+ : navWidth,
+ atBottom ? navHeight
+ : FrameLayout.LayoutParams.MATCH_PARENT,
+ atBottom ? Gravity.BOTTOM|Gravity.FILL_HORIZONTAL
+ : Gravity.RIGHT|Gravity.FILL_VERTICAL));
+ mFakeNavBar.setPivotY(navHeight);
+ mFakeNavBar.setPivotX(navWidth);
+ }
+ mFakeNavBar.setAlpha(0f);
+ if (atBottom) {
+ mFakeNavBar.setScaleY(0.5f);
+ } else {
+ mFakeNavBar.setScaleX(0.5f);
+ }
+ mFakeNavBar.setVisibility(View.VISIBLE);
+ mFakeNavBar.animate()
+ .alpha(1f)
+ .scaleY(1f)
+ .scaleY(1f)
+ .setDuration(WIDGET_ANIMATION_DURATION)
+ .start();
+ }
mCallbacks.onLaunchingCamera();
}
@@ -397,6 +442,10 @@
mFullscreenPreview.animate().cancel();
mFullscreenPreview.setVisibility(View.GONE);
}
+ if (mFakeNavBar != null) {
+ mFakeNavBar.animate().cancel();
+ mFakeNavBar.setVisibility(View.GONE);
+ }
enableWindowExitAnimation(true);
}
@@ -404,6 +453,10 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (DEBUG) Log.d(TAG, String.format("onSizeChanged new=%sx%s old=%sx%s at %s",
w, h, oldw, oldh, SystemClock.uptimeMillis()));
+ if ((w != oldw && oldw > 0) || (h != oldh && oldh > 0)) {
+ // we can't trust the old geometry anymore; force a re-render
+ mRenderedSize.x = mRenderedSize.y = -1;
+ }
mHandler.post(mRenderRunnable);
super.onSizeChanged(w, h, oldw, oldh);
}
@@ -454,4 +507,9 @@
private String instanceId() {
return Integer.toHexString(hashCode());
}
+
+ public void setInsets(Rect insets) {
+ if (DEBUG) Log.d(TAG, "setInsets: " + insets);
+ mInsets.set(insets);
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index c4be72f..ef3d712 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -1454,6 +1454,9 @@
mInsets.set(insets);
if (mSlidingChallengeLayout != null) mSlidingChallengeLayout.setInsets(mInsets);
if (mMultiPaneChallengeLayout != null) mMultiPaneChallengeLayout.setInsets(mInsets);
+
+ final CameraWidgetFrame cameraWidget = findCameraPage();
+ if (cameraWidget != null) cameraWidget.setInsets(mInsets);
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 58ca0b0..d37aaaf 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -85,6 +85,7 @@
public void onSetBackground(Bitmap bmp) {
mKeyguardHost.setCustomBackground(bmp != null ?
new BitmapDrawable(mContext.getResources(), bmp) : null);
+ updateShowWallpaper(bmp == null);
}
};
@@ -379,6 +380,16 @@
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
}
+ void updateShowWallpaper(boolean show) {
+ if (show) {
+ mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+ } else {
+ mWindowLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+ }
+
+ mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
+ }
+
public void setNeedsInput(boolean needsInput) {
mNeedsInput = needsInput;
if (mWindowLayoutParams != null) {
@@ -489,6 +500,7 @@
lastView.cleanUp();
// Let go of any large bitmaps.
mKeyguardHost.setCustomBackground(null);
+ updateShowWallpaper(true);
mKeyguardHost.removeView(lastView);
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
index d1862cd..7039218 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -17,12 +17,14 @@
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
import android.view.View;
public class KeyguardViewStateManager implements
SlidingChallengeLayout.OnChallengeScrolledListener,
ChallengeLayout.OnBouncerStateChangedListener {
+ private static final String TAG = "KeyguardViewStateManager";
private KeyguardWidgetPager mKeyguardWidgetPager;
private ChallengeLayout mChallengeLayout;
private KeyguardHostView mKeyguardHostView;
@@ -100,18 +102,20 @@
}
public void fadeOutSecurity(int duration) {
- ((View) mKeyguardSecurityContainer).animate().alpha(0).setDuration(duration);
+ ((View) mKeyguardSecurityContainer).animate().alpha(0f).setDuration(duration).start();
}
public void fadeInSecurity(int duration) {
- ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration);
+ ((View) mKeyguardSecurityContainer).animate().alpha(1f).setDuration(duration).start();
}
public void onPageBeginMoving() {
if (mChallengeLayout.isChallengeOverlapping() &&
mChallengeLayout instanceof SlidingChallengeLayout) {
SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
- scl.fadeOutChallenge();
+ if (!mKeyguardWidgetPager.isWarping()) {
+ scl.fadeOutChallenge();
+ }
mPageIndexOnPageBeginMoving = mKeyguardWidgetPager.getCurrentPage();
}
// We use mAppWidgetToShow to show a particular widget after you add it--
@@ -133,7 +137,9 @@
public void onPageSwitching(View newPage, int newPageIndex) {
if (mKeyguardWidgetPager != null && mChallengeLayout instanceof SlidingChallengeLayout) {
boolean isCameraPage = newPage instanceof CameraWidgetFrame;
- ((SlidingChallengeLayout) mChallengeLayout).setChallengeInteractive(!isCameraPage);
+ SlidingChallengeLayout scl = (SlidingChallengeLayout) mChallengeLayout;
+ scl.setChallengeInteractive(!isCameraPage);
+ if (isCameraPage) scl.fadeOutChallenge();
}
// If the page we're settling to is the same as we started on, and the action of
@@ -174,13 +180,15 @@
}
public void onPageBeginWarp() {
- // fadeOutSecurity(WARP_FADE_DURATION);
- // mKeyguardWidgetPager.showNonWarpViews(WARP_FADE_DURATION, false);
+ fadeOutSecurity(SlidingChallengeLayout.CHALLENGE_FADE_OUT_DURATION);
+ View frame = mKeyguardWidgetPager.getPageAt(mKeyguardWidgetPager.getPageWarpIndex());
+ ((KeyguardWidgetFrame)frame).showFrame(this);
}
public void onPageEndWarp() {
- // fadeInSecurity(WARP_FADE_DURATION);
- // mKeyguardWidgetPager.showNonWarpViews(WARP_FADE_DURATION, true);
+ fadeInSecurity(SlidingChallengeLayout.CHALLENGE_FADE_IN_DURATION);
+ View frame = mKeyguardWidgetPager.getPageAt(mKeyguardWidgetPager.getPageWarpIndex());
+ ((KeyguardWidgetFrame)frame).hideFrame(this);
}
private int getChallengeTopRelativeToFrame(KeyguardWidgetFrame frame, int top) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
index f8857ab..704af6e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -188,11 +188,13 @@
@Override
public void onPageBeginWarp() {
+ showOutlinesAndSidePages();
mViewStateManager.onPageBeginWarp();
}
@Override
public void onPageEndWarp() {
+ hideOutlinesAndSidePages();
mViewStateManager.onPageEndWarp();
}
@@ -495,7 +497,7 @@
}
public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
- if (getPageWarpIndex() != -1) {
+ if (isWarping()) {
return index == getPageWarpIndex() ? 1.0f : 0.0f;
}
if (showSidePages) {
@@ -949,17 +951,17 @@
// to keep event dispatch happy.
mCameraEventInProgress = true;
userActivity();
- startWarp(cameraPage);
+ startPageWarp(cameraPage);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mCameraEventInProgress = false;
- endWarp = true;
+ endWarp = isWarping();
break;
}
dispatchTouchEvent(event);
// This has to happen after the event has been handled by the real widget pager
- if (endWarp) endWarp();
+ if (endWarp) stopPageWarp();
}
endCameraEvent();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
index 666227c..6cf6953 100644
--- a/packages/Keyguard/src/com/android/keyguard/PagedView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -47,6 +47,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -60,12 +61,13 @@
* sequential list of "pages"
*/
public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarchyChangeListener {
+ private static final int WARP_SNAP_DURATION = 160;
private static final String TAG = "WidgetPagedView";
private static final boolean DEBUG = false;
private static final boolean DEBUG_WARP = false;
protected static final int INVALID_PAGE = -1;
- private static final int WARP_PEEK_ANIMATION_DURATION = 250;
- private static final float WARP_ANIMATE_AMOUNT = -40.0f; // in dip
+ private static final int WARP_PEEK_ANIMATION_DURATION = 150;
+ private static final float WARP_ANIMATE_AMOUNT = -75.0f; // in dip
// the min drag distance for a fling to register, to prevent random page shifts
private static final int MIN_LENGTH_FOR_FLING = 25;
@@ -261,6 +263,8 @@
private boolean mIsCameraEvent;
private float mWarpPeekAmount;
+ private boolean mAnimatingWarp; // true while warped page is being animated
+ private boolean mFingerDown;
public interface PageSwitchListener {
void onPageSwitching(View newPage, int newPageIndex);
@@ -484,7 +488,7 @@
if (DEBUG_WARP) Log.v(TAG, "pageBeginMoving(" + mIsPageMoving + ")");
if (!mIsPageMoving) {
mIsPageMoving = true;
- if (mPageWarpIndex != -1) {
+ if (isWarping()) {
onPageBeginWarp();
if (mPageSwapIndex != -1) {
swapPages(mPageSwapIndex, mPageWarpIndex);
@@ -498,12 +502,12 @@
if (DEBUG_WARP) Log.v(TAG, "pageEndMoving(" + mIsPageMoving + ")");
if (mIsPageMoving) {
mIsPageMoving = false;
- if (mPageWarpIndex != -1) {
+ if (isWarping()) {
if (mPageSwapIndex != -1) {
swapPages(mPageSwapIndex, mPageWarpIndex);
- resetPageWarp();
}
onPageEndWarp();
+ resetPageWarp();
}
onPageEndMoving();
}
@@ -1124,8 +1128,8 @@
}
case MotionEvent.ACTION_DOWN: {
- if (mIsCameraEvent) {
- animateWarpPageOnScreen();
+ if (mIsCameraEvent && !mAnimatingWarp) {
+ animateWarpPageOnScreen("interceptTouch(): DOWN");
}
// Remember where the motion event started
saveDownState(ev);
@@ -1219,6 +1223,8 @@
mTotalMotionX = 0;
mActivePointerId = ev.getPointerId(0);
+ mFingerDown = true;
+
// Determine if the down event is within the threshold to be an edge swipe
int leftEdgeBoundary = getViewportOffsetX() + mEdgeSwipeRegionSize;
int rightEdgeBoundary = getMeasuredWidth() - getViewportOffsetX() - mEdgeSwipeRegionSize;
@@ -1393,8 +1399,10 @@
if (mTouchState == TOUCH_STATE_SCROLLING) {
pageBeginMoving();
- } else {
- animateWarpPageOnScreen();
+ }
+
+ if (mIsCameraEvent && !mAnimatingWarp) {
+ animateWarpPageOnScreen("onTouch(): DOWN");
}
break;
@@ -1571,7 +1579,8 @@
// move to the left and fling to the right will register as a fling to the right.
if (((isSignificantMove && deltaX > 0 && !isFling) ||
(isFling && velocityX > 0)) && mCurrentPage > 0) {
- finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage - 1;
+ finalPage = returnToOriginalPage || isWarping()
+ ? mCurrentPage : mCurrentPage - 1;
snapToPageWithVelocity(finalPage, velocityX);
} else if (((isSignificantMove && deltaX < 0 && !isFling) ||
(isFling && velocityX < 0)) &&
@@ -1661,6 +1670,7 @@
setTouchState(TOUCH_STATE_REST);
mActivePointerId = INVALID_POINTER;
mDownEventOnEdge = false;
+ mFingerDown = false;
}
protected void onUnhandledTap(MotionEvent ev) {}
@@ -1790,7 +1800,14 @@
}
protected void snapToDestination() {
- snapToPage(getPageNearestToCenterOfScreen(), PAGE_SNAP_ANIMATION_DURATION);
+ if (isWarping()) {
+ cancelWarpAnimation("snapToDestination");
+ }
+ snapToPage(getPageNearestToCenterOfScreen(), getPageSnapDuration());
+ }
+
+ private int getPageSnapDuration() {
+ return isWarping() ? WARP_SNAP_DURATION : PAGE_SNAP_ANIMATION_DURATION;
}
private static class ScrollInterpolator implements Interpolator {
@@ -1817,6 +1834,10 @@
whichPage = Math.max(0, Math.min(whichPage, getChildCount() - 1));
int halfScreenSize = getViewportWidth() / 2;
+ if (isWarping()) {
+ cancelWarpAnimation("snapToPageWithVelocity");
+ }
+
if (DEBUG) Log.d(TAG, "snapToPage.getChildOffset(): " + getChildOffset(whichPage));
if (DEBUG) Log.d(TAG, "snapToPageWithVelocity.getRelativeChildOffset(): "
+ getViewportWidth() + ", " + getChildWidth(whichPage));
@@ -1827,7 +1848,7 @@
if (Math.abs(velocity) < mMinFlingVelocity) {
// If the velocity is low enough, then treat this more as an automatic page advance
// as opposed to an apparent physical response to flinging
- snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+ snapToPage(whichPage, getPageSnapDuration());
return;
}
@@ -1851,10 +1872,10 @@
}
protected void snapToPage(int whichPage) {
- snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION);
+ snapToPage(whichPage, getPageSnapDuration());
}
protected void snapToPageImmediately(int whichPage) {
- snapToPage(whichPage, PAGE_SNAP_ANIMATION_DURATION, true);
+ snapToPage(whichPage, getPageSnapDuration(), true);
}
protected void snapToPage(int whichPage, int duration) {
@@ -1884,8 +1905,8 @@
mNextPage = whichPage;
}
- if (mPageWarpIndex != -1) {
- animateWarpPageOffScreen();
+ if (isWarping()) {
+ onPageEndWarp();
resetPageWarp();
}
@@ -1918,6 +1939,10 @@
invalidate();
}
+ protected boolean isWarping() {
+ return mPageWarpIndex != -1;
+ }
+
public void scrollLeft() {
if (mScroller.isFinished()) {
if (mCurrentPage > 0) snapToPage(mCurrentPage - 1);
@@ -2650,21 +2675,53 @@
mIsCameraEvent = false;
}
- private void animateWarpPageOnScreen() {
- if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOnScreen()");
- if (mPageWarpIndex != -1) {
+ AnimatorListenerAdapter mFinishWarpAnimationListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mAnimatingWarp = false;
+ if (!mFingerDown) {
+ animateWarpPageOffScreen("animation end", true);
+ }
+ }
+ };
+
+ private void cancelWarpAnimation(String msg) {
+ if (DEBUG_WARP) Log.v(TAG, "cancelWarpAnimation(" + msg + ")");
+ // We're done with the animation, let the scroller take over the positioning
+ KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+ v.animate().cancel();
+ v.setTranslationX(0f);
+ scrollBy((int) Math.round(v.getTranslationX() - mWarpPeekAmount), 0);
+ }
+
+ private void animateWarpPageOnScreen(String reason) {
+ if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOnScreen(" + reason + ")");
+ if (isWarping()) {
+ onPageBeginWarp();
KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
if (DEBUG_WARP) Log.v(TAG, "moving page on screen: Tx=" + v.getTranslationX());
- v.animate().translationX(mWarpPeekAmount).setDuration(WARP_PEEK_ANIMATION_DURATION);
+ DecelerateInterpolator interp = new DecelerateInterpolator(1.5f);
+ v.animate().translationX(mWarpPeekAmount)
+ .setInterpolator(interp)
+ .setDuration(WARP_PEEK_ANIMATION_DURATION)
+ .setListener(mFinishWarpAnimationListener);
+ mAnimatingWarp = true;
}
}
- private void animateWarpPageOffScreen() {
- if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOffScreen()");
- if (mPageWarpIndex != -1) {
+ private void animateWarpPageOffScreen(String reason, boolean animate) {
+ if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOffScreen(" + reason + " anim:" + animate + ")");
+ if (isWarping()) {
+ onPageEndWarp();
KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
if (DEBUG_WARP) Log.v(TAG, "moving page off screen: Tx=" + v.getTranslationX());
- v.animate().translationX(0.0f).setDuration(WARP_PEEK_ANIMATION_DURATION);
+ AccelerateInterpolator interp = new AccelerateInterpolator(1.5f);
+ v.animate().translationX(0.0f)
+ .setInterpolator(interp)
+ .setDuration(animate ? WARP_PEEK_ANIMATION_DURATION : 0)
+ .setListener(null);
+ } else {
+ if (DEBUG_WARP) Log.e(TAG, "animateWarpPageOffScreen(): not warping", new Exception());
}
}
@@ -2681,7 +2738,7 @@
}
}
- public void startWarp(int pageIndex) {
+ public void startPageWarp(int pageIndex) {
if (DEBUG_WARP) Log.v(TAG, "START WARP");
if (pageIndex != mCurrentPage + 1) {
mPageSwapIndex = mCurrentPage + 1;
@@ -2693,7 +2750,7 @@
return mPageWarpIndex;
}
- public void endWarp() {
+ public void stopPageWarp() {
if (DEBUG_WARP) Log.v(TAG, "END WARP");
// mPageSwapIndex is reset in snapToPage() after the scroll animation completes
}
diff --git a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
index 5e7816c..1036c83 100644
--- a/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
+++ b/packages/Keyguard/src/com/android/keyguard/SlidingChallengeLayout.java
@@ -88,8 +88,8 @@
public static final int SCROLL_STATE_SETTLING = 2;
public static final int SCROLL_STATE_FADING = 3;
- private static final int CHALLENGE_FADE_OUT_DURATION = 100;
- private static final int CHALLENGE_FADE_IN_DURATION = 160;
+ public static final int CHALLENGE_FADE_OUT_DURATION = 100;
+ public static final int CHALLENGE_FADE_IN_DURATION = 160;
private static final int MAX_SETTLE_DURATION = 600; // ms
diff --git a/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
index 98b5cfe..d503216 100644
--- a/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
+++ b/packages/PrintSpooler/res/layout/print_job_config_activity_container.xml
@@ -15,9 +15,12 @@
-->
<com.android.printspooler.PrintDialogFrame xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/content_container"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:background="@color/container_background">
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <FrameLayout
+ android:id="@+id/content_container"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@color/container_background">
+ </FrameLayout>
</com.android.printspooler.PrintDialogFrame>
diff --git a/packages/PrintSpooler/res/values-be/arrays.xml b/packages/PrintSpooler/res/values-be/arrays.xml
new file mode 100644
index 0000000..d40278c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-be/arrays.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>NA_LETTER</item>
+ <item>NA_GOVT_LETTER</item>
+ <item>NA_LEGAL</item>
+ <item>NA_JUNIOR_LEGAL</item>
+ <item>NA_LEDGER</item>
+ <item>NA_TABLOID</item>
+ <item>NA_INDEX_3X5</item>
+ <item>NA_INDEX_4X6</item>
+ <item>NA_INDEX_5X8</item>
+ <item>NA_MONARCH</item>
+ <item>NA_QUARTO</item>
+ <item>NA_FOOLSCAP</item>
+ </string-array>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values-ca/arrays.xml b/packages/PrintSpooler/res/values-ca/arrays.xml
new file mode 100644
index 0000000..d40278c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ca/arrays.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>NA_LETTER</item>
+ <item>NA_GOVT_LETTER</item>
+ <item>NA_LEGAL</item>
+ <item>NA_JUNIOR_LEGAL</item>
+ <item>NA_LEDGER</item>
+ <item>NA_TABLOID</item>
+ <item>NA_INDEX_3X5</item>
+ <item>NA_INDEX_4X6</item>
+ <item>NA_INDEX_5X8</item>
+ <item>NA_MONARCH</item>
+ <item>NA_QUARTO</item>
+ <item>NA_FOOLSCAP</item>
+ </string-array>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values-ca/donottranslate.xml b/packages/PrintSpooler/res/values-ca/donottranslate.xml
new file mode 100644
index 0000000..7537aa5
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ca/donottranslate.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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.
+-->
+
+<resources>
+
+ <string name="mediasize_default">NA_LETTER</string>
+ <string name="mediasize_standard">@string/mediasize_standard_north_america</string>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/arrays.xml b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
new file mode 100644
index 0000000..d40278c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>NA_LETTER</item>
+ <item>NA_GOVT_LETTER</item>
+ <item>NA_LEGAL</item>
+ <item>NA_JUNIOR_LEGAL</item>
+ <item>NA_LEDGER</item>
+ <item>NA_TABLOID</item>
+ <item>NA_INDEX_3X5</item>
+ <item>NA_INDEX_4X6</item>
+ <item>NA_INDEX_5X8</item>
+ <item>NA_MONARCH</item>
+ <item>NA_QUARTO</item>
+ <item>NA_FOOLSCAP</item>
+ </string-array>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values-ja/arrays.xml b/packages/PrintSpooler/res/values-ja/arrays.xml
new file mode 100644
index 0000000..3187cbe
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ja/arrays.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>JIS_B10</item>
+ <item>JIS_B9</item>
+ <item>JIS_B8</item>
+ <item>JIS_B7</item>
+ <item>JIS_B6</item>
+ <item>JIS_B5</item>
+ <item>JIS_B4</item>
+ <item>JIS_B3</item>
+ <item>JIS_B2</item>
+ <item>JIS_B1</item>
+ <item>JIS_B0</item>
+ <item>JIS_EXEC</item>
+ <item>JPN_CHOU4</item>
+ <item>JPN_CHOU3</item>
+ <item>JPN_CHOU2</item>
+ <item>JPN_HAGAKI</item>
+ <item>JPN_OUFUKU</item>
+ <item>JPN_KAHU</item>
+ <item>JPN_KAKU2</item>
+ <item>JPN_YOU4</item>
+ </string-array>
+
+</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/arrays.xml b/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
new file mode 100644
index 0000000..4fc75db
--- /dev/null
+++ b/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+ <string-array name="pdf_printer_media_sizes" translatable="false">
+ <item>ROC_8K</item>
+ <item>ROC_16K</item>
+ <item>PRC_1</item>
+ <item>PRC_2</item>
+ <item>PRC_3</item>
+ <item>PRC_4</item>
+ <item>PRC_5</item>
+ <item>PRC_6</item>
+ <item>PRC_7</item>
+ <item>PRC_8</item>
+ <item>PRC_9</item>
+ <item>PRC_10</item>
+ <item>PRC_16K</item>
+ <item>OM_PA_KAI</item>
+ <item>OM_DAI_PA_KAI</item>
+ <item>OM_JUURO_KU_KAI</item>
+ </string-array>
+
+</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java b/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java
index 6dd8aa0..c1c4d21 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintDialogFrame.java
@@ -24,6 +24,8 @@
public final int mMaxWidth;
+ public int mHeight;
+
public PrintDialogFrame(Context context, AttributeSet attrs) {
super(context, attrs);
mMaxWidth = context.getResources().getDimensionPixelSize(
@@ -32,13 +34,36 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
- if (widthMode == MeasureSpec.AT_MOST) {
- final int receivedWidth = MeasureSpec.getSize(widthMeasureSpec);
- final int computedWidth = Math.min(mMaxWidth, receivedWidth);
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(computedWidth,
- MeasureSpec.EXACTLY);
- }
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ int measuredWidth = getMeasuredWidth();
+ final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+ switch (widthMode) {
+ case MeasureSpec.UNSPECIFIED: {
+ measuredWidth = mMaxWidth;
+ } break;
+
+ case MeasureSpec.AT_MOST: {
+ final int receivedWidth = MeasureSpec.getSize(widthMeasureSpec);
+ measuredWidth = Math.min(mMaxWidth, receivedWidth);
+ } break;
+ }
+
+ mHeight = Math.max(mHeight, getMeasuredHeight());
+
+ int measuredHeight = getMeasuredHeight();
+ final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+ switch (heightMode) {
+ case MeasureSpec.UNSPECIFIED: {
+ measuredHeight = mHeight;
+ } break;
+
+ case MeasureSpec.AT_MOST: {
+ final int receivedHeight = MeasureSpec.getSize(heightMeasureSpec);
+ measuredHeight = Math.min(mHeight, receivedHeight);
+ } break;
+ }
+
+ setMeasuredDimension(measuredWidth, measuredHeight);
}
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index d6ebc2d..2922dd1 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -59,12 +59,14 @@
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnClickListener;
+import android.view.ViewGroup.LayoutParams;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
@@ -75,6 +77,7 @@
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
@@ -1409,7 +1412,9 @@
postSwitchCallback.run();
}
}
- });
+ },
+ new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
} break;
}
} break;
@@ -1426,7 +1431,9 @@
postSwitchCallback.run();
}
}
- });
+ },
+ new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
} break;
}
} break;
@@ -1474,7 +1481,8 @@
getLayoutInflater().inflate(showLayoutId, contentContainer, true);
}
- private void animateUiSwitch(int showLayoutId, final Runnable postAnimateCommand) {
+ private void animateUiSwitch(int showLayoutId, final Runnable postAnimateCommand,
+ final LayoutParams containerParams) {
// Find everything we will shuffle around.
final ViewGroup contentContainer = (ViewGroup) findViewById(R.id.content_container);
final View hidingView = contentContainer.getChildAt(0);
@@ -1511,6 +1519,8 @@
contentContainer.setScaleY(1.0f);
contentContainer.addView(showingView);
+ contentContainer.setLayoutParams(containerParams);
+
// Third animation - show the new content.
AutoCancellingAnimator.animate(showingView).withLayer().alpha(1.0f)
.withEndAction(new Runnable() {
diff --git a/packages/SystemUI/res/drawable-hdpi/nav_background.9.png b/packages/SystemUI/res/drawable-hdpi/nav_background.9.png
index db36d2b..a09e654 100644
--- a/packages/SystemUI/res/drawable-hdpi/nav_background.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/nav_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png
index 9befc34..d43d1dc 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/nav_background.9.png b/packages/SystemUI/res/drawable-mdpi/nav_background.9.png
index 45e6e8f..aa74153 100644
--- a/packages/SystemUI/res/drawable-mdpi/nav_background.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/nav_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png
index 2e24f6f..61d7511 100644
--- a/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/nav_background.9.png b/packages/SystemUI/res/drawable-xhdpi/nav_background.9.png
index 152e4ac..3b52195 100644
--- a/packages/SystemUI/res/drawable-xhdpi/nav_background.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/nav_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png
index a7f0017..192d3f7 100644
--- a/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/nav_background.9.png b/packages/SystemUI/res/drawable-xxhdpi/nav_background.9.png
index cce2e06..b35183c 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/nav_background.9.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/nav_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png
index ad34d49..1e5f15f 100644
--- a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_device_access_location_found.png
Binary files differ
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 9d0418d..e6823ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -34,6 +34,7 @@
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
@@ -308,6 +309,7 @@
refreshBluetoothTile();
refreshBrightnessTile();
refreshRotationLockTile();
+ refreshRssiTile();
}
// Settings
@@ -501,6 +503,14 @@
}
}
+ void refreshRssiTile() {
+ if (mRSSITile != null) {
+ // We reinflate the original view due to potential styling changes that may have
+ // taken place due to a configuration change.
+ mRSSITile.reinflateContent(LayoutInflater.from(mContext));
+ }
+ }
+
// Bluetooth
void addBluetoothTile(QuickSettingsTileView view, RefreshCallback cb) {
mBluetoothTile = view;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
index 9cff242..3d520f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsTileView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
@@ -26,13 +27,16 @@
*
*/
class QuickSettingsTileView extends FrameLayout {
+ private static final String TAG = "QuickSettingsTileView";
+ private int mContentLayoutId;
private int mColSpan;
private int mRowSpan;
public QuickSettingsTileView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mContentLayoutId = -1;
mColSpan = 1;
mRowSpan = 1;
}
@@ -46,9 +50,19 @@
}
void setContent(int layoutId, LayoutInflater inflater) {
+ mContentLayoutId = layoutId;
inflater.inflate(layoutId, this);
}
+ void reinflateContent(LayoutInflater inflater) {
+ if (mContentLayoutId != -1) {
+ removeAllViews();
+ setContent(mContentLayoutId, inflater);
+ } else {
+ Log.e(TAG, "Not reinflating content: No layoutId set");
+ }
+ }
+
@Override
public void setVisibility(int vis) {
if (QuickSettings.DEBUG_GONE_TILES) {
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index d2d5280..546324a 100644
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -766,13 +766,17 @@
case MESSAGE_REGISTER_STATE_CHANGE_CALLBACK:
{
IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
- mStateChangeCallbacks.register(callback);
+ if (callback != null) {
+ mStateChangeCallbacks.register(callback);
+ }
break;
}
case MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK:
{
IBluetoothStateChangeCallback callback = (IBluetoothStateChangeCallback) msg.obj;
- mStateChangeCallbacks.unregister(callback);
+ if (callback != null) {
+ mStateChangeCallbacks.unregister(callback);
+ }
break;
}
case MESSAGE_BLUETOOTH_SERVICE_CONNECTED:
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 5695ee5..70418e8 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -353,6 +353,11 @@
*/
private static final int EVENT_SAMPLE_INTERVAL_ELAPSED = 15;
+ /**
+ * PAC manager has received new port.
+ */
+ private static final int EVENT_PROXY_HAS_CHANGED = 16;
+
/** Handler used for internal events. */
private InternalHandler mHandler;
/** Handler used for incoming {@link NetworkStateTracker} events. */
@@ -679,7 +684,7 @@
},
new IntentFilter(filter));
- mPacManager = new PacManager(mContext);
+ mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
filter = new IntentFilter();
filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
@@ -3124,6 +3129,10 @@
handleNetworkSamplingTimeout();
break;
}
+ case EVENT_PROXY_HAS_CHANGED: {
+ handleApplyDefaultProxy((ProxyProperties)msg.obj);
+ break;
+ }
}
}
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index aae4cb8..4fbbb78 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -14267,6 +14267,8 @@
}
}
+ boolean mayBeTop = false;
+
for (int is = app.services.size()-1;
is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
@@ -14427,18 +14429,27 @@
if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
- if (clientProcState <=
- ActivityManager.PROCESS_STATE_PERSISTENT_UI &&
- clientProcState >=
- ActivityManager.PROCESS_STATE_PERSISTENT) {
- // Persistent processes don't allow us to become top.
- // However the top process DOES allow us to become top,
- // because in that case we are running because the current
- // top process wants us, so we should be counted as part
- // of the top set and not just running for some random
- // unknown reason in the background.
- clientProcState =
- ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
+ if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
+ // Special handling of clients who are in the top state.
+ // We *may* want to consider this process to be in the
+ // top state as well, but only if there is not another
+ // reason for it to be running. Being on the top is a
+ // special state, meaning you are specifically running
+ // for the current top app. If the process is already
+ // running in the background for some other reason, it
+ // is more important to continue considering it to be
+ // in the background state.
+ mayBeTop = true;
+ clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+ } else {
+ // Special handling for above-top states (persistent
+ // processes). These should not bring the current process
+ // into the top state, since they are not on top. Instead
+ // give them the best state after that.
+ clientProcState =
+ ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ }
}
} else {
if (clientProcState <
@@ -14526,18 +14537,27 @@
app.adjSourceOom = clientAdj;
app.adjTarget = cpr.name;
}
- if (clientProcState <=
- ActivityManager.PROCESS_STATE_PERSISTENT_UI &&
- clientProcState >=
- ActivityManager.PROCESS_STATE_PERSISTENT) {
- // Persistent processes don't allow us to become top.
- // However the top process DOES allow us to become top,
- // because in that case we are running because the current
- // top process wants us, so we should be counted as part
- // of the top set and not just running for some random
- // unknown reason in the background.
- clientProcState =
- ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
+ if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
+ // Special handling of clients who are in the top state.
+ // We *may* want to consider this process to be in the
+ // top state as well, but only if there is not another
+ // reason for it to be running. Being on the top is a
+ // special state, meaning you are specifically running
+ // for the current top app. If the process is already
+ // running in the background for some other reason, it
+ // is more important to continue considering it to be
+ // in the background state.
+ mayBeTop = true;
+ clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+ } else {
+ // Special handling for above-top states (persistent
+ // processes). These should not bring the current process
+ // into the top state, since they are not on top. Instead
+ // give them the best state after that.
+ clientProcState =
+ ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ }
}
if (procState > clientProcState) {
procState = clientProcState;
@@ -14564,6 +14584,28 @@
}
}
+ if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
+ // A client of one of our services or providers is in the top state. We
+ // *may* want to be in the top state, but not if we are already running in
+ // the background for some other reason. For the decision here, we are going
+ // to pick out a few specific states that we want to remain in when a client
+ // is top (states that tend to be longer-term) and otherwise allow it to go
+ // to the top state.
+ switch (procState) {
+ case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
+ case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
+ case ActivityManager.PROCESS_STATE_SERVICE:
+ // These all are longer-term states, so pull them up to the top
+ // of the background states, but not all the way to the top state.
+ procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+ break;
+ default:
+ // Otherwise, top is a better choice, so take it.
+ procState = ActivityManager.PROCESS_STATE_TOP;
+ break;
+ }
+ }
+
if (adj == ProcessList.SERVICE_ADJ) {
if (doingAll) {
app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
diff --git a/services/java/com/android/server/am/ProcessStatsService.java b/services/java/com/android/server/am/ProcessStatsService.java
index a6375e1..50a7b5c 100644
--- a/services/java/com/android/server/am/ProcessStatsService.java
+++ b/services/java/com/android/server/am/ProcessStatsService.java
@@ -473,11 +473,11 @@
current.setDataPosition(0);
ProcessStats stats = ProcessStats.CREATOR.createFromParcel(current);
current.recycle();
- int i = 0;
- while (i < files.size() && (stats.mTimePeriodEndRealtime
+ int i = files.size()-1;
+ while (i >= 0 && (stats.mTimePeriodEndRealtime
- stats.mTimePeriodStartRealtime) < minTime) {
AtomicFile file = new AtomicFile(new File(files.get(i)));
- i++;
+ i--;
ProcessStats moreStats = new ProcessStats(false);
readLocked(moreStats, file);
if (moreStats.mReadError == null) {
@@ -490,7 +490,7 @@
- moreStats.mTimePeriodStartRealtime, sb);
Slog.i(TAG, sb.toString());
} else {
- Slog.w(TAG, "Failure reading " + files.get(i-1) + "; "
+ Slog.w(TAG, "Failure reading " + files.get(i+1) + "; "
+ moreStats.mReadError);
continue;
}
diff --git a/services/java/com/android/server/connectivity/PacManager.java b/services/java/com/android/server/connectivity/PacManager.java
index 1cb2fe3..837fb05 100644
--- a/services/java/com/android/server/connectivity/PacManager.java
+++ b/services/java/com/android/server/connectivity/PacManager.java
@@ -27,6 +27,7 @@
import android.net.Proxy;
import android.net.ProxyProperties;
import android.os.Binder;
+import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -89,6 +90,9 @@
private boolean mHasSentBroadcast;
private boolean mHasDownloaded;
+ private Handler mConnectivityHandler;
+ private int mProxyMessage;
+
/**
* Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac.
*/
@@ -128,7 +132,7 @@
}
}
- public PacManager(Context context) {
+ public PacManager(Context context, Handler handler, int proxyMessage) {
mContext = context;
mLastPort = -1;
@@ -136,6 +140,8 @@
context, 0, new Intent(ACTION_PAC_REFRESH), 0);
context.registerReceiver(new PacRefreshIntentReceiver(),
new IntentFilter(ACTION_PAC_REFRESH));
+ mConnectivityHandler = handler;
+ mProxyMessage = proxyMessage;
}
private AlarmManager getAlarmManager() {
@@ -156,6 +162,10 @@
*/
public synchronized boolean setCurrentProxyScriptUrl(ProxyProperties proxy) {
if (!TextUtils.isEmpty(proxy.getPacFileUrl())) {
+ if (proxy.getPacFileUrl().equals(mPacUrl)) {
+ // Allow to send broadcast, nothing to do.
+ return false;
+ }
synchronized (mProxyLock) {
mPacUrl = proxy.getPacFileUrl();
}
@@ -356,16 +366,7 @@
}
private void sendPacBroadcast(ProxyProperties proxy) {
- Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
- Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(Proxy.EXTRA_PROXY_INFO, proxy);
- final long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
+ mConnectivityHandler.sendMessage(mConnectivityHandler.obtainMessage(mProxyMessage, proxy));
}
private synchronized void sendProxyIfNeeded() {
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 647f014..3e8db06 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -215,4 +215,26 @@
* Requires system permission.
*/
void setPremiumSmsPermission(String packageName, int permission);
+
+ /**
+ * SMS over IMS is supported if IMS is registered and SMS is supported
+ * on IMS.
+ *
+ * @return true if SMS over IMS is supported, false otherwise
+ *
+ * @see #getImsSmsFormat()
+ */
+ boolean isImsSmsSupported();
+
+ /**
+ * Gets SMS format supported on IMS. SMS over IMS format is
+ * either 3GPP or 3GPP2.
+ *
+ * @return android.telephony.SmsMessage.FORMAT_3GPP,
+ * android.telephony.SmsMessage.FORMAT_3GPP2
+ * or android.telephony.SmsMessage.FORMAT_UNKNOWN
+ *
+ * @see #isImsSmsSupported()
+ */
+ String getImsSmsFormat();
}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 923fef2..821a11c 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -263,6 +263,8 @@
int RIL_REQUEST_GET_CELL_INFO_LIST = 109;
int RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE = 110;
int RIL_REQUEST_SET_INITIAL_ATTACH_APN = 111;
+ int RIL_REQUEST_IMS_REGISTRATION_STATE = 112;
+ int RIL_REQUEST_IMS_SEND_SMS = 113;
int RIL_UNSOL_RESPONSE_BASE = 1000;
int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
@@ -301,4 +303,5 @@
int RIL_UNSOL_RIL_CONNECTED = 1034;
int RIL_UNSOL_VOICE_RADIO_TECH_CHANGED = 1035;
int RIL_UNSOL_CELL_INFO_LIST = 1036;
+ int RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED = 1037;
}
diff --git a/telephony/java/com/android/internal/telephony/SmsConstants.java b/telephony/java/com/android/internal/telephony/SmsConstants.java
index 1ccdc3b..2449108 100644
--- a/telephony/java/com/android/internal/telephony/SmsConstants.java
+++ b/telephony/java/com/android/internal/telephony/SmsConstants.java
@@ -62,6 +62,12 @@
}
/**
+ * Indicates unknown format SMS message.
+ * @hide pending API council approval
+ */
+ public static final String FORMAT_UNKNOWN = "unknown";
+
+ /**
* Indicates a 3GPP format SMS message.
* @hide pending API council approval
*/