diff options
96 files changed, 1060 insertions, 780 deletions
diff --git a/api/current.txt b/api/current.txt index 8f505ccdadce..f06d99f0baf4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2684,6 +2684,7 @@ package android.app { method public final boolean isChild(); method public boolean isDestroyed(); method public boolean isFinishing(); + method public boolean isImmersive(); method public boolean isTaskRoot(); method public final deprecated android.database.Cursor managedQuery(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String); method public boolean moveTaskToBack(boolean); @@ -2771,6 +2772,7 @@ package android.app { method public final void setFeatureDrawableResource(int, int); method public final void setFeatureDrawableUri(int, android.net.Uri); method public void setFinishOnTouchOutside(boolean); + method public void setImmersive(boolean); method public void setIntent(android.content.Intent); method public final void setProgress(int); method public final void setProgressBarIndeterminate(boolean); @@ -6331,6 +6333,7 @@ package android.content.pm { field public static final int FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS = 256; // 0x100 field public static final int FLAG_FINISH_ON_TASK_LAUNCH = 2; // 0x2 field public static final int FLAG_HARDWARE_ACCELERATED = 512; // 0x200 + field public static final int FLAG_IMMERSIVE = 2048; // 0x800 field public static final int FLAG_MULTIPROCESS = 1; // 0x1 field public static final int FLAG_NO_HISTORY = 128; // 0x80 field public static final int FLAG_SINGLE_USER = 1073741824; // 0x40000000 @@ -13560,6 +13563,7 @@ package android.net.wifi.p2p { ctor public WifiP2pDeviceList(); ctor public WifiP2pDeviceList(android.net.wifi.p2p.WifiP2pDeviceList); method public int describeContents(); + method public android.net.wifi.p2p.WifiP2pDevice get(java.lang.String); method public java.util.Collection<android.net.wifi.p2p.WifiP2pDevice> getDeviceList(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; @@ -13615,7 +13619,9 @@ package android.net.wifi.p2p { field public static final int ERROR = 0; // 0x0 field public static final java.lang.String EXTRA_DISCOVERY_STATE = "discoveryState"; field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; + field public static final java.lang.String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList"; field public static final java.lang.String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice"; + field public static final java.lang.String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo"; field public static final java.lang.String EXTRA_WIFI_P2P_INFO = "wifiP2pInfo"; field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_p2p_state"; field public static final int NO_SERVICE_REQUESTS = 3; // 0x3 @@ -41391,8 +41397,8 @@ package java.util.zip { public class ZipFile { ctor public ZipFile(java.io.File) throws java.io.IOException, java.util.zip.ZipException; - ctor public ZipFile(java.io.File, int) throws java.io.IOException; ctor public ZipFile(java.lang.String) throws java.io.IOException; + ctor public ZipFile(java.io.File, int) throws java.io.IOException; method public void close() throws java.io.IOException; method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries(); method public java.util.zip.ZipEntry getEntry(java.lang.String); diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index ecf3b19c12e3..7efe189fe015 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -557,7 +557,7 @@ public abstract class AccessibilityService extends Service { public IAccessibilityServiceClientWrapper(Context context, Looper looper, Callbacks callback) { mCallback = callback; - mCaller = new HandlerCaller(context, looper, this); + mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/); } public void setConnection(IAccessibilityServiceConnection connection, int connectionId) { diff --git a/core/java/android/accounts/AccountAuthenticatorResponse.java b/core/java/android/accounts/AccountAuthenticatorResponse.java index 614e13965394..41f26ac164b7 100644 --- a/core/java/android/accounts/AccountAuthenticatorResponse.java +++ b/core/java/android/accounts/AccountAuthenticatorResponse.java @@ -33,7 +33,7 @@ public class AccountAuthenticatorResponse implements Parcelable { /** * @hide */ - /* package private */ AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) { + public AccountAuthenticatorResponse(IAccountAuthenticatorResponse response) { mAccountAuthenticatorResponse = response; } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 5dc9da285ee9..cbeffc1b8008 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2544,7 +2544,7 @@ public class Activity extends ContextThemeWrapper // Put event logging here so it gets called even if subclass // doesn't call through to superclass's implmeentation of each // of these methods below - EventLog.writeEvent(50000, 0, item.getTitleCondensed()); + EventLog.writeEvent(50000, 0, item.getTitleCondensed().toString()); if (onOptionsItemSelected(item)) { return true; } @@ -2562,7 +2562,7 @@ public class Activity extends ContextThemeWrapper return false; case Window.FEATURE_CONTEXT_MENU: - EventLog.writeEvent(50000, 1, item.getTitleCondensed()); + EventLog.writeEvent(50000, 1, item.getTitleCondensed().toString()); if (onContextItemSelected(item)) { return true; } @@ -4818,8 +4818,8 @@ public class Activity extends ContextThemeWrapper * <code>android:immersive</code> but may be changed at runtime by * {@link #setImmersive}. * + * @see #setImmersive(boolean) * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE - * @hide */ public boolean isImmersive() { try { @@ -4831,7 +4831,7 @@ public class Activity extends ContextThemeWrapper /** * Adjust the current immersive mode setting. - * + * * Note that changing this value will have no effect on the activity's * {@link android.content.pm.ActivityInfo} structure; that is, if * <code>android:immersive</code> is set to <code>true</code> @@ -4840,9 +4840,8 @@ public class Activity extends ContextThemeWrapper * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE * FLAG_IMMERSIVE} bit set. * - * @see #isImmersive + * @see #isImmersive() * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE - * @hide */ public void setImmersive(boolean i) { try { diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index b20cf8839119..e34c827d290e 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -116,6 +116,10 @@ public abstract class ContentResolver { */ public static final String SYNC_EXTRAS_INITIALIZE = "initialize"; + /** @hide */ + public static final Intent ACTION_SYNC_CONN_STATUS_CHANGED = + new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); + public static final String SCHEME_CONTENT = "content"; public static final String SCHEME_ANDROID_RESOURCE = "android.resource"; public static final String SCHEME_FILE = "file"; @@ -181,7 +185,7 @@ public abstract class ContentResolver { }; /** @hide */ - static String syncErrorToString(int error) { + public static String syncErrorToString(int error) { if (error < 1 || error > SYNC_ERROR_NAMES.length) { return String.valueOf(error); } diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java index 17813ec3aaf0..513a556429e9 100644 --- a/core/java/android/content/PeriodicSync.java +++ b/core/java/android/content/PeriodicSync.java @@ -79,6 +79,25 @@ public class PeriodicSync implements Parcelable { return account.equals(other.account) && authority.equals(other.authority) && period == other.period - && SyncStorageEngine.equals(extras, other.extras); + && syncExtrasEquals(extras, other.extras); + } + + /** {@hide} */ + public static boolean syncExtrasEquals(Bundle b1, Bundle b2) { + if (b1.size() != b2.size()) { + return false; + } + if (b1.isEmpty()) { + return true; + } + for (String key : b1.keySet()) { + if (!b2.containsKey(key)) { + return false; + } + if (!b1.get(key).equals(b2.get(key))) { + return false; + } + } + return true; } } diff --git a/core/java/android/content/SyncAdaptersCache.java b/core/java/android/content/SyncAdaptersCache.java index 7b643a0801cb..8bb3ee7f178b 100644 --- a/core/java/android/content/SyncAdaptersCache.java +++ b/core/java/android/content/SyncAdaptersCache.java @@ -31,7 +31,7 @@ import java.io.IOException; * A cache of services that export the {@link android.content.ISyncAdapter} interface. * @hide */ -/* package private */ class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> { +public class SyncAdaptersCache extends RegisteredServicesCache<SyncAdapterType> { private static final String TAG = "Account"; private static final String SERVICE_INTERFACE = "android.content.SyncAdapter"; @@ -39,7 +39,7 @@ import java.io.IOException; private static final String ATTRIBUTES_NAME = "sync-adapter"; private static final MySerializer sSerializer = new MySerializer(); - SyncAdaptersCache(Context context) { + public SyncAdaptersCache(Context context) { super(context, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, sSerializer); } diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java index abfe964fa44c..0284882963c7 100644 --- a/core/java/android/content/SyncInfo.java +++ b/core/java/android/content/SyncInfo.java @@ -46,7 +46,7 @@ public class SyncInfo implements Parcelable { public final long startTime; /** @hide */ - SyncInfo(int authorityId, Account account, String authority, + public SyncInfo(int authorityId, Account account, String authority, long startTime) { this.authorityId = authorityId; this.account = account; diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java index bb2b2dace8bf..49e3e353c0e5 100644 --- a/core/java/android/content/SyncStatusInfo.java +++ b/core/java/android/content/SyncStatusInfo.java @@ -46,7 +46,7 @@ public class SyncStatusInfo implements Parcelable { private static final String TAG = "Sync"; - SyncStatusInfo(int authorityId) { + public SyncStatusInfo(int authorityId) { this.authorityId = authorityId; } @@ -92,7 +92,7 @@ public class SyncStatusInfo implements Parcelable { } } - SyncStatusInfo(Parcel parcel) { + public SyncStatusInfo(Parcel parcel) { int version = parcel.readInt(); if (version != VERSION && version != 1) { Log.w("SyncStatusInfo", "Unknown version: " + version); diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index e2ca1ddea376..8f3b62d8f21c 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -161,7 +161,6 @@ public class ActivityInfo extends ComponentInfo */ public static final int FLAG_SHOW_ON_LOCK_SCREEN = 0x0400; /** - * @hide * Bit in {@link #flags} corresponding to an immersive activity * that wishes not to be interrupted by notifications. * Applications that hide the system notification bar with @@ -174,7 +173,14 @@ public class ActivityInfo extends ComponentInfo * {@link #FLAG_IMMERSIVE} set, however, will not be interrupted; the * notification may be shown in some other way (such as a small floating * "toast" window). - * {@see android.app.Notification#FLAG_HIGH_PRIORITY} + * + * Note that this flag will always reflect the Activity's + * <code>android:immersive</code> manifest definition, even if the Activity's + * immersive state is changed at runtime via + * {@link android.app.Activity#setImmersive(boolean)}. + * + * @see android.app.Notification#FLAG_HIGH_PRIORITY + * @see android.app.Activity#setImmersive(boolean) */ public static final int FLAG_IMMERSIVE = 0x0800; /** diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index 5324f81794f1..d78262b6aacd 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -70,7 +70,8 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub public IInputMethodSessionWrapper(Context context, InputMethodSession inputMethodSession) { - mCaller = new HandlerCaller(context, this); + mCaller = new HandlerCaller(context, null, + this, true /*asyncHandler*/); mInputMethodSession = inputMethodSession; } diff --git a/core/java/android/inputmethodservice/IInputMethodWrapper.java b/core/java/android/inputmethodservice/IInputMethodWrapper.java index 5275314b036a..2d67875c6084 100644 --- a/core/java/android/inputmethodservice/IInputMethodWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodWrapper.java @@ -102,7 +102,8 @@ class IInputMethodWrapper extends IInputMethod.Stub public IInputMethodWrapper(AbstractInputMethodService context, InputMethod inputMethod) { mTarget = new WeakReference<AbstractInputMethodService>(context); - mCaller = new HandlerCaller(context.getApplicationContext(), this); + mCaller = new HandlerCaller(context.getApplicationContext(), null, + this, true /*asyncHandler*/); mInputMethod = new WeakReference<InputMethod>(inputMethod); mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index dc089bdcdf58..4dbc4b4fa0fd 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4296,6 +4296,13 @@ public final class Settings { public static final String POWER_SOUNDS_ENABLED = "power_sounds_enabled"; /** + * URI for the "wireless charging started" sound. + * @hide + */ + public static final String WIRELESS_CHARGING_STARTED_SOUND = + "wireless_charging_started_sound"; + + /** * Whether we keep the device on while the device is plugged in. * Supported values are: * <ul> diff --git a/core/java/android/server/package.html b/core/java/android/server/package.html deleted file mode 100644 index c9f96a66ab3b..000000000000 --- a/core/java/android/server/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> diff --git a/core/java/android/server/search/package.html b/core/java/android/server/search/package.html deleted file mode 100644 index c9f96a66ab3b..000000000000 --- a/core/java/android/server/search/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 500bb2c8dc5a..9dc77b909d08 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -960,7 +960,7 @@ public abstract class WallpaperService extends Service { IWallpaperEngineWrapper(WallpaperService context, IWallpaperConnection conn, IBinder windowToken, int windowType, boolean isPreview, int reqWidth, int reqHeight) { - mCaller = new HandlerCaller(context, context.getMainLooper(), this); + mCaller = new HandlerCaller(context, context.getMainLooper(), this, true); mConnection = conn; mWindowToken = windowToken; mWindowType = windowType; diff --git a/core/java/android/view/SimulatedTrackball.java b/core/java/android/view/SimulatedTrackball.java index b9173718c105..0eb197e6be33 100644 --- a/core/java/android/view/SimulatedTrackball.java +++ b/core/java/android/view/SimulatedTrackball.java @@ -40,7 +40,7 @@ class SimulatedTrackball { private static final int MAX_TAP_TIME = 250; // Where the cutoff is for determining an edge swipe private static final float EDGE_SWIPE_THRESHOLD = 0.9f; - private static final int FLICK_MSG_ID = 313; + private static final int MSG_FLICK = 313; // TODO: Pass touch slop from the input device private static final int TOUCH_SLOP = 30; @@ -75,8 +75,11 @@ class SimulatedTrackball { // Has the TouchSlop constraint been invalidated private boolean mAlwaysInTapRegion = true; - // Most recent event. Used to determine what device sent the event. - private MotionEvent mRecentEvent; + // Information from the most recent event. + // Used to determine what device sent the event during a fling. + private int mLastSource; + private int mLastMetaState; + private int mLastDeviceId; // TODO: Currently using screen dimensions tuned to a Galaxy Nexus, need to // read this from a config file instead @@ -101,33 +104,34 @@ class SimulatedTrackball { mTouchSlopSquared = mTouchSlop * mTouchSlop; } - private final Handler mHandler = new Handler(new Callback() { + private final Handler mHandler = new Handler(true /*async*/) { @Override - public boolean handleMessage(Message msg) { - if (msg.what != FLICK_MSG_ID) - return false; + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_FLICK: { + final long time = SystemClock.uptimeMillis(); + ViewRootImpl viewroot = (ViewRootImpl) msg.obj; + // Send the key + viewroot.enqueueInputEvent(new KeyEvent(time, time, + KeyEvent.ACTION_DOWN, msg.arg2, 0, mLastMetaState, + mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource)); + viewroot.enqueueInputEvent(new KeyEvent(time, time, + KeyEvent.ACTION_UP, msg.arg2, 0, mLastMetaState, + mLastDeviceId, 0, KeyEvent.FLAG_FALLBACK, mLastSource)); - final long time = SystemClock.uptimeMillis(); - ViewRootImpl viewroot = (ViewRootImpl) msg.obj; - // Send the key - viewroot.enqueueInputEvent(new KeyEvent(time, time, - KeyEvent.ACTION_DOWN, msg.arg2, 0, mRecentEvent.getMetaState(), - mRecentEvent.getDeviceId(), 0, - KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource())); - viewroot.enqueueInputEvent(new KeyEvent(time, time, - KeyEvent.ACTION_UP, msg.arg2, 0, mRecentEvent.getMetaState(), - mRecentEvent.getDeviceId(), 0, - KeyEvent.FLAG_FALLBACK, mRecentEvent.getSource())); - Message msgCopy = Message.obtain(msg); - // Increase the delay by the decay factor - msgCopy.arg1 = (int) Math.ceil(mFlickDecay * msgCopy.arg1); - if (msgCopy.arg1 <= mMaxRepeatDelay) { - // Send the key again in arg1 milliseconds - mHandler.sendMessageDelayed(msgCopy, msgCopy.arg1); + // Increase the delay by the decay factor and resend + final int delay = (int) Math.ceil(mFlickDecay * msg.arg1); + if (delay <= mMaxRepeatDelay) { + Message msgCopy = Message.obtain(msg); + msgCopy.arg1 = delay; + msgCopy.setAsynchronous(true); + mHandler.sendMessageDelayed(msgCopy, delay); + } + break; + } } - return false; } - }); + }; public void updateTrackballDirection(ViewRootImpl viewroot, MotionEvent event) { // Store what time the touchpad event occurred @@ -148,7 +152,7 @@ class SimulatedTrackball { mEdgeSwipePossible = true; } // Clear any flings - mHandler.removeMessages(FLICK_MSG_ID); + mHandler.removeMessages(MSG_FLICK); break; case MotionEvent.ACTION_MOVE: @@ -245,15 +249,20 @@ class SimulatedTrackball { if (mMinFlickDistanceSquared <= xMoveSquared + yMoveSquared && time - mLastTouchPadEventTimeMs <= MAX_TAP_TIME && mKeySendRateMs <= mMaxRepeatDelay && mKeySendRateMs > 0) { - Message message = Message.obtain(mHandler, FLICK_MSG_ID, + mLastDeviceId = event.getDeviceId(); + mLastSource = event.getSource(); + mLastMetaState = event.getMetaState(); + + Message message = Message.obtain(mHandler, MSG_FLICK, mKeySendRateMs, mLastKeySent, viewroot); - mRecentEvent = event; + message.setAsynchronous(true); mHandler.sendMessageDelayed(message, mKeySendRateMs); } } mEdgeSwipePossible = false; break; } + // Store touch event position and time mLastTouchPadEventTimeMs = time; mLastTouchpadXPosition = event.getX(); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 61ecc314c5f3..080e7c0543b0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17332,6 +17332,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <li>{@link android.view.View.MeasureSpec#AT_MOST}</li> * </ul> * + * <p><strong>Note:</strong> On API level 17 and lower, makeMeasureSpec's + * implementation was such that the order of arguments did not matter + * and overflow in either value could impact the resulting MeasureSpec. + * {@link android.widget.RelativeLayout} was affected by this bug. + * Apps targeting API levels greater than 17 will get the fixed, more strict + * behavior.</p> + * * @param size the size of the measure specification * @param mode the mode of the measure specification * @return the measure specification based on size and mode diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index a6b7dba78441..57bf0d3aee92 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -3416,13 +3416,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchModeReset = new Runnable() { @Override public void run() { + mTouchModeReset = null; mTouchMode = TOUCH_MODE_REST; child.setPressed(false); setPressed(false); if (!mDataChanged) { performClick.run(); } - mTouchModeReset = null; } }; postDelayed(mTouchModeReset, diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java index f279f8e39547..a3791574df51 100644 --- a/core/java/android/widget/AbsSpinner.java +++ b/core/java/android/widget/AbsSpinner.java @@ -375,7 +375,7 @@ public abstract class AbsSpinner extends AdapterView<SpinnerAdapter> { /** * Constructor called from {@link #CREATOR} */ - private SavedState(Parcel in) { + SavedState(Parcel in) { super(in); selectedId = in.readLong(); position = in.readInt(); diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java index e0c5bbd7e4ad..c4ef11c78e36 100644 --- a/core/java/android/widget/Gallery.java +++ b/core/java/android/widget/Gallery.java @@ -891,7 +891,7 @@ public class Gallery extends AbsSpinner implements GestureDetector.OnGestureList lp = (Gallery.LayoutParams) generateDefaultLayoutParams(); } - addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp); + addViewInLayout(child, fromLeft != mIsRtl ? -1 : 0, lp, true); child.setSelected(offset == 0); diff --git a/core/java/android/widget/HeaderViewListAdapter.java b/core/java/android/widget/HeaderViewListAdapter.java index e2a269ea13ef..0685e613c073 100644 --- a/core/java/android/widget/HeaderViewListAdapter.java +++ b/core/java/android/widget/HeaderViewListAdapter.java @@ -79,7 +79,8 @@ public class HeaderViewListAdapter implements WrapperListAdapter, Filterable { } public boolean isEmpty() { - return mAdapter == null || mAdapter.isEmpty(); + return (mAdapter == null || mAdapter.isEmpty()) + && getFootersCount() + getHeadersCount() == 0; } private boolean areAllListInfosSelectable(ArrayList<ListView.FixedViewInfo> infos) { diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index aa977a1810c9..b40260c0ade5 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -234,8 +234,15 @@ public class ImageView extends View { /** * Set this to true if you want the ImageView to adjust its bounds * to preserve the aspect ratio of its drawable. + * + * <p><strong>Note:</strong> If the application targets API level 17 or lower, + * adjustViewBounds will allow the drawable to shrink the view bounds, but not grow + * to fill available measured space in all cases. This is for compatibility with + * legacy {@link android.view.View.MeasureSpec MeasureSpec} and + * {@link android.widget.RelativeLayout RelativeLayout} behavior.</p> + * * @param adjustViewBounds Whether to adjust the bounds of this view - * to presrve the original aspect ratio of the drawable + * to preserve the original aspect ratio of the drawable. * * @see #getAdjustViewBounds() * diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 8a0928263d18..e749e63cae6d 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -54,6 +54,21 @@ import static android.util.Log.d; * {@link #ALIGN_PARENT_BOTTOM}. * </p> * + * <p><strong>Note:</strong> In platform version 17 and lower, RelativeLayout was affected by + * a measurement bug that could cause child views to be measured with incorrect + * {@link android.view.View.MeasureSpec MeasureSpec} values. (See + * {@link android.view.View.MeasureSpec#makeMeasureSpec(int, int) MeasureSpec.makeMeasureSpec} + * for more details.) This was triggered when a RelativeLayout container was placed in + * a scrolling container, such as a ScrollView or HorizontalScrollView. If a custom view + * not equipped to properly measure with the MeasureSpec mode + * {@link android.view.View.MeasureSpec#UNSPECIFIED UNSPECIFIED} was placed in a RelativeLayout, + * this would silently work anyway as RelativeLayout would pass a very large + * {@link android.view.View.MeasureSpec#AT_MOST AT_MOST} MeasureSpec instead.</p> + * + * <p>This behavior has been preserved for apps that set <code>android:targetSdkVersion="17"</code> + * or older in their manifest's <code>uses-sdk</code> tag for compatibility. Apps targeting SDK + * version 18 or newer will receive the correct behavior</p> + * * <p>See the <a href="{@docRoot}guide/topics/ui/layout/relative.html">Relative * Layout</a> guide.</p> * diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java index cd8638daab26..02816023ccfc 100644 --- a/core/java/android/widget/SearchView.java +++ b/core/java/android/widget/SearchView.java @@ -1247,6 +1247,7 @@ public class SearchView extends LinearLayout implements CollapsibleActionView { */ @Override public void onActionViewCollapsed() { + setQuery("", false); clearFocus(); updateViewsVisibility(true); mQueryTextView.setImeOptions(mCollapsedImeOptions); diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index 925864c9e311..fa64fd3b6760 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -25,6 +25,8 @@ import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.os.Parcel; +import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; @@ -697,6 +699,69 @@ public class Spinner extends AbsSpinner implements OnClickListener { return width; } + @Override + public Parcelable onSaveInstanceState() { + final SavedState ss = new SavedState(super.onSaveInstanceState()); + ss.showDropdown = mPopup != null && mPopup.isShowing(); + return ss; + } + + @Override + public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + + super.onRestoreInstanceState(ss.getSuperState()); + + if (ss.showDropdown) { + ViewTreeObserver vto = getViewTreeObserver(); + if (vto != null) { + final OnGlobalLayoutListener listener = new OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + if (!mPopup.isShowing()) { + mPopup.show(); + } + final ViewTreeObserver vto = getViewTreeObserver(); + if (vto != null) { + vto.removeOnGlobalLayoutListener(this); + } + } + }; + vto.addOnGlobalLayoutListener(listener); + } + } + } + + static class SavedState extends AbsSpinner.SavedState { + boolean showDropdown; + + SavedState(Parcelable superState) { + super(superState); + } + + private SavedState(Parcel in) { + super(in); + showDropdown = in.readByte() != 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeByte((byte) (showDropdown ? 1 : 0)); + } + + public static final Parcelable.Creator<SavedState> CREATOR = + new Parcelable.Creator<SavedState>() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + /** * <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance * into a ListAdapter.</p> @@ -941,8 +1006,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { mHintText = hintText; } - @Override - public void show() { + void computeContentWidth() { final Drawable background = getBackground(); int hOffset = 0; if (background != null) { @@ -955,6 +1019,7 @@ public class Spinner extends AbsSpinner implements OnClickListener { final int spinnerPaddingLeft = Spinner.this.getPaddingLeft(); final int spinnerPaddingRight = Spinner.this.getPaddingRight(); final int spinnerWidth = Spinner.this.getWidth(); + if (mDropDownWidth == WRAP_CONTENT) { int contentWidth = measureContentWidth( (SpinnerAdapter) mAdapter, getBackground()); @@ -977,11 +1042,25 @@ public class Spinner extends AbsSpinner implements OnClickListener { hOffset += spinnerPaddingLeft; } setHorizontalOffset(hOffset); + } + + @Override + public void show() { + final boolean wasShowing = isShowing(); + + computeContentWidth(); + setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED); super.show(); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); setSelection(Spinner.this.getSelectedItemPosition()); + if (wasShowing) { + // Skip setting up the layout/dismiss listener below. If we were previously + // showing it will still stick around. + return; + } + // Make sure we hide if our anchor goes away. // TODO: This might be appropriate to push all the way down to PopupWindow, // but it may have other side effects to investigate first. (Text editing handles, etc.) @@ -992,6 +1071,12 @@ public class Spinner extends AbsSpinner implements OnClickListener { public void onGlobalLayout() { if (!Spinner.this.isVisibleToUser()) { dismiss(); + } else { + computeContentWidth(); + + // Use super.show here to update; we don't want to move the selected + // position or adjust other things that would be reset otherwise. + DropdownPopup.super.show(); } } }; diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index 84699dcd4a0c..b442ff52f635 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -24,38 +24,32 @@ import android.os.Message; public class HandlerCaller { public final Context mContext; - + final Looper mMainLooper; final Handler mH; final Callback mCallback; class MyHandler extends Handler { - MyHandler(Looper looper) { - super(looper); + MyHandler(Looper looper, boolean async) { + super(looper, null, async); } - + @Override public void handleMessage(Message msg) { mCallback.executeMessage(msg); } } - + public interface Callback { public void executeMessage(Message msg); } - - public HandlerCaller(Context context, Callback callback) { - mContext = context; - mMainLooper = context.getMainLooper(); - mH = new MyHandler(mMainLooper); - mCallback = callback; - } - public HandlerCaller(Context context, Looper looper, Callback callback) { + public HandlerCaller(Context context, Looper looper, Callback callback, + boolean asyncHandler) { mContext = context; - mMainLooper = looper; - mH = new MyHandler(mMainLooper); + mMainLooper = looper != null ? looper : context.getMainLooper(); + mH = new MyHandler(mMainLooper, asyncHandler); mCallback = callback; } diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 6fb459c1b5ed..61bc002756d1 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -687,6 +687,7 @@ public class ActionBarView extends AbsActionBarView { if (mSpinner == null) { mSpinner = new Spinner(mContext, null, com.android.internal.R.attr.actionDropDownStyle); + mSpinner.setId(com.android.internal.R.id.action_bar_spinner); mListNavLayout = new LinearLayout(mContext, null, com.android.internal.R.attr.actionBarTabBarStyle); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 907b52aa7ef8..555c7c256e99 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -123,14 +123,14 @@ public class LockPatternUtils { */ public static final int ID_DEFAULT_STATUS_WIDGET = -2; - protected final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently"; - protected final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline"; - protected final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen"; + public final static String LOCKOUT_PERMANENT_KEY = "lockscreen.lockedoutpermanently"; + public final static String LOCKOUT_ATTEMPT_DEADLINE = "lockscreen.lockoutattemptdeadline"; + public final static String PATTERN_EVER_CHOSEN_KEY = "lockscreen.patterneverchosen"; public final static String PASSWORD_TYPE_KEY = "lockscreen.password_type"; public static final String PASSWORD_TYPE_ALTERNATE_KEY = "lockscreen.password_type_alternate"; - protected final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt"; - protected final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled"; - protected final static String LOCKSCREEN_OPTIONS = "lockscreen.options"; + public final static String LOCK_PASSWORD_SALT_KEY = "lockscreen.password_salt"; + public final static String DISABLE_LOCKSCREEN_KEY = "lockscreen.disabled"; + public final static String LOCKSCREEN_OPTIONS = "lockscreen.options"; public final static String LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK = "lockscreen.biometric_weak_fallback"; public final static String BIOMETRIC_WEAK_EVER_CHOSEN_KEY @@ -138,7 +138,7 @@ public class LockPatternUtils { public final static String LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS = "lockscreen.power_button_instantly_locks"; - protected final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory"; + public final static String PASSWORD_HISTORY_KEY = "lockscreen.passwordhistory"; private final Context mContext; private final ContentResolver mContentResolver; diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 842c55756c44..33150451d6b7 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -87,7 +87,7 @@ sp<ANativeWindow> android_SurfaceTexture_getNativeWindow( { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); sp<SurfaceTextureClient> surfaceTextureClient(surfaceTexture != NULL ? - new SurfaceTextureClient(surfaceTexture) : NULL); + new SurfaceTextureClient(surfaceTexture->getBufferQueue()) : NULL); return surfaceTextureClient; } diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index b1664c6690ad..2b265db32207 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -627,7 +627,11 @@ not_valid_surface: goto exit; } surfaceTexture = android::SurfaceTexture_getSurfaceTexture(_env, win); - window = new android::SurfaceTextureClient(surfaceTexture); + + if (surfaceTexture == NULL) + goto not_valid_surface; + + window = new android::SurfaceTextureClient(surfaceTexture->getBufferQueue()); if (window == NULL) goto not_valid_surface; diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index 9484c6b5798d..854c9ae2c95f 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -102,7 +102,7 @@ static void android_view_TextureView_createNativeWindow(JNIEnv* env, jobject tex jobject surface) { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface)); - sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture); + sp<ANativeWindow> window = new SurfaceTextureClient(surfaceTexture->getBufferQueue()); window->incStrong(0); SET_INT(textureView, gTextureViewClassInfo.nativeWindow, jint(window.get())); diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index f8904bd243da..1c9562ec98e1 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -355,7 +355,7 @@ not_valid_surface: sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(_env, native_window)); - window = new SurfaceTextureClient(surfaceTexture); + window = new SurfaceTextureClient(surfaceTexture->getBufferQueue()); if (window == NULL) goto not_valid_surface; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 316de5067b75..9822e63b0319 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -164,9 +164,10 @@ <protected-broadcast android:name="android.net.wifi.p2p.PERSISTENT_GROUPS_CHANGED" /> <protected-broadcast android:name="android.net.conn.TETHER_STATE_CHANGED" /> <protected-broadcast android:name="android.net.conn.INET_CONDITION_ACTION" /> - - - + <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" /> + <protected-broadcast android:name="android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE" /> + <protected-broadcast android:name="android.intent.action.AIRPLANE_MODE" /> + <protected-broadcast android:name="android.intent.action.ADVANCED_SETTINGS" /> <!-- ====================================== --> <!-- Permissions for things that cost money --> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 563d1a52ec0e..6ccc5903dbef 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -170,7 +170,7 @@ <string name="permgroupdesc_costMoney" msgid="3293301903409869495">"Kostenpflichtige Aktionen"</string> <string name="permgrouplab_messages" msgid="7521249148445456662">"Ihre Nachrichten"</string> <string name="permgroupdesc_messages" msgid="7821999071003699236">"SMS, E-Mails und andere Nachrichten lesen und schreiben"</string> - <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ihre persönlichen Informationen"</string> + <string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Ihre personenbezogenen Daten"</string> <string name="permgroupdesc_personalInfo" msgid="8426453129788861338">"Direkter Zugriff auf Informationen über Sie, die in Ihrer Kontaktkarte gespeichert sind"</string> <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Ihre sozialen Informationen"</string> <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Direkter Zugriff auf Informationen über Ihre Kontakte und sozialen Verbindungen"</string> @@ -375,8 +375,8 @@ <string name="permlab_movePackage" msgid="3289890271645921411">"App-Ressourcen verschieben"</string> <string name="permdesc_movePackage" msgid="319562217778244524">"Ermöglicht der App, App-Ressourcen von internen auf externe Medien zu verschieben und umgekehrt"</string> <string name="permlab_readLogs" msgid="6615778543198967614">"Vertrauliche Protokolldaten lesen"</string> - <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Tablet durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string> - <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch persönliche oder geheime Daten."</string> + <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Tablet durchgeführten Aktionen eingesehen werden, darunter auch personenbezogene oder vertrauliche Daten."</string> + <string name="permdesc_readLogs" product="default" msgid="2063438140241560443">"Ermöglicht der App, die verschiedenen Protokolldateien des Systems zu lesen. So können allgemeine Informationen zu den auf Ihrem Telefon durchgeführten Aktionen eingesehen werden, darunter auch personenbezogene oder vertrauliche Daten."</string> <string name="permlab_anyCodecForPlayback" msgid="715805555823881818">"Für Wiedergabe beliebigen Mediendecodierer verwenden"</string> <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Ermöglicht der App, alle installierten Mediendecodierer zur Wiedergabe zu verwenden."</string> <string name="permlab_diagnostic" msgid="8076743953908000342">"Lese-/Schreibberechtigung für zu Diagnosegruppe gehörige Elemente"</string> @@ -413,9 +413,9 @@ <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, das Anrufprotokoll Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string> <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, das Anrufprotokoll Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihr Anrufprotokoll löschen oder ändern."</string> <string name="permlab_readProfile" msgid="4701889852612716678">"Meine Kontaktkarten lesen"</string> - <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string> + <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string> <string name="permlab_writeProfile" msgid="907793628777397643">"Meine Kontaktkarten ändern"</string> - <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte persönliche Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string> + <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ermöglicht der App, auf Updates aus sozialen Netzwerken von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Seien Sie vorsichtig, wenn Sie Informationen teilen: Der App wird erlaubt, die Kommunikation zwischen Ihnen und Ihren Freunden in sozialen Netzwerken zu lesen, unabhängig von der Vertraulichkeit der kommunizierten Informationen. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"In sozialem Stream schreiben"</string> @@ -496,7 +496,7 @@ <string name="permlab_checkinProperties" msgid="7855259461268734914">"Auf Check-in-Eigenschaften zugreifen"</string> <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Ermöglicht der App Schreib-/Lesezugriff auf vom Check-in-Service hochgeladene Elemente. Nicht für normale Apps vorgesehen."</string> <string name="permlab_bindGadget" msgid="776905339015863471">"Widgets auswählen"</string> - <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ermöglicht der App, dem System zu melden, welche Widgets von welcher App verwendet werden können. Mit dieser Berechtigung können Apps anderen Apps Zugriff auf persönliche Daten gewähren. Nicht für normale Apps vorgesehen."</string> + <string name="permdesc_bindGadget" msgid="8261326938599049290">"Ermöglicht der App, dem System zu melden, welche Widgets von welcher App verwendet werden können. Mit dieser Berechtigung können Apps anderen Apps Zugriff auf personenbezogene Daten gewähren. Nicht für normale Apps vorgesehen."</string> <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"Telefonstatus ändern"</string> <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ermöglicht der App, die Telefonfunktionen des Geräts zu steuern. Eine App mit dieser Berechtigung kann das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string> <string name="permlab_readPhoneState" msgid="9178228524507610486">"Telefonstatus und Identität abrufen"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 2d15fb36edec..1b5c66109d49 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1047,7 +1047,7 @@ <string name="chooseUsbActivity" msgid="6894748416073583509">"בחר יישום עבור התקן ה-USB"</string> <string name="noApplications" msgid="2991814273936504689">"אין יישומים שיכולים לבצע פעולה זו."</string> <string name="aerr_title" msgid="1905800560317137752"></string> - <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת ה<xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string> + <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת <xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string> <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string> <string name="anr_title" msgid="4351948481459135709"></string> <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n"תרצה לסגור אותו?"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index d8652cdf5af1..1239695d4bb8 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -762,7 +762,7 @@ <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Tentar novamente"</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Excedido o n.º máximo de tentativas de Desbloqueio Através do Rosto"</string> <string name="lockscreen_plugged_in" msgid="8057762828355572315">"A carregar, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> - <string name="lockscreen_charged" msgid="321635745684060624">"Cobrado"</string> + <string name="lockscreen_charged" msgid="321635745684060624">"Carregado"</string> <string name="lockscreen_battery_short" msgid="4477264849386850266">"<xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> <string name="lockscreen_low_battery" msgid="1482873981919249740">"Ligue o carregador."</string> <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nenhum cartão SIM"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 460a811696c2..7ef501f73b32 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1031,4 +1031,7 @@ <item>150</item> <item>100</item> </integer-array> + + <!-- Flag indicating if the speed up audio on mt call code should be executed --> + <bool name="config_speed_up_audio_on_mt_calls">false</bool> </resources> diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index 547a192fde45..21bae040464a 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -79,4 +79,5 @@ <item type="id" name="action_menu_presenter" /> <item type="id" name="overflow_menu_presenter" /> <item type="id" name="popup_submenu_presenter" /> + <item type="id" name="action_bar_spinner" /> </resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 592ebb7acfd9..4c3644c98772 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -218,6 +218,7 @@ <java-symbol type="id" name="sms_short_code_remember_choice_checkbox" /> <java-symbol type="id" name="sms_short_code_remember_undo_instruction" /> <java-symbol type="id" name="breadcrumb_section" /> + <java-symbol type="id" name="action_bar_spinner" /> <java-symbol type="attr" name="actionModeShareDrawable" /> <java-symbol type="attr" name="alertDialogCenterButtons" /> @@ -277,6 +278,7 @@ <java-symbol type="bool" name="config_safe_media_volume_enabled" /> <java-symbol type="bool" name="config_camera_sound_forced" /> <java-symbol type="bool" name="config_dontPreferApn" /> + <java-symbol type="bool" name="config_speed_up_audio_on_mt_calls" /> <java-symbol type="integer" name="config_cursorWindowSize" /> <java-symbol type="integer" name="config_longPressOnPowerBehavior" /> diff --git a/data/sounds/AudioPackage10.mk b/data/sounds/AudioPackage10.mk index a930a5428c8b..90d8eaa5bd00 100755 --- a/data/sounds/AudioPackage10.mk +++ b/data/sounds/AudioPackage10.mk @@ -29,6 +29,7 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/effects/ogg/Undock.ogg:system/media/audio/ui/Undock.ogg \ $(LOCAL_PATH)/effects/ogg/Lock.ogg:system/media/audio/ui/Lock.ogg \ $(LOCAL_PATH)/effects/ogg/Unlock.ogg:system/media/audio/ui/Unlock.ogg \ + $(LOCAL_PATH)/effects/ogg/WirelessChargingStarted.ogg:system/media/audio/ui/WirelessChargingStarted.ogg \ $(LOCAL_PATH)/notifications/ogg/Adara.ogg:system/media/audio/notifications/Adara.ogg \ $(LOCAL_PATH)/notifications/ogg/Alya.ogg:system/media/audio/notifications/Alya.ogg \ $(LOCAL_PATH)/notifications/ogg/Arcturus.ogg:system/media/audio/notifications/Arcturus.ogg \ diff --git a/data/sounds/effects/ogg/LowBattery.ogg b/data/sounds/effects/ogg/LowBattery.ogg Binary files differindex 710e3856471c..ab9eba356348 100644 --- a/data/sounds/effects/ogg/LowBattery.ogg +++ b/data/sounds/effects/ogg/LowBattery.ogg diff --git a/data/sounds/effects/ogg/WirelessChargingStarted.ogg b/data/sounds/effects/ogg/WirelessChargingStarted.ogg Binary files differnew file mode 100644 index 000000000000..66f6cd251822 --- /dev/null +++ b/data/sounds/effects/ogg/WirelessChargingStarted.ogg diff --git a/docs/html/google/play/billing/billing_overview.jd b/docs/html/google/play/billing/billing_overview.jd index 28c38387b4de..aa48fc8195f7 100644 --- a/docs/html/google/play/billing/billing_overview.jd +++ b/docs/html/google/play/billing/billing_overview.jd @@ -34,8 +34,8 @@ parent.link=index.html </div> <p>This documentation describes the fundamental In-app Billing components and -features that you need to understand in order to implement your own In-app -Billing application.</p> +features that you need to understand in order to add In-app +Billing features into your application.</p> <h2 id="api">In-app Billing API</h2> <p>Your application accesses the In-app Billing service using an API that is @@ -148,7 +148,7 @@ providing the checkout user interface (middle screen). When checkout is complete, the application resumes. </p> -<h2>The Sample Applications</h2> +<h2 id="samples">Sample Applications</h2> <p>To help you integrate In-app Billing into your application, the Android SDK provides two sample applications that demonstrate how to sell in-app products from inside an app.</p> diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index b320e4bbab14..e0470dc3c445 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -247,7 +247,7 @@ nContextSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con, jint width } else { st = SurfaceTexture_getSurfaceTexture(_env, sur); - window = new SurfaceTextureClient(st); + window = new SurfaceTextureClient(st->getBufferQueue()); } rsContextSetSurface(con, width, height, window.get()); diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index 282ea8ac5b6c..82627c083811 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -73,6 +73,8 @@ <integer name="def_lockscreen_sounds_enabled">1</integer> <string name="def_lock_sound" translatable="false">/system/media/audio/ui/Lock.ogg</string> <string name="def_unlock_sound" translatable="false">/system/media/audio/ui/Unlock.ogg</string> + <string name="def_wireless_charging_started_sound" translatable="false">/system/media/audio/ui/WirelessChargingStarted.ogg</string> + <bool name="def_lockscreen_disabled">false</bool> <bool name="def_device_provisioned">false</bool> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 2c8c4a28ce24..fd0b79ffbeb4 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -71,7 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 94; + private static final int DATABASE_VERSION = 95; private Context mContext; private int mUserHandle; @@ -1505,6 +1505,25 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 94; } + if (upgradeVersion == 94) { + // Add wireless charging started sound setting + if (mUserHandle == UserHandle.USER_OWNER) { + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)" + + " VALUES(?,?);"); + loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND, + R.string.def_wireless_charging_started_sound); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + } + upgradeVersion = 95; + } + // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { @@ -2188,6 +2207,8 @@ public class DatabaseHelper extends SQLiteOpenHelper { R.string.def_car_dock_sound); loadStringSetting(stmt, Settings.Global.CAR_UNDOCK_SOUND, R.string.def_car_undock_sound); + loadStringSetting(stmt, Settings.Global.WIRELESS_CHARGING_STARTED_SOUND, + R.string.def_wireless_charging_started_sound); loadSetting(stmt, Settings.Global.SET_INSTALL_LOCATION, 0); loadSetting(stmt, Settings.Global.DEFAULT_INSTALL_LOCATION, diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index c454bb1bb15d..fff1aa043d30 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -157,14 +157,14 @@ <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string> - <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Wyłączono komórkową transmisję danych"</string> + <string name="data_usage_disabled_dialog_mobile_title" msgid="1046047248844821202">"Transmisja danych została wyłączona"</string> <string name="data_usage_disabled_dialog_title" msgid="2086815304858964954">"Wyłączono transmisję danych"</string> - <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Osiągnięto określony limit wykorzystania transmisji danych."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć opłaty."</string> + <string name="data_usage_disabled_dialog" msgid="3853117269051806280">"Ustawiony limit transmisji danych został osiągnięty."\n\n"Jeśli ponownie włączysz przesyłanie danych, operator może naliczyć dodatkowe opłaty."</string> <string name="data_usage_disabled_dialog_enable" msgid="7729772039208664606">"Włącz transmisję danych"</string> <string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"Brak internetu"</string> <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi: połączono"</string> <string name="gps_notification_searching_text" msgid="8574247005642736060">"Wyszukiwanie sygnału GPS"</string> - <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja ustawiona według GPS"</string> + <string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string> <string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string> <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"O aplikacji"</string> <string name="close_universe" msgid="3736513750241754348">"Zamknij"</string> diff --git a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java index f436cb4824a3..305ee3788303 100644 --- a/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java +++ b/packages/WAPPushManager/tests/src/com/android/smspush/unitTests/WapPushTest.java @@ -27,10 +27,10 @@ import android.provider.Telephony.Sms.Intents; import android.test.ServiceTestCase; import android.util.Log; -import com.android.internal.telephony.IccUtils; import com.android.internal.telephony.IWapPushManager; import com.android.internal.telephony.WapPushManagerParams; import com.android.internal.telephony.WspTypeDecoder; +import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.util.HexDump; import com.android.smspush.WapPushManager; diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 88f55330ab4d..91ac1de85575 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -602,12 +602,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mHandler = new Handler(this); mIWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); - mCaller = new HandlerCaller(context, new HandlerCaller.Callback() { + mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() { @Override public void executeMessage(Message msg) { handleMessage(msg); } - }); + }, true /*asyncHandler*/); mWindowManagerService = windowManager; mHardKeyboardListener = new HardKeyboardListener(); diff --git a/core/java/com/android/internal/widget/LockSettingsService.java b/services/java/com/android/server/LockSettingsService.java index 4ecbd1609e76..e20a21ff7982 100644 --- a/core/java/com/android/internal/widget/LockSettingsService.java +++ b/services/java/com/android/server/LockSettingsService.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.internal.widget; +package com.android.server; import android.content.ContentResolver; import android.content.ContentValues; @@ -32,6 +32,9 @@ import android.provider.Settings.Secure; import android.text.TextUtils; import android.util.Slog; +import com.android.internal.widget.ILockSettings; +import com.android.internal.widget.LockPatternUtils; + import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; diff --git a/services/java/com/android/server/NativeDaemonEvent.java b/services/java/com/android/server/NativeDaemonEvent.java index f11ae1d391eb..209515279bf8 100644 --- a/services/java/com/android/server/NativeDaemonEvent.java +++ b/services/java/com/android/server/NativeDaemonEvent.java @@ -223,8 +223,8 @@ public class NativeDaemonEvent { current++; // skip the trailing quote } // unescape stuff within the word - word.replace("\\\\", "\\"); - word.replace("\\\"", "\""); + word = word.replace("\\\\", "\\"); + word = word.replace("\\\"", "\""); if (DEBUG_ROUTINE) Slog.e(LOGTAG, "found '" + word + "'"); parsed.add(word); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 55885e6ed37f..a7b502ae97dd 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -16,12 +16,10 @@ package com.android.server; -import android.accounts.AccountManagerService; import android.app.ActivityManagerNative; import android.bluetooth.BluetoothAdapter; import android.content.ComponentName; import android.content.ContentResolver; -import android.content.ContentService; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; @@ -32,13 +30,11 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.RemoteException; -import android.os.SchedulingPolicyService; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; -import android.server.search.SearchManagerService; import android.service.dreams.DreamService; import android.util.DisplayMetrics; import android.util.EventLog; @@ -48,20 +44,23 @@ import android.view.WindowManager; import com.android.internal.os.BinderInternal; import com.android.internal.os.SamplingProfilerIntegration; -import com.android.internal.widget.LockSettingsService; import com.android.server.accessibility.AccessibilityManagerService; +import com.android.server.accounts.AccountManagerService; import com.android.server.am.ActivityManagerService; import com.android.server.am.BatteryStatsService; +import com.android.server.content.ContentService; import com.android.server.display.DisplayManagerService; import com.android.server.dreams.DreamManagerService; import com.android.server.input.InputManagerService; import com.android.server.net.NetworkPolicyManagerService; import com.android.server.net.NetworkStatsService; +import com.android.server.os.SchedulingPolicyService; import com.android.server.pm.Installer; import com.android.server.pm.PackageManagerService; import com.android.server.pm.UserManagerService; import com.android.server.power.PowerManagerService; import com.android.server.power.ShutdownThread; +import com.android.server.search.SearchManagerService; import com.android.server.usb.UsbService; import com.android.server.wm.WindowManagerService; diff --git a/core/java/android/accounts/AccountAuthenticatorCache.java b/services/java/com/android/server/accounts/AccountAuthenticatorCache.java index f937cde82877..75523680d335 100644 --- a/core/java/android/accounts/AccountAuthenticatorCache.java +++ b/services/java/com/android/server/accounts/AccountAuthenticatorCache.java @@ -14,8 +14,11 @@ * limitations under the License. */ -package android.accounts; +package com.android.server.accounts; +import android.accounts.AccountManager; +import android.accounts.AuthenticatorDescription; +import android.accounts.IAccountAuthenticator; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; diff --git a/core/java/android/accounts/AccountManagerService.java b/services/java/com/android/server/accounts/AccountManagerService.java index 2b1a2b21c5a3..150df9edf7be 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/services/java/com/android/server/accounts/AccountManagerService.java @@ -14,9 +14,19 @@ * limitations under the License. */ -package android.accounts; +package com.android.server.accounts; import android.Manifest; +import android.accounts.Account; +import android.accounts.AccountAndUser; +import android.accounts.AccountAuthenticatorResponse; +import android.accounts.AccountManager; +import android.accounts.AuthenticatorDescription; +import android.accounts.GrantCredentialsPermissionActivity; +import android.accounts.IAccountAuthenticator; +import android.accounts.IAccountAuthenticatorResponse; +import android.accounts.IAccountManager; +import android.accounts.IAccountManagerResponse; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.Notification; diff --git a/core/java/android/accounts/IAccountAuthenticatorCache.java b/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java index 06c21065e7e5..bb09687720cc 100644 --- a/core/java/android/accounts/IAccountAuthenticatorCache.java +++ b/services/java/com/android/server/accounts/IAccountAuthenticatorCache.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package android.accounts; +package com.android.server.accounts; +import android.accounts.AuthenticatorDescription; import android.content.pm.RegisteredServicesCache; import android.content.pm.RegisteredServicesCacheListener; import android.os.Handler; diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 60b208dfaa81..8728976483de 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -115,6 +115,7 @@ import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.UpdateLock; import android.os.UserHandle; import android.provider.Settings; import android.text.format.Time; @@ -191,6 +192,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final boolean DEBUG_POWER = localLOGV || false; static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; static final boolean DEBUG_MU = localLOGV || false; + static final boolean DEBUG_IMMERSIVE = localLOGV || false; static final boolean VALIDATE_TOKENS = false; static final boolean SHOW_ACTIVITY_START_TIME = true; @@ -827,6 +829,12 @@ public final class ActivityManagerService extends ActivityManagerNative long mLastWriteTime = 0; /** + * Used to retain an update lock when the foreground activity is in + * immersive mode. + */ + final UpdateLock mUpdateLock = new UpdateLock("immersive"); + + /** * Set to true after the system has finished booting. */ boolean mBooted = false; @@ -895,6 +903,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int REPORT_USER_SWITCH_MSG = 34; static final int CONTINUE_USER_SWITCH_MSG = 35; static final int USER_SWITCH_TIMEOUT_MSG = 36; + static final int IMMERSIVE_MODE_LOCK_MSG = 37; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1356,6 +1365,21 @@ public final class ActivityManagerService extends ActivityManagerNative timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); break; } + case IMMERSIVE_MODE_LOCK_MSG: { + final boolean nextState = (msg.arg1 != 0); + if (mUpdateLock.isHeld() != nextState) { + if (DEBUG_IMMERSIVE) { + final ActivityRecord r = (ActivityRecord) msg.obj; + Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); + } + if (nextState) { + mUpdateLock.acquire(); + } else { + mUpdateLock.release(); + } + } + break; + } } } }; @@ -1824,9 +1848,20 @@ public final class ActivityManagerService extends ActivityManagerNative if (r != null) { mWindowManager.setFocusedApp(r.appToken, true); } + applyUpdateLockStateLocked(r); } } + final void applyUpdateLockStateLocked(ActivityRecord r) { + // Modifications to the UpdateLock state are done on our handler, outside + // the activity manager's locks. The new state is determined based on the + // state *now* of the relevant activity record. The object is passed to + // the handler solely for logging detail, not to be consulted/modified. + final boolean nextState = r != null && r.immersive; + mHandler.sendMessage( + mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); + } + private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) { // put it on the LRU to keep track of when it should be exited. int lrui = mLruProcesses.indexOf(app); @@ -7423,11 +7458,19 @@ public final class ActivityManagerService extends ActivityManagerNative public void setImmersive(IBinder token, boolean immersive) { synchronized(this) { - ActivityRecord r = mMainStack.isInStackLocked(token); + final ActivityRecord r = mMainStack.isInStackLocked(token); if (r == null) { throw new IllegalArgumentException(); } r.immersive = immersive; + + // update associated state if we're frontmost + if (r == mFocusedActivity) { + if (DEBUG_IMMERSIVE) { + Slog.d(TAG, "Frontmost changed immersion: "+ r); + } + applyUpdateLockStateLocked(r); + } } } diff --git a/core/java/android/content/ContentService.java b/services/java/com/android/server/content/ContentService.java index 8bac88805abe..3b92338c1752 100644 --- a/core/java/android/content/ContentService.java +++ b/services/java/com/android/server/content/ContentService.java @@ -14,10 +14,19 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; +import android.Manifest; import android.accounts.Account; import android.app.ActivityManager; +import android.content.ContentResolver; +import android.content.Context; +import android.content.IContentService; +import android.content.ISyncStatusObserver; +import android.content.PeriodicSync; +import android.content.SyncAdapterType; +import android.content.SyncInfo; +import android.content.SyncStatusInfo; import android.database.IContentObserver; import android.database.sqlite.SQLiteException; import android.net.Uri; @@ -30,7 +39,6 @@ import android.os.ServiceManager; import android.os.UserHandle; import android.util.Log; import android.util.SparseIntArray; -import android.Manifest; import java.io.FileDescriptor; import java.io.PrintWriter; diff --git a/core/java/android/content/SyncManager.java b/services/java/com/android/server/content/SyncManager.java index e42896807e00..cd66cf283c10 100644 --- a/core/java/android/content/SyncManager.java +++ b/services/java/com/android/server/content/SyncManager.java @@ -14,18 +14,32 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; import android.accounts.Account; import android.accounts.AccountAndUser; import android.accounts.AccountManager; -import android.accounts.AccountManagerService; import android.app.ActivityManager; import android.app.AlarmManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.content.SyncStorageEngine.OnSyncRequestListener; +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.ContentResolver; +import android.content.Context; +import android.content.ISyncAdapter; +import android.content.ISyncContext; +import android.content.ISyncStatusObserver; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.SyncActivityTooManyDeletes; +import android.content.SyncAdapterType; +import android.content.SyncAdaptersCache; +import android.content.SyncInfo; +import android.content.SyncResult; +import android.content.SyncStatusInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; @@ -55,11 +69,12 @@ import android.text.format.Time; import android.util.EventLog; import android.util.Log; import android.util.Pair; -import android.util.Slog; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; +import com.android.server.accounts.AccountManagerService; +import com.android.server.content.SyncStorageEngine.OnSyncRequestListener; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import com.google.android.collect.Sets; diff --git a/core/java/android/content/SyncOperation.java b/services/java/com/android/server/content/SyncOperation.java index a4c2cff54675..eaad98229206 100644 --- a/core/java/android/content/SyncOperation.java +++ b/services/java/com/android/server/content/SyncOperation.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; import android.accounts.Account; import android.content.pm.PackageManager; +import android.content.ContentResolver; import android.os.Bundle; import android.os.SystemClock; diff --git a/core/java/android/content/SyncQueue.java b/services/java/com/android/server/content/SyncQueue.java index c09703c739bf..951e92cf32cd 100644 --- a/core/java/android/content/SyncQueue.java +++ b/services/java/com/android/server/content/SyncQueue.java @@ -14,14 +14,15 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; import android.accounts.Account; import android.content.pm.PackageManager; import android.content.pm.RegisteredServicesCache; +import android.content.SyncAdapterType; +import android.content.SyncAdaptersCache; import android.content.pm.RegisteredServicesCache.ServiceInfo; import android.os.SystemClock; -import android.os.UserHandle; import android.text.format.DateUtils; import android.util.Log; import android.util.Pair; diff --git a/core/java/android/content/SyncStorageEngine.java b/services/java/com/android/server/content/SyncStorageEngine.java index 8d9b8e0c3b29..5b8d26ff77cd 100644 --- a/core/java/android/content/SyncStorageEngine.java +++ b/services/java/com/android/server/content/SyncStorageEngine.java @@ -14,18 +14,16 @@ * limitations under the License. */ -package android.content; - -import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; -import com.android.internal.util.FastXmlSerializer; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; +package com.android.server.content; import android.accounts.Account; import android.accounts.AccountAndUser; +import android.content.ContentResolver; +import android.content.Context; +import android.content.ISyncStatusObserver; +import android.content.PeriodicSync; +import android.content.SyncInfo; +import android.content.SyncStatusInfo; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; @@ -39,9 +37,17 @@ import android.os.RemoteCallbackList; import android.os.RemoteException; import android.util.AtomicFile; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import android.util.Xml; -import android.util.Pair; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FastXmlSerializer; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; import java.io.File; import java.io.FileInputStream; @@ -50,9 +56,9 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Random; import java.util.TimeZone; -import java.util.List; /** * Singleton that tracks the sync data and overall sync @@ -107,9 +113,6 @@ public class SyncStorageEngine extends Handler { public static final long NOT_IN_BACKOFF_MODE = -1; - public static final Intent SYNC_CONNECTION_SETTING_CHANGED_INTENT = - new Intent("com.android.sync.SYNC_CONN_STATUS_CHANGED"); - // TODO: i18n -- grab these out of resources. /** String names for the sync source types. */ public static final String[] SOURCES = { "SERVER", @@ -710,7 +713,7 @@ public class SyncStorageEngine extends Handler { for (int i = 0, N = authority.periodicSyncs.size(); i < N; i++) { Pair<Bundle, Long> syncInfo = authority.periodicSyncs.get(i); final Bundle existingExtras = syncInfo.first; - if (equals(existingExtras, extras)) { + if (PeriodicSync.syncExtrasEquals(existingExtras, extras)) { if (syncInfo.second == period) { return; } @@ -734,7 +737,7 @@ public class SyncStorageEngine extends Handler { int i = 0; while (iterator.hasNext()) { Pair<Bundle, Long> syncInfo = iterator.next(); - if (equals(syncInfo.first, extras)) { + if (PeriodicSync.syncExtrasEquals(syncInfo.first, extras)) { iterator.remove(); changed = true; // if we removed an entry from the periodicSyncs array also @@ -800,7 +803,7 @@ public class SyncStorageEngine extends Handler { new Bundle()); } reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS); - mContext.sendBroadcast(SYNC_CONNECTION_SETTING_CHANGED_INTENT); + mContext.sendBroadcast(ContentResolver.ACTION_SYNC_CONN_STATUS_CHANGED); } public boolean getMasterSyncAutomatically(int userId) { @@ -1095,24 +1098,6 @@ public class SyncStorageEngine extends Handler { return id; } - public static boolean equals(Bundle b1, Bundle b2) { - if (b1.size() != b2.size()) { - return false; - } - if (b1.isEmpty()) { - return true; - } - for (String key : b1.keySet()) { - if (!b2.containsKey(key)) { - return false; - } - if (!b1.get(key).equals(b2.get(key))) { - return false; - } - } - return true; - } - public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage, long downstreamActivity, long upstreamActivity) { synchronized (mAuthorities) { diff --git a/services/java/com/android/server/dreams/DreamManagerService.java b/services/java/com/android/server/dreams/DreamManagerService.java index 7e4a554d4c5d..dd0b5b367add 100644 --- a/services/java/com/android/server/dreams/DreamManagerService.java +++ b/services/java/com/android/server/dreams/DreamManagerService.java @@ -25,6 +25,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -38,6 +39,8 @@ import android.util.Slog; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; import libcore.util.Objects; @@ -279,7 +282,37 @@ public final class DreamManagerService extends IDreamManager.Stub { String names = Settings.Secure.getStringForUser(mContext.getContentResolver(), Settings.Secure.SCREENSAVER_COMPONENTS, userId); - return names == null ? null : componentsFromString(names); + ComponentName[] components = componentsFromString(names); + + // first, ensure components point to valid services + List<ComponentName> validComponents = new ArrayList<ComponentName>(); + if (components != null) { + for (ComponentName component : components) { + if (serviceExists(component)) { + validComponents.add(component); + } else { + Slog.w(TAG, "Dream " + component + " does not exist"); + } + } + } + + // fallback to the default dream component if necessary + if (validComponents.isEmpty()) { + ComponentName defaultDream = getDefaultDreamComponent(); + if (defaultDream != null) { + Slog.w(TAG, "Falling back to default dream " + defaultDream); + validComponents.add(defaultDream); + } + } + return validComponents.toArray(new ComponentName[validComponents.size()]); + } + + private boolean serviceExists(ComponentName name) { + try { + return name != null && mContext.getPackageManager().getServiceInfo(name, 0) != null; + } catch (NameNotFoundException e) { + return false; + } } private void startDreamLocked(final ComponentName name, diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index b83933152eff..b09390c05303 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -425,11 +425,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private BroadcastReceiver mScreenReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - synchronized (mRulesLock) { - // screen-related broadcasts are protected by system, no need - // for permissions check. - mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); - } + // screen-related broadcasts are protected by system, no need + // for permissions check. + mHandler.obtainMessage(MSG_SCREEN_ON_CHANGED).sendToTarget(); } }; diff --git a/core/java/android/os/SchedulingPolicyService.java b/services/java/com/android/server/os/SchedulingPolicyService.java index a3fede681085..c0123bf1b0f5 100644 --- a/core/java/android/os/SchedulingPolicyService.java +++ b/services/java/com/android/server/os/SchedulingPolicyService.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package android.os; +package com.android.server.os; -import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; +import android.os.ISchedulingPolicyService; import android.os.Process; -import android.util.Log; /** * The implementation of the scheduling policy service interface. diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index fd649a16b970..2238f17621f1 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -6353,6 +6353,18 @@ public class PackageManagerService extends IPackageManager.Stub { pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags, lowThreshold); } + /* + * The cache free must have deleted the file we + * downloaded to install. + * + * TODO: fix the "freeCache" call to not delete + * the file we care about. + */ + if (pkgLite.recommendedInstallLocation + == PackageHelper.RECOMMEND_FAILED_INVALID_URI) { + pkgLite.recommendedInstallLocation + = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE; + } } } } finally { diff --git a/services/java/com/android/server/power/Notifier.java b/services/java/com/android/server/power/Notifier.java index 5e056934e835..d99d523f5cf5 100644 --- a/services/java/com/android/server/power/Notifier.java +++ b/services/java/com/android/server/power/Notifier.java @@ -23,6 +23,10 @@ import android.app.ActivityManagerNative; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.media.AudioManager; +import android.media.Ringtone; +import android.media.RingtoneManager; +import android.net.Uri; import android.os.BatteryStats; import android.os.Handler; import android.os.Looper; @@ -32,6 +36,7 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.WorkSource; +import android.provider.Settings; import android.util.EventLog; import android.util.Slog; import android.view.WindowManagerPolicy; @@ -64,6 +69,7 @@ final class Notifier { private static final int MSG_USER_ACTIVITY = 1; private static final int MSG_BROADCAST = 2; + private static final int MSG_WIRELESS_CHARGING_STARTED = 3; private final Object mLock = new Object(); @@ -312,6 +318,20 @@ final class Notifier { } } + /** + * Called when wireless charging has started so as to provide user feedback. + */ + public void onWirelessChargingStarted() { + if (DEBUG) { + Slog.d(TAG, "onWirelessChargingStarted"); + } + + mSuspendBlocker.acquire(); + Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED); + msg.setAsynchronous(true); + mHandler.sendMessage(msg); + } + private void updatePendingBroadcastLocked() { if (!mBroadcastInProgress && mActualPowerState != POWER_STATE_UNKNOWN @@ -473,6 +493,23 @@ final class Notifier { } }; + private void playWirelessChargingStartedSound() { + final String soundPath = Settings.Global.getString(mContext.getContentResolver(), + Settings.Global.WIRELESS_CHARGING_STARTED_SOUND); + if (soundPath != null) { + final Uri soundUri = Uri.parse("file://" + soundPath); + if (soundUri != null) { + final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); + if (sfx != null) { + sfx.setStreamType(AudioManager.STREAM_SYSTEM); + sfx.play(); + } + } + } + + mSuspendBlocker.release(); + } + private final class NotifierHandler extends Handler { public NotifierHandler(Looper looper) { super(looper, null, true /*async*/); @@ -488,6 +525,10 @@ final class Notifier { case MSG_BROADCAST: sendNextBroadcast(); break; + + case MSG_WIRELESS_CHARGING_STARTED: + playWirelessChargingStartedSound(); + break; } } } diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java index 7f83c17c94a6..5a5d91000ef1 100644 --- a/services/java/com/android/server/power/PowerManagerService.java +++ b/services/java/com/android/server/power/PowerManagerService.java @@ -1150,6 +1150,16 @@ public final class PowerManagerService extends IPowerManager.Stub } userActivityNoUpdateLocked( now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID); + + // Tell the notifier whether wireless charging has started so that + // it can provide feedback to the user. Refer to + // shouldWakeUpWhenPluggedOrUnpluggedLocked for justification of the + // heuristics used here. + if (!wasPowered && mIsPowered + && mPlugType == BatteryManager.BATTERY_PLUGGED_WIRELESS + && mBatteryLevel < WIRELESS_CHARGER_TURN_ON_BATTERY_LEVEL_LIMIT) { + mNotifier.onWirelessChargingStarted(); + } } } } diff --git a/core/java/android/server/search/SearchManagerService.java b/services/java/com/android/server/search/SearchManagerService.java index 46f27234a851..132ae79177b0 100644 --- a/core/java/android/server/search/SearchManagerService.java +++ b/services/java/com/android/server/search/SearchManagerService.java @@ -14,10 +14,7 @@ * limitations under the License. */ -package android.server.search; - -import com.android.internal.content.PackageMonitor; -import com.android.internal.util.IndentingPrintWriter; +package com.android.server.search; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -45,6 +42,9 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; +import com.android.internal.content.PackageMonitor; +import com.android.internal.util.IndentingPrintWriter; + import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.List; diff --git a/core/java/android/server/search/Searchables.java b/services/java/com/android/server/search/Searchables.java index a0095d6287bc..0ffbb7d0aa59 100644 --- a/core/java/android/server/search/Searchables.java +++ b/services/java/com/android/server/search/Searchables.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.server.search; +package com.android.server.search; import android.app.AppGlobals; import android.app.SearchManager; diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index 49f8c0eb03c6..34513a188410 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -129,7 +129,7 @@ public class AppWindowAnimator { if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) { mService.setInputMethodAnimLayerAdjustment(adj); } - if (w == mAnimator.mWallpaperTarget && mAnimator.mLowerWallpaperTarget == null) { + if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) { mService.setWallpaperAnimLayerAdjustmentLocked(adj); } } diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java index 3ec6d26e98f0..275c9bf311dc 100644 --- a/services/java/com/android/server/wm/AppWindowToken.java +++ b/services/java/com/android/server/wm/AppWindowToken.java @@ -30,7 +30,6 @@ import android.view.View; import android.view.WindowManager; import java.io.PrintWriter; -import java.util.ArrayList; /** * Version of WindowToken that is specifically for a particular application (or @@ -42,7 +41,7 @@ class AppWindowToken extends WindowToken { // All of the windows and child windows that are included in this // application token. Note this list is NOT sorted! - final ArrayList<WindowState> allAppWindows = new ArrayList<WindowState>(); + final WindowList allAppWindows = new WindowList(); final AppWindowAnimator mAppAnimator; final WindowAnimator mAnimator; diff --git a/services/java/com/android/server/wm/DisplayMagnificationMediator.java b/services/java/com/android/server/wm/DisplayMagnificationMediator.java index 8621c5cd396b..0e3a6e1d72fb 100644 --- a/services/java/com/android/server/wm/DisplayMagnificationMediator.java +++ b/services/java/com/android/server/wm/DisplayMagnificationMediator.java @@ -183,8 +183,6 @@ final class DisplayMagnificationMediator extends IDisplayMagnificationMediator.S displayState.mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY); spec.recycle(); - } - synchronized (mWindowManagerService.mLayoutToAnim) { mWindowManagerService.scheduleAnimationLocked(); } } diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 73293b068ca2..f041d9fe1b0c 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -9,8 +9,7 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED; import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE; - -import static com.android.server.wm.WindowManagerService.H.UPDATE_ANIM_PARAMETERS; +import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING; import android.content.Context; import android.os.Debug; @@ -25,9 +24,8 @@ import android.view.Surface; import android.view.WindowManagerPolicy; import android.view.animation.Animation; -import com.android.server.wm.WindowManagerService.AppWindowAnimParams; +import com.android.server.wm.WindowManagerService.DisplayContentsIterator; import com.android.server.wm.WindowManagerService.LayoutFields; -import com.android.server.wm.WindowManagerService.LayoutToAnimatorParams; import java.io.PrintWriter; import java.util.ArrayList; @@ -49,9 +47,6 @@ public class WindowAnimator { int mAdjResult; - // Layout changes for individual Displays. Indexed by displayId. - SparseIntArray mPendingLayoutChanges = new SparseIntArray(); - /** Time of current animation step. Reset on each iteration */ long mCurrentTime; @@ -73,28 +68,6 @@ public class WindowAnimator { SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = new SparseArray<WindowAnimator.DisplayContentsAnimator>(); - static final int WALLPAPER_ACTION_PENDING = 1; - int mPendingActions; - - WindowState mWallpaperTarget = null; - AppWindowAnimator mWpAppAnimator = null; - WindowState mLowerWallpaperTarget = null; - WindowState mUpperWallpaperTarget = null; - - ArrayList<AppWindowAnimator> mAppAnimators = new ArrayList<AppWindowAnimator>(); - - ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>(); - - /** Parameters being passed from this into mService. */ - static class AnimatorToLayoutParams { - boolean mUpdateQueued; - int mBulkUpdateParams; - SparseIntArray mPendingLayoutChanges; - WindowState mWindowDetachedWallpaper; - } - /** Do not modify unless holding mService.mWindowMap or this and mAnimToLayout in that order */ - final AnimatorToLayoutParams mAnimToLayout = new AnimatorToLayoutParams(); - boolean mInitialized = false; // forceHiding states. @@ -122,13 +95,9 @@ public class WindowAnimator { mAnimationRunnable = new Runnable() { @Override public void run() { - // TODO(cmautner): When full isolation is achieved for animation, the first lock - // goes away and only the WindowAnimator.this remains. - synchronized(mService.mWindowMap) { - synchronized(WindowAnimator.this) { - copyLayoutToAnimParamsLocked(); - animateLocked(); - } + synchronized (mService.mWindowMap) { + mService.mAnimationScheduled = false; + animateLocked(); } } }; @@ -162,117 +131,17 @@ public class WindowAnimator { mDisplayContentsAnimators.delete(displayId); } - /** Locked on mAnimToLayout */ - void updateAnimToLayoutLocked() { - final AnimatorToLayoutParams animToLayout = mAnimToLayout; - synchronized (animToLayout) { - animToLayout.mBulkUpdateParams = mBulkUpdateParams; - animToLayout.mPendingLayoutChanges = mPendingLayoutChanges.clone(); - animToLayout.mWindowDetachedWallpaper = mWindowDetachedWallpaper; - - if (!animToLayout.mUpdateQueued) { - animToLayout.mUpdateQueued = true; - mService.mH.sendMessage(mService.mH.obtainMessage(UPDATE_ANIM_PARAMETERS)); - } - } + AppWindowAnimator getWallpaperAppAnimator() { + return mService.mWallpaperTarget == null + ? null : mService.mWallpaperTarget.mAppToken == null + ? null : mService.mWallpaperTarget.mAppToken.mAppAnimator; } - /** Copy all WindowManagerService params into local params here. Locked on 'this'. */ - private void copyLayoutToAnimParamsLocked() { - final LayoutToAnimatorParams layoutToAnim = mService.mLayoutToAnim; - synchronized(layoutToAnim) { - layoutToAnim.mAnimationScheduled = false; - - if (!layoutToAnim.mParamsModified) { - return; - } - layoutToAnim.mParamsModified = false; - - if ((layoutToAnim.mChanges & LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED) != 0) { - layoutToAnim.mChanges &= ~LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED; - mWallpaperTokens = new ArrayList<WindowToken>(layoutToAnim.mWallpaperTokens); - } - - if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) { - if (mWallpaperTarget != layoutToAnim.mWallpaperTarget - || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget - || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) { - Slog.d(TAG, "Pulling anim wallpaper: target=" + layoutToAnim.mWallpaperTarget - + " lower=" + layoutToAnim.mLowerWallpaperTarget + " upper=" - + layoutToAnim.mUpperWallpaperTarget); - } - } - mWallpaperTarget = layoutToAnim.mWallpaperTarget; - mWpAppAnimator = mWallpaperTarget == null - ? null : mWallpaperTarget.mAppToken == null - ? null : mWallpaperTarget.mAppToken.mAppAnimator; - mLowerWallpaperTarget = layoutToAnim.mLowerWallpaperTarget; - mUpperWallpaperTarget = layoutToAnim.mUpperWallpaperTarget; - - // Set the new DimAnimator params. - final int numDisplays = mDisplayContentsAnimators.size(); - for (int i = 0; i < numDisplays; i++) { - final int displayId = mDisplayContentsAnimators.keyAt(i); - DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); - - displayAnimator.mWinAnimators.clear(); - final WinAnimatorList winAnimators = layoutToAnim.mWinAnimatorLists.get(displayId); - if (winAnimators != null) { - displayAnimator.mWinAnimators.addAll(winAnimators); - } - - DimAnimator.Parameters dimParams = layoutToAnim.mDimParams.get(displayId); - if (dimParams == null) { - displayAnimator.mDimParams = null; - } else { - final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator; - - // Only set dim params on the highest dimmed layer. - final WindowStateAnimator existingDimWinAnimator = - displayAnimator.mDimParams == null ? - null : displayAnimator.mDimParams.mDimWinAnimator; - // Don't turn on for an unshown surface, or for any layer but the highest - // dimmed layer. - if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null - || !existingDimWinAnimator.mSurfaceShown - || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) { - displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams); - } - } - } - - mAppAnimators.clear(); - final int N = layoutToAnim.mAppWindowAnimParams.size(); - for (int i = 0; i < N; i++) { - final AppWindowAnimParams params = layoutToAnim.mAppWindowAnimParams.get(i); - AppWindowAnimator appAnimator = params.mAppAnimator; - appAnimator.mAllAppWinAnimators.clear(); - appAnimator.mAllAppWinAnimators.addAll(params.mWinAnimators); - mAppAnimators.add(appAnimator); - } - } - } + void hideWallpapersLocked(final WindowState w) { + final WindowState wallpaperTarget = mService.mWallpaperTarget; + final WindowState lowerWallpaperTarget = mService.mLowerWallpaperTarget; + final ArrayList<WindowToken> wallpaperTokens = mService.mWallpaperTokens; - void hideWallpapersLocked(final WindowState w, boolean fromAnimator) { - // There is an issue where this function can be called either from - // the animation or the layout side of the window manager. The problem - // is that if it is called from the layout side, we may not yet have - // propagated the current layout wallpaper state over into the animation - // state. If that is the case, we can do bad things like hide the - // wallpaper when we had just made it shown because the animation side - // doesn't yet see that there is now a wallpaper target. As a temporary - // work-around, we tell the function here which side of the window manager - // is calling so it can use the right state. - if (fromAnimator) { - hideWallpapersLocked(w, mWallpaperTarget, mLowerWallpaperTarget, mWallpaperTokens); - } else { - hideWallpapersLocked(w, mService.mWallpaperTarget, - mService.mLowerWallpaperTarget, mService.mWallpaperTokens); - } - } - - void hideWallpapersLocked(final WindowState w, final WindowState wallpaperTarget, - final WindowState lowerWallpaperTarget, final ArrayList<WindowToken> wallpaperTokens) { if ((wallpaperTarget == w && lowerWallpaperTarget == null) || wallpaperTarget == null) { final int numTokens = wallpaperTokens.size(); for (int i = numTokens - 1; i >= 0; i--) { @@ -299,9 +168,10 @@ public class WindowAnimator { private void updateAppWindowsLocked() { int i; - final int NAT = mAppAnimators.size(); + final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens; + final int NAT = appTokens.size(); for (i=0; i<NAT; i++) { - final AppWindowAnimator appAnimator = mAppAnimators.get(i); + final AppWindowAnimator appAnimator = appTokens.get(i).mAppAnimator; final boolean wasAnimating = appAnimator.animation != null && appAnimator.animation != AppWindowAnimator.sDummyAnimation; if (appAnimator.stepAnimationLocked(mCurrentTime)) { @@ -335,15 +205,14 @@ public class WindowAnimator { private void updateWindowsLocked(final int displayId) { ++mAnimTransactionSequence; - final WinAnimatorList winAnimatorList = - getDisplayContentsAnimatorLocked(displayId).mWinAnimators; + final WindowList windows = mService.getWindowListLocked(displayId); ArrayList<WindowStateAnimator> unForceHiding = null; boolean wallpaperInUnForceHiding = false; mForceHiding = KEYGUARD_NOT_SHOWN; - for (int i = winAnimatorList.size() - 1; i >= 0; i--) { - WindowStateAnimator winAnimator = winAnimatorList.get(i); - WindowState win = winAnimator.mWin; + for (int i = windows.size() - 1; i >= 0; i--) { + WindowState win = windows.get(i); + WindowStateAnimator winAnimator = win.mWinAnimator; final int flags = winAnimator.mAttrFlags; if (winAnimator.mSurface != null) { @@ -355,13 +224,13 @@ public class WindowAnimator { ", nowAnimating=" + nowAnimating); } - if (wasAnimating && !winAnimator.mAnimating && mWallpaperTarget == win) { + if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) { mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE; setPendingLayoutChanges(Display.DEFAULT_DISPLAY, WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 2", - mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); + getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); } } @@ -375,7 +244,7 @@ public class WindowAnimator { WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 3", - mPendingLayoutChanges.get(displayId)); + getPendingLayoutChanges(displayId)); } mService.mFocusMayChange = true; } @@ -438,7 +307,7 @@ public class WindowAnimator { WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 4", - mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY)); + getPendingLayoutChanges(Display.DEFAULT_DISPLAY)); } } } @@ -448,11 +317,11 @@ public class WindowAnimator { if (winAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW) { if (atoken == null || atoken.allDrawn) { if (winAnimator.performShowLocked()) { - mPendingLayoutChanges.put(displayId, + setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats("updateWindowsAndWallpaperLocked 5", - mPendingLayoutChanges.get(displayId)); + getPendingLayoutChanges(displayId)); } } } @@ -486,21 +355,21 @@ public class WindowAnimator { private void updateWallpaperLocked(int displayId) { final DisplayContentsAnimator displayAnimator = getDisplayContentsAnimatorLocked(displayId); - final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; + final WindowList windows = mService.getWindowListLocked(displayId); WindowStateAnimator windowAnimationBackground = null; int windowAnimationBackgroundColor = 0; WindowState detachedWallpaper = null; final DimSurface windowAnimationBackgroundSurface = displayAnimator.mWindowAnimationBackgroundSurface; - for (int i = winAnimatorList.size() - 1; i >= 0; i--) { - WindowStateAnimator winAnimator = winAnimatorList.get(i); + for (int i = windows.size() - 1; i >= 0; i--) { + final WindowState win = windows.get(i); + WindowStateAnimator winAnimator = win.mWinAnimator; if (winAnimator.mSurface == null) { continue; } final int flags = winAnimator.mAttrFlags; - final WindowState win = winAnimator.mWin; // If this window is animating, make a note that we have // an animating window and take care of a request to run @@ -559,11 +428,11 @@ public class WindowAnimator { // don't cause the wallpaper to suddenly disappear. int animLayer = windowAnimationBackground.mAnimLayer; WindowState win = windowAnimationBackground.mWin; - if (mWallpaperTarget == win - || mLowerWallpaperTarget == win || mUpperWallpaperTarget == win) { - final int N = winAnimatorList.size(); + if (mService.mWallpaperTarget == win || mService.mLowerWallpaperTarget == win + || mService.mUpperWallpaperTarget == win) { + final int N = windows.size(); for (int i = 0; i < N; i++) { - WindowStateAnimator winAnimator = winAnimatorList.get(i); + WindowStateAnimator winAnimator = windows.get(i).mWinAnimator; if (winAnimator.mIsWallpaper) { animLayer = winAnimator.mAnimLayer; break; @@ -586,10 +455,13 @@ public class WindowAnimator { /** See if any windows have been drawn, so they (and others associated with them) can now be * shown. */ private void testTokenMayBeDrawnLocked() { - final int NT = mAppAnimators.size(); + // See if any windows have been drawn, so they (and others + // associated with them) can now be shown. + final ArrayList<AppWindowToken> appTokens = mService.mAnimatingAppTokens; + final int NT = appTokens.size(); for (int i=0; i<NT; i++) { - AppWindowAnimator appAnimator = mAppAnimators.get(i); - AppWindowToken wtoken = appAnimator.mAppToken; + AppWindowToken wtoken = appTokens.get(i); + AppWindowAnimator appAnimator = wtoken.mAppAnimator; final boolean allDrawn = wtoken.allDrawn; if (allDrawn != appAnimator.allDrawn) { appAnimator.allDrawn = allDrawn; @@ -611,7 +483,7 @@ public class WindowAnimator { setAppLayoutChanges(appAnimator, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, "testTokenMayBeDrawnLocked"); - + // We can now show all of the drawn windows! if (!mService.mOpeningApps.contains(wtoken)) { mAnimating |= appAnimator.showAllWindowsLocked(); @@ -634,7 +506,6 @@ public class WindowAnimator { return; } - mPendingLayoutChanges.clear(); mCurrentTime = SystemClock.uptimeMillis(); mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; boolean wasAnimating = mAnimating; @@ -671,10 +542,10 @@ public class WindowAnimator { // associated with exiting/removed apps performAnimationsLocked(displayId); - final WinAnimatorList winAnimatorList = displayAnimator.mWinAnimators; - final int N = winAnimatorList.size(); + final WindowList windows = mService.getWindowListLocked(displayId); + final int N = windows.size(); for (int j = 0; j < N; j++) { - winAnimatorList.get(j).prepareSurfaceLocked(true); + windows.get(j).mWinAnimator.prepareSurfaceLocked(true); } } @@ -712,21 +583,30 @@ public class WindowAnimator { TAG, "<<< CLOSE TRANSACTION animateLocked"); } - for (int i = mPendingLayoutChanges.size() - 1; i >= 0; i--) { - if ((mPendingLayoutChanges.valueAt(i) - & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { - mPendingActions |= WALLPAPER_ACTION_PENDING; + boolean hasPendingLayoutChanges = false; + DisplayContentsIterator iterator = mService.new DisplayContentsIterator(); + while (iterator.hasNext()) { + final DisplayContent displayContent = iterator.next(); + final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId()); + if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) { + mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING; } + if (pendingChanges != 0) { + hasPendingLayoutChanges = true; + } + } + + boolean doRequest = false; + if (mBulkUpdateParams != 0) { + doRequest = mService.copyAnimToLayoutParamsLocked(); } - if (mBulkUpdateParams != 0 || mPendingLayoutChanges.size() > 0) { - updateAnimToLayoutLocked(); + if (hasPendingLayoutChanges || doRequest) { + mService.requestTraversalLocked(); } if (mAnimating) { - synchronized (mService.mLayoutToAnim) { - mService.scheduleAnimationLocked(); - } + mService.scheduleAnimationLocked(); } else if (wasAnimating) { mService.requestTraversalLocked(); } @@ -734,7 +614,7 @@ public class WindowAnimator { Slog.i(TAG, "!!! animate: exit mAnimating=" + mAnimating + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams) + " mPendingLayoutChanges(DEFAULT_DISPLAY)=" - + Integer.toHexString(mPendingLayoutChanges.get(Display.DEFAULT_DISPLAY))); + + Integer.toHexString(getPendingLayoutChanges(Display.DEFAULT_DISPLAY))); } } @@ -777,51 +657,16 @@ public class WindowAnimator { final String subPrefix = " " + prefix; final String subSubPrefix = " " + subPrefix; - boolean needSep = false; - if (mAppAnimators.size() > 0) { - needSep = true; - pw.println(" App Animators:"); - for (int i=mAppAnimators.size()-1; i>=0; i--) { - AppWindowAnimator anim = mAppAnimators.get(i); - pw.print(prefix); pw.print("App Animator #"); pw.print(i); - pw.print(' '); pw.print(anim); - if (dumpAll) { - pw.println(':'); - anim.dump(pw, subPrefix, dumpAll); - } else { - pw.println(); - } - } - } - if (mWallpaperTokens.size() > 0) { - if (needSep) { - pw.println(); - } - needSep = true; - pw.print(prefix); pw.println("Wallpaper tokens:"); - for (int i=mWallpaperTokens.size()-1; i>=0; i--) { - WindowToken token = mWallpaperTokens.get(i); - pw.print(prefix); pw.print("Wallpaper #"); pw.print(i); - pw.print(' '); pw.print(token); - if (dumpAll) { - pw.println(':'); - token.dump(pw, subPrefix); - } else { - pw.println(); - } - } - } - - if (needSep) { - pw.println(); - } for (int i = 0; i < mDisplayContentsAnimators.size(); i++) { pw.print(prefix); pw.print("DisplayContentsAnimator #"); pw.print(mDisplayContentsAnimators.keyAt(i)); pw.println(":"); DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); - for (int j=0; j<displayAnimator.mWinAnimators.size(); j++) { - WindowStateAnimator wanim = displayAnimator.mWinAnimators.get(j); + final WindowList windows = + mService.getWindowListLocked(mDisplayContentsAnimators.keyAt(i)); + final int N = windows.size(); + for (int j = 0; j < N; j++) { + WindowStateAnimator wanim = windows.get(j).mWinAnimator; pw.print(subPrefix); pw.print("Window #"); pw.print(j); pw.print(": "); pw.println(wanim); } @@ -867,48 +712,34 @@ public class WindowAnimator { pw.print(Integer.toHexString(mBulkUpdateParams)); pw.println(bulkUpdateParamsToString(mBulkUpdateParams)); } - if (mPendingActions != 0) { - pw.print(prefix); pw.print("mPendingActions=0x"); - pw.println(Integer.toHexString(mPendingActions)); - } if (mWindowDetachedWallpaper != null) { pw.print(prefix); pw.print("mWindowDetachedWallpaper="); pw.println(mWindowDetachedWallpaper); } - pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget); - pw.print(prefix); pw.print("mWpAppAnimator="); pw.println(mWpAppAnimator); - if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) { - pw.print(prefix); pw.print("mLowerWallpaperTarget="); - pw.println(mLowerWallpaperTarget); - pw.print(prefix); pw.print("mUpperWallpaperTarget="); - pw.println(mUpperWallpaperTarget); - } if (mUniverseBackground != null) { pw.print(prefix); pw.print("mUniverseBackground="); pw.print(mUniverseBackground); pw.print(" mAboveUniverseLayer="); pw.println(mAboveUniverseLayer); } } - void clearPendingActions() { - synchronized (this) { - mPendingActions = 0; - } + int getPendingLayoutChanges(final int displayId) { + return mService.getDisplayContentLocked(displayId).pendingLayoutChanges; } void setPendingLayoutChanges(final int displayId, final int changes) { - mPendingLayoutChanges.put(displayId, mPendingLayoutChanges.get(displayId) | changes); + mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; } void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { // Used to track which displays layout changes have been done. SparseIntArray displays = new SparseIntArray(); - for (int i = appAnimator.mAllAppWinAnimators.size() - 1; i >= 0; i--) { - WindowStateAnimator winAnimator = appAnimator.mAllAppWinAnimators.get(i); - final int displayId = winAnimator.mWin.mDisplayContent.getDisplayId(); + WindowList windows = appAnimator.mAppToken.allAppWindows; + for (int i = windows.size() - 1; i >= 0; i--) { + final int displayId = windows.get(i).getDisplayId(); if (displays.indexOfKey(displayId) < 0) { setPendingLayoutChanges(displayId, changes); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { - mService.debugLayoutRepeats(s, mPendingLayoutChanges.get(displayId)); + mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId)); } // Keep from processing this display again. displays.put(displayId, changes); @@ -916,6 +747,27 @@ public class WindowAnimator { } } + void setDimParamsLocked(int displayId, DimAnimator.Parameters dimParams) { + DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); + if (dimParams == null) { + displayAnimator.mDimParams = null; + } else { + final WindowStateAnimator newWinAnimator = dimParams.mDimWinAnimator; + + // Only set dim params on the highest dimmed layer. + final WindowStateAnimator existingDimWinAnimator = + displayAnimator.mDimParams == null ? + null : displayAnimator.mDimParams.mDimWinAnimator; + // Don't turn on for an unshown surface, or for any layer but the highest + // dimmed layer. + if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null + || !existingDimWinAnimator.mSurfaceShown + || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) { + displayAnimator.mDimParams = new DimAnimator.Parameters(dimParams); + } + } + } + private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); if (displayAnimator == null) { @@ -934,7 +786,6 @@ public class WindowAnimator { } private class DisplayContentsAnimator { - WinAnimatorList mWinAnimators = new WinAnimatorList(); DimAnimator mDimAnimator = null; DimAnimator.Parameters mDimParams = null; DimSurface mWindowAnimationBackgroundSurface = null; diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 9041a9bf09ef..d078273b84fc 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -125,7 +125,6 @@ import android.view.InputDevice; import android.view.InputEvent; import android.view.InputEventReceiver; import android.view.KeyEvent; -import android.view.MagnificationSpec; import android.view.MotionEvent; import android.view.Surface; import android.view.SurfaceSession; @@ -522,7 +521,7 @@ public class WindowManagerService extends IWindowManager.Stub WindowState mLowerWallpaperTarget = null; // If non-null, we are in the middle of animating from one wallpaper target // to another, and this is the higher one in Z-order. - private WindowState mUpperWallpaperTarget = null; + WindowState mUpperWallpaperTarget = null; int mWallpaperAnimLayerAdjustment; float mLastWallpaperX = -1; float mLastWallpaperY = -1; @@ -566,6 +565,7 @@ public class WindowManagerService extends IWindowManager.Stub static final int SET_FORCE_HIDING_CHANGED = 1 << 2; static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3; static final int SET_TURN_ON_SCREEN = 1 << 4; + static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5; boolean mWallpaperForceHidingChanged = false; boolean mWallpaperMayChange = false; @@ -579,6 +579,7 @@ public class WindowManagerService extends IWindowManager.Stub private float mButtonBrightness = -1; private long mUserActivityTimeout = -1; private boolean mUpdateRotation = false; + boolean mWallpaperActionPending = false; private static final int DISPLAY_CONTENT_UNKNOWN = 0; private static final int DISPLAY_CONTENT_MIRROR = 1; @@ -603,27 +604,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - static class LayoutToAnimatorParams { - boolean mParamsModified; - - static final long WALLPAPER_TOKENS_CHANGED = 1 << 0; - long mChanges; - - boolean mAnimationScheduled; - SparseArray<WinAnimatorList> mWinAnimatorLists = new SparseArray<WinAnimatorList>(); - WindowState mWallpaperTarget; - WindowState mLowerWallpaperTarget; - WindowState mUpperWallpaperTarget; - SparseArray<DimAnimator.Parameters> mDimParams = new SparseArray<DimAnimator.Parameters>(); - ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>(); - ArrayList<AppWindowAnimParams> mAppWindowAnimParams = new ArrayList<AppWindowAnimParams>(); - } - /** Params from WindowManagerService to WindowAnimator. Do not modify or read without first - * locking on either mWindowMap or mAnimator and then on mLayoutToAnim */ - final LayoutToAnimatorParams mLayoutToAnim = new LayoutToAnimatorParams(); - - /** The lowest wallpaper target with a detached wallpaper animation on it. */ - WindowState mWindowDetachedWallpaper = null; + boolean mAnimationScheduled; /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */ @@ -703,9 +684,6 @@ public class WindowManagerService extends IWindowManager.Stub */ boolean mInTouchMode = true; - // Temp regions for intermediary calculations. - private final Region mTempRegion = new Region(); - private ViewServer mViewServer; private ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<WindowChangeListener>(); @@ -1592,7 +1570,7 @@ public class WindowManagerService extends IWindowManager.Stub continue; } topCurW = null; - if (w != mWindowDetachedWallpaper && w.mAppToken != null) { + if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) { // If this window's app token is hidden and not animating, // it is of no interest to us. if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) { @@ -1618,7 +1596,7 @@ public class WindowManagerService extends IWindowManager.Stub continue; } break; - } else if (w == mWindowDetachedWallpaper) { + } else if (w == mAnimator.mWindowDetachedWallpaper) { windowDetachedI = i; } } @@ -2817,7 +2795,7 @@ public class WindowManagerService extends IWindowManager.Stub } if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) { // To change the format, we need to re-build the surface. - winAnimator.destroySurfaceLocked(false); + winAnimator.destroySurfaceLocked(); toBeDisplayed = true; surfaceChanged = true; } @@ -2898,7 +2876,7 @@ public class WindowManagerService extends IWindowManager.Stub if (mInputMethodWindow == win) { mInputMethodWindow = null; } - winAnimator.destroySurfaceLocked(false); + winAnimator.destroySurfaceLocked(); } if (mMagnificationMediator != null) { mMagnificationMediator.onWindowTransitionLw(win, transit); @@ -3002,7 +2980,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win == null) { return; } - win.mWinAnimator.destroyDeferredSurfaceLocked(false); + win.mWinAnimator.destroyDeferredSurfaceLocked(); } } finally { Binder.restoreCallingIdentity(origId); @@ -3179,7 +3157,6 @@ public class WindowManagerService extends IWindowManager.Stub mTokenMap.put(token, wtoken); if (type == TYPE_WALLPAPER) { mWallpaperTokens.add(wtoken); - updateLayoutToAnimWallpaperTokens(); } } } @@ -3231,7 +3208,6 @@ public class WindowManagerService extends IWindowManager.Stub mExitingTokens.add(wtoken); } else if (wtoken.windowType == TYPE_WALLPAPER) { mWallpaperTokens.remove(wtoken); - updateLayoutToAnimWallpaperTokens(); } } @@ -5593,7 +5569,7 @@ public class WindowManagerService extends IWindowManager.Stub rotation, mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, displayInfo.logicalWidth, displayInfo.logicalHeight)) { - updateLayoutToAnimationLocked(); + scheduleAnimationLocked(); } } @@ -6641,19 +6617,17 @@ public class WindowManagerService extends IWindowManager.Stub public static final int REPORT_HARD_KEYBOARD_STATUS_CHANGE = 22; public static final int BOOT_TIMEOUT = 23; public static final int WAITING_FOR_DRAWN_TIMEOUT = 24; - public static final int UPDATE_ANIM_PARAMETERS = 25; - public static final int SHOW_STRICT_MODE_VIOLATION = 26; - public static final int DO_ANIMATION_CALLBACK = 27; + public static final int SHOW_STRICT_MODE_VIOLATION = 25; + public static final int DO_ANIMATION_CALLBACK = 26; - public static final int DO_DISPLAY_ADDED = 28; - public static final int DO_DISPLAY_REMOVED = 29; - public static final int DO_DISPLAY_CHANGED = 30; + public static final int DO_DISPLAY_ADDED = 27; + public static final int DO_DISPLAY_REMOVED = 28; + public static final int DO_DISPLAY_CHANGED = 29; - public static final int CLIENT_FREEZE_TIMEOUT = 31; + public static final int CLIENT_FREEZE_TIMEOUT = 30; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; - public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2; public H() { } @@ -6933,20 +6907,18 @@ public class WindowManagerService extends IWindowManager.Stub case FORCE_GC: { synchronized (mWindowMap) { - synchronized (mAnimator) { - // Since we're holding both mWindowMap and mAnimator we don't need to - // hold mAnimator.mLayoutToAnim. - if (mAnimator.mAnimating || mLayoutToAnim.mAnimationScheduled) { - // If we are animating, don't do the gc now but - // delay a bit so we don't interrupt the animation. - sendEmptyMessageDelayed(H.FORCE_GC, 2000); - return; - } - // If we are currently rotating the display, it will - // schedule a new message when done. - if (mDisplayFrozen) { - return; - } + // Since we're holding both mWindowMap and mAnimator we don't need to + // hold mAnimator.mLayoutToAnim. + if (mAnimator.mAnimating || mAnimationScheduled) { + // If we are animating, don't do the gc now but + // delay a bit so we don't interrupt the animation. + sendEmptyMessageDelayed(H.FORCE_GC, 2000); + return; + } + // If we are currently rotating the display, it will + // schedule a new message when done. + if (mDisplayFrozen) { + return; } } Runtime.getRuntime().gc(); @@ -6960,16 +6932,14 @@ public class WindowManagerService extends IWindowManager.Stub case APP_FREEZE_TIMEOUT: { synchronized (mWindowMap) { - synchronized (mAnimator) { - Slog.w(TAG, "App freeze timeout expired."); - int i = mAppTokens.size(); - while (i > 0) { - i--; - AppWindowToken tok = mAppTokens.get(i); - if (tok.mAppAnimator.freezingScreen) { - Slog.w(TAG, "Force clearing freeze: " + tok); - unsetAppFreezingScreenLocked(tok, true, true); - } + Slog.w(TAG, "App freeze timeout expired."); + int i = mAppTokens.size(); + while (i > 0) { + i--; + AppWindowToken tok = mAppTokens.get(i); + if (tok.mAppAnimator.freezingScreen) { + Slog.w(TAG, "Force clearing freeze: " + tok); + unsetAppFreezingScreenLocked(tok, true, true); } } } @@ -7060,17 +7030,6 @@ public class WindowManagerService extends IWindowManager.Stub break; } - case UPDATE_ANIM_PARAMETERS: { - // Used to send multiple changes from the animation side to the layout side. - synchronized (mWindowMap) { - if (copyAnimToLayoutParamsLocked()) { - sendEmptyMessage(CLEAR_PENDING_ACTIONS); - performLayoutAndPlaceSurfacesLocked(); - } - } - break; - } - case SHOW_STRICT_MODE_VIOLATION: { showStrictModeViolation(msg.arg1, msg.arg2); break; @@ -7085,11 +7044,6 @@ public class WindowManagerService extends IWindowManager.Stub break; } - case CLEAR_PENDING_ACTIONS: { - mAnimator.clearPendingActions(); - break; - } - case DO_ANIMATION_CALLBACK: { try { ((IRemoteCallback)msg.obj).sendResult(null); @@ -7468,7 +7422,7 @@ public class WindowManagerService extends IWindowManager.Stub pw.flush(); Slog.w(TAG, "This window was lost: " + ws); Slog.w(TAG, sw.toString()); - ws.mWinAnimator.destroySurfaceLocked(false); + ws.mWinAnimator.destroySurfaceLocked(); } } Slog.w(TAG, "Current app token list:"); @@ -7530,7 +7484,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (layerChanged && mAnimator.isDimmingLocked(winAnimator)) { // Force an animation pass just to update the mDimAnimator layer. - updateLayoutToAnimationLocked(); + scheduleAnimationLocked(); } if (DEBUG_LAYERS) Slog.v(TAG, "Assign layer " + w + ": " + "mBase=" + w.mBaseLayer @@ -7556,6 +7510,7 @@ public class WindowManagerService extends IWindowManager.Stub mH.removeMessages(H.DO_TRAVERSAL); loopCount--; } while (mTraversalScheduled && loopCount > 0); + mInnerFields.mWallpaperActionPending = false; } private boolean mInLayout = false; @@ -7688,7 +7643,7 @@ public class WindowManagerService extends IWindowManager.Stub // soon won't be visible, to avoid wasting time and funky // changes while a window is animating away. final boolean gone = (behindDream && mPolicy.canBeForceHidden(win, win.mAttrs)) - || (win.isGoneForLayoutLw() && !win.isOnScreen()); + || (win.isGoneForLayoutLw() && !(win.isOnScreen() && win.isDrawFinishedLw())); if (DEBUG_LAYOUT && !win.mLayoutAttached) { Slog.v(TAG, "1ST PASS " + win @@ -8780,7 +8735,7 @@ public class WindowManagerService extends IWindowManager.Stub if (win == mWallpaperTarget) { wallpaperDestroyed = true; } - win.mWinAnimator.destroySurfaceLocked(false); + win.mWinAnimator.destroySurfaceLocked(); } while (i > 0); mDestroySurface.clear(); } @@ -8792,7 +8747,6 @@ public class WindowManagerService extends IWindowManager.Stub mExitingTokens.remove(i); if (token.windowType == TYPE_WALLPAPER) { mWallpaperTokens.remove(token); - updateLayoutToAnimWallpaperTokens(); } } } @@ -8903,7 +8857,7 @@ public class WindowManagerService extends IWindowManager.Stub // be enabled, because the window obscured flags have changed. enableScreenIfNeededLocked(); - updateLayoutToAnimationLocked(); + scheduleAnimationLocked(); if (DEBUG_WINDOW_TRACE) { Slog.e(TAG, "performLayoutAndPlaceSurfacesLockedInner exit: animating=" @@ -9000,82 +8954,21 @@ public class WindowManagerService extends IWindowManager.Stub /** Note that Locked in this case is on mLayoutToAnim */ void scheduleAnimationLocked() { - final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim; - if (!layoutToAnim.mAnimationScheduled) { - layoutToAnim.mAnimationScheduled = true; + if (!mAnimationScheduled) { + mAnimationScheduled = true; mChoreographer.postCallback( Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null); } } - void updateLayoutToAnimationLocked() { - final LayoutToAnimatorParams layoutToAnim = mLayoutToAnim; - synchronized (layoutToAnim) { - // Copy local params to transfer params. - SparseArray<WinAnimatorList> allWinAnimatorLists = layoutToAnim.mWinAnimatorLists; - allWinAnimatorLists.clear(); - DisplayContentsIterator iterator = new DisplayContentsIterator(); - while (iterator.hasNext()) { - final DisplayContent displayContent = iterator.next(); - WinAnimatorList winAnimatorList = new WinAnimatorList(); - final WindowList windows = displayContent.getWindowList(); - int N = windows.size(); - for (int i = 0; i < N; i++) { - final WindowStateAnimator winAnimator = windows.get(i).mWinAnimator; - if (winAnimator.mSurface != null) { - winAnimatorList.add(winAnimator); - } - } - allWinAnimatorLists.put(displayContent.getDisplayId(), winAnimatorList); - } - - if (WindowManagerService.DEBUG_WALLPAPER_LIGHT) { - if (mWallpaperTarget != layoutToAnim.mWallpaperTarget - || mLowerWallpaperTarget != layoutToAnim.mLowerWallpaperTarget - || mUpperWallpaperTarget != layoutToAnim.mUpperWallpaperTarget) { - Slog.d(TAG, "Pushing anim wallpaper: target=" + mWallpaperTarget - + " lower=" + mLowerWallpaperTarget + " upper=" - + mUpperWallpaperTarget + "\n" + Debug.getCallers(5, " ")); - } - } - layoutToAnim.mWallpaperTarget = mWallpaperTarget; - layoutToAnim.mLowerWallpaperTarget = mLowerWallpaperTarget; - layoutToAnim.mUpperWallpaperTarget = mUpperWallpaperTarget; - - final ArrayList<AppWindowAnimParams> paramList = layoutToAnim.mAppWindowAnimParams; - paramList.clear(); - int N = mAnimatingAppTokens.size(); - for (int i = 0; i < N; i++) { - paramList.add(new AppWindowAnimParams(mAnimatingAppTokens.get(i).mAppAnimator)); - } - - layoutToAnim.mParamsModified = true; - scheduleAnimationLocked(); - } - } - - void updateLayoutToAnimWallpaperTokens() { - synchronized(mLayoutToAnim) { - mLayoutToAnim.mWallpaperTokens = new ArrayList<WindowToken>(mWallpaperTokens); - mLayoutToAnim.mChanges |= LayoutToAnimatorParams.WALLPAPER_TOKENS_CHANGED; - } - } - - void setAnimDimParams(int displayId, DimAnimator.Parameters params) { - synchronized (mLayoutToAnim) { - mLayoutToAnim.mDimParams.put(displayId, params); - scheduleAnimationLocked(); - } - } - void startDimmingLocked(final WindowStateAnimator winAnimator, final float target, final int width, final int height) { - setAnimDimParams(winAnimator.mWin.getDisplayId(), + mAnimator.setDimParamsLocked(winAnimator.mWin.getDisplayId(), new DimAnimator.Parameters(winAnimator, width, height, target)); } void stopDimmingLocked(int displayId) { - setAnimDimParams(displayId, null); + mAnimator.setDimParamsLocked(displayId, null); } private boolean needsLayout() { @@ -9088,53 +8981,39 @@ public class WindowManagerService extends IWindowManager.Stub return false; } - private boolean copyAnimToLayoutParamsLocked() { + boolean copyAnimToLayoutParamsLocked() { boolean doRequest = false; - final WindowAnimator.AnimatorToLayoutParams animToLayout = mAnimator.mAnimToLayout; - synchronized (animToLayout) { - animToLayout.mUpdateQueued = false; - final int bulkUpdateParams = animToLayout.mBulkUpdateParams; - // TODO(cmautner): As the number of bits grows, use masks of bit groups to - // eliminate unnecessary tests. - if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { - mInnerFields.mUpdateRotation = true; - doRequest = true; - } - if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { - mInnerFields.mWallpaperMayChange = true; - doRequest = true; - } - if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { - mInnerFields.mWallpaperForceHidingChanged = true; - doRequest = true; - } - if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) { - mInnerFields.mOrientationChangeComplete = false; - } else { - mInnerFields.mOrientationChangeComplete = true; - if (mWindowsFreezingScreen) { - doRequest = true; - } - } - if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { - mTurnOnScreen = true; - } - SparseIntArray pendingLayouts = animToLayout.mPendingLayoutChanges; - final int count = pendingLayouts.size(); - if (count > 0) { + final int bulkUpdateParams = mAnimator.mBulkUpdateParams; + // TODO(cmautner): As the number of bits grows, use masks of bit groups to + // eliminate unnecessary tests. + if ((bulkUpdateParams & LayoutFields.SET_UPDATE_ROTATION) != 0) { + mInnerFields.mUpdateRotation = true; + doRequest = true; + } + if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_MAY_CHANGE) != 0) { + mInnerFields.mWallpaperMayChange = true; + doRequest = true; + } + if ((bulkUpdateParams & LayoutFields.SET_FORCE_HIDING_CHANGED) != 0) { + mInnerFields.mWallpaperForceHidingChanged = true; + doRequest = true; + } + if ((bulkUpdateParams & LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE) == 0) { + mInnerFields.mOrientationChangeComplete = false; + } else { + mInnerFields.mOrientationChangeComplete = true; + if (mWindowsFreezingScreen) { doRequest = true; } - for (int i = 0; i < count; ++i) { - final DisplayContent displayContent = - getDisplayContentLocked(pendingLayouts.keyAt(i)); - if (displayContent != null) { - displayContent.pendingLayoutChanges |= pendingLayouts.valueAt(i); - } - } - - mWindowDetachedWallpaper = animToLayout.mWindowDetachedWallpaper; } + if ((bulkUpdateParams & LayoutFields.SET_TURN_ON_SCREEN) != 0) { + mTurnOnScreen = true; + } + if ((bulkUpdateParams & LayoutFields.SET_WALLPAPER_ACTION_PENDING) != 0) { + mInnerFields.mWallpaperActionPending = true; + } + return doRequest; } @@ -9298,7 +9177,7 @@ public class WindowManagerService extends IWindowManager.Stub } return false; } - + private void finishUpdateFocusedWindowAfterAssignLayersLocked(boolean updateInputWindows) { mInputMonitor.setInputFocusLw(mCurrentFocus, updateInputWindows); } @@ -9450,7 +9329,7 @@ public class WindowManagerService extends IWindowManager.Stub + ", mClientFreezingScreen=" + mClientFreezingScreen); return; } - + mDisplayFrozen = false; mH.removeMessages(H.APP_FREEZE_TIMEOUT); mH.removeMessages(H.CLIENT_FREEZE_TIMEOUT); @@ -9472,7 +9351,7 @@ public class WindowManagerService extends IWindowManager.Stub if (screenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION, mTransitionAnimationScale, displayInfo.logicalWidth, displayInfo.logicalHeight)) { - updateLayoutToAnimationLocked(); + scheduleAnimationLocked(); } else { screenRotationAnimation.kill(); screenRotationAnimation = null; @@ -9668,14 +9547,17 @@ public class WindowManagerService extends IWindowManager.Stub return mPolicy.hasNavigationBar(); } + @Override public void lockNow(Bundle options) { mPolicy.lockNow(options); } + @Override public boolean isSafeModeEnabled() { return mSafeMode; } + @Override public void showAssistant() { // TODO: What permission? if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER) @@ -10015,31 +9897,6 @@ public class WindowManagerService extends IWindowManager.Stub pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition); pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation); pw.println(" mLayoutToAnim:"); - pw.print(" mParamsModified="); pw.print(mLayoutToAnim.mParamsModified); - pw.print(" mAnimationScheduled="); pw.print(mLayoutToAnim.mAnimationScheduled); - pw.print(" mChanges=0x"); - pw.println(Long.toHexString(mLayoutToAnim.mChanges)); - pw.print(" mWallpaperTarget="); pw.println(mLayoutToAnim.mWallpaperTarget); - if (mLayoutToAnim.mLowerWallpaperTarget != null - || mLayoutToAnim.mUpperWallpaperTarget != null) { - pw.print(" mLowerWallpaperTarget="); - pw.println(mLayoutToAnim.mLowerWallpaperTarget); - pw.print(" mUpperWallpaperTarget="); - pw.println(mLayoutToAnim.mUpperWallpaperTarget); - } - for (int i=0; i<mLayoutToAnim.mWinAnimatorLists.size(); i++) { - pw.print(" Win Animator List #"); - pw.print(mLayoutToAnim.mWinAnimatorLists.keyAt(i)); pw.println(":"); - WinAnimatorList wanim = mLayoutToAnim.mWinAnimatorLists.valueAt(i); - for (int wi=0; wi<wanim.size(); wi++) { - pw.print(" "); pw.println(wanim.get(wi)); - } - } - for (int i=0; i<mLayoutToAnim.mWallpaperTokens.size(); i++) { - pw.print(" Wallpaper Token #"); pw.print(i); pw.print(": "); - pw.println(mLayoutToAnim.mWallpaperTokens.get(i)); - } - // XXX also need to print mDimParams and mAppWindowAnimParams. I am lazy. mAppTransition.dump(pw); } } @@ -10250,6 +10107,7 @@ public class WindowManagerService extends IWindowManager.Stub } // Called by the heartbeat to ensure locks are not held indefnitely (for deadlock detection). + @Override public void monitor() { synchronized (mWindowMap) { } } @@ -10391,7 +10249,16 @@ public class WindowManagerService extends IWindowManager.Stub * @return The list of WindowStates on the screen, or null if the there is no screen. */ public WindowList getWindowListLocked(final Display display) { - final DisplayContent displayContent = getDisplayContentLocked(display.getDisplayId()); + return getWindowListLocked(display.getDisplayId()); + } + + /** + * Return the list of WindowStates associated on the passed display. + * @param displayId The screen to return windows from. + * @return The list of WindowStates on the screen, or null if the there is no screen. + */ + public WindowList getWindowListLocked(final int displayId) { + final DisplayContent displayContent = getDisplayContentLocked(displayId); return displayContent != null ? displayContent.getWindowList() : null; } diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java index 541e8594bb8a..cc658c254aaf 100644 --- a/services/java/com/android/server/wm/WindowState.java +++ b/services/java/com/android/server/wm/WindowState.java @@ -730,7 +730,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { final AppWindowToken atoken = mAppToken; if (atoken != null) { return ((!mAttachedHidden && !atoken.hiddenRequested) - || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); + || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null); } return !mAttachedHidden || mWinAnimator.mAnimation != null; } @@ -811,6 +811,17 @@ final class WindowState implements WindowManagerPolicy.WindowState { * Returns true if the window has a surface that it has drawn a * complete UI in to. */ + public boolean isDrawFinishedLw() { + return mHasSurface && !mDestroying && + (mWinAnimator.mDrawState == WindowStateAnimator.COMMIT_DRAW_PENDING + || mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW + || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN); + } + + /** + * Returns true if the window has a surface that it has drawn a + * complete UI in to. + */ public boolean isDrawnLw() { return mHasSurface && !mDestroying && (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW @@ -872,8 +883,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow); mAttachedWindow.mChildWindows.remove(this); } - mWinAnimator.destroyDeferredSurfaceLocked(false); - mWinAnimator.destroySurfaceLocked(false); + mWinAnimator.destroyDeferredSurfaceLocked(); + mWinAnimator.destroySurfaceLocked(); mSession.windowRemovedLocked(); try { mClient.asBinder().unlinkToDeath(mDeathRecipient, 0); @@ -974,7 +985,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true); } if (requestAnim) { - mService.updateLayoutToAnimationLocked(); + mService.scheduleAnimationLocked(); } return true; } @@ -1017,7 +1028,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } if (requestAnim) { - mService.updateLayoutToAnimationLocked(); + mService.scheduleAnimationLocked(); } return true; } diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 3c9424a7e0be..e03e40deacf9 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -226,7 +226,7 @@ class WindowStateAnimator { mAnimation.cancel(); mAnimation = null; mLocalAnimating = false; - destroySurfaceLocked(true); + destroySurfaceLocked(); } } @@ -369,7 +369,7 @@ class WindowStateAnimator { final int displayId = mWin.mDisplayContent.getDisplayId(); mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats( - "WindowStateAnimator", mAnimator.mPendingLayoutChanges.get(displayId)); + "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId)); if (mWin.mAppToken != null) { mWin.mAppToken.updateReportedVisibilityLocked(); @@ -413,7 +413,7 @@ class WindowStateAnimator { mService.mPendingRemove.add(mWin); mWin.mRemoveOnExit = false; } - mAnimator.hideWallpapersLocked(mWin, true); + mAnimator.hideWallpapersLocked(mWin); } void hide() { @@ -752,7 +752,7 @@ class WindowStateAnimator { return mSurface; } - void destroySurfaceLocked(boolean fromAnimator) { + void destroySurfaceLocked() { if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) { mWin.mAppToken.startingDisplayed = false; } @@ -802,7 +802,7 @@ class WindowStateAnimator { } mSurface.destroy(); } - mAnimator.hideWallpapersLocked(mWin, fromAnimator); + mAnimator.hideWallpapersLocked(mWin); } catch (RuntimeException e) { Slog.w(TAG, "Exception thrown when destroying Window " + this + " surface " + mSurface + " session " + mSession @@ -816,7 +816,7 @@ class WindowStateAnimator { } } - void destroyDeferredSurfaceLocked(boolean fromAnimator) { + void destroyDeferredSurfaceLocked() { try { if (mPendingDestroySurface != null) { if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) { @@ -828,7 +828,7 @@ class WindowStateAnimator { WindowManagerService.logSurface(mWin, "DESTROY PENDING", e); } mPendingDestroySurface.destroy(); - mAnimator.hideWallpapersLocked(mWin, fromAnimator); + mAnimator.hideWallpapersLocked(mWin); } } catch (RuntimeException e) { Slog.w(TAG, "Exception thrown when destroying Window " @@ -849,9 +849,9 @@ class WindowStateAnimator { // Wallpapers are animated based on the "real" window they // are currently targeting. - if (mIsWallpaper && mAnimator.mLowerWallpaperTarget == null - && mAnimator.mWallpaperTarget != null) { - final WindowStateAnimator wallpaperAnimator = mAnimator.mWallpaperTarget.mWinAnimator; + if (mIsWallpaper && mService.mLowerWallpaperTarget == null + && mService.mWallpaperTarget != null) { + final WindowStateAnimator wallpaperAnimator = mService.mWallpaperTarget.mWinAnimator; if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) { @@ -860,7 +860,7 @@ class WindowStateAnimator { Slog.v(TAG, "WP target attached xform: " + attachedTransformation); } } - final AppWindowAnimator wpAppAnimator = mAnimator.mWpAppAnimator; + final AppWindowAnimator wpAppAnimator = mAnimator.getWallpaperAppAnimator(); if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) { @@ -986,8 +986,7 @@ class WindowStateAnimator { + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null")); return; - } else if (mIsWallpaper && - (mAnimator.mPendingActions & WindowAnimator.WALLPAPER_ACTION_PENDING) != 0) { + } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) { return; } @@ -1220,7 +1219,7 @@ class WindowStateAnimator { hide(); } else if (w.mAttachedHidden || !w.isReadyForDisplay()) { hide(); - mAnimator.hideWallpapersLocked(w, true); + mAnimator.hideWallpapersLocked(w); // If we are waiting for this window to handle an // orientation change, well, it is hidden, so @@ -1414,7 +1413,7 @@ class WindowStateAnimator { if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this); mDrawState = HAS_DRAWN; - mService.updateLayoutToAnimationLocked(); + mService.scheduleAnimationLocked(); int i = mWin.mChildWindows.size(); while (i > 0) { diff --git a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java index 84c995719a84..00c3a6728479 100644 --- a/core/tests/coretests/src/android/accounts/AccountManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java @@ -14,8 +14,10 @@ * limitations under the License. */ -package android.accounts; +package com.android.server.accounts; +import android.accounts.Account; +import android.accounts.AuthenticatorDescription; import android.app.Notification; import android.content.Context; import android.content.pm.PackageManager; diff --git a/core/tests/coretests/src/android/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java index 1acff9c185fd..5b70c17ae28d 100644 --- a/core/tests/coretests/src/android/content/ObserverNodeTest.java +++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java @@ -14,18 +14,19 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; import java.util.ArrayList; -import android.content.ContentService.ObserverCall; -import android.content.ContentService.ObserverNode; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; import android.os.UserHandle; import android.test.AndroidTestCase; +import com.android.server.content.ContentService.ObserverCall; +import com.android.server.content.ContentService.ObserverNode; + public class ObserverNodeTest extends AndroidTestCase { static class TestObserver extends ContentObserver { public TestObserver() { diff --git a/core/tests/coretests/src/android/content/SyncOperationTest.java b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java index 1fd25d23d32c..f2772c8d13ee 100644 --- a/core/tests/coretests/src/android/content/SyncOperationTest.java +++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java @@ -14,13 +14,15 @@ * limitations under the License. */ -package android.content; +package com.android.server; import android.accounts.Account; import android.os.Bundle; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; +import com.android.server.content.SyncOperation; + /** * You can run those tests with: * diff --git a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java index 58d232777ad2..8b00f2c2ce11 100644 --- a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java +++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java @@ -14,9 +14,14 @@ * limitations under the License. */ -package android.content; +package com.android.server.content; import android.accounts.Account; +import android.content.ContentResolver; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.PeriodicSync; import android.os.Bundle; import android.test.AndroidTestCase; import android.test.RenamingDelegatingContext; diff --git a/core/tests/coretests/src/android/app/SearchablesTest.java b/services/tests/servicestests/src/com/android/server/search/SearchablesTest.java index 4d3b1441e0ef..79b9135d9466 100644 --- a/core/tests/coretests/src/android/app/SearchablesTest.java +++ b/services/tests/servicestests/src/com/android/server/search/SearchablesTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package android.app; +package com.android.server.search; import android.app.SearchManager; import android.app.SearchableInfo; @@ -30,7 +30,7 @@ import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.RemoteException; -import android.server.search.Searchables; +import com.android.server.search.Searchables; import android.test.AndroidTestCase; import android.test.MoreAsserts; import android.test.mock.MockContext; diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index 10ac15390e8f..80c985f1d5c5 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -23,7 +23,6 @@ import com.android.internal.util.Protocol; public class DctConstants { /** * IDLE: ready to start data connection setup, default state - * INITING: state of issued setupDefaultPDP() but not finish yet * CONNECTING: state of issued startPppd() but not finish yet * SCANNING: data connection fails with one apn but other apns are available * ready to start data connection on other apns (before INITING) @@ -34,12 +33,11 @@ public class DctConstants { * * getDataConnectionState() maps State to DataState * FAILED or IDLE : DISCONNECTED - * INITING or CONNECTING or SCANNING: CONNECTING + * CONNECTING or SCANNING: CONNECTING * CONNECTED : CONNECTED or DISCONNECTING */ public enum State { IDLE, - INITING, CONNECTING, SCANNING, CONNECTED, @@ -113,4 +111,3 @@ public class DctConstants { "com.android.internal.telephony"; public static String EXTRA_MESSENGER = "EXTRA_MESSENGER"; } - diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java index 80e0f1a7e353..f3cf1b773ca1 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Contrast.java @@ -28,7 +28,7 @@ public class Contrast extends TestBase { } public void runTest() { - mScript.set_bright(50.f); + mScript.invoke_setBright(50.f); mScript.forEach_contrast(mInPixelsAllocation, mOutPixelsAllocation); } diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java index 6aad4be53eb6..bec53abef441 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/Exposure.java @@ -28,7 +28,7 @@ public class Exposure extends TestBase { } public void runTest() { - mScript.set_bright(50.f); + mScript.invoke_setBright(50.f); mScript.forEach_exposure(mInPixelsAllocation, mOutPixelsAllocation); } diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs index 80a626ad5abf..2818bf5b1d06 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/bwfilter.rs @@ -48,6 +48,6 @@ void bwFilterKernel(const uchar4 *in, uchar4 *out) { localMin = fmin(r,localMin); localMax = fmax(g,b); localMax = fmax(r,localMax); - avg =(localMin+localMax)/2; + avg = (localMin+localMax) * 0.5f; out->r = out->g = out->b = rsClamp(avg, 0, 255); } diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs index 987315ee63ee..5fd7be1f3db2 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/contrast.rs @@ -16,27 +16,24 @@ #pragma version(1) #pragma rs java_package_name(com.android.rs.image) -#pragma rs_fp_relaxed +#pragma rs_fp_full -float bright = 0.f; +static float brightM = 0.f; +static float brightC = 0.f; -static unsigned char contrastClamp(int c) -{ - int N = 255; - c &= ~(c >> 31); - c -= N; - c &= (c >> 31); - c += N; - return (unsigned char) c; +void setBright(float v) { + brightM = pow(2.f, v / 100.f); + brightC = 127.f - brightM * 127.f; } void contrast(const uchar4 *in, uchar4 *out) { - float m = (float)pow(2, bright/100.f); - float c = 127-m*127; - - out->r = contrastClamp((int)(m*in->r+c)); - out->g = contrastClamp((int)(m*in->g+c)); - out->b = contrastClamp((int)(m*in->b+c)); - +#if 0 + out->r = rsClamp((int)(brightM * in->r + brightC), 0, 255); + out->g = rsClamp((int)(brightM * in->g + brightC), 0, 255); + out->b = rsClamp((int)(brightM * in->b + brightC), 0, 255); +#else + float3 v = convert_float3(in->rgb) * brightM + brightC; + out->rgb = convert_uchar3(clamp(v, 0.f, 255.f)); +#endif } diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs index d15fd87ced20..adfae4ae87b7 100644 --- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs +++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/exposure.rs @@ -16,24 +16,18 @@ #pragma version(1) #pragma rs java_package_name(com.android.rs.image) -#pragma rs_fp_relaxed +#pragma rs_fp_full -float bright = 0.f; +static float bright = 0.f; -static unsigned char contrastClamp(int c) -{ - int N = 255; - c &= ~(c >> 31); - c -= N; - c &= (c >> 31); - c += N; - return (unsigned char) c; +void setBright(float v) { + bright = 255.f / (255.f - v); } void exposure(const uchar4 *in, uchar4 *out) { - int m = 255 - bright; - out->r = contrastClamp((255 * in->r)/m); - out->g = contrastClamp((255 * in->g)/m); - out->b = contrastClamp((255 * in->b)/m); + out->r = rsClamp((int)(bright * in->r), 0, 255); + out->g = rsClamp((int)(bright * in->g), 0, 255); + out->b = rsClamp((int)(bright * in->b), 0, 255); } + diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java index 7662007cab19..8645ae584811 100644 --- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java @@ -84,6 +84,7 @@ public class RSTestCore { unitTests.add(new UT_alloc(this, mRes, mCtx)); unitTests.add(new UT_refcount(this, mRes, mCtx)); unitTests.add(new UT_foreach(this, mRes, mCtx)); + unitTests.add(new UT_foreach_bounds(this, mRes, mCtx)); unitTests.add(new UT_noroot(this, mRes, mCtx)); unitTests.add(new UT_atomic(this, mRes, mCtx)); unitTests.add(new UT_struct(this, mRes, mCtx)); diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java new file mode 100644 index 000000000000..bda055b4c10b --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_foreach_bounds.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.rs.test; + +import android.content.Context; +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_foreach_bounds extends UnitTest { + private Resources mRes; + private Allocation A; + + protected UT_foreach_bounds(RSTestCore rstc, Resources res, Context ctx) { + super(rstc, "ForEach (bounds)", ctx); + mRes = res; + } + + private void initializeGlobals(RenderScript RS, ScriptC_foreach_bounds s) { + Type.Builder typeBuilder = new Type.Builder(RS, Element.I32(RS)); + int X = 5; + int Y = 7; + s.set_dimX(X); + s.set_dimY(Y); + typeBuilder.setX(X).setY(Y); + A = Allocation.createTyped(RS, typeBuilder.create()); + s.bind_a(A); + s.set_s(s); + s.set_ain(A); + s.set_aout(A); + s.set_xStart(2); + s.set_xEnd(5); + s.set_yStart(3); + s.set_yEnd(6); + s.forEach_zero(A); + + return; + } + + public void run() { + RenderScript pRS = RenderScript.create(mCtx); + ScriptC_foreach_bounds s = new ScriptC_foreach_bounds(pRS); + pRS.setMessageHandler(mRsMessage); + initializeGlobals(pRS, s); + s.invoke_foreach_bounds_test(); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs new file mode 100644 index 000000000000..ddf17f81e5ec --- /dev/null +++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/foreach_bounds.rs @@ -0,0 +1,71 @@ +#include "shared.rsh" + +int *a; +int dimX; +int dimY; +int xStart = 0; +int xEnd = 0; +int yStart = 0; +int yEnd = 0; + +rs_script s; +rs_allocation ain; +rs_allocation aout; + +void root(int *out, uint32_t x, uint32_t y) { + *out = x + y * dimX; +} + +int __attribute__((kernel)) zero() { + return 0; +} + +static bool test_root_output() { + bool failed = false; + int i, j; + + for (j = 0; j < dimY; j++) { + for (i = 0; i < dimX; i++) { + rsDebug("i: ", i); + rsDebug("j: ", j); + rsDebug("a[j][i]: ", a[i + j * dimX]); + if (i < xStart || i >= xEnd || j < yStart || j >= yEnd) { + _RS_ASSERT(a[i + j * dimX] == 0); + } else { + _RS_ASSERT(a[i + j * dimX] == (i + j * dimX)); + } + } + } + + if (failed) { + rsDebug("test_root_output FAILED", 0); + } + else { + rsDebug("test_root_output PASSED", 0); + } + + return failed; +} + +void foreach_bounds_test() { + static bool failed = false; + + rs_script_call_t rssc = {0}; + rssc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE; + rssc.xStart = xStart; + rssc.xEnd = xEnd; + rssc.yStart = yStart; + rssc.yEnd = yEnd; + + rsForEach(s, ain, aout, NULL, 0, &rssc); + + failed |= test_root_output(); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 7d71539596bf..ad5258558840 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -26,6 +26,7 @@ import java.util.regex.Matcher; /** * A class representing a Wi-Fi p2p device * + * Note that the operations are not thread safe * {@see WifiP2pManager} */ public class WifiP2pDevice implements Parcelable { @@ -260,9 +261,29 @@ public class WifiP2pDevice implements Parcelable { return (groupCapability & GROUP_CAPAB_GROUP_LIMIT) != 0; } - /** @hide */ + /** + * Update device details. This will be throw an exception if the device address + * does not match. + * @param device to be updated + * @throws IllegalArgumentException if the device is null or device address does not match + * @hide + */ public void update(WifiP2pDevice device) { - if (device == null || device.deviceAddress == null) return; + updateSupplicantDetails(device); + status = device.status; + } + + /** Updates details obtained from supplicant @hide */ + void updateSupplicantDetails(WifiP2pDevice device) { + if (device == null) { + throw new IllegalArgumentException("device is null"); + } + if (device.deviceAddress == null) { + throw new IllegalArgumentException("deviceAddress is null"); + } + if (!deviceAddress.equals(device.deviceAddress)) { + throw new IllegalArgumentException("deviceAddress does not match"); + } deviceName = device.deviceName; primaryDeviceType = device.primaryDeviceType; secondaryDeviceType = device.secondaryDeviceType; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index f14c3052f765..f7bceacb8cb4 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -58,16 +58,28 @@ public class WifiP2pDeviceList implements Parcelable { } } - /** @hide */ + /** Clear the list @hide */ public boolean clear() { if (mDevices.isEmpty()) return false; mDevices.clear(); return true; } - /** @hide */ + /** + * Add/update a device to the list. If the device is not found, a new device entry + * is created. If the device is already found, the device details are updated + * @param device to be updated + * @hide + */ public void update(WifiP2pDevice device) { if (device == null || device.deviceAddress == null) return; + updateSupplicantDetails(device); + mDevices.get(device.deviceAddress).status = device.status; + } + + /** Only updates details fetched from the supplicant @hide */ + void updateSupplicantDetails(WifiP2pDevice device) { + if (device == null || device.deviceAddress == null) return; WifiP2pDevice d = mDevices.get(device.deviceAddress); if (d != null) { d.deviceName = device.deviceName; @@ -84,7 +96,7 @@ public class WifiP2pDeviceList implements Parcelable { } /** @hide */ - public void updateGroupCapability(String deviceAddress, int groupCapab) { + void updateGroupCapability(String deviceAddress, int groupCapab) { if (TextUtils.isEmpty(deviceAddress)) return; WifiP2pDevice d = mDevices.get(deviceAddress); if (d != null) { @@ -93,7 +105,7 @@ public class WifiP2pDeviceList implements Parcelable { } /** @hide */ - public void updateStatus(String deviceAddress, int status) { + void updateStatus(String deviceAddress, int status) { if (TextUtils.isEmpty(deviceAddress)) return; WifiP2pDevice d = mDevices.get(deviceAddress); if (d != null) { @@ -101,7 +113,11 @@ public class WifiP2pDeviceList implements Parcelable { } } - /** @hide */ + /** + * Fetch a device from the list + * @param deviceAddress is the address of the device + * @return WifiP2pDevice device found, or null if none found + */ public WifiP2pDevice get(String deviceAddress) { if (deviceAddress == null) return null; @@ -114,6 +130,17 @@ public class WifiP2pDeviceList implements Parcelable { return mDevices.remove(device.deviceAddress) != null; } + /** + * Remove a device from the list + * @param deviceAddress is the address of the device + * @return WifiP2pDevice device removed, or null if none removed + * @hide + */ + public WifiP2pDevice remove(String deviceAddress) { + if (deviceAddress == null) return null; + return mDevices.remove(deviceAddress); + } + /** Returns true if any device the list was removed @hide */ public boolean remove(WifiP2pDeviceList list) { boolean ret = false; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index cf7604d8a074..ca737f9e64d9 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -27,7 +27,9 @@ import java.util.regex.Pattern; import java.util.regex.Matcher; /** - * A class representing a Wi-Fi P2p group + * A class representing a Wi-Fi P2p group. A p2p group consists of a single group + * owner and one or more clients. In the case of a group with only two devices, one + * will be the group owner and the other will be a group client. * * {@see WifiP2pManager} */ diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index d79421fa008e..5bd0349f3a0b 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -171,10 +171,12 @@ public class WifiP2pManager { * Broadcast intent action indicating that the state of Wi-Fi p2p connectivity * has changed. One extra {@link #EXTRA_WIFI_P2P_INFO} provides the p2p connection info in * the form of a {@link WifiP2pInfo} object. Another extra {@link #EXTRA_NETWORK_INFO} provides - * the network info in the form of a {@link android.net.NetworkInfo}. + * the network info in the form of a {@link android.net.NetworkInfo}. A third extra provides + * the details of the group. * * @see #EXTRA_WIFI_P2P_INFO * @see #EXTRA_NETWORK_INFO + * @see #EXTRA_WIFI_P2P_GROUP */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = @@ -188,41 +190,46 @@ public class WifiP2pManager { /** * The lookup key for a {@link android.net.NetworkInfo} object associated with the - * Wi-Fi network. Retrieve with + * p2p network. Retrieve with * {@link android.content.Intent#getParcelableExtra(String)}. */ public static final String EXTRA_NETWORK_INFO = "networkInfo"; /** - * The lookup key for a {@link android.net.LinkProperties} object associated with the - * network. Retrieve with + * The lookup key for a {@link android.net.wifi.p2p.WifiP2pGroup} object + * associated with the p2p network. Retrieve with * {@link android.content.Intent#getParcelableExtra(String)}. - * @hide */ - public static final String EXTRA_LINK_PROPERTIES = "linkProperties"; + public static final String EXTRA_WIFI_P2P_GROUP = "p2pGroupInfo"; /** - * The lookup key for a {@link android.net.LinkCapabilities} object associated with the - * network. Retrieve with - * {@link android.content.Intent#getParcelableExtra(String)}. - * @hide - */ - public static final String EXTRA_LINK_CAPABILITIES = "linkCapabilities"; - - /** - * Broadcast intent action indicating that the available peer list has changed. Fetch - * the changed list of peers with {@link #requestPeers} + * Broadcast intent action indicating that the available peer list has changed. This + * can be sent as a result of peers being found, lost or updated. + * + * <p> An extra {@link #EXTRA_P2P_DEVICE_LIST} provides the full list of + * current peers. The full list of peers can also be obtained any time with + * {@link #requestPeers}. + * + * @see #EXTRA_P2P_DEVICE_LIST */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_P2P_PEERS_CHANGED_ACTION = "android.net.wifi.p2p.PEERS_CHANGED"; + /** + * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDeviceList} object representing + * the new peer list when {@link #WIFI_P2P_PEERS_CHANGED_ACTION} broadcast is sent. + * + * <p>Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. + */ + public static final String EXTRA_P2P_DEVICE_LIST = "wifiP2pDeviceList"; + /** * Broadcast intent action indicating that peer discovery has either started or stopped. * One extra {@link #EXTRA_DISCOVERY_STATE} indicates whether discovery has started * or stopped. * - * Note that discovery will be stopped during a connection setup. If the application tries + * <p>Note that discovery will be stopped during a connection setup. If the application tries * to re-initiate discovery during this time, it can fail. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index ccd983ddb598..c1d177d68046 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -791,7 +791,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { //Nothing to do break; case WifiStateMachine.CMD_DISABLE_P2P_REQ: - if (mPeers.clear()) sendP2pPeersChangedBroadcast(); + if (mPeers.clear()) { + sendPeersChangedBroadcast(); + } if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast(); mWifiNative.closeSupplicantConnection(); @@ -859,12 +861,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_DEVICE_FOUND_EVENT: WifiP2pDevice device = (WifiP2pDevice) message.obj; if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break; - mPeers.update(device); - sendP2pPeersChangedBroadcast(); + mPeers.updateSupplicantDetails(device); + sendPeersChangedBroadcast(); break; case WifiMonitor.P2P_DEVICE_LOST_EVENT: device = (WifiP2pDevice) message.obj; - if (mPeers.remove(device)) sendP2pPeersChangedBroadcast(); + // Gets current details for the one removed + device = mPeers.remove(device.deviceAddress); + if (device != null) { + sendPeersChangedBroadcast(); + } break; case WifiP2pManager.ADD_LOCAL_SERVICE: if (DBG) logd(getName() + " add service"); @@ -960,7 +966,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { break; } mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED); - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED); if (connectRet == NEEDS_PROVISION_REQ) { if (DBG) logd("Sending prov disc"); @@ -1106,7 +1112,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } // Do nothing if (DBG) logd("Add device to lost list " + device); - mPeersLostDuringConnection.update(device); + mPeersLostDuringConnection.updateSupplicantDetails(device); break; case WifiP2pManager.DISCOVER_PEERS: /* Discovery will break negotiation */ @@ -1150,7 +1156,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { break; } mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED); - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); transitionTo(mGroupNegotiationState); break; case PEER_CONNECTION_USER_REJECT: @@ -1282,9 +1288,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP); WifiP2pDevice groupOwner = mGroup.getOwner(); /* update group owner details with the ones found at discovery */ - groupOwner.update(mPeers.get(groupOwner.deviceAddress)); + groupOwner.updateSupplicantDetails(mPeers.get(groupOwner.deviceAddress)); mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED); - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); } mSavedPeerConfig = null; transitionTo(mGroupCreatedState); @@ -1477,7 +1483,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED); if (DBG) logd(getName() + " ap sta connected"); - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); } else { loge("Connect on null device address, ignore"); } @@ -1505,7 +1511,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { if (DBG) logd("client " + c.deviceAddress); } } - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); if (DBG) logd(getName() + " ap sta disconnected"); } else { loge("Disconnect on unknown device: " + device); @@ -1558,7 +1564,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { //Device loss for a connected device indicates it is not in discovery any more if (mGroup.contains(device)) { if (DBG) logd("Add device to lost list " + device); - mPeersLostDuringConnection.update(device); + mPeersLostDuringConnection.updateSupplicantDetails(device); return HANDLED; } // Do the regular device lost handling @@ -1595,7 +1601,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mSavedPeerConfig = config; if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) { mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED); - sendP2pPeersChangedBroadcast(); + sendPeersChangedBroadcast(); replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED); } else { replyToMessage(message, WifiP2pManager.CONNECT_FAILED, @@ -1771,8 +1777,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void sendP2pPeersChangedBroadcast() { + private void sendPeersChangedBroadcast() { final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); + intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, mPeers); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); } @@ -1784,6 +1791,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { | Intent.FLAG_RECEIVER_REPLACE_PENDING); intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo)); intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo)); + intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, new WifiP2pGroup(mGroup)); mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); mWifiChannel.sendMessage(WifiP2pService.P2P_CONNECTION_CHANGED, new NetworkInfo(mNetworkInfo)); @@ -2311,26 +2319,24 @@ public class WifiP2pService extends IWifiP2pManager.Stub { resetWifiP2pInfo(); mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null); sendP2pConnectionChangedBroadcast(); + + // Remove only the peer we failed to connect to so that other devices discovered + // that have not timed out still remain in list for connection + boolean peersChanged = mPeers.remove(mPeersLostDuringConnection); + if (mSavedPeerConfig != null && mPeers.remove(mSavedPeerConfig.deviceAddress) != null) { + peersChanged = true; + } + if (peersChanged) { + sendPeersChangedBroadcast(); + } + mSavedPeerConfig = null; - /* After cancelling group formation, new connections on existing peers can fail - * at supplicant. Flush and restart discovery */ - mWifiNative.p2pFlush(); - if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast(); mPeersLostDuringConnection.clear(); mServiceDiscReqId = null; sendMessage(WifiP2pManager.DISCOVER_PEERS); } private void handleGroupRemoved() { - Collection <WifiP2pDevice> devices = mGroup.getClientList(); - boolean changed = false; - for (WifiP2pDevice d : mPeers.getDeviceList()) { - if (devices.contains(d) || mGroup.getOwner().equals(d)) { - d.status = WifiP2pDevice.AVAILABLE; - changed = true; - } - } - if (mGroup.isGroupOwner()) { stopDhcpServer(mGroup.getInterface()); } else { @@ -2351,12 +2357,21 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // that reuse the main p2p interface for a created group. mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0); + boolean peersChanged = false; + // Remove only peers part of the group, so that other devices discovered + // that have not timed out still remain in list for connection + for (WifiP2pDevice d : mGroup.getClientList()) { + if (mPeers.remove(d)) peersChanged = true; + } + if (mPeers.remove(mGroup.getOwner())) peersChanged = true; + if (mPeers.remove(mPeersLostDuringConnection)) peersChanged = true; + if (peersChanged) { + sendPeersChangedBroadcast(); + } + mGroup = null; - mWifiNative.p2pFlush(); - if (mPeers.remove(mPeersLostDuringConnection)) sendP2pPeersChangedBroadcast(); mPeersLostDuringConnection.clear(); mServiceDiscReqId = null; - if (changed) sendP2pPeersChangedBroadcast(); if (mTempoarilyDisconnectedWifi) { mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 0); |