diff options
51 files changed, 928 insertions, 625 deletions
diff --git a/api/current.txt b/api/current.txt index 20a1657..6960cff 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2006,26 +2006,24 @@ package android.accessibilityservice { method protected void onServiceConnected(); method public final boolean performGlobalAction(int); method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo); - field public static final int GESTURE_CLOCKWISE_CIRCLE = 9; // 0x9 - field public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10; // 0xa field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2 - field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17; // 0x11 - field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; // 0x12 + field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf + field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10 field public static final int GESTURE_SWIPE_DOWN_AND_UP = 8; // 0x8 field public static final int GESTURE_SWIPE_LEFT = 3; // 0x3 - field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12; // 0xc + field public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 10; // 0xa field public static final int GESTURE_SWIPE_LEFT_AND_RIGHT = 5; // 0x5 - field public static final int GESTURE_SWIPE_LEFT_AND_UP = 11; // 0xb + field public static final int GESTURE_SWIPE_LEFT_AND_UP = 9; // 0x9 field public static final int GESTURE_SWIPE_RIGHT = 4; // 0x4 - field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14; // 0xe + field public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 12; // 0xc field public static final int GESTURE_SWIPE_RIGHT_AND_LEFT = 6; // 0x6 - field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13; // 0xd + field public static final int GESTURE_SWIPE_RIGHT_AND_UP = 11; // 0xb field public static final int GESTURE_SWIPE_UP = 1; // 0x1 field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7 - field public static final int GESTURE_SWIPE_UP_AND_LEFT = 15; // 0xf - field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16; // 0x10 - field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20; // 0x14 - field public static final int GESTURE_TWO_FINGER_TAP = 19; // 0x13 + field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd + field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe + field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; // 0x12 + field public static final int GESTURE_TWO_FINGER_TAP = 17; // 0x11 field public static final int GLOBAL_ACTION_BACK = 1; // 0x1 field public static final int GLOBAL_ACTION_HOME = 2; // 0x2 field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4 @@ -3750,23 +3748,24 @@ package android.app { field public long when; } - public static class Notification.BigPictureStyle { + public static class Notification.BigPictureStyle extends android.app.Notification.Style { + ctor public Notification.BigPictureStyle(); ctor public Notification.BigPictureStyle(android.app.Notification.Builder); method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap); - method public android.app.Notification build(); } - public static class Notification.BigTextStyle { + public static class Notification.BigTextStyle extends android.app.Notification.Style { + ctor public Notification.BigTextStyle(); ctor public Notification.BigTextStyle(android.app.Notification.Builder); method public android.app.Notification.BigTextStyle bigText(java.lang.CharSequence); - method public android.app.Notification build(); } public static class Notification.Builder { ctor public Notification.Builder(android.content.Context); method public android.app.Notification.Builder addAction(int, java.lang.CharSequence, android.app.PendingIntent); method public android.app.Notification.Builder addKind(java.lang.String); - method public android.app.Notification getNotification(); + method public android.app.Notification build(); + method public deprecated android.app.Notification getNotification(); method public android.app.Notification.Builder setAutoCancel(boolean); method public android.app.Notification.Builder setContent(android.widget.RemoteViews); method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence); @@ -3787,6 +3786,7 @@ package android.app { method public android.app.Notification.Builder setSmallIcon(int, int); method public android.app.Notification.Builder setSound(android.net.Uri); method public android.app.Notification.Builder setSound(android.net.Uri, int); + method public android.app.Notification.Builder setStyle(android.app.Notification.Style); method public android.app.Notification.Builder setSubText(java.lang.CharSequence); method public android.app.Notification.Builder setTicker(java.lang.CharSequence); method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews); @@ -3795,10 +3795,17 @@ package android.app { method public android.app.Notification.Builder setWhen(long); } - public static class Notification.InboxStyle { + public static class Notification.InboxStyle extends android.app.Notification.Style { + ctor public Notification.InboxStyle(); ctor public Notification.InboxStyle(android.app.Notification.Builder); method public android.app.Notification.InboxStyle addLine(java.lang.CharSequence); + } + + public static class Notification.Style { + ctor public Notification.Style(); method public android.app.Notification build(); + method public void setBuilder(android.app.Notification.Builder); + field protected android.app.Notification.Builder mBuilder; } public class NotificationManager { @@ -22519,6 +22526,7 @@ package android.view { method public abstract java.lang.CharSequence getSubtitle(); method public java.lang.Object getTag(); method public abstract java.lang.CharSequence getTitle(); + method public boolean getTitleOptionalHint(); method public abstract void invalidate(); method public boolean isTitleOptional(); method public abstract void setCustomView(android.view.View); diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index c858e3c..b644dd1 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -244,64 +244,54 @@ public abstract class AccessibilityService extends Service { public static final int GESTURE_SWIPE_DOWN_AND_UP = 8; /** - * The user has performed a clockwise circle gesture on the touch screen. - */ - public static final int GESTURE_CLOCKWISE_CIRCLE = 9; - - /** - * The user has performed a counter clockwise circle gesture on the touch screen. - */ - public static final int GESTURE_COUNTER_CLOCKWISE_CIRCLE = 10; - - /** * The user has performed a left and up gesture on the touch screen. */ - public static final int GESTURE_SWIPE_LEFT_AND_UP = 11; + public static final int GESTURE_SWIPE_LEFT_AND_UP = 9; /** * The user has performed a left and down gesture on the touch screen. */ - public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 12; + public static final int GESTURE_SWIPE_LEFT_AND_DOWN = 10; /** * The user has performed a right and up gesture on the touch screen. */ - public static final int GESTURE_SWIPE_RIGHT_AND_UP = 13; + public static final int GESTURE_SWIPE_RIGHT_AND_UP = 11; /** * The user has performed a right and down gesture on the touch screen. */ - public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 14; + public static final int GESTURE_SWIPE_RIGHT_AND_DOWN = 12; /** * The user has performed an up and left gesture on the touch screen. */ - public static final int GESTURE_SWIPE_UP_AND_LEFT = 15; + public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; /** * The user has performed an up and right gesture on the touch screen. */ - public static final int GESTURE_SWIPE_UP_AND_RIGHT = 16; + public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; /** * The user has performed an down and left gesture on the touch screen. */ - public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 17; + public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; /** * The user has performed an down and right gesture on the touch screen. */ - public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 18; + public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; /** * The user has performed a two finger tap gesture on the touch screen. */ - public static final int GESTURE_TWO_FINGER_TAP = 19; + public static final int GESTURE_TWO_FINGER_TAP = 17; /** * The user has performed a two finger long press gesture on the touch screen. */ - public static final int GESTURE_TWO_FINGER_LONG_PRESS = 20; + public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; /** * The {@link Intent} that must be declared as handled by the service. diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 3ae286f..8d6a496 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2742,6 +2742,10 @@ public class Activity extends ContextThemeWrapper * may choose to override this method to construct the desired task stack in a different * way.</p> * + * <p>This method will be invoked by the default implementation of {@link #onNavigateUp()} + * if {@link #shouldUpRecreateTask(Intent)} returns true when supplied with the intent + * returned by {@link #getParentActivityIntent()}.</p> + * * <p>Applications that wish to supply extra Intent parameters to the parent stack defined * by the manifest should override {@link #onPrepareNavigateUpTaskStack(TaskStackBuilder)}.</p> * diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index c62e5cf..3f0b4d4 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -16,17 +16,20 @@ package android.app; -import com.android.internal.R; - import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; +import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.DatePicker; import android.widget.DatePicker.OnDateChangedListener; +import com.android.internal.R; + +import java.util.Calendar; + /** * A simple dialog containing an {@link android.widget.DatePicker}. * @@ -42,6 +45,9 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, private final DatePicker mDatePicker; private final OnDateSetListener mCallBack; + private final Calendar mCalendar; + + private boolean mTitleNeedsUpdate = true; /** * The callback used to indicate the user is done filling in the date. @@ -91,10 +97,11 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, mCallBack = callBack; + mCalendar = Calendar.getInstance(); + Context themeContext = getContext(); setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this); setIcon(0); - setTitle(R.string.date_picker_dialog_title); LayoutInflater inflater = (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); @@ -102,6 +109,7 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, setView(view); mDatePicker = (DatePicker) view.findViewById(R.id.datePicker); mDatePicker.init(year, monthOfYear, dayOfMonth, this); + updateTitle(year, monthOfYear, dayOfMonth); } public void onClick(DialogInterface dialog, int which) { @@ -110,7 +118,8 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, public void onDateChanged(DatePicker view, int year, int month, int day) { - mDatePicker.init(year, month, day, null); + mDatePicker.init(year, month, day, this); + updateTitle(year, month, day); } /** @@ -147,6 +156,28 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, super.onStop(); } + private void updateTitle(int year, int month, int day) { + if (!mDatePicker.getCalendarViewShown()) { + mCalendar.set(Calendar.YEAR, year); + mCalendar.set(Calendar.MONTH, month); + mCalendar.set(Calendar.DAY_OF_MONTH, day); + String title = DateUtils.formatDateTime(mContext, + mCalendar.getTimeInMillis(), + DateUtils.FORMAT_SHOW_DATE + | DateUtils.FORMAT_SHOW_WEEKDAY + | DateUtils.FORMAT_SHOW_YEAR + | DateUtils.FORMAT_ABBREV_MONTH + | DateUtils.FORMAT_ABBREV_WEEKDAY); + setTitle(title); + mTitleNeedsUpdate = true; + } else { + if (mTitleNeedsUpdate) { + mTitleNeedsUpdate = false; + setTitle(R.string.date_picker_dialog_title); + } + } + } + @Override public Bundle onSaveInstanceState() { Bundle state = super.onSaveInstanceState(); diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 0713127..93f732c 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -1155,7 +1155,7 @@ public class DownloadManager { validateArgumentIsNonEmpty("description", description); validateArgumentIsNonEmpty("path", path); validateArgumentIsNonEmpty("mimeType", mimeType); - if (length <= 0) { + if (length < 0) { throw new IllegalArgumentException(" invalid value for param: totalBytes"); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 69689c9..8f4efab 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -888,7 +888,7 @@ public class Notification implements Parcelable * .setContentText(subject) * .setSmallIcon(R.drawable.new_mail) * .setLargeIcon(aBitmap) - * .getNotification(); + * .build(); * </pre> */ public static class Builder { @@ -925,6 +925,7 @@ public class Notification implements Parcelable private int mPriority; private ArrayList<Action> mActions = new ArrayList<Action>(3); private boolean mUseChronometer; + private Style mStyle; /** * Constructs a new Builder with the defaults: @@ -1305,7 +1306,7 @@ public class Notification implements Parcelable * Add metadata to this notification. * * A reference to the Bundle is held for the lifetime of this Builder, and the Bundle's - * current contents are copied into the Notification each time {@link #getNotification()} is + * current contents are copied into the Notification each time {@link #build()} is * called. * * @see Notification#extras @@ -1329,6 +1330,19 @@ public class Notification implements Parcelable return this; } + /** + * Add a rich notification style to be applied at build time. + * + * @param style Object responsible for modifying the notification style. + */ + public Builder setStyle(Style style) { + if (mStyle != style) { + mStyle = style; + mStyle.setBuilder(this); + } + return this; + } + private void setFlag(int mask, boolean value) { if (value) { mFlags |= mask; @@ -1464,10 +1478,9 @@ public class Notification implements Parcelable } /** - * Combine all of the options that have been set and return a new {@link Notification} - * object. + * Apply the unstyled operations and return a new {@link Notification} object. */ - public Notification getNotification() { + private Notification buildUnstyled() { Notification n = new Notification(); n.when = mWhen; n.icon = mSmallIcon; @@ -1509,6 +1522,49 @@ public class Notification implements Parcelable } return n; } + + /** + * @deprecated Use {@link #build()} instead. + */ + @Deprecated + public Notification getNotification() { + return build(); + } + + /** + * Combine all of the options that have been set and return a new {@link Notification} + * object. + */ + public Notification build() { + if (mStyle != null) { + return mStyle.build(); + } else { + return buildUnstyled(); + } + } + } + + + /** + * An object that can apply a rich notification style to a {@link Notification.Builder} + * object. + */ + public static class Style { + protected Builder mBuilder; + + public void setBuilder(Builder builder) { + if (mBuilder != builder) { + mBuilder = builder; + mBuilder.setStyle(this); + } + } + + public Notification build() { + if (mBuilder == null) { + throw new IllegalArgumentException("Style requires a valid Builder object"); + } + return mBuilder.buildUnstyled(); + } } /** @@ -1528,12 +1584,14 @@ public class Notification implements Parcelable * * @see Notification#bigContentView */ - public static class BigPictureStyle { - private Builder mBuilder; + public static class BigPictureStyle extends Style { private Bitmap mPicture; + public BigPictureStyle() { + } + public BigPictureStyle(Builder builder) { - mBuilder = builder; + setBuilder(builder); } public BigPictureStyle bigPicture(Bitmap b) { @@ -1549,8 +1607,12 @@ public class Notification implements Parcelable return contentView; } + @Override public Notification build() { - Notification wip = mBuilder.getNotification(); + if (mBuilder == null) { + throw new IllegalArgumentException("Style requires a valid Builder object"); + } + Notification wip = mBuilder.buildUnstyled(); wip.bigContentView = makeBigContentView(); return wip; } @@ -1573,12 +1635,14 @@ public class Notification implements Parcelable * * @see Notification#bigContentView */ - public static class BigTextStyle { - private Builder mBuilder; + public static class BigTextStyle extends Style { private CharSequence mBigText; + public BigTextStyle() { + } + public BigTextStyle(Builder builder) { - mBuilder = builder; + setBuilder(builder); } public BigTextStyle bigText(CharSequence cs) { @@ -1587,17 +1651,21 @@ public class Notification implements Parcelable } private RemoteViews makeBigContentView() { - RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(R.layout.notification_template_big_text); - + int bigTextId = R.layout.notification_template_big_text; + RemoteViews contentView = mBuilder.applyStandardTemplateWithActions(bigTextId); contentView.setTextViewText(R.id.big_text, mBigText); contentView.setViewVisibility(R.id.big_text, View.VISIBLE); - contentView.setTextViewText(R.id.text, ""); // XXX: what do do with this spot? + contentView.setViewVisibility(R.id.text2, View.GONE); return contentView; } + @Override public Notification build() { - Notification wip = mBuilder.getNotification(); + if (mBuilder == null) { + throw new IllegalArgumentException("Style requires a valid Builder object"); + } + Notification wip = mBuilder.buildUnstyled(); wip.bigContentView = makeBigContentView(); return wip; } @@ -1608,7 +1676,7 @@ public class Notification implements Parcelable * * This class is a "rebuilder": It consumes a Builder object and modifies its behavior, like so: * <pre class="prettyprint"> - * Notification noti = new Notification.DigestStyle( + * Notification noti = new Notification.InboxStyle( * new Notification.Builder() * .setContentTitle("New mail from " + sender.toString()) * .setContentText(subject) @@ -1621,12 +1689,14 @@ public class Notification implements Parcelable * * @see Notification#bigContentView */ - public static class InboxStyle { - private Builder mBuilder; + public static class InboxStyle extends Style { private ArrayList<CharSequence> mTexts = new ArrayList<CharSequence>(5); + public InboxStyle() { + } + public InboxStyle(Builder builder) { - mBuilder = builder; + setBuilder(builder); } public InboxStyle addLine(CharSequence cs) { @@ -1652,8 +1722,12 @@ public class Notification implements Parcelable return contentView; } + @Override public Notification build() { - Notification wip = mBuilder.getNotification(); + if (mBuilder == null) { + throw new IllegalArgumentException("Style requires a valid Builder object"); + } + Notification wip = mBuilder.buildUnstyled(); wip.bigContentView = makeBigContentView(); return wip; } diff --git a/core/java/android/view/ActionMode.java b/core/java/android/view/ActionMode.java index 0ba5fdb..a359952 100644 --- a/core/java/android/view/ActionMode.java +++ b/core/java/android/view/ActionMode.java @@ -30,6 +30,7 @@ package android.view; */ public abstract class ActionMode { private Object mTag; + private boolean mTitleOptionalHint; /** * Set a tag object associated with this ActionMode. @@ -119,6 +120,18 @@ public abstract class ActionMode { * @param titleOptional true if the title only presents optional information. */ public void setTitleOptionalHint(boolean titleOptional) { + mTitleOptionalHint = titleOptional; + } + + /** + * @return true if this action mode has been given a hint to consider the + * title/subtitle display to be optional. + * + * @see #setTitleOptionalHint(boolean) + * @see #isTitleOptional() + */ + public boolean getTitleOptionalHint() { + return mTitleOptionalHint; } /** diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 092bcbd..2f67481 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5423,6 +5423,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * app should not need to concern itself with saving and restoring, but that * the framework should take special note to preserve when possible. * + * <p>A view with transient state cannot be trivially rebound from an external + * data source, such as an adapter binding item views in a list. This may be + * because the view is performing an animation, tracking user selection + * of content, or similar.</p> + * * @return true if the view has transient state */ @ViewDebug.ExportedProperty(category = "layout") @@ -5436,6 +5441,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * so every call to setHasTransientState(true) should be paired with a later call * to setHasTransientState(false). * + * <p>A view with transient state cannot be trivially rebound from an external + * data source, such as an adapter binding item views in a list. This may be + * because the view is performing an animation, tracking user selection + * of content, or similar.</p> + * * @param hasTransientState true if this view has transient state */ public void setHasTransientState(boolean hasTransientState) { diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index 78a7d46..5c60a12 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -135,7 +135,12 @@ public class AccessibilityRecord { */ public void setSource(View root, int virtualDescendantId) { enforceNotSealed(); - final boolean important = (root != null) ? root.isImportantForAccessibility() : true; + final boolean important; + if (virtualDescendantId == UNDEFINED) { + important = (root != null) ? root.isImportantForAccessibility() : true; + } else { + important = true; + } setBooleanProperty(PROPERTY_IMPORTANT_FOR_ACCESSIBILITY, important); mSourceWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED; final int rootViewId = (root != null) ? root.getAccessibilityViewId() : UNDEFINED; diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java index 0bdcdee..f0a9cc2 100644 --- a/core/java/android/webkit/WebViewClassic.java +++ b/core/java/android/webkit/WebViewClassic.java @@ -102,6 +102,7 @@ import android.webkit.WebView.PictureListener; import android.webkit.WebViewCore.DrawData; import android.webkit.WebViewCore.EventHub; import android.webkit.WebViewCore.TextFieldInitData; +import android.webkit.WebViewCore.TextSelectionData; import android.webkit.WebViewCore.TouchHighlightData; import android.webkit.WebViewCore.WebKitHitTest; import android.widget.AbsoluteLayout; @@ -1315,6 +1316,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case WebViewInputDispatcher.EVENT_TYPE_TOUCH: onHandleUiTouchEvent(event); break; + case WebViewInputDispatcher.EVENT_TYPE_CLICK: + if (mFocusedNode != null && mFocusedNode.mIntentUrl != null) { + mWebView.playSoundEffect(SoundEffectConstants.CLICK); + overrideLoading(mFocusedNode.mIntentUrl); + } + break; } } @@ -2017,6 +2024,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } private void destroyImpl() { + int drawGLFunction = nativeGetDrawGLFunction(mNativeClass); + ViewRootImpl viewRoot = mWebView.getViewRootImpl(); + Log.d(LOGTAG, String.format("destroyImpl, drawGLFunction %x, viewroot == null %b, isHWAccel %b", + drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated())); + mCallbackProxy.blockMessages(); clearHelpers(); if (mListBoxDialog != null) { @@ -4206,7 +4218,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc // decide which adornments to draw int extras = DRAW_EXTRAS_NONE; - if (!mFindIsUp && mSelectingText) { + if (!mFindIsUp && mShowTextSelectionExtra) { extras = DRAW_EXTRAS_SELECTION; } @@ -4530,11 +4542,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private void startSelectingText() { mSelectingText = true; + mShowTextSelectionExtra = true; mHandleAlphaAnimator.setIntValues(255); mHandleAlphaAnimator.start(); } private void endSelectingText() { mSelectingText = false; + mShowTextSelectionExtra = false; mHandleAlphaAnimator.setIntValues(0); mHandleAlphaAnimator.start(); } @@ -5307,9 +5321,6 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc mSelectCallback.finish(); mSelectCallback = null; } - if (!mIsCaretSelection) { - updateWebkitSelection(); - } invalidate(); // redraw without selection mAutoScrollX = 0; mAutoScrollY = 0; @@ -5429,9 +5440,11 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc removeAccessibilityApisFromJavaScript(); updateHwAccelerated(); + int drawGLFunction = nativeGetDrawGLFunction(mNativeClass); + ViewRootImpl viewRoot = mWebView.getViewRootImpl(); + Log.d(LOGTAG, String.format("onDetachedFromWindow, drawGLFunction %x, viewroot == null %b, isHWAccel %b", + drawGLFunction, (viewRoot == null), mWebView.isHardwareAccelerated())); if (mWebView.isHardwareAccelerated()) { - int drawGLFunction = nativeGetDrawGLFunction(mNativeClass); - ViewRootImpl viewRoot = mWebView.getViewRootImpl(); if (drawGLFunction != 0 && viewRoot != null) { viewRoot.detachFunctor(drawGLFunction); } @@ -6435,6 +6448,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc private int mTrackballXMove = 0; private int mTrackballYMove = 0; private boolean mSelectingText = false; + private boolean mShowTextSelectionExtra = false; private boolean mSelectionStarted = false; private static final int TRACKBALL_KEY_TIMEOUT = 1000; private static final int TRACKBALL_TIMEOUT = 200; @@ -7585,6 +7599,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc case UPDATE_CONTENT_BOUNDS: mEditTextContentBounds.set((Rect) msg.obj); + nativeMapLayerRect(mNativeClass, mEditTextLayerId, + mEditTextContentBounds); break; case SCROLL_EDIT_TEXT: @@ -7611,6 +7627,26 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc public Context getContext() { return WebViewClassic.this.getContext(); } + + @Override + public boolean shouldInterceptTouchEvent(MotionEvent event) { + if (!mSelectingText) { + return false; + } + ensureSelectionHandles(); + int y = Math.round(event.getY() - getTitleHeight() + getScrollY()); + int x = Math.round(event.getX() + getScrollX()); + boolean isPressingHandle; + if (mIsCaretSelection) { + isPressingHandle = mSelectHandleCenter.getBounds() + .contains(x, y); + } else { + isPressingHandle = + mSelectHandleLeft.getBounds().contains(x, y) + || mSelectHandleRight.getBounds().contains(x, y); + } + return isPressingHandle; + } } private void setHitTestTypeFromUrl(String url) { @@ -7935,6 +7971,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc } nativeSetTextSelection(mNativeClass, data.mSelectTextPtr); + if (data.mSelectionReason == TextSelectionData.REASON_ACCESSIBILITY_INJECTOR) { + selectionDone(); + mShowTextSelectionExtra = true; + invalidate(); + return; + } + if (data.mSelectTextPtr != 0 && (data.mStart != data.mEnd || (mFieldPointer == nodePointer && mFieldPointer != 0))) { diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 7a757a8..661bbf8 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -143,6 +143,7 @@ public final class WebViewCore { private int mHighUsageDeltaMb; private int mChromeCanFocusDirection; + private int mTextSelectionChangeReason = TextSelectionData.REASON_UNKNOWN; // The thread name used to identify the WebCore thread and for use in // debugging other classes that require operation within the WebCore thread. @@ -861,6 +862,8 @@ public final class WebViewCore { } static class TextSelectionData { + static final int REASON_UNKNOWN = 0; + static final int REASON_ACCESSIBILITY_INJECTOR = 1; public TextSelectionData(int start, int end, int selectTextPtr) { mStart = start; mEnd = end; @@ -869,6 +872,7 @@ public final class WebViewCore { int mStart; int mEnd; int mSelectTextPtr; + int mSelectionReason = TextSelectionData.REASON_UNKNOWN; } static class TouchUpData { @@ -1544,12 +1548,16 @@ public final class WebViewCore { break; case MODIFY_SELECTION: + mTextSelectionChangeReason + = TextSelectionData.REASON_ACCESSIBILITY_INJECTOR; String modifiedSelectionString = nativeModifySelection(mNativeClass, msg.arg1, msg.arg2); mWebViewClassic.mPrivateHandler.obtainMessage( WebViewClassic.SELECTION_STRING_CHANGED, modifiedSelectionString).sendToTarget(); + mTextSelectionChangeReason + = TextSelectionData.REASON_UNKNOWN; break; case LISTBOX_CHOICES: @@ -2763,13 +2771,19 @@ public final class WebViewCore { } } + private TextSelectionData createTextSelection(int start, int end, int selPtr) { + TextSelectionData data = new TextSelectionData(start, end, selPtr); + data.mSelectionReason = mTextSelectionChangeReason; + return data; + } + // called by JNI private void updateTextSelection(int pointer, int start, int end, int textGeneration, int selectionPtr) { if (mWebViewClassic != null) { Message.obtain(mWebViewClassic.mPrivateHandler, WebViewClassic.UPDATE_TEXT_SELECTION_MSG_ID, pointer, textGeneration, - new TextSelectionData(start, end, selectionPtr)).sendToTarget(); + createTextSelection(start, end, selectionPtr)).sendToTarget(); } } @@ -2803,7 +2817,7 @@ public final class WebViewCore { Message.obtain(mWebViewClassic.mPrivateHandler, WebViewClassic.UPDATE_TEXT_SELECTION_MSG_ID, initData.mFieldPointer, 0, - new TextSelectionData(start, end, selectionPtr)) + createTextSelection(start, end, selectionPtr)) .sendToTarget(); } diff --git a/core/java/android/webkit/WebViewInputDispatcher.java b/core/java/android/webkit/WebViewInputDispatcher.java index b612a3b..ef23a11 100644 --- a/core/java/android/webkit/WebViewInputDispatcher.java +++ b/core/java/android/webkit/WebViewInputDispatcher.java @@ -22,7 +22,6 @@ import android.os.Looper; import android.os.Message; import android.os.SystemClock; import android.util.Log; -import android.view.InputDevice; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -314,11 +313,13 @@ final class WebViewInputDispatcher { return false; } - if (mPostSendTouchEventsToWebKit - && mPostDoNotSendTouchEventsToWebKitUntilNextGesture - && action == MotionEvent.ACTION_DOWN) { - // Recover from a previous web kit timeout. - mPostDoNotSendTouchEventsToWebKitUntilNextGesture = false; + if (action == MotionEvent.ACTION_DOWN && mPostSendTouchEventsToWebKit) { + if (mUiCallbacks.shouldInterceptTouchEvent(eventToEnqueue)) { + mPostDoNotSendTouchEventsToWebKitUntilNextGesture = true; + } else if (mPostDoNotSendTouchEventsToWebKitUntilNextGesture) { + // Recover from a previous web kit timeout. + mPostDoNotSendTouchEventsToWebKitUntilNextGesture = false; + } } } @@ -949,6 +950,15 @@ final class WebViewInputDispatcher { * @param flags The event's dispatch flags. */ public void dispatchUiEvent(MotionEvent event, int eventType, int flags); + + /** + * Asks the UI thread whether this touch event stream should be + * intercepted based on the touch down event. + * @param event The touch down event. + * @return true if the UI stream wants the touch stream without going + * through webkit or false otherwise. + */ + public boolean shouldInterceptTouchEvent(MotionEvent event); } /* Implemented by {@link WebViewCore} to perform operations on the web kit thread. */ diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index ed711f3..805c0a9 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -817,6 +817,7 @@ public class ActionBarImpl extends ActionBar { @Override public void setTitleOptionalHint(boolean titleOptional) { + super.setTitleOptionalHint(titleOptional); mContextView.setTitleOptional(titleOptional); } diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java index 4b681ec..fae7ea1 100644 --- a/core/java/com/android/internal/view/StandaloneActionMode.java +++ b/core/java/com/android/internal/view/StandaloneActionMode.java @@ -73,6 +73,7 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call @Override public void setTitleOptionalHint(boolean titleOptional) { + super.setTitleOptionalHint(titleOptional); mContextView.setTitleOptional(titleOptional); } diff --git a/core/java/com/android/server/NetworkManagementSocketTagger.java b/core/java/com/android/server/NetworkManagementSocketTagger.java index c77992d..06ef4c9 100644 --- a/core/java/com/android/server/NetworkManagementSocketTagger.java +++ b/core/java/com/android/server/NetworkManagementSocketTagger.java @@ -16,20 +16,14 @@ package com.android.server; -import android.net.NetworkStats; import android.os.SystemProperties; import android.util.Log; import android.util.Slog; import dalvik.system.SocketTagger; -import libcore.io.IoUtils; import java.io.FileDescriptor; -import java.io.FileOutputStream; -import java.io.IOException; -import java.math.BigInteger; import java.net.SocketException; -import java.nio.charset.Charsets; /** * Assigns tags to sockets for traffic stats. @@ -141,8 +135,12 @@ public final class NetworkManagementSocketTagger extends SocketTagger { * format like {@code 0x7fffffff00000000}. */ public static int kernelToTag(String string) { - // TODO: migrate to direct integer instead of odd shifting - return (int) (Long.decode(string) >> 32); + int length = string.length(); + if (length > 10) { + return Long.decode(string.substring(0, length - 8)).intValue(); + } else { + return 0; + } } private static native int native_tagSocketFd(FileDescriptor fd, int tag, int uid); diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml index 1dc6275..ae29537 100644 --- a/core/res/res/layout/notification_template_base.xml +++ b/core/res/res/layout/notification_template_base.xml @@ -85,13 +85,6 @@ android:ellipsize="marquee" android:visibility="gone" /> - <TextView android:id="@+id/big_text" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:singleLine="false" - android:visibility="gone" - /> <LinearLayout android:id="@+id/line3" android:layout_width="match_parent" diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml index b6d71e1..ee6adc6 100644 --- a/core/res/res/layout/notification_template_big_text.xml +++ b/core/res/res/layout/notification_template_big_text.xml @@ -33,7 +33,6 @@ android:layout_height="wrap_content" android:layout_gravity="fill_vertical" android:layout_marginLeft="@dimen/notification_large_icon_width" - android:minHeight="@dimen/notification_large_icon_height" android:orientation="vertical" android:paddingLeft="12dp" android:paddingRight="12dp" @@ -42,55 +41,73 @@ android:gravity="center_vertical" > <LinearLayout - android:id="@+id/line1" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" - > - <TextView android:id="@+id/title" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:minHeight="@dimen/notification_large_icon_height" + android:orientation="vertical" + > + <LinearLayout + android:id="@+id/line1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:layout_weight="1" + /> + <ViewStub android:id="@+id/time" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_weight="0" + android:visibility="gone" + android:layout="@layout/notification_template_part_time" + /> + <ViewStub android:id="@+id/chronometer" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_weight="0" + android:visibility="gone" + android:layout="@layout/notification_template_part_chronometer" + /> + </LinearLayout> + <TextView android:id="@+id/text2" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginTop="-2dp" + android:layout_marginBottom="-2dp" android:singleLine="true" - android:ellipsize="marquee" android:fadingEdge="horizontal" - android:layout_weight="1" - /> - <ViewStub android:id="@+id/time" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" + android:ellipsize="marquee" android:visibility="gone" - android:layout="@layout/notification_template_part_time" /> - <ViewStub android:id="@+id/chronometer" - android:layout_width="wrap_content" + <TextView android:id="@+id/big_text" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center" - android:layout_weight="0" + android:layout_marginTop="2dp" + android:layout_marginBottom="2dp" + android:singleLine="false" android:visibility="gone" - android:layout="@layout/notification_template_part_chronometer" /> </LinearLayout> - <TextView android:id="@+id/text2" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Line2" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="-2dp" - android:layout_marginBottom="-2dp" - android:singleLine="true" - android:fadingEdge="horizontal" - android:ellipsize="marquee" - android:visibility="gone" - /> - <TextView android:id="@+id/big_text" - android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + <LinearLayout + android:id="@+id/actions" android:layout_width="match_parent" android:layout_height="wrap_content" - android:singleLine="false" + android:orientation="vertical" android:visibility="gone" - /> + > + <!-- actions will be added here --> + </LinearLayout> <LinearLayout android:id="@+id/line3" android:layout_width="match_parent" @@ -135,13 +152,5 @@ android:visibility="gone" style="?android:attr/progressBarStyleHorizontal" /> - <LinearLayout - android:id="@+id/actions" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:visibility="gone" - > - <!-- actions will be added here --> - </LinearLayout> </LinearLayout> </FrameLayout> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 2d29d06..978e2a8 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1316,6 +1316,7 @@ <java-symbol type="string" name="lockscreen_password_wrong" /> <java-symbol type="string" name="lockscreen_pattern_instructions" /> <java-symbol type="string" name="lockscreen_pattern_wrong" /> + <java-symbol type="string" name="lockscreen_permanent_disabled_sim_message_short" /> <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" /> <java-symbol type="string" name="lockscreen_plugged_in" /> <java-symbol type="string" name="lockscreen_sim_locked_message" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index bc1e79c..c863e7c 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1898,6 +1898,8 @@ <string name="lockscreen_missing_sim_instructions">Insert a SIM card.</string> <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. --> <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Insert a SIM card.</string> + <!-- Shown in the lock screen when SIM card is permanently disabled. --> + <string name="lockscreen_permanent_disabled_sim_message_short">Unusable SIM card.</string> <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. --> <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card has been permanently disabled.\n Contact your wireless service provider for another SIM card.</string> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 71738ad..77dbaa5 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -174,6 +174,13 @@ please see themes_device_defaults.xml. <item name="windowActionModeOverlay">false</item> <item name="windowCloseOnTouchOutside">false</item> + <!-- Define these here; ContextThemeWrappers around themes that define them should + always clear these values. --> + <item name="windowFixedWidthMajor">0dp</item> + <item name="windowFixedWidthMinor">0dp</item> + <item name="windowFixedHeightMajor">0dp</item> + <item name="windowFixedHeightMinor">0dp</item> + <!-- Dialog attributes --> <item name="alertDialogStyle">@android:style/AlertDialog</item> <item name="dialogTheme">@android:style/Theme.Dialog</item> diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 8a5f8bb..77e4986 100755 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -1229,9 +1229,8 @@ public class PackageManagerTests extends AndroidTestCase { installFromRawResource("install.apk", R.raw.install_loc_unspecified, PackageManager.INSTALL_FORWARD_LOCK | - PackageManager.INSTALL_EXTERNAL, true, true, - PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, - PackageInfo.INSTALL_LOCATION_UNSPECIFIED); + PackageManager.INSTALL_EXTERNAL, true, false, -1, + PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); } @LargeTest @@ -1626,8 +1625,8 @@ public class PackageManagerTests extends AndroidTestCase { int installFlags = PackageManager.INSTALL_FORWARD_LOCK; int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA; - boolean fail = true; - int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED; + boolean fail = false; + int result = PackageManager.MOVE_SUCCEEDED; sampleMoveFromRawResource(installFlags, moveFlags, fail, result); } @@ -1950,7 +1949,7 @@ public class PackageManagerTests extends AndroidTestCase { PackageManager.INSTALL_FORWARD_LOCK, true, false, -1, - PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); + PackageInfo.INSTALL_LOCATION_AUTO); } /* The following test functions verify install location for existing apps. diff --git a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java index 58269a8..b994483 100644 --- a/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java +++ b/core/tests/coretests/src/com/android/internal/net/NetworkStatsFactoryTest.java @@ -25,6 +25,7 @@ import static com.android.server.NetworkManagementSocketTagger.kernelToTag; import android.content.res.Resources; import android.net.NetworkStats; +import android.net.TrafficStats; import android.test.AndroidTestCase; import com.android.frameworks.coretests.R; @@ -138,6 +139,12 @@ public class NetworkStatsFactoryTest extends AndroidTestCase { assertEquals(2147483647, kernelToTag("0x7fffffff00000000")); assertEquals(0, kernelToTag("0x0000000000000000")); assertEquals(2147483136, kernelToTag("0x7FFFFE0000000000")); + + assertEquals(0, kernelToTag("0x0")); + assertEquals(0, kernelToTag("0xf00d")); + assertEquals(1, kernelToTag("0x100000000")); + assertEquals(14438007, kernelToTag("0xdc4e7700000000")); + assertEquals(TrafficStats.TAG_SYSTEM_DOWNLOAD, kernelToTag("0xffffff0100000000")); } public void testNetworkStatsWithSet() throws Exception { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index da2192f..80db693 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -247,6 +247,7 @@ void OpenGLRenderer::resume() { } void OpenGLRenderer::detachFunctor(Functor* functor) { + ALOGD("OGLR %p detachFunctor %p", this, functor); mFunctors.remove(functor); } diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 3eec18c..c709e40 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -311,6 +311,14 @@ public class DefaultContainerService extends IntentService { return null; } + try { + Libcore.os.chmod(resFile.getAbsolutePath(), 0640); + } catch (ErrnoException e) { + Slog.e(TAG, "Could not chown APK: " + e.getMessage()); + PackageHelper.destroySdDir(newCid); + return null; + } + if (isForwardLocked) { File publicZipFile = new File(newCachePath, publicResFileName); try { @@ -326,10 +334,9 @@ public class DefaultContainerService extends IntentService { } try { - Libcore.os.chmod(resFile.getAbsolutePath(), 0640); Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644); } catch (ErrnoException e) { - Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage()); + Slog.e(TAG, "Could not chown public resource file: " + e.getMessage()); PackageHelper.destroySdDir(newCid); return null; } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 9c9844e..9d3a942 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -29,6 +29,7 @@ <uses-permission android:name="android.permission.DEVICE_POWER" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" /> + <uses-permission android:name="android.permission.MASTER_CLEAR" /> <!-- ActivityManager --> <uses-permission android:name="android.permission.GET_TASKS" /> diff --git a/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml new file mode 100644 index 0000000..8e86234 --- /dev/null +++ b/packages/SystemUI/res/layout-sw600dp/super_status_bar.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +** +** Copyright 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. +*/ +--> + +<!-- This is the combined status bar / notification panel window. --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" + android:fitsSystemWindows="true" + > + + <include layout="@layout/status_bar_expanded" + android:layout_width="@dimen/notification_panel_width" + android:layout_height="match_parent" + android:layout_gravity="center_horizontal|top" + /> + + <include layout="@layout/status_bar" + android:layout_width="match_parent" + android:layout_height="@*android:dimen/status_bar_height" + /> + +</FrameLayout> diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index eb1e1c0..1de4ab8 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -21,120 +21,114 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" - android:focusable="true" - android:descendantFocusability="afterDescendants" + android:id="@+id/notification_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:background="@drawable/notification_tracking_bg" + android:paddingTop="@*android:dimen/status_bar_height" + android:layout_marginLeft="@dimen/notification_panel_margin_left" > - <FrameLayout + <RelativeLayout android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:id="@+id/notification_panel" - android:background="@drawable/notification_tracking_bg" - android:paddingTop="@*android:dimen/status_bar_height" + android:layout_height="52dp" + android:paddingTop="3dp" + android:paddingBottom="5dp" + android:paddingRight="3dp" + android:background="@drawable/notification_header_bg" > + <com.android.systemui.statusbar.policy.DateView android:id="@+id/date" + android:textAppearance="@style/TextAppearance.StatusBar.Date" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_alignParentLeft="true" + android:singleLine="true" + android:gravity="center_vertical|left" + android:paddingLeft="16dp" + /> + <!-- + <com.android.systemui.statusbar.phone.CarrierLabel + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_marginTop="1dp" + android:layout_marginLeft="5dp" + android:layout_gravity="center_vertical" + android:paddingBottom="1dp" + android:paddingLeft="4dp" + android:textAppearance="?android:attr/textAppearanceLarge" + android:textColor="?android:attr/textColorSecondary" + /> + --> - <RelativeLayout - android:layout_width="match_parent" - android:layout_height="52dp" - android:paddingTop="3dp" - android:paddingBottom="5dp" - android:paddingRight="3dp" - android:background="@drawable/notification_header_bg" - > - <com.android.systemui.statusbar.policy.DateView android:id="@+id/date" - android:textAppearance="@style/TextAppearance.StatusBar.Date" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_alignParentLeft="true" - android:singleLine="true" - android:gravity="center_vertical|left" - android:paddingLeft="16dp" - /> - <!-- - <com.android.systemui.statusbar.phone.CarrierLabel - android:layout_width="0dp" - android:layout_height="wrap_content" - android:layout_weight="1" - android:layout_marginTop="1dp" - android:layout_marginLeft="5dp" - android:layout_gravity="center_vertical" - android:paddingBottom="1dp" - android:paddingLeft="4dp" - android:textAppearance="?android:attr/textAppearanceLarge" - android:textColor="?android:attr/textColorSecondary" - /> - --> - - <ImageView android:id="@+id/settings_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_toRightOf="@id/date" - android:paddingLeft="8dp" - android:paddingRight="8dp" - android:src="@drawable/ic_notify_quicksettings" - android:contentDescription="@string/accessibility_settings_button" - /> - - <ImageView android:id="@+id/clear_all_button" - android:layout_width="wrap_content" - android:layout_height="match_parent" - android:layout_alignParentRight="true" - android:paddingLeft="8dp" - android:paddingRight="8dp" - android:src="@drawable/ic_notify_clear" - android:contentDescription="@string/accessibility_clear_all" - /> - </RelativeLayout> - - <View - android:layout_width="match_parent" - android:layout_height="2dp" - android:layout_marginTop="52dp" - android:background="@drawable/status_bar_hr" + <ImageView android:id="@+id/settings_button" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toRightOf="@id/date" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:src="@drawable/ic_notify_quicksettings" + android:contentDescription="@string/accessibility_settings_button" /> - - <ScrollView - android:id="@+id/scroll" - android:layout_width="match_parent" + + <ImageView android:id="@+id/clear_all_button" + android:layout_width="wrap_content" android:layout_height="match_parent" - android:fadingEdge="none" - android:overScrollMode="ifContentScrolls" - android:layout_marginTop="54dp" - android:layout_marginBottom="34dp" - > - <com.android.systemui.statusbar.policy.NotificationRowLayout - android:id="@+id/latestItems" - android:layout_width="match_parent" - android:layout_height="wrap_content" - systemui:rowHeight="@dimen/notification_height" - /> - </ScrollView> - - <ImageView + android:layout_alignParentRight="true" + android:paddingLeft="8dp" + android:paddingRight="8dp" + android:src="@drawable/ic_notify_clear" + android:contentDescription="@string/accessibility_clear_all" + /> + </RelativeLayout> + + <View + android:layout_width="match_parent" + android:layout_height="2dp" + android:layout_marginTop="52dp" + android:background="@drawable/status_bar_hr" + /> + + <ScrollView + android:id="@+id/scroll" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fadingEdge="none" + android:overScrollMode="ifContentScrolls" + android:layout_marginTop="54dp" + android:layout_marginBottom="34dp" + > + <com.android.systemui.statusbar.policy.NotificationRowLayout + android:id="@+id/latestItems" android:layout_width="match_parent" android:layout_height="wrap_content" - android:src="@drawable/title_bar_shadow" - android:layout_marginTop="54dp" - android:scaleType="fitXY" - /> - - <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close" + systemui:rowHeight="@dimen/notification_height" + /> + </ScrollView> + + <ImageView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:src="@drawable/title_bar_shadow" + android:layout_marginTop="54dp" + android:scaleType="fitXY" + /> + + <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close" + android:layout_width="match_parent" + android:layout_height="@dimen/close_handle_height" + android:layout_gravity="bottom" + android:orientation="vertical" + > + <ImageView android:layout_width="match_parent" - android:layout_height="@dimen/close_handle_height" + android:layout_height="34dp" android:layout_gravity="bottom" - android:orientation="vertical" - > - <ImageView - android:layout_width="match_parent" - android:layout_height="34dp" - android:layout_gravity="bottom" - android:scaleType="fitXY" - android:src="@drawable/status_bar_close_on" - /> - - </com.android.systemui.statusbar.phone.CloseDragHandle> - - </FrameLayout><!-- end of sliding panel --> + android:scaleType="fitXY" + android:src="@drawable/status_bar_close_on" + /> + + </com.android.systemui.statusbar.phone.CloseDragHandle> -</FrameLayout><!-- end of window -->
\ No newline at end of file +</FrameLayout><!-- end of sliding panel -->
\ No newline at end of file diff --git a/packages/SystemUI/res/values-large-port/dimens.xml b/packages/SystemUI/res/values-large-port/dimens.xml deleted file mode 100644 index 56effa3..0000000 --- a/packages/SystemUI/res/values-large-port/dimens.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (c) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ ---> -<resources> - <!-- gap on either side of status bar notification icons --> - <dimen name="status_bar_icon_padding">2dp</dimen> -</resources> - - - diff --git a/packages/SystemUI/res/values-large/colors.xml b/packages/SystemUI/res/values-large/colors.xml deleted file mode 100644 index a7a70c3..0000000 --- a/packages/SystemUI/res/values-large/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <drawable name="status_bar_background">#000000</drawable> - <drawable name="notification_icon_area_smoke">#aa000000</drawable> -</resources> - diff --git a/packages/SystemUI/res/values-large/config.xml b/packages/SystemUI/res/values-large/config.xml deleted file mode 100644 index 4014f8d..0000000 --- a/packages/SystemUI/res/values-large/config.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2010, 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. -*/ ---> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds. --> -<resources> - <!-- Whether or not we show the number in the bar. --> - <bool name="config_statusBarShowNumber">false</bool> -</resources> - diff --git a/packages/SystemUI/res/values-large/dimens.xml b/packages/SystemUI/res/values-large/dimens.xml deleted file mode 100644 index 9d89e21..0000000 --- a/packages/SystemUI/res/values-large/dimens.xml +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (c) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ ---> -<resources> - <!-- The width of the ticker, including the icon --> - <dimen name="notification_ticker_width">360dp</dimen> - <!-- Status bar panel bottom offset (height of status bar - overlap) --> - <dimen name="status_bar_panel_bottom_offset">36dp</dimen> - <!-- gap on either side of status bar notification icons --> - <dimen name="status_bar_icon_padding">8dp</dimen> -</resources> - - diff --git a/packages/SystemUI/res/values-large/strings.xml b/packages/SystemUI/res/values-large/strings.xml deleted file mode 100644 index f04dc04..0000000 --- a/packages/SystemUI/res/values-large/strings.xml +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/** - * Copyright (c) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ ---> -<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- The text for the button in the notification window-shade that clears - all of the currently visible notifications. [CHAR LIMIT=10]--> - <string name="status_bar_clear_all_button">Clear all</string> - - <!-- Separator for PLMN and SPN in network name. --> - <string name="status_bar_network_name_separator" translatable="false">" – "</string> - - <!-- Title for the pseudo-notification shown when notifications are disabled (do-not-disturb - mode) --> - <string name="notifications_off_title">Notifications off</string> - - <!-- Content text for do-not-disturb mode notification --> - <string name="notifications_off_text">Tap here to turn notifications back on.</string> -</resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml new file mode 100644 index 0000000..afa0b20 --- /dev/null +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * 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. +*/ +--> +<resources> + <!-- Layout parameters for the notification panel --> + <dimen name="notification_panel_margin_bottom">0dp</dimen> + <dimen name="notification_panel_margin_left">32dp</dimen> + + <!-- Gravity for the notification panel --> + <!-- 0x33 = left|top --> + <integer name="notification_panel_layout_gravity">0x33</integer> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp-port/config.xml b/packages/SystemUI/res/values-sw600dp-port/config.xml deleted file mode 100644 index ab7661a..0000000 --- a/packages/SystemUI/res/values-sw600dp-port/config.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** Copyright 2011, 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. -*/ ---> - -<!-- These resources are around just to allow their values to be customized - for different hardware and product builds. --> -<resources> - <integer name="config_maxNotificationIcons">3</integer> -</resources> - diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml deleted file mode 100644 index 39eade6..0000000 --- a/packages/SystemUI/res/values-sw600dp-port/dimens.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - * Copyright (c) 2011, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ ---> -<resources> - <!-- gap on either side of status bar notification icons --> - <dimen name="status_bar_icon_padding">0dp</dimen> - - <!-- The width of the view containing non-menu status bar icons --> - <dimen name="navigation_key_width">70dip</dimen> - - <!-- The width of the view containing the menu status bar icon --> - <dimen name="navigation_menu_key_width">40dip</dimen> -</resources> - diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml new file mode 100644 index 0000000..43ae557 --- /dev/null +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * 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. +*/ +--> +<resources> + <!-- The width of the notification panel window --> + <dimen name="notification_panel_width">446dp</dimen> + + <!-- Layout parameters for the notification panel --> + <dimen name="notification_panel_margin_bottom">192dp</dimen> + <dimen name="notification_panel_margin_left">0dp</dimen> + + <!-- Gravity for the notification panel --> + <!-- 0x33 = center_horizontal|top --> + <integer name="notification_panel_layout_gravity">0x31</integer> +</resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index f7b8cc9..e92dbc5 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -120,4 +120,12 @@ <!-- Height of the draggable handle at the bottom of the phone notification panel --> <dimen name="close_handle_height">34dp</dimen> + + <!-- Layout parameters for the notification panel --> + <dimen name="notification_panel_margin_bottom">0dp</dimen> + <dimen name="notification_panel_margin_left">0dp</dimen> + + <!-- Gravity for the notification panel --> + <!-- 0x37 = fill_horizontal|top --> + <integer name="notification_panel_layout_gravity">0x37</integer> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 0125b64..db8316f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -46,6 +46,7 @@ import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.util.Slog; +import android.util.TypedValue; import android.view.Display; import android.view.Gravity; import android.view.IWindowManager; @@ -61,6 +62,7 @@ import android.view.WindowManagerImpl; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.AnimationUtils; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RemoteViews; @@ -73,6 +75,7 @@ import com.android.systemui.R; import com.android.systemui.recent.RecentTasksLoader; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.NotificationData; +import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.policy.BatteryController; @@ -116,6 +119,9 @@ public class PhoneStatusBar extends BaseStatusBar { private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true; + private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService + private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER; + // fling gesture tuning parameters, scaled to display density private float mSelfExpandVelocityPx; // classic value: 2000px/s private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up") @@ -158,6 +164,9 @@ public class PhoneStatusBar extends BaseStatusBar { View mNotificationPanel; // the sliding/resizing panel within the notification window ScrollView mScrollView; View mExpandedContents; + int mNotificationPanelMarginBottomPx, mNotificationPanelMarginLeftPx; + int mNotificationPanelGravity; + // top bar View mClearButton; View mSettingsButton; @@ -279,6 +288,17 @@ public class PhoneStatusBar extends BaseStatusBar { if (DEBUG) { mStatusBarWindow.setBackgroundColor(0x6000FF80); } + mStatusBarWindow.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (mExpanded && !mAnimating) { + animateCollapse(); + } + } + return true; + }}); + mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar); mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel); @@ -889,7 +909,10 @@ public class PhoneStatusBar extends BaseStatusBar { ArrayList<View> toShow = new ArrayList<View>(); for (int i=0; i<N; i++) { - toShow.add(mNotificationData.get(N-i-1).icon); + Entry ent = mNotificationData.get(N-i-1); + if (ent.notification.score >= HIDE_ICONS_BELOW_SCORE) { + toShow.add(ent.icon); + } } ArrayList<View> toRemove = new ArrayList<View>(); @@ -1111,7 +1134,7 @@ public class PhoneStatusBar extends BaseStatusBar { // Expand the window to encompass the full screen in anticipation of the drag. // This is only possible to do atomically because the status bar is at the top of the screen! WindowManager.LayoutParams lp = (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams(); - lp.height = mDisplayMetrics.heightPixels; + lp.height = ViewGroup.LayoutParams.MATCH_PARENT; final WindowManager wm = WindowManagerImpl.getDefault(); wm.updateViewLayout(mStatusBarWindow, lp); @@ -1162,7 +1185,7 @@ public class PhoneStatusBar extends BaseStatusBar { if (mAnimating) { y = (int)mAnimY; } else { - y = mDisplayMetrics.heightPixels-1; + y = getExpandedViewMaxHeight()-1; } // Let the fling think that we're open so it goes in the right direction // and doesn't try to re-open the windowshade. @@ -1224,7 +1247,7 @@ public class PhoneStatusBar extends BaseStatusBar { if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY); incrementAnim(); if (SPEW) Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY); - if (mAnimY >= mDisplayMetrics.heightPixels-1) { + if (mAnimY >= getExpandedViewMaxHeight()-1) { if (SPEW) Slog.d(TAG, "Animation completed to expanded state."); mAnimating = false; updateExpandedViewPos(EXPANDED_FULL_OPEN); @@ -1329,7 +1352,7 @@ public class PhoneStatusBar extends BaseStatusBar { if (mExpanded) { if (!always && ( vel > mFlingCollapseMinVelocityPx - || (y > (mDisplayMetrics.heightPixels*(1f-mCollapseMinDisplayFraction)) && + || (y > (getExpandedViewMaxHeight()*(1f-mCollapseMinDisplayFraction)) && vel > -mFlingExpandMinVelocityPx))) { // We are expanded, but they didn't move sufficiently to cause // us to retract. Animate back to the expanded position. @@ -1348,7 +1371,7 @@ public class PhoneStatusBar extends BaseStatusBar { } else { if (always || ( vel > mFlingExpandMinVelocityPx - || (y > (mDisplayMetrics.heightPixels*(1f-mExpandMinDisplayFraction)) && + || (y > (getExpandedViewMaxHeight()*(1f-mExpandMinDisplayFraction)) && vel > -mFlingCollapseMinVelocityPx))) { // We are collapsed, and they moved enough to allow us to // expand. Animate in the notifications. @@ -1412,7 +1435,8 @@ public class PhoneStatusBar extends BaseStatusBar { // mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y; } if ((!mExpanded && y < hitSize) || - (mExpanded && y > (mDisplayMetrics.heightPixels-hitSize))) { + // @@ add taps outside the panel if it's not full-screen + (mExpanded && y > (getExpandedViewMaxHeight()-hitSize))) { // We drop events at the edge of the screen to make the windowshade come // down by accident less, especially when pushing open a device with a keyboard @@ -1864,15 +1888,22 @@ public class PhoneStatusBar extends BaseStatusBar { return a < 0f ? 0f : (a > 1f ? 1f : a); } + int getExpandedViewMaxHeight() { + return mDisplayMetrics.heightPixels - mNotificationPanelMarginBottomPx; + } + void updateExpandedViewPos(int expandedPosition) { if (SPEW) { Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition //+ " mTrackingParams.y=" + ((mTrackingParams == null) ? "?" : mTrackingParams.y) - + " mTrackingPosition=" + mTrackingPosition); + + " mTrackingPosition=" + mTrackingPosition + + " gravity=" + mNotificationPanelGravity); } int panelh = 0; - final int disph = mDisplayMetrics.heightPixels; + final boolean portrait = mDisplayMetrics.heightPixels > mDisplayMetrics.widthPixels; + + final int disph = getExpandedViewMaxHeight(); // If the expanded view is not visible, make sure they're still off screen. // Maybe the view was resized. @@ -1906,113 +1937,25 @@ public class PhoneStatusBar extends BaseStatusBar { mTrackingPosition = panelh; - final View cropView = mNotificationPanel; - ViewGroup.LayoutParams lp = cropView.getLayoutParams(); + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mNotificationPanel.getLayoutParams(); lp.height = panelh; + lp.gravity = mNotificationPanelGravity; + lp.leftMargin = mNotificationPanelMarginLeftPx; if (SPEW) { - Slog.v(TAG, "updated cropView height=" + panelh); + Slog.v(TAG, "updated cropView height=" + panelh + " grav=" + lp.gravity); } - cropView.setLayoutParams(lp); + mNotificationPanel.setLayoutParams(lp); // woo, special effects final int barh = getCloseViewHeight() + getStatusBarHeight(); final float frac = saturate((float)(panelh - barh) / (disph - barh)); final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24; mStatusBarWindow.setBackgroundColor(color); - -// Slog.d(TAG, String.format("updateExpanded: pos=%d frac=%.2f col=0x%08x", pos, frac, color)); - -// if (mExpandedParams != null) { -// if (mCloseView.getWindowVisibility() == View.VISIBLE) { -// mCloseView.getLocationInWindow(mPositionTmp); -// final int closePos = mPositionTmp[1]; -// -// mExpandedContents.getLocationInWindow(mPositionTmp); -// final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight(); -// -// mExpandedParams.y = pos + mTrackingView.getHeight() -// - (mTrackingParams.height-closePos) - contentsBottom; -// -// if (SPEW) { -// Slog.d(PhoneStatusBar.TAG, -// "pos=" + pos + -// " trackingHeight=" + mTrackingView.getHeight() + -// " (trackingParams.height - closePos)=" + -// (mTrackingParams.height - closePos) + -// " contentsBottom=" + contentsBottom); -// } -// -// } else { -// // If the tracking view is not yet visible, then we can't have -// // a good value of the close view location. We need to wait for -// // it to be visible to do a layout. -// mExpandedParams.y = -mDisplayMetrics.heightPixels; -// } -// int max = h; -// if (mExpandedParams.y > max) { -// mExpandedParams.y = max; -// } -// int min = mTrackingPosition; -// if (mExpandedParams.y < min) { -// mExpandedParams.y = min; -// } -// -// boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h; -// if (!visible) { -// // if the contents aren't visible, move the expanded view way off screen -// // because the window itself extends below the content view. -// mExpandedParams.y = -disph; -// } -// mExpandedDialog.getWindow().setAttributes(mExpandedParams); -// -// // As long as this isn't just a repositioning that's not supposed to affect -// // the user's perception of what's showing, call to say that the visibility -// // has changed. (Otherwise, someone else will call to do that). -// if (expandedPosition != EXPANDED_LEAVE_ALONE) { -// if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")"); -// visibilityChanged(visible); -// } -// } -// -// if (SPEW) { -// Slog.d(TAG, "updateExpandedViewPos after expandedPosition=" + expandedPosition -// + " mTrackingParams.y=" + mTrackingParams.y -// + " mTrackingPosition=" + mTrackingPosition -// + " mExpandedParams.y=" + mExpandedParams.y -// + " mExpandedParams.height=" + mExpandedParams.height); -// } - } - - int getExpandedHeight() { - return mDisplayMetrics.heightPixels; } void updateDisplaySize() { mDisplay.getMetrics(mDisplayMetrics); -// if (DEBUG) { -// Slog.d(TAG, "updateDisplaySize: " + mDisplayMetrics); -// } -// updateExpandedSize(); } -// void updateExpandedSize() { -// if (DEBUG) { -// Slog.d(TAG, "updateExpandedSize()"); -// } -// if (mStatusBarWindow != null && mDisplayMetrics != null) { -// mExpandedParams.width = mDisplayMetrics.widthPixels; -// mExpandedParams.height = getExpandedHeight(); -// if (!mExpandedVisible) { -// updateExpandedInvisiblePosition(); -// } else { -// mExpandedDialog.getWindow().setAttributes(mExpandedParams); -// } -// if (DEBUG) { -// Slog.d(TAG, "updateExpandedSize: height=" + mExpandedParams.height + " " + -// (mExpandedVisible ? "VISIBLE":"INVISIBLE")); -// } -// } -// } - void performDisableActions(int net) { int old = mDisabled; int diff = net ^ old; @@ -2152,8 +2095,9 @@ public class PhoneStatusBar extends BaseStatusBar { animateCollapse(excludeRecents); } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { - repositionNavigationBar(); updateResources(); + repositionNavigationBar(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); } } }; @@ -2228,6 +2172,15 @@ public class PhoneStatusBar extends BaseStatusBar { mCollapseAccelPx = res.getDimension(R.dimen.collapse_accel); mFlingGestureMaxXVelocityPx = res.getDimension(R.dimen.fling_gesture_max_x_velocity); + + mNotificationPanelMarginBottomPx + = (int) res.getDimension(R.dimen.notification_panel_margin_bottom); + mNotificationPanelMarginLeftPx + = (int) res.getDimension(R.dimen.notification_panel_margin_left); + mNotificationPanelGravity = res.getInteger(R.integer.notification_panel_layout_gravity); + if (mNotificationPanelGravity <= 0) { + mNotificationPanelGravity = Gravity.CENTER_VERTICAL | Gravity.TOP; + } if (false) Slog.v(TAG, "updateResources"); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index f3a10e9..6e87dd7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -70,6 +70,7 @@ import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.NotificationData; import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.StatusBarIconView; +import com.android.systemui.statusbar.NotificationData.Entry; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BluetoothController; import com.android.systemui.statusbar.policy.CompatModeButton; @@ -111,6 +112,9 @@ public class TabletStatusBar extends BaseStatusBar implements final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms + private static final int NOTIFICATION_PRIORITY_MULTIPLIER = 10; // see NotificationManagerService + private static final int HIDE_ICONS_BELOW_SCORE = Notification.PRIORITY_LOW * NOTIFICATION_PRIORITY_MULTIPLIER; + // The height of the bar, as definied by the build. It may be taller if we're plugged // into hdmi. int mNaturalBarHeight = -1; @@ -268,7 +272,7 @@ public class TabletStatusBar extends BaseStatusBar implements WindowManager.LayoutParams lp = mNotificationPanelParams = new WindowManager.LayoutParams( res.getDimensionPixelSize(R.dimen.notification_panel_width), getNotificationPanelHeight(), - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM @@ -636,7 +640,7 @@ public class TabletStatusBar extends BaseStatusBar implements WindowManager.LayoutParams lp = new WindowManager.LayoutParams( (int) mContext.getResources().getDimension(R.dimen.status_bar_recents_width), ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH @@ -1713,9 +1717,12 @@ public class TabletStatusBar extends BaseStatusBar implements if (mInputMethodSwitchButton.getVisibility() != View.GONE) maxNotificationIconsCount --; if (mCompatModeButton.getVisibility() != View.GONE) maxNotificationIconsCount --; - for (int i=0; i< maxNotificationIconsCount; i++) { - if (i>=N) break; - toShow.add(mNotificationData.get(N-i-1).icon); + for (int i=0; toShow.size()< maxNotificationIconsCount; i++) { + if (i >= N) break; + Entry ent = mNotificationData.get(N-i-1); + if (ent.notification.score >= HIDE_ICONS_BELOW_SCORE) { + toShow.add(ent.icon); + } } ArrayList<View> toRemove = new ArrayList<View>(); @@ -1764,7 +1771,8 @@ public class TabletStatusBar extends BaseStatusBar implements for (int i=0; i<toShow.size(); i++) { View v = toShow.get(i); if (v.getParent() == null) { - mPile.addView(v, N-1-i); // the notification panel has newest at the bottom + // the notification panel has the most important things at the bottom + mPile.addView(v, N-1-i); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java index 754441c..d4ebe6d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java @@ -223,7 +223,7 @@ public class TabletTicker windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; } WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, mLargeIconHeight, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, windowFlags, + WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, windowFlags, PixelFormat.TRANSLUCENT); lp.gravity = Gravity.BOTTOM | Gravity.RIGHT; // lp.windowAnimations = com.android.internal.R.style.Animation_Toast; diff --git a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java index a6986de..d0fe42d 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java @@ -509,7 +509,8 @@ class KeyguardStatusViewManager implements OnClickListener { break; case SimPermDisabled: - carrierText = getContext().getText(R.string.lockscreen_missing_sim_message_short); + carrierText = getContext().getText( + R.string.lockscreen_permanent_disabled_sim_message_short); carrierHelpTextId = R.string.lockscreen_permanent_disabled_sim_instructions; mEmergencyButtonEnabledBecauseSimLocked = true; break; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index c3c49b0..4b91422 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -2108,8 +2108,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { w = 0; } - final int widthSize = MeasureSpec.getSize(widthMeasureSpec); - widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(w, widthSize), EXACTLY); + if (w > 0) { + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + widthMeasureSpec = MeasureSpec.makeMeasureSpec( + Math.min(w, widthSize), EXACTLY); + } } } @@ -2125,9 +2128,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { h = 0; } - final int heightSize = MeasureSpec.getSize(heightMeasureSpec); - heightMeasureSpec = - MeasureSpec.makeMeasureSpec(Math.min(h, heightSize), EXACTLY); + if (h > 0) { + final int heightSize = MeasureSpec.getSize(heightMeasureSpec); + heightMeasureSpec = MeasureSpec.makeMeasureSpec( + Math.min(h, heightSize), EXACTLY); + } } } diff --git a/services/java/com/android/server/NetworkTimeUpdateService.java b/services/java/com/android/server/NetworkTimeUpdateService.java index 1ff914f..76972bc 100644 --- a/services/java/com/android/server/NetworkTimeUpdateService.java +++ b/services/java/com/android/server/NetworkTimeUpdateService.java @@ -165,9 +165,15 @@ public class NetworkTimeUpdateService { if (mTime.getCacheAge() < POLLING_INTERVAL_MS) { final long ntp = mTime.currentTimeMillis(); mTryAgainCounter = 0; - mLastNtpFetchTime = SystemClock.elapsedRealtime(); - if (Math.abs(ntp - currentTime) > TIME_ERROR_THRESHOLD_MS) { + // If the clock is more than N seconds off or this is the first time it's been + // fetched since boot, set the current time. + if (Math.abs(ntp - currentTime) > TIME_ERROR_THRESHOLD_MS + || mLastNtpFetchTime == NOT_SET) { // Set the system time + if (DBG && mLastNtpFetchTime == NOT_SET + && Math.abs(ntp - currentTime) <= TIME_ERROR_THRESHOLD_MS) { + Log.d(TAG, "For initial setup, rtc = " + currentTime); + } if (DBG) Log.d(TAG, "Ntp time to be set = " + ntp); // Make sure we don't overflow, since it's going to be converted to an int if (ntp / 1000 < Integer.MAX_VALUE) { @@ -176,6 +182,7 @@ public class NetworkTimeUpdateService { } else { if (DBG) Log.d(TAG, "Ntp time is close enough = " + ntp); } + mLastNtpFetchTime = SystemClock.elapsedRealtime(); } else { // Try again shortly mTryAgainCounter++; diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 21ae624..b5d0b60 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -5863,9 +5863,28 @@ public class PackageManagerService extends IPackageManager.Stub { Log.w(TAG, "Insufficient storage to install"); return; } - // Create the file args now. + + mRet = srcArgs.doPreCopy(); + if (mRet != PackageManager.INSTALL_SUCCEEDED) { + return; + } + mRet = targetArgs.copyApk(mContainerService, false); - targetArgs.doPreInstall(mRet); + if (mRet != PackageManager.INSTALL_SUCCEEDED) { + srcArgs.doPostCopy(uid); + return; + } + + mRet = srcArgs.doPostCopy(uid); + if (mRet != PackageManager.INSTALL_SUCCEEDED) { + return; + } + + mRet = targetArgs.doPreInstall(mRet); + if (mRet != PackageManager.INSTALL_SUCCEEDED) { + return; + } + if (DEBUG_SD_INSTALL) { StringBuilder builder = new StringBuilder(); if (srcArgs != null) { @@ -5936,7 +5955,7 @@ public class PackageManagerService extends IPackageManager.Stub { String nativeLibraryPath) { if (installOnSd(flags) || installForwardLocked(flags)) { return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, - (flags & PackageManager.INSTALL_EXTERNAL) != 0); + installOnSd(flags), installForwardLocked(flags)); } else { return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); } @@ -5945,9 +5964,10 @@ public class PackageManagerService extends IPackageManager.Stub { // Used by package mover private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { if (installOnSd(flags) || installForwardLocked(flags)) { - String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME); - return new AsecInstallArgs(packageURI, cid, - (flags & PackageManager.INSTALL_EXTERNAL) != 0); + String cid = getNextCodePath(packageURI.getPath(), pkgName, "/" + + AsecInstallArgs.RES_FILE_NAME); + return new AsecInstallArgs(packageURI, cid, installOnSd(flags), + installForwardLocked(flags)); } else { return new FileInstallArgs(packageURI, pkgName, dataDir); } @@ -5984,6 +6004,26 @@ public class PackageManagerService extends IPackageManager.Stub { abstract boolean doPostDeleteLI(boolean delete); abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; + /** + * Called before the source arguments are copied. This is used mostly + * for MoveParams when it needs to read the source file to put it in the + * destination. + */ + int doPreCopy() { + return PackageManager.INSTALL_SUCCEEDED; + } + + /** + * Called after the source arguments are copied. This is used mostly for + * MoveParams when it needs to read the source file to put it in the + * destination. + * + * @return + */ + int doPostCopy(int uid) { + return PackageManager.INSTALL_SUCCEEDED; + } + protected boolean isFwdLocked() { return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; } @@ -6280,8 +6320,9 @@ public class PackageManagerService extends IPackageManager.Stub { } AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, - boolean isExternal) { - super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); + boolean isExternal, boolean isForwardLocked) { + super(null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) + | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null); // Extract cid from fullCodePath int eidx = fullCodePath.lastIndexOf("/"); String subStr1 = fullCodePath.substring(0, eidx); @@ -6296,8 +6337,9 @@ public class PackageManagerService extends IPackageManager.Stub { setCachePath(PackageHelper.getSdDir(cid)); } - AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) { - super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); + AsecInstallArgs(Uri packageURI, String cid, boolean isExternal, boolean isForwardLocked) { + super(packageURI, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) + | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), null, null); this.cid = cid; } @@ -6443,8 +6485,18 @@ public class PackageManagerService extends IPackageManager.Stub { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); } else { + final int groupOwner; + final String protectedFile; + if (isFwdLocked()) { + groupOwner = uid; + protectedFile = RES_FILE_NAME; + } else { + groupOwner = -1; + protectedFile = null; + } + if (uid < Process.FIRST_APPLICATION_UID - || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) { + || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) { Slog.e(TAG, "Failed to finalize " + cid); PackageHelper.destroySdDir(cid); return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; @@ -6505,6 +6557,33 @@ public class PackageManagerService extends IPackageManager.Stub { } return ret; } + + @Override + int doPreCopy() { + if (isFwdLocked()) { + if (!PackageHelper.fixSdPermissions(cid, + getPackageUid(DEFAULT_CONTAINER_PACKAGE, 0), RES_FILE_NAME)) { + return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; + } + } + + return PackageManager.INSTALL_SUCCEEDED; + } + + @Override + int doPostCopy(int uid) { + if (isFwdLocked()) { + PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME); + if (uid < Process.FIRST_APPLICATION_UID + || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) { + Slog.e(TAG, "Failed to finalize " + cid); + PackageHelper.destroySdDir(cid); + return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; + } + } + + return PackageManager.INSTALL_SUCCEEDED; + } }; // Utility method used to create code paths based on package name and available index. @@ -8696,9 +8775,15 @@ public class PackageManagerService extends IPackageManager.Stub { : PackageManager.INSTALL_INTERNAL; currFlags = isExternal(pkg) ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL; + if (newFlags == currFlags) { Slog.w(TAG, "No move required. Trying to move to same location"); returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; + } else { + if (isForwardLocked(pkg)) { + currFlags |= PackageManager.INSTALL_FORWARD_LOCK; + newFlags |= PackageManager.INSTALL_FORWARD_LOCK; + } } } if (returnCode == PackageManager.MOVE_SUCCEEDED) { @@ -8784,21 +8869,31 @@ public class PackageManagerService extends IPackageManager.Stub { final String newNativePath = mp.targetArgs .getNativeLibraryPath(); - if ((mp.flags & PackageManager.INSTALL_EXTERNAL) == 0) { - if (mInstaller - .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) { - returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; + try { + final File newNativeDir = new File(newNativePath); + + final String libParentDir = newNativeDir.getParentFile() + .getCanonicalPath(); + if (newNativeDir.getParentFile().getCanonicalPath() + .equals(pkg.applicationInfo.dataDir)) { + if (mInstaller + .unlinkNativeLibraryDirectory(pkg.applicationInfo.dataDir) < 0) { + returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; + } else { + NativeLibraryHelper.copyNativeBinariesIfNeededLI( + new File(newCodePath), newNativeDir); + } } else { - NativeLibraryHelper.copyNativeBinariesIfNeededLI(new File( - newCodePath), new File(newNativePath)); - } - } else { - if (mInstaller.linkNativeLibraryDirectory( - pkg.applicationInfo.dataDir, newNativePath) < 0) { - returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; + if (mInstaller.linkNativeLibraryDirectory( + pkg.applicationInfo.dataDir, newNativePath) < 0) { + returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE; + } } + } catch (IOException e) { + returnCode = PackageManager.MOVE_FAILED_INVALID_LOCATION; } + if (returnCode == PackageManager.MOVE_SUCCEEDED) { pkg.mPath = newCodePath; // Move dex files around diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index d635e8c..de756b1 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -85,6 +85,9 @@ public class AppWindowAnimator { animation = sDummyAnimation; animInitialized = false; } + hasTransformation = true; + transformation.clear(); + transformation.setAlpha(mAppToken.reportedVisible ? 1 : 0); } public void clearAnimation() { @@ -186,8 +189,6 @@ public class AppWindowAnimator { // it as not animating for purposes of scheduling transactions; // when it is really time to animate, this will be set to // a real animation and the next call will execute normally. - hasTransformation = true; - transformation.setAlpha(mAppToken.reportedVisible ? 1 : 0); return false; } diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java index 75eb226..190d909 100644 --- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java @@ -463,6 +463,61 @@ public abstract class ServiceStateTracker extends Handler { pollingContext = new int[1]; } + /** + * Return true if time zone needs fixing. + * + * @param phoneBase + * @param operatorNumeric + * @param prevOperatorNumeric + * @param needToFixTimeZone + * @return true if time zone needs to be fixed + */ + protected boolean isTimeZoneFixNeeded(PhoneBase phoneBase, String operatorNumeric, + String prevOperatorNumeric, boolean needToFixTimeZone) { + // Return false if the mcc isn't valid as we don't know where we are. + // Return true if we have an IccCard and the mcc changed or we + // need to fix it because when the NITZ time came in we didn't + // know the country code. + + // If mcc is invalid then we'll return false + int mcc; + try { + mcc = Integer.parseInt(operatorNumeric.substring(0, 3)); + } catch (Exception e) { + if (DBG) { + log("isTimeZoneFixNeeded: no mcc, operatorNumeric=" + operatorNumeric + + " retVal=false"); + } + return false; + } + + // If prevMcc is invalid will make it different from mcc + // so we'll return true if the card exists. + int prevMcc; + try { + prevMcc = Integer.parseInt(prevOperatorNumeric.substring(0, 3)); + } catch (Exception e) { + prevMcc = mcc + 1; + } + + // Determine if the Icc card exists + IccCard iccCard = phoneBase.getIccCard(); + boolean iccCardExist = (iccCard != null) && iccCard.getState().iccCardExist(); + + // Determine retVal + boolean retVal = ((iccCardExist && (mcc != prevMcc)) || needToFixTimeZone); + if (DBG) { + log("isTimeZoneFixNeeded: retVal=" + retVal + + " iccCard=" + iccCard + + " iccCard.state=" + (iccCard == null ? "null" : iccCard.getState().toString()) + + " iccCardExist=" + iccCardExist + + " operatorNumeric=" + operatorNumeric + " mcc=" + mcc + + " prevOperatorNumeric=" + prevOperatorNumeric + " prevMcc=" + prevMcc + + " needToFixTimeZone=" + needToFixTimeZone); + } + return retVal; + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("ServiceStateTracker:"); pw.println(" ss=" + ss); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java index ff7a0810..5a0df99 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaLteServiceStateTracker.java @@ -377,12 +377,7 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); if (operatorNumeric == null) { - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " clear PROPERTY_OPERATOR_ISO_COUNTRY"); - } + if (DBG) log("operatorNumeric is null"); phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); mGotCountryCode = false; } else { @@ -396,20 +391,13 @@ public class CdmaLteServiceStateTracker extends CdmaServiceStateTracker { } catch (StringIndexOutOfBoundsException ex) { loge("countryCodeForMcc error" + ex); } - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " mcc=" + mcc + " iso-cc=" + isoCountryCode); - } phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, isoCountryCode); mGotCountryCode = true; - // Fix the time zone If the operator changed or we need to fix it because - // when the NITZ time came in we didn't know the country code. - if ( ! operatorNumeric.equals(prevOperatorNumeric) || mNeedFixZone) { + if (isTimeZoneFixNeeded(phone, operatorNumeric, prevOperatorNumeric, + mNeedFixZone)) { fixTimeZone(isoCountryCode); } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index b694e0a..dd188e9 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -904,9 +904,11 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { if (getAutoTimeZone()) { setAndBroadcastNetworkSetTimeZone(zone.getID()); } else { - log("fixTimeZone: zone == null"); + log("fixTimeZone: skip changing zone as getAutoTimeZone was false"); } saveNitzTimeZone(zone.getID()); + } else { + log("fixTimeZone: zone == null, do nothing for zone"); } } @@ -1003,12 +1005,7 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); if (operatorNumeric == null) { - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " clear PROPERTY_OPERATOR_ISO_COUNTRY"); - } + if (DBG) log("operatorNumeric is null"); phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); mGotCountryCode = false; } else { @@ -1022,20 +1019,13 @@ public class CdmaServiceStateTracker extends ServiceStateTracker { } catch ( StringIndexOutOfBoundsException ex) { loge("pollStateDone: countryCodeForMcc error" + ex); } - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " mcc=" + mcc + " iso-cc=" + isoCountryCode); - } phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, isoCountryCode); mGotCountryCode = true; - // Fix the time zone If the operator changed or we need to fix it because - // when the NITZ time came in we didn't know the country code. - if ( ! operatorNumeric.equals(prevOperatorNumeric) || mNeedFixZone) { + if (isTimeZoneFixNeeded(phone, operatorNumeric, prevOperatorNumeric, + mNeedFixZone)) { fixTimeZone(isoCountryCode); } } diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java index c0acf5b..bded25a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java @@ -21,6 +21,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.DataConnectionTracker; import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.IccCardStatus; import com.android.internal.telephony.MccTable; import com.android.internal.telephony.Phone; import com.android.internal.telephony.RestrictedState; @@ -645,8 +646,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { String opNames[] = (String[])ar.result; if (opNames != null && opNames.length >= 3) { - newSS.setOperatorName ( - opNames[0], opNames[1], opNames[2]); + newSS.setOperatorName (opNames[0], opNames[1], opNames[2]); } break; @@ -858,12 +858,7 @@ final class GsmServiceStateTracker extends ServiceStateTracker { phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric); if (operatorNumeric == null) { - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " clear PROPERTY_OPERATOR_ISO_COUNTRY"); - } + if (DBG) log("operatorNumeric is null"); phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); mGotCountryCode = false; mNitzUpdatedTime = false; @@ -877,12 +872,6 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } catch ( StringIndexOutOfBoundsException ex) { loge("pollStateDone: countryCodeForMcc error" + ex); } - if (DBG) { - log("pollStateDone: operatorNumeric=" + operatorNumeric + - " prevOperatorNumeric=" + prevOperatorNumeric + - " mNeedFixZone=" + mNeedFixZone + - " mcc=" + mcc + " iso-cc=" + iso); - } phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso); mGotCountryCode = true; @@ -916,9 +905,8 @@ final class GsmServiceStateTracker extends ServiceStateTracker { } } - // Fix the time zone If the operator changed or we need to fix it because - // when the NITZ time came in we didn't know the country code. - if ( ! operatorNumeric.equals(prevOperatorNumeric) || mNeedFixZone) { + if (isTimeZoneFixNeeded(phone, operatorNumeric, prevOperatorNumeric, + mNeedFixZone)) { // If the offset is (0, false) and the timezone property // is set, use the timezone property rather than // GMT. diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java index 80988fd..52e2caf 100755 --- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java +++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java @@ -1459,6 +1459,11 @@ public class SIMRecords extends IccRecords { * After starting, FSM will search SPN EFs in order and stop after finding * the first valid SPN * + * If the FSM gets restart while waiting for one of + * SPN EFs results (i.e. a SIM refresh occurs after issuing + * read EF_CPHS_SPN), it will re-initialize only after + * receiving and discarding the unfinished SPN EF result. + * * @param start set true only for initialize loading * @param ar the AsyncResult from loadEFTransparent * ar.exception holds exception in error @@ -1468,7 +1473,19 @@ public class SIMRecords extends IccRecords { byte[] data; if (start) { - spnState = Get_Spn_Fsm_State.INIT; + // Check previous state to see if there is outstanding + // SPN read + if(spnState == Get_Spn_Fsm_State.READ_SPN_3GPP || + spnState == Get_Spn_Fsm_State.READ_SPN_CPHS || + spnState == Get_Spn_Fsm_State.READ_SPN_SHORT_CPHS || + spnState == Get_Spn_Fsm_State.INIT) { + // Set INIT then return so the INIT code + // will run when the outstanding read done. + spnState = Get_Spn_Fsm_State.INIT; + return; + } else { + spnState = Get_Spn_Fsm_State.INIT; + } } switch(spnState){ diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index b49f46c..b099202 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -184,6 +184,9 @@ public class WifiStateMachine extends StateMachine { private LinkProperties mLinkProperties; + /* Tracks sequence number on a periodic scan message */ + private int mPeriodicScanToken = 0; + // Wakelock held during wifi start/stop and driver load/unload private PowerManager.WakeLock mWakeLock; @@ -331,6 +334,9 @@ public class WifiStateMachine extends StateMachine { static final int CMD_SET_SUSPEND_OPTIMIZATIONS = BASE + 86; /* Clear suspend mode optimizations in the driver */ static final int CMD_CLEAR_SUSPEND_OPTIMIZATIONS = BASE + 87; + /* When there are no saved networks, we do a periodic scan to notify user of + * an open network */ + static final int CMD_NO_NETWORKS_PERIODIC_SCAN = BASE + 88; /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */ static final int MULTICAST_V6 = 1; @@ -385,10 +391,11 @@ public class WifiStateMachine extends StateMachine { private final int mDefaultFrameworkScanIntervalMs; /** - * Default supplicant scan interval in milliseconds. - * {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} can override this. + * Supplicant scan interval in milliseconds. + * Comes from {@link Settings.Secure#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} or + * from the default config if the setting is not set */ - private final int mDefaultSupplicantScanIntervalMs; + private long mSupplicantScanIntervalMs; /** * Minimum time interval between enabling all networks. @@ -568,9 +575,6 @@ public class WifiStateMachine extends StateMachine { mDefaultFrameworkScanIntervalMs = mContext.getResources().getInteger( com.android.internal.R.integer.config_wifi_framework_scan_interval); - mDefaultSupplicantScanIntervalMs = mContext.getResources().getInteger( - com.android.internal.R.integer.config_wifi_supplicant_scan_interval); - mDriverStopDelayMs = mContext.getResources().getInteger( com.android.internal.R.integer.config_wifi_driver_stop_delay); @@ -1869,6 +1873,7 @@ public class WifiStateMachine extends StateMachine { case WifiWatchdogStateMachine.POOR_LINK_DETECTED: case WifiWatchdogStateMachine.GOOD_LINK_DETECTED: case CMD_CLEAR_SUSPEND_OPTIMIZATIONS: + case CMD_NO_NETWORKS_PERIODIC_SCAN: break; case CMD_SET_SUSPEND_OPTIMIZATIONS: mSuspendWakeLock.release(); @@ -2268,11 +2273,15 @@ public class WifiStateMachine extends StateMachine { mIsScanMode = false; /* Wifi is available as long as we have a connection to supplicant */ mNetworkInfo.setIsAvailable(true); - /* Set scan interval */ - long supplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + + int defaultInterval = mContext.getResources().getInteger( + com.android.internal.R.integer.config_wifi_supplicant_scan_interval); + + mSupplicantScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), Settings.Secure.WIFI_SUPPLICANT_SCAN_INTERVAL_MS, - mDefaultSupplicantScanIntervalMs); - mWifiNative.setScanInterval((int)supplicantScanIntervalMs / 1000); + defaultInterval); + + mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000); } @Override public boolean processMessage(Message message) { @@ -3273,11 +3282,39 @@ public class WifiStateMachine extends StateMachine { } else { setScanAlarm(true); } + + /** + * If we have no networks saved, the supplicant stops doing the periodic scan. + * The scans are useful to notify the user of the presence of an open network. + * Note that these are not wake up scans. + */ + if (mWifiConfigStore.getConfiguredNetworks().size() == 0) { + sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, + ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); + } } @Override public boolean processMessage(Message message) { if (DBG) log(getName() + message.toString() + "\n"); + boolean ret = HANDLED; switch (message.what) { + case CMD_NO_NETWORKS_PERIODIC_SCAN: + if (message.arg1 == mPeriodicScanToken && + mWifiConfigStore.getConfiguredNetworks().size() == 0) { + sendMessage(CMD_START_SCAN); + sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, + ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); + } + break; + case WifiManager.FORGET_NETWORK: + case CMD_REMOVE_NETWORK: + // Set up a delayed message here. After the forget/remove is handled + // the handled delayed message will determine if there is a need to + // scan and continue + sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN, + ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs); + ret = NOT_HANDLED; + break; case CMD_SET_SCAN_MODE: if (message.arg1 == SCAN_ONLY_MODE) { mWifiNative.setScanResultHandling(message.arg1); @@ -3304,25 +3341,28 @@ public class WifiStateMachine extends StateMachine { StateChangeResult stateChangeResult = (StateChangeResult) message.obj; setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); /* ConnectModeState does the rest of the handling */ - return NOT_HANDLED; + ret = NOT_HANDLED; + break; case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { mWifiNative.enableBackgroundScan(false); } /* Handled in parent state */ - return NOT_HANDLED; + ret = NOT_HANDLED; + break; case WifiMonitor.SCAN_RESULTS_EVENT: /* Re-enable background scan when a pending scan result is received */ if (mEnableBackgroundScan && mScanResultIsPending) { mWifiNative.enableBackgroundScan(true); } /* Handled in parent state */ - return NOT_HANDLED; + ret = NOT_HANDLED; + break; default: - return NOT_HANDLED; + ret = NOT_HANDLED; } - return HANDLED; + return ret; } @Override |
