summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java11
-rw-r--r--core/java/android/app/ApplicationPackageManager.java13
-rw-r--r--core/java/android/app/Notification.java9
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java19
-rw-r--r--core/java/android/content/pm/PackageManager.java5
-rw-r--r--core/java/android/content/res/Resources.java9
-rw-r--r--core/java/android/hardware/Sensor.java67
-rw-r--r--core/java/android/hardware/SensorEventListener2.java13
-rw-r--r--core/java/android/hardware/SensorManager.java251
-rw-r--r--core/java/android/hardware/hdmi/HdmiRecordSources.java4
-rw-r--r--core/java/android/preference/SeekBarVolumizer.java31
-rw-r--r--core/java/android/preference/VolumePreference.java1
-rw-r--r--core/java/android/provider/Settings.java21
-rw-r--r--core/java/android/util/PathParser.java50
-rw-r--r--core/java/android/view/View.java23
-rw-r--r--core/java/android/view/ViewGroup.java34
-rw-r--r--core/java/android/widget/AppSecurityPermissions.java4
-rw-r--r--core/java/android/widget/CalendarView.java19
-rw-r--r--core/java/android/widget/ListPopupWindow.java14
-rw-r--r--core/java/android/widget/PopupMenu.java57
-rw-r--r--core/java/android/widget/ProgressBar.java3
-rw-r--r--core/java/android/widget/RemoteViews.java50
-rw-r--r--core/java/android/widget/Toolbar.java9
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java5
-rw-r--r--core/java/com/android/internal/view/menu/MenuPopupHelper.java13
-rw-r--r--core/java/com/android/internal/widget/ExploreByTouchHelper.java7
26 files changed, 510 insertions, 232 deletions
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 540376e..5455a0f 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -222,8 +222,15 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
if (mListener != null) {
mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
}
- mSharedElementNames.addAll(sharedElements.keySet());
- mSharedElements.addAll(sharedElements.values());
+ int numSharedElements = sharedElements.size();
+ for (int i = 0; i < numSharedElements; i++) {
+ View sharedElement = sharedElements.valueAt(i);
+ String name = sharedElements.keyAt(i);
+ if (sharedElement != null && sharedElement.isAttachedToWindow() && name != null) {
+ mSharedElements.add(sharedElement);
+ mSharedElementNames.add(name);
+ }
+ }
if (getViewsTransition() != null && mTransitioningViews != null) {
ViewGroup decorView = getDecor();
if (decorView != null) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 1e1a613..854719d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1664,6 +1664,17 @@ final class ApplicationPackageManager extends PackageManager {
* @hide
*/
public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
+ Drawable dr = loadUnbadgedItemIcon(itemInfo, appInfo);
+ if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
+ return dr;
+ }
+ return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
+ }
+
+ /**
+ * @hide
+ */
+ public Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
if (bitmap == null) {
@@ -1678,7 +1689,7 @@ final class ApplicationPackageManager extends PackageManager {
if (dr == null) {
dr = itemInfo.loadDefaultIcon(this);
}
- return getUserBadgedIcon(dr, new UserHandle(mContext.getUserId()));
+ return dr;
}
private Drawable getBadgedDrawable(Drawable drawable, Drawable badgeDrawable,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fb10e17..9849c51 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
@@ -2773,6 +2774,14 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.progress, View.VISIBLE);
contentView.setProgressBar(
R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
+ contentView.setProgressBackgroundTintList(
+ R.id.progress, ColorStateList.valueOf(mContext.getResources().getColor(
+ R.color.notification_progress_background_color)));
+ if (mColor != COLOR_DEFAULT) {
+ ColorStateList colorStateList = ColorStateList.valueOf(mColor);
+ contentView.setProgressTintList(R.id.progress, colorStateList);
+ contentView.setProgressIndeterminateTintList(R.id.progress, colorStateList);
+ }
showLine2 = true;
} else {
contentView.setViewVisibility(R.id.progress, View.GONE);
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index cacdf8e..22a899c 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -138,7 +138,7 @@ public class PackageItemInfo {
}
return packageName;
}
-
+
/**
* Retrieve the current graphical icon associated with this item. This
* will call back on the given PackageManager to load the icon from
@@ -156,6 +156,23 @@ public class PackageItemInfo {
}
/**
+ * Retrieve the current graphical icon associated with this item without
+ * the addition of a work badge if applicable.
+ * This will call back on the given PackageManager to load the icon from
+ * the application.
+ *
+ * @param pm A PackageManager from which the icon can be loaded; usually
+ * the PackageManager from which you originally retrieved this item.
+ *
+ * @return Returns a Drawable containing the item's icon. If the
+ * item does not have an icon, the item's default icon is returned
+ * such as the default activity icon.
+ */
+ public Drawable loadUnbadgedIcon(PackageManager pm) {
+ return pm.loadUnbadgedItemIcon(this, getApplicationInfo());
+ }
+
+ /**
* Retrieve the current graphical banner associated with this item. This
* will call back on the given PackageManager to load the banner from
* the application.
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e519163..ab90b66 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3911,6 +3911,11 @@ public abstract class PackageManager {
*/
public abstract Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo);
+ /**
+ * @hide
+ */
+ public abstract Drawable loadUnbadgedItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo);
+
/** {@hide} */
public abstract boolean isPackageAvailable(String packageName);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 7f276c2..e34ce3e 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2323,7 +2323,14 @@ public class Resources {
final Drawable dr;
if (cs != null) {
- dr = cs.newDrawable(this, theme);
+ final Drawable clonedDr = cs.newDrawable(this);
+ if (theme != null) {
+ dr = clonedDr.mutate();
+ dr.applyTheme(theme);
+ dr.clearMutated();
+ } else {
+ dr = clonedDr;
+ }
} else if (isColorDrawable) {
dr = new ColorDrawable(value.data);
} else {
diff --git a/core/java/android/hardware/Sensor.java b/core/java/android/hardware/Sensor.java
index f514e42..cf6a779 100644
--- a/core/java/android/hardware/Sensor.java
+++ b/core/java/android/hardware/Sensor.java
@@ -329,7 +329,11 @@ public final class Sensor {
* A sensor of this type triggers an event each time a step is taken by the user. The only
* allowed value to return is 1.0 and an event is generated for each step. Like with any other
* event, the timestamp indicates when the event (here the step) occurred, this corresponds to
- * when the foot hit the ground, generating a high variation in acceleration.
+ * when the foot hit the ground, generating a high variation in acceleration. This sensor is
+ * only for detecting every individual step as soon as it is taken, for example to perform dead
+ * reckoning. If you only need aggregate number of steps taken over a period of time, register
+ * for {@link #TYPE_STEP_COUNTER} instead. It is defined as a
+ * {@link Sensor#REPORTING_MODE_SPECIAL_TRIGGER} sensor.
* <p>
* See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
*/
@@ -349,7 +353,12 @@ public final class Sensor {
* while activated. The value is returned as a float (with the fractional part set to zero) and
* is reset to zero only on a system reboot. The timestamp of the event is set to the time when
* the last step for that event was taken. This sensor is implemented in hardware and is
- * expected to be low power.
+ * expected to be low power. If you want to continuously track the number of steps over a long
+ * period of time, do NOT unregister for this sensor, so that it keeps counting steps in the
+ * background even when the AP is in suspend mode and report the aggregate count when the AP
+ * is awake. Application needs to stay registered for this sensor because step counter does not
+ * count steps if it is not activated. This sensor is ideal for fitness tracking applications.
+ * It is defined as an {@link Sensor#REPORTING_MODE_ON_CHANGE} sensor.
* <p>
* See {@link android.hardware.SensorEvent#values SensorEvent.values} for more details.
*/
@@ -750,31 +759,41 @@ public final class Sensor {
}
/**
- * Returns whether this sensor is a wake-up sensor.
+ * Returns true if the sensor is a wake-up sensor.
* <p>
- * Wake up sensors wake the application processor up when they have events to deliver. When a
- * wake up sensor is registered to without batching enabled, each event will wake the
- * application processor up.
- * <p>
- * When a wake up sensor is registered to with batching enabled, it
- * wakes the application processor up when maxReportingLatency has elapsed or when the hardware
- * FIFO storing the events from wake up sensors is getting full.
- * <p>
- * Non-wake up sensors never wake the application processor up. Their events are only reported
- * when the application processor is awake, for example because the application holds a wake
- * lock, or another source woke the application processor up.
+ * <b>Application Processor Power modes</b> <p>
+ * Application Processor(AP), is the processor on which applications run. When no wake lock is held
+ * and the user is not interacting with the device, this processor can enter a “Suspend” mode,
+ * reducing the power consumption by 10 times or more.
+ * </p>
* <p>
- * When a non-wake up sensor is registered to without batching enabled, the measurements made
- * while the application processor is asleep might be lost and never returned.
+ * <b>Non-wake-up sensors</b> <p>
+ * Non-wake-up sensors are sensors that do not wake the AP out of suspend to report data. While
+ * the AP is in suspend mode, the sensors continue to function and generate events, which are
+ * put in a hardware FIFO. The events in the FIFO are delivered to the application when the AP
+ * wakes up. If the FIFO was too small to store all events generated while the AP was in
+ * suspend mode, the older events are lost: the oldest data is dropped to accommodate the newer
+ * data. In the extreme case where the FIFO is non-existent {@code maxFifoEventCount() == 0},
+ * all events generated while the AP was in suspend mode are lost. Applications using
+ * non-wake-up sensors should usually:
+ * <ul>
+ * <li>Either unregister from the sensors when they do not need them, usually in the activity’s
+ * {@code onPause} method. This is the most common case.
+ * <li>Or realize that the sensors are consuming some power while the AP is in suspend mode and
+ * that even then, some events might be lost.
+ * </ul>
+ * </p>
* <p>
- * When a non-wake up sensor is registered to with batching enabled, the measurements made while
- * the application processor is asleep are stored in the hardware FIFO for non-wake up sensors.
- * When this FIFO gets full, new events start overwriting older events. When the application
- * then wakes up, the latest events are returned, and some old events might be lost. The number
- * of events actually returned depends on the hardware FIFO size, as well as on what other
- * sensors are activated. If losing sensor events is not acceptable during batching, you must
- * use the wake-up version of the sensor.
- * @return true if this is a wake up sensor, false otherwise.
+ * <b>Wake-up sensors</b> <p>
+ * In opposition to non-wake-up sensors, wake-up sensors ensure that their data is delivered
+ * independently of the state of the AP. While the AP is awake, the wake-up sensors behave
+ * like non-wake-up-sensors. When the AP is asleep, wake-up sensors wake up the AP to deliver
+ * events. That is, the AP will wake up and the sensor will deliver the events before the
+ * maximum reporting latency is elapsed or the hardware FIFO gets full. See {@link
+ * SensorManager#registerListener(SensorEventListener, Sensor, int, int)} for more details.
+ * </p>
+ *
+ * @return <code>true</code> if this is a wake-up sensor, <code>false</code> otherwise.
*/
public boolean isWakeUpSensor() {
return (mFlags & SENSOR_FLAG_WAKE_UP_SENSOR) != 0;
diff --git a/core/java/android/hardware/SensorEventListener2.java b/core/java/android/hardware/SensorEventListener2.java
index 70eff08..fd3e62b 100644
--- a/core/java/android/hardware/SensorEventListener2.java
+++ b/core/java/android/hardware/SensorEventListener2.java
@@ -21,15 +21,16 @@ package android.hardware;
*/
public interface SensorEventListener2 extends SensorEventListener {
/**
- * Called after flush() is completed. All the events in the batch at the point when
- * the flush was called have been delivered to the applications registered for those
- * sensor events. Flush Complete Events are sent ONLY to the application that has
- * explicitly called flush(). If the hardware FIFO is flushed due to some other
- * application calling flush(), flush complete event is not delivered to this application.
+ * Called after flush() is completed. All the events in the batch at the point when the flush
+ * was called have been delivered to the applications registered for those sensor events. In
+ * {@link android.os.Build.VERSION_CODES#KITKAT}, applications may receive flush complete events
+ * even if some other application has called flush() on the same sensor. Starting with
+ * {@link android.os.Build.VERSION_CODES#LOLLIPOP}, flush Complete events are sent ONLY to the
+ * application that has explicitly called flush(). If the hardware FIFO is flushed due to some
+ * other application calling flush(), flush complete event is not delivered to this application.
* <p>
*
* @param sensor The {@link android.hardware.Sensor Sensor} on which flush was called.
- *
* @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 cccd624..e4e5a8c 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -626,73 +626,90 @@ public abstract class SensorManager {
protected abstract void unregisterListenerImpl(SensorEventListener listener, Sensor sensor);
/**
- * 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.
+ * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+ * sensor at the given sampling frequency.
+ * <p>
+ * The events will be delivered to the provided {@code SensorEventListener} as soon as they are
+ * available. To reduce the power consumption, applications can use
+ * {@link #registerListener(SensorEventListener, Sensor, int, int)} instead and specify a
+ * positive non-zero maximum reporting latency.
+ * </p>
+ * <p>
+ * In the case of non-wake-up sensors, the events are only delivered while the Application
+ * Processor (AP) is not in suspend mode. See {@link Sensor#isWakeUpSensor()} for more details.
+ * To ensure delivery of events from non-wake-up sensors even when the screen is OFF, the
+ * application registering to the sensor must hold a partial wake-lock to keep the AP awake,
+ * otherwise some events might be lost while the AP is asleep. Note that although events might
+ * be lost while the AP is asleep, the sensor will still consume power if it is not explicitly
+ * deactivated by the application. Applications must unregister their {@code
+ * SensorEventListener}s in their activity's {@code onPause()} method to avoid consuming power
+ * while the device is inactive. See {@link #registerListener(SensorEventListener, Sensor, int,
+ * int)} for more details on hardware FIFO (queueing) capabilities and when some sensor events
+ * might be lost.
+ * </p>
+ * <p>
+ * In the case of wake-up sensors, each event generated by the sensor will cause the AP to
+ * wake-up, ensuring that each event can be delivered. Because of this, registering to a wake-up
+ * sensor has very significant power implications. Call {@link Sensor#isWakeUpSensor()} to check
+ * whether a sensor is a wake-up sensor. See
+ * {@link #registerListener(SensorEventListener, Sensor, int, int)} for information on how to
+ * reduce the power impact of registering to wake-up sensors.
+ * </p>
+ * <p class="note">
+ * Note: Don't use this method with one-shot trigger sensors such as
+ * {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
+ * {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. Use
+ * {@link Sensor#getReportingMode()} to obtain the reporting mode of a given sensor.
* </p>
*
- * @param listener
- * A {@link android.hardware.SensorEventListener SensorEventListener}
- * object.
- *
- * @param sensor
- * The {@link android.hardware.Sensor Sensor} to register to.
- *
- * @param rateUs
- * The rate {@link android.hardware.SensorEvent sensor events} are
- * delivered at. This is only a hint to the system. Events may be
- * received faster or slower than the specified rate. Usually events
- * are received faster. The value must be one of
- * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
- * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}
- * or, the desired delay between events in microseconds.
- * Specifying the delay in microseconds only works from Android
- * 2.3 (API level 9) onwards. For earlier releases, you must use
- * one of the {@code SENSOR_DELAY_*} constants.
- *
- * @return <code>true</code> if the sensor is supported and successfully
- * enabled.
- *
+ * @param listener A {@link android.hardware.SensorEventListener SensorEventListener} object.
+ * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+ * @param samplingPeriodUs The rate {@link android.hardware.SensorEvent sensor events} are
+ * delivered at. This is only a hint to the system. Events may be received faster or
+ * slower than the specified rate. Usually events are received faster. The value must
+ * be one of {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+ * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} or, the desired delay
+ * between events in microseconds. Specifying the delay in microseconds only works
+ * from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of
+ * the {@code SENSOR_DELAY_*} constants.
+ * @return <code>true</code> if the sensor is supported and successfully enabled.
* @see #registerListener(SensorEventListener, Sensor, int, Handler)
* @see #unregisterListener(SensorEventListener)
* @see #unregisterListener(SensorEventListener, Sensor)
- *
*/
- public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs) {
- return registerListener(listener, sensor, rateUs, null);
+ public boolean registerListener(SensorEventListener listener, Sensor sensor,
+ int samplingPeriodUs) {
+ return registerListener(listener, sensor, samplingPeriodUs, null);
}
/**
- * Enables batch mode for a sensor with the given rate and maxBatchReportLatency. If the
- * underlying hardware does not support batch mode, this defaults to
- * {@link #registerListener(SensorEventListener, Sensor, int)} and other parameters are
- * ignored. In non-batch mode, all sensor events must be reported as soon as they are detected.
- * While in batch mode, sensor events do not need to be reported as soon as they are detected.
- * They can be temporarily stored in batches and reported in batches, as long as no event is
- * delayed by more than "maxBatchReportLatency" microseconds. That is, all events since the
- * previous batch are recorded and returned all at once. This allows to reduce the amount of
- * interrupts sent to the SoC, and allows the SoC to switch to a lower power state (Idle) while
- * the sensor is capturing and batching data.
- * <p>
- * Registering to a sensor in batch mode will not prevent the SoC from going to suspend mode. In
- * this case, the sensor will continue to gather events and store it in a hardware FIFO. If the
- * FIFO gets full before the AP wakes up again, some events will be lost, as the older events
- * get overwritten by new events in the hardware FIFO. This can be avoided by holding a wake
- * lock. If the application holds a wake lock, the SoC will not go to suspend mode, so no events
- * will be lost, as the events will be reported before the FIFO gets full.
- * </p>
+ * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+ * sensor at the given sampling frequency and the given maximum reporting latency.
* <p>
- * Batching is always best effort. If a different application requests updates in continuous
- * mode, this application will also get events in continuous mode. Batch mode updates can be
- * unregistered by calling {@link #unregisterListener(SensorEventListener)}.
+ * This function is similar to {@link #registerListener(SensorEventListener, Sensor, int)} but
+ * it allows events to stay temporarily in the hardware FIFO (queue) before being delivered. The
+ * events can be stored in the hardware FIFO up to {@code maxReportLatencyUs} microseconds. Once
+ * one of the events in the FIFO needs to be reported, all of the events in the FIFO are
+ * reported sequentially. This means that some events will be reported before the maximum
+ * reporting latency has elapsed.
+ * </p><p>
+ * When {@code maxReportLatencyUs} is 0, the call is equivalent to a call to
+ * {@link #registerListener(SensorEventListener, Sensor, int)}, as it requires the events to be
+ * delivered as soon as possible.
+ * </p><p>
+ * When {@code sensor.maxFifoEventCount()} is 0, the sensor does not use a FIFO, so the call
+ * will also be equivalent to {@link #registerListener(SensorEventListener, Sensor, int)}.
+ * </p><p>
+ * Setting {@code maxReportLatencyUs} to a positive value allows to reduce the number of
+ * interrupts the AP (Application Processor) receives, hence reducing power consumption, as the
+ * AP can switch to a lower power state while the sensor is capturing the data. This is
+ * especially important when registering to wake-up sensors, for which each interrupt causes the
+ * AP to wake up if it was in suspend mode. See {@link Sensor#isWakeUpSensor()} for more
+ * information on wake-up sensors.
* </p>
* <p class="note">
* </p>
- * Note: Don't use this method with a one shot trigger sensor such as
+ * Note: Don't use this method with one-shot trigger sensors such as
* {@link Sensor#TYPE_SIGNIFICANT_MOTION}. Use
* {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead. </p>
*
@@ -701,118 +718,104 @@ public abstract class SensorManager {
* 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
+ * @param samplingPeriodUs 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
+ * @param maxReportLatencyUs Maximum time in microseconds that events can be delayed before
+ * being reported to the application. A large value allows reducing the power
+ * consumption associated with the sensor. If maxReportLatencyUs is set to zero,
+ * events are delivered as soon as they are available, which is equivalent to calling
* {@link #registerListener(SensorEventListener, Sensor, int)}.
- * @return <code>true</code> if batch mode is successfully enabled for this sensor,
- * <code>false</code> otherwise.
+ * @return <code>true</code> if the sensor is supported and successfully enabled.
* @see #registerListener(SensorEventListener, Sensor, int)
* @see #unregisterListener(SensorEventListener)
* @see #flush(SensorEventListener)
*/
- public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
- int maxBatchReportLatencyUs) {
- int delay = getDelay(rateUs);
- return registerListenerImpl(listener, sensor, delay, null, maxBatchReportLatencyUs, 0);
+ public boolean registerListener(SensorEventListener listener, Sensor sensor,
+ int samplingPeriodUs, int maxReportLatencyUs) {
+ int delay = getDelay(samplingPeriodUs);
+ return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 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)} 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
- * {@link Sensor#TYPE_SIGNIFICANT_MOTION}.
- * Use {@link #requestTriggerSensor(TriggerEventListener, Sensor)} instead.
+ * power consumption, applications can use
+ * {@link #registerListener(SensorEventListener, Sensor, int, int)} instead and specify a
+ * positive non-zero maximum reporting latency.
+ * <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.
- *
- * @param sensor
- * The {@link android.hardware.Sensor Sensor} to register to.
- *
- * @param rateUs
- * The rate {@link android.hardware.SensorEvent sensor events} are
- * delivered at. This is only a hint to the system. Events may be
- * received faster or slower than the specified rate. Usually events
- * are received faster. The value must be one of
- * {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
- * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST}.
- * or, the desired delay between events in microseconds.
- * Specifying the delay in microseconds only works from Android
- * 2.3 (API level 9) onwards. For earlier releases, you must use
- * one of the {@code SENSOR_DELAY_*} constants.
- *
- * @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.
+ * @param sensor The {@link android.hardware.Sensor Sensor} to register to.
+ * @param samplingPeriodUs The rate {@link android.hardware.SensorEvent sensor events} are
+ * delivered at. This is only a hint to the system. Events may be received faster or
+ * slower than the specified rate. Usually events are received faster. The value must
+ * be one of {@link #SENSOR_DELAY_NORMAL}, {@link #SENSOR_DELAY_UI},
+ * {@link #SENSOR_DELAY_GAME}, or {@link #SENSOR_DELAY_FASTEST} or, the desired
+ * delay between events in microseconds. Specifying the delay in microseconds only
+ * works from Android 2.3 (API level 9) onwards. For earlier releases, you must use
+ * one of the {@code SENSOR_DELAY_*} constants.
+ * @param handler The {@link android.os.Handler Handler} the {@link android.hardware.SensorEvent
+ * sensor events} will be delivered to.
* @return <code>true</code> if the sensor is supported and successfully enabled.
- *
* @see #registerListener(SensorEventListener, Sensor, int)
* @see #unregisterListener(SensorEventListener)
* @see #unregisterListener(SensorEventListener, Sensor)
*/
- public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
- Handler handler) {
- int delay = getDelay(rateUs);
+ public boolean registerListener(SensorEventListener listener, Sensor sensor,
+ int samplingPeriodUs, Handler handler) {
+ int delay = getDelay(samplingPeriodUs);
return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
}
/**
- * Enables batch mode for a sensor with the given rate and maxBatchReportLatency.
+ * Registers a {@link android.hardware.SensorEventListener SensorEventListener} for the given
+ * sensor at the given sampling frequency and the given maximum reporting latency.
+ *
* @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
+ * @param samplingPeriodUs 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
+ * @param maxReportLatencyUs Maximum time in microseconds that events can be delayed before
+ * being reported to the application. A large value allows reducing the power
+ * consumption associated with the sensor. If maxReportLatencyUs is set to zero,
+ * events are delivered 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.
- *
- * @return <code>true</code> if batch mode is successfully enabled for this sensor,
- * <code>false</code> otherwise.
+ * @param handler The {@link android.os.Handler Handler} the {@link android.hardware.SensorEvent
+ * sensor events} will be delivered to.
+ * @return <code>true</code> if the sensor is supported and successfully enabled.
* @see #registerListener(SensorEventListener, Sensor, int, int)
*/
- public boolean registerListener(SensorEventListener listener, Sensor sensor, int rateUs,
- int maxBatchReportLatencyUs, Handler handler) {
- int delayUs = getDelay(rateUs);
- return registerListenerImpl(listener, sensor, delayUs, handler, maxBatchReportLatencyUs, 0);
+ public boolean registerListener(SensorEventListener listener, Sensor sensor, int samplingPeriodUs,
+ int maxReportLatencyUs, Handler handler) {
+ int delayUs = getDelay(samplingPeriodUs);
+ return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);
}
/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
- int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags);
+ int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);
/**
- * 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
+ * Flushes the 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 maxReportLantecy of the FIFO has
+ * expired. Events are returned in the usual way through the SensorEventListener.
+ * This call doesn't affect the maxReportLantecy 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
diff --git a/core/java/android/hardware/hdmi/HdmiRecordSources.java b/core/java/android/hardware/hdmi/HdmiRecordSources.java
index dcc41fa..c294f72 100644
--- a/core/java/android/hardware/hdmi/HdmiRecordSources.java
+++ b/core/java/android/hardware/hdmi/HdmiRecordSources.java
@@ -55,8 +55,10 @@ public final class HdmiRecordSources {
/**
* Base class for each record source.
+ * @hide
*/
- static abstract class RecordSource {
+ @SystemApi
+ public static abstract class RecordSource {
protected final int mSourceType;
protected final int mExtraDataSize;
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 671f722..a680b51 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -47,7 +47,6 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
}
private final Context mContext;
- private final Handler mHandler;
private final H mUiHandler = new H();
private final Callback mCallback;
private final Uri mDefaultUri;
@@ -55,8 +54,9 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
private final int mStreamType;
private final int mMaxStreamVolume;
private final Receiver mReceiver = new Receiver();
- private final Observer mVolumeObserver;
+ private Handler mHandler;
+ private Observer mVolumeObserver;
private int mOriginalStreamVolume;
private Ringtone mRingtone;
private int mLastProgress = -1;
@@ -75,16 +75,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mStreamType = streamType;
mMaxStreamVolume = mAudioManager.getStreamMaxVolume(mStreamType);
- HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
- thread.start();
- mHandler = new Handler(thread.getLooper(), this);
mCallback = callback;
mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
- mVolumeObserver = new Observer(mHandler);
- mContext.getContentResolver().registerContentObserver(
- System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
- false, mVolumeObserver);
- mReceiver.setListening(true);
if (defaultUri == null) {
if (mStreamType == AudioManager.STREAM_RING) {
defaultUri = Settings.System.DEFAULT_RINGTONE_URI;
@@ -95,7 +87,6 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
}
}
mDefaultUri = defaultUri;
- mHandler.sendEmptyMessage(MSG_INIT_SAMPLE);
}
public void setSeekBar(SeekBar seekBar) {
@@ -173,11 +164,27 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba
}
public void stop() {
+ if (mHandler == null) return; // already stopped
postStopSample();
mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
- mSeekBar.setOnSeekBarChangeListener(null);
mReceiver.setListening(false);
+ mSeekBar.setOnSeekBarChangeListener(null);
mHandler.getLooper().quitSafely();
+ mHandler = null;
+ mVolumeObserver = null;
+ }
+
+ public void start() {
+ if (mHandler != null) return; // already started
+ HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
+ thread.start();
+ mHandler = new Handler(thread.getLooper(), this);
+ mHandler.sendEmptyMessage(MSG_INIT_SAMPLE);
+ mVolumeObserver = new Observer(mHandler);
+ mContext.getContentResolver().registerContentObserver(
+ System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
+ false, mVolumeObserver);
+ mReceiver.setListening(true);
}
public void revertVolume() {
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index df9e10e..86d96f2 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -67,6 +67,7 @@ public class VolumePreference extends SeekBarDialogPreference implements
final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
mSeekBarVolumizer = new SeekBarVolumizer(getContext(), mStreamType, null, this);
+ mSeekBarVolumizer.start();
mSeekBarVolumizer.setSeekBar(seekBar);
getPreferenceManager().registerOnActivityStopListener(this);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 79e84d9..75c435e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5013,10 +5013,19 @@ public final class Settings {
default:
throw new IllegalArgumentException("Invalid location mode: " + mode);
}
- boolean gpsSuccess = Settings.Secure.setLocationProviderEnabledForUser(
- cr, LocationManager.GPS_PROVIDER, gps, userId);
+ // Note it's important that we set the NLP mode first. The Google implementation
+ // of NLP clears its NLP consent setting any time it receives a
+ // LocationManager.PROVIDERS_CHANGED_ACTION broadcast and NLP is disabled. Also,
+ // it shows an NLP consent dialog any time it receives the broadcast, NLP is
+ // enabled, and the NLP consent is not set. If 1) we were to enable GPS first,
+ // 2) a setup wizard has its own NLP consent UI that sets the NLP consent setting,
+ // and 3) the receiver happened to complete before we enabled NLP, then the Google
+ // NLP would detect the attempt to enable NLP and show a redundant NLP consent
+ // dialog. Then the people who wrote the setup wizard would be sad.
boolean nlpSuccess = Settings.Secure.setLocationProviderEnabledForUser(
cr, LocationManager.NETWORK_PROVIDER, network, userId);
+ boolean gpsSuccess = Settings.Secure.setLocationProviderEnabledForUser(
+ cr, LocationManager.GPS_PROVIDER, gps, userId);
return gpsSuccess && nlpSuccess;
}
}
@@ -6579,6 +6588,14 @@ public final class Settings {
public static final String REQUIRE_PASSWORD_TO_DECRYPT = "require_password_to_decrypt";
/**
+ * Whether the Volte/VT is enabled
+ * <p>
+ * Type: int (0 for false, 1 for true)
+ * @hide
+ */
+ public static final String VOLTE_VT_ENABLED = "volte_vt_enabled";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
diff --git a/core/java/android/util/PathParser.java b/core/java/android/util/PathParser.java
index 6820f77..e5f3b2c 100644
--- a/core/java/android/util/PathParser.java
+++ b/core/java/android/util/PathParser.java
@@ -34,7 +34,11 @@ public class PathParser {
Path path = new Path();
PathDataNode[] nodes = createNodesFromPathData(pathData);
if (nodes != null) {
- PathDataNode.nodesToPath(nodes, path);
+ try {
+ PathDataNode.nodesToPath(nodes, path);
+ } catch (RuntimeException e) {
+ throw new RuntimeException("Error in parsing " + pathData, e);
+ }
return path;
}
return null;
@@ -128,7 +132,12 @@ public class PathParser {
while (end < s.length()) {
c = s.charAt(end);
- if (((c - 'A') * (c - 'Z') <= 0) || (((c - 'a') * (c - 'z') <= 0))) {
+ // Note that 'e' or 'E' are not valid path commands, but could be
+ // used for floating point numbers' scientific notation.
+ // Therefore, when searching for next command, we should ignore 'e'
+ // and 'E'.
+ if ((((c - 'A') * (c - 'Z') <= 0) || ((c - 'a') * (c - 'z') <= 0))
+ && c != 'e' && c != 'E') {
return end;
}
end++;
@@ -142,9 +151,9 @@ public class PathParser {
private static class ExtractFloatResult {
// We need to return the position of the next separator and whether the
- // next float starts with a '-'.
+ // next float starts with a '-' or a '.'.
int mEndPosition;
- boolean mEndWithNegSign;
+ boolean mEndWithNegOrDot;
}
/**
@@ -179,8 +188,8 @@ public class PathParser {
s.substring(startPosition, endPosition));
}
- if (result.mEndWithNegSign) {
- // Keep the '-' sign with next number.
+ if (result.mEndWithNegOrDot) {
+ // Keep the '-' or '.' sign with next number.
startPosition = endPosition;
} else {
startPosition = endPosition + 1;
@@ -188,8 +197,7 @@ public class PathParser {
}
return Arrays.copyOf(results, count);
} catch (NumberFormatException e) {
- Log.e(LOGTAG, "error in parsing \"" + s + "\"");
- throw e;
+ throw new RuntimeException("error in parsing \"" + s + "\"", e);
}
}
@@ -201,11 +209,15 @@ public class PathParser {
* the starting position of next number, whether it is ending with a '-'.
*/
private static void extract(String s, int start, ExtractFloatResult result) {
- // Now looking for ' ', ',' or '-' from the start.
+ // Now looking for ' ', ',', '.' or '-' from the start.
int currentIndex = start;
boolean foundSeparator = false;
- result.mEndWithNegSign = false;
+ result.mEndWithNegOrDot = false;
+ boolean secondDot = false;
+ boolean isExponential = false;
for (; currentIndex < s.length(); currentIndex++) {
+ boolean isPrevExponential = isExponential;
+ isExponential = false;
char currentChar = s.charAt(currentIndex);
switch (currentChar) {
case ' ':
@@ -213,11 +225,25 @@ public class PathParser {
foundSeparator = true;
break;
case '-':
- if (currentIndex != start) {
+ // The negative sign following a 'e' or 'E' is not a separator.
+ if (currentIndex != start && !isPrevExponential) {
foundSeparator = true;
- result.mEndWithNegSign = true;
+ result.mEndWithNegOrDot = true;
}
break;
+ case '.':
+ if (!secondDot) {
+ secondDot = true;
+ } else {
+ // This is the second dot, and it is considered as a separator.
+ foundSeparator = true;
+ result.mEndWithNegOrDot = true;
+ }
+ break;
+ case 'e':
+ case 'E':
+ isExponential = true;
+ break;
}
if (foundSeparator) {
break;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1ecc8d9..8e58cd6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16617,8 +16617,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
invalidate(true);
refreshDrawableState();
dispatchSetSelected(selected);
- notifyViewAccessibilityStateChangedIfNeeded(
- AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+ if (selected) {
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+ } else {
+ notifyViewAccessibilityStateChangedIfNeeded(
+ AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
+ }
}
}
@@ -17414,17 +17418,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
long key = (long) widthMeasureSpec << 32 | (long) heightMeasureSpec & 0xffffffffL;
if (mMeasureCache == null) mMeasureCache = new LongSparseLongArray(2);
- if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
- widthMeasureSpec != mOldWidthMeasureSpec ||
- heightMeasureSpec != mOldHeightMeasureSpec) {
+ final boolean forceLayout = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
+ final boolean isExactly = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
+ MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY;
+ final boolean matchingSize = isExactly &&
+ getMeasuredWidth() == MeasureSpec.getSize(widthMeasureSpec) &&
+ getMeasuredHeight() == MeasureSpec.getSize(heightMeasureSpec);
+ if (forceLayout || !matchingSize &&
+ (widthMeasureSpec != mOldWidthMeasureSpec ||
+ heightMeasureSpec != mOldHeightMeasureSpec)) {
// first clears the measured dimension flag
mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
resolveRtlPropertiesIfNeeded();
- int cacheIndex = (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ? -1 :
- mMeasureCache.indexOfKey(key);
+ int cacheIndex = forceLayout ? -1 : mMeasureCache.indexOfKey(key);
if (cacheIndex < 0 || sIgnoreMeasureCache) {
// measure ourselves, this should set the measured dimension flag back
onMeasure(widthMeasureSpec, heightMeasureSpec);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 4116b6b..7538dff 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -864,6 +864,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (siblingBounds.intersect(bounds)) {
// If an interactive sibling completely covers the child, done.
if (siblingBounds.equals(bounds)) {
+ if (orderedList != null) orderedList.clear();
return false;
}
// Keep track of the intersection rectangle.
@@ -871,6 +872,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
intersections.add(intersection);
}
}
+ if (orderedList != null) orderedList.clear();
if (mParent instanceof ViewGroup) {
ViewGroup parentGroup = (ViewGroup) mParent;
@@ -3293,7 +3295,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* Populates (and returns) mPreSortedChildren with a pre-ordered list of the View's children,
- * sorted first by Z, then by child drawing order (if applicable).
+ * sorted first by Z, then by child drawing order (if applicable). This list must be cleared
+ * after use to avoid leaking child Views.
*
* Uses a stable, insertion sort which is commonly O(n) for ViewGroups with very few elevated
* children.
@@ -3668,6 +3671,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @see #generateDefaultLayoutParams()
*/
public void addView(View child, int index) {
+ if (child == null) {
+ throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
+ }
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
@@ -3725,6 +3731,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
System.out.println(this + " addView");
}
+ if (child == null) {
+ throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
+ }
+
// addViewInner() will call child.requestLayout() when setting the new LayoutParams
// therefore, we call requestLayout() on ourselves before, so that the child's request
// will be blocked at our level
@@ -3852,6 +3862,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
protected boolean addViewInLayout(View child, int index, LayoutParams params,
boolean preventRequestLayout) {
+ if (child == null) {
+ throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
+ }
child.mParent = null;
addViewInner(child, index, params, preventRequestLayout);
child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
@@ -6488,7 +6501,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public static class MarginLayoutParams extends ViewGroup.LayoutParams {
/**
- * The left margin in pixels of the child.
+ * The left margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6496,7 +6509,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public int leftMargin;
/**
- * The top margin in pixels of the child.
+ * The top margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6504,7 +6517,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public int topMargin;
/**
- * The right margin in pixels of the child.
+ * The right margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6512,7 +6525,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public int rightMargin;
/**
- * The bottom margin in pixels of the child.
+ * The bottom margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6520,7 +6533,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
public int bottomMargin;
/**
- * The start margin in pixels of the child.
+ * The start margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6528,7 +6541,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
private int startMargin = DEFAULT_MARGIN_RELATIVE;
/**
- * The end margin in pixels of the child.
+ * The end margin in pixels of the child. Margin values should be positive.
* Call {@link ViewGroup#setLayoutParams(LayoutParams)} after reassigning a new value
* to this field.
*/
@@ -6709,6 +6722,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* Sets the margins, in pixels. A call to {@link android.view.View#requestLayout()} needs
* to be done so that the new margins are taken into account. Left and right margins may be
* overriden by {@link android.view.View#requestLayout()} depending on layout direction.
+ * Margin values should be positive.
*
* @param left the left margin size
* @param top the top margin size
@@ -6738,7 +6752,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* Sets the relative margins, in pixels. A call to {@link android.view.View#requestLayout()}
* needs to be done so that the new relative margins are taken into account. Left and right
* margins may be overriden by {@link android.view.View#requestLayout()} depending on layout
- * direction.
+ * direction. Margin values should be positive.
*
* @param start the start margin size
* @param top the top margin size
@@ -6761,7 +6775,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
- * Sets the relative start margin.
+ * Sets the relative start margin. Margin values should be positive.
*
* @param start the start margin size
*
@@ -6794,7 +6808,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
- * Sets the relative end margin.
+ * Sets the relative end margin. Margin values should be positive.
*
* @param end the end margin size
*
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 10e56c7..5c05b5a 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -99,12 +99,12 @@ public class AppSecurityPermissions {
public Drawable loadGroupIcon(PackageManager pm) {
if (icon != 0) {
- return loadIcon(pm);
+ return loadUnbadgedIcon(pm);
} else {
ApplicationInfo appInfo;
try {
appInfo = pm.getApplicationInfo(packageName, 0);
- return appInfo.loadIcon(pm);
+ return appInfo.loadUnbadgedIcon(pm);
} catch (NameNotFoundException e) {
}
}
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index ea60abb..f380d68 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -775,9 +775,14 @@ public class CalendarView extends FrameLayout {
private ViewGroup mDayNamesHeader;
/**
- * Cached labels for the week names header.
+ * Cached abbreviations for day of week names.
*/
- private String[] mDayLabels;
+ private String[] mDayNamesShort;
+
+ /**
+ * Cached full-length day of week names.
+ */
+ private String[] mDayNamesLong;
/**
* The first day of the week.
@@ -1306,11 +1311,14 @@ public class CalendarView extends FrameLayout {
* Sets up the strings to be used by the header.
*/
private void setUpHeader() {
- mDayLabels = new String[mDaysPerWeek];
+ mDayNamesShort = new String[mDaysPerWeek];
+ mDayNamesLong = new String[mDaysPerWeek];
for (int i = mFirstDayOfWeek, count = mFirstDayOfWeek + mDaysPerWeek; i < count; i++) {
int calendarDay = (i > Calendar.SATURDAY) ? i - Calendar.SATURDAY : i;
- mDayLabels[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+ mDayNamesShort[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
DateUtils.LENGTH_SHORTEST);
+ mDayNamesLong[i - mFirstDayOfWeek] = DateUtils.getDayOfWeekString(calendarDay,
+ DateUtils.LENGTH_LONG);
}
TextView label = (TextView) mDayNamesHeader.getChildAt(0);
@@ -1325,7 +1333,8 @@ public class CalendarView extends FrameLayout {
label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
}
if (i < mDaysPerWeek + 1) {
- label.setText(mDayLabels[i - 1]);
+ label.setText(mDayNamesShort[i - 1]);
+ label.setContentDescription(mDayNamesLong[i - 1]);
label.setVisibility(View.VISIBLE);
} else {
label.setVisibility(View.GONE);
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 3c186e3..9f540c0 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -1639,6 +1639,11 @@ public class ListPopupWindow {
setPressed(false);
updateSelectorState();
+ final View motionView = getChildAt(mMotionPosition - mFirstPosition);
+ if (motionView != null) {
+ motionView.setPressed(false);
+ }
+
if (mClickAnimation != null) {
mClickAnimation.cancel();
mClickAnimation = null;
@@ -1653,6 +1658,15 @@ public class ListPopupWindow {
setPressed(true);
layoutChildren();
+ // Manage the pressed view based on motion position. This allows us to
+ // play nicely with actual touch and scroll events.
+ final View motionView = getChildAt(mMotionPosition - mFirstPosition);
+ if (motionView != null) {
+ motionView.setPressed(false);
+ }
+ mMotionPosition = position;
+ child.setPressed(true);
+
// Ensure that keyboard focus starts from the last touched position.
setSelectedPositionInt(position);
positionSelectorLikeTouch(position, child, x, y);
diff --git a/core/java/android/widget/PopupMenu.java b/core/java/android/widget/PopupMenu.java
index 111dadc..2708398 100644
--- a/core/java/android/widget/PopupMenu.java
+++ b/core/java/android/widget/PopupMenu.java
@@ -16,6 +16,7 @@
package android.widget;
+import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuPopupHelper;
import com.android.internal.view.menu.MenuPresenter;
@@ -37,10 +38,11 @@ import android.widget.ListPopupWindow.ForwardingListener;
* of the popup will dismiss it.
*/
public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback {
- private Context mContext;
- private MenuBuilder mMenu;
- private View mAnchor;
- private MenuPopupHelper mPopup;
+ private final Context mContext;
+ private final MenuBuilder mMenu;
+ private final View mAnchor;
+ private final MenuPopupHelper mPopup;
+
private OnMenuItemClickListener mMenuItemClickListener;
private OnDismissListener mDismissListener;
private OnTouchListener mDragListener;
@@ -58,31 +60,56 @@ public class PopupMenu implements MenuBuilder.Callback, MenuPresenter.Callback {
}
/**
- * Construct a new PopupMenu.
+ * Constructor to create a new popup menu with an anchor view.
*
- * @param context Context for the PopupMenu.
- * @param anchor Anchor view for this popup. The popup will appear below the anchor if there
- * is room, or above it if there is not.
+ * @param context Context the popup menu is running in, through which it
+ * can access the current theme, resources, etc.
+ * @param anchor Anchor view for this popup. The popup will appear below
+ * the anchor if there is room, or above it if there is not.
*/
public PopupMenu(Context context, View anchor) {
this(context, anchor, Gravity.NO_GRAVITY);
}
/**
- * Construct a new PopupMenu.
+ * Constructor to create a new popup menu with an anchor view and alignment
+ * gravity.
*
- * @param context Context for the PopupMenu.
- * @param anchor Anchor view for this popup. The popup will appear below the anchor if there
- * is room, or above it if there is not.
- * @param gravity The {@link Gravity} value for aligning the popup with its anchor
+ * @param context Context the popup menu is running in, through which it
+ * can access the current theme, resources, etc.
+ * @param anchor Anchor view for this popup. The popup will appear below
+ * the anchor if there is room, or above it if there is not.
+ * @param gravity The {@link Gravity} value for aligning the popup with its
+ * anchor.
*/
public PopupMenu(Context context, View anchor, int gravity) {
- // TODO Theme?
+ this(context, anchor, gravity, R.attr.popupMenuStyle, 0);
+ }
+
+ /**
+ * Constructor a create a new popup menu with a specific style.
+ *
+ * @param context Context the popup menu is running in, through which it
+ * can access the current theme, resources, etc.
+ * @param anchor Anchor view for this popup. The popup will appear below
+ * the anchor if there is room, or above it if there is not.
+ * @param gravity The {@link Gravity} value for aligning the popup with its
+ * anchor.
+ * @param popupStyleAttr An attribute in the current theme that contains a
+ * reference to a style resource that supplies default values for
+ * the popup window. Can be 0 to not look for defaults.
+ * @param popupStyleRes A resource identifier of a style resource that
+ * supplies default values for the popup window, used only if
+ * popupStyleAttr is 0 or can not be found in the theme. Can be 0
+ * to not look for defaults.
+ */
+ public PopupMenu(Context context, View anchor, int gravity, int popupStyleAttr,
+ int popupStyleRes) {
mContext = context;
mMenu = new MenuBuilder(context);
mMenu.setCallback(this);
mAnchor = anchor;
- mPopup = new MenuPopupHelper(context, mMenu, anchor);
+ mPopup = new MenuPopupHelper(context, mMenu, anchor, false, popupStyleAttr, popupStyleRes);
mPopup.setGravity(gravity);
mPopup.setCallback(this);
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index e9298c2..1c190c3 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -604,6 +604,7 @@ public class ProgressBar extends View {
* @see #getIndeterminateTintList()
* @see Drawable#setTintList(ColorStateList)
*/
+ @RemotableViewMethod
public void setIndeterminateTintList(@Nullable ColorStateList tint) {
if (mProgressTintInfo == null) {
mProgressTintInfo = new ProgressTintInfo();
@@ -842,6 +843,7 @@ public class ProgressBar extends View {
* @see #getProgressTintList()
* @see Drawable#setTintList(ColorStateList)
*/
+ @RemotableViewMethod
public void setProgressTintList(@Nullable ColorStateList tint) {
if (mProgressTintInfo == null) {
mProgressTintInfo = new ProgressTintInfo();
@@ -923,6 +925,7 @@ public class ProgressBar extends View {
* @see #getProgressBackgroundTintList()
* @see Drawable#setTintList(ColorStateList)
*/
+ @RemotableViewMethod
public void setProgressBackgroundTintList(@Nullable ColorStateList tint) {
if (mProgressTintInfo == null) {
mProgressTintInfo = new ProgressTintInfo();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 7cb3c37..80f364b 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -27,6 +27,7 @@ import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
@@ -1069,6 +1070,7 @@ public class RemoteViews implements Parcelable, Filter {
static final int BITMAP = 12;
static final int BUNDLE = 13;
static final int INTENT = 14;
+ static final int COLOR_STATE_LIST = 15;
String methodName;
int type;
@@ -1142,6 +1144,11 @@ public class RemoteViews implements Parcelable, Filter {
this.value = Intent.CREATOR.createFromParcel(in);
}
break;
+ case COLOR_STATE_LIST:
+ if (in.readInt() != 0) {
+ this.value = ColorStateList.CREATOR.createFromParcel(in);
+ }
+ break;
default:
break;
}
@@ -1212,6 +1219,11 @@ public class RemoteViews implements Parcelable, Filter {
((Intent)this.value).writeToParcel(out, flags);
}
break;
+ case COLOR_STATE_LIST:
+ out.writeInt(this.value != null ? 1 : 0);
+ if (this.value != null) {
+ ((ColorStateList)this.value).writeToParcel(out, flags);
+ }
default:
break;
}
@@ -1247,6 +1259,8 @@ public class RemoteViews implements Parcelable, Filter {
return Bundle.class;
case INTENT:
return Intent.class;
+ case COLOR_STATE_LIST:
+ return ColorStateList.class;
default:
return null;
}
@@ -2207,6 +2221,42 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * @hide
+ * Equivalent to calling {@link android.widget.ProgressBar#setProgressTintList}.
+ *
+ * @param viewId The id of the view whose tint should change
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setProgressTintList(int viewId, ColorStateList tint) {
+ addAction(new ReflectionAction(viewId, "setProgressTintList",
+ ReflectionAction.COLOR_STATE_LIST, tint));
+ }
+
+ /**
+ * @hide
+ * Equivalent to calling {@link android.widget.ProgressBar#setProgressBackgroundTintList}.
+ *
+ * @param viewId The id of the view whose tint should change
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setProgressBackgroundTintList(int viewId, ColorStateList tint) {
+ addAction(new ReflectionAction(viewId, "setProgressBackgroundTintList",
+ ReflectionAction.COLOR_STATE_LIST, tint));
+ }
+
+ /**
+ * @hide
+ * Equivalent to calling {@link android.widget.ProgressBar#setIndeterminateTintList}.
+ *
+ * @param viewId The id of the view whose tint should change
+ * @param tint the tint to apply, may be {@code null} to clear tint
+ */
+ public void setProgressIndeterminateTintList(int viewId, ColorStateList tint) {
+ addAction(new ReflectionAction(viewId, "setIndeterminateTintList",
+ ReflectionAction.COLOR_STATE_LIST, tint));
+ }
+
+ /**
* Equivalent to calling {@link android.widget.TextView#setTextColor(int)}.
*
* @param viewId The id of the view whose text color should change
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 1ce19ce..d8e39e3 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -66,7 +66,9 @@ import java.util.List;
* <li><em>A navigation button.</em> This may be an Up arrow, navigation menu toggle, close,
* collapse, done or another glyph of the app's choosing. This button should always be used
* to access other navigational destinations within the container of the Toolbar and
- * its signified content or otherwise leave the current context signified by the Toolbar.</li>
+ * its signified content or otherwise leave the current context signified by the Toolbar.
+ * The navigation button is vertically aligned within the Toolbar's
+ * {@link android.R.styleable#View_minHeight minimum height}, if set.</li>
* <li><em>A branded logo image.</em> This may extend to the height of the bar and can be
* arbitrarily wide.</li>
* <li><em>A title and subtitle.</em> The title should be a signpost for the Toolbar's current
@@ -82,8 +84,9 @@ import java.util.List;
* <li><em>An {@link ActionMenuView action menu}.</em> The menu of actions will pin to the
* end of the Toolbar offering a few
* <a href="http://developer.android.com/design/patterns/actionbar.html#ActionButtons">
- * frequent, important or typical</a> actions along with an optional overflow menu for
- * additional actions.</li>
+ * frequent, important or typical</a> actions along with an optional overflow menu for
+ * additional actions. Action buttons are vertically aligned within the Toolbar's
+ * {@link android.R.styleable#View_minHeight minimum height}, if set.</li>
* </ul>
* </p>
*
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0062e2d..f9da09a 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -819,6 +819,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
+ UserManager userManager =
+ (UserManager) getSystemService(Context.USER_SERVICE);
+ if (userManager.isManagedProfile()) {
+ ri.noResourceId = true;
+ }
if (ii instanceof LabeledIntent) {
LabeledIntent li = (LabeledIntent)ii;
ri.resolvePackageName = li.getSourcePackage();
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 40f58e9..99bb1ac 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -54,6 +54,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
private final boolean mOverflowOnly;
private final int mPopupMaxWidth;
private final int mPopupStyleAttr;
+ private final int mPopupStyleRes;
private View mAnchorView;
private ListPopupWindow mPopup;
@@ -73,21 +74,27 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
private int mDropDownGravity = Gravity.NO_GRAVITY;
public MenuPopupHelper(Context context, MenuBuilder menu) {
- this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle);
+ this(context, menu, null, false, com.android.internal.R.attr.popupMenuStyle, 0);
}
public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView) {
- this(context, menu, anchorView, false, com.android.internal.R.attr.popupMenuStyle);
+ this(context, menu, anchorView, false, com.android.internal.R.attr.popupMenuStyle, 0);
}
public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView,
boolean overflowOnly, int popupStyleAttr) {
+ this(context, menu, anchorView, overflowOnly, popupStyleAttr, 0);
+ }
+
+ public MenuPopupHelper(Context context, MenuBuilder menu, View anchorView,
+ boolean overflowOnly, int popupStyleAttr, int popupStyleRes) {
mContext = context;
mInflater = LayoutInflater.from(context);
mMenu = menu;
mAdapter = new MenuAdapter(mMenu);
mOverflowOnly = overflowOnly;
mPopupStyleAttr = popupStyleAttr;
+ mPopupStyleRes = popupStyleRes;
final Resources res = context.getResources();
mPopupMaxWidth = Math.max(res.getDisplayMetrics().widthPixels / 2,
@@ -122,7 +129,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
}
public boolean tryShow() {
- mPopup = new ListPopupWindow(mContext, null, mPopupStyleAttr);
+ mPopup = new ListPopupWindow(mContext, null, mPopupStyleAttr, mPopupStyleRes);
mPopup.setOnDismissListener(this);
mPopup.setOnItemClickListener(this);
mPopup.setAdapter(mAdapter);
diff --git a/core/java/com/android/internal/widget/ExploreByTouchHelper.java b/core/java/com/android/internal/widget/ExploreByTouchHelper.java
index 11c4ca1..4689179 100644
--- a/core/java/com/android/internal/widget/ExploreByTouchHelper.java
+++ b/core/java/com/android/internal/widget/ExploreByTouchHelper.java
@@ -54,6 +54,10 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
/** Default class name used for virtual views. */
private static final String DEFAULT_CLASS_NAME = View.class.getName();
+ /** Default bounds used to determine if the client didn't set any. */
+ private static final Rect INVALID_PARENT_BOUNDS = new Rect(
+ Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
+
// Temporary, reusable data structures.
private final Rect mTempScreenRect = new Rect();
private final Rect mTempParentRect = new Rect();
@@ -372,6 +376,7 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
// Ensure the client has good defaults.
node.setEnabled(true);
node.setClassName(DEFAULT_CLASS_NAME);
+ node.setBoundsInParent(INVALID_PARENT_BOUNDS);
// Allow the client to populate the node.
onPopulateNodeForVirtualView(virtualViewId, node);
@@ -383,7 +388,7 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate {
}
node.getBoundsInParent(mTempParentRect);
- if (mTempParentRect.isEmpty()) {
+ if (mTempParentRect.equals(INVALID_PARENT_BOUNDS)) {
throw new RuntimeException("Callbacks must set parent bounds in "
+ "populateNodeForVirtualViewId()");
}