diff options
71 files changed, 1627 insertions, 433 deletions
@@ -429,10 +429,10 @@ framework_docs_SDK_CURRENT_DIR:=$(framework_docs_SDK_VERSION)_r$(framework_docs_ framework_docs_SDK_PREVIEW:=0 ## Latest ADT version identifiers, for reference from published docs -framework_docs_ADT_VERSION:=0.9.7 -framework_docs_ADT_DOWNLOAD:=ADT-0.9.7.zip -framework_docs_ADT_BYTES:=8033750 -framework_docs_ADT_CHECKSUM:=de2431c8d4786d127ae5bfc95b4605df +framework_docs_ADT_VERSION:=0.9.8 +framework_docs_ADT_DOWNLOAD:=ADT-0.9.8.zip +framework_docs_ADT_BYTES:=8703591 +framework_docs_ADT_CHECKSUM:=22070f8e52924605a3b3abf87c1ba39f framework_docs_LOCAL_DROIDDOC_OPTIONS += \ -hdf sdk.version $(framework_docs_SDK_VERSION) \ diff --git a/api/current.xml b/api/current.xml index e938246..a495d04 100644 --- a/api/current.xml +++ b/api/current.xml @@ -4024,6 +4024,17 @@ visibility="public" > </field> +<field name="filterTouchesWhenObscured" + type="int" + transient="false" + volatile="false" + value="16843460" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="finishOnCloseSystemDialogs" type="int" transient="false" @@ -5861,17 +5872,6 @@ visibility="public" > </field> -<field name="kraken_resource_pad61" - type="int" - transient="false" - volatile="false" - value="16843460" - static="true" - final="true" - deprecated="not deprecated" - visibility="public" -> -</field> <field name="kraken_resource_pad7" type="int" transient="false" @@ -78402,7 +78402,7 @@ type="float" transient="false" volatile="false" - value="0.001f" + value="0.0010f" static="true" final="true" deprecated="not deprecated" @@ -140773,6 +140773,17 @@ visibility="public" > </field> +<field name="INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.media.action.MEDIA_PLAY_FROM_SEARCH"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="INTENT_ACTION_MEDIA_SEARCH" type="java.lang.String" transient="false" @@ -164852,6 +164863,29 @@ <parameter name="flags" type="int"> </parameter> </method> +<method name="formatDateRange" + return="java.util.Formatter" + abstract="false" + native="false" + synchronized="false" + static="true" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="context" type="android.content.Context"> +</parameter> +<parameter name="formatter" type="java.util.Formatter"> +</parameter> +<parameter name="startMillis" type="long"> +</parameter> +<parameter name="endMillis" type="long"> +</parameter> +<parameter name="flags" type="int"> +</parameter> +<parameter name="timeZone" type="java.lang.String"> +</parameter> +</method> <method name="formatDateTime" return="java.lang.String" abstract="false" @@ -165345,7 +165379,7 @@ value="8192" static="true" final="true" - deprecated="not deprecated" + deprecated="deprecated" visibility="public" > </field> @@ -181662,6 +181696,17 @@ visibility="public" > </method> +<method name="getFlags" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="true" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getHistoricalEventTime" return="long" abstract="false" @@ -182299,6 +182344,8 @@ </parameter> <parameter name="source" type="int"> </parameter> +<parameter name="flags" type="int"> +</parameter> </method> <method name="obtain" return="android.view.MotionEvent" @@ -182755,6 +182802,17 @@ visibility="public" > </field> +<field name="FLAG_WINDOW_IS_OBSCURED" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="MotionEvent.PointerCoords" extends="java.lang.Object" @@ -185477,6 +185535,17 @@ visibility="public" > </method> +<method name="getFilterTouchesWhenObscured" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="getFocusables" return="java.util.ArrayList<android.view.View>" abstract="false" @@ -186765,6 +186834,19 @@ <parameter name="canvas" type="android.graphics.Canvas"> </parameter> </method> +<method name="onFilterTouchEventForSecurity" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="event" type="android.view.MotionEvent"> +</parameter> +</method> <method name="onFinishInflate" return="void" abstract="false" @@ -187671,6 +187753,19 @@ <parameter name="length" type="int"> </parameter> </method> +<method name="setFilterTouchesWhenObscured" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="enabled" type="boolean"> +</parameter> +</method> <method name="setFocusable" return="void" abstract="false" @@ -225393,7 +225488,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="arg0" type="T"> +<parameter name="t" type="T"> </parameter> </method> </interface> diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 2acc4a0..7154aee 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -1567,6 +1567,30 @@ public class Intent implements Parcelable, Cloneable { @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK"; /** + * Broadcast Action: A sticky broadcast that indicates a memory full + * condition on the device. This is intended for activities that want + * to be able to fill the data partition completely, leaving only + * enough free space to prevent system-wide SQLite failures. + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * + * {@hide} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DEVICE_STORAGE_FULL = "android.intent.action.DEVICE_STORAGE_FULL"; + /** + * Broadcast Action: Indicates memory full condition on the device + * no longer exists. + * + * <p class="note">This is a protected intent that can only be sent + * by the system. + * + * {@hide} + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_DEVICE_STORAGE_NOT_FULL = "android.intent.action.DEVICE_STORAGE_NOT_FULL"; + /** * Broadcast Action: Indicates low memory condition notification acknowledged by user * and package management should be started. * This is triggered by the user from the ACTION_DEVICE_STORAGE_LOW diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 280ded6..331ce10 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -102,6 +102,14 @@ public class ConnectivityManager * it with {@link android.content.Intent#getStringExtra(String)}. */ public static final String EXTRA_EXTRA_INFO = "extraInfo"; + /** + * The lookup key for an int that provides information about + * our connection to the internet at large. 0 indicates no connection, + * 100 indicates a great connection. Retrieve it with + * {@link android.content.Intent@getIntExtra(String)}. + * {@hide} + */ + public static final String EXTRA_INET_CONDITION = "inetCondition"; /** * Broadcast Action: The setting for background data usage has changed @@ -524,5 +532,17 @@ public class ConnectivityManager } catch (RemoteException e) { return TETHER_ERROR_SERVICE_UNAVAIL; } - } + } + + /** + * @param networkType The type of network you want to report on + * @param percentage The quality of the connection 0 is bad, 100 is good + * {@hide} + */ + public void reportInetCondition(int networkType, int percentage) { + try { + mService.reportInetCondition(networkType, percentage); + } catch (RemoteException e) { + } + } } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index b05c2ed..b734ac7 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -72,4 +72,6 @@ interface IConnectivityManager String[] getTetherableUsbRegexs(); String[] getTetherableWifiRegexs(); + + void reportInetCondition(int networkType, int percentage); } diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java index 0277d2d..c5a3277 100644 --- a/core/java/android/net/NetworkStateTracker.java +++ b/core/java/android/net/NetworkStateTracker.java @@ -62,6 +62,15 @@ public abstract class NetworkStateTracker extends Handler { public static final int EVENT_ROAMING_CHANGED = 5; public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 6; public static final int EVENT_RESTORE_DEFAULT_NETWORK = 7; + /** + * arg1: network type + * arg2: condition (0 bad, 100 good) + */ + public static final int EVENT_INET_CONDITION_CHANGE = 8; + /** + * arg1: network type + */ + public static final int EVENT_INET_CONDITION_HOLD_END = 9; public NetworkStateTracker(Context context, Handler target, diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index a857e58..32fb108 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -1586,8 +1586,10 @@ public abstract class BatteryStats implements Parcelable { sb.append(prefix); sb.append(" CPU: "); formatTime(sb, userTime); sb.append("usr + "); formatTime(sb, systemTime); sb.append("krn\n"); - sb.append(prefix); sb.append(" "); sb.append(starts); - sb.append(" proc starts"); + if (starts != 0) { + sb.append(prefix); sb.append(" "); sb.append(starts); + sb.append(" proc starts"); + } pw.println(sb.toString()); for (int e=0; e<numExcessive; e++) { Uid.Proc.ExcessiveWake ew = ps.getExcessiveWake(e); diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index d20e89d..075da33 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -75,6 +75,22 @@ public final class MediaStore { public static final String INTENT_ACTION_MEDIA_SEARCH = "android.intent.action.MEDIA_SEARCH"; /** + * An intent to perform a search for music media and automatically play content from the + * result when possible. This can be fired, for example, by the result of a voice recognition + * command to listen to music. + * <p> + * Contains the {@link android.app.SearchManager#QUERY} extra, which is a string + * that can contain any type of unstructured music search, like the name of an artist, + * an album, a song, a genre, or any combination of these. + * <p> + * Because this intent includes an open-ended unstructured search string, it makes the most + * sense for apps that can support large-scale search of music, such as services connected + * to an online database of music which can be streamed and played on the device. + */ + public static final String INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH = + "android.media.action.MEDIA_PLAY_FROM_SEARCH"; + + /** * The name of the Intent-extra used to define the artist */ public static final String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist"; diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 78a384b..f37ef99 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2961,31 +2961,31 @@ public final class Settings { public static final String WTF_IS_FATAL = "wtf_is_fatal"; /** - * Maximum age of entries kept by {@link android.os.IDropBox}. + * Maximum age of entries kept by {@link com.android.internal.os.IDropBoxManagerService}. * @hide */ public static final String DROPBOX_AGE_SECONDS = "dropbox_age_seconds"; /** - * Maximum number of entry files which {@link android.os.IDropBox} will keep around. + * Maximum number of entry files which {@link com.android.internal.os.IDropBoxManagerService} will keep around. * @hide */ public static final String DROPBOX_MAX_FILES = "dropbox_max_files"; /** - * Maximum amount of disk space used by {@link android.os.IDropBox} no matter what. + * Maximum amount of disk space used by {@link com.android.internal.os.IDropBoxManagerService} no matter what. * @hide */ public static final String DROPBOX_QUOTA_KB = "dropbox_quota_kb"; /** - * Percent of free disk (excluding reserve) which {@link android.os.IDropBox} will use. + * Percent of free disk (excluding reserve) which {@link com.android.internal.os.IDropBoxManagerService} will use. * @hide */ public static final String DROPBOX_QUOTA_PERCENT = "dropbox_quota_percent"; /** - * Percent of total disk which {@link android.os.IDropBox} will never dip into. + * Percent of total disk which {@link com.android.internal.os.IDropBoxManagerService} will never dip into. * @hide */ public static final String DROPBOX_RESERVE_PERCENT = @@ -3045,6 +3045,15 @@ public final class Settings { "sys_storage_threshold_percentage"; /** + * Minimum bytes of free storage on the device before the data + * partition is considered full. By default, 1 MB is reserved + * to avoid system-wide SQLite disk full exceptions. + * @hide + */ + public static final String SYS_STORAGE_FULL_THRESHOLD_BYTES = + "sys_storage_full_threshold_bytes"; + + /** * The interval in milliseconds after which Wi-Fi is considered idle. * When idle, it is possible for the device to be switched from Wi-Fi to * the mobile data network. @@ -3418,6 +3427,21 @@ public final class Settings { public static final String DOWNLOAD_MAX_BYTES_OVER_MOBILE = "download_manager_max_bytes_over_mobile"; + /** + * ms during which to consume extra events related to Inet connection condition + * after a transtion to fully-connected + * @hide + */ + public static final String INET_CONDITION_DEBOUNCE_UP_DELAY = + "inet_condition_debounce_up_delay"; + + /** + * ms during which to consume extra events related to Inet connection condtion + * after a transtion to partly-connected + * @hide + */ + public static final String INET_CONDITION_DEBOUNCE_DOWN_DELAY = + "inet_condition_debounce_down_delay"; /** * @hide diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 57a72bf..2b083dc 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -30,6 +30,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; +import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; @@ -178,6 +179,9 @@ public abstract class WallpaperService extends Service { }; final BaseSurfaceHolder mSurfaceHolder = new BaseSurfaceHolder() { + { + mRequestedFormat = PixelFormat.RGB_565; + } @Override public boolean onAllowLockCanvas() { diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java index dde0889..4e2c3c3 100644 --- a/core/java/android/text/format/DateUtils.java +++ b/core/java/android/text/format/DateUtils.java @@ -168,6 +168,12 @@ public class DateUtils public static final int FORMAT_CAP_NOON = 0x00400; public static final int FORMAT_NO_MIDNIGHT = 0x00800; public static final int FORMAT_CAP_MIDNIGHT = 0x01000; + /** + * @deprecated Use + * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} + * and pass in {@link Time#TIMEZONE_UTC Time.TIMEZONE_UTC} for the timeZone instead. + */ + @Deprecated public static final int FORMAT_UTC = 0x02000; public static final int FORMAT_ABBREV_TIME = 0x04000; public static final int FORMAT_ABBREV_WEEKDAY = 0x08000; @@ -946,12 +952,12 @@ public class DateUtils * {@link java.util.Formatter} instance and use the version of * {@link #formatDateRange(Context, long, long, int) formatDateRange} * that takes a {@link java.util.Formatter}. - * + * * @param context the context is required only if the time is shown * @param startMillis the start time in UTC milliseconds * @param endMillis the end time in UTC milliseconds * @param flags a bit mask of options See - * {@link #formatDateRange(Context, long, long, int) formatDateRange} + * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} * @return a string containing the formatted date/time range. */ public static String formatDateRange(Context context, long startMillis, @@ -962,6 +968,29 @@ public class DateUtils /** * Formats a date or a time range according to the local conventions. + * <p> + * Note that this is a convenience method for formatting the date or + * time range in the local time zone. If you want to specify the time + * zone please use + * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}. + * + * @param context the context is required only if the time is shown + * @param formatter the Formatter used for formatting the date range. + * Note: be sure to call setLength(0) on StringBuilder passed to + * the Formatter constructor unless you want the results to accumulate. + * @param startMillis the start time in UTC milliseconds + * @param endMillis the end time in UTC milliseconds + * @param flags a bit mask of options See + * {@link #formatDateRange(Context, Formatter, long, long, int, String) formatDateRange} + * @return a string containing the formatted date/time range. + */ + public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis, + long endMillis, int flags) { + return formatDateRange(context, formatter, startMillis, endMillis, flags, null); + } + + /** + * Formats a date or a time range according to the local conventions. * * <p> * Example output strings (date formats in these examples are shown using @@ -1076,8 +1105,9 @@ public class DateUtils * FORMAT_24HOUR takes precedence. * * <p> - * If FORMAT_UTC is set, then the UTC timezone is used for the start - * and end milliseconds. + * If FORMAT_UTC is set, then the UTC time zone is used for the start + * and end milliseconds unless a time zone is specified. If a time zone + * is specified it will be used regardless of the FORMAT_UTC flag. * * <p> * If FORMAT_ABBREV_TIME is set and 12-hour time format is used, then the @@ -1109,11 +1139,13 @@ public class DateUtils * @param startMillis the start time in UTC milliseconds * @param endMillis the end time in UTC milliseconds * @param flags a bit mask of options - * + * @param timeZone the time zone to compute the string in. Use null for local + * or if the FORMAT_UTC flag is being used. + * * @return the formatter with the formatted date/time range appended to the string buffer. */ public static Formatter formatDateRange(Context context, Formatter formatter, long startMillis, - long endMillis, int flags) { + long endMillis, int flags, String timeZone) { Resources res = Resources.getSystem(); boolean showTime = (flags & FORMAT_SHOW_TIME) != 0; boolean showWeekDay = (flags & FORMAT_SHOW_WEEKDAY) != 0; @@ -1130,7 +1162,14 @@ public class DateUtils // computation below that'd otherwise be thrown out. boolean isInstant = (startMillis == endMillis); - Time startDate = useUTC ? new Time(Time.TIMEZONE_UTC) : new Time(); + Time startDate; + if (timeZone != null) { + startDate = new Time(timeZone); + } else if (useUTC) { + startDate = new Time(Time.TIMEZONE_UTC); + } else { + startDate = new Time(); + } startDate.set(startMillis); Time endDate; @@ -1139,7 +1178,13 @@ public class DateUtils endDate = startDate; dayDistance = 0; } else { - endDate = useUTC ? new Time(Time.TIMEZONE_UTC) : new Time(); + if (timeZone != null) { + endDate = new Time(timeZone); + } else if (useUTC) { + endDate = new Time(Time.TIMEZONE_UTC); + } else { + endDate = new Time(); + } endDate.set(endMillis); int startJulianDay = Time.getJulianDay(startMillis, startDate.gmtoff); int endJulianDay = Time.getJulianDay(endMillis, endDate.gmtoff); diff --git a/core/java/android/text/method/TextKeyListener.java b/core/java/android/text/method/TextKeyListener.java index 5be2a48..09cbbb8 100644 --- a/core/java/android/text/method/TextKeyListener.java +++ b/core/java/android/text/method/TextKeyListener.java @@ -246,8 +246,10 @@ public class TextKeyListener extends BaseKeyListener implements SpanWatcher { private void initPrefs(Context context) { final ContentResolver contentResolver = context.getContentResolver(); mResolver = new WeakReference<ContentResolver>(contentResolver); - mObserver = new SettingsObserver(); - contentResolver.registerContentObserver(Settings.System.CONTENT_URI, true, mObserver); + if (mObserver == null) { + mObserver = new SettingsObserver(); + contentResolver.registerContentObserver(Settings.System.CONTENT_URI, true, mObserver); + } updatePrefs(contentResolver); mPrefsInited = true; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 74318ba..78b9b5d 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -30,6 +30,7 @@ import android.os.SystemClock; */ public final class MotionEvent extends InputEvent implements Parcelable { private static final long MS_PER_NS = 1000000; + private static final boolean TRACK_RECYCLED_LOCATION = false; /** * Bit mask of the parts of the action code that are the action itself. @@ -155,7 +156,17 @@ public final class MotionEvent extends InputEvent implements Parcelable { @Deprecated public static final int ACTION_POINTER_ID_SHIFT = 8; - private static final boolean TRACK_RECYCLED_LOCATION = false; + /** + * This flag indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + public static final int FLAG_WINDOW_IS_OBSCURED = 0x1; /** * Flag indicating the motion event intersected the top edge of the screen. @@ -251,6 +262,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { private float mYPrecision; private int mEdgeFlags; private int mMetaState; + private int mFlags; private int mNumPointers; private int mNumSamples; @@ -338,20 +350,22 @@ public final class MotionEvent extends InputEvent implements Parcelable { * @param deviceId The id for the device that this event came from. An id of * zero indicates that the event didn't come from a physical device; other * numbers are arbitrary and you shouldn't depend on the values. - * @param edgeFlags A bitfield indicating which edges, if any, where touched by this + * @param edgeFlags A bitfield indicating which edges, if any, were touched by this * MotionEvent. * @param source The source of this event. + * @param flags The motion event flags. */ static public MotionEvent obtain(long downTime, long eventTime, int action, int pointers, int[] pointerIds, PointerCoords[] pointerCoords, int metaState, float xPrecision, float yPrecision, int deviceId, - int edgeFlags, int source) { + int edgeFlags, int source, int flags) { MotionEvent ev = obtain(pointers, 1); ev.mDeviceId = deviceId; ev.mSource = source; ev.mEdgeFlags = edgeFlags; ev.mDownTimeNano = downTime * MS_PER_NS; ev.mAction = action; + ev.mFlags = flags; ev.mMetaState = metaState; ev.mXOffset = 0; ev.mYOffset = 0; @@ -401,7 +415,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { * @param deviceId The id for the device that this event came from. An id of * zero indicates that the event didn't come from a physical device; other * numbers are arbitrary and you shouldn't depend on the values. - * @param edgeFlags A bitfield indicating which edges, if any, where touched by this + * @param edgeFlags A bitfield indicating which edges, if any, were touched by this * MotionEvent. */ static public MotionEvent obtain(long downTime, long eventTime, int action, @@ -413,6 +427,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { ev.mEdgeFlags = edgeFlags; ev.mDownTimeNano = downTime * MS_PER_NS; ev.mAction = action; + ev.mFlags = 0; ev.mMetaState = metaState; ev.mXOffset = 0; ev.mYOffset = 0; @@ -462,7 +477,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { * @param deviceId The id for the device that this event came from. An id of * zero indicates that the event didn't come from a physical device; other * numbers are arbitrary and you shouldn't depend on the values. - * @param edgeFlags A bitfield indicating which edges, if any, where touched by this + * @param edgeFlags A bitfield indicating which edges, if any, were touched by this * MotionEvent. * * @deprecated Use {@link #obtain(long, long, int, float, float, float, float, int, float, float, int, int)} @@ -509,6 +524,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { ev.mEdgeFlags = o.mEdgeFlags; ev.mDownTimeNano = o.mDownTimeNano; ev.mAction = o.mAction; + ev.mFlags = o.mFlags; ev.mMetaState = o.mMetaState; ev.mXOffset = o.mXOffset; ev.mYOffset = o.mYOffset; @@ -540,6 +556,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { ev.mEdgeFlags = o.mEdgeFlags; ev.mDownTimeNano = o.mDownTimeNano; ev.mAction = o.mAction; + o.mFlags = o.mFlags; ev.mMetaState = o.mMetaState; ev.mXOffset = o.mXOffset; ev.mYOffset = o.mYOffset; @@ -651,6 +668,15 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** + * Gets the motion event flags. + * + * @see #FLAG_WINDOW_IS_OBSCURED + */ + public final int getFlags() { + return mFlags; + } + + /** * Returns the time (in ms) when the user originally pressed down to start * a stream of position events. */ @@ -1285,7 +1311,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { /** - * Sets the bitfield indicating which edges, if any, where touched by this + * Sets the bitfield indicating which edges, if any, were touched by this * MotionEvent. * * @see #getEdgeFlags() @@ -1480,6 +1506,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { ev.mYPrecision = in.readFloat(); ev.mEdgeFlags = in.readInt(); ev.mMetaState = in.readInt(); + ev.mFlags = in.readInt(); final int[] pointerIdentifiers = ev.mPointerIdentifiers; for (int i = 0; i < NP; i++) { @@ -1521,6 +1548,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { out.writeFloat(mYPrecision); out.writeInt(mEdgeFlags); out.writeInt(mMetaState); + out.writeInt(mFlags); final int[] pointerIdentifiers = mPointerIdentifiers; for (int i = 0; i < NP; i++) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 7332c16..fe003a4 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -542,6 +542,28 @@ import java.util.WeakHashMap; * take care of redrawing the appropriate views until the animation completes. * </p> * + * <a name="Security"></a> + * <h3>Security</h3> + * <p> + * Sometimes it is essential that an application be able to verify that an action + * is being performed with the full knowledge and consent of the user, such as + * granting a permission request, making a purchase or clicking on an advertisement. + * Unfortunately, a malicious application could try to spoof the user into + * performing these actions, unaware, by concealing the intended purpose of the view. + * As a remedy, the framework offers a touch filtering mechanism that can be used to + * improve the security of views that provide access to sensitive functionality. + * </p><p> + * To enable touch filtering, call {@link #setFilterTouchesWhenObscured} or set the + * andoird:filterTouchesWhenObscured attribute to true. When enabled, the framework + * will discard touches that are received whenever the view's window is obscured by + * another visible window. As a result, the view will not receive touches whenever a + * toast, dialog or other window appears above the view's window. + * </p><p> + * For more fine-grained control over security, consider overriding the + * {@link #onFilterTouchEventForSecurity} method to implement your own security policy. + * See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}. + * </p> + * * @attr ref android.R.styleable#View_background * @attr ref android.R.styleable#View_clickable * @attr ref android.R.styleable#View_contentDescription @@ -550,6 +572,7 @@ import java.util.WeakHashMap; * @attr ref android.R.styleable#View_id * @attr ref android.R.styleable#View_fadingEdge * @attr ref android.R.styleable#View_fadingEdgeLength + * @attr ref android.R.styleable#View_filterTouchesWhenObscured * @attr ref android.R.styleable#View_fitsSystemWindows * @attr ref android.R.styleable#View_isScrollContainer * @attr ref android.R.styleable#View_focusable @@ -711,7 +734,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ static final int SCROLLBARS_MASK = 0x00000300; - // note 0x00000400 and 0x00000800 are now available for next flags... + /** + * Indicates that the view should filter touches when its window is obscured. + * Refer to the class comments for more information about this security feature. + * {@hide} + */ + static final int FILTER_TOUCHES_WHEN_OBSCURED = 0x00000400; + + // note flag value 0x00000800 is now available for next flags... /** * <p>This view doesn't show fading edges.</p> @@ -2052,6 +2082,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility viewFlagMasks |= KEEP_SCREEN_ON; } break; + case R.styleable.View_filterTouchesWhenObscured: + if (a.getBoolean(attr, false)) { + viewFlagValues |= FILTER_TOUCHES_WHEN_OBSCURED; + viewFlagMasks |= FILTER_TOUCHES_WHEN_OBSCURED; + } + break; case R.styleable.View_nextFocusLeft: mNextFocusLeftId = a.getResourceId(attr, View.NO_ID); break; @@ -3389,6 +3425,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility setFlags(enabled ? 0 : SAVE_DISABLED, SAVE_DISABLED_MASK); } + /** + * Gets whether the framework should discard touches when the view's + * window is obscured by another visible window. + * Refer to the {@link View} security documentation for more details. + * + * @return True if touch filtering is enabled. + * + * @see #setFilterTouchesWhenObscured(boolean) + * @attr ref android.R.styleable#View_filterTouchesWhenObscured + */ + @ViewDebug.ExportedProperty + public boolean getFilterTouchesWhenObscured() { + return (mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0; + } + + /** + * Sets whether the framework should discard touches when the view's + * window is obscured by another visible window. + * Refer to the {@link View} security documentation for more details. + * + * @param enabled True if touch filtering should be enabled. + * + * @see #getFilterTouchesWhenObscured + * @attr ref android.R.styleable#View_filterTouchesWhenObscured + */ + public void setFilterTouchesWhenObscured(boolean enabled) { + setFlags(enabled ? 0 : FILTER_TOUCHES_WHEN_OBSCURED, + FILTER_TOUCHES_WHEN_OBSCURED); + } /** * Returns whether this View is able to take focus. @@ -3808,6 +3873,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility * @return True if the event was handled by the view, false otherwise. */ public boolean dispatchTouchEvent(MotionEvent event) { + if (!onFilterTouchEventForSecurity(event)) { + return false; + } + if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && mOnTouchListener.onTouch(this, event)) { return true; @@ -3816,6 +3885,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } /** + * Filter the touch event to apply security policies. + * + * @param event The motion event to be filtered. + * @return True if the event should be dispatched, false if the event should be dropped. + * + * @see #getFilterTouchesWhenObscured + */ + public boolean onFilterTouchEventForSecurity(MotionEvent event) { + if ((mViewFlags & FILTER_TOUCHES_WHEN_OBSCURED) != 0 + && (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0) { + // Window is obscured, drop this touch. + return false; + } + return true; + } + + /** * Pass a trackball motion event down to the focused view. * * @param event The motion event to be dispatched. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 7159929..28bed3a 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -822,6 +822,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager */ @Override public boolean dispatchTouchEvent(MotionEvent ev) { + if (!onFilterTouchEventForSecurity(ev)) { + return false; + } + final int action = ev.getAction(); final float xf = ev.getX(); final float yf = ev.getY(); diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 659f9cd..76701a9 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -74,6 +74,8 @@ public interface WindowManagerPolicy { public final static int FLAG_MENU = 0x00000040; public final static int FLAG_LAUNCHER = 0x00000080; + public final static int FLAG_INJECTED = 0x01000000; + public final static int FLAG_WOKE_HERE = 0x10000000; public final static int FLAG_BRIGHT_HERE = 0x20000000; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 3428206..fea53e5 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5761,18 +5761,25 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } private void convertFromViewportToContentCoordinates(Rect r) { - int paddingTop = getExtendedPaddingTop(); - if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) { - paddingTop += getVerticalOffset(false); - } - r.top += paddingTop; - r.bottom += paddingTop; + final int horizontalOffset = viewportToContentHorizontalOffset(); + r.left += horizontalOffset; + r.right += horizontalOffset; - int paddingLeft = getCompoundPaddingLeft(); - r.left += paddingLeft; - r.right += paddingLeft; + final int verticalOffset = viewportToContentVerticalOffset(); + r.top += verticalOffset; + r.bottom += verticalOffset; + } - r.offset(-mScrollX, -mScrollY); + private int viewportToContentHorizontalOffset() { + return getCompoundPaddingLeft() - mScrollX; + } + + private int viewportToContentVerticalOffset() { + int offset = getExtendedPaddingTop() - mScrollY; + if ((mGravity & Gravity.VERTICAL_GRAVITY_MASK) != Gravity.TOP) { + offset += getVerticalOffset(false); + } + return offset; } @Override @@ -7651,9 +7658,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener bounds.right = bounds.left + drawableWidth; bounds.bottom = bounds.top + drawableHeight; - int boundTopBefore = bounds.top; convertFromViewportToContentCoordinates(bounds); - mHotSpotVerticalPosition += bounds.top - boundTopBefore; mDrawable.setBounds(bounds); postInvalidate(); } @@ -7797,6 +7802,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mOffsetX = (bounds.left + bounds.right) / 2.0f - x; mOffsetY = mHandle.mHotSpotVerticalPosition - y; + mOffsetX += viewportToContentHorizontalOffset(); + mOffsetY += viewportToContentVerticalOffset(); + mOnDownTimerStart = event.getEventTime(); } break; @@ -7986,6 +7994,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mOffsetX = (bounds.left + bounds.right) / 2.0f - x; mOffsetY = draggedHandle.mHotSpotVerticalPosition - y; + mOffsetX += viewportToContentHorizontalOffset(); + mOffsetY += viewportToContentVerticalOffset(); + mOnDownTimerStart = event.getEventTime(); ((ArrowKeyMovementMethod)mMovement).setCursorController(this); } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 566ed29..b73b78b 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -22,6 +22,8 @@ import android.bluetooth.BluetoothHeadset; import android.net.TrafficStats; import android.os.BatteryManager; import android.os.BatteryStats; +import android.os.Handler; +import android.os.Message; import android.os.Parcel; import android.os.ParcelFormatException; import android.os.Parcelable; @@ -79,6 +81,38 @@ public final class BatteryStatsImpl extends BatteryStats { private final JournaledFile mFile; + static final int MSG_UPDATE_WAKELOCKS = 1; + static final int MSG_REPORT_POWER_CHANGE = 2; + static final long DELAY_UPDATE_WAKELOCKS = 15*1000; + + public interface BatteryCallback { + public void batteryNeedsCpuUpdate(); + public void batteryPowerChanged(boolean onBattery); + } + + final class MyHandler extends Handler { + @Override + public void handleMessage(Message msg) { + BatteryCallback cb = mCallback; + switch (msg.what) { + case MSG_UPDATE_WAKELOCKS: + if (cb != null) { + cb.batteryNeedsCpuUpdate(); + } + break; + case MSG_REPORT_POWER_CHANGE: + if (cb != null) { + cb.batteryPowerChanged(msg.arg1 != 0); + } + break; + } + } + } + + private final MyHandler mHandler; + + private BatteryCallback mCallback; + /** * The statistics we have collected organized by uids. */ @@ -95,6 +129,9 @@ public final class BatteryStatsImpl extends BatteryStats { final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<ArrayList<StopwatchTimer>>(); + // Last partial timers we use for distributing CPU usage. + final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<StopwatchTimer>(); + // These are the objects that will want to do something when the device // is unplugged from power. final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); @@ -240,6 +277,7 @@ public final class BatteryStatsImpl extends BatteryStats { // For debugging public BatteryStatsImpl() { mFile = null; + mHandler = null; } public static interface Unpluggable { @@ -739,7 +777,9 @@ public final class BatteryStatsImpl extends BatteryStats { * State for keeping track of timing information. */ public static final class StopwatchTimer extends Timer { + final Uid mUid; final ArrayList<StopwatchTimer> mTimerPool; + int mNesting; /** @@ -757,16 +797,24 @@ public final class BatteryStatsImpl extends BatteryStats { long mTimeout; - StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, + /** + * For partial wake locks, keep track of whether we are in the list + * to consume CPU cycles. + */ + boolean mInList; + + StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, ArrayList<Unpluggable> unpluggables, Parcel in) { super(type, unpluggables, in); + mUid = uid; mTimerPool = timerPool; mUpdateTime = in.readLong(); } - StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool, + StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool, ArrayList<Unpluggable> unpluggables) { super(type, unpluggables); + mUid = uid; mTimerPool = timerPool; } @@ -1252,6 +1300,10 @@ public final class BatteryStatsImpl extends BatteryStats { mWakeLockNesting++; } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type); } } @@ -1267,10 +1319,112 @@ public final class BatteryStatsImpl extends BatteryStats { } } if (uid >= 0) { + if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) { + Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS); + mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS); + } getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type); } } + public int startAddingCpuLocked() { + mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + + if (mScreenOn) { + return 0; + } + + final int N = mPartialTimers.size(); + if (N == 0) { + mLastPartialTimers.clear(); + return 0; + } + + // How many timers should consume CPU? Only want to include ones + // that have already been in the list. + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + Uid uid = st.mUid; + // We don't include the system UID, because it so often + // holds wake locks at one request or another of an app. + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + return 50; + } + } + } + + return 0; + } + + public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { + final int N = mPartialTimers.size(); + if (perc != 0) { + int num = 0; + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + Uid uid = st.mUid; + // We don't include the system UID, because it so often + // holds wake locks at one request or another of an app. + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + num++; + } + } + } + if (num != 0) { + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + if (st.mInList) { + int myUTime = utime/num; + int mySTime = stime/num; + utime -= myUTime; + stime -= mySTime; + num--; + Uid uid = st.mUid; + if (uid != null && uid.mUid != Process.SYSTEM_UID) { + Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); + proc.addCpuTimeLocked(myUTime, mySTime); + proc.addSpeedStepTimes(cpuSpeedTimes); + } + } + } + } + + // Just in case, collect any lost CPU time. + if (utime != 0 || stime != 0) { + Uid uid = getUidStatsLocked(Process.SYSTEM_UID); + if (uid != null) { + Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); + proc.addCpuTimeLocked(utime, stime); + proc.addSpeedStepTimes(cpuSpeedTimes); + } + } + } + + final int NL = mLastPartialTimers.size(); + boolean diff = N != NL; + for (int i=0; i<NL && !diff; i++) { + diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i); + } + if (!diff) { + for (int i=0; i<NL; i++) { + mPartialTimers.get(i).mInList = true; + } + return; + } + + for (int i=0; i<NL; i++) { + mLastPartialTimers.get(i).mInList = false; + } + mLastPartialTimers.clear(); + for (int i=0; i<N; i++) { + StopwatchTimer st = mPartialTimers.get(i); + st.mInList = true; + mLastPartialTimers.add(st); + } + } + public void noteProcessDiedLocked(int uid, int pid) { Uid u = mUidStats.get(uid); if (u != null) { @@ -1922,13 +2076,18 @@ public final class BatteryStatsImpl extends BatteryStats { public Uid(int uid) { mUid = uid; - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables); - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables); - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables); - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, + null, mUnpluggables); + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, + null, mUnpluggables); + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, + null, mUnpluggables); + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, + null, mUnpluggables); + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, + null, mUnpluggables); + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables); - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables); - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables); } @Override @@ -1996,7 +2155,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mWifiTurnedOn) { mWifiTurnedOn = true; if (mWifiTurnedOnTimer == null) { - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, null, mUnpluggables); } mWifiTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2016,7 +2175,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mFullWifiLockOut) { mFullWifiLockOut = true; if (mFullWifiLockTimer == null) { - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, null, mUnpluggables); } mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2036,7 +2195,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mScanWifiLockOut) { mScanWifiLockOut = true; if (mScanWifiLockTimer == null) { - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, null, mUnpluggables); } mScanWifiLockTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2056,7 +2215,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mWifiMulticastEnabled) { mWifiMulticastEnabled = true; if (mWifiMulticastTimer == null) { - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, null, mUnpluggables); } mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2076,7 +2235,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mAudioTurnedOn) { mAudioTurnedOn = true; if (mAudioTurnedOnTimer == null) { - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, null, mUnpluggables); } mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2096,7 +2255,7 @@ public final class BatteryStatsImpl extends BatteryStats { if (!mVideoTurnedOn) { mVideoTurnedOn = true; if (mVideoTurnedOnTimer == null) { - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables); } mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this); @@ -2456,42 +2615,42 @@ public final class BatteryStatsImpl extends BatteryStats { mTcpBytesSentAtLastUnplug = in.readLong(); mWifiTurnedOn = false; if (in.readInt() != 0) { - mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, + mWifiTurnedOnTimer = new StopwatchTimer(Uid.this, WIFI_TURNED_ON, null, mUnpluggables, in); } else { mWifiTurnedOnTimer = null; } mFullWifiLockOut = false; if (in.readInt() != 0) { - mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, + mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK, null, mUnpluggables, in); } else { mFullWifiLockTimer = null; } mScanWifiLockOut = false; if (in.readInt() != 0) { - mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, + mScanWifiLockTimer = new StopwatchTimer(Uid.this, SCAN_WIFI_LOCK, null, mUnpluggables, in); } else { mScanWifiLockTimer = null; } mWifiMulticastEnabled = false; if (in.readInt() != 0) { - mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED, + mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED, null, mUnpluggables, in); } else { mWifiMulticastTimer = null; } mAudioTurnedOn = false; if (in.readInt() != 0) { - mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, + mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON, null, mUnpluggables, in); } else { mAudioTurnedOnTimer = null; } mVideoTurnedOn = false; if (in.readInt() != 0) { - mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, + mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON, null, mUnpluggables, in); } else { mVideoTurnedOnTimer = null; @@ -2538,7 +2697,7 @@ public final class BatteryStatsImpl extends BatteryStats { return null; } - return new StopwatchTimer(type, pool, unpluggables, in); + return new StopwatchTimer(Uid.this, type, pool, unpluggables, in); } boolean reset() { @@ -2614,7 +2773,7 @@ public final class BatteryStatsImpl extends BatteryStats { pool = new ArrayList<StopwatchTimer>(); mSensorTimers.put(mHandle, pool); } - return new StopwatchTimer(0, pool, unpluggables, in); + return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in); } boolean reset() { @@ -3416,21 +3575,24 @@ public final class BatteryStatsImpl extends BatteryStats { case WAKE_TYPE_PARTIAL: t = wl.mTimerPartial; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_PARTIAL, mPartialTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL, + mPartialTimers, mUnpluggables); wl.mTimerPartial = t; } return t; case WAKE_TYPE_FULL: t = wl.mTimerFull; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_FULL, mFullTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL, + mFullTimers, mUnpluggables); wl.mTimerFull = t; } return t; case WAKE_TYPE_WINDOW: t = wl.mTimerWindow; if (t == null) { - t = new StopwatchTimer(WAKE_TYPE_WINDOW, mWindowTimers, mUnpluggables); + t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW, + mWindowTimers, mUnpluggables); wl.mTimerWindow = t; } return t; @@ -3457,7 +3619,7 @@ public final class BatteryStatsImpl extends BatteryStats { timers = new ArrayList<StopwatchTimer>(); mSensorTimers.put(sensor, timers); } - t = new StopwatchTimer(BatteryStats.SENSOR, timers, mUnpluggables); + t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables); se.mTimer = t; return t; } @@ -3530,25 +3692,26 @@ public final class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(String filename) { mFile = new JournaledFile(new File(filename), new File(filename + ".tmp")); + mHandler = new MyHandler(); mStartCount++; - mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables); + mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { - mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables); + mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables); } mInputEventCounter = new Counter(mUnpluggables); - mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables); + mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables); for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { - mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables); + mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables); } - mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables); + mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables); for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { - mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables); + mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables); } - mWifiOnTimer = new StopwatchTimer(-3, null, mUnpluggables); - mWifiRunningTimer = new StopwatchTimer(-4, null, mUnpluggables); - mBluetoothOnTimer = new StopwatchTimer(-5, null, mUnpluggables); - mAudioOnTimer = new StopwatchTimer(-6, null, mUnpluggables); - mVideoOnTimer = new StopwatchTimer(-7, null, mUnpluggables); + mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables); + mWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables); + mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables); + mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables); + mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables); mOnBattery = mOnBatteryInternal = false; initTimes(); mTrackBatteryPastUptime = 0; @@ -3566,9 +3729,14 @@ public final class BatteryStatsImpl extends BatteryStats { public BatteryStatsImpl(Parcel p) { mFile = null; + mHandler = null; readFromParcel(p); } + public void setCallback(BatteryCallback cb) { + mCallback = cb; + } + public void setNumSpeedSteps(int steps) { if (sNumSpeedSteps == 0) sNumSpeedSteps = steps; } @@ -3653,6 +3821,9 @@ public final class BatteryStatsImpl extends BatteryStats { void setOnBattery(boolean onBattery, int oldStatus, int level) { synchronized(this) { boolean doWrite = false; + Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE); + m.arg1 = onBattery ? 1 : 0; + mHandler.sendMessage(m); mOnBattery = mOnBatteryInternal = onBattery; long uptime = SystemClock.uptimeMillis() * 1000; @@ -4553,26 +4724,29 @@ public final class BatteryStatsImpl extends BatteryStats { mBatteryRealtime = in.readLong(); mBatteryLastRealtime = 0; mScreenOn = false; - mScreenOnTimer = new StopwatchTimer(-1, null, mUnpluggables, in); + mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in); for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) { - mScreenBrightnessTimer[i] = new StopwatchTimer(-100-i, null, mUnpluggables, in); + mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, + null, mUnpluggables, in); } mInputEventCounter = new Counter(mUnpluggables, in); mPhoneOn = false; - mPhoneOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) { - mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in); + mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, + null, mUnpluggables, in); } - mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in); + mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in); for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) { - mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in); + mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, + null, mUnpluggables, in); } mWifiOn = false; - mWifiOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mWifiOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mWifiRunning = false; - mWifiRunningTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mBluetoothOn = false; - mBluetoothOnTimer = new StopwatchTimer(-2, null, mUnpluggables, in); + mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in); mUptime = in.readLong(); mUptimeStart = in.readLong(); mLastUptime = 0; diff --git a/core/java/com/android/internal/view/BaseSurfaceHolder.java b/core/java/com/android/internal/view/BaseSurfaceHolder.java index 3a04993..1e97cd6 100644 --- a/core/java/com/android/internal/view/BaseSurfaceHolder.java +++ b/core/java/com/android/internal/view/BaseSurfaceHolder.java @@ -41,7 +41,8 @@ public abstract class BaseSurfaceHolder implements SurfaceHolder { int mRequestedWidth = -1; int mRequestedHeight = -1; - int mRequestedFormat = PixelFormat.OPAQUE; + /** @hide */ + protected int mRequestedFormat = PixelFormat.OPAQUE; int mRequestedType = -1; long mLastLockTime = 0; diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index fe247e8..93fd54f 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -46,6 +46,7 @@ static struct { jfieldID mYPrecision; jfieldID mEdgeFlags; jfieldID mMetaState; + jfieldID mFlags; jfieldID mNumPointers; jfieldID mNumSamples; jfieldID mPointerIdentifiers; @@ -91,6 +92,8 @@ jobject android_view_MotionEvent_fromNative(JNIEnv* env, const MotionEvent* even event->getEdgeFlags()); env->SetIntField(eventObj, gMotionEventClassInfo.mMetaState, event->getMetaState()); + env->SetIntField(eventObj, gMotionEventClassInfo.mFlags, + event->getFlags()); env->SetIntField(eventObj, gMotionEventClassInfo.mNumPointers, numPointers); env->SetIntField(eventObj, gMotionEventClassInfo.mNumSamples, @@ -162,6 +165,7 @@ void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, jfloat yPrecision = env->GetFloatField(eventObj, gMotionEventClassInfo.mYPrecision); jint edgeFlags = env->GetIntField(eventObj, gMotionEventClassInfo.mEdgeFlags); jint metaState = env->GetIntField(eventObj, gMotionEventClassInfo.mMetaState); + jint flags = env->GetIntField(eventObj, gMotionEventClassInfo.mFlags); jint numPointers = env->GetIntField(eventObj, gMotionEventClassInfo.mNumPointers); jint numSamples = env->GetIntField(eventObj, gMotionEventClassInfo.mNumSamples); jintArray pointerIdentifierArray = jintArray(env->GetObjectField(eventObj, @@ -196,7 +200,7 @@ void android_view_MotionEvent_toNative(JNIEnv* env, jobject eventObj, samplePointerCoords[j].orientation = *(srcDataSamples++); } - event->initialize(deviceId, source, action, edgeFlags, metaState, + event->initialize(deviceId, source, action, flags, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTimeNano, sampleEventTime, numPointers, pointerIdentifiers, samplePointerCoords); @@ -281,6 +285,8 @@ int register_android_view_MotionEvent(JNIEnv* env) { "mEdgeFlags", "I"); GET_FIELD_ID(gMotionEventClassInfo.mMetaState, gMotionEventClassInfo.clazz, "mMetaState", "I"); + GET_FIELD_ID(gMotionEventClassInfo.mFlags, gMotionEventClassInfo.clazz, + "mFlags", "I"); GET_FIELD_ID(gMotionEventClassInfo.mNumPointers, gMotionEventClassInfo.clazz, "mNumPointers", "I"); GET_FIELD_ID(gMotionEventClassInfo.mNumSamples, gMotionEventClassInfo.clazz, diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 0323b70..a9e4971 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -50,6 +50,8 @@ <protected-broadcast android:name="android.intent.action.ACTION_SHUTDOWN" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_LOW" /> <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_OK" /> + <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_FULL" /> + <protected-broadcast android:name="android.intent.action.DEVICE_STORAGE_NOT_FULL" /> <protected-broadcast android:name="android.intent.action.NEW_OUTGOING_CALL" /> <protected-broadcast android:name="android.intent.action.REBOOT" /> <protected-broadcast android:name="android.intent.action.DOCK_EVENT" /> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 1130b69..13c3e7e 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1274,6 +1274,12 @@ be saved. --> <attr name="saveEnabled" format="boolean" /> + <!-- Specifies whether to filter touches when the view's window is obscured by + another visible window. When set to true, the view will not receive touches + whenever a toast, dialog or other window appears above the view's window. + Refer to the {@link android.view.View} security documentation for more details. --> + <attr name="filterTouchesWhenObscured" format="boolean" /> + <!-- Defines the quality of translucent drawing caches. This property is used only when the drawing cache is enabled and translucent. The default value is auto. --> <attr name="drawingCacheQuality"> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 86e79c8..28a7cca 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1254,6 +1254,7 @@ <public type="attr" name="overscrollMode" id="0x010102c1" /> <public type="attr" name="overscrollHeader" id="0x010102c2" /> <public type="attr" name="overscrollFooter" id="0x010102c3" /> + <public type="attr" name="filterTouchesWhenObscured" id="0x010102c4" /> <public-padding type="attr" name="kraken_resource_pad" end="0x01010300" /> diff --git a/docs/html/guide/developing/eclipse-adt.jd b/docs/html/guide/developing/eclipse-adt.jd index 9c77ece..d0fc9b8 100644 --- a/docs/html/guide/developing/eclipse-adt.jd +++ b/docs/html/guide/developing/eclipse-adt.jd @@ -21,6 +21,7 @@ page.title=Developing In Eclipse, with ADT <li><a href="#librarySetup">Setting up a library project</a></li> <li><a href="#libraryReference">Referencing a library project</a></li> <li><a href="#considerations">Development considerations</a></li> + <li><a href="#libraryMigrating">Migrating library projects to ADT 0.9.8</a></li> </ol> </li> <li><a href="#Tips">Eclipse Tips</a></li> @@ -644,10 +645,6 @@ across all projects). </p> is because the library project is compiled by the main project to use the correct resource IDs.</p> -<p><strong>One library project cannot reference another</strong></p> - -<p>A library cannot depend on another library.</p> - <p><strong>A library project can include a JAR library</strong></p> <p>You can develop a library project that itself includes a JAR library, however @@ -664,13 +661,6 @@ application must declare the external library their manifest files, in a <a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code><uses-library></code></a> element. </p> -<p><strong>Library project can not include AIDL files</strong></p> - -<p>The tools do not support the use of <a -href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> files in a library project. -Any AIDL files used by an application must be stored in the application project -itself.</p> - <p><strong>Library project can not include raw assets</strong></p> <p>The tools do not support the use of raw asset files in a library project. @@ -730,8 +720,76 @@ project can reference the library project by a relative link. You can place the library project What is important is that the main project can reference the library project through a relative link.</p> +<h3 id="libraryMigrating">Migrating library projects to ADT 0.9.8</h3> + +<p>This section provides information about how to migrate a library project +created with ADT 0.9.7 to ADT 0.9.8 (or higher). The migration is needed only if +you are developing in Eclipse with ADT and assumes that you have also upgraded +to SDK Tools r7 (or higher). </p> + +<p>The way that ADT handles library projects has changed between +ADT 0.9.7 and ADT 0.9.8. Specifically, in ADT 0.9.7, the <code>src/</code> +source folder of the library was linked into the dependent application project +as a folder that had the same name as the library project. This worked because +of two restrictions on the library projects:</p> + +<ul> +<li>The library was only able to contain a single source folder (excluding the +special <code>gen/</code> source folder), and</li> +<li>The source folder was required to have the name <code>src/</code> and be +stored at the root of the project.</li> +</ul> + +<p>In ADT 0.9.8, both of those restrictions were removed. A library project can +have as many source folders as needed and each can have any name. Additionally, +a library project can store source folders in any location of the project. For +example, you could store sources in a <code>src/java/</code> directory. In order +to support this, the name of the linked source folders in the main project are +now called <<em>library-name</em>>_<<em>folder-name</em>> For +example: <code>MyLibrary_src/</code> or <code>MyLibrary_src_java/</code>.</p> + +<p>Additionally, the linking process now flags those folders in order for ADT to +recognize that it created them. This will allow ADT to automatically migrate the +project to new versions of ADT, should they contain changes to the handling of +library projects. ADT 0.9.7 did not flag the linked source folders, so ADT 0.9.8 +cannot be sure whether the old linked folders can be removed safely. After +upgrading ADT to 0.9.8, you will need to remove the old linked folders manually +in a simple two-step process, as described below.</p> + +<p>Before you begin, make sure to create a backup copy of your application or +save the latest version to your code version control system. This ensures that +you will be able to easily revert the migration changes in case there is a +problem in your environment.</p> + +<p>When you first upgrade to ADT 0.9.8, your main project will look as shown +below, with two linked folders (in this example, <code>MyLibrary</code> and +<code>MyLibrary_src</code> — both of which link to +<code>MyLibrary/src</code>. Eclipse shows an error on one of them because they +are duplicate links to a single class.</p> + +<img src="{@docRoot}images/developing/lib-migration-0.png" alt=""> + +<p>To fix the error, remove the linked folder that <em>does not</em> contain the +<code>_src</code> suffix. </p> + +<ol> +<li>Right click the folder that you want to remove (in this case, the +<code>MyLibrary</code> folder) and choose <strong>Build Path</strong> > +<strong>Remove from Build Path</strong>, as shown below.</li> + +<img src="{@docRoot}images/developing/lib-migration-1.png" style="height:600px" +alt=""> + +<li>Next, When asked about unlinking the folder from the project, select +<strong>Yes</strong>, as shown below.</li> + +<img src="{@docRoot}images/developing/lib-migration-2.png" alt=""> +</ol> + +<p>This should resolve the error and migrate your library project to the new +ADT environment. </p> -<h2 id="Tips">Eclipse Tips </h2> +<h2 id="Tips">Eclipse Tips</h2> <h3 id="arbitraryexpressions">Executing arbitrary Java expressions in Eclipse</h3> diff --git a/docs/html/guide/developing/other-ide.jd b/docs/html/guide/developing/other-ide.jd index 1d67aa9..ff13f43 100644 --- a/docs/html/guide/developing/other-ide.jd +++ b/docs/html/guide/developing/other-ide.jd @@ -838,10 +838,6 @@ across all projects). </p> is because the library project is compiled by the main project to use the correct resource IDs.</p> -<p><strong>One library project cannot reference another</strong></p> - -<p>A library cannot depend on another library.</p> - <p><strong>A library project can include a JAR library</strong></p> <p>You can develop a library project that itself includes a JAR library. When @@ -858,13 +854,6 @@ application must declare the external library their manifest files, in a <a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><code><uses-library></code></a> element. </p> -<p><strong>Library project cannot include AIDL files</strong></p> - -<p>The tools do not support the use of <a -href="{@docRoot}guide/developing/tools/aidl.html">AIDL</a> files in a library project. -Any AIDL files used by an application must be stored in the application project -itself.</p> - <p><strong>Library project cannot include raw assets</strong></p> <p>The tools do not support the use of raw asset files in a library project. diff --git a/docs/html/images/developing/lib-migration-0.png b/docs/html/images/developing/lib-migration-0.png Binary files differnew file mode 100644 index 0000000..226b0a5 --- /dev/null +++ b/docs/html/images/developing/lib-migration-0.png diff --git a/docs/html/images/developing/lib-migration-1.png b/docs/html/images/developing/lib-migration-1.png Binary files differnew file mode 100644 index 0000000..f413dab --- /dev/null +++ b/docs/html/images/developing/lib-migration-1.png diff --git a/docs/html/images/developing/lib-migration-2.png b/docs/html/images/developing/lib-migration-2.png Binary files differnew file mode 100644 index 0000000..0aa5849 --- /dev/null +++ b/docs/html/images/developing/lib-migration-2.png diff --git a/docs/html/sdk/adt_download.jd b/docs/html/sdk/adt_download.jd index f98caf5..126c052 100644 --- a/docs/html/sdk/adt_download.jd +++ b/docs/html/sdk/adt_download.jd @@ -22,11 +22,18 @@ ADT Installation</a>.</p> <th>Notes</th> </tr> <tr> - <td>0.9.7</td> - <td><a href="http://dl-ssl.google.com/android/ADT-0.9.7.zip">ADT-0.9.7.zip</a></td> + <td>0.9.8</td> + <td><a href="http://dl-ssl.google.com/android/ADT-0.9.8.zip">ADT-0.9.8.zip</a></td> <td><nobr>{@adtZipBytes} bytes</nobr></td> <td>{@adtZipChecksum}</td> - <td>Requires SDK Tools, Revision 6 <em><nobr>May 2010</nobr></em></td> + <td>Requires SDK Tools, Revision 7 <em><nobr>September 2010</nobr></em></td> + </tr> + <tr> + <td>0.9.7</td> + <td><a href="http://dl-ssl.google.com/android/ADT-0.9.7.zip">ADT-0.9.7.zip</a></td> + <td><nobr>8033750 bytes</nobr></td> + <td>de2431c8d4786d127ae5bfc95b4605df</td> + <td>Requires SDK Tools, Revision 5 <em><nobr>May 2010</nobr></em></td> </tr> <tr> <td>0.9.6</td> diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd index bd7eeed..9d6c3ab 100644 --- a/docs/html/sdk/eclipse-adt.jd +++ b/docs/html/sdk/eclipse-adt.jd @@ -95,8 +95,62 @@ padding: .25em 1em; } </style> + + + <div class="toggleable opened"> <a href="#" onclick="return toggleDiv(this)"> + <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" /> +ADT 0.9.8</a> <em>(August 2010)</em> + <div class="toggleme"> + + +</ul> +</dd> + +<dl> + +<dt>Dependencies:</dt> + +<dd><p>ADT 0.9.8 is designed for use with SDK Tools r7 and later. Before +updating to ADT 0.9.8, we highly recommend that you use the Android SDK and +AVD Manager to install SDK Tools r7 into your SDK.</p></dd> + +<dt>General notes:</dt> +<dd> +<ul> +<li>Adds a new Action, "Rename Application Package", to the Android Tools +contextual menu. The Action does a full application package refactoring. +<li>Adds support for library projects that don't have a source folder +called <code>src/</code>. There is now support for any number of source folders, +with no name restriction. They can even be in subfolder such as +<code>src/java</code>. If you are already working with library projects created +in ADT 0.9.7, see <a +href="{@docRoot}guide/developing/eclipse-adt.html#libraryMigrating">Migrating +library projects to ADT 0.9.8</a> for important information about moving +to the new ADT environment.</li> +<li>Adds support for library projects that depend on other library +projects.</li> +<li>Adds support for additional resource qualifiers: +<code>car</code>/<code>desk</code>, <code>night</code>/<code>notnight</code> and +<code>navexposed</code>/<code>navhidden</code>.</li> +<li>Adds more device screen types in the layout editor. All screen +resolution/density combinations listed in the <a +href="{@docRoot}guide/practices/screens_support.html#range">Supporting +Multiple Screens</a> are now available.</li> +<li>Fixes problems with handling of library project names that +contain characters that are incompatible with the Eclipse path variable. +Now properly sets up the link between the main project and the library +project.</li> +</ul> +</dd> +</dl> + </div> +</div> + + +<div class="toggleable closed"> + <a href="#" onclick="return toggleDiv(this)"> <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" /> ADT 0.9.7</a> <em>(May 2010)</em> <div class="toggleme"> @@ -120,6 +174,7 @@ project support through the Ant build system.</p> </div> </div> + <div class="toggleable closed"> <a href="#" onclick="return toggleDiv(this)"> <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" /> diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index 5e92253..7016eee 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -1,17 +1,17 @@ page.title=Android SDK sdk.redirect=0 -sdk.win_download=android-sdk_r06-windows.zip -sdk.win_bytes=23293160 -sdk.win_checksum=7c7fcec3c6b5c7c3df6ae654b27effb5 +sdk.win_download=android-sdk_r07-windows.zip +sdk.win_bytes=23669664 +sdk.win_checksum=69c40c2d2e408b623156934f9ae574f0 -sdk.mac_download=android-sdk_r06-mac_86.zip -sdk.mac_bytes=19108077 -sdk.mac_checksum=c92abf66a82c7a3f2b8493ebe025dd22 +sdk.mac_download=android-sdk_r07-mac_x86.zip +sdk.mac_bytes=19229546 +sdk.mac_checksum=0f330ed3ebb36786faf6dc72b8acf819 -sdk.linux_download=android-sdk_r06-linux_86.tgz -sdk.linux_bytes=16971139 -sdk.linux_checksum=848371e4bf068dbb582b709f4e56d903 +sdk.linux_download=android-sdk_r07-linux_x86.tgz +sdk.linux_bytes=17114517 +sdk.linux_checksum=e10c75da3d1aa147ddd4a5c58bfc3646 @jd:body @@ -50,7 +50,7 @@ for Eclipse</a>.</p> <p><strong>4. Add Android platforms and other components to your SDK</strong></p> <p>Use the Android SDK and AVD Manager, included in the SDK starter package, to -add one or more Android platforms (for example, Android 1.6 or Android 2.0) and +add one or more Android platforms (for example, Android 1.6 or Android 2.2) and other components to your SDK. If you aren't sure what to add, see <a href="installing.html#which">Which components do I need?</a></p> diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index 404e938..a665e95 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -75,8 +75,8 @@ </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r6</a> - </li> + <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a> + <span class="new">new!</span></li> <li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for Windows, r3</a> </li> @@ -94,7 +94,7 @@ <span style="display:none" class="zh-TW"></span> </h2> <ul> - <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 0.9.7 + <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 0.9.8 <span style="display:none" class="de"></span> <span style="display:none" class="es"></span> <span style="display:none" class="fr"></span> @@ -102,7 +102,7 @@ <span style="display:none" class="ja"></span> <span style="display:none" class="zh-CN"></span> <span style="display:none" class="zh-TW"></span></a> - </li> + <span class="new">new!</span></li> </ul> </li> <li> diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd index c9be6ff..dc58801 100644 --- a/docs/html/sdk/tools-notes.jd +++ b/docs/html/sdk/tools-notes.jd @@ -64,6 +64,39 @@ padding: .25em 1em; <div class="toggleable opened"> <a href="#" onclick="return toggleDiv(this)"> <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" /> +SDK Tools, Revision 7</a> <em>(September 2010)</em> + <div class="toggleme"> + +<dl> +<dt>Dependencies:</dt> +<dd> +<p>If you are developing in Eclipse with ADT, note that SDK Tools r7 is +designed for use with ADT 0.9.8 and later. After installing SDK Tools r7, we +highly recommend updating your ADT Plugin to 0.9.8.</p> +</dd> + +<dt>General notes:</dt> +<dd> +<ul> +<li>Added support for library projects that depend on other library projects.</li> +<li>Adds support for aidl files in library projects.</li> +<li>Adds support for extension targets in Ant build to perform tasks between the +normal tasks: <code>-pre-build</code>, <code>-pre-compile</code>, and +<code>-post-compile</code>.</li> +<li>Adds support for "headless" SDK update. See <code>android -h update sdk</code> +for more information.</li> +<li>Fixes location control in DDMS to work in any locale not using '.' as a +decimal point.</li> +</li> +</ul> +</dd> +</dl> + </div> +</div> + +<div class="toggleable closed"> + <a href="#" onclick="return toggleDiv(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px" width="9px" /> SDK Tools, Revision 6</a> <em>(May 2010)</em> <div class="toggleme"> diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h index 2233e3f..36accd8 100644 --- a/include/media/EffectEnvironmentalReverbApi.h +++ b/include/media/EffectEnvironmentalReverbApi.h @@ -48,16 +48,16 @@ typedef enum //t_reverb_settings is equal to SLEnvironmentalReverbSettings defined in OpenSL ES specification. typedef struct s_reverb_settings { - int16_t roomLevel; - int16_t roomHFLevel; - int32_t decayTime; - int16_t decayHFRatio; - int16_t reflectionsLevel; - int32_t reflectionsDelay; - int16_t reverbLevel; - int32_t reverbDelay; - int16_t diffusion; - int16_t density; + int16_t roomLevel; + int16_t roomHFLevel; + uint32_t decayTime; + int16_t decayHFRatio; + int16_t reflectionsLevel; + uint32_t reflectionsDelay; + int16_t reverbLevel; + uint32_t reverbDelay; + int16_t diffusion; + int16_t density; } __attribute__((packed)) t_reverb_settings; diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h index 1e447f1..1594e31 100644 --- a/include/media/stagefright/MetaData.h +++ b/include/media/stagefright/MetaData.h @@ -49,6 +49,7 @@ enum { kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp) kKeyTargetTime = 'tarT', // int64_t (usecs) kKeyDriftTime = 'dftT', // int64_t (usecs) + kKeyAnchorTime = 'ancT', // int64_t (usecs) kKeyDuration = 'dura', // int64_t (usecs) kKeyColorFormat = 'colf', kKeyPlatformPrivate = 'priv', // pointer diff --git a/include/ui/Input.h b/include/ui/Input.h index 3fa825f..b587e94 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -78,6 +78,11 @@ enum { POLICY_FLAG_RAW_MASK = 0x0000ffff, + /* These flags are set by the input dispatcher. */ + + // Indicates that the input event was injected. + POLICY_FLAG_INJECTED = 0x01000000, + /* These flags are set by the input reader policy as it intercepts each event. */ // Indicates that the screen was off when the event was received and the event @@ -225,6 +230,8 @@ public: inline int32_t getAction() const { return mAction; } + inline int32_t getFlags() const { return mFlags; } + inline int32_t getEdgeFlags() const { return mEdgeFlags; } inline int32_t getMetaState() const { return mMetaState; } @@ -343,6 +350,7 @@ public: int32_t deviceId, int32_t source, int32_t action, + int32_t flags, int32_t edgeFlags, int32_t metaState, float xOffset, @@ -370,6 +378,7 @@ public: private: int32_t mAction; + int32_t mFlags; int32_t mEdgeFlags; int32_t mMetaState; float mXOffset; diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h index aed4fa1..f00f2db 100644 --- a/include/ui/InputDispatcher.h +++ b/include/ui/InputDispatcher.h @@ -84,14 +84,22 @@ struct InputTarget { * current event is delivered to this target or a timeout occurs. */ FLAG_SYNC = 0x01, - /* This flag indicates that a MotionEvent with ACTION_DOWN falls outside of the area of - * this target and so should instead be delivered as an ACTION_OUTSIDE to this target. */ + /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside + * of the area of this target and so should instead be delivered as an + * AMOTION_EVENT_ACTION_OUTSIDE to this target. */ FLAG_OUTSIDE = 0x02, /* This flag indicates that a KeyEvent or MotionEvent is being canceled. - * In the case of a key event, it should be delivered with KeyEvent.FLAG_CANCELED set. - * In the case of a motion event, it should be delivered as MotionEvent.ACTION_CANCEL. */ - FLAG_CANCEL = 0x04 + * In the case of a key event, it should be delivered with flag + * AKEY_EVENT_FLAG_CANCELED set. + * In the case of a motion event, it should be delivered with action + * AMOTION_EVENT_ACTION_CANCEL instead. */ + FLAG_CANCEL = 0x04, + + /* This flag indicates that the target of a MotionEvent is partly or wholly + * obscured by another visible window above it. The motion event should be + * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ + FLAG_WINDOW_IS_OBSCURED = 0x08, }; // The input channel to be targeted. @@ -139,9 +147,12 @@ public: /* Notifies the system that an input channel recovered from ANR. */ virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0; - /* Gets the key repeat timeout or -1 if automatic key repeating is disabled. */ + /* Gets the key repeat initial timeout or -1 if automatic key repeating is disabled. */ virtual nsecs_t getKeyRepeatTimeout() = 0; + /* Gets the key repeat inter-key delay. */ + virtual nsecs_t getKeyRepeatDelay() = 0; + /* Waits for key event input targets to become available. * If the event is being injected, injectorPid and injectorUid should specify the * process id and used id of the injecting application, otherwise they should both @@ -193,7 +204,8 @@ public: uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0; virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, + uint32_t policyFlags, int32_t action, int32_t flags, + int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime) = 0; @@ -257,7 +269,8 @@ public: uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime); virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, + uint32_t policyFlags, int32_t action, int32_t flags, + int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime); @@ -327,6 +340,7 @@ private: int32_t source; uint32_t policyFlags; int32_t action; + int32_t flags; int32_t metaState; int32_t edgeFlags; float xPrecision; @@ -458,7 +472,8 @@ private: int32_t repeatCount, nsecs_t downTime); MotionEntry* obtainMotionEntry(nsecs_t eventTime, int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, - int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision, + int32_t flags, int32_t metaState, int32_t edgeFlags, + float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords); DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry); diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h index 31ec701..82831e2 100644 --- a/include/ui/InputTransport.h +++ b/include/ui/InputTransport.h @@ -135,6 +135,7 @@ struct InputMessage { struct { int32_t action; + int32_t flags; int32_t metaState; int32_t edgeFlags; nsecs_t downTime; @@ -218,6 +219,7 @@ public: int32_t deviceId, int32_t source, int32_t action, + int32_t flags, int32_t edgeFlags, int32_t metaState, float xOffset, diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp index 4973cd8..811edaf 100644 --- a/libs/ui/Input.cpp +++ b/libs/ui/Input.cpp @@ -129,6 +129,7 @@ void MotionEvent::initialize( int32_t deviceId, int32_t source, int32_t action, + int32_t flags, int32_t edgeFlags, int32_t metaState, float xOffset, @@ -142,6 +143,7 @@ void MotionEvent::initialize( const PointerCoords* pointerCoords) { InputEvent::initialize(deviceId, source); mAction = action; + mFlags = flags; mEdgeFlags = edgeFlags; mMetaState = metaState; mXOffset = xOffset; diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 886c785..df232d4 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -97,6 +97,7 @@ InputDispatcher::~InputDispatcher() { void InputDispatcher::dispatchOnce() { nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout(); + nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay(); bool skipPoll = false; nsecs_t currentTime; @@ -146,7 +147,7 @@ void InputDispatcher::dispatchOnce() { if (mInboundQueue.isEmpty()) { if (mKeyRepeatState.lastKeyEntry) { if (currentTime >= mKeyRepeatState.nextRepeatTime) { - processKeyRepeatLockedInterruptible(currentTime, keyRepeatTimeout); + processKeyRepeatLockedInterruptible(currentTime, keyRepeatDelay); skipPoll = true; } else { if (mKeyRepeatState.nextRepeatTime < nextWakeupTime) { @@ -335,7 +336,7 @@ void InputDispatcher::processKeyLockedInterruptible( } void InputDispatcher::processKeyRepeatLockedInterruptible( - nsecs_t currentTime, nsecs_t keyRepeatTimeout) { + nsecs_t currentTime, nsecs_t keyRepeatDelay) { KeyEntry* entry = mKeyRepeatState.lastKeyEntry; // Search the inbound queue for a key up corresponding to this device. @@ -352,7 +353,7 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( } } - // Synthesize a key repeat after the repeat timeout expired. + // Synthesize a key repeat. // Reuse the repeated key entry if it is otherwise unreferenced. uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK; if (entry->refCount == 1) { @@ -375,7 +376,7 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS; } - mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatTimeout; + mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay; #if DEBUG_OUTBOUND_EVENT_DETAILS LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, " @@ -392,9 +393,11 @@ void InputDispatcher::processKeyRepeatLockedInterruptible( void InputDispatcher::processMotionLockedInterruptible( nsecs_t currentTime, MotionEntry* entry) { #if DEBUG_OUTBOUND_EVENT_DETAILS - LOGD("processMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, " + LOGD("processMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, " + "action=0x%x, flags=0x%x, " "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld", - entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action, + entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, + entry->action, entry->flags, entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision, entry->downTime); @@ -406,7 +409,7 @@ void InputDispatcher::processMotionLockedInterruptible( } for (uint32_t i = 0; i < entry->pointerCount; i++) { LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, " - "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, " + "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " "orientation=%f", i, entry->pointerIds[i], sample->pointerCoords[i].x, sample->pointerCoords[i].y, @@ -465,7 +468,7 @@ void InputDispatcher::identifyInputTargetsAndDispatchMotionLockedInterruptible( mCurrentInputTargetsValid = false; mLock.unlock(); - mReusableMotionEvent.initialize(entry->deviceId, entry->source, entry->action, + mReusableMotionEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags, entry->edgeFlags, entry->metaState, 0, 0, entry->xPrecision, entry->yPrecision, entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds, @@ -698,12 +701,16 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, // Apply target flags. int32_t action = motionEntry->action; + int32_t flags = motionEntry->flags; if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) { action = AMOTION_EVENT_ACTION_OUTSIDE; } if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) { action = AMOTION_EVENT_ACTION_CANCEL; } + if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) { + flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; + } // If headMotionSample is non-NULL, then it points to the first new sample that we // were unable to dispatch during the previous cycle so we resume dispatching from @@ -726,7 +733,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, // Publish the motion event and the first motion sample. status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId, - motionEntry->source, action, motionEntry->edgeFlags, motionEntry->metaState, + motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState, xOffset, yOffset, motionEntry->xPrecision, motionEntry->yPrecision, motionEntry->downTime, firstMotionSample->eventTime, @@ -1073,18 +1080,18 @@ void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t sou } void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source, - uint32_t policyFlags, int32_t action, int32_t metaState, int32_t edgeFlags, + uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords, float xPrecision, float yPrecision, nsecs_t downTime) { #if DEBUG_INBOUND_EVENT_DETAILS LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, " - "action=0x%x, metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, " - "downTime=%lld", - eventTime, deviceId, source, policyFlags, action, metaState, edgeFlags, + "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, " + "xPrecision=%f, yPrecision=%f, downTime=%lld", + eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags, xPrecision, yPrecision, downTime); for (uint32_t i = 0; i < pointerCount; i++) { LOGD(" Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, " - "touchMajor=%f, touchMinor=%d, toolMajor=%f, toolMinor=%f, " + "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " "orientation=%f", i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y, pointerCoords[i].pressure, pointerCoords[i].size, @@ -1209,7 +1216,7 @@ NoBatchingOrStreaming:; // Just enqueue a new motion event. MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime, - deviceId, source, policyFlags, action, metaState, edgeFlags, + deviceId, source, policyFlags, action, flags, metaState, edgeFlags, xPrecision, yPrecision, downTime, pointerCount, pointerIds, pointerCoords); @@ -1359,7 +1366,7 @@ InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked( switch (event->getType()) { case AINPUT_EVENT_TYPE_KEY: { const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event); - uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events + uint32_t policyFlags = POLICY_FLAG_INJECTED; KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(), keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags, @@ -1371,7 +1378,7 @@ InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked( case AINPUT_EVENT_TYPE_MOTION: { const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); - uint32_t policyFlags = 0; // XXX consider adding a policy flag to track injected events + uint32_t policyFlags = POLICY_FLAG_INJECTED; const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes(); const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords(); @@ -1379,7 +1386,8 @@ InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked( MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes, motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags, - motionEvent->getAction(), motionEvent->getMetaState(), motionEvent->getEdgeFlags(), + motionEvent->getAction(), motionEvent->getFlags(), + motionEvent->getMetaState(), motionEvent->getEdgeFlags(), motionEvent->getXPrecision(), motionEvent->getYPrecision(), motionEvent->getDownTime(), uint32_t(pointerCount), motionEvent->getPointerIds(), samplePointerCoords); @@ -1664,7 +1672,7 @@ InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t ev } InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime, - int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, + int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision, nsecs_t downTime, uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords) { @@ -1676,6 +1684,7 @@ InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsec entry->source = source; entry->policyFlags = policyFlags; entry->action = action; + entry->flags = flags; entry->metaState = metaState; entry->edgeFlags = edgeFlags; entry->xPrecision = xPrecision; diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 8ffb48d..d57b38c 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -1153,7 +1153,7 @@ void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEv int32_t pointerId = 0; getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags, - motionEventAction, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, + motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE, 1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime); } @@ -2324,7 +2324,7 @@ void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags, } // release lock getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags, - motionEventAction, getContext()->getGlobalMetaState(), motionEventEdgeFlags, + motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags, pointerCount, pointerIds, pointerCoords, xPrecision, yPrecision, mDownTime); } diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp index cf0f63e..4c402dc 100644 --- a/libs/ui/InputTransport.cpp +++ b/libs/ui/InputTransport.cpp @@ -318,8 +318,8 @@ status_t InputPublisher::publishKeyEvent( nsecs_t downTime, nsecs_t eventTime) { #if DEBUG_TRANSPORT_ACTIONS - LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=%d, " - "action=%d, flags=%d, keyCode=%d, scanCode=%d, metaState=%d, repeatCount=%d," + LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=0x%x, " + "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d," "downTime=%lld, eventTime=%lld", mChannel->getName().string(), deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, @@ -346,6 +346,7 @@ status_t InputPublisher::publishMotionEvent( int32_t deviceId, int32_t source, int32_t action, + int32_t flags, int32_t edgeFlags, int32_t metaState, float xOffset, @@ -358,12 +359,12 @@ status_t InputPublisher::publishMotionEvent( const int32_t* pointerIds, const PointerCoords* pointerCoords) { #if DEBUG_TRANSPORT_ACTIONS - LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=%d, " - "action=%d, edgeFlags=%d, metaState=%d, xOffset=%f, yOffset=%f, " + LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, " + "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, xOffset=%f, yOffset=%f, " "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, " "pointerCount=%d", mChannel->getName().string(), - deviceId, source, action, edgeFlags, metaState, xOffset, yOffset, + deviceId, source, action, flags, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount); #endif @@ -379,6 +380,7 @@ status_t InputPublisher::publishMotionEvent( } mSharedMessage->motion.action = action; + mSharedMessage->motion.flags = flags; mSharedMessage->motion.edgeFlags = edgeFlags; mSharedMessage->motion.metaState = metaState; mSharedMessage->motion.xOffset = xOffset; @@ -664,6 +666,7 @@ void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const { mSharedMessage->deviceId, mSharedMessage->source, mSharedMessage->motion.action, + mSharedMessage->motion.flags, mSharedMessage->motion.edgeFlags, mSharedMessage->motion.metaState, mSharedMessage->motion.xOffset, diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp index 3bc21fa..952b974 100644 --- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp +++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp @@ -138,6 +138,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( const int32_t deviceId = 1; const int32_t source = AINPUT_SOURCE_TOUCHSCREEN; const int32_t action = AMOTION_EVENT_ACTION_MOVE; + const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP; const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON; const float xOffset = -10; @@ -167,7 +168,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( } } - status = mPublisher->publishMotionEvent(deviceId, source, action, edgeFlags, + status = mPublisher->publishMotionEvent(deviceId, source, action, flags, edgeFlags, metaState, xOffset, yOffset, xPrecision, yPrecision, downTime, sampleEventTimes[0], pointerCount, pointerIds, samplePointerCoords.array()); ASSERT_EQ(OK, status) @@ -213,6 +214,7 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent( EXPECT_EQ(deviceId, motionEvent->getDeviceId()); EXPECT_EQ(source, motionEvent->getSource()); EXPECT_EQ(action, motionEvent->getAction()); + EXPECT_EQ(flags, motionEvent->getFlags()); EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags()); EXPECT_EQ(metaState, motionEvent->getMetaState()); EXPECT_EQ(xPrecision, motionEvent->getXPrecision()); @@ -322,12 +324,12 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenNotReset_ReturnsErr int32_t pointerIds[pointerCount] = { 0 }; PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; - status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status) << "publisher publishMotionEvent should return OK"; - status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(INVALID_OPERATION, status) << "publisher publishMotionEvent should return INVALID_OPERATION because "; @@ -342,7 +344,7 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessTha int32_t pointerIds[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -356,7 +358,7 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreater int32_t pointerIds[pointerCount]; PointerCoords pointerCoords[pointerCount]; - status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(BAD_VALUE, status) << "publisher publishMotionEvent should return BAD_VALUE"; @@ -402,7 +404,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenPublishedMotionEven PointerCoords pointerCoords[pointerCount]; status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_DOWN, - 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); + 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); status = mPublisher->appendMotionSample(0, pointerCoords); @@ -419,7 +421,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenAlreadyConsumed_Ret PointerCoords pointerCoords[pointerCount]; status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE, - 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); + 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); status = mPublisher->sendDispatchSignal(); @@ -446,7 +448,7 @@ TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenBufferFull_ReturnsE PointerCoords pointerCoords[pointerCount]; status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE, - 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); + 0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords); ASSERT_EQ(OK, status); for (int count = 1;; count++) { diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp index 45ef416..b3e1531 100755 --- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp @@ -1133,7 +1133,7 @@ void ReverbSetDecayTime(ReverbContext *pContext, uint32_t time){ //LOGV("\tReverbSetDecayTime() just Got -> %d\n", ActiveParams.T60); if (time <= LVREV_MAX_T60) { - ActiveParams.T60 = time; + ActiveParams.T60 = (LVM_UINT16)time; } else { ActiveParams.T60 = LVREV_MAX_T60; @@ -1146,7 +1146,7 @@ void ReverbSetDecayTime(ReverbContext *pContext, uint32_t time){ pContext->SamplesToExitCount = (ActiveParams.T60 * pContext->config.inputCfg.samplingRate)/1000; //LOGV("\tReverbSetDecayTime() just Set SamplesToExitCount-> %d\n",pContext->SamplesToExitCount); - pContext->SavedDecayTime = time; + pContext->SavedDecayTime = (int16_t)time; //LOGV("\tReverbSetDecayTime end"); return; } @@ -1162,7 +1162,7 @@ void ReverbSetDecayTime(ReverbContext *pContext, uint32_t time){ // //---------------------------------------------------------------------------- -int32_t ReverbGetDecayTime(ReverbContext *pContext){ +uint32_t ReverbGetDecayTime(ReverbContext *pContext){ //LOGV("\tReverbGetDecayTime start"); LVREV_ControlParams_st ActiveParams; /* Current control Parameters */ @@ -1181,7 +1181,7 @@ int32_t ReverbGetDecayTime(ReverbContext *pContext){ } //LOGV("\tReverbGetDecayTime end"); - return ActiveParams.T60; + return (uint32_t)ActiveParams.T60; } //---------------------------------------------------------------------------- @@ -1606,7 +1606,7 @@ int Reverb_getParameter(ReverbContext *pContext, // *(int16_t *)pValue); break; case REVERB_PARAM_DECAY_TIME: - *(int32_t *)pValue = ReverbGetDecayTime(pContext); + *(uint32_t *)pValue = ReverbGetDecayTime(pContext); //LOGV("\tReverb_getParameter() REVERB_PARAM_DECAY_TIME Value is %d", // *(int32_t *)pValue); @@ -1671,6 +1671,7 @@ int Reverb_getParameter(ReverbContext *pContext, int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){ int status = 0; int16_t level; + int16_t ratio; uint32_t time; t_reverb_settings *pProperties; int32_t *pParamTemp = (int32_t *)pParam; @@ -1688,6 +1689,7 @@ int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){ return -EINVAL; } pContext->nextPreset = preset; + return 0; } switch (param){ @@ -1724,10 +1726,10 @@ int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){ //LOGV("\tReverb_setParameter() Called ReverbSetDecayTime"); break; case REVERB_PARAM_DECAY_HF_RATIO: - time = *(int16_t *)pValue; - //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_HF_RATIO value is %d", time); + ratio = *(int16_t *)pValue; + //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_HF_RATIO value is %d", ratio); //LOGV("\tReverb_setParameter() Calling ReverbSetDecayHfRatio"); - ReverbSetDecayHfRatio(pContext, time); + ReverbSetDecayHfRatio(pContext, ratio); //LOGV("\tReverb_setParameter() Called ReverbSetDecayHfRatio"); break; case REVERB_PARAM_REVERB_LEVEL: @@ -1738,17 +1740,17 @@ int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){ //LOGV("\tReverb_setParameter() Called ReverbSetReverbLevel"); break; case REVERB_PARAM_DIFFUSION: - time = *(int16_t *)pValue; - //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DIFFUSION value is %d", time); + ratio = *(int16_t *)pValue; + //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DIFFUSION value is %d", ratio); //LOGV("\tReverb_setParameter() Calling ReverbSetDiffusion"); - ReverbSetDiffusion(pContext, time); + ReverbSetDiffusion(pContext, ratio); //LOGV("\tReverb_setParameter() Called ReverbSetDiffusion"); break; case REVERB_PARAM_DENSITY: - time = *(int16_t *)pValue; - //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DENSITY value is %d", time); + ratio = *(int16_t *)pValue; + //LOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DENSITY value is %d", ratio); //LOGV("\tReverb_setParameter() Calling ReverbSetDensity"); - ReverbSetDensity(pContext, time); + ReverbSetDensity(pContext, ratio); //LOGV("\tReverb_setParameter() Called ReverbSetDensity"); break; break; diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp index c2f79e8..8d7ada3 100644 --- a/media/libstagefright/AudioSource.cpp +++ b/media/libstagefright/AudioSource.cpp @@ -316,8 +316,10 @@ status_t AudioSource::read( } if (numFramesRecorded == 0) { - buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs); + buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs); } + + buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs + mPrevSampleTimeUs); buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs); CHECK(timestampUs > mPrevSampleTimeUs); mPrevSampleTimeUs = timestampUs; diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index 2e36968..82c0426 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -459,7 +459,8 @@ private: MP3Extractor::MP3Extractor( const sp<DataSource> &source, const sp<AMessage> &meta) - : mDataSource(source), + : mInitCheck(NO_INIT), + mDataSource(source), mFirstFramePos(-1), mFixedHeader(0), mByteNumber(0) { @@ -480,53 +481,54 @@ MP3Extractor::MP3Extractor( success = true; } else { success = Resync(mDataSource, 0, &pos, &header); - CHECK(success); } - if (success) { - mFirstFramePos = pos; - mFixedHeader = header; - - size_t frame_size; - int sample_rate; - int num_channels; - int bitrate; - get_mp3_frame_size( - header, &frame_size, &sample_rate, &num_channels, &bitrate); - - mMeta = new MetaData; + if (!success) { + // mInitCheck will remain NO_INIT + return; + } - mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); - mMeta->setInt32(kKeySampleRate, sample_rate); - mMeta->setInt32(kKeyBitRate, bitrate * 1000); - mMeta->setInt32(kKeyChannelCount, num_channels); + mFirstFramePos = pos; + mFixedHeader = header; - int64_t duration; - parse_xing_header( - mDataSource, mFirstFramePos, NULL, &mByteNumber, - mTableOfContents, NULL, &duration); - if (duration > 0) { - mMeta->setInt64(kKeyDuration, duration); - } else { - off_t fileSize; - if (mDataSource->getSize(&fileSize) == OK) { - mMeta->setInt64( - kKeyDuration, - 8000LL * (fileSize - mFirstFramePos) / bitrate); - } + size_t frame_size; + int sample_rate; + int num_channels; + int bitrate; + get_mp3_frame_size( + header, &frame_size, &sample_rate, &num_channels, &bitrate); + + mMeta = new MetaData; + + mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG); + mMeta->setInt32(kKeySampleRate, sample_rate); + mMeta->setInt32(kKeyBitRate, bitrate * 1000); + mMeta->setInt32(kKeyChannelCount, num_channels); + + int64_t duration; + parse_xing_header( + mDataSource, mFirstFramePos, NULL, &mByteNumber, + mTableOfContents, NULL, &duration); + if (duration > 0) { + mMeta->setInt64(kKeyDuration, duration); + } else { + off_t fileSize; + if (mDataSource->getSize(&fileSize) == OK) { + mMeta->setInt64( + kKeyDuration, + 8000LL * (fileSize - mFirstFramePos) / bitrate); } } -} -MP3Extractor::~MP3Extractor() { + mInitCheck = OK; } size_t MP3Extractor::countTracks() { - return (mFirstFramePos < 0) ? 0 : 1; + return mInitCheck != OK ? 0 : 1; } sp<MediaSource> MP3Extractor::getTrack(size_t index) { - if (mFirstFramePos < 0 || index != 0) { + if (mInitCheck != OK || index != 0) { return NULL; } @@ -536,7 +538,7 @@ sp<MediaSource> MP3Extractor::getTrack(size_t index) { } sp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) { - if (mFirstFramePos < 0 || index != 0) { + if (mInitCheck != OK || index != 0) { return NULL; } @@ -713,7 +715,7 @@ status_t MP3Source::read( sp<MetaData> MP3Extractor::getMetaData() { sp<MetaData> meta = new MetaData; - if (mFirstFramePos < 0) { + if (mInitCheck != OK) { return meta; } diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp index e391c72..df9f107 100644 --- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp +++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp @@ -243,7 +243,7 @@ status_t AACEncoder::read( if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { wallClockTimeUs = timeUs; } - if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { + if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { mAnchorTimeUs = timeUs; } readFromSource = true; diff --git a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp index 858e6d0..94a79ab 100644 --- a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp +++ b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp @@ -174,7 +174,7 @@ status_t AMRNBEncoder::read( if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { wallClockTimeUs = timeUs; } - if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { + if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { mAnchorTimeUs = timeUs; } } else { diff --git a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp index cd28413..002f055 100644 --- a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp +++ b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp @@ -224,7 +224,7 @@ status_t AMRWBEncoder::read( if (mInputBuffer->meta_data()->findInt64(kKeyDriftTime, &timeUs)) { wallClockTimeUs = timeUs; } - if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { + if (mInputBuffer->meta_data()->findInt64(kKeyAnchorTime, &timeUs)) { mAnchorTimeUs = timeUs; } readFromSource = true; diff --git a/media/libstagefright/include/MP3Extractor.h b/media/libstagefright/include/MP3Extractor.h index 0e6ccde..30136e7d 100644 --- a/media/libstagefright/include/MP3Extractor.h +++ b/media/libstagefright/include/MP3Extractor.h @@ -37,10 +37,9 @@ public: virtual sp<MetaData> getMetaData(); -protected: - virtual ~MP3Extractor(); - private: + status_t mInitCheck; + sp<DataSource> mDataSource; off_t mFirstFramePos; sp<MetaData> mMeta; diff --git a/native/android/input.cpp b/native/android/input.cpp index c79f913..57f0072 100644 --- a/native/android/input.cpp +++ b/native/android/input.cpp @@ -84,6 +84,10 @@ int32_t AMotionEvent_getAction(const AInputEvent* motion_event) { return static_cast<const MotionEvent*>(motion_event)->getAction(); } +int32_t AMotionEvent_getFlags(const AInputEvent* motion_event) { + return static_cast<const MotionEvent*>(motion_event)->getFlags(); +} + int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event) { return static_cast<const MotionEvent*>(motion_event)->getMetaState(); } diff --git a/native/include/android/input.h b/native/include/android/input.h index 5b62da4..9da122b 100644 --- a/native/include/android/input.h +++ b/native/include/android/input.h @@ -247,6 +247,22 @@ enum { }; /* + * Motion event flags. + */ +enum { + /* This flag indicates that the window that received this motion event is partly + * or wholly obscured by another visible window above it. This flag is set to true + * even if the event did not directly pass through the obscured area. + * A security sensitive application can check this flag to identify situations in which + * a malicious application may have covered up part of its content for the purpose + * of misleading the user or hijacking touches. An appropriate response might be + * to drop the suspect touches or to take additional precautions to confirm the user's + * actual intent. + */ + AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1, +}; + +/* * Motion event edge touch flags. */ enum { @@ -395,6 +411,9 @@ int64_t AKeyEvent_getEventTime(const AInputEvent* key_event); /* Get the combined motion event action code and pointer index. */ int32_t AMotionEvent_getAction(const AInputEvent* motion_event); +/* Get the motion event flags. */ +int32_t AMotionEvent_getFlags(const AInputEvent* motion_event); + /* Get the state of any meta / modifier keys that were in effect when the * event was generated. */ int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event); diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp index 06fa0c2..9f80ed4 100644 --- a/opengl/tests/angeles/app-linux.cpp +++ b/opengl/tests/angeles/app-linux.cpp @@ -190,24 +190,33 @@ int main(int argc, char *argv[]) } appInit(); + + struct timeval timeTemp; + int frameCount = 0; + gettimeofday(&timeTemp, NULL); + double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec; while (gAppAlive) { struct timeval timeNow; - if (gAppAlive) - { - gettimeofday(&timeNow, NULL); - appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, - sWindowWidth, sWindowHeight); - checkGLErrors(); - eglSwapBuffers(sEglDisplay, sEglSurface); - checkEGLErrors(); - } + gettimeofday(&timeNow, NULL); + appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000, + sWindowWidth, sWindowHeight); + checkGLErrors(); + eglSwapBuffers(sEglDisplay, sEglSurface); + checkEGLErrors(); + frameCount++; } + gettimeofday(&timeTemp, NULL); + appDeinit(); deinitGraphics(); + totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime; + printf("totalTime=%f s, frameCount=%d, %.2f fps\n", + totalTime, frameCount, frameCount/totalTime); + return EXIT_SUCCESS; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java index e828f68..c5688e6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java @@ -36,6 +36,7 @@ import android.location.LocationManager; import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; +import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.net.wifi.WifiManager; @@ -91,6 +92,8 @@ public class StatusBarPolicy { private static final int AM_PM_STYLE = AM_PM_STYLE_GONE; + private static final int INET_CONDITION_THRESHOLD = 50; + private final Context mContext; private final StatusBarManager mService; private final Handler mHandler = new StatusBarHandler(); @@ -232,42 +235,62 @@ public class StatusBarPolicy { }; //***** Data connection icons - private int[] mDataIconList = sDataNetType_g; + private int[] mDataIconList = sDataNetType_g[0]; //GSM/UMTS - private static final int[] sDataNetType_g = new int[] { - R.drawable.stat_sys_data_connected_g, - R.drawable.stat_sys_data_in_g, - R.drawable.stat_sys_data_out_g, - R.drawable.stat_sys_data_inandout_g, + private static final int[][] sDataNetType_g = { + { R.drawable.stat_sys_data_connected_g, + R.drawable.stat_sys_data_in_g, + R.drawable.stat_sys_data_out_g, + R.drawable.stat_sys_data_inandout_g }, + { R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 } }; - private static final int[] sDataNetType_3g = new int[] { - R.drawable.stat_sys_data_connected_3g, - R.drawable.stat_sys_data_in_3g, - R.drawable.stat_sys_data_out_3g, - R.drawable.stat_sys_data_inandout_3g, + private static final int[][] sDataNetType_3g = { + { R.drawable.stat_sys_data_connected_3g, + R.drawable.stat_sys_data_in_3g, + R.drawable.stat_sys_data_out_3g, + R.drawable.stat_sys_data_inandout_3g }, + { R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 } }; - private static final int[] sDataNetType_e = new int[] { - R.drawable.stat_sys_data_connected_e, - R.drawable.stat_sys_data_in_e, - R.drawable.stat_sys_data_out_e, - R.drawable.stat_sys_data_inandout_e, + private static final int[][] sDataNetType_e = { + { R.drawable.stat_sys_data_connected_e, + R.drawable.stat_sys_data_in_e, + R.drawable.stat_sys_data_out_e, + R.drawable.stat_sys_data_inandout_e }, + { R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 } }; //3.5G - private static final int[] sDataNetType_h = new int[] { - R.drawable.stat_sys_data_connected_h, - R.drawable.stat_sys_data_in_h, - R.drawable.stat_sys_data_out_h, - R.drawable.stat_sys_data_inandout_h, + private static final int[][] sDataNetType_h = { + { R.drawable.stat_sys_data_connected_h, + R.drawable.stat_sys_data_in_h, + R.drawable.stat_sys_data_out_h, + R.drawable.stat_sys_data_inandout_h }, + { R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 } }; //CDMA // Use 3G icons for EVDO data and 1x icons for 1XRTT data - private static final int[] sDataNetType_1x = new int[] { - R.drawable.stat_sys_data_connected_1x, - R.drawable.stat_sys_data_in_1x, - R.drawable.stat_sys_data_out_1x, - R.drawable.stat_sys_data_inandout_1x, - }; + private static final int[][] sDataNetType_1x = { + { R.drawable.stat_sys_data_connected_1x, + R.drawable.stat_sys_data_in_1x, + R.drawable.stat_sys_data_out_1x, + R.drawable.stat_sys_data_inandout_1x }, + { R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0, + R.drawable.stat_sys_roaming_cdma_0 } + }; // Assume it's all good unless we hear otherwise. We don't always seem // to get broadcasts that it *is* there. @@ -292,17 +315,22 @@ public class StatusBarPolicy { private boolean mBluetoothEnabled; // wifi - private static final int[] sWifiSignalImages = new int[] { - R.drawable.stat_sys_wifi_signal_1, - R.drawable.stat_sys_wifi_signal_2, - R.drawable.stat_sys_wifi_signal_3, - R.drawable.stat_sys_wifi_signal_4, + private static final int[][] sWifiSignalImages = { + { R.drawable.stat_sys_wifi_signal_1, + R.drawable.stat_sys_wifi_signal_2, + R.drawable.stat_sys_wifi_signal_3, + R.drawable.stat_sys_wifi_signal_4 }, + { R.drawable.stat_sys_data_in_e, + R.drawable.stat_sys_data_in_e, + R.drawable.stat_sys_data_in_e, + R.drawable.stat_sys_data_in_e } }; private static final int sWifiTemporarilyNotConnectedImage = R.drawable.stat_sys_wifi_signal_0; private int mLastWifiSignalLevel = -1; private boolean mIsWifiConnected = false; + private int mLastWifiInetConnectivityState = 0; // sync state // If sync is active the SyncActive icon is displayed. If sync is not active but @@ -353,6 +381,10 @@ public class StatusBarPolicy { else if (action.equals(TtyIntent.TTY_ENABLED_CHANGE_ACTION)) { updateTTY(intent); } + else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { + // TODO - stop using other means to get wifi/mobile info + updateConnectivity(intent); + } } }; @@ -389,7 +421,7 @@ public class StatusBarPolicy { mService.setIconVisibility("data_connection", false); // wifi - mService.setIcon("wifi", sWifiSignalImages[0], 0); + mService.setIcon("wifi", sWifiSignalImages[0][0], 0); mService.setIconVisibility("wifi", false); // wifi will get updated by the sticky intents @@ -456,6 +488,7 @@ public class StatusBarPolicy { filter.addAction(LocationManager.GPS_FIX_CHANGE_ACTION); filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); filter.addAction(TtyIntent.TTY_ENABLED_CHANGE_ACTION); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); // load config to determine if to distinguish Hspa data icon @@ -659,6 +692,50 @@ public class StatusBarPolicy { } } + private void updateConnectivity(Intent intent) { + NetworkInfo info = (NetworkInfo)(intent.getParcelableExtra( + ConnectivityManager.EXTRA_NETWORK_INFO)); + int connectionStatus = intent.getIntExtra(ConnectivityManager.EXTRA_INET_CONDITION, 0); + Slog.d(TAG, "got CONNECTIVITY_ACTION - info=" + info + ", status = " + connectionStatus); + if (info.isConnected() == false) return; + + switch (info.getType()) { + case ConnectivityManager.TYPE_MOBILE: + if (info.isConnected()) { + updateDataNetType(info.getSubtype(), connectionStatus); + updateDataIcon(); + } + break; + case ConnectivityManager.TYPE_WIFI: + if (info.isConnected()) { + mIsWifiConnected = true; + mLastWifiInetConnectivityState = + (connectionStatus > INET_CONDITION_THRESHOLD ? 1 : 0); + int iconId; + if (mLastWifiSignalLevel == -1) { + iconId = sWifiSignalImages[mLastWifiInetConnectivityState][0]; + } else { + iconId = sWifiSignalImages[mLastWifiInetConnectivityState] + [mLastWifiSignalLevel]; + } + + mService.setIcon("wifi", iconId, 0); + // Show the icon since wi-fi is connected + mService.setIconVisibility("wifi", true); + } else { + mLastWifiSignalLevel = -1; + mIsWifiConnected = false; + mLastWifiInetConnectivityState = 0; + int iconId = sWifiSignalImages[0][0]; + + mService.setIcon("wifi", iconId, 0); + // Hide the icon since we're not connected + mService.setIconVisibility("wifi", false); + } + break; + } + } + private PhoneStateListener mPhoneStateListener = new PhoneStateListener() { @Override public void onSignalStrengthsChanged(SignalStrength signalStrength) { @@ -686,7 +763,7 @@ public class StatusBarPolicy { @Override public void onDataConnectionStateChanged(int state, int networkType) { mDataState = state; - updateDataNetType(networkType); + updateDataNetType(networkType, 0); updateDataIcon(); } @@ -848,37 +925,38 @@ public class StatusBarPolicy { return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; } - private final void updateDataNetType(int net) { + private final void updateDataNetType(int net, int inetCondition) { + int connected = (inetCondition > INET_CONDITION_THRESHOLD ? 1 : 0); switch (net) { case TelephonyManager.NETWORK_TYPE_EDGE: - mDataIconList = sDataNetType_e; + mDataIconList = sDataNetType_e[connected]; break; case TelephonyManager.NETWORK_TYPE_UMTS: - mDataIconList = sDataNetType_3g; + mDataIconList = sDataNetType_3g[connected]; break; case TelephonyManager.NETWORK_TYPE_HSDPA: case TelephonyManager.NETWORK_TYPE_HSUPA: case TelephonyManager.NETWORK_TYPE_HSPA: if (mHspaDataDistinguishable) { - mDataIconList = sDataNetType_h; + mDataIconList = sDataNetType_h[connected]; } else { - mDataIconList = sDataNetType_3g; + mDataIconList = sDataNetType_3g[connected]; } break; case TelephonyManager.NETWORK_TYPE_CDMA: // display 1xRTT for IS95A/B - mDataIconList = this.sDataNetType_1x; + mDataIconList = sDataNetType_1x[connected]; break; case TelephonyManager.NETWORK_TYPE_1xRTT: - mDataIconList = this.sDataNetType_1x; + mDataIconList = sDataNetType_1x[connected]; break; case TelephonyManager.NETWORK_TYPE_EVDO_0: //fall through case TelephonyManager.NETWORK_TYPE_EVDO_A: case TelephonyManager.NETWORK_TYPE_EVDO_B: - mDataIconList = sDataNetType_3g; + mDataIconList = sDataNetType_3g[connected]; break; default: - mDataIconList = sDataNetType_g; + mDataIconList = sDataNetType_g[connected]; break; } } @@ -1019,34 +1097,6 @@ public class StatusBarPolicy { if (!enabled) { mService.setIconVisibility("wifi", false); } - } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { - - final NetworkInfo networkInfo = (NetworkInfo) - intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); - - int iconId; - if (networkInfo != null && networkInfo.isConnected()) { - mIsWifiConnected = true; - if (mLastWifiSignalLevel == -1) { - iconId = sWifiSignalImages[0]; - } else { - iconId = sWifiSignalImages[mLastWifiSignalLevel]; - } - - mService.setIcon("wifi", iconId, 0); - // Show the icon since wi-fi is connected - mService.setIconVisibility("wifi", true); - - } else { - mLastWifiSignalLevel = -1; - mIsWifiConnected = false; - iconId = sWifiSignalImages[0]; - - mService.setIcon("wifi", iconId, 0); - // Hide the icon since we're not connected - mService.setIconVisibility("wifi", false); - } - } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { int iconId; final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); @@ -1055,7 +1105,7 @@ public class StatusBarPolicy { if (newSignalLevel != mLastWifiSignalLevel) { mLastWifiSignalLevel = newSignalLevel; if (mIsWifiConnected) { - iconId = sWifiSignalImages[newSignalLevel]; + iconId = sWifiSignalImages[mLastWifiInetConnectivityState][newSignalLevel]; } else { iconId = sWifiTemporarilyNotConnectedImage; } diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 3db5dc1..e454c08 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -668,7 +668,7 @@ class BackupManagerService extends IBackupManager.Stub { while (true) { String packageName = in.readUTF(); Slog.i(TAG, " + " + packageName); - dataChanged(packageName); + dataChangedImpl(packageName); } } catch (EOFException e) { // no more data; we're done @@ -740,7 +740,7 @@ class BackupManagerService extends IBackupManager.Stub { int uid = mBackupParticipants.keyAt(i); HashSet<ApplicationInfo> participants = mBackupParticipants.valueAt(i); for (ApplicationInfo app: participants) { - dataChanged(app.packageName); + dataChangedImpl(app.packageName); } } } @@ -896,7 +896,7 @@ class BackupManagerService extends IBackupManager.Stub { if (!mEverStoredApps.contains(pkg.packageName)) { if (DEBUG) Slog.i(TAG, "New app " + pkg.packageName + " never backed up; scheduling"); - dataChanged(pkg.packageName); + dataChangedImpl(pkg.packageName); } } } @@ -1327,7 +1327,7 @@ class BackupManagerService extends IBackupManager.Stub { if (status != BackupConstants.TRANSPORT_OK) { Slog.w(TAG, "Backup pass unsuccessful, restaging"); for (BackupRequest req : mQueue) { - dataChanged(req.appInfo.packageName); + dataChangedImpl(req.appInfo.packageName); } // We also want to reset the backup schedule based on whatever @@ -1997,25 +1997,66 @@ class BackupManagerService extends IBackupManager.Stub { } } + private void dataChangedImpl(String packageName) { + HashSet<ApplicationInfo> targets = dataChangedTargets(packageName); + dataChangedImpl(packageName, targets); + } - // ----- IBackupManager binder interface ----- - - public void dataChanged(String packageName) { + private void dataChangedImpl(String packageName, HashSet<ApplicationInfo> targets) { // Record that we need a backup pass for the caller. Since multiple callers // may share a uid, we need to note all candidates within that uid and schedule // a backup pass for each of them. EventLog.writeEvent(EventLogTags.BACKUP_DATA_CHANGED, packageName); + if (targets == null) { + Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'" + + " uid=" + Binder.getCallingUid()); + return; + } + + synchronized (mQueueLock) { + // Note that this client has made data changes that need to be backed up + for (ApplicationInfo app : targets) { + // validate the caller-supplied package name against the known set of + // packages associated with this uid + if (app.packageName.equals(packageName)) { + // Add the caller to the set of pending backups. If there is + // one already there, then overwrite it, but no harm done. + BackupRequest req = new BackupRequest(app, false); + if (mPendingBackups.put(app, req) == null) { + // Journal this request in case of crash. The put() + // operation returned null when this package was not already + // in the set; we want to avoid touching the disk redundantly. + writeToJournalLocked(packageName); + + if (DEBUG) { + int numKeys = mPendingBackups.size(); + Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:"); + for (BackupRequest b : mPendingBackups.values()) { + Slog.d(TAG, " + " + b + " agent=" + b.appInfo.backupAgentName); + } + } + } + } + } + } + } + + // Note: packageName is currently unused, but may be in the future + private HashSet<ApplicationInfo> dataChangedTargets(String packageName) { // If the caller does not hold the BACKUP permission, it can only request a // backup of its own data. - HashSet<ApplicationInfo> targets; if ((mContext.checkPermission(android.Manifest.permission.BACKUP, Binder.getCallingPid(), Binder.getCallingUid())) == PackageManager.PERMISSION_DENIED) { - targets = mBackupParticipants.get(Binder.getCallingUid()); - } else { - // a caller with full permission can ask to back up any participating app - // !!! TODO: allow backup of ANY app? - targets = new HashSet<ApplicationInfo>(); + synchronized (mBackupParticipants) { + return mBackupParticipants.get(Binder.getCallingUid()); + } + } + + // a caller with full permission can ask to back up any participating app + // !!! TODO: allow backup of ANY app? + HashSet<ApplicationInfo> targets = new HashSet<ApplicationInfo>(); + synchronized (mBackupParticipants) { int N = mBackupParticipants.size(); for (int i = 0; i < N; i++) { HashSet<ApplicationInfo> s = mBackupParticipants.valueAt(i); @@ -2024,37 +2065,7 @@ class BackupManagerService extends IBackupManager.Stub { } } } - if (targets != null) { - synchronized (mQueueLock) { - // Note that this client has made data changes that need to be backed up - for (ApplicationInfo app : targets) { - // validate the caller-supplied package name against the known set of - // packages associated with this uid - if (app.packageName.equals(packageName)) { - // Add the caller to the set of pending backups. If there is - // one already there, then overwrite it, but no harm done. - BackupRequest req = new BackupRequest(app, false); - if (mPendingBackups.put(app, req) == null) { - // Journal this request in case of crash. The put() - // operation returned null when this package was not already - // in the set; we want to avoid touching the disk redundantly. - writeToJournalLocked(packageName); - - if (DEBUG) { - int numKeys = mPendingBackups.size(); - Slog.d(TAG, "Now awaiting backup for " + numKeys + " participants:"); - for (BackupRequest b : mPendingBackups.values()) { - Slog.d(TAG, " + " + b + " agent=" + b.appInfo.backupAgentName); - } - } - } - } - } - } - } else { - Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'" - + " uid=" + Binder.getCallingUid()); - } + return targets; } private void writeToJournalLocked(String str) { @@ -2072,6 +2083,23 @@ class BackupManagerService extends IBackupManager.Stub { } } + // ----- IBackupManager binder interface ----- + + public void dataChanged(final String packageName) { + final HashSet<ApplicationInfo> targets = dataChangedTargets(packageName); + if (targets == null) { + Slog.w(TAG, "dataChanged but no participant pkg='" + packageName + "'" + + " uid=" + Binder.getCallingUid()); + return; + } + + mBackupHandler.post(new Runnable() { + public void run() { + dataChangedImpl(packageName, targets); + } + }); + } + // Clear the given package's backup data from the current transport public void clearBackupData(String packageName) { if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName); diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index c751f3d..9784d96 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -89,6 +89,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { private Context mContext; private int mNetworkPreference; private int mActiveDefaultNetwork = -1; + // 0 is full bad, 100 is full good + private int mDefaultInetCondition = 0; + private int mDefaultInetConditionPublished = 0; + private boolean mInetConditionChangeInFlight = false; + private int mDefaultConnectionSequence = 0; private int mNumDnsEntries; @@ -1016,6 +1021,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo()); } + intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished); sendStickyBroadcast(intent); } @@ -1134,6 +1140,14 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } mActiveDefaultNetwork = type; + // this will cause us to come up initially as unconnected and switching + // to connected after our normal pause unless somebody reports us as reall + // disconnected + mDefaultInetConditionPublished = 0; + mDefaultConnectionSequence++; + mInetConditionChangeInFlight = false; + // Don't do this - if we never sign in stay, grey + //reportNetworkCondition(mActiveDefaultNetwork, 100); } thisNet.setTeardownRequested(false); thisNet.updateNetworkSettings(); @@ -1436,6 +1450,70 @@ public class ConnectivityService extends IConnectivityManager.Stub { FeatureUser u = (FeatureUser)msg.obj; u.expire(); break; + case NetworkStateTracker.EVENT_INET_CONDITION_CHANGE: + if (DBG) { + Slog.d(TAG, "Inet connectivity change, net=" + + msg.arg1 + ", condition=" + msg.arg2 + + ",mActiveDefaultNetwork=" + mActiveDefaultNetwork); + } + if (mActiveDefaultNetwork == -1) { + if (DBG) Slog.d(TAG, "no active default network - aborting"); + break; + } + if (mActiveDefaultNetwork != msg.arg1) { + if (DBG) Slog.d(TAG, "given net not default - aborting"); + break; + } + mDefaultInetCondition = msg.arg2; + int delay; + if (mInetConditionChangeInFlight == false) { + if (DBG) Slog.d(TAG, "starting a change hold"); + // setup a new hold to debounce this + if (mDefaultInetCondition > 50) { + delay = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.INET_CONDITION_DEBOUNCE_UP_DELAY, 500); + } else { + delay = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.INET_CONDITION_DEBOUNCE_DOWN_DELAY, 3000); + } + mInetConditionChangeInFlight = true; + sendMessageDelayed(obtainMessage( + NetworkStateTracker.EVENT_INET_CONDITION_HOLD_END, + mActiveDefaultNetwork, mDefaultConnectionSequence), delay); + } else { + // we've set the new condition, when this hold ends that will get + // picked up + if (DBG) Slog.d(TAG, "currently in hold - not setting new end evt"); + } + break; + case NetworkStateTracker.EVENT_INET_CONDITION_HOLD_END: + if (DBG) { + Slog.d(TAG, "Inet hold end, net=" + msg.arg1 + + ", condition =" + mDefaultInetCondition + + ", published condition =" + mDefaultInetConditionPublished); + } + mInetConditionChangeInFlight = false; + + if (mActiveDefaultNetwork == -1) { + if (DBG) Slog.d(TAG, "no active default network - aborting"); + break; + } + if (mDefaultConnectionSequence != msg.arg2) { + if (DBG) Slog.d(TAG, "event hold for obsolete network - aborting"); + break; + } + if (mDefaultInetConditionPublished == mDefaultInetCondition) { + if (DBG) Slog.d(TAG, "no change in condition - aborting"); + break; + } + NetworkInfo networkInfo = mNetTrackers[mActiveDefaultNetwork].getNetworkInfo(); + if (networkInfo.isConnected() == false) { + if (DBG) Slog.d(TAG, "default network not connected - aborting"); + break; + } + mDefaultInetConditionPublished = mDefaultInetCondition; + sendConnectedBroadcast(networkInfo); + break; } } } @@ -1519,4 +1597,15 @@ public class ConnectivityService extends IConnectivityManager.Stub { Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0); return tetherEnabledInSettings && mTetheringConfigValid; } + + // 100 percent is full good, 0 is full bad. + public void reportInetCondition(int networkType, int percentage) { + if (DBG) Slog.d(TAG, "reportNetworkCondition(" + networkType + ", " + percentage + ")"); + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.STATUS_BAR, + "ConnectivityService"); + + mHandler.sendMessage(mHandler.obtainMessage( + NetworkStateTracker.EVENT_INET_CONDITION_CHANGE, networkType, percentage)); + } } diff --git a/services/java/com/android/server/DeviceStorageMonitorService.java b/services/java/com/android/server/DeviceStorageMonitorService.java index 4a0df59..0b1a4a3 100644 --- a/services/java/com/android/server/DeviceStorageMonitorService.java +++ b/services/java/com/android/server/DeviceStorageMonitorService.java @@ -69,10 +69,12 @@ class DeviceStorageMonitorService extends Binder { private static final int DEFAULT_FREE_STORAGE_LOG_INTERVAL_IN_MINUTES = 12*60; //in minutes private static final long DEFAULT_DISK_FREE_CHANGE_REPORTING_THRESHOLD = 2 * 1024 * 1024; // 2MB private static final long DEFAULT_CHECK_INTERVAL = MONITOR_INTERVAL*60*1000; + private static final int DEFAULT_FULL_THRESHOLD_BYTES = 1024*1024; // 1MB private long mFreeMem; // on /data private long mLastReportedFreeMem; private long mLastReportedFreeMemTime; private boolean mLowMemFlag=false; + private boolean mMemFullFlag=false; private Context mContext; private ContentResolver mContentResolver; private long mTotalMemory; // on /data @@ -87,9 +89,13 @@ class DeviceStorageMonitorService extends Binder { private boolean mClearingCache; private Intent mStorageLowIntent; private Intent mStorageOkIntent; + private Intent mStorageFullIntent; + private Intent mStorageNotFullIntent; private CachePackageDataObserver mClearCacheObserver; private static final int _TRUE = 1; private static final int _FALSE = 0; + private long mMemLowThreshold; + private int mMemFullThreshold; /** * This string is used for ServiceManager access to this class. @@ -103,7 +109,7 @@ class DeviceStorageMonitorService extends Binder { Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { - //dont handle an invalid message + //don't handle an invalid message if (msg.what != DEVICE_MEMORY_WHAT) { Slog.e(TAG, "Will not process invalid message"); return; @@ -184,7 +190,7 @@ class DeviceStorageMonitorService extends Binder { try { if (localLOGV) Slog.i(TAG, "Clearing cache"); IPackageManager.Stub.asInterface(ServiceManager.getService("package")). - freeStorageAndNotify(getMemThreshold(), mClearCacheObserver); + freeStorageAndNotify(mMemLowThreshold, mClearCacheObserver); } catch (RemoteException e) { Slog.w(TAG, "Failed to get handle for PackageManger Exception: "+e); mClearingCache = false; @@ -209,8 +215,7 @@ class DeviceStorageMonitorService extends Binder { if (localLOGV) Slog.v(TAG, "freeMemory="+mFreeMem); //post intent to NotificationManager to display icon if necessary - long memThreshold = getMemThreshold(); - if (mFreeMem < memThreshold) { + if (mFreeMem < mMemLowThreshold) { if (!mLowMemFlag) { if (checkCache) { // See if clearing cache helps @@ -235,6 +240,17 @@ class DeviceStorageMonitorService extends Binder { mLowMemFlag = false; } } + if (mFreeMem < mMemFullThreshold) { + if (!mMemFullFlag) { + sendFullNotification(); + mMemFullFlag = true; + } + } else { + if (mMemFullFlag) { + cancelFullNotification(); + mMemFullFlag = false; + } + } } if(localLOGV) Slog.i(TAG, "Posting Message again"); //keep posting messages to itself periodically @@ -264,6 +280,20 @@ class DeviceStorageMonitorService extends Binder { return mTotalMemory*value; } + /* + * just query settings to retrieve the memory full threshold. + * Preferred this over using a ContentObserver since Settings.Secure caches the value + * any way + */ + private int getMemFullThreshold() { + int value = Settings.Secure.getInt( + mContentResolver, + Settings.Secure.SYS_STORAGE_FULL_THRESHOLD_BYTES, + DEFAULT_FULL_THRESHOLD_BYTES); + if(localLOGV) Slog.v(TAG, "Full Threshold Bytes="+value); + return value; + } + /** * Constructor to run service. initializes the disk space threshold value * and posts an empty message to kickstart the process. @@ -283,6 +313,13 @@ class DeviceStorageMonitorService extends Binder { mStorageLowIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mStorageOkIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_OK); mStorageOkIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mStorageFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_FULL); + mStorageFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + mStorageNotFullIntent = new Intent(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); + mStorageNotFullIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + // cache storage thresholds + mMemLowThreshold = getMemThreshold(); + mMemFullThreshold = getMemFullThreshold(); checkMemory(true); } @@ -332,6 +369,23 @@ class DeviceStorageMonitorService extends Binder { mContext.sendBroadcast(mStorageOkIntent); } + /** + * Send a notification when storage is full. + */ + private final void sendFullNotification() { + if(localLOGV) Slog.i(TAG, "Sending memory full notification"); + mContext.sendStickyBroadcast(mStorageFullIntent); + } + + /** + * Cancels memory full notification and sends "not full" intent. + */ + private final void cancelFullNotification() { + if(localLOGV) Slog.i(TAG, "Canceling memory full notification"); + mContext.removeStickyBroadcast(mStorageFullIntent); + mContext.sendBroadcast(mStorageNotFullIntent); + } + public void updateMemory() { int callingUid = getCallingUid(); if(callingUid != Process.SYSTEM_UID) { diff --git a/services/java/com/android/server/InputWindow.java b/services/java/com/android/server/InputWindow.java index 8da0cf1..dbc59ef 100644 --- a/services/java/com/android/server/InputWindow.java +++ b/services/java/com/android/server/InputWindow.java @@ -34,9 +34,17 @@ public final class InputWindow { // Dispatching timeout. public long dispatchingTimeoutNanos; - // Window frame position. + // Window frame area. public int frameLeft; public int frameTop; + public int frameRight; + public int frameBottom; + + // Window visible frame area. + public int visibleFrameLeft; + public int visibleFrameTop; + public int visibleFrameRight; + public int visibleFrameBottom; // Window touchable area. public int touchableAreaLeft; diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 3841f75..0bc9b61 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -5218,6 +5218,14 @@ public class WindowManagerService extends IWindowManager.Stub final Rect frame = child.mFrame; inputWindow.frameLeft = frame.left; inputWindow.frameTop = frame.top; + inputWindow.frameRight = frame.right; + inputWindow.frameBottom = frame.bottom; + + final Rect visibleFrame = child.mVisibleFrame; + inputWindow.visibleFrameLeft = visibleFrame.left; + inputWindow.visibleFrameTop = visibleFrame.top; + inputWindow.visibleFrameRight = visibleFrame.right; + inputWindow.visibleFrameBottom = visibleFrame.bottom; switch (child.mTouchableInsets) { default: diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 89a1627..3142ee4 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -131,7 +131,8 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor { +public final class ActivityManagerService extends ActivityManagerNative + implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { static final String TAG = "ActivityManager"; static final boolean DEBUG = false; static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; @@ -750,6 +751,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen boolean mBooting = false; boolean mWaitingUpdate = false; boolean mDidUpdate = false; + boolean mOnBattery = false; Context mContext; @@ -1381,8 +1383,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen systemDir, "batterystats.bin").toString()); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.getActiveStatistics().writeLocked(); + mOnBattery = mBatteryStatsService.getActiveStatistics().getIsOnBattery(); + mBatteryStatsService.getActiveStatistics().setCallback(this); - mUsageStatsService = new UsageStatsService( new File( + mUsageStatsService = new UsageStatsService(new File( systemDir, "usagestats").toString()); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", @@ -1495,25 +1499,36 @@ public final class ActivityManagerService extends ActivityManagerNative implemen synchronized(bstats) { synchronized(mPidsSelfLocked) { if (haveNewCpuStats) { - if (mBatteryStatsService.isOnBattery()) { + if (mOnBattery) { + int perc = bstats.startAddingCpuLocked(); + int totalUTime = 0; + int totalSTime = 0; final int N = mProcessStats.countWorkingStats(); for (int i=0; i<N; i++) { ProcessStats.Stats st = mProcessStats.getWorkingStats(i); ProcessRecord pr = mPidsSelfLocked.get(st.pid); + int otherUTime = (st.rel_utime*perc)/100; + int otherSTime = (st.rel_stime*perc)/100; + totalUTime += otherUTime; + totalSTime += otherSTime; if (pr != null) { BatteryStatsImpl.Uid.Proc ps = pr.batteryStats; - ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); + ps.addCpuTimeLocked(st.rel_utime-otherUTime, + st.rel_stime-otherSTime); ps.addSpeedStepTimes(cpuSpeedTimes); } else { BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(st.name, st.pid); if (ps != null) { - ps.addCpuTimeLocked(st.rel_utime, st.rel_stime); + ps.addCpuTimeLocked(st.rel_utime-otherUTime, + st.rel_stime-otherSTime); ps.addSpeedStepTimes(cpuSpeedTimes); } } } + bstats.finishAddingCpuLocked(perc, totalUTime, + totalSTime, cpuSpeedTimes); } } } @@ -1526,6 +1541,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } + @Override + public void batteryNeedsCpuUpdate() { + updateCpuStatsNow(); + } + + @Override + public void batteryPowerChanged(boolean onBattery) { + // When plugging in, update the CPU stats first before changing + // the plug state. + updateCpuStatsNow(); + synchronized (this) { + synchronized(mPidsSelfLocked) { + mOnBattery = onBattery; + } + } + } + /** * Initialize the application bind args. These are passed to each * process when the bindApplication() IPC is sent to the process. They're diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 6d1fbab..67df707 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -131,6 +131,13 @@ class ProcessRecord { void dump(PrintWriter pw, String prefix) { final long now = SystemClock.uptimeMillis(); + long wtime; + synchronized (batteryStats.getBatteryStats()) { + wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid, + pid, SystemClock.elapsedRealtime()); + } + long timeUsed = wtime - lastWakeTime; + if (info.className != null) { pw.print(prefix); pw.print("class="); pw.println(info.className); } @@ -182,7 +189,9 @@ class ProcessRecord { pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); pw.print(" lruSeq="); pw.println(lruSeq); pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime); - pw.print(" lastRequestedGc="); + pw.print(" time used="); + TimeUtils.formatDuration(timeUsed, pw); pw.println(""); + pw.print(prefix); pw.print("lastRequestedGc="); TimeUtils.formatDuration(lastRequestedGc, now, pw); pw.print(" lastLowMemory="); TimeUtils.formatDuration(lastLowMemory, now, pw); diff --git a/services/java/com/android/server/sip/SipService.java b/services/java/com/android/server/sip/SipService.java index 563ce58..eee97c3 100644 --- a/services/java/com/android/server/sip/SipService.java +++ b/services/java/com/android/server/sip/SipService.java @@ -490,7 +490,7 @@ public final class SipService extends ISipService.Stub { private class KeepAliveProcess implements Runnable { private static final String TAG = "\\KEEPALIVE/"; - private static final int INTERVAL = 15; + private static final int INTERVAL = 10; private SipSessionGroup.SipSessionImpl mSession; public KeepAliveProcess(SipSessionGroup.SipSessionImpl session) { diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index a237ee9..7af5e95 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -169,6 +169,12 @@ static struct { jfieldID dispatchingTimeoutNanos; jfieldID frameLeft; jfieldID frameTop; + jfieldID frameRight; + jfieldID frameBottom; + jfieldID visibleFrameLeft; + jfieldID visibleFrameTop; + jfieldID visibleFrameRight; + jfieldID visibleFrameBottom; jfieldID touchableAreaLeft; jfieldID touchableAreaTop; jfieldID touchableAreaRight; @@ -269,6 +275,7 @@ public: nsecs_t& outNewTimeout); virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel); virtual nsecs_t getKeyRepeatTimeout(); + virtual nsecs_t getKeyRepeatDelay(); virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets); virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, @@ -283,6 +290,12 @@ private: nsecs_t dispatchingTimeout; int32_t frameLeft; int32_t frameTop; + int32_t frameRight; + int32_t frameBottom; + int32_t visibleFrameLeft; + int32_t visibleFrameTop; + int32_t visibleFrameRight; + int32_t visibleFrameBottom; int32_t touchableAreaLeft; int32_t touchableAreaTop; int32_t touchableAreaRight; @@ -294,10 +307,8 @@ private: int32_t ownerPid; int32_t ownerUid; - inline bool touchableAreaContainsPoint(int32_t x, int32_t y) { - return x >= touchableAreaLeft && x <= touchableAreaRight - && y >= touchableAreaTop && y <= touchableAreaBottom; - } + bool visibleFrameIntersects(const InputWindow* other) const; + bool touchableAreaContainsPoint(int32_t x, int32_t y) const; }; struct InputApplication { @@ -370,9 +381,13 @@ private: // Focus tracking for touch. bool mTouchDown; InputWindow* mTouchedWindow; // primary target for current down + bool mTouchedWindowIsObscured; // true if other windows may obscure the target Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets - - Vector<InputWindow*> mTempTouchedOutsideWindows; // temporary outside touch targets + struct OutsideTarget { + InputWindow* window; + bool obscured; + }; + Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets // Focused application. @@ -391,6 +406,7 @@ private: int32_t waitForTouchedWindowLd(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets, InputWindow*& outTouchedWindow); + bool isWindowObscuredLocked(const InputWindow* window); void releaseTouchedWindowLd(); @@ -996,6 +1012,10 @@ nsecs_t NativeInputManager::getKeyRepeatTimeout() { } } +nsecs_t NativeInputManager::getKeyRepeatDelay() { + return milliseconds_to_nanoseconds(50); +} + int32_t NativeInputManager::getMaxEventsPerSecond() { if (mMaxEventsPerSecond < 0) { JNIEnv* env = jniEnv(); @@ -1117,6 +1137,18 @@ bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj, gInputWindowClassInfo.frameLeft); jint frameTop = env->GetIntField(windowObj, gInputWindowClassInfo.frameTop); + jint frameRight = env->GetIntField(windowObj, + gInputWindowClassInfo.frameRight); + jint frameBottom = env->GetIntField(windowObj, + gInputWindowClassInfo.frameBottom); + jint visibleFrameLeft = env->GetIntField(windowObj, + gInputWindowClassInfo.visibleFrameLeft); + jint visibleFrameTop = env->GetIntField(windowObj, + gInputWindowClassInfo.visibleFrameTop); + jint visibleFrameRight = env->GetIntField(windowObj, + gInputWindowClassInfo.visibleFrameRight); + jint visibleFrameBottom = env->GetIntField(windowObj, + gInputWindowClassInfo.visibleFrameBottom); jint touchableAreaLeft = env->GetIntField(windowObj, gInputWindowClassInfo.touchableAreaLeft); jint touchableAreaTop = env->GetIntField(windowObj, @@ -1144,6 +1176,12 @@ bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj, outWindow.dispatchingTimeout = dispatchingTimeoutNanos; outWindow.frameLeft = frameLeft; outWindow.frameTop = frameTop; + outWindow.frameRight = frameRight; + outWindow.frameBottom = frameBottom; + outWindow.visibleFrameLeft = visibleFrameLeft; + outWindow.visibleFrameTop = visibleFrameTop; + outWindow.visibleFrameRight = visibleFrameRight; + outWindow.visibleFrameBottom = visibleFrameBottom; outWindow.touchableAreaLeft = touchableAreaLeft; outWindow.touchableAreaTop = touchableAreaTop; outWindow.touchableAreaRight = touchableAreaRight; @@ -1417,11 +1455,12 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin /* Case 1: ACTION_DOWN */ InputWindow* newTouchedWindow = NULL; - mTempTouchedOutsideWindows.clear(); + mTempTouchedOutsideTargets.clear(); int32_t x = int32_t(motionEvent->getX(0)); int32_t y = int32_t(motionEvent->getY(0)); InputWindow* topErrorWindow = NULL; + bool obscured = false; // Traverse windows from front to back to find touched window and outside targets. size_t numWindows = mWindows.size(); @@ -1442,13 +1481,17 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin if (isTouchModal || window->touchableAreaContainsPoint(x, y)) { if (! screenWasOff || flags & FLAG_TOUCHABLE_WHEN_WAKING) { newTouchedWindow = window; + obscured = isWindowObscuredLocked(window); } break; // found touched window, exit window loop } } if (flags & FLAG_WATCH_OUTSIDE_TOUCH) { - mTempTouchedOutsideWindows.push(window); + OutsideTarget outsideTarget; + outsideTarget.window = window; + outsideTarget.obscured = isWindowObscuredLocked(window); + mTempTouchedOutsideTargets.push(outsideTarget); } } } @@ -1501,6 +1544,7 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin releaseTouchedWindowLd(); mTouchedWindow = newTouchedWindow; + mTouchedWindowIsObscured = obscured; if (newTouchedWindow->hasWallpaper) { mTouchedWallpaperWindows.appendVector(mWallpaperWindows); @@ -1557,21 +1601,31 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) { size_t numWallpaperWindows = mTouchedWallpaperWindows.size(); for (size_t i = 0; i < numWallpaperWindows; i++) { - addTarget(mTouchedWallpaperWindows[i], 0, 0, outTargets); + addTarget(mTouchedWallpaperWindows[i], + InputTarget::FLAG_WINDOW_IS_OBSCURED, 0, outTargets); } - size_t numOutsideWindows = mTempTouchedOutsideWindows.size(); - for (size_t i = 0; i < numOutsideWindows; i++) { - addTarget(mTempTouchedOutsideWindows[i], InputTarget::FLAG_OUTSIDE, 0, outTargets); + size_t numOutsideTargets = mTempTouchedOutsideTargets.size(); + for (size_t i = 0; i < numOutsideTargets; i++) { + const OutsideTarget& outsideTarget = mTempTouchedOutsideTargets[i]; + int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE; + if (outsideTarget.obscured) { + outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } + addTarget(outsideTarget.window, outsideTargetFlags, 0, outTargets); } - addTarget(mTouchedWindow, InputTarget::FLAG_SYNC, + int32_t targetFlags = InputTarget::FLAG_SYNC; + if (mTouchedWindowIsObscured) { + targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; + } + addTarget(mTouchedWindow, targetFlags, anrTimer.getTimeSpentWaitingForApplication(), outTargets); outTouchedWindow = mTouchedWindow; } else { outTouchedWindow = NULL; } - mTempTouchedOutsideWindows.clear(); + mTempTouchedOutsideTargets.clear(); // Check injection permission once and for all. if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) { @@ -1616,6 +1670,7 @@ int32_t NativeInputManager::waitForTouchedWindowLd(MotionEvent* motionEvent, uin void NativeInputManager::releaseTouchedWindowLd() { mTouchedWindow = NULL; + mTouchedWindowIsObscured = false; mTouchedWallpaperWindows.clear(); } @@ -1661,6 +1716,20 @@ bool NativeInputManager::checkInjectionPermission(const InputWindow* window, return true; } +bool NativeInputManager::isWindowObscuredLocked(const InputWindow* window) { + size_t numWindows = mWindows.size(); + for (size_t i = 0; i < numWindows; i++) { + const InputWindow* other = & mWindows.itemAt(i); + if (other == window) { + break; + } + if (other->visible && window->visibleFrameIntersects(other)) { + return true; + } + } + return false; +} + int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) { #if DEBUG_INPUT_DISPATCHER_POLICY @@ -1935,12 +2004,17 @@ void NativeInputManager::dumpDispatchStateLd(String8& dump) { for (size_t i = 0; i < mWindows.size(); i++) { dump.appendFormat(" windows[%d]: '%s', paused=%d, hasFocus=%d, hasWallpaper=%d, " "visible=%d, flags=0x%08x, type=0x%08x, " - "frame=[%d,%d], touchableArea=[%d,%d][%d,%d], " + "frame=[%d,%d][%d,%d], " + "visibleFrame=[%d,%d][%d,%d], " + "touchableArea=[%d,%d][%d,%d], " "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", i, mWindows[i].inputChannel->getName().string(), mWindows[i].paused, mWindows[i].hasFocus, mWindows[i].hasWallpaper, mWindows[i].visible, mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType, mWindows[i].frameLeft, mWindows[i].frameTop, + mWindows[i].frameRight, mWindows[i].frameBottom, + mWindows[i].visibleFrameLeft, mWindows[i].visibleFrameTop, + mWindows[i].visibleFrameRight, mWindows[i].visibleFrameBottom, mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop, mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom, mWindows[i].ownerPid, mWindows[i].ownerUid, @@ -1955,6 +2029,20 @@ void NativeInputManager::dumpDispatchStateLd(String8& dump) { // ---------------------------------------------------------------------------- +bool NativeInputManager::InputWindow::visibleFrameIntersects(const InputWindow* other) const { + return visibleFrameRight > other->visibleFrameLeft + && visibleFrameLeft < other->visibleFrameRight + && visibleFrameBottom > other->visibleFrameTop + && visibleFrameTop < other->visibleFrameBottom; +} + +bool NativeInputManager::InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const { + return x >= touchableAreaLeft && x <= touchableAreaRight + && y >= touchableAreaTop && y <= touchableAreaBottom; +} + +// ---------------------------------------------------------------------------- + NativeInputManager::ANRTimer::ANRTimer() : mBudget(APPLICATION), mStartTime(now()), mFrozen(false), mPausedWindow(NULL) { } @@ -2507,6 +2595,24 @@ int register_android_server_InputManager(JNIEnv* env) { GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz, "frameTop", "I"); + GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz, + "frameRight", "I"); + + GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz, + "frameBottom", "I"); + + GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz, + "visibleFrameLeft", "I"); + + GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz, + "visibleFrameTop", "I"); + + GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz, + "visibleFrameRight", "I"); + + GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz, + "visibleFrameBottom", "I"); + GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz, "touchableAreaLeft", "I"); diff --git a/telephony/java/com/android/internal/telephony/CallManager.java b/telephony/java/com/android/internal/telephony/CallManager.java index c1232e8..caec7e1 100644 --- a/telephony/java/com/android/internal/telephony/CallManager.java +++ b/telephony/java/com/android/internal/telephony/CallManager.java @@ -466,6 +466,33 @@ public final class CallManager { } /** + * Hangup foreground call and resume the specific background call + * + * Note: this is noop if there is no foreground call or the heldCall is null + * + * @param heldCall to become foreground + * @throws CallStateException + */ + public void hangupForegroundResumeBackground(Call heldCall) throws CallStateException { + Phone foregroundPhone = null; + Phone backgroundPhone = null; + + if (hasActiveFgCall()) { + foregroundPhone = getFgPhone(); + if (heldCall != null) { + backgroundPhone = heldCall.getPhone(); + if (foregroundPhone == backgroundPhone) { + getActiveFgCall().hangup(); + } else { + // the call to be hangup and resumed belongs to different phones + getActiveFgCall().hangup(); + switchHoldingAndActive(heldCall); + } + } + } + } + + /** * Whether or not the phone can conference in the current phone * state--that is, one call holding and one call active. * @return true if the phone can conference; false otherwise. diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java index 8a5a6ae..5fef6de 100644 --- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java @@ -57,7 +57,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * @param destPort the port to deliver the message to * @param data the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is sucessfully sent, or failed. + * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> @@ -67,7 +67,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the extra "errorCode" containing a radio technology specific value, * generally only useful for troubleshooting.<br> * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, + * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The @@ -94,7 +94,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * the current default SMSC * @param text the body of the message to send * @param sentIntent if not NULL this <code>PendingIntent</code> is - * broadcast when the message is sucessfully sent, or failed. + * broadcast when the message is successfully sent, or failed. * The result code will be <code>Activity.RESULT_OK<code> for success, * or one of these errors:<br> * <code>RESULT_ERROR_GENERIC_FAILURE</code><br> @@ -140,7 +140,7 @@ public abstract class IccSmsInterfaceManager extends ISms.Stub { * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, + * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntents if not null, an <code>ArrayList</code> of * <code>PendingIntent</code>s (one for each message part) that is diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 606b52d..917e1d8 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -32,9 +32,11 @@ import android.database.Cursor; import android.database.SQLException; import android.net.Uri; import android.os.AsyncResult; +import android.os.Environment; import android.os.Handler; import android.os.Message; import android.os.PowerManager; +import android.os.StatFs; import android.provider.Telephony; import android.provider.Telephony.Sms.Intents; import android.provider.Settings; @@ -240,11 +242,9 @@ public abstract class SMSDispatcher extends Handler { // Register for device storage intents. Use these to notify the RIL // that storage for SMS is or is not available. - // TODO: Revisit this for a later release. Storage reporting should - // rely more on application indication. IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_LOW); - filter.addAction(Intent.ACTION_DEVICE_STORAGE_OK); + filter.addAction(Intent.ACTION_DEVICE_STORAGE_FULL); + filter.addAction(Intent.ACTION_DEVICE_STORAGE_NOT_FULL); mContext.registerReceiver(mResultReceiver, filter); } @@ -679,7 +679,7 @@ public abstract class SMSDispatcher extends Handler { * the extra "errorCode" containing a radio technology specific value, * generally only useful for troubleshooting.<br> * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, + * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is delivered to the recipient. The @@ -732,7 +732,7 @@ public abstract class SMSDispatcher extends Handler { * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, + * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntents if not null, an <code>ArrayList</code> of * <code>PendingIntent</code>s (one for each message part) that is @@ -748,7 +748,7 @@ public abstract class SMSDispatcher extends Handler { * Send a SMS * * @param smsc the SMSC to send the message through, or NULL for the - * defatult SMSC + * default SMSC * @param pdu the raw PDU to send * @param sentIntent if not NULL this <code>Intent</code> is * broadcast when the message is successfully sent, or failed. @@ -758,7 +758,7 @@ public abstract class SMSDispatcher extends Handler { * <code>RESULT_ERROR_RADIO_OFF</code> * <code>RESULT_ERROR_NULL_PDU</code>. * The per-application based SMS control checks sentIntent. If sentIntent - * is NULL the caller will be checked against all unknown applicaitons, + * is NULL the caller will be checked against all unknown applications, * which cause smaller number of SMS to be sent in checking period. * @param deliveryIntent if not NULL this <code>Intent</code> is * broadcast when the message is delivered to the recipient. The @@ -965,10 +965,10 @@ public abstract class SMSDispatcher extends Handler { private BroadcastReceiver mResultReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_LOW)) { + if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_FULL)) { mStorageAvailable = false; mCm.reportSmsMemoryStatus(false, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); - } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_OK)) { + } else if (intent.getAction().equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) { mStorageAvailable = true; mCm.reportSmsMemoryStatus(true, obtainMessage(EVENT_REPORT_MEMORY_STATUS_DONE)); } else { diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index 4508e9a..f48c956 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -100,7 +100,6 @@ public class CDMAPhone extends PhoneBase { CdmaCallTracker mCT; CdmaSMSDispatcher mSMS; CdmaServiceStateTracker mSST; - RuimFileHandler mRuimFileHandler; RuimRecords mRuimRecords; RuimCard mRuimCard; ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>(); @@ -158,7 +157,7 @@ public class CDMAPhone extends PhoneBase { mDataConnection = new CdmaDataConnectionTracker (this); mRuimCard = new RuimCard(this); mRuimPhoneBookInterfaceManager = new RuimPhoneBookInterfaceManager(this); - mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this); + mRuimSmsInterfaceManager = new RuimSmsInterfaceManager(this, mSMS); mSubInfo = new PhoneSubInfo(this); mEriManager = new EriManager(this, context, EriManager.ERI_FROM_XML); diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java index cfcfd98..e97549d 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimSmsInterfaceManager.java @@ -27,6 +27,7 @@ import com.android.internal.telephony.IccConstants; import com.android.internal.telephony.IccSmsInterfaceManager; import com.android.internal.telephony.IccUtils; import com.android.internal.telephony.PhoneProxy; +import com.android.internal.telephony.SMSDispatcher; import com.android.internal.telephony.SmsRawData; import java.util.ArrayList; @@ -81,9 +82,9 @@ public class RuimSmsInterfaceManager extends IccSmsInterfaceManager { } }; - public RuimSmsInterfaceManager(CDMAPhone phone) { + public RuimSmsInterfaceManager(CDMAPhone phone, SMSDispatcher dispatcher) { super(phone); - mDispatcher = new CdmaSMSDispatcher(phone); + mDispatcher = dispatcher; } public void dispose() { diff --git a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java index e5ca519..689a972 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java +++ b/telephony/java/com/android/internal/telephony/gsm/GSMPhone.java @@ -117,10 +117,6 @@ public class GSMPhone extends PhoneBase { Thread debugPortThread; ServerSocket debugSocket; - private int mReportedRadioResets; - private int mReportedAttemptedConnects; - private int mReportedSuccessfulConnects; - private String mImei; private String mImeiSv; private String mVmNumber; @@ -151,7 +147,7 @@ public class GSMPhone extends PhoneBase { mSimCard = new SimCard(this); if (!unitTestMode) { mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); - mSimSmsIntManager = new SimSmsInterfaceManager(this); + mSimSmsIntManager = new SimSmsInterfaceManager(this, mSMS); mSubInfo = new PhoneSubInfo(this); } mStkService = StkService.getInstance(mCM, mSIMRecords, mContext, diff --git a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java index 2028ca4..67ecc77 100644 --- a/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java +++ b/telephony/java/com/android/internal/telephony/gsm/SimSmsInterfaceManager.java @@ -25,6 +25,7 @@ import android.util.Log; import com.android.internal.telephony.IccConstants; import com.android.internal.telephony.IccSmsInterfaceManager; import com.android.internal.telephony.IccUtils; +import com.android.internal.telephony.SMSDispatcher; import com.android.internal.telephony.SmsRawData; import java.util.ArrayList; @@ -78,9 +79,9 @@ public class SimSmsInterfaceManager extends IccSmsInterfaceManager { } }; - public SimSmsInterfaceManager(GSMPhone phone) { + public SimSmsInterfaceManager(GSMPhone phone, SMSDispatcher dispatcher) { super(phone); - mDispatcher = new GsmSMSDispatcher(phone); + mDispatcher = dispatcher; } public void dispose() { diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp index bb45a9a..3433dcf 100644 --- a/voip/jni/rtp/AudioGroup.cpp +++ b/voip/jni/rtp/AudioGroup.cpp @@ -588,7 +588,7 @@ bool AudioGroup::set(int sampleRate, int sampleCount) // Give device socket a reasonable timeout and buffer size. timeval tv; tv.tv_sec = 0; - tv.tv_usec = 1000 * sampleCount / sampleRate * 1000; + tv.tv_usec = 1000 * sampleCount / sampleRate * 500; if (setsockopt(pair[0], SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) || setsockopt(pair[0], SOL_SOCKET, SO_RCVBUF, &output, sizeof(output)) || setsockopt(pair[1], SOL_SOCKET, SO_SNDBUF, &output, sizeof(output))) { @@ -793,7 +793,7 @@ bool AudioGroup::deviceLoop() status_t status = mRecord.obtainBuffer(&buffer, 1); if (status == NO_ERROR) { - int count = (buffer.frameCount < toRead) ? + int count = ((int)buffer.frameCount < toRead) ? buffer.frameCount : toRead; memcpy(&input[mSampleCount - toRead], buffer.i8, count * 2); toRead -= count; |
