diff options
183 files changed, 795 insertions, 901 deletions
diff --git a/api/current.txt b/api/current.txt index b291e4d..8f3b38f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -190,6 +190,8 @@ package android { field public static final int accountPreferences = 16843423; // 0x101029f field public static final int accountType = 16843407; // 0x101028f field public static final int action = 16842797; // 0x101002d + field public static final int actionBarDivider = 16843685; // 0x10103a5 + field public static final int actionBarItemBackground = 16843686; // 0x10103a6 field public static final int actionBarSize = 16843499; // 0x10102eb field public static final int actionBarSplitStyle = 16843666; // 0x1010392 field public static final int actionBarStyle = 16843470; // 0x10102ce @@ -17269,6 +17271,7 @@ package android.provider { } public class VoicemailContract { + field public static final java.lang.String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL"; field public static final java.lang.String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL"; field public static final java.lang.String AUTHORITY = "com.android.voicemail"; field public static final java.lang.String EXTRA_SELF_CHANGE = "com.android.voicemail.extra.SELF_CHANGE"; diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java index 06d18ec..9e2b833 100644 --- a/core/java/android/animation/LayoutTransition.java +++ b/core/java/android/animation/LayoutTransition.java @@ -593,11 +593,13 @@ public class LayoutTransition { } } if (mAnimateParentHierarchy) { + Animator parentAnimator = (changeReason == APPEARING) ? + defaultChangeIn : defaultChangeOut; ViewGroup tempParent = parent; while (tempParent != null) { ViewParent parentParent = tempParent.getParent(); if (parentParent instanceof ViewGroup) { - setupChangeAnimation((ViewGroup)parentParent, changeReason, baseAnimator, + setupChangeAnimation((ViewGroup)parentParent, changeReason, parentAnimator, duration, tempParent); tempParent = (ViewGroup) parentParent; } else { @@ -626,12 +628,18 @@ public class LayoutTransition { /** * This flag controls whether CHANGE_APPEARING or CHANGE_DISAPPEARING animations will - * cause the same changing animation to be run on the parent hierarchy as well. This allows + * cause the default changing animation to be run on the parent hierarchy as well. This allows * containers of transitioning views to also transition, which may be necessary in situations * where the containers bounds change between the before/after states and may clip their * children during the transition animations. For example, layouts with wrap_content will * adjust their bounds according to the dimensions of their children. * + * <p>The default changing transitions animate the bounds and scroll positions of the + * target views. These are the animations that will run on the parent hierarchy, not + * the custom animations that happen to be set on the transition. This allows custom + * behavior for the children of the transitioning container, but uses standard behavior + * of resizing/rescrolling on any changing parents. + * * @param animateParentHierarchy A boolean value indicating whether the parents of * transitioning views should also be animated during the transition. Default value is true. */ diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java index 814f50b..6787fd0 100644 --- a/core/java/android/provider/VoicemailContract.java +++ b/core/java/android/provider/VoicemailContract.java @@ -78,6 +78,18 @@ public class VoicemailContract { /** Broadcast intent when a new voicemail record is inserted. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_NEW_VOICEMAIL = "android.intent.action.NEW_VOICEMAIL"; + + /** + * Broadcast intent to request a voicemail source to fetch voicemail content of a specific + * voicemail from the remote server. The voicemail to fetch is specified by the data uri + * of the intent. + * <p> + * All voicemail sources are expected to handle this event. After storing the content + * the application should also set {@link Voicemails#HAS_CONTENT} to 1; + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_FETCH_VOICEMAIL = "android.intent.action.FETCH_VOICEMAIL"; + /** * Extra included in {@link Intent#ACTION_PROVIDER_CHANGED} broadcast intents to indicate if the * receiving package made this change. diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 3e5f32e..376e4f5 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -16,8 +16,6 @@ package android.text; -import com.android.internal.util.ArrayUtils; - import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; @@ -30,6 +28,8 @@ import android.text.style.MetricAffectingSpan; import android.text.style.ReplacementSpan; import android.util.Log; +import com.android.internal.util.ArrayUtils; + /** * Represents a line of styled text, for measuring in visual order and * for rendering. @@ -720,7 +720,7 @@ class TextLine { float ret = 0; int contextLen = contextEnd - contextStart; - if (needWidth || (c != null && (wp.bgColor != 0 || runIsRtl))) { + if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor !=0 || runIsRtl))) { int flags = runIsRtl ? Paint.DIRECTION_RTL : Paint.DIRECTION_LTR; if (mCharsValid) { ret = wp.getTextRunAdvances(mChars, start, runLen, @@ -739,15 +739,32 @@ class TextLine { } if (wp.bgColor != 0) { - int color = wp.getColor(); - Paint.Style s = wp.getStyle(); + int previousColor = wp.getColor(); + Paint.Style previousStyle = wp.getStyle(); + wp.setColor(wp.bgColor); wp.setStyle(Paint.Style.FILL); - c.drawRect(x, top, x + ret, bottom, wp); - wp.setStyle(s); - wp.setColor(color); + wp.setStyle(previousStyle); + wp.setColor(previousColor); + } + + if (wp.underlineColor != 0) { + // kStdUnderline_Offset = 1/9, defined in SkTextFormatParams.h + float middle = y + wp.baselineShift + (1.0f / 9.0f) * wp.getTextSize(); + // kStdUnderline_Thickness = 1/18, defined in SkTextFormatParams.h + float halfHeight = wp.underlineThickness * (1.0f / 18.0f / 2.0f) * wp.getTextSize(); + + int previousColor = wp.getColor(); + Paint.Style previousStyle = wp.getStyle(); + + wp.setColor(wp.underlineColor); + wp.setStyle(Paint.Style.FILL); + c.drawRect(x, middle - halfHeight, x + ret, middle + halfHeight, wp); + + wp.setStyle(previousStyle); + wp.setColor(previousColor); } drawTextRun(c, wp, start, end, contextStart, contextEnd, runIsRtl, diff --git a/core/java/android/text/TextPaint.java b/core/java/android/text/TextPaint.java index f9e7cac..de57dfa 100644 --- a/core/java/android/text/TextPaint.java +++ b/core/java/android/text/TextPaint.java @@ -23,11 +23,22 @@ import android.graphics.Paint; * data used during text measuring and drawing. */ public class TextPaint extends Paint { + // Special value 0 means no background paint public int bgColor; public int baselineShift; public int linkColor; public int[] drawableState; public float density = 1.0f; + /** + * Special value 0 means no custom underline + * @hide + */ + public int underlineColor; + /** + * Defined as a multiplier of the default underline thickness. Use 1.0f for default thickness. + * @hide + */ + public float underlineThickness; public TextPaint() { super(); @@ -53,5 +64,24 @@ public class TextPaint extends Paint { linkColor = tp.linkColor; drawableState = tp.drawableState; density = tp.density; + underlineColor = tp.underlineColor; + underlineThickness = tp.underlineThickness; + } + + /** + * Defines a custom underline for this Paint. + * @param color underline solid color + * @param thickness underline thickness, defined as a multiplier of the default underline + * thickness. + * @hide + */ + public void setUnderlineText(boolean isUnderlined, int color, float thickness) { + setUnderlineText(false); + if (isUnderlined) { + underlineColor = color; + underlineThickness = thickness; + } else { + underlineColor = 0; + } } } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index a7fe95d..e586370 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -509,13 +509,6 @@ class GLES20Canvas extends HardwareCanvas { private static native void nSetMatrix(int renderer, int matrix); @Override - public int getNativeMatrix() { - return nGetMatrix(mRenderer); - } - - private static native int nGetMatrix(int renderer); - - @Override public void getMatrix(Matrix matrix) { nGetMatrix(mRenderer, matrix.native_instance); } diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index 0df7bcc..31360e1 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -253,7 +253,7 @@ public class ActionBarImpl extends ActionBar { @Override public void setCustomView(int resId) { - setCustomView(LayoutInflater.from(mContext).inflate(resId, mActionView, false)); + setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId, mActionView, false)); } @Override @@ -630,14 +630,14 @@ public class ActionBarImpl extends ActionBar { public ActionModeImpl(ActionMode.Callback callback) { mCallback = callback; - mMenu = new MenuBuilder(mActionView.getContext()) + mMenu = new MenuBuilder(getThemedContext()) .setDefaultShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); mMenu.setCallback(this); } @Override public MenuInflater getMenuInflater() { - return new MenuInflater(mContext); + return new MenuInflater(getThemedContext()); } @Override @@ -755,7 +755,7 @@ public class ActionBarImpl extends ActionBar { return true; } - new MenuPopupHelper(mContext, subMenu).show(); + new MenuPopupHelper(getThemedContext(), subMenu).show(); return true; } @@ -819,7 +819,8 @@ public class ActionBarImpl extends ActionBar { @Override public Tab setCustomView(int layoutResId) { - return setCustomView(LayoutInflater.from(mContext).inflate(layoutResId, null)); + return setCustomView(LayoutInflater.from(getThemedContext()) + .inflate(layoutResId, null)); } @Override diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl index dd22e25..d407080 100755 --- a/core/java/com/android/internal/app/IMediaContainerService.aidl +++ b/core/java/com/android/internal/app/IMediaContainerService.aidl @@ -25,7 +25,7 @@ interface IMediaContainerService { String copyResourceToContainer(in Uri packageURI, String containerId, String key, String resFileName); - boolean copyResource(in Uri packageURI, + int copyResource(in Uri packageURI, in ParcelFileDescriptor outStream); PackageInfoLite getMinimalPackageInfo(in Uri fileUri, in int flags, in long threshold); boolean checkInternalFreeStorage(in Uri fileUri, in long threshold); diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java index b4d2d72..fd9ee08 100644 --- a/core/java/com/android/internal/widget/ActionBarContainer.java +++ b/core/java/com/android/internal/widget/ActionBarContainer.java @@ -25,6 +25,7 @@ import android.util.AttributeSet; import android.view.ActionMode; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; /** @@ -109,7 +110,9 @@ public class ActionBarContainer extends FrameLayout { mTabContainer = tabView; if (tabView != null) { addView(tabView); - tabView.getLayoutParams().width = LayoutParams.MATCH_PARENT; + final ViewGroup.LayoutParams lp = tabView.getLayoutParams(); + lp.width = LayoutParams.MATCH_PARENT; + lp.height = LayoutParams.WRAP_CONTENT; tabView.setAllowCollapse(false); } } diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java index 0e4c9ef..71f9364 100644 --- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java +++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java @@ -68,6 +68,11 @@ public class ScrollingTabContainerView extends HorizontalScrollView super(context); setHorizontalScrollBarEnabled(false); + TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionBar, + com.android.internal.R.attr.actionBarStyle, 0); + setContentHeight(a.getLayoutDimension(R.styleable.ActionBar_height, 0)); + a.recycle(); + mTabLayout = createTabLayout(); addView(mTabLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)); @@ -91,16 +96,7 @@ public class ScrollingTabContainerView extends HorizontalScrollView mMaxTabWidth = -1; } - int heightMode = MeasureSpec.getMode(heightMeasureSpec); - int heightSize = MeasureSpec.getSize(heightMeasureSpec); - if (heightMode != MeasureSpec.UNSPECIFIED) { - if (mContentHeight == 0 && heightMode == MeasureSpec.EXACTLY) { - // Use this as our content height. - mContentHeight = heightSize; - } - heightSize = Math.min(heightSize, mContentHeight); - heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); - } + heightMeasureSpec = MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY); final boolean canCollapse = !lockedExpanded && mAllowCollapse; diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index b3f2d51..039c5ba 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -289,11 +289,6 @@ static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz, renderer->setMatrix(matrix); } -static const float* android_view_GLES20Canvas_getNativeMatrix(JNIEnv* env, - jobject clazz, OpenGLRenderer* renderer) { - return renderer->getMatrix(); -} - static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz, OpenGLRenderer* renderer, SkMatrix* matrix) { renderer->getMatrix(matrix); @@ -776,7 +771,6 @@ static JNINativeMethod gMethods[] = { { "nSkew", "(IFF)V", (void*) android_view_GLES20Canvas_skew }, { "nSetMatrix", "(II)V", (void*) android_view_GLES20Canvas_setMatrix }, - { "nGetMatrix", "(I)I", (void*) android_view_GLES20Canvas_getNativeMatrix }, { "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix }, { "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix }, diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png Binary files differindex 595e0a4..1d33e47 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo1.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png Binary files differindex 75ad3d6..81fe085 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo2.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png Binary files differindex 74e90fd..cf864d2 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo3.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png Binary files differindex 7e6948a..583e0c9 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo4.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png Binary files differindex 38b376c..357b660 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo5.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png Binary files differindex 7cbdcf8..0add340 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo6.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png Binary files differindex b362b20..e1a8a63 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo7.png diff --git a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png Binary files differindex 45f4f59..934d6d1 100644 --- a/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png +++ b/core/res/res/drawable-hdpi/progressbar_indeterminate_holo8.png diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png Binary files differindex f2266a2..3c4a50e 100644 --- a/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/scrollbar_handle_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png Binary files differindex 03e412b..222c776 100644 --- a/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png +++ b/core/res/res/drawable-hdpi/scrollbar_handle_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png Binary files differindex 822da81..a231195 100644 --- a/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png +++ b/core/res/res/drawable-hdpi/scrubber_control_disabled_holo.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_holo.png b/core/res/res/drawable-hdpi/scrubber_control_holo.png Binary files differindex 9957851..fae05e5 100644 --- a/core/res/res/drawable-hdpi/scrubber_control_holo.png +++ b/core/res/res/drawable-hdpi/scrubber_control_holo.png diff --git a/core/res/res/drawable-hdpi/scrubber_control_pressed_holo.png b/core/res/res/drawable-hdpi/scrubber_control_pressed_holo.png Binary files differnew file mode 100644 index 0000000..ff4d710 --- /dev/null +++ b/core/res/res/drawable-hdpi/scrubber_control_pressed_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png Binary files differindex 8c93779..01f4278 100644 --- a/core/res/res/drawable-hdpi/spinner_16_inner_holo.png +++ b/core/res/res/drawable-hdpi/spinner_16_inner_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_16_outer_holo.png b/core/res/res/drawable-hdpi/spinner_16_outer_holo.png Binary files differindex d272f93..20fc20a 100644 --- a/core/res/res/drawable-hdpi/spinner_16_outer_holo.png +++ b/core/res/res/drawable-hdpi/spinner_16_outer_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png Binary files differindex 3c371b2d..4c9849f 100644 --- a/core/res/res/drawable-hdpi/spinner_20_inner_holo.png +++ b/core/res/res/drawable-hdpi/spinner_20_inner_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png Binary files differindex 2820b5f..82b5671 100644 --- a/core/res/res/drawable-hdpi/spinner_20_outer_holo.png +++ b/core/res/res/drawable-hdpi/spinner_20_outer_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png Binary files differindex a992251..5d15e74 100644 --- a/core/res/res/drawable-hdpi/spinner_48_inner_holo.png +++ b/core/res/res/drawable-hdpi/spinner_48_inner_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png Binary files differindex 27452b1..5648af0 100644 --- a/core/res/res/drawable-hdpi/spinner_48_outer_holo.png +++ b/core/res/res/drawable-hdpi/spinner_48_outer_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png Binary files differindex 3d426e0..cc8affe 100644 --- a/core/res/res/drawable-hdpi/spinner_76_inner_holo.png +++ b/core/res/res/drawable-hdpi/spinner_76_inner_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png Binary files differindex 92f77a3..1efa5eb 100644 --- a/core/res/res/drawable-hdpi/spinner_76_outer_holo.png +++ b/core/res/res/drawable-hdpi/spinner_76_outer_holo.png diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png Binary files differindex ac36c06..80bba6b 100644 --- a/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png Binary files differindex 6821599..ffd9e37 100644 --- a/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png Binary files differindex adde694..ea20276 100644 --- a/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png Binary files differindex fdb4bdf..c2b031c 100644 --- a/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png Binary files differindex d40d165..a3fc804 100644 --- a/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png Binary files differindex 096b977..a3fc804 100644 --- a/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png Binary files differindex 3b26017..86aa7da 100644 --- a/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png Binary files differindex 33b661b..c8ec05d 100644 --- a/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png +++ b/core/res/res/drawable-hdpi/spinner_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png Binary files differindex d9ac6ad..a32dc0d 100644 --- a/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_activated_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png Binary files differindex d9ac6ad..a32dc0d 100644 --- a/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_activated_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png Binary files differindex 503607e..1f71467 100644 --- a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png Binary files differindex bfc378b..00fe8c7 100644 --- a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png Binary files differindex ddc4f7d..b988435 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png Binary files differindex e2540570..0419273 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png Binary files differindex 374c576..b26accb 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png Binary files differindex ebaaa14..1eb5e3a 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png Binary files differindex d9ac6ad..a32dc0d 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png Binary files differindex d9ac6ad..a32dc0d 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_activated_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png Binary files differindex 503607e..1f71467 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png Binary files differindex bfc378b..00fe8c7 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png Binary files differindex ddc4f7d..b988435 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png Binary files differindex e2540570..0419273 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png Binary files differindex 374c576..b26accb 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png Binary files differindex ebaaa14..1eb5e3a 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png Binary files differindex 78cbf0b..03a81d9 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png Binary files differindex 78cbf0b..03a81d9 100644 --- a/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_multiline_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png Binary files differindex c22a53a..4cab1a1 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo1.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png Binary files differindex c288541..2692bd1 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo2.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png Binary files differindex 25df6b9..d83cad9 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo3.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png Binary files differindex 65718e1..4ef84a1 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo4.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png Binary files differindex 39148e0..f661b11 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo5.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png Binary files differindex 8ff7b24..69df8e0 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo6.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png Binary files differindex a7302c1..c34f0a5 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo7.png diff --git a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png Binary files differindex 70bf210..2258b20 100644 --- a/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png +++ b/core/res/res/drawable-mdpi/progressbar_indeterminate_holo8.png diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png Binary files differindex d3e3a38..9407756 100644 --- a/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/scrollbar_handle_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png Binary files differindex d0ec4dd..d2d0292 100644 --- a/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png +++ b/core/res/res/drawable-mdpi/scrollbar_handle_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-mdpi/scrubber_control_disabled_holo.png Binary files differindex 66dc001..9d7b77c 100644 --- a/core/res/res/drawable-mdpi/scrubber_control_disabled_holo.png +++ b/core/res/res/drawable-mdpi/scrubber_control_disabled_holo.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_holo.png b/core/res/res/drawable-mdpi/scrubber_control_holo.png Binary files differindex 6e0e85a..832fa07 100644 --- a/core/res/res/drawable-mdpi/scrubber_control_holo.png +++ b/core/res/res/drawable-mdpi/scrubber_control_holo.png diff --git a/core/res/res/drawable-mdpi/scrubber_control_pressed_holo.png b/core/res/res/drawable-mdpi/scrubber_control_pressed_holo.png Binary files differnew file mode 100644 index 0000000..4a518f2 --- /dev/null +++ b/core/res/res/drawable-mdpi/scrubber_control_pressed_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_16_inner_holo.png b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png Binary files differindex 392e1f8..a322a02 100644 --- a/core/res/res/drawable-mdpi/spinner_16_inner_holo.png +++ b/core/res/res/drawable-mdpi/spinner_16_inner_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_16_outer_holo.png b/core/res/res/drawable-mdpi/spinner_16_outer_holo.png Binary files differindex d862a25..07df4cb 100644 --- a/core/res/res/drawable-mdpi/spinner_16_outer_holo.png +++ b/core/res/res/drawable-mdpi/spinner_16_outer_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png b/core/res/res/drawable-mdpi/spinner_20_inner_holo.png Binary files differindex f5e7f73..538788a 100644 --- a/core/res/res/drawable-mdpi/spinner_20_inner_holo.png +++ b/core/res/res/drawable-mdpi/spinner_20_inner_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png b/core/res/res/drawable-mdpi/spinner_20_outer_holo.png Binary files differindex b7ecfff..f345311 100644 --- a/core/res/res/drawable-mdpi/spinner_20_outer_holo.png +++ b/core/res/res/drawable-mdpi/spinner_20_outer_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_48_inner_holo.png b/core/res/res/drawable-mdpi/spinner_48_inner_holo.png Binary files differindex 5231a5b..b59dc64 100644 --- a/core/res/res/drawable-mdpi/spinner_48_inner_holo.png +++ b/core/res/res/drawable-mdpi/spinner_48_inner_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_48_outer_holo.png b/core/res/res/drawable-mdpi/spinner_48_outer_holo.png Binary files differindex e1e5b52..024f0f2 100644 --- a/core/res/res/drawable-mdpi/spinner_48_outer_holo.png +++ b/core/res/res/drawable-mdpi/spinner_48_outer_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_76_inner_holo.png b/core/res/res/drawable-mdpi/spinner_76_inner_holo.png Binary files differindex 982f037..e7d654c 100644 --- a/core/res/res/drawable-mdpi/spinner_76_inner_holo.png +++ b/core/res/res/drawable-mdpi/spinner_76_inner_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_76_outer_holo.png b/core/res/res/drawable-mdpi/spinner_76_outer_holo.png Binary files differindex 01b6ab3..e81bb06 100644 --- a/core/res/res/drawable-mdpi/spinner_76_outer_holo.png +++ b/core/res/res/drawable-mdpi/spinner_76_outer_holo.png diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png Binary files differindex 99b1605..ddc2b22 100644 --- a/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png Binary files differindex c820e40..eb0d501 100644 --- a/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png Binary files differindex 95d7c86..8ba2a42 100644 --- a/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png Binary files differindex 2dba270..cf50964 100644 --- a/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png Binary files differindex 2e2fadd..7ab9428 100644 --- a/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png Binary files differindex 5bbbf63..7ab9428 100644 --- a/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png Binary files differindex 083194a..5654920 100644 --- a/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png Binary files differindex 29cbc46..655339d 100644 --- a/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png +++ b/core/res/res/drawable-mdpi/spinner_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png Binary files differindex 466beba..c97cff4 100644 --- a/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_activated_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png Binary files differindex 466beba..c97cff4 100644 --- a/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_activated_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png Binary files differindex 0ef89fe..bf7df17 100644 --- a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png Binary files differindex d9583ee..6aa64c6 100644 --- a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png Binary files differindex 4091b7b..c5f098c 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png Binary files differindex d56e8f4..8a63152 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png Binary files differindex fce496a..7f15e1e 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png Binary files differindex c258087..8bdbb2e 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png Binary files differindex 466beba..c97cff4 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png Binary files differindex 466beba..c97cff4 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_activated_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png Binary files differindex 0ef89fe..bf7df17 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png Binary files differindex d9583ee..6aa64c6 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png Binary files differindex 4091b7b..c5f098c 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png Binary files differindex d56e8f4..8a63152 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png Binary files differindex fce496a..7f15e1e 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png Binary files differindex c258087..8bdbb2e 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png Binary files differindex 83e1d98..efbaef8 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png Binary files differindex 83e1d98..efbaef8 100644 --- a/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_multiline_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png Binary files differnew file mode 100644 index 0000000..f96a4a6 --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo1.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png Binary files differnew file mode 100644 index 0000000..3a6554f --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo2.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png Binary files differnew file mode 100644 index 0000000..30bd7ad --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo3.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png Binary files differnew file mode 100644 index 0000000..209036b --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo4.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png Binary files differnew file mode 100644 index 0000000..830820b --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo5.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png Binary files differnew file mode 100644 index 0000000..39eb204 --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo6.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png Binary files differnew file mode 100644 index 0000000..a2d4dc2 --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo7.png diff --git a/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png Binary files differnew file mode 100644 index 0000000..1772aea --- /dev/null +++ b/core/res/res/drawable-xhdpi/progressbar_indeterminate_holo8.png diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png Binary files differindex 664cc85..948072f 100644 --- a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png Binary files differindex f463f39..461be3f 100644 --- a/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/scrollbar_handle_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_horizontal.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_horizontal.9.png Binary files differnew file mode 100644 index 0000000..be3e90e --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrollbar_handle_horizontal.9.png diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_vertical.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_vertical.9.png Binary files differnew file mode 100644 index 0000000..4f6391f --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrollbar_handle_vertical.9.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png b/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png Binary files differindex c3b9bb4..0b0bf24 100644 --- a/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png +++ b/core/res/res/drawable-xhdpi/scrubber_control_disabled_holo.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_holo.png b/core/res/res/drawable-xhdpi/scrubber_control_holo.png Binary files differindex f72e48c..45060cb 100644 --- a/core/res/res/drawable-xhdpi/scrubber_control_holo.png +++ b/core/res/res/drawable-xhdpi/scrubber_control_holo.png diff --git a/core/res/res/drawable-xhdpi/scrubber_control_pressed_holo.png b/core/res/res/drawable-xhdpi/scrubber_control_pressed_holo.png Binary files differnew file mode 100644 index 0000000..d1fe115 --- /dev/null +++ b/core/res/res/drawable-xhdpi/scrubber_control_pressed_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png Binary files differindex f5e9164..d49d67a 100644 --- a/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_16_inner_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png Binary files differindex 6f977a2..583e4a2 100644 --- a/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_16_outer_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png Binary files differindex 16c8430..5eec6f3 100644 --- a/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_20_inner_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png Binary files differindex 9593616..34fbbf0 100644 --- a/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_20_outer_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png Binary files differindex cebf1d8..6f82402 100644 --- a/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_48_inner_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png Binary files differindex 5a9e001..fd202f4 100644 --- a/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_48_outer_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png b/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png Binary files differindex c68cc37..af88495 100644 --- a/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_76_inner_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png b/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png Binary files differindex 611dc5a..a416478 100644 --- a/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png +++ b/core/res/res/drawable-xhdpi/spinner_76_outer_holo.png diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..06b6dc7 --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_default_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png Binary files differnew file mode 100644 index 0000000..aa32bcf --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_default_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..ba25eb0 --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png Binary files differnew file mode 100644 index 0000000..7a015ba --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..c6aad24 --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..c6aad24 --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..a0a7867 --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png Binary files differnew file mode 100644 index 0000000..85a3cae --- /dev/null +++ b/core/res/res/drawable-xhdpi/spinner_pressed_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png Binary files differindex 2f35995..4c4e02c 100644 --- a/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_activated_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png Binary files differindex 2f35995..4c4e02c 100644 --- a/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_activated_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png Binary files differindex b22dd41..86221f0 100644 --- a/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_default_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png Binary files differindex 3a9a51a..a604537 100644 --- a/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_default_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png Binary files differindex c11d800..cf1b79f 100644 --- a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png Binary files differindex cdd8752..d1ecc73 100644 --- a/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png Binary files differindex 5f40cac..e97c5d7 100644 --- a/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png Binary files differindex aa35049..5c52dd5 100644 --- a/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png Binary files differindex 2f35995..4c4e02c 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png Binary files differindex 2f35995..4c4e02c 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_activated_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png Binary files differindex b22dd41..86221f0 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png Binary files differindex 3a9a51a..a604537 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_default_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png Binary files differindex c11d800..cf1b79f 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png Binary files differindex cdd8752..d1ecc73 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png Binary files differindex 5f40cac..e97c5d7 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png Binary files differindex aa35049..5c52dd5 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_disabled_holo_light.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png Binary files differindex 09e3fff..3ed03f3 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_dark.9.png diff --git a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png Binary files differindex 09e3fff..3ed03f3 100644 --- a/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png +++ b/core/res/res/drawable-xhdpi/textfield_multiline_focused_holo_light.9.png diff --git a/core/res/res/drawable/scrubber_control_selector_holo.xml b/core/res/res/drawable/scrubber_control_selector_holo.xml index c7b8854..d146eee 100644 --- a/core/res/res/drawable/scrubber_control_selector_holo.xml +++ b/core/res/res/drawable/scrubber_control_selector_holo.xml @@ -15,6 +15,7 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:state_enabled="true" android:drawable="@android:drawable/scrubber_control_pressed_holo" /> <item android:state_enabled="true" android:drawable="@android:drawable/scrubber_control_holo" /> <item android:drawable="@android:drawable/scrubber_control_disabled_holo" /> </selector> diff --git a/core/res/res/layout/action_bar_home.xml b/core/res/res/layout/action_bar_home.xml index 9612710..96467d0 100644 --- a/core/res/res/layout/action_bar_home.xml +++ b/core/res/res/layout/action_bar_home.xml @@ -18,7 +18,7 @@ class="com.android.internal.widget.ActionBarView$HomeView" android:layout_width="wrap_content" android:layout_height="match_parent" - android:background="?android:attr/selectableItemBackground" > + android:background="?android:attr/actionBarItemBackground" > <ImageView android:id="@android:id/up" android:src="?android:attr/homeAsUpIndicator" android:layout_gravity="center_vertical|left" diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml index f6b5b53..673c96c 100644 --- a/core/res/res/layout/search_bar.xml +++ b/core/res/res/layout/search_bar.xml @@ -75,5 +75,5 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitXY" - android:src="@drawable/title_bar_shadow"/> + android:src="@drawable/ab_solid_shadow_holo"/> </view> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index f4c0240..140a8c9 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -633,6 +633,10 @@ <attr name="actionBarSize" format="dimension" > <enum name="wrap_content" value="0" /> </attr> + <!-- Custom divider drawable to use for elements in the action bar. --> + <attr name="actionBarDivider" format="reference" /> + <!-- Custom item state list drawable background for action bar items. --> + <attr name="actionBarItemBackground" format="reference" /> <!-- TextAppearance style that will be applied to text that appears within action menu items. --> <attr name="actionMenuTextAppearance" format="reference" /> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 1ba54cf..44995c8 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1788,6 +1788,9 @@ <public type="attr" name="subtypeLocale" /> <public type="attr" name="subtypeExtraValue" /> + <public type="attr" name="actionBarDivider" /> + <public type="attr" name="actionBarItemBackground" /> + <public type="style" name="TextAppearance.SuggestionHighlight" /> <public type="style" name="Theme.Holo.Light.DarkActionBar" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 583310d..71e302f 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -916,18 +916,19 @@ applications can use this to erase or modify your contact data.</string> <!-- Title of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=30] --> - <string name="permlab_readProfile">read profile data</string> + <string name="permlab_readProfile">read your profile data</string> <!-- Description of the read profile permission, listed so the user can decide whether to allow the application to read the user's personal profile data. [CHAR LIMIT=NONE] --> - <string name="permdesc_readProfile" product="default">Allows an application to read all - of your personal profile information. Malicious applications can use this to identify - you and send your personal information to other people.</string> + <string name="permdesc_readProfile" product="default">Allows the application to read personal + profile information stored on your device, such as your name and contact information. This + means the application can identify you and send your profile information to others.</string> <!-- Title of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=30] --> - <string name="permlab_writeProfile">write profile data</string> + <string name="permlab_writeProfile">write to your profile data</string> <!-- Description of the write profile permission, listed so the user can decide whether to allow the application to write to the user's personal profile data. [CHAR LIMIT=NONE] --> - <string name="permdesc_writeProfile" product="default">Allows an application to modify - your personal profile information. Malicious applications can use this to erase or - modify your profile data.</string> + <string name="permdesc_writeProfile" product="default">Allows the application to change or add + to personal profile information stored on your device, such as your name and contact + information. This means other applications can identify you and send your profile + information to others.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_readCalendar">read calendar events plus confidential information</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 0c6e20f..1f6b50a 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1113,7 +1113,7 @@ please see styles_device_defaults.xml. </style> <style name="Widget.ActionButton"> - <item name="android:background">?android:attr/selectableItemBackground</item> + <item name="android:background">?android:attr/actionBarItemBackground</item> <item name="android:paddingLeft">12dip</item> <item name="android:paddingRight">12dip</item> <item name="android:minWidth">56dip</item> @@ -1847,9 +1847,9 @@ please see styles_device_defaults.xml. </style> <style name="Widget.Holo.ActionBar.TabBar" parent="Widget.ActionBar.TabBar"> - <item name="android:divider">?android:attr/dividerVertical</item> + <item name="android:divider">?android:attr/actionBarDivider</item> <item name="android:showDividers">middle</item> - <item name="android:dividerPadding">8dip</item> + <item name="android:dividerPadding">12dip</item> </style> <style name="Widget.Holo.ActionBar.TabText" parent="Widget.ActionBar.TabText"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 82299b8..add7dc8 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -308,6 +308,8 @@ please see themes_device_defaults.xml. <item name="actionMenuTextAppearance">@android:style/TextAppearance.Holo.Widget.ActionBar.Menu</item> <item name="actionMenuTextColor">?android:attr/textColorPrimary</item> <item name="actionBarWidgetTheme">@null</item> + <item name="actionBarDivider">?android:attr/dividerVertical</item> + <item name="actionBarItemBackground">?android:attr/selectableItemBackground</item> <item name="dividerVertical">@drawable/divider_vertical_dark</item> <item name="dividerHorizontal">@drawable/divider_vertical_dark</item> @@ -1429,7 +1431,7 @@ please see themes_device_defaults.xml. with an inverse color profile. The dark action bar sharply stands out against the light content. --> <style name="Theme.Holo.Light.DarkActionBar"> - <item name="android:windowContentOverlay">@android:drawable/title_bar_shadow</item> + <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item> <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item> <item name="actionBarWidgetTheme">@android:style/Theme.Holo</item> @@ -1442,6 +1444,8 @@ please see themes_device_defaults.xml. <item name="actionBarTabStyle">@style/Widget.Holo.Light.ActionBar.TabView.Inverse</item> <item name="actionBarTabBarStyle">@style/Widget.Holo.Light.ActionBar.TabBar.Inverse</item> <item name="actionBarTabTextStyle">@style/Widget.Holo.Light.ActionBar.TabText.Inverse</item> + <item name="actionBarDivider">@android:drawable/list_divider_holo_dark</item> + <item name="actionBarItemBackground">@android:drawable/item_background_holo_dark</item> <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item> <item name="actionModeStyle">@style/Widget.Holo.Light.ActionMode.Inverse</item> <item name="actionModeCloseButtonStyle">@style/Widget.Holo.ActionButton.CloseMode</item> diff --git a/docs/html/guide/practices/design/jni.jd b/docs/html/guide/practices/design/jni.jd index 1d0e26e..6e984b0 100644 --- a/docs/html/guide/practices/design/jni.jd +++ b/docs/html/guide/practices/design/jni.jd @@ -18,9 +18,9 @@ page.title=JNI Tips <li><a href="#native_libraries">Native Libraries</a></li> <li><a href="#64_bit">64-bit Considerations</a></li> <li><a href="#unsupported">Unsupported Features</a></li> - <li><a href="#faq_ULE">FAQ: UnsatisfiedLinkError</a></li> - <li><a href="#faq_FindClass">FAQ: FindClass didn't find my class</a></li> - <li><a href="#faq_sharing">FAQ: Sharing raw data with native code</a></li> + <li><a href="#faq_ULE">FAQ: Why do I get <code>UnsatisfiedLinkError</code></a></li> + <li><a href="#faq_FindClass">FAQ: Why didn't <code>FindClass</code> find my class?</a></li> + <li><a href="#faq_sharing">FAQ: How do I share raw data with native code?</a></li> </ol> </div> @@ -28,7 +28,7 @@ page.title=JNI Tips <p>JNI is the Java Native Interface. It defines a way for code written in the Java programming language to interact with native -code, e.g. functions written in C/C++. It's VM-neutral, has support for loading code from +code: functions written in C/C++. It's VM-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.</p> <p>You really should read through the @@ -36,8 +36,7 @@ dynamic shared libraries, and while cumbersome at times is reasonably efficient. to get a sense for how JNI works and what features are available. Some aspects of the interface aren't immediately obvious on first reading, so you may find the next few sections handy. -The more detailed <i>JNI Programmer's Guide and Specification</i> can be found -<a href="http://java.sun.com/docs/books/jni/html/jniTOC.html">here</a>.</p> +There's a more detailed <a href="http://java.sun.com/docs/books/jni/html/jniTOC.html">JNI Programmer's Guide and Specification</a>.</p> <a name="JavaVM_and_JNIEnv" id="JavaVM_and_JNIEnv"></a> @@ -55,20 +54,20 @@ the first argument.</p> <p>On some VMs, the JNIEnv is used for thread-local storage. For this reason, <strong>you cannot share a JNIEnv between threads</strong>. If a piece of code has no other way to get its JNIEnv, you should share -the JavaVM, and use JavaVM->GetEnv to discover the thread's JNIEnv. (Assuming it has one; see <code>AttachCurrentThread</code> below.)</p> +the JavaVM, and use <code>GetEnv</code> to discover the thread's JNIEnv. (Assuming it has one; see <code>AttachCurrentThread</code> below.)</p> <p>The C declarations of JNIEnv and JavaVM are different from the C++ -declarations. "jni.h" provides different typedefs -depending on whether it's included into ".c" or ".cpp". For this reason it's a bad idea to +declarations. The <code>"jni.h"</code> include file provides different typedefs +depending on whether it's included into C or C++. For this reason it's a bad idea to include JNIEnv arguments in header files included by both languages. (Put another way: if your -header file requires "#ifdef __cplusplus", you may have to do some extra work if anything in +header file requires <code>#ifdef __cplusplus</code>, you may have to do some extra work if anything in that header refers to JNIEnv.)</p> <a name="threads" id="threads"></a> <h2>Threads</h2> <p>All VM threads are Linux threads, scheduled by the kernel. They're usually -started using Java language features (notably <code>Thread.start()</code>), +started using Java language features (notably <code>Thread.start</code>), but they can also be created elsewhere and then attached to the VM. For example, a thread started with <code>pthread_create</code> can be attached with the JNI <code>AttachCurrentThread</code> or @@ -87,7 +86,7 @@ request, the VM will pause the thread the next time it makes a JNI call.</p> <p>Threads attached through JNI <strong>must call <code>DetachCurrentThread</code> before they exit</strong>. -If coding this directly is awkward, in Android >= 2.0 ("Eclair") you +If coding this directly is awkward, in Android 2.0 (Eclair) and higher you can use <code>pthread_key_create</code> to define a destructor function that will be called before the thread exits, and call <code>DetachCurrentThread</code> from there. (Use that @@ -104,7 +103,7 @@ the argument.)</p> <ul> <li> Get the class object reference for the class with <code>FindClass</code></li> <li> Get the field ID for the field with <code>GetFieldID</code></li> -<li> Get the contents of the field with something appropriate, e.g. +<li> Get the contents of the field with something appropriate, such as <code>GetIntField</code></li> </ul> @@ -114,12 +113,12 @@ comparisons, but once you have them the actual call to get the field or invoke t is very quick.</p> <p>If performance is important, it's useful to look the values up once and cache the results -in your native code. Because we are limiting ourselves to one VM per process, it's reasonable +in your native code. Because there is a limit of one VM per process, it's reasonable to store this data in a static local structure.</p> <p>The class references, field IDs, and method IDs are guaranteed valid until the class is unloaded. Classes are only unloaded if all classes associated with a ClassLoader can be garbage collected, -which is rare but will not be impossible in our system. Note however that +which is rare but will not be impossible in Android. Note however that the <code>jclass</code> is a class reference and <strong>must be protected</strong> with a call to <code>NewGlobalRef</code> (see the next section).</p> @@ -130,27 +129,18 @@ the IDs is to add a piece of code that looks like this to the appropriate class: <pre> /* * We use a class initializer to allow the native code to cache some - * field offsets. + * field offsets. This native function looks up and caches interesting + * class/field/method IDs. Throws on failure. */ + private static native void nativeInit(); - /* - * A native function that looks up and caches interesting - * class/field/method IDs for this class. Returns false on failure. - */ - native private static boolean nativeClassInit(); - - /* - * Invoke the native initializer when the class is loaded. - */ static { - if (!nativeClassInit()) - throw new RuntimeException("native init failed"); + nativeInit(); }</pre> -<p>Create a nativeClassInit method in your C/C++ code that performs the ID lookups. The code +<p>Create a <code>nativeClassInit</code> method in your C/C++ code that performs the ID lookups. The code will be executed once, when the class is initialized. If the class is ever unloaded and -then reloaded, it will be executed again. (See the implementation of java.io.FileDescriptor -for an example in our source tree.)</p> +then reloaded, it will be executed again.</p> <a name="local_and_global_references" id="local_and_global_references"></a> <h2>Local and Global References</h2> @@ -175,12 +165,12 @@ from <code>FindClass</code>, e.g.:</p> jclass globalClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));</pre> <p>All JNI methods accept both local and global references as arguments. -It's possible for references to the same object to have different values; -for example, the return values from consecutive calls to +It's possible for references to the same object to have different values. +For example, the return values from consecutive calls to <code>NewGlobalRef</code> on the same object may be different. <strong>To see if two references refer to the same object, you must use the <code>IsSameObject</code> function.</strong> Never compare -references with "==" in native code.</p> +references with <code>==</code> in native code.</p> <p>One consequence of this is that you <strong>must not assume object references are constant or unique</strong> @@ -197,13 +187,13 @@ VM is only required to reserve slots for 16 local references, so if you need more than that you should either delete as you go or use <code>EnsureLocalCapacity</code> to reserve more.</p> -<p>Note: method and field IDs are just 32-bit identifiers, not object +<p>Note that <code>jfieldID</code>s and <code>jmethodID</code>s are just integers, not object references, and should not be passed to <code>NewGlobalRef</code>. The raw data pointers returned by functions like <code>GetStringUTFChars</code> and <code>GetByteArrayElements</code> are also not objects.</p> <p>One unusual case deserves separate mention. If you attach a native -thread to the VM with AttachCurrentThread, the code you are running will +thread to the VM with <code>AttachCurrentThread</code>, the code you are running will never "return" to the VM until the thread detaches from the VM. Any local references you create will have to be deleted manually unless you're going to detach the thread soon.</p> @@ -217,17 +207,17 @@ The nice thing about this is that you can count on having C-style zero-terminate suitable for use with standard libc string functions. The down side is that you cannot pass arbitrary UTF-8 data into the VM and expect it to work correctly.</p> -<p>It's usually best to operate with UTF-16 strings. With our current VMs, the +<p>It's usually best to operate with UTF-16 strings. With Android's current VMs, the <code>GetStringChars</code> method does not require a copy, whereas <code>GetStringUTFChars</code> requires a malloc and a UTF conversion. Note that <strong>UTF-16 strings are not zero-terminated</strong>, and \u0000 is allowed, so you need to hang on to the string length as well as the string pointer.</p> -<p><strong>Don't forget to Release the strings you Get</strong>. The +<p><strong>Don't forget to <code>Release</code> the strings you <code>Get</code></strong>. The string functions return <code>jchar*</code> or <code>jbyte*</code>, which are C-style pointers to primitive data rather than local references. They -are guaranteed valid until Release is called, which means they are not +are guaranteed valid until <code>Release</code> is called, which means they are not released when the native method returns.</p> <p><strong>Data passed to NewStringUTF must be in Modified UTF-8 format</strong>. A @@ -254,8 +244,8 @@ allocate some memory and make a copy. Either way, the raw pointer returned is guaranteed to be valid until the corresponding <code>Release</code> call is issued (which implies that, if the data wasn't copied, the array object will be pinned down and can't be relocated as part of compacting the heap). -<strong>You must Release every array you Get.</strong> Also, if the Get -call fails, you must ensure that your code doesn't try to Release a NULL +<strong>You must <code>Release</code> every array you <code>Get</code>.</strong> Also, if the <code>Get</code> +call fails, you must ensure that your code doesn't try to <code>Release</code> a NULL pointer later.</p> <p>You can determine whether or not the data was copied by passing in a @@ -298,12 +288,12 @@ then discard the changes. If you know that JNI is making a new copy for you, there's no need to create another "editable" copy. If JNI is passing you the original, then you do need to make your own copy.</p> -<p>Some have asserted that you can skip the <code>Release</code> call if +<p>It is a common mistake (repeated in example code) to assume that you can skip the <code>Release</code> call if <code>*isCopy</code> is false. This is not the case. If no copy buffer was allocated, then the original memory must be pinned down and can't be moved by the garbage collector.</p> -<p>Also note that the <code>JNI_COMMIT</code> flag does NOT release the array, +<p>Also note that the <code>JNI_COMMIT</code> flag does <strong>not</strong> release the array, and you will need to call <code>Release</code> again with a different flag eventually.</p> @@ -315,8 +305,7 @@ eventually.</p> and <code>GetStringChars</code> that may be very helpful when all you want to do is copy data in or out. Consider the following:</p> -<pre> - jbyte* data = env->GetByteArrayElements(array, NULL); +<pre> jbyte* data = env->GetByteArrayElements(array, NULL); if (data != NULL) { memcpy(buffer, data, len); env->ReleaseByteArrayElements(array, data, JNI_ABORT); @@ -325,12 +314,11 @@ to do is copy data in or out. Consider the following:</p> <p>This grabs the array, copies the first <code>len</code> byte elements out of it, and then releases the array. Depending upon the VM policies the <code>Get</code> call will either pin or copy the array contents. -We copy the data (for perhaps a second time), then call Release; in this case -we use <code>JNI_ABORT</code> so there's no chance of a third copy.</p> +The code copies the data (for perhaps a second time), then calls <code>Release</code>; in this case +<code>JNI_ABORT</code> ensures there's no chance of a third copy.</p> -<p>We can accomplish the same thing with this:</p> -<pre> - env->GetByteArrayRegion(array, 0, len, buffer);</pre> +<p>One can accomplish the same thing more simply:</p> +<pre> env->GetByteArrayRegion(array, 0, len, buffer);</pre> <p>This has several advantages:</p> <ul> @@ -349,29 +337,29 @@ to copy data into an array, and <code>GetStringRegion</code> or <a name="exceptions" id="exceptions"></a> <h2>Exception</h2> -<p><strong>You may not call most JNI functions while an exception is pending.</strong> +<p><strong>You must not call most JNI functions while an exception is pending.</strong> Your code is expected to notice the exception (via the function's return value, -<code>ExceptionCheck()</code>, or <code>ExceptionOccurred()</code>) and return, +<code>ExceptionCheck</code>, or <code>ExceptionOccurred</code>) and return, or clear the exception and handle it.</p> <p>The only JNI functions that you are allowed to call while an exception is pending are:</p> <ul> - <li>DeleteGlobalRef - <li>DeleteLocalRef - <li>DeleteWeakGlobalRef - <li>ExceptionCheck - <li>ExceptionClear - <li>ExceptionDescribe - <li>ExceptionOccurred - <li>MonitorExit - <li>PopLocalFrame - <li>PushLocalFrame - <li>Release<PrimitiveType>ArrayElements - <li>ReleasePrimitiveArrayCritical - <li>ReleaseStringChars - <li>ReleaseStringCritical - <li>ReleaseStringUTFChars + <li><code>DeleteGlobalRef</code> + <li><code>DeleteLocalRef</code> + <li><code>DeleteWeakGlobalRef</code> + <li><code>ExceptionCheck</code> + <li><code>ExceptionClear</code> + <li><code>ExceptionDescribe</code> + <li><code>ExceptionOccurred</code> + <li><code>MonitorExit</code> + <li><code>PopLocalFrame</code> + <li><code>PushLocalFrame</code> + <li><code>Release<PrimitiveType>ArrayElements</code> + <li><code>ReleasePrimitiveArrayCritical</code> + <li><code>ReleaseStringChars</code> + <li><code>ReleaseStringCritical</code> + <li><code>ReleaseStringUTFChars</code> </ul> <p>Many JNI calls can throw an exception, but often provide a simpler way @@ -392,86 +380,80 @@ native code, the exception will be noted and handled appropriately.</p> <code>ExceptionClear</code>. As usual, discarding exceptions without handling them can lead to problems.</p> -<p>There are no built-in functions for manipulating the Throwable object +<p>There are no built-in functions for manipulating the <code>Throwable</code> object itself, so if you want to (say) get the exception string you will need to -find the Throwable class, look up the method ID for +find the <code>Throwable</code> class, look up the method ID for <code>getMessage "()Ljava/lang/String;"</code>, invoke it, and if the result is non-NULL use <code>GetStringUTFChars</code> to get something you can -hand to printf or a LOG macro.</p> +hand to <code>printf(3)</code> or equivalent.</p> <a name="extended_checking" id="extended_checking"></a> <h2>Extended Checking</h2> -<p>JNI does very little error checking. Calling <code>SetIntField</code> -on an Object field will succeed, even if the field is marked -<code>private</code> and <code>final</code>. The -goal is to minimize the overhead on the assumption that, if you've written it in native code, -you probably did it for performance reasons.</p> - -<p>In Dalvik, you can enable additional checks by setting the -"<code>-Xcheck:jni</code>" flag. If the flag is set, the VM directs -the JavaVM and JNIEnv pointers to a different table of functions. -These functions perform an extended series of checks before calling the -standard implementation.</p> +<p>JNI does very little error checking. Errors usually result in a crash. Android also offers a mode called CheckJNI, where the JavaVM and JNIEnv function table pointers are switched to tables of functions that perform an extended series of checks before calling the standard implementation.</p> -<p>The additional tests include:</p> +<p>The additional checks include:</p> <ul> -<li> Check for null pointers where not allowed.</li> -<li> Verify argument type correctness (jclass is a class object, -jfieldID points to field data, jstring is a java.lang.String).</li> -<li> Field type correctness, e.g. don't store a HashMap in a String field.</li> -<li> Ensure jmethodID is appropriate when making a static or virtual -method call.</li> -<li> Check to see if an exception is pending on calls where pending exceptions are not legal.</li> -<li> Check for calls to inappropriate functions between Critical get/release calls.</li> -<li> Check that JNIEnv structs aren't being shared between threads.</li> -<li> Make sure local references aren't used outside their allowed lifespan.</li> -<li> UTF-8 strings contain only valid <a href="http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8">Modified UTF-8</a> data.</li> +<li>Arrays: attempting to allocate a negative-sized array.</li> +<li>Bad pointers: passing a bad jarray/jclass/jobject/jstring to a JNI call, or passing a NULL pointer to a JNI call with a non-nullable argument.</li> +<li>Class names: passing anything but the “java/lang/String” style of class name to a JNI call.</li> +<li>Critical calls: making a JNI call between a “critical” get and its corresponding release.</li> +<li>Direct ByteBuffers: passing bad arguments to <code>NewDirectByteBuffer</code>.</li> +<li>Exceptions: making a JNI call while there’s an exception pending.</li> +<li>JNIEnv*s: using a JNIEnv* from the wrong thread.</li> +<li>jfieldIDs: using a NULL jfieldID, or using a jfieldID to set a field to a value of the wrong type (trying to assign a StringBuilder to a String field, say), or using a jfieldID for a static field to set an instance field or vice versa, or using a jfieldID from one class with instances of another class.</li> +<li>jmethodIDs: using the wrong kind of jmethodID when making a <code>Call*Method</code> JNI call: incorrect return type, static/non-static mismatch, wrong type for ‘this’ (for non-static calls) or wrong class (for static calls).</li> +<li>References: using <code>DeleteGlobalRef</code>/<code>DeleteLocalRef</code> on the wrong kind of reference.</li> +<li>Release modes: passing a bad release mode to a release call (something other than <code>0</code>, <code>JNI_ABORT</code>, or <code>JNI_COMMIT</code>).</li> +<li>Type safety: returning an incompatible type from your native method (returning a StringBuilder from a method declared to return a String, say).</li> +<li>UTF-8: passing an invalid <a href="http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8">Modified UTF-8</a> byte sequence to a JNI call.</li> </ul> -<p>Accessibility of methods and fields (i.e. public vs. private) is not -checked.</p> +<p>(Accessibility of methods and fields is still not checked: access restrictions don't apply to native code.)</p> + +<p>There are several ways to enable CheckJNI.</p> + +<p>If you’re using the emulator, CheckJNI is on by default.</p> + +<p>If you have a rooted device, you can use the following sequence of commands to restart the runtime with CheckJNI enabled:</p> + +<pre>adb shell stop +adb shell setprop dalvik.vm.checkjni true +adb shell start</pre> + +<p>In either of these cases, you’ll see something like this in your logcat output when the runtime starts:</p> + +<pre>D AndroidRuntime: CheckJNI is ON</pre> + +<p>If you have a regular device, you can use the following command:</p> + +<pre>adb shell setprop debug.checkjni 1</pre> + +<p>This won’t affect already-running apps, but any app launched from that point on will have CheckJNI enabled. (Change the property to any other value or simply rebooting will disable CheckJNI again.) In this case, you’ll see something like this in your logcat output the next time an app starts:</p> -<p>For a description of how to enable CheckJNI for Android apps, see -<a href="embedded-vm-control.html">Controlling the Embedded VM</a>. -It's currently enabled by default in the Android emulator and on -"engineering" device builds.</p> +<pre>D Late-enabling CheckJNI</pre> -<p>JNI checks can be modified with the <code>-Xjniopts</code> command-line -flag. Currently supported values include:</p> -<dl> -<dt>forcecopy -<dd>When set, any function that can return a copy of the original data -(array of primitive values, UTF-16 chars) will always do so. The buffers -are over-allocated and surrounded with a guard pattern to help identify -code writing outside the buffer, and the contents are erased before the -storage is freed to trip up code that uses the data after calling Release. -This will have a noticeable performance impact on some applications. -<dt>warnonly -<dd>By default, JNI "warnings" cause the VM to abort. With this flag -it continues on. -</dl> <a name="native_libraries" id="native_libraries"></a> <h2>Native Libraries</h2> <p>You can load native code from shared libraries with the standard -<code>System.loadLibrary()</code> call. The +<code>System.loadLibrary</code> call. The preferred way to get at your native code is:</p> <ul> -<li> Call <code>System.loadLibrary()</code> from a static class +<li> Call <code>System.loadLibrary</code> from a static class initializer. (See the earlier example, where one is used to call -<code>nativeClassInit()</code>.) The argument is the "undecorated" -library name, e.g. to load "libfubar.so" you would pass in "fubar".</li> +<code>nativeClassInit</code>.) The argument is the "undecorated" +library name, so to load "libfubar.so" you would pass in "fubar".</li> <li> Provide a native function: <code><strong>jint JNI_OnLoad(JavaVM* vm, void* reserved)</strong></code></li> <li>In <code>JNI_OnLoad</code>, register all of your native methods. You should declare -the functions <code>static</code> so the names don't take up space in the symbol table +the methods "static" so the names don't take up space in the symbol table on the device.</li> </ul> @@ -490,7 +472,7 @@ written in C++:</p> return JNI_VERSION_1_6; }</pre> -<p>You can also call <code>System.load()</code> with the full path name of the +<p>You can also call <code>System.load</code> with the full path name of the shared library. For Android apps, you may find it useful to get the full path to the application's private data storage area from the context object.</p> @@ -549,28 +531,28 @@ that use 64-bit pointers, <strong>you need to stash your native pointers in a <p>For backward compatibility, you may need to be aware of:</p> <ul> - <li>Until Android 2.0 ("Eclair"), the '$' character was not properly + <li>Until Android 2.0 (Eclair), the '$' character was not properly converted to "_00024" during searches for method names. Working around this requires using explicit registration or moving the native methods out of inner classes. - <li>Until Android 2.0 ("Eclair"), it was not possible to use a <code>pthread_key_create</code> + <li>Until Android 2.0 (Eclair), it was not possible to use a <code>pthread_key_create</code> destructor function to avoid the VM's "thread must be detached before exit" check. (The VM also uses a pthread key destructor function, so it'd be a race to see which gets called first.) - <li>"Weak global" references were not implemented until Android 2.2 ("Froyo"). + <li>Until Android 2.2 (Froyo), weak global references were not implemented. Older VMs will vigorously reject attempts to use them. You can use the Android platform version constants to test for support. </ul> <a name="faq_ULE" id="faq_ULE"></a> -<h2>FAQ: UnsatisfiedLinkError</h2> +<h2>FAQ: Why do I get <code>UnsatisfiedLinkError</code>?</h2> <p>When working on native code it's not uncommon to see a failure like this:</p> <pre>java.lang.UnsatisfiedLinkError: Library foo not found</pre> <p>In some cases it means what it says — the library wasn't found. In -other cases the library exists but couldn't be opened by dlopen(), and +other cases the library exists but couldn't be opened by <code>dlopen(3)</code>, and the details of the failure can be found in the exception's detail message.</p> <p>Common reasons why you might encounter "library not found" exceptions:</p> @@ -601,7 +583,7 @@ Some common reasons for this are:</p> <li>For lazy method lookup, failing to declare C++ functions with <code>extern "C"</code>. You can use <code>arm-eabi-nm</code> to see the symbols as they appear in the library; if they look - mangled (e.g. <code>_Z15Java_Foo_myfuncP7_JNIEnvP7_jclass</code> + mangled (something like <code>_Z15Java_Foo_myfuncP7_JNIEnvP7_jclass</code> rather than <code>Java_Foo_myfunc</code>) then you need to adjust the declaration. <li>For explicit registration, minor errors when entering the @@ -610,8 +592,7 @@ Some common reasons for this are:</p> Remember that 'B' is <code>byte</code> and 'Z' is <code>boolean</code>. Class name components in signatures start with 'L', end with ';', use '/' to separate package/class names, and use '$' to separate - inner-class names - (e.g. <code>Ljava/util/Map$Entry;</code>). + inner-class names (<code>Ljava/util/Map$Entry;</code>, say). </ul> </ul> @@ -620,11 +601,11 @@ avoid some problems. <a name="faq_FindClass" id="faq_FindClass"></a> -<h2>FAQ: FindClass didn't find my class</h2> +<h2>FAQ: Why didn't <code>FindClass</code> find my class?</h2> <p>Make sure that the class name string has the correct format. JNI class names start with the package name and are separated with slashes, -e.g. <code>java/lang/String</code>. If you're looking up an array class, +such as <code>java/lang/String</code>. If you're looking up an array class, you need to start with the appropriate number of square brackets and must also wrap the class with 'L' and ';', so a one-dimensional array of <code>String</code> would be <code>[Ljava/lang/String;</code>.</p> @@ -663,8 +644,8 @@ with your application, so attempts to find app-specific classes will fail.</p> If your app code is loading the library, <code>FindClass</code> will use the correct class loader. <li>Pass an instance of the class into the functions that need - it, e.g. declare your native method to take a Class argument and - then pass <code>Foo.class</code> in. + it, by declaring your native method to take a Class argument and + then passing <code>Foo.class</code> in. <li>Cache a reference to the <code>ClassLoader</code> object somewhere handy, and issue <code>loadClass</code> calls directly. This requires some effort. @@ -672,7 +653,7 @@ with your application, so attempts to find app-specific classes will fail.</p> <a name="faq_sharing" id="faq_sharing"></a> -<h2>FAQ: Sharing raw data with native code</h2> +<h2>FAQ: How do I share raw data with native code?</h2> <p>You may find yourself in a situation where you need to access a large buffer of raw data from code written in Java and C/C++. Common examples diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 6ae8c9b..eefd21e 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -508,17 +508,6 @@ public class Canvas { } /** - * Returns a pointer to an internal 4x4 native matrix. The returned - * pointer is a pointer to an array of 16 floats. - * - * @hide - */ - @SuppressWarnings({"UnusedDeclaration"}) - public int getNativeMatrix() { - return 0; - } - - /** * Return a new matrix with a copy of the canvas' current transformation * matrix. */ diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index eb22e32..e0d7898 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -183,6 +183,7 @@ public: int session, int id); static status_t unregisterEffect(int id); + static status_t setEffectEnabled(int id, bool enabled); static const sp<IAudioPolicyService>& get_audio_policy_service(); diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h index ed265e1..9807cbe 100644 --- a/include/media/IAudioPolicyService.h +++ b/include/media/IAudioPolicyService.h @@ -84,6 +84,7 @@ public: int session, int id) = 0; virtual status_t unregisterEffect(int id) = 0; + virtual status_t setEffectEnabled(int id, bool enabled) = 0; virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0; virtual status_t queryDefaultPreProcessing(int audioSession, effect_descriptor_t *descriptors, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index ed2fa3c..4864cff 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -924,13 +924,6 @@ void OpenGLRenderer::setMatrix(SkMatrix* matrix) { mSnapshot->transform->load(*matrix); } -const float* OpenGLRenderer::getMatrix() const { - if (mSnapshot->fbo != 0) { - return &mSnapshot->transform->data[0]; - } - return &mIdentity.data[0]; -} - void OpenGLRenderer::getMatrix(SkMatrix* matrix) { mSnapshot->transform->copyTo(*matrix); } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index fa893f0..14b22b3 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -87,7 +87,6 @@ public: virtual void scale(float sx, float sy); virtual void skew(float sx, float sy); - const float* getMatrix() const; void getMatrix(SkMatrix* matrix); virtual void setMatrix(SkMatrix* matrix); virtual void concatMatrix(SkMatrix* matrix); diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 1ba4c4f..2d1761f 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -327,6 +327,8 @@ public class MediaScanner // used when scanning the image database so we know whether we have to prune // old thumbnail files private int mOriginalCount; + /** Whether the database had any entries in it before the scan started */ + private boolean mWasEmptyPriorToScan = false; /** Whether the scanner has set a default sound for the ringer ringtone. */ private boolean mDefaultRingtoneSet; /** Whether the scanner has set a default sound for the notification ringtone. */ @@ -547,6 +549,7 @@ public class MediaScanner return entry; } + @Override public void scanFile(String path, long lastModified, long fileSize, boolean isDirectory, boolean noMedia) { // This is the callback funtion from native codes. @@ -901,19 +904,19 @@ public class MediaScanner mMediaProvider.update(result, values, null, null); } - if (notifications && !mDefaultNotificationSet) { + if (notifications && mWasEmptyPriorToScan && !mDefaultNotificationSet) { if (TextUtils.isEmpty(mDefaultNotificationFilename) || doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) { setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, tableUri, rowId); mDefaultNotificationSet = true; } - } else if (ringtones && !mDefaultRingtoneSet) { + } else if (ringtones && mWasEmptyPriorToScan && !mDefaultRingtoneSet) { if (TextUtils.isEmpty(mDefaultRingtoneFilename) || doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) { setSettingIfNotSet(Settings.System.RINGTONE, tableUri, rowId); mDefaultRingtoneSet = true; } - } else if (alarms && !mDefaultAlarmSet) { + } else if (alarms && mWasEmptyPriorToScan && !mDefaultAlarmSet) { if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) || doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) { setSettingIfNotSet(Settings.System.ALARM_ALERT, tableUri, rowId); @@ -997,6 +1000,7 @@ public class MediaScanner where, selectionArgs, null); if (c != null) { + mWasEmptyPriorToScan = c.getCount() == 0; while (c.moveToNext()) { long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); String path = c.getString(FILES_PRESCAN_PATH_COLUMN_INDEX); diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index b26ed71..bb91fa9 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -710,6 +710,13 @@ status_t AudioSystem::unregisterEffect(int id) return aps->unregisterEffect(id); } +status_t AudioSystem::setEffectEnabled(int id, bool enabled) +{ + const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); + if (aps == 0) return PERMISSION_DENIED; + return aps->setEffectEnabled(id, enabled); +} + status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) { const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service(); diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 15f4be0..50b4855 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -53,7 +53,8 @@ enum { UNREGISTER_EFFECT, IS_STREAM_ACTIVE, GET_DEVICES_FOR_STREAM, - QUERY_DEFAULT_PRE_PROCESSING + QUERY_DEFAULT_PRE_PROCESSING, + SET_EFFECT_ENABLED }; class BpAudioPolicyService : public BpInterface<IAudioPolicyService> @@ -313,6 +314,16 @@ public: return static_cast <status_t> (reply.readInt32()); } + virtual status_t setEffectEnabled(int id, bool enabled) + { + Parcel data, reply; + data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); + data.writeInt32(id); + data.writeInt32(enabled); + remote()->transact(SET_EFFECT_ENABLED, data, &reply); + return static_cast <status_t> (reply.readInt32()); + } + virtual bool isStreamActive(int stream, uint32_t inPastMs) const { Parcel data, reply; @@ -577,6 +588,14 @@ status_t BnAudioPolicyService::onTransact( return NO_ERROR; } break; + case SET_EFFECT_ENABLED: { + CHECK_INTERFACE(IAudioPolicyService, data, reply); + int id = data.readInt32(); + bool enabled = static_cast <bool>(data.readInt32()); + reply->writeInt32(static_cast <int32_t>(setEffectEnabled(id, enabled))); + return NO_ERROR; + } break; + case IS_STREAM_ACTIVE: { CHECK_INTERFACE(IAudioPolicyService, data, reply); int stream = data.readInt32(); diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index eae6112..8c57595 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -20,6 +20,7 @@ import com.android.internal.app.IMediaContainerService; import com.android.internal.content.NativeLibraryHelper; import com.android.internal.content.PackageHelper; +import android.app.IntentService; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; @@ -30,25 +31,24 @@ import android.content.res.ObbInfo; import android.content.res.ObbScanner; import android.net.Uri; import android.os.Environment; +import android.os.FileUtils; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StatFs; -import android.app.IntentService; +import android.provider.Settings; import android.util.DisplayMetrics; import android.util.Slog; +import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; - -import android.os.FileUtils; -import android.provider.Settings; +import java.io.OutputStream; /* * This service copies a downloaded apk to a file passed in as @@ -88,19 +88,32 @@ public class DefaultContainerService extends IntentService { /* * Copy specified resource to output stream - * @param packageURI the uri of resource to be copied. Should be a - * file uri + * @param packageURI the uri of resource to be copied. Should be a file + * uri * @param outStream Remote file descriptor to be used for copying - * @return Returns true if copy succeded or false otherwise. + * @return returns status code according to those in {@link + * PackageManager} */ - public boolean copyResource(final Uri packageURI, - ParcelFileDescriptor outStream) { - if (packageURI == null || outStream == null) { - return false; + public int copyResource(final Uri packageURI, ParcelFileDescriptor outStream) { + if (packageURI == null || outStream == null) { + return PackageManager.INSTALL_FAILED_INVALID_URI; + } + + ParcelFileDescriptor.AutoCloseOutputStream autoOut + = new ParcelFileDescriptor.AutoCloseOutputStream(outStream); + + try { + copyFile(packageURI, autoOut); + return PackageManager.INSTALL_SUCCEEDED; + } catch (FileNotFoundException e) { + Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " FNF: " + + e.getMessage()); + return PackageManager.INSTALL_FAILED_INVALID_URI; + } catch (IOException e) { + Slog.e(TAG, "Could not copy URI " + packageURI.toString() + " IO: " + + e.getMessage()); + return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; } - ParcelFileDescriptor.AutoCloseOutputStream - autoOut = new ParcelFileDescriptor.AutoCloseOutputStream(outStream); - return copyFile(packageURI, autoOut); } /* @@ -315,76 +328,63 @@ public class DefaultContainerService extends IntentService { return newCachePath; } - private static boolean copyToFile(InputStream inputStream, FileOutputStream out) { - try { - byte[] buffer = new byte[4096]; - int bytesRead; - while ((bytesRead = inputStream.read(buffer)) >= 0) { - out.write(buffer, 0, bytesRead); - } - return true; - } catch (IOException e) { - Slog.i(TAG, "Exception : " + e + " when copying file"); - return false; + private static void copyToFile(InputStream inputStream, OutputStream out) throws IOException { + byte[] buffer = new byte[16384]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) >= 0) { + out.write(buffer, 0, bytesRead); } } - private static boolean copyToFile(File srcFile, FileOutputStream out) { - InputStream inputStream = null; + private static void copyToFile(File srcFile, OutputStream out) + throws FileNotFoundException, IOException { + InputStream inputStream = new BufferedInputStream(new FileInputStream(srcFile)); try { - inputStream = new FileInputStream(srcFile); - return copyToFile(inputStream, out); - } catch (IOException e) { - return false; + copyToFile(inputStream, out); } finally { - try { if (inputStream != null) inputStream.close(); } catch (IOException e) {} + try { inputStream.close(); } catch (IOException e) {} } } - private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) { + private void copyFile(Uri pPackageURI, OutputStream outStream) throws FileNotFoundException, + IOException { String scheme = pPackageURI.getScheme(); if (scheme == null || scheme.equals("file")) { final File srcPackageFile = new File(pPackageURI.getPath()); // We copy the source package file to a temp file and then rename it to the // destination file in order to eliminate a window where the package directory // scanner notices the new package file but it's not completely copied yet. - if (!copyToFile(srcPackageFile, outStream)) { - Slog.e(TAG, "Couldn't copy file: " + srcPackageFile); - return false; - } + copyToFile(srcPackageFile, outStream); } else if (scheme.equals("content")) { ParcelFileDescriptor fd = null; try { fd = getContentResolver().openFileDescriptor(pPackageURI, "r"); } catch (FileNotFoundException e) { - Slog.e(TAG, - "Couldn't open file descriptor from download service. Failed with exception " - + e); - return false; + Slog.e(TAG, "Couldn't open file descriptor from download service. " + + "Failed with exception " + e); + throw e; } + if (fd == null) { - Slog.e(TAG, "Couldn't open file descriptor from download service (null)."); - return false; + Slog.e(TAG, "Provider returned no file descriptor for " + pPackageURI.toString()); + throw new FileNotFoundException("provider returned no file descriptor"); } else { if (localLOGV) { Slog.i(TAG, "Opened file descriptor from download service."); } - ParcelFileDescriptor.AutoCloseInputStream - dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd); + ParcelFileDescriptor.AutoCloseInputStream dlStream + = new ParcelFileDescriptor.AutoCloseInputStream(fd); + // We copy the source package file to a temp file and then rename it to the // destination file in order to eliminate a window where the package directory // scanner notices the new package file but it's not completely - // cop - if (!copyToFile(dlStream, outStream)) { - Slog.e(TAG, "Couldn't copy " + pPackageURI + " to temp file."); - return false; - } + // copied + copyToFile(dlStream, outStream); } } else { Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI); - return false; + throw new FileNotFoundException("Package URI is not 'file:' or 'content:'"); } - return true; } private static final int PREFER_INTERNAL = 1; diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml index 17fa653..c735dbd 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_area.xml @@ -24,6 +24,8 @@ android:layout_height="match_parent" android:layout_alignParentRight="true" android:orientation="horizontal" + android:background="?android:attr/listChoiceBackgroundIndicator" + android:clickable="true" > <LinearLayout @@ -65,14 +67,7 @@ android:layout_height="match_parent" android:layout_gravity="center_vertical" android:layout_marginLeft="8dp" - /> - <View - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alignLeft="@id/icons" - android:layout_alignRight="@id/icons" - android:background="@drawable/notification_icon_area_smoke" - android:clickable="false" + android:alpha="0.4" /> </com.android.systemui.statusbar.tablet.NotificationIconArea> </LinearLayout> @@ -88,7 +83,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="3dip" - android:layout_marginLeft="4dip" + android:layout_marginLeft="8dip" android:layout_marginRight="4dip" > <TextView android:id="@+id/time_solid" 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 7f56d45..e90aad4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -103,6 +103,11 @@ public class TabletStatusBar extends StatusBar implements // Fitts' Law assistance for LatinIME; see policy.EventHole private static final boolean FAKE_SPACE_BAR = true; + // Notification "peeking" (flyover preview of individual notifications) + final static boolean NOTIFICATION_PEEK_ENABLED = false; + final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms + final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms + // The height of the bar, as definied by the build. It may be taller if we're plugged // into hdmi. int mNaturalBarHeight = -1; @@ -250,43 +255,45 @@ public class TabletStatusBar extends StatusBar implements WindowManagerImpl.getDefault().addView(mNotificationPanel, lp); // Notification preview window - mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context, - R.layout.status_bar_notification_peek, null); - mNotificationPeekWindow.setBar(this); - - mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content); - mNotificationPeekWindow.setVisibility(View.GONE); - mNotificationPeekWindow.setOnTouchListener( - new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow)); - mNotificationPeekScrubRight = new LayoutTransition(); - mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING, - ObjectAnimator.ofInt(null, "left", -512, 0)); - mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING, - ObjectAnimator.ofInt(null, "left", -512, 0)); - mNotificationPeekScrubRight.setDuration(500); - - mNotificationPeekScrubLeft = new LayoutTransition(); - mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING, - ObjectAnimator.ofInt(null, "left", 512, 0)); - mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING, - ObjectAnimator.ofInt(null, "left", 512, 0)); - mNotificationPeekScrubLeft.setDuration(500); - - // XXX: setIgnoreChildren? - lp = new WindowManager.LayoutParams( - 512, // ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM - | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - lp.gravity = Gravity.BOTTOM | Gravity.RIGHT; - lp.y = res.getDimensionPixelOffset(R.dimen.peek_window_y_offset); - lp.setTitle("NotificationPeekWindow"); - lp.windowAnimations = com.android.internal.R.style.Animation_Toast; - - WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp); + if (NOTIFICATION_PEEK_ENABLED) { + mNotificationPeekWindow = (NotificationPeekPanel) View.inflate(context, + R.layout.status_bar_notification_peek, null); + mNotificationPeekWindow.setBar(this); + + mNotificationPeekRow = (ViewGroup) mNotificationPeekWindow.findViewById(R.id.content); + mNotificationPeekWindow.setVisibility(View.GONE); + mNotificationPeekWindow.setOnTouchListener( + new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PEEK, mNotificationPeekWindow)); + mNotificationPeekScrubRight = new LayoutTransition(); + mNotificationPeekScrubRight.setAnimator(LayoutTransition.APPEARING, + ObjectAnimator.ofInt(null, "left", -512, 0)); + mNotificationPeekScrubRight.setAnimator(LayoutTransition.DISAPPEARING, + ObjectAnimator.ofInt(null, "left", -512, 0)); + mNotificationPeekScrubRight.setDuration(500); + + mNotificationPeekScrubLeft = new LayoutTransition(); + mNotificationPeekScrubLeft.setAnimator(LayoutTransition.APPEARING, + ObjectAnimator.ofInt(null, "left", 512, 0)); + mNotificationPeekScrubLeft.setAnimator(LayoutTransition.DISAPPEARING, + ObjectAnimator.ofInt(null, "left", 512, 0)); + mNotificationPeekScrubLeft.setDuration(500); + + // XXX: setIgnoreChildren? + lp = new WindowManager.LayoutParams( + 512, // ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM + | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSLUCENT); + lp.gravity = Gravity.BOTTOM | Gravity.RIGHT; + lp.y = res.getDimensionPixelOffset(R.dimen.peek_window_y_offset); + lp.setTitle("NotificationPeekWindow"); + lp.windowAnimations = com.android.internal.R.style.Animation_Toast; + + WindowManagerImpl.getDefault().addView(mNotificationPeekWindow, lp); + } // Recents Panel mRecentsPanel = (RecentsPanelView) View.inflate(context, @@ -444,17 +451,24 @@ public class TabletStatusBar extends StatusBar implements // the whole right-hand side of the bar mNotificationArea = sb.findViewById(R.id.notificationArea); + if (!NOTIFICATION_PEEK_ENABLED) { + mNotificationArea.setOnTouchListener(new NotificationTriggerTouchListener()); + } // the button to open the notification area mNotificationTrigger = sb.findViewById(R.id.notificationTrigger); - mNotificationTrigger.setOnTouchListener(new NotificationTriggerTouchListener()); + if (NOTIFICATION_PEEK_ENABLED) { + mNotificationTrigger.setOnTouchListener(new NotificationTriggerTouchListener()); + } // the more notifications icon mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons); // where the icons go mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons); - mIconLayout.setOnTouchListener(new NotificationIconTouchListener()); + if (NOTIFICATION_PEEK_ENABLED) { + mIconLayout.setOnTouchListener(new NotificationIconTouchListener()); + } ViewConfiguration vc = ViewConfiguration.get(context); mNotificationPeekTapDuration = vc.getTapTimeout(); @@ -684,7 +698,9 @@ public class TabletStatusBar extends StatusBar implements case MSG_OPEN_NOTIFICATION_PANEL: if (DEBUG) Slog.d(TAG, "opening notifications panel"); if (!mNotificationPanel.isShowing()) { - mNotificationPeekWindow.setVisibility(View.GONE); + if (NOTIFICATION_PEEK_ENABLED) { + mNotificationPeekWindow.setVisibility(View.GONE); + } mNotificationPanel.show(true, true); mNotificationArea.setVisibility(View.INVISIBLE); mTicker.halt(); @@ -863,7 +879,7 @@ public class TabletStatusBar extends StatusBar implements oldEntry.largeIcon.setVisibility(View.INVISIBLE); } - if (key == mNotificationPeekKey) { + if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) { // must update the peek window Message peekMsg = mHandler.obtainMessage(MSG_OPEN_NOTIFICATION_PEEK); peekMsg.arg1 = mNotificationPeekIndex; @@ -1010,9 +1026,11 @@ public class TabletStatusBar extends StatusBar implements } public void animateExpand() { - mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); - mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK); - mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); + if (NOTIFICATION_PEEK_ENABLED) { + mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); + mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PEEK); + mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); + } mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL); mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL); } @@ -1026,8 +1044,10 @@ public class TabletStatusBar extends StatusBar implements mHandler.sendEmptyMessage(MSG_CLOSE_INPUT_METHODS_PANEL); mHandler.removeMessages(MSG_CLOSE_COMPAT_MODE_PANEL); mHandler.sendEmptyMessage(MSG_CLOSE_COMPAT_MODE_PANEL); - mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); - mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); + if (NOTIFICATION_PEEK_ENABLED) { + mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PEEK); + mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); + } } private void notifyUiVisibilityChanged() { @@ -1328,7 +1348,7 @@ public class TabletStatusBar extends StatusBar implements ViewGroup rowParent = (ViewGroup)entry.row.getParent(); if (rowParent != null) rowParent.removeView(entry.row); - if (key == mNotificationPeekKey) { + if (NOTIFICATION_PEEK_ENABLED && key == mNotificationPeekKey) { // must close the peek as well, since it's gone mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK); } @@ -1349,6 +1369,19 @@ public class TabletStatusBar extends StatusBar implements mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } + private Runnable mHiliteOnR = new Runnable() { public void run() { + mNotificationArea.setBackgroundResource( + com.android.internal.R.drawable.list_selector_pressed_holo_dark); + }}; + public void hilite(final boolean on) { + if (on) { + mNotificationArea.postDelayed(mHiliteOnR, 100); + } else { + mNotificationArea.removeCallbacks(mHiliteOnR); + mNotificationArea.setBackgroundDrawable(null); + } + } + public boolean onTouch(View v, MotionEvent event) { // Slog.d(TAG, String.format("touch: (%.1f, %.1f) initial: (%.1f, %.1f)", // event.getX(), @@ -1361,6 +1394,7 @@ public class TabletStatusBar extends StatusBar implements mVT = VelocityTracker.obtain(); mInitialTouchX = event.getX(); mInitialTouchY = event.getY(); + hilite(true); // fall through case MotionEvent.ACTION_OUTSIDE: case MotionEvent.ACTION_MOVE: @@ -1371,6 +1405,7 @@ public class TabletStatusBar extends StatusBar implements // require a little more oomph once we're already in peekaboo mode if (mVT.getYVelocity() < -mNotificationFlingVelocity) { animateExpand(); + hilite(false); mVT.recycle(); mVT = null; } @@ -1378,6 +1413,7 @@ public class TabletStatusBar extends StatusBar implements return true; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: + hilite(false); if (mVT != null) { if (action == MotionEvent.ACTION_UP // was this a sloppy tap? @@ -1399,9 +1435,6 @@ public class TabletStatusBar extends StatusBar implements } } - final static int NOTIFICATION_PEEK_HOLD_THRESH = 200; // ms - final static int NOTIFICATION_PEEK_FADE_DELAY = 3000; // ms - public void resetNotificationPeekFadeTimer() { if (DEBUG) { Slog.d(TAG, "setting peek fade timer for " + NOTIFICATION_PEEK_FADE_DELAY diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index d6bfda6..95c469d 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1232,18 +1232,6 @@ void AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectCha } } -void AudioFlinger::ThreadBase::updateSuspendedSessionsOnRemoveEffectChain_l( - const sp<EffectChain>& chain) -{ - int index = mSuspendedSessions.indexOfKey(chain->sessionId()); - if (index < 0) { - return; - } - LOGV("updateSuspendedSessionsOnRemoveEffectChain_l() removed suspended session %d", - chain->sessionId()); - mSuspendedSessions.removeItemsAt(index); -} - void AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type, bool suspend, int sessionId) @@ -1311,7 +1299,14 @@ void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule { Mutex::Autolock _l(mLock); - // TODO: implement PlaybackThread or RecordThread specific behavior here + if (mType != RECORD) { + // suspend all effects in AUDIO_SESSION_OUTPUT_MIX when enabling any effect on + // another session. This gives the priority to well behaved effect control panels + // and applications not using global effects. + if (sessionId != AUDIO_SESSION_OUTPUT_MIX) { + setEffectSuspended_l(NULL, enabled, AUDIO_SESSION_OUTPUT_MIX); + } + } sp<EffectChain> chain = getEffectChain_l(sessionId); if (chain != 0) { @@ -5847,7 +5842,6 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& for (size_t i = 0; i < mEffectChains.size(); i++) { if (chain == mEffectChains[i]) { - updateSuspendedSessionsOnRemoveEffectChain_l(chain); mEffectChains.removeAt(i); // detach all active tracks from the chain for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) { @@ -5939,7 +5933,6 @@ size_t AudioFlinger::RecordThread::removeEffectChain_l(const sp<EffectChain>& ch "removeEffectChain_l() %p invalid chain size %d on thread %p", chain.get(), mEffectChains.size(), this); if (mEffectChains.size() == 1) { - updateSuspendedSessionsOnRemoveEffectChain_l(chain); mEffectChains.removeAt(0); } return 0; @@ -6393,10 +6386,16 @@ status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, status_t AudioFlinger::EffectModule::setEnabled(bool enabled) { + Mutex::Autolock _l(mLock); LOGV("setEnabled %p enabled %d", this, enabled); if (enabled != isEnabled()) { + status_t status = AudioSystem::setEffectEnabled(mId, enabled); + if (enabled && status != NO_ERROR) { + return status; + } + switch (mState) { // going from disabled to enabled case IDLE: @@ -6704,6 +6703,10 @@ status_t AudioFlinger::EffectHandle::enable() if (!mHasControl) return INVALID_OPERATION; if (mEffect == 0) return DEAD_OBJECT; + if (mEnabled) { + return NO_ERROR; + } + mEnabled = true; sp<ThreadBase> thread = mEffect->thread().promote(); @@ -6716,7 +6719,14 @@ status_t AudioFlinger::EffectHandle::enable() return NO_ERROR; } - return mEffect->setEnabled(true); + status_t status = mEffect->setEnabled(true); + if (status != NO_ERROR) { + if (thread != 0) { + thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); + } + mEnabled = false; + } + return status; } status_t AudioFlinger::EffectHandle::disable() @@ -6725,6 +6735,9 @@ status_t AudioFlinger::EffectHandle::disable() if (!mHasControl) return INVALID_OPERATION; if (mEffect == 0) return DEAD_OBJECT; + if (!mEnabled) { + return NO_ERROR; + } mEnabled = false; if (mEffect->suspended()) { @@ -6754,9 +6767,11 @@ void AudioFlinger::EffectHandle::disconnect(bool unpiniflast) } mEffect->disconnect(this, unpiniflast); - sp<ThreadBase> thread = mEffect->thread().promote(); - if (thread != 0) { - thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); + if (mEnabled) { + sp<ThreadBase> thread = mEffect->thread().promote(); + if (thread != 0) { + thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); + } } // release sp on module => module destructor can be called now @@ -7367,15 +7382,22 @@ void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend) } } +bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc) +{ + // auxiliary effects and visualizer are never suspended on output mix + if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && + (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) || + (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) { + return false; + } + return true; +} + Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects() { Vector< sp<EffectModule> > effects; for (size_t i = 0; i < mEffects.size(); i++) { - effect_descriptor_t desc = mEffects[i]->desc(); - // auxiliary effects and vizualizer are never suspended on output mix - if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && ( - ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) || - (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) { + if (!isEffectEligibleForSuspend(mEffects[i]->desc())) { continue; } effects.add(mEffects[i]); @@ -7405,8 +7427,15 @@ void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModul if (index < 0) { return; } + if (!isEffectEligibleForSuspend(effect->desc())) { + return; + } setEffectSuspended_l(&effect->desc().type, enabled); index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow); + if (index < 0) { + LOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!"); + return; + } } LOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x", effect->desc().type.timeLow); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 3a0aac9..1141f6c 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -522,8 +522,6 @@ private: int sessionId); // check if some effects must be suspended when an effect chain is added void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain); - // updated mSuspendedSessions when an effect chain is removed - void updateSuspendedSessionsOnRemoveEffectChain_l(const sp<EffectChain>& chain); friend class AudioFlinger; friend class Track; @@ -1320,6 +1318,10 @@ private: Vector< sp<EffectModule> > getSuspendEligibleEffects(); // get an effect module if it is currently enable sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type); + // true if the effect whose descriptor is passed can be suspended + // OEMs can modify the rules implemented in this method to exclude specific effect + // types or implementations from the suspend/restore mechanism. + bool isEffectEligibleForSuspend(const effect_descriptor_t& desc); wp<ThreadBase> mThread; // parent mixer thread Mutex mLock; // mutex protecting effect list diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 6d06d83..d747b5ad 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -488,6 +488,14 @@ status_t AudioPolicyService::unregisterEffect(int id) return mpAudioPolicy->unregister_effect(mpAudioPolicy, id); } +status_t AudioPolicyService::setEffectEnabled(int id, bool enabled) +{ + if (mpAudioPolicy == NULL) { + return NO_INIT; + } + return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled); +} + bool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const { if (mpAudioPolicy == NULL) { diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h index 834b794..d898a53 100644 --- a/services/audioflinger/AudioPolicyService.h +++ b/services/audioflinger/AudioPolicyService.h @@ -102,6 +102,7 @@ public: int session, int id); virtual status_t unregisterEffect(int id); + virtual status_t setEffectEnabled(int id, bool enabled); virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const; virtual status_t queryDefaultPreProcessing(int audioSession, diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 2eacbeb..2035a4b 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -1335,7 +1335,7 @@ void MultiTouchMotionAccumulator::configure(size_t slotCount, bool usingSlotsPro void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) { for (size_t i = 0; i < mSlotCount; i++) { - mSlots[i].clearIfInUse(); + mSlots[i].clear(); } mCurrentSlot = initialSlot; } @@ -1396,7 +1396,9 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) { break; case ABS_MT_TRACKING_ID: if (mUsingSlotsProtocol && rawEvent->value < 0) { - slot->clearIfInUse(); + // The slot is no longer in use but it retains its previous contents, + // which may be reused for subsequent touches. + slot->mInUse = false; } else { slot->mInUse = true; slot->mAbsMTTrackingId = rawEvent->value; @@ -1430,12 +1432,6 @@ MultiTouchMotionAccumulator::Slot::Slot() { clear(); } -void MultiTouchMotionAccumulator::Slot::clearIfInUse() { - if (mInUse) { - clear(); - } -} - void MultiTouchMotionAccumulator::Slot::clear() { mInUse = false; mHaveAbsMTTouchMinor = false; @@ -2217,10 +2213,6 @@ void TouchInputMapper::dump(String8& dump) { dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision); dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision); dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale); - dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mToolSizeLinearScale); - dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mToolSizeLinearBias); - dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mToolSizeAreaScale); - dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mToolSizeAreaBias); dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale); dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale); dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale); @@ -2541,9 +2533,21 @@ bool TouchInputMapper::configureSurface() { // Size of diagonal axis. float diagonalSize = hypotf(width, height); - // TouchMajor and TouchMinor factors. - if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) { + // Size factors. + if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { + if (mRawPointerAxes.touchMajor.valid + && mRawPointerAxes.touchMajor.maxValue != 0) { + mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue; + } else if (mRawPointerAxes.toolMajor.valid + && mRawPointerAxes.toolMajor.maxValue != 0) { + mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue; + } else { + mSizeScale = 0.0f; + } + mOrientedRanges.haveTouchSize = true; + mOrientedRanges.haveToolSize = true; + mOrientedRanges.haveSize = true; mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR; mOrientedRanges.touchMajor.source = mTouchSource; @@ -2554,51 +2558,6 @@ bool TouchInputMapper::configureSurface() { mOrientedRanges.touchMinor = mOrientedRanges.touchMajor; mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR; - } - - // ToolMajor and ToolMinor factors. - mToolSizeLinearScale = 0; - mToolSizeLinearBias = 0; - mToolSizeAreaScale = 0; - mToolSizeAreaBias = 0; - if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { - if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) { - if (mCalibration.haveToolSizeLinearScale) { - mToolSizeLinearScale = mCalibration.toolSizeLinearScale; - } else if (mRawPointerAxes.toolMajor.valid - && mRawPointerAxes.toolMajor.maxValue != 0) { - mToolSizeLinearScale = float(min(width, height)) - / mRawPointerAxes.toolMajor.maxValue; - } - - if (mCalibration.haveToolSizeLinearBias) { - mToolSizeLinearBias = mCalibration.toolSizeLinearBias; - } - } else if (mCalibration.toolSizeCalibration == - Calibration::TOOL_SIZE_CALIBRATION_AREA) { - if (mCalibration.haveToolSizeLinearScale) { - mToolSizeLinearScale = mCalibration.toolSizeLinearScale; - } else { - mToolSizeLinearScale = min(width, height); - } - - if (mCalibration.haveToolSizeLinearBias) { - mToolSizeLinearBias = mCalibration.toolSizeLinearBias; - } - - if (mCalibration.haveToolSizeAreaScale) { - mToolSizeAreaScale = mCalibration.toolSizeAreaScale; - } else if (mRawPointerAxes.toolMajor.valid - && mRawPointerAxes.toolMajor.maxValue != 0) { - mToolSizeAreaScale = 1.0f / mRawPointerAxes.toolMajor.maxValue; - } - - if (mCalibration.haveToolSizeAreaBias) { - mToolSizeAreaBias = mCalibration.toolSizeAreaBias; - } - } - - mOrientedRanges.haveToolSize = true; mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR; mOrientedRanges.toolMajor.source = mTouchSource; @@ -2609,30 +2568,28 @@ bool TouchInputMapper::configureSurface() { mOrientedRanges.toolMinor = mOrientedRanges.toolMajor; mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR; + + mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE; + mOrientedRanges.size.source = mTouchSource; + mOrientedRanges.size.min = 0; + mOrientedRanges.size.max = 1.0; + mOrientedRanges.size.flat = 0; + mOrientedRanges.size.fuzz = 0; + } else { + mSizeScale = 0.0f; } // Pressure factors. mPressureScale = 0; if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) { - RawAbsoluteAxisInfo rawPressureAxis; - switch (mCalibration.pressureSource) { - case Calibration::PRESSURE_SOURCE_PRESSURE: - rawPressureAxis = mRawPointerAxes.pressure; - break; - case Calibration::PRESSURE_SOURCE_TOUCH: - rawPressureAxis = mRawPointerAxes.touchMajor; - break; - default: - rawPressureAxis.clear(); - } - if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL || mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) { if (mCalibration.havePressureScale) { mPressureScale = mCalibration.pressureScale; - } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) { - mPressureScale = 1.0f / rawPressureAxis.maxValue; + } else if (mRawPointerAxes.pressure.valid + && mRawPointerAxes.pressure.maxValue != 0) { + mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue; } } @@ -2646,31 +2603,13 @@ bool TouchInputMapper::configureSurface() { mOrientedRanges.pressure.fuzz = 0; } - // Size factors. - mSizeScale = 0; - if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) { - if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) { - if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) { - mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue; - } - } - - mOrientedRanges.haveSize = true; - - mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE; - mOrientedRanges.size.source = mTouchSource; - mOrientedRanges.size.min = 0; - mOrientedRanges.size.max = 1.0; - mOrientedRanges.size.flat = 0; - mOrientedRanges.size.fuzz = 0; - } - // Orientation mOrientationScale = 0; if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) { if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) { - if (mRawPointerAxes.orientation.valid && mRawPointerAxes.orientation.maxValue != 0) { + if (mRawPointerAxes.orientation.valid + && mRawPointerAxes.orientation.maxValue != 0) { mOrientationScale = float(M_PI_2) / mRawPointerAxes.orientation.maxValue; } } @@ -2879,50 +2818,30 @@ void TouchInputMapper::parseCalibration() { const PropertyMap& in = getDevice()->getConfiguration(); Calibration& out = mCalibration; - // Touch Size - out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT; - String8 touchSizeCalibrationString; - if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) { - if (touchSizeCalibrationString == "none") { - out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; - } else if (touchSizeCalibrationString == "geometric") { - out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC; - } else if (touchSizeCalibrationString == "pressure") { - out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; - } else if (touchSizeCalibrationString != "default") { - LOGW("Invalid value for touch.touchSize.calibration: '%s'", - touchSizeCalibrationString.string()); - } - } - - // Tool Size - out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT; - String8 toolSizeCalibrationString; - if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) { - if (toolSizeCalibrationString == "none") { - out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; - } else if (toolSizeCalibrationString == "geometric") { - out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC; - } else if (toolSizeCalibrationString == "linear") { - out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; - } else if (toolSizeCalibrationString == "area") { - out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA; - } else if (toolSizeCalibrationString != "default") { - LOGW("Invalid value for touch.toolSize.calibration: '%s'", - toolSizeCalibrationString.string()); - } - } - - out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"), - out.toolSizeLinearScale); - out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"), - out.toolSizeLinearBias); - out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"), - out.toolSizeAreaScale); - out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"), - out.toolSizeAreaBias); - out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"), - out.toolSizeIsSummed); + // Size + out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; + String8 sizeCalibrationString; + if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { + if (sizeCalibrationString == "none") { + out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; + } else if (sizeCalibrationString == "geometric") { + out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC; + } else if (sizeCalibrationString == "diameter") { + out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER; + } else if (sizeCalibrationString == "area") { + out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA; + } else if (sizeCalibrationString != "default") { + LOGW("Invalid value for touch.size.calibration: '%s'", + sizeCalibrationString.string()); + } + } + + out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"), + out.sizeScale); + out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"), + out.sizeBias); + out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"), + out.sizeIsSummed); // Pressure out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT; @@ -2940,36 +2859,9 @@ void TouchInputMapper::parseCalibration() { } } - out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT; - String8 pressureSourceString; - if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) { - if (pressureSourceString == "pressure") { - out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; - } else if (pressureSourceString == "touch") { - out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; - } else if (pressureSourceString != "default") { - LOGW("Invalid value for touch.pressure.source: '%s'", - pressureSourceString.string()); - } - } - out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"), out.pressureScale); - // Size - out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT; - String8 sizeCalibrationString; - if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) { - if (sizeCalibrationString == "none") { - out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; - } else if (sizeCalibrationString == "normalized") { - out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; - } else if (sizeCalibrationString != "default") { - LOGW("Invalid value for touch.size.calibration: '%s'", - sizeCalibrationString.string()); - } - } - // Orientation out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT; String8 orientationCalibrationString; @@ -3005,178 +2897,77 @@ void TouchInputMapper::parseCalibration() { } void TouchInputMapper::resolveCalibration() { - // Pressure - switch (mCalibration.pressureSource) { - case Calibration::PRESSURE_SOURCE_DEFAULT: - if (mRawPointerAxes.pressure.valid) { - mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE; - } else if (mRawPointerAxes.touchMajor.valid) { - mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH; - } - break; - - case Calibration::PRESSURE_SOURCE_PRESSURE: - if (! mRawPointerAxes.pressure.valid) { - LOGW("Calibration property touch.pressure.source is 'pressure' but " - "the pressure axis is not available."); - } - break; - - case Calibration::PRESSURE_SOURCE_TOUCH: - if (! mRawPointerAxes.touchMajor.valid) { - LOGW("Calibration property touch.pressure.source is 'touch' but " - "the touchMajor axis is not available."); - } - break; - - default: - break; - } - - switch (mCalibration.pressureCalibration) { - case Calibration::PRESSURE_CALIBRATION_DEFAULT: - if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) { - mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE; - } else { - mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; - } - break; - - default: - break; - } - - // Tool Size - switch (mCalibration.toolSizeCalibration) { - case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT: - if (mRawPointerAxes.toolMajor.valid) { - mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR; - } else { - mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE; - } - break; - - default: - break; - } - - // Touch Size - switch (mCalibration.touchSizeCalibration) { - case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT: - if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE - && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) { - mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE; - } else { - mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE; + // Size + if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) { + if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) { + mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC; } - break; - - default: - break; + } else { + mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; } - // Size - switch (mCalibration.sizeCalibration) { - case Calibration::SIZE_CALIBRATION_DEFAULT: - if (mRawPointerAxes.toolMajor.valid) { - mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED; - } else { - mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE; + // Pressure + if (mRawPointerAxes.pressure.valid) { + if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) { + mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL; } - break; - - default: - break; + } else { + mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE; } // Orientation - switch (mCalibration.orientationCalibration) { - case Calibration::ORIENTATION_CALIBRATION_DEFAULT: - if (mRawPointerAxes.orientation.valid) { + if (mRawPointerAxes.orientation.valid) { + if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) { mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED; - } else { - mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; } - break; - - default: - break; + } else { + mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE; } // Distance - switch (mCalibration.distanceCalibration) { - case Calibration::DISTANCE_CALIBRATION_DEFAULT: - if (mRawPointerAxes.distance.valid) { + if (mRawPointerAxes.distance.valid) { + if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) { mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED; - } else { - mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE; } - break; - - default: - break; + } else { + mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE; } } void TouchInputMapper::dumpCalibration(String8& dump) { dump.append(INDENT3 "Calibration:\n"); - // Touch Size - switch (mCalibration.touchSizeCalibration) { - case Calibration::TOUCH_SIZE_CALIBRATION_NONE: - dump.append(INDENT4 "touch.touchSize.calibration: none\n"); - break; - case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: - dump.append(INDENT4 "touch.touchSize.calibration: geometric\n"); - break; - case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: - dump.append(INDENT4 "touch.touchSize.calibration: pressure\n"); - break; - default: - LOG_ASSERT(false); - } - - // Tool Size - switch (mCalibration.toolSizeCalibration) { - case Calibration::TOOL_SIZE_CALIBRATION_NONE: - dump.append(INDENT4 "touch.toolSize.calibration: none\n"); + // Size + switch (mCalibration.sizeCalibration) { + case Calibration::SIZE_CALIBRATION_NONE: + dump.append(INDENT4 "touch.size.calibration: none\n"); break; - case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: - dump.append(INDENT4 "touch.toolSize.calibration: geometric\n"); + case Calibration::SIZE_CALIBRATION_GEOMETRIC: + dump.append(INDENT4 "touch.size.calibration: geometric\n"); break; - case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: - dump.append(INDENT4 "touch.toolSize.calibration: linear\n"); + case Calibration::SIZE_CALIBRATION_DIAMETER: + dump.append(INDENT4 "touch.size.calibration: diameter\n"); break; - case Calibration::TOOL_SIZE_CALIBRATION_AREA: - dump.append(INDENT4 "touch.toolSize.calibration: area\n"); + case Calibration::SIZE_CALIBRATION_AREA: + dump.append(INDENT4 "touch.size.calibration: area\n"); break; default: LOG_ASSERT(false); } - if (mCalibration.haveToolSizeLinearScale) { - dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n", - mCalibration.toolSizeLinearScale); - } - - if (mCalibration.haveToolSizeLinearBias) { - dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n", - mCalibration.toolSizeLinearBias); + if (mCalibration.haveSizeScale) { + dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n", + mCalibration.sizeScale); } - if (mCalibration.haveToolSizeAreaScale) { - dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n", - mCalibration.toolSizeAreaScale); + if (mCalibration.haveSizeBias) { + dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n", + mCalibration.sizeBias); } - if (mCalibration.haveToolSizeAreaBias) { - dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n", - mCalibration.toolSizeAreaBias); - } - - if (mCalibration.haveToolSizeIsSummed) { - dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %s\n", - toString(mCalibration.toolSizeIsSummed)); + if (mCalibration.haveSizeIsSummed) { + dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n", + toString(mCalibration.sizeIsSummed)); } // Pressure @@ -3194,36 +2985,11 @@ void TouchInputMapper::dumpCalibration(String8& dump) { LOG_ASSERT(false); } - switch (mCalibration.pressureSource) { - case Calibration::PRESSURE_SOURCE_PRESSURE: - dump.append(INDENT4 "touch.pressure.source: pressure\n"); - break; - case Calibration::PRESSURE_SOURCE_TOUCH: - dump.append(INDENT4 "touch.pressure.source: touch\n"); - break; - case Calibration::PRESSURE_SOURCE_DEFAULT: - break; - default: - LOG_ASSERT(false); - } - if (mCalibration.havePressureScale) { dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n", mCalibration.pressureScale); } - // Size - switch (mCalibration.sizeCalibration) { - case Calibration::SIZE_CALIBRATION_NONE: - dump.append(INDENT4 "touch.size.calibration: none\n"); - break; - case Calibration::SIZE_CALIBRATION_NORMALIZED: - dump.append(INDENT4 "touch.size.calibration: normalized\n"); - break; - default: - LOG_ASSERT(false); - } - // Orientation switch (mCalibration.orientationCalibration) { case Calibration::ORIENTATION_CALIBRATION_NONE: @@ -3613,119 +3379,94 @@ void TouchInputMapper::cookPointerData() { for (uint32_t i = 0; i < currentPointerCount; i++) { const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i]; - // ToolMajor and ToolMinor - float toolMajor, toolMinor; - switch (mCalibration.toolSizeCalibration) { - case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC: - toolMajor = in.toolMajor * mGeometricScale; - if (mRawPointerAxes.toolMinor.valid) { - toolMinor = in.toolMinor * mGeometricScale; + // Size + float touchMajor, touchMinor, toolMajor, toolMinor, size; + switch (mCalibration.sizeCalibration) { + case Calibration::SIZE_CALIBRATION_GEOMETRIC: + case Calibration::SIZE_CALIBRATION_DIAMETER: + case Calibration::SIZE_CALIBRATION_AREA: + if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) { + touchMajor = in.touchMajor; + touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor; + toolMajor = in.toolMajor; + toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor; + size = mRawPointerAxes.touchMinor.valid + ? avg(in.touchMajor, in.touchMinor) : in.touchMajor; + } else if (mRawPointerAxes.touchMajor.valid) { + toolMajor = touchMajor = in.touchMajor; + toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid + ? in.touchMinor : in.touchMajor; + size = mRawPointerAxes.touchMinor.valid + ? avg(in.touchMajor, in.touchMinor) : in.touchMajor; + } else if (mRawPointerAxes.toolMajor.valid) { + touchMajor = toolMajor = in.toolMajor; + touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid + ? in.toolMinor : in.toolMajor; + size = mRawPointerAxes.toolMinor.valid + ? avg(in.toolMajor, in.toolMinor) : in.toolMajor; } else { - toolMinor = toolMajor; + LOG_ASSERT(false, "No touch or tool axes. " + "Size calibration should have been resolved to NONE."); + touchMajor = 0; + touchMinor = 0; + toolMajor = 0; + toolMinor = 0; + size = 0; } - break; - case Calibration::TOOL_SIZE_CALIBRATION_LINEAR: - toolMajor = in.toolMajor != 0 - ? in.toolMajor * mToolSizeLinearScale + mToolSizeLinearBias - : 0; - if (mRawPointerAxes.toolMinor.valid) { - toolMinor = in.toolMinor != 0 - ? in.toolMinor * mToolSizeLinearScale - + mToolSizeLinearBias - : 0; - } else { - toolMinor = toolMajor; + + if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) { + uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count(); + if (touchingCount > 1) { + touchMajor /= touchingCount; + touchMinor /= touchingCount; + toolMajor /= touchingCount; + toolMinor /= touchingCount; + size /= touchingCount; + } } - break; - case Calibration::TOOL_SIZE_CALIBRATION_AREA: - if (in.toolMajor != 0) { - float diameter = sqrtf(in.toolMajor - * mToolSizeAreaScale + mToolSizeAreaBias); - toolMajor = diameter * mToolSizeLinearScale + mToolSizeLinearBias; - } else { - toolMajor = 0; + + if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) { + touchMajor *= mGeometricScale; + touchMinor *= mGeometricScale; + toolMajor *= mGeometricScale; + toolMinor *= mGeometricScale; + } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) { + touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0; + touchMinor = touchMajor; + toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0; + toolMinor = toolMajor; + } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) { + touchMinor = touchMajor; + toolMinor = toolMajor; } - toolMinor = toolMajor; + + mCalibration.applySizeScaleAndBias(&touchMajor); + mCalibration.applySizeScaleAndBias(&touchMinor); + mCalibration.applySizeScaleAndBias(&toolMajor); + mCalibration.applySizeScaleAndBias(&toolMinor); + size *= mSizeScale; break; default: + touchMajor = 0; + touchMinor = 0; toolMajor = 0; toolMinor = 0; + size = 0; break; } - if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) { - uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count(); - toolMajor /= touchingCount; - toolMinor /= touchingCount; - } - // Pressure - float rawPressure; - switch (mCalibration.pressureSource) { - case Calibration::PRESSURE_SOURCE_PRESSURE: - rawPressure = in.pressure; - break; - case Calibration::PRESSURE_SOURCE_TOUCH: - rawPressure = in.touchMajor; - break; - default: - rawPressure = 0; - } - float pressure; switch (mCalibration.pressureCalibration) { case Calibration::PRESSURE_CALIBRATION_PHYSICAL: case Calibration::PRESSURE_CALIBRATION_AMPLITUDE: - pressure = rawPressure * mPressureScale; + pressure = in.pressure * mPressureScale; break; default: pressure = in.isHovering ? 0 : 1; break; } - // TouchMajor and TouchMinor - float touchMajor, touchMinor; - switch (mCalibration.touchSizeCalibration) { - case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC: - touchMajor = in.touchMajor * mGeometricScale; - if (mRawPointerAxes.touchMinor.valid) { - touchMinor = in.touchMinor * mGeometricScale; - } else { - touchMinor = touchMajor; - } - break; - case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE: - touchMajor = toolMajor * pressure; - touchMinor = toolMinor * pressure; - break; - default: - touchMajor = 0; - touchMinor = 0; - break; - } - - if (touchMajor > toolMajor) { - touchMajor = toolMajor; - } - if (touchMinor > toolMinor) { - touchMinor = toolMinor; - } - - // Size - float size; - switch (mCalibration.sizeCalibration) { - case Calibration::SIZE_CALIBRATION_NORMALIZED: { - float rawSize = mRawPointerAxes.toolMinor.valid - ? avg(in.toolMajor, in.toolMinor) - : in.toolMajor; - size = rawSize * mSizeScale; - break; - } - default: - size = 0; - break; - } - // Orientation float orientation; switch (mCalibration.orientationCalibration) { @@ -3737,7 +3478,8 @@ void TouchInputMapper::cookPointerData() { int32_t c2 = signExtendNybble(in.orientation & 0x0f); if (c1 != 0 || c2 != 0) { orientation = atan2f(c1, c2) * 0.5f; - float scale = 1.0f + hypotf(c1, c2) / 16.0f; + float confidence = hypotf(c1, c2); + float scale = 1.0f + confidence / 16.0f; touchMajor *= scale; touchMinor /= scale; toolMajor *= scale; diff --git a/services/input/InputReader.h b/services/input/InputReader.h index e9daef5..72802fc 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -696,7 +696,6 @@ public: int32_t mAbsMTToolType; Slot(); - void clearIfInUse(); void clear(); }; @@ -978,36 +977,23 @@ protected: // Immutable calibration parameters in parsed form. struct Calibration { - // Touch Size - enum TouchSizeCalibration { - TOUCH_SIZE_CALIBRATION_DEFAULT, - TOUCH_SIZE_CALIBRATION_NONE, - TOUCH_SIZE_CALIBRATION_GEOMETRIC, - TOUCH_SIZE_CALIBRATION_PRESSURE, + // Size + enum SizeCalibration { + SIZE_CALIBRATION_DEFAULT, + SIZE_CALIBRATION_NONE, + SIZE_CALIBRATION_GEOMETRIC, + SIZE_CALIBRATION_DIAMETER, + SIZE_CALIBRATION_AREA, }; - TouchSizeCalibration touchSizeCalibration; - - // Tool Size - enum ToolSizeCalibration { - TOOL_SIZE_CALIBRATION_DEFAULT, - TOOL_SIZE_CALIBRATION_NONE, - TOOL_SIZE_CALIBRATION_GEOMETRIC, - TOOL_SIZE_CALIBRATION_LINEAR, - TOOL_SIZE_CALIBRATION_AREA, - }; + SizeCalibration sizeCalibration; - ToolSizeCalibration toolSizeCalibration; - bool haveToolSizeLinearScale; - float toolSizeLinearScale; - bool haveToolSizeLinearBias; - float toolSizeLinearBias; - bool haveToolSizeAreaScale; - float toolSizeAreaScale; - bool haveToolSizeAreaBias; - float toolSizeAreaBias; - bool haveToolSizeIsSummed; - bool toolSizeIsSummed; + bool haveSizeScale; + float sizeScale; + bool haveSizeBias; + float sizeBias; + bool haveSizeIsSummed; + bool sizeIsSummed; // Pressure enum PressureCalibration { @@ -1016,26 +1002,11 @@ protected: PRESSURE_CALIBRATION_PHYSICAL, PRESSURE_CALIBRATION_AMPLITUDE, }; - enum PressureSource { - PRESSURE_SOURCE_DEFAULT, - PRESSURE_SOURCE_PRESSURE, - PRESSURE_SOURCE_TOUCH, - }; PressureCalibration pressureCalibration; - PressureSource pressureSource; bool havePressureScale; float pressureScale; - // Size - enum SizeCalibration { - SIZE_CALIBRATION_DEFAULT, - SIZE_CALIBRATION_NONE, - SIZE_CALIBRATION_NORMALIZED, - }; - - SizeCalibration sizeCalibration; - // Orientation enum OrientationCalibration { ORIENTATION_CALIBRATION_DEFAULT, @@ -1056,6 +1027,15 @@ protected: DistanceCalibration distanceCalibration; bool haveDistanceScale; float distanceScale; + + inline void applySizeScaleAndBias(float* outSize) const { + if (haveSizeScale) { + *outSize *= sizeScale; + } + if (haveSizeBias) { + *outSize += sizeBias; + } + } } mCalibration; // Raw pointer axis information from the driver. @@ -1118,11 +1098,6 @@ private: float mGeometricScale; - float mToolSizeLinearScale; - float mToolSizeLinearBias; - float mToolSizeAreaScale; - float mToolSizeAreaBias; - float mPressureScale; float mSizeScale; diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 87f212b..ebf66aa 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -2487,6 +2487,8 @@ protected: static const float X_PRECISION; static const float Y_PRECISION; + static const float GEOMETRIC_SCALE; + static const VirtualKeyDefinition VIRTUAL_KEYS[2]; enum Axes { @@ -2531,6 +2533,10 @@ const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9; const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH; const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT; +const float TouchInputMapperTest::GEOMETRIC_SCALE = + avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1), + float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1)); + const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = { { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 }, { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 }, @@ -3268,8 +3274,7 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { float y = toDisplayY(rawY); float pressure = float(rawPressure) / RAW_PRESSURE_MAX; float size = float(rawToolMajor) / RAW_TOOL_MAX; - float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size; - float touch = min(tool * pressure, tool); + float tool = float(rawToolMajor) * GEOMETRIC_SCALE; float distance = float(rawDistance); processDown(mapper, rawX, rawY); @@ -3281,7 +3286,7 @@ TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) { NotifyMotionArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], - x, y, pressure, size, touch, touch, tool, tool, 0, distance)); + x, y, pressure, size, tool, tool, tool, tool, 0, distance)); } TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) { @@ -4443,11 +4448,11 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { float x = toDisplayX(rawX); float y = toDisplayY(rawY); float pressure = float(rawPressure) / RAW_PRESSURE_MAX; - float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX; - float toolMajor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMajor / RAW_TOOL_MAX; - float toolMinor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMinor / RAW_TOOL_MAX; - float touchMajor = min(toolMajor * pressure, toolMajor); - float touchMinor = min(toolMinor * pressure, toolMinor); + float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX; + float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE; + float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE; + float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE; + float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE; float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2; float distance = float(rawDistance); @@ -4467,7 +4472,8 @@ TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) { ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_EQ(0, args.pointerProperties[0].id); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], - x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation, distance)); + x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, + orientation, distance)); } TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) { @@ -4475,8 +4481,7 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL | MINOR); - addConfigurationProperty("touch.touchSize.calibration", "geometric"); - addConfigurationProperty("touch.toolSize.calibration", "geometric"); + addConfigurationProperty("touch.size.calibration", "geometric"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. @@ -4489,14 +4494,11 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) float x = toDisplayX(rawX); float y = toDisplayY(rawY); - float pressure = float(rawTouchMajor) / RAW_TOUCH_MAX; - float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX; - float scale = avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1), - float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1)); - float toolMajor = float(rawToolMajor) * scale; - float toolMinor = float(rawToolMinor) * scale; - float touchMajor = min(float(rawTouchMajor) * scale, toolMajor); - float touchMinor = min(float(rawTouchMinor) * scale, toolMinor); + float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX; + float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE; + float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE; + float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE; + float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE; processPosition(mapper, rawX, rawY); processTouchMajor(mapper, rawTouchMajor); @@ -4509,22 +4511,18 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) NotifyMotionArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], - x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0)); + x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0)); } -TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) { +TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) { MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL); - addConfigurationProperty("touch.touchSize.calibration", "pressure"); - addConfigurationProperty("touch.toolSize.calibration", "linear"); - addConfigurationProperty("touch.toolSize.linearScale", "10"); - addConfigurationProperty("touch.toolSize.linearBias", "160"); - addConfigurationProperty("touch.toolSize.isSummed", "1"); - addConfigurationProperty("touch.pressure.calibration", "amplitude"); - addConfigurationProperty("touch.pressure.source", "touch"); - addConfigurationProperty("touch.pressure.scale", "0.01"); + addConfigurationProperty("touch.size.calibration", "diameter"); + addConfigurationProperty("touch.size.scale", "10"); + addConfigurationProperty("touch.size.bias", "160"); + addConfigurationProperty("touch.size.isSummed", "1"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. @@ -4534,17 +4532,16 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinear int32_t rawY = 200; int32_t rawX2 = 150; int32_t rawY2 = 250; - int32_t rawTouchMajor = 60; - int32_t rawToolMajor = 5; + int32_t rawTouchMajor = 5; + int32_t rawToolMajor = 8; float x = toDisplayX(rawX); float y = toDisplayY(rawY); float x2 = toDisplayX(rawX2); float y2 = toDisplayY(rawY2); - float pressure = float(rawTouchMajor) * 0.01f; - float size = float(rawToolMajor) / RAW_TOOL_MAX; - float tool = (float(rawToolMajor) * 10.0f + 160.0f) / 2; - float touch = min(tool * pressure, tool); + float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX; + float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f; + float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f; processPosition(mapper, rawX, rawY); processTouchMajor(mapper, rawTouchMajor); @@ -4565,39 +4562,32 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinear args.action); ASSERT_EQ(size_t(2), args.pointerCount); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], - x, y, pressure, size, touch, touch, tool, tool, 0, 0)); + x, y, 1.0f, size, touch, touch, tool, tool, 0, 0)); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1], - x2, y2, pressure, size, touch, touch, tool, tool, 0, 0)); + x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0)); } -TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) { +TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) { MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); addConfigurationProperty("touch.deviceType", "touchScreen"); prepareDisplay(DISPLAY_ORIENTATION_0); prepareAxes(POSITION | TOUCH | TOOL); - addConfigurationProperty("touch.touchSize.calibration", "pressure"); - addConfigurationProperty("touch.toolSize.calibration", "area"); - addConfigurationProperty("touch.toolSize.areaScale", "22"); - addConfigurationProperty("touch.toolSize.areaBias", "1"); - addConfigurationProperty("touch.toolSize.linearScale", "9.2"); - addConfigurationProperty("touch.toolSize.linearBias", "3"); - addConfigurationProperty("touch.pressure.calibration", "amplitude"); - addConfigurationProperty("touch.pressure.source", "touch"); - addConfigurationProperty("touch.pressure.scale", "0.01"); + addConfigurationProperty("touch.size.calibration", "area"); + addConfigurationProperty("touch.size.scale", "43"); + addConfigurationProperty("touch.size.bias", "3"); addMapperAndConfigure(mapper); // These calculations are based on the input device calibration documentation. int32_t rawX = 100; int32_t rawY = 200; - int32_t rawTouchMajor = 60; - int32_t rawToolMajor = 5; + int32_t rawTouchMajor = 5; + int32_t rawToolMajor = 8; float x = toDisplayX(rawX); float y = toDisplayY(rawY); - float pressure = float(rawTouchMajor) * 0.01f; - float size = float(rawToolMajor) / RAW_TOOL_MAX; - float tool = sqrtf(float(rawToolMajor) * 22.0f + 1.0f) * 9.2f + 3.0f; - float touch = min(tool * pressure, tool); + float size = float(rawTouchMajor) / RAW_TOUCH_MAX; + float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f; + float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f; processPosition(mapper, rawX, rawY); processTouchMajor(mapper, rawTouchMajor); @@ -4608,7 +4598,36 @@ TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibrat NotifyMotionArgs args; ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], - x, y, pressure, size, touch, touch, tool, tool, 0, 0)); + x, y, 1.0f, size, touch, touch, tool, tool, 0, 0)); +} + +TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) { + MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice); + addConfigurationProperty("touch.deviceType", "touchScreen"); + prepareDisplay(DISPLAY_ORIENTATION_0); + prepareAxes(POSITION | PRESSURE); + addConfigurationProperty("touch.pressure.calibration", "amplitude"); + addConfigurationProperty("touch.pressure.scale", "0.01"); + addMapperAndConfigure(mapper); + + // These calculations are based on the input device calibration documentation. + int32_t rawX = 100; + int32_t rawY = 200; + int32_t rawPressure = 60; + + float x = toDisplayX(rawX); + float y = toDisplayY(rawY); + float pressure = float(rawPressure) * 0.01f; + + processPosition(mapper, rawX, rawY); + processPressure(mapper, rawPressure); + processMTSync(mapper); + processSync(mapper); + + NotifyMotionArgs args; + ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args)); + ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0], + x, y, pressure, 0, 0, 0, 0, 0, 0, 0)); } TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) { diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 8b7d3a8..1c06636 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -2105,10 +2105,13 @@ class BackupManagerService extends IBackupManager.Stub { backupOnePackage(pkg, out); } - // Finally, shared storage if requested + // Shared storage if requested if (mIncludeShared) { backupSharedStorage(); } + + // Done! + finalizeBackup(out); } catch (RemoteException e) { Slog.e(TAG, "App died during full backup"); } finally { @@ -2326,6 +2329,16 @@ class BackupManagerService extends IBackupManager.Stub { } } + private void finalizeBackup(OutputStream out) { + try { + // A standard 'tar' EOF sequence: two 512-byte blocks of all zeroes. + byte[] eof = new byte[512 * 2]; // newly allocated == zero filled + out.write(eof); + } catch (IOException e) { + Slog.w(TAG, "Error attempting to finalize backup stream"); + } + } + private void writeAppManifest(PackageInfo pkg, File manifestFile, boolean withApk) throws IOException { // Manifest format. All data are strings ending in LF: @@ -3186,9 +3199,11 @@ class BackupManagerService extends IBackupManager.Stub { void skipTarPadding(long size, InputStream instream) throws IOException { long partial = (size + 512) % 512; if (partial > 0) { - byte[] buffer = new byte[512]; - int nRead = instream.read(buffer, 0, 512 - (int)partial); - if (nRead >= 0) mBytes += nRead; + final int needed = 512 - (int)partial; + byte[] buffer = new byte[needed]; + if (readExactly(instream, buffer, 0, needed) == needed) { + mBytes += needed; + } else throw new IOException("Unexpected EOF in padding"); } } @@ -3199,12 +3214,11 @@ class BackupManagerService extends IBackupManager.Stub { if (info.size > 64 * 1024) { throw new IOException("Restore manifest too big; corrupt? size=" + info.size); } + byte[] buffer = new byte[(int) info.size]; - int nRead = 0; - while (nRead < info.size) { - nRead += instream.read(buffer, nRead, (int)info.size - nRead); - } - if (nRead >= 0) mBytes += nRead; + if (readExactly(instream, buffer, 0, (int)info.size) == info.size) { + mBytes += info.size; + } else throw new IOException("Unexpected EOF in manifest"); RestorePolicy policy = RestorePolicy.IGNORE; String[] str = new String[1]; @@ -3453,7 +3467,7 @@ class BackupManagerService extends IBackupManager.Stub { } } catch (IOException e) { if (DEBUG) { - Slog.e(TAG, "Parse error in header. Hexdump:"); + Slog.e(TAG, "Parse error in header: " + e.getMessage()); HEXLOG(block); } throw e; @@ -3479,22 +3493,31 @@ class BackupManagerService extends IBackupManager.Stub { } } - boolean readTarHeader(InputStream instream, byte[] block) throws IOException { - int totalRead = 0; - while (totalRead < 512) { - int nRead = instream.read(block, totalRead, 512 - totalRead); - if (nRead >= 0) { - mBytes += nRead; - totalRead += nRead; - } else { - if (totalRead == 0) { - // EOF instead of a new header; we're done - break; - } - throw new IOException("Unable to read full block header, t=" + totalRead); + // Read exactly the given number of bytes into a buffer at the stated offset. + // Returns false if EOF is encountered before the requested number of bytes + // could be read. + int readExactly(InputStream in, byte[] buffer, int offset, int size) + throws IOException { + if (size <= 0) throw new IllegalArgumentException("size must be > 0"); + + int soFar = 0; + while (soFar < size) { + int nRead = in.read(buffer, offset + soFar, size - soFar); + if (nRead <= 0) { + if (MORE_DEBUG) Slog.w(TAG, "- wanted exactly " + size + " but got only " + soFar); + break; } + soFar += nRead; } - return (totalRead == 512); + return soFar; + } + + boolean readTarHeader(InputStream instream, byte[] block) throws IOException { + final int got = readExactly(instream, block, 0, 512); + if (got == 0) return false; // Clean EOF + if (got < 512) throw new IOException("Unable to read full block header"); + mBytes += 512; + return true; } // overwrites 'info' fields based on the pax extended header @@ -3510,11 +3533,10 @@ class BackupManagerService extends IBackupManager.Stub { // read whole blocks, not just the content size int numBlocks = (int)((info.size + 511) >> 9); byte[] data = new byte[numBlocks * 512]; - int nRead = instream.read(data); - if (nRead >= 0) mBytes += nRead; - if (nRead != data.length) { - return false; + if (readExactly(instream, data, 0, data.length) < data.length) { + throw new IOException("Unable to read full pax header"); } + mBytes += data.length; final int contentSize = (int) info.size; int offset = 0; diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index a57f68d..177cf41 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -5348,7 +5348,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { out = ParcelFileDescriptor.open(codeFile, ParcelFileDescriptor.MODE_READ_WRITE); } catch (FileNotFoundException e) { - Slog.e(TAG, "Failed to create file descritpor for : " + codeFileName); + Slog.e(TAG, "Failed to create file descriptor for : " + codeFileName); return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; } // Copy the resource now @@ -5356,9 +5356,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - if (imcs.copyResource(packageURI, out)) { - ret = PackageManager.INSTALL_SUCCEEDED; - } + ret = imcs.copyResource(packageURI, out); } finally { try { if (out != null) out.close(); } catch (IOException e) {} mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); @@ -5553,6 +5551,12 @@ public class PackageManagerService extends IPackageManager.Stub { int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { if (temp) { createCopyFile(); + } else { + /* + * Pre-emptively destroy the container since it's destroyed if + * copying fails due to it existing anyway. + */ + PackageHelper.destroySdDir(cid); } final String newCachePath; |