diff options
189 files changed, 3743 insertions, 1617 deletions
diff --git a/Android.mk b/Android.mk index 781d5d1c8bd0..0865d24a20ee 100644 --- a/Android.mk +++ b/Android.mk @@ -89,6 +89,8 @@ LOCAL_SRC_FILES += \ core/java/android/app/backup/IFullBackupRestoreObserver.aidl \ core/java/android/app/backup/IRestoreObserver.aidl \ core/java/android/app/backup/IRestoreSession.aidl \ + core/java/android/app/maintenance/IIdleCallback.aidl \ + core/java/android/app/maintenance/IIdleService.aidl \ core/java/android/bluetooth/IBluetooth.aidl \ core/java/android/bluetooth/IBluetoothA2dp.aidl \ core/java/android/bluetooth/IBluetoothCallback.aidl \ diff --git a/api/current.txt b/api/current.txt index 52900c96b631..7673ff3f830c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -400,6 +400,10 @@ package android { field public static final int content = 16843355; // 0x101025b field public static final int contentAuthority = 16843408; // 0x1010290 field public static final int contentDescription = 16843379; // 0x1010273 + field public static final int controlX1 = 16843770; // 0x10103fa + field public static final int controlX2 = 16843772; // 0x10103fc + field public static final int controlY1 = 16843771; // 0x10103fb + field public static final int controlY2 = 16843773; // 0x10103fd field public static final int cropToPadding = 16843043; // 0x1010123 field public static final int cursorVisible = 16843090; // 0x1010152 field public static final int customNavigationLayout = 16843474; // 0x10102d2 @@ -633,6 +637,7 @@ package android { field public static final int isScrollContainer = 16843342; // 0x101024e field public static final int isSticky = 16843335; // 0x1010247 field public static final int isolatedProcess = 16843689; // 0x10103a9 + field public static final int isolatedZVolume = 16843769; // 0x10103f9 field public static final int itemBackground = 16843056; // 0x1010130 field public static final int itemIconDisabledAlpha = 16843057; // 0x1010131 field public static final int itemPadding = 16843565; // 0x101032d @@ -4205,6 +4210,7 @@ package android.app { field public static final java.lang.String EXTRA_SMALL_ICON = "android.icon"; field public static final java.lang.String EXTRA_SUB_TEXT = "android.subText"; field public static final java.lang.String EXTRA_SUMMARY_TEXT = "android.summaryText"; + field public static final java.lang.String EXTRA_TEMPLATE = "android.template"; field public static final java.lang.String EXTRA_TEXT = "android.text"; field public static final java.lang.String EXTRA_TEXT_LINES = "android.textLines"; field public static final java.lang.String EXTRA_TITLE = "android.title"; @@ -4223,6 +4229,9 @@ package android.app { field public static final int PRIORITY_MAX = 2; // 0x2 field public static final int PRIORITY_MIN = -2; // 0xfffffffe field public static final int STREAM_DEFAULT = -1; // 0xffffffff + field public static final int VISIBILITY_PRIVATE = 0; // 0x0 + field public static final int VISIBILITY_PUBLIC = 1; // 0x1 + field public static final int VISIBILITY_SECRET = -1; // 0xffffffff field public android.app.Notification.Action[] actions; field public int audioStreamType; field public android.widget.RemoteViews bigContentView; @@ -4241,10 +4250,12 @@ package android.app { field public int ledOnMS; field public int number; field public int priority; + field public android.app.Notification publicVersion; field public android.net.Uri sound; field public java.lang.CharSequence tickerText; field public android.widget.RemoteViews tickerView; field public long[] vibrate; + field public int visibility; field public long when; } @@ -4298,6 +4309,7 @@ package android.app { method public android.app.Notification.Builder setOnlyAlertOnce(boolean); method public android.app.Notification.Builder setPriority(int); method public android.app.Notification.Builder setProgress(int, int, boolean); + method public android.app.Notification.Builder setPublicVersion(android.app.Notification); method public android.app.Notification.Builder setShowWhen(boolean); method public android.app.Notification.Builder setSmallIcon(int); method public android.app.Notification.Builder setSmallIcon(int, int); @@ -4309,6 +4321,7 @@ package android.app { method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews); method public android.app.Notification.Builder setUsesChronometer(boolean); method public android.app.Notification.Builder setVibrate(long[]); + method public android.app.Notification.Builder setVisibility(int); method public android.app.Notification.Builder setWhen(long); } @@ -4873,6 +4886,20 @@ package android.app.backup { } +package android.app.maintenance { + + public abstract class IdleService extends android.app.Service { + ctor public IdleService(); + method public final void finishIdle(); + method public final android.os.IBinder onBind(android.content.Intent); + method public abstract boolean onIdleStart(); + method public abstract void onIdleStop(); + field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_IDLE_SERVICE"; + field public static final java.lang.String SERVICE_INTERFACE = "android.service.idle.IdleService"; + } + +} + package android.appwidget { public class AppWidgetHost { @@ -9903,8 +9930,6 @@ package android.graphics { method public void toggleInverseFillType(); method public void transform(android.graphics.Matrix, android.graphics.Path); method public void transform(android.graphics.Matrix); - method public void trim(float, float, float); - method public void trim(float, float, float, android.graphics.Path); } public static final class Path.Direction extends java.lang.Enum { @@ -10338,6 +10363,7 @@ package android.graphics.drawable { ctor public BitmapDrawable(android.content.res.Resources, java.lang.String); ctor public deprecated BitmapDrawable(java.io.InputStream); ctor public BitmapDrawable(android.content.res.Resources, java.io.InputStream); + method public void draw(android.graphics.Canvas); method public final android.graphics.Bitmap getBitmap(); method public final android.graphics.drawable.Drawable.ConstantState getConstantState(); method public int getGravity(); @@ -10363,6 +10389,7 @@ package android.graphics.drawable { public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public ClipDrawable(android.graphics.drawable.Drawable, int, int); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public void invalidateDrawable(android.graphics.drawable.Drawable); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); @@ -10376,6 +10403,7 @@ package android.graphics.drawable { public class ColorDrawable extends android.graphics.drawable.Drawable { ctor public ColorDrawable(); ctor public ColorDrawable(int); + method public void draw(android.graphics.Canvas); method public int getColor(); method public int getOpacity(); method public void setAlpha(int); @@ -10394,7 +10422,7 @@ package android.graphics.drawable { method public static android.graphics.drawable.Drawable createFromStream(java.io.InputStream, java.lang.String); method public static android.graphics.drawable.Drawable createFromXml(android.content.res.Resources, org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; method public static android.graphics.drawable.Drawable createFromXmlInner(android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException; - method public void draw(android.graphics.Canvas); + method public abstract void draw(android.graphics.Canvas); method public int getAlpha(); method public final android.graphics.Rect getBounds(); method public android.graphics.drawable.Drawable.Callback getCallback(); @@ -10418,7 +10446,6 @@ package android.graphics.drawable { method public void jumpToCurrentState(); method public android.graphics.drawable.Drawable mutate(); method protected void onBoundsChange(android.graphics.Rect); - method protected void onDraw(android.graphics.Canvas); method protected boolean onLevelChange(int); method protected boolean onStateChange(int[]); method public static int resolveOpacity(int, int); @@ -10454,6 +10481,7 @@ package android.graphics.drawable { public class DrawableContainer extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public DrawableContainer(); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public void invalidateDrawable(android.graphics.drawable.Drawable); method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long); @@ -10494,6 +10522,7 @@ package android.graphics.drawable { public class GradientDrawable extends android.graphics.drawable.Drawable { ctor public GradientDrawable(); ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.drawable.GradientDrawable.Orientation getOrientation(); method public boolean onStateChange(int[]); @@ -10540,6 +10569,7 @@ package android.graphics.drawable { public class InsetDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public InsetDrawable(android.graphics.drawable.Drawable, int); ctor public InsetDrawable(android.graphics.drawable.Drawable, int, int, int, int); + method public void draw(android.graphics.Canvas); method public android.graphics.drawable.Drawable getDrawable(); method public int getOpacity(); method public void invalidateDrawable(android.graphics.drawable.Drawable); @@ -10551,6 +10581,7 @@ package android.graphics.drawable { public class LayerDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public LayerDrawable(android.graphics.drawable.Drawable[]); + method public void draw(android.graphics.Canvas); method public android.graphics.drawable.Drawable findDrawableByLayerId(int); method public android.graphics.drawable.Drawable getDrawable(int); method public int getId(int); @@ -10581,6 +10612,7 @@ package android.graphics.drawable { ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.Bitmap, byte[], android.graphics.Rect, java.lang.String); ctor public deprecated NinePatchDrawable(android.graphics.NinePatch); ctor public NinePatchDrawable(android.content.res.Resources, android.graphics.NinePatch); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.Paint getPaint(); method public void setAlpha(int); @@ -10599,6 +10631,7 @@ package android.graphics.drawable { public class PictureDrawable extends android.graphics.drawable.Drawable { ctor public PictureDrawable(android.graphics.Picture); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.Picture getPicture(); method public void setAlpha(int); @@ -10612,6 +10645,7 @@ package android.graphics.drawable { public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public RotateDrawable(); + method public void draw(android.graphics.Canvas); method public android.graphics.drawable.Drawable getDrawable(); method public int getOpacity(); method public void invalidateDrawable(android.graphics.drawable.Drawable); @@ -10623,6 +10657,7 @@ package android.graphics.drawable { public class ScaleDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback { ctor public ScaleDrawable(android.graphics.drawable.Drawable, int, float, float); + method public void draw(android.graphics.Canvas); method public android.graphics.drawable.Drawable getDrawable(); method public int getOpacity(); method public void invalidateDrawable(android.graphics.drawable.Drawable); @@ -10635,6 +10670,7 @@ package android.graphics.drawable { public class ShapeDrawable extends android.graphics.drawable.Drawable { ctor public ShapeDrawable(); ctor public ShapeDrawable(android.graphics.drawable.shapes.Shape); + method public void draw(android.graphics.Canvas); method public int getOpacity(); method public android.graphics.Paint getPaint(); method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory(); @@ -23797,6 +23833,7 @@ package android.speech.tts { } public final class SynthesisRequestV2 implements android.os.Parcelable { + ctor public SynthesisRequestV2(java.lang.String, java.lang.String, java.lang.String, android.os.Bundle, android.os.Bundle); method public int describeContents(); method public android.os.Bundle getAudioParams(); method public java.lang.String getText(); @@ -23953,10 +23990,9 @@ package android.speech.tts { field public static final int SUCCESS = 0; // 0x0 } - public static final class TextToSpeechClient.UtteranceId { + public static class TextToSpeechClient.UtteranceId { ctor public TextToSpeechClient.UtteranceId(); - ctor public TextToSpeechClient.UtteranceId(java.lang.String); - method public java.lang.String toUniqueString(); + method public final java.lang.String toUniqueString(); } public abstract class TextToSpeechService extends android.app.Service { @@ -29320,6 +29356,7 @@ package android.view { method public int getLayoutMode(); method public android.animation.LayoutTransition getLayoutTransition(); method public int getPersistentDrawingCache(); + method public boolean hasIsolatedZVolume(); method public int indexOfChild(android.view.View); method public final void invalidateChild(android.view.View, android.graphics.Rect); method public android.view.ViewParent invalidateChildInParent(int[], android.graphics.Rect); @@ -29364,6 +29401,7 @@ package android.view { method public void setClipChildren(boolean); method public void setClipToPadding(boolean); method public void setDescendantFocusability(int); + method public void setIsolatedZVolume(boolean); method public void setLayoutAnimation(android.view.animation.LayoutAnimationController); method public void setLayoutAnimationListener(android.view.animation.Animation.AnimationListener); method public void setLayoutMode(int); @@ -30459,6 +30497,14 @@ package android.view.animation { method public float getInterpolation(float); } + public class PathInterpolator implements android.view.animation.Interpolator { + ctor public PathInterpolator(android.graphics.Path); + ctor public PathInterpolator(float, float); + ctor public PathInterpolator(float, float, float, float); + ctor public PathInterpolator(android.content.Context, android.util.AttributeSet); + method public float getInterpolation(float); + } + public class RotateAnimation extends android.view.animation.Animation { ctor public RotateAnimation(android.content.Context, android.util.AttributeSet); ctor public RotateAnimation(float, float); @@ -45652,12 +45698,12 @@ package java.util.regex { public final class Matcher implements java.util.regex.MatchResult { method public java.util.regex.Matcher appendReplacement(java.lang.StringBuffer, java.lang.String); method public java.lang.StringBuffer appendTail(java.lang.StringBuffer); - method public int end(int); method public int end(); + method public int end(int); method public boolean find(int); method public boolean find(); - method public java.lang.String group(int); method public java.lang.String group(); + method public java.lang.String group(int); method public int groupCount(); method public boolean hasAnchoringBounds(); method public boolean hasTransparentBounds(); @@ -45674,8 +45720,8 @@ package java.util.regex { method public boolean requireEnd(); method public java.util.regex.Matcher reset(); method public java.util.regex.Matcher reset(java.lang.CharSequence); - method public int start(int) throws java.lang.IllegalStateException; method public int start(); + method public int start(int) throws java.lang.IllegalStateException; method public java.util.regex.MatchResult toMatchResult(); method public java.util.regex.Matcher useAnchoringBounds(boolean); method public java.util.regex.Matcher usePattern(java.util.regex.Pattern); diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index 1b028e0aab05..8fce80aa758b 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -1046,9 +1046,9 @@ public class PropertyValuesHolder implements Cloneable { static class IntPropertyValuesHolder extends PropertyValuesHolder { // Cache JNI functions to avoid looking them up twice - private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - new HashMap<Class, HashMap<String, Integer>>(); - int mJniSetter; + private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap = + new HashMap<Class, HashMap<String, Long>>(); + long mJniSetter; private IntProperty mIntProperty; IntKeyframeSet mIntKeyframeSet; @@ -1148,11 +1148,11 @@ public class PropertyValuesHolder implements Cloneable { // Check new static hashmap<propName, int> for setter method try { mPropertyMapLock.writeLock().lock(); - HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); + HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass); if (propertyMap != null) { - Integer mJniSetterInteger = propertyMap.get(mPropertyName); - if (mJniSetterInteger != null) { - mJniSetter = mJniSetterInteger; + Long jniSetter = propertyMap.get(mPropertyName); + if (jniSetter != null) { + mJniSetter = jniSetter; } } if (mJniSetter == 0) { @@ -1160,7 +1160,7 @@ public class PropertyValuesHolder implements Cloneable { mJniSetter = nGetIntMethod(targetClass, methodName); if (mJniSetter != 0) { if (propertyMap == null) { - propertyMap = new HashMap<String, Integer>(); + propertyMap = new HashMap<String, Long>(); sJNISetterPropertyMap.put(targetClass, propertyMap); } propertyMap.put(mPropertyName, mJniSetter); @@ -1183,9 +1183,9 @@ public class PropertyValuesHolder implements Cloneable { static class FloatPropertyValuesHolder extends PropertyValuesHolder { // Cache JNI functions to avoid looking them up twice - private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - new HashMap<Class, HashMap<String, Integer>>(); - int mJniSetter; + private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap = + new HashMap<Class, HashMap<String, Long>>(); + long mJniSetter; private FloatProperty mFloatProperty; FloatKeyframeSet mFloatKeyframeSet; @@ -1285,11 +1285,11 @@ public class PropertyValuesHolder implements Cloneable { // Check new static hashmap<propName, int> for setter method try { mPropertyMapLock.writeLock().lock(); - HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); + HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass); if (propertyMap != null) { - Integer mJniSetterInteger = propertyMap.get(mPropertyName); - if (mJniSetterInteger != null) { - mJniSetter = mJniSetterInteger; + Long jniSetter = propertyMap.get(mPropertyName); + if (jniSetter != null) { + mJniSetter = jniSetter; } } if (mJniSetter == 0) { @@ -1297,7 +1297,7 @@ public class PropertyValuesHolder implements Cloneable { mJniSetter = nGetFloatMethod(targetClass, methodName); if (mJniSetter != 0) { if (propertyMap == null) { - propertyMap = new HashMap<String, Integer>(); + propertyMap = new HashMap<String, Long>(); sJNISetterPropertyMap.put(targetClass, propertyMap); } propertyMap.put(mPropertyName, mJniSetter); @@ -1319,9 +1319,9 @@ public class PropertyValuesHolder implements Cloneable { } static class MultiFloatValuesHolder extends PropertyValuesHolder { - private int mJniSetter; - private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - new HashMap<Class, HashMap<String, Integer>>(); + private long mJniSetter; + private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap = + new HashMap<Class, HashMap<String, Long>>(); public MultiFloatValuesHolder(String propertyName, TypeConverter converter, TypeEvaluator evaluator, Object... values) { @@ -1389,11 +1389,11 @@ public class PropertyValuesHolder implements Cloneable { } try { mPropertyMapLock.writeLock().lock(); - HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); + HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass); if (propertyMap != null) { - Integer jniSetterInteger = propertyMap.get(mPropertyName); - if (jniSetterInteger != null) { - mJniSetter = jniSetterInteger; + Long jniSetterLong = propertyMap.get(mPropertyName); + if (jniSetterLong != null) { + mJniSetter = jniSetterLong; } } if (mJniSetter == 0) { @@ -1409,7 +1409,7 @@ public class PropertyValuesHolder implements Cloneable { } if (mJniSetter != 0) { if (propertyMap == null) { - propertyMap = new HashMap<String, Integer>(); + propertyMap = new HashMap<String, Long>(); sJNISetterPropertyMap.put(targetClass, propertyMap); } propertyMap.put(mPropertyName, mJniSetter); @@ -1422,9 +1422,9 @@ public class PropertyValuesHolder implements Cloneable { } static class MultiIntValuesHolder extends PropertyValuesHolder { - private int mJniSetter; - private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = - new HashMap<Class, HashMap<String, Integer>>(); + private long mJniSetter; + private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap = + new HashMap<Class, HashMap<String, Long>>(); public MultiIntValuesHolder(String propertyName, TypeConverter converter, TypeEvaluator evaluator, Object... values) { @@ -1492,11 +1492,11 @@ public class PropertyValuesHolder implements Cloneable { } try { mPropertyMapLock.writeLock().lock(); - HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass); + HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass); if (propertyMap != null) { - Integer jniSetterInteger = propertyMap.get(mPropertyName); - if (jniSetterInteger != null) { - mJniSetter = jniSetterInteger; + Long jniSetterLong = propertyMap.get(mPropertyName); + if (jniSetterLong != null) { + mJniSetter = jniSetterLong; } } if (mJniSetter == 0) { @@ -1512,7 +1512,7 @@ public class PropertyValuesHolder implements Cloneable { } if (mJniSetter != 0) { if (propertyMap == null) { - propertyMap = new HashMap<String, Integer>(); + propertyMap = new HashMap<String, Long>(); sJNISetterPropertyMap.put(targetClass, propertyMap); } propertyMap.put(mPropertyName, mJniSetter); @@ -1631,21 +1631,21 @@ public class PropertyValuesHolder implements Cloneable { } }; - native static private int nGetIntMethod(Class targetClass, String methodName); - native static private int nGetFloatMethod(Class targetClass, String methodName); - native static private int nGetMultipleIntMethod(Class targetClass, String methodName, + native static private long nGetIntMethod(Class targetClass, String methodName); + native static private long nGetFloatMethod(Class targetClass, String methodName); + native static private long nGetMultipleIntMethod(Class targetClass, String methodName, int numParams); - native static private int nGetMultipleFloatMethod(Class targetClass, String methodName, + native static private long nGetMultipleFloatMethod(Class targetClass, String methodName, int numParams); - native static private void nCallIntMethod(Object target, int methodID, int arg); - native static private void nCallFloatMethod(Object target, int methodID, float arg); - native static private void nCallTwoIntMethod(Object target, int methodID, int arg1, int arg2); - native static private void nCallFourIntMethod(Object target, int methodID, int arg1, int arg2, + native static private void nCallIntMethod(Object target, long methodID, int arg); + native static private void nCallFloatMethod(Object target, long methodID, float arg); + native static private void nCallTwoIntMethod(Object target, long methodID, int arg1, int arg2); + native static private void nCallFourIntMethod(Object target, long methodID, int arg1, int arg2, int arg3, int arg4); - native static private void nCallMultipleIntMethod(Object target, int methodID, int[] args); - native static private void nCallTwoFloatMethod(Object target, int methodID, float arg1, + native static private void nCallMultipleIntMethod(Object target, long methodID, int[] args); + native static private void nCallTwoFloatMethod(Object target, long methodID, float arg1, float arg2); - native static private void nCallFourFloatMethod(Object target, int methodID, float arg1, + native static private void nCallFourFloatMethod(Object target, long methodID, float arg1, float arg2, float arg3, float arg4); - native static private void nCallMultipleFloatMethod(Object target, int methodID, float[] args); + native static private void nCallMultipleFloatMethod(Object target, long methodID, float[] args); } diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 62a84219533f..e2ea76356a45 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -402,6 +402,31 @@ public class Notification implements Parcelable @Priority public int priority; + + /** + * Sphere of visibility of this notification, which affects how and when the SystemUI reveals + * the notification's presence and contents in untrusted situations (namely, on the secure + * lockscreen). + * + * The default level, {@link #VISIBILITY_PRIVATE}, behaves exactly as notifications have always + * done on Android: The notification's {@link #icon} and {@link #tickerText} (if available) are + * shown in all situations, but the contents are only available if the device is unlocked for + * the appropriate user. + * + * A more permissive policy can be expressed by {@link #VISIBILITY_PUBLIC}; such a notification + * can be read even in an "insecure" context (that is, above a secure lockscreen). + * To modify the public version of this notification—for example, to redact some portions—see + * {@link Builder#setPublicVersion(Notification)}. + * + * Finally, a notification can be made {@link #VISIBILITY_SECRET}, which will suppress its icon + * and ticker until the user has bypassed the lockscreen. + */ + public int visibility; + + public static final int VISIBILITY_PUBLIC = 1; + public static final int VISIBILITY_PRIVATE = 0; + public static final int VISIBILITY_SECRET = -1; + /** * @hide * Notification type: incoming call (voice or video) or similar synchronous communication request. @@ -549,6 +574,7 @@ public class Notification implements Parcelable * notifications, each of which was supplied to {@link InboxStyle#addLine(CharSequence)}. */ public static final String EXTRA_TEXT_LINES = "android.textLines"; + public static final String EXTRA_TEMPLATE = "android.template"; /** * {@link #extras} key: An array of people that this notification relates to, specified @@ -670,6 +696,13 @@ public class Notification implements Parcelable public Action[] actions; /** + * Replacement version of this notification whose content will be shown + * in an insecure context such as atop a secure keyguard. See {@link #visibility} + * and {@link #VISIBILITY_PUBLIC}. + */ + public Notification publicVersion; + + /** * Constructs a Notification object with default values. * You might want to consider using {@link Builder} instead. */ @@ -768,6 +801,12 @@ public class Notification implements Parcelable if (parcel.readInt() != 0) { bigContentView = RemoteViews.CREATOR.createFromParcel(parcel); } + + visibility = parcel.readInt(); + + if (parcel.readInt() != 0) { + publicVersion = Notification.CREATOR.createFromParcel(parcel); + } } @Override @@ -853,6 +892,13 @@ public class Notification implements Parcelable that.bigContentView = this.bigContentView.clone(); } + that.visibility = this.visibility; + + if (this.publicVersion != null) { + that.publicVersion = new Notification(); + this.publicVersion.cloneInto(that.publicVersion, heavy); + } + if (!heavy) { that.lightenPayload(); // will clean out extras } @@ -978,6 +1024,15 @@ public class Notification implements Parcelable } else { parcel.writeInt(0); } + + parcel.writeInt(visibility); + + if (publicVersion != null) { + parcel.writeInt(1); + publicVersion.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } } /** @@ -1181,6 +1236,8 @@ public class Notification implements Parcelable private boolean mUseChronometer; private Style mStyle; private boolean mShowWhen = true; + private int mVisibility = VISIBILITY_PRIVATE; + private Notification mPublicVersion = null; /** * Constructs a new Builder with the defaults: @@ -1627,6 +1684,30 @@ public class Notification implements Parcelable return this; } + /** + * Specify the value of {@link #visibility}. + + * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default), + * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}. + * + * @return The same Builder. + */ + public Builder setVisibility(int visibility) { + mVisibility = visibility; + return this; + } + + /** + * Supply a replacement Notification whose contents should be shown in insecure contexts + * (i.e. atop the secure lockscreen). See {@link #visibility} and {@link #VISIBILITY_PUBLIC}. + * @param n A replacement notification, presumably with some or all info redacted. + * @return The same Builder. + */ + public Builder setPublicVersion(Notification n) { + mPublicVersion = n; + return this; + } + private void setFlag(int mask, boolean value) { if (value) { mFlags |= mask; @@ -1839,6 +1920,12 @@ public class Notification implements Parcelable n.actions = new Action[mActions.size()]; mActions.toArray(n.actions); } + n.visibility = mVisibility; + + if (mPublicVersion != null) { + n.publicVersion = new Notification(); + mPublicVersion.cloneInto(n.publicVersion, true); + } return n; } @@ -1989,6 +2076,7 @@ public class Notification implements Parcelable if (mBigContentTitle != null) { extras.putCharSequence(EXTRA_TITLE_BIG, mBigContentTitle); } + extras.putString(EXTRA_TEMPLATE, this.getClass().getName()); } /** diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java index 2045ed8411a3..a6a04d11ee16 100644 --- a/core/java/android/app/StatusBarManager.java +++ b/core/java/android/app/StatusBarManager.java @@ -38,8 +38,11 @@ public class StatusBarManager { public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS; public static final int DISABLE_NOTIFICATION_ALERTS = View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS; + @Deprecated public static final int DISABLE_NOTIFICATION_TICKER = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER; + public static final int DISABLE_PRIVATE_NOTIFICATIONS + = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER; public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO; public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME; public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT; diff --git a/core/java/android/app/maintenance/IIdleCallback.aidl b/core/java/android/app/maintenance/IIdleCallback.aidl new file mode 100644 index 000000000000..582dede9574c --- /dev/null +++ b/core/java/android/app/maintenance/IIdleCallback.aidl @@ -0,0 +1,53 @@ +/** + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.maintenance; + +import android.app.maintenance.IIdleService; + +/** + * The server side of the idle maintenance IPC protocols. The app-side implementation + * invokes on this interface to indicate completion of the (asynchronous) instructions + * issued by the server. + * + * In all cases, the 'who' parameter is the caller's service binder, used to track + * which idle service instance is reporting. + * + * {@hide} + */ +interface IIdleCallback { + /** + * Acknowledge receipt and processing of the asynchronous "start idle work" incall. + * 'result' is true if the app wants some time to perform ongoing background + * idle-time work; or false if the app declares that it does not need any time + * for such work. + */ + void acknowledgeStart(int token, boolean result); + + /** + * Acknowledge receipt and processing of the asynchronous "stop idle work" incall. + */ + void acknowledgeStop(int token); + + /* + * Tell the idle service manager that we're done with our idle maintenance, so that + * it can go on to the next one and stop attributing wakelock time to us etc. + * + * @param opToken The identifier passed in the startIdleMaintenance() call that + * indicated the beginning of this service's idle timeslice. + */ + void idleFinished(int token); +} diff --git a/core/java/android/app/maintenance/IIdleService.aidl b/core/java/android/app/maintenance/IIdleService.aidl new file mode 100644 index 000000000000..54abccdc1b4f --- /dev/null +++ b/core/java/android/app/maintenance/IIdleService.aidl @@ -0,0 +1,34 @@ +/** + * Copyright 2014, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.maintenance; + +import android.app.maintenance.IIdleCallback; + +/** + * Interface that the framework uses to communicate with application code + * that implements an idle-time "maintenance" service. End user code does + * not implement this interface directly; instead, the app's idle service + * implementation will extend android.app.maintenance.IdleService. + * {@hide} + */ +oneway interface IIdleService { + /** + * Begin your idle-time work. + */ + void startIdleMaintenance(IIdleCallback callbackBinder, int token); + void stopIdleMaintenance(IIdleCallback callbackBinder, int token); +} diff --git a/core/java/android/app/maintenance/IdleService.java b/core/java/android/app/maintenance/IdleService.java new file mode 100644 index 000000000000..2331b81aba1b --- /dev/null +++ b/core/java/android/app/maintenance/IdleService.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app.maintenance; + +import android.annotation.SdkConstant; +import android.annotation.SdkConstant.SdkConstantType; +import android.app.Service; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.RemoteException; +import android.util.Log; +import android.util.Slog; + +/** + * Idle maintenance API. Full docs TBW (to be written). + */ +public abstract class IdleService extends Service { + private static final String TAG = "IdleService"; + + static final int MSG_START = 1; + static final int MSG_STOP = 2; + static final int MSG_FINISH = 3; + + IdleHandler mHandler; + IIdleCallback mCallbackBinder; + int mToken; + final Object mHandlerLock = new Object(); + + void ensureHandler() { + synchronized (mHandlerLock) { + if (mHandler == null) { + mHandler = new IdleHandler(getMainLooper()); + } + } + } + + /** + * TBW: the idle service should supply an intent-filter handling this intent + * <p> + * <p class="note">The application must also protect the idle service with the + * {@code "android.permission.BIND_IDLE_SERVICE"} permission to ensure that other + * applications cannot maliciously bind to it. If an idle service's manifest + * declaration does not require that permission, it will never be invoked. + * </p> + */ + @SdkConstant(SdkConstantType.SERVICE_ACTION) + public static final String SERVICE_INTERFACE = + "android.service.idle.IdleService"; + + /** + * Idle services must be protected with this permission: + * + * <pre class="prettyprint"> + * <service android:name="MyIdleService" + * android:permission="android.permission.BIND_IDLE_SERVICE" > + * ... + * </service> + * </pre> + * + * <p>If an idle service is declared in the manifest but not protected with this + * permission, that service will be ignored by the OS. + */ + public static final String PERMISSION_BIND = + "android.permission.BIND_IDLE_SERVICE"; + + // Trampoline: the callbacks are always run on the main thread + IIdleService mBinder = new IIdleService.Stub() { + @Override + public void startIdleMaintenance(IIdleCallback callbackBinder, int token) + throws RemoteException { + ensureHandler(); + Message msg = mHandler.obtainMessage(MSG_START, token, 0, callbackBinder); + mHandler.sendMessage(msg); + } + + @Override + public void stopIdleMaintenance(IIdleCallback callbackBinder, int token) + throws RemoteException { + ensureHandler(); + Message msg = mHandler.obtainMessage(MSG_STOP, token, 0, callbackBinder); + mHandler.sendMessage(msg); + } + }; + + /** + * Your application may begin doing "idle" maintenance work in the background. + * <p> + * Your application may continue to run in the background until it receives a call + * to {@link #onIdleStop()}, at which point you <i>must</i> cease doing work. The + * OS will hold a wakelock on your application's behalf from the time this method is + * called until after the following call to {@link #onIdleStop()} returns. + * </p> + * <p> + * Returning {@code false} from this method indicates that you have no ongoing work + * to do at present. The OS will respond by immediately calling {@link #onIdleStop()} + * and returning your application to its normal stopped state. Returning {@code true} + * indicates that the application is indeed performing ongoing work, so the OS will + * let your application run in this state until it's no longer appropriate. + * </p> + * <p> + * You will always receive a matching call to {@link #onIdleStop()} even if your + * application returns {@code false} from this method. + * + * @return {@code true} to indicate that the application wishes to perform some ongoing + * background work; {@code false} to indicate that it does not need to perform such + * work at present. + */ + public abstract boolean onIdleStart(); + + /** + * Your app's maintenance opportunity is over. Once the application returns from + * this method, the wakelock held by the OS on its behalf will be released. + */ + public abstract void onIdleStop(); + + /** + * Tell the OS that you have finished your idle work. Calling this more than once, + * or calling it when you have not received an {@link #onIdleStart()} callback, is + * an error. + * + * <p>It is safe to call {@link #finishIdle()} from any thread. + */ + public final void finishIdle() { + ensureHandler(); + mHandler.sendEmptyMessage(MSG_FINISH); + } + + class IdleHandler extends Handler { + IdleHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_START: { + // Call the concrete onIdleStart(), reporting its return value back to + // the OS. If onIdleStart() throws, report it as a 'false' return but + // rethrow the exception at the offending app. + boolean result = false; + IIdleCallback callbackBinder = (IIdleCallback) msg.obj; + mCallbackBinder = callbackBinder; + final int token = mToken = msg.arg1; + try { + result = IdleService.this.onIdleStart(); + } catch (Exception e) { + Log.e(TAG, "Unable to start idle workload", e); + throw new RuntimeException(e); + } finally { + // don't bother if the service already called finishIdle() + if (mCallbackBinder != null) { + try { + callbackBinder.acknowledgeStart(token, result); + } catch (RemoteException re) { + Log.e(TAG, "System unreachable to start idle workload"); + } + } + } + break; + } + + case MSG_STOP: { + // Structured just like MSG_START for the stop-idle bookend call. + IIdleCallback callbackBinder = (IIdleCallback) msg.obj; + final int token = msg.arg1; + try { + IdleService.this.onIdleStop(); + } catch (Exception e) { + Log.e(TAG, "Unable to stop idle workload", e); + throw new RuntimeException(e); + } finally { + if (mCallbackBinder != null) { + try { + callbackBinder.acknowledgeStop(token); + } catch (RemoteException re) { + Log.e(TAG, "System unreachable to stop idle workload"); + } + } + } + break; + } + + case MSG_FINISH: { + if (mCallbackBinder != null) { + try { + mCallbackBinder.idleFinished(mToken); + } catch (RemoteException e) { + Log.e(TAG, "System unreachable to finish idling"); + } finally { + mCallbackBinder = null; + } + } else { + Log.e(TAG, "finishIdle() called but the idle service is not started"); + } + break; + } + + default: { + Slog.w(TAG, "Unknown message " + msg.what); + } + } + } + } + + /** @hide */ + @Override + public final IBinder onBind(Intent intent) { + return mBinder.asBinder(); + } + +} diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 9f3b682ecc6a..3fdb6e722132 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3547,6 +3547,11 @@ public class Intent implements Parcelable, Cloneable { * it will be finished so that the user does not return to them, but * instead returns to whatever activity preceeded it. * + * <p>When this flag is assigned to the root activity all activities up + * to, but not including the root activity, will be cleared. This prevents + * this flag from being used to finish all activities in a task and thereby + * ending the task. + * * <p>This is useful for cases where you have a logical break in your * application. For example, an e-mail application may have a command * to view an attachment, which launches an image view activity to diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 8944dcb9a6fb..276e19b4666d 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -68,13 +68,13 @@ public final class AssetManager { private final long[] mOffsets = new long[2]; // For communication with native code. - private int mObject; + private long mObject; private StringBlock mStringBlocks[] = null; private int mNumRefs = 1; private boolean mOpen = true; - private HashMap<Integer, RuntimeException> mRefStacks; + private HashMap<Long, RuntimeException> mRefStacks; /** * Create a new AssetManager containing only the basic system assets. @@ -223,7 +223,7 @@ public final class AssetManager { return retArray; } - /*package*/ final boolean getThemeValue(int theme, int ident, + /*package*/ final boolean getThemeValue(long theme, int ident, TypedValue outValue, boolean resolveRefs) { int block = loadThemeAttributeValue(theme, ident, outValue, resolveRefs); if (block >= 0) { @@ -311,7 +311,7 @@ public final class AssetManager { if (!mOpen) { throw new RuntimeException("Assetmanager has been closed"); } - int asset = openAsset(fileName, accessMode); + long asset = openAsset(fileName, accessMode); if (asset != 0) { AssetInputStream res = new AssetInputStream(asset); incRefsLocked(res.hashCode()); @@ -403,7 +403,7 @@ public final class AssetManager { if (!mOpen) { throw new RuntimeException("Assetmanager has been closed"); } - int asset = openNonAssetNative(cookie, fileName, accessMode); + long asset = openNonAssetNative(cookie, fileName, accessMode); if (asset != 0) { AssetInputStream res = new AssetInputStream(asset); incRefsLocked(res.hashCode()); @@ -483,7 +483,7 @@ public final class AssetManager { if (!mOpen) { throw new RuntimeException("Assetmanager has been closed"); } - int xmlBlock = openXmlAssetNative(cookie, fileName); + long xmlBlock = openXmlAssetNative(cookie, fileName); if (xmlBlock != 0) { XmlBlock res = new XmlBlock(this, xmlBlock); incRefsLocked(res.hashCode()); @@ -499,18 +499,18 @@ public final class AssetManager { } } - /*package*/ final int createTheme() { + /*package*/ final long createTheme() { synchronized (this) { if (!mOpen) { throw new RuntimeException("Assetmanager has been closed"); } - int res = newTheme(); + long res = newTheme(); incRefsLocked(res); return res; } } - /*package*/ final void releaseTheme(int theme) { + /*package*/ final void releaseTheme(long theme) { synchronized (this) { deleteTheme(theme); decRefsLocked(theme); @@ -539,7 +539,7 @@ public final class AssetManager { * @hide */ public final int getAssetInt() { - return mAsset; + return (int) mAsset; } /** * @hide @@ -547,7 +547,7 @@ public final class AssetManager { public final long getNativeAsset() { return mAsset; } - private AssetInputStream(int asset) + private AssetInputStream(long asset) { mAsset = asset; mLength = getAssetLength(asset); @@ -599,7 +599,7 @@ public final class AssetManager { close(); } - private int mAsset; + private long mAsset; private long mLength; private long mMarkPos; } @@ -680,19 +680,19 @@ public final class AssetManager { /*package*/ native final String getResourceTypeName(int resid); /*package*/ native final String getResourceEntryName(int resid); - private native final int openAsset(String fileName, int accessMode); + private native final long openAsset(String fileName, int accessMode); private final native ParcelFileDescriptor openAssetFd(String fileName, long[] outOffsets) throws IOException; - private native final int openNonAssetNative(int cookie, String fileName, + private native final long openNonAssetNative(int cookie, String fileName, int accessMode); private native ParcelFileDescriptor openNonAssetFdNative(int cookie, String fileName, long[] outOffsets) throws IOException; - private native final void destroyAsset(int asset); - private native final int readAssetChar(int asset); - private native final int readAsset(int asset, byte[] b, int off, int len); - private native final long seekAsset(int asset, long offset, int whence); - private native final long getAssetLength(int asset); - private native final long getAssetRemainingLength(int asset); + private native final void destroyAsset(long asset); + private native final int readAssetChar(long asset); + private native final int readAsset(long asset, byte[] b, int off, int len); + private native final long seekAsset(long asset, long offset, int whence); + private native final long getAssetLength(long asset); + private native final long getAssetRemainingLength(long asset); /** Returns true if the resource was found, filling in mRetStringBlock and * mRetData. */ @@ -709,15 +709,15 @@ public final class AssetManager { /*package*/ static final int STYLE_RESOURCE_ID = 3; /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4; /*package*/ static final int STYLE_DENSITY = 5; - /*package*/ native static final boolean applyStyle(int theme, - int defStyleAttr, int defStyleRes, int xmlParser, + /*package*/ native static final boolean applyStyle(long theme, + int defStyleAttr, int defStyleRes, long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); /*package*/ native final boolean retrieveAttributes( - int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); + long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices); /*package*/ native final int getArraySize(int resource); /*package*/ native final int retrieveArray(int resource, int[] outValues); private native final int getStringBlockCount(); - private native final int getNativeStringBlock(int block); + private native final long getNativeStringBlock(int block); /** * {@hide} @@ -739,16 +739,16 @@ public final class AssetManager { */ public native static final int getGlobalAssetManagerCount(); - private native final int newTheme(); - private native final void deleteTheme(int theme); - /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force); - /*package*/ native static final void copyTheme(int dest, int source); - /*package*/ native static final int loadThemeAttributeValue(int theme, int ident, + private native final long newTheme(); + private native final void deleteTheme(long theme); + /*package*/ native static final void applyThemeStyle(long theme, int styleRes, boolean force); + /*package*/ native static final void copyTheme(long dest, long source); + /*package*/ native static final int loadThemeAttributeValue(long theme, int ident, TypedValue outValue, boolean resolve); - /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix); + /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix); - private native final int openXmlAssetNative(int cookie, String fileName); + private native final long openXmlAssetNative(int cookie, String fileName); private native final String[] getArrayStringResource(int arrayRes); private native final int[] getArrayStringInfo(int arrayRes); @@ -757,19 +757,19 @@ public final class AssetManager { private native final void init(); private native final void destroy(); - private final void incRefsLocked(int id) { + private final void incRefsLocked(long id) { if (DEBUG_REFS) { if (mRefStacks == null) { - mRefStacks = new HashMap<Integer, RuntimeException>(); - RuntimeException ex = new RuntimeException(); - ex.fillInStackTrace(); - mRefStacks.put(this.hashCode(), ex); + mRefStacks = new HashMap<Long, RuntimeException>(); } + RuntimeException ex = new RuntimeException(); + ex.fillInStackTrace(); + mRefStacks.put(id, ex); } mNumRefs++; } - private final void decRefsLocked(int id) { + private final void decRefsLocked(long id) { if (DEBUG_REFS && mRefStacks != null) { mRefStacks.remove(id); } diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index eb41ee9ecb1f..185bfd8f7299 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -71,16 +71,19 @@ import libcore.icu.NativePluralRules; */ public class Resources { static final String TAG = "Resources"; + private static final boolean DEBUG_LOAD = false; private static final boolean DEBUG_CONFIG = false; private static final boolean DEBUG_ATTRIBUTES_CACHE = false; private static final boolean TRACE_FOR_PRELOAD = false; private static final boolean TRACE_FOR_MISS_PRELOAD = false; + private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative( + ActivityInfo.CONFIG_LAYOUT_DIRECTION); + private static final int ID_OTHER = 0x01000004; private static final Object sSync = new Object(); - /*package*/ static Resources mSystem = null; // Information about preloaded resources. Note that they are not // protected by a lock, because while preloading in zygote we are all @@ -91,32 +94,35 @@ public class Resources { private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists = new LongSparseArray<ColorStateList>(); + // Used by BridgeResources in layoutlib + static Resources mSystem = null; + private static boolean sPreloaded; private static int sPreloadedDensity; // These are protected by mAccessLock. + private final Object mAccessLock = new Object(); + private final Configuration mTmpConfig = new Configuration(); + private final LongSparseArray<WeakReference<Drawable.ConstantState>> mDrawableCache + = new LongSparseArray<WeakReference<Drawable.ConstantState>>(0); + private final LongSparseArray<WeakReference<ColorStateList>> mColorStateListCache + = new LongSparseArray<WeakReference<ColorStateList>>(0); + private final LongSparseArray<WeakReference<Drawable.ConstantState>> mColorDrawableCache + = new LongSparseArray<WeakReference<Drawable.ConstantState>>(0); - /*package*/ final Object mAccessLock = new Object(); - /*package*/ final Configuration mTmpConfig = new Configuration(); - /*package*/ TypedValue mTmpValue = new TypedValue(); - /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache - = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0); - /*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache - = new LongSparseArray<WeakReference<ColorStateList> >(0); - /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache - = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0); - /*package*/ boolean mPreloading; + private TypedValue mTmpValue = new TypedValue(); + private boolean mPreloading; - /*package*/ TypedArray mCachedStyledAttributes = null; - RuntimeException mLastRetrievedAttrs = null; + private TypedArray mCachedStyledAttributes = null; + private RuntimeException mLastRetrievedAttrs = null; private int mLastCachedXmlBlockIndex = -1; private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 }; private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4]; - /*package*/ final AssetManager mAssets; + private final AssetManager mAssets; private final Configuration mConfiguration = new Configuration(); - /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics(); + private final DisplayMetrics mMetrics = new DisplayMetrics(); private NativePluralRules mPluralRule; private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; @@ -1459,7 +1465,7 @@ public class Resources { } private final AssetManager mAssets; - private final int mTheme; + private final long mTheme; } /** @@ -2022,9 +2028,6 @@ public class Resources { return true; } - static private final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative( - ActivityInfo.CONFIG_LAYOUT_DIRECTION); - /*package*/ Drawable loadDrawable(TypedValue value, int id) throws NotFoundException { @@ -2365,6 +2368,16 @@ public class Resources { + Integer.toHexString(id)); } + /*package*/ void recycleCachedStyledAttributes(TypedArray attrs) { + synchronized (mAccessLock) { + final TypedArray cached = mCachedStyledAttributes; + if (cached == null || cached.mData.length < attrs.mData.length) { + attrs.mXml = null; + mCachedStyledAttributes = attrs; + } + } + } + private TypedArray getCachedStyledAttributes(int len) { synchronized (mAccessLock) { TypedArray attrs = mCachedStyledAttributes; diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java index 78180b1c69a9..77b8a3314148 100644 --- a/core/java/android/content/res/StringBlock.java +++ b/core/java/android/content/res/StringBlock.java @@ -36,7 +36,7 @@ final class StringBlock { private static final String TAG = "AssetManager"; private static final boolean localLOGV = false; - private final int mNative; + private final long mNative; private final boolean mUseSparse; private final boolean mOwnsNative; private CharSequence[] mStrings; @@ -474,7 +474,7 @@ final class StringBlock { * are doing! The given native object must exist for the entire lifetime * of this newly creating StringBlock. */ - StringBlock(int obj, boolean useSparse) { + StringBlock(long obj, boolean useSparse) { mNative = obj; mUseSparse = useSparse; mOwnsNative = false; @@ -482,11 +482,11 @@ final class StringBlock { + ": " + nativeGetSize(mNative)); } - private static native int nativeCreate(byte[] data, + private static native long nativeCreate(byte[] data, int offset, int size); - private static native int nativeGetSize(int obj); - private static native String nativeGetString(int obj, int idx); - private static native int[] nativeGetStyle(int obj, int idx); - private static native void nativeDestroy(int obj); + private static native int nativeGetSize(long obj); + private static native String nativeGetString(long obj, int idx); + private static native int[] nativeGetStyle(long obj, int idx); + private static native void nativeDestroy(long obj); } diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 4b9680067718..87d65a5e84f2 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -37,6 +37,8 @@ import java.util.Arrays; */ public class TypedArray { private final Resources mResources; + private final DisplayMetrics mMetrics; + private final AssetManager mAssets; /*package*/ XmlBlock.Parser mXml; /*package*/ int[] mRsrcs; /*package*/ int[] mData; @@ -392,7 +394,7 @@ public class TypedArray { return defValue; } else if (type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimension( - data[index+AssetManager.STYLE_DATA], mResources.mMetrics); + data[index+AssetManager.STYLE_DATA], mMetrics); } throw new UnsupportedOperationException("Can't convert to dimension: type=0x" @@ -424,7 +426,7 @@ public class TypedArray { return defValue; } else if (type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelOffset( - data[index+AssetManager.STYLE_DATA], mResources.mMetrics); + data[index+AssetManager.STYLE_DATA], mMetrics); } throw new UnsupportedOperationException("Can't convert to dimension: type=0x" @@ -457,7 +459,7 @@ public class TypedArray { return defValue; } else if (type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelSize( - data[index+AssetManager.STYLE_DATA], mResources.mMetrics); + data[index+AssetManager.STYLE_DATA], mMetrics); } throw new UnsupportedOperationException("Can't convert to dimension: type=0x" @@ -485,7 +487,7 @@ public class TypedArray { return data[index+AssetManager.STYLE_DATA]; } else if (type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelSize( - data[index+AssetManager.STYLE_DATA], mResources.mMetrics); + data[index+AssetManager.STYLE_DATA], mMetrics); } throw new RuntimeException(getPositionDescription() @@ -514,7 +516,7 @@ public class TypedArray { return data[index+AssetManager.STYLE_DATA]; } else if (type == TypedValue.TYPE_DIMENSION) { return TypedValue.complexToDimensionPixelSize( - data[index+AssetManager.STYLE_DATA], mResources.mMetrics); + data[index+AssetManager.STYLE_DATA], mMetrics); } return defValue; @@ -687,13 +689,7 @@ public class TypedArray { * Give back a previously retrieved array, for later re-use. */ public void recycle() { - synchronized (mResources.mAccessLock) { - TypedArray cached = mResources.mCachedStyledAttributes; - if (cached == null || cached.mData.length < mData.length) { - mXml = null; - mResources.mCachedStyledAttributes = this; - } - } + mResources.recycleCachedStyledAttributes(this); } private boolean getValueAt(int index, TypedValue outValue) { @@ -722,18 +718,19 @@ public class TypedArray { } return null; } - //System.out.println("Getting pooled from: " + v); - return mResources.mAssets.getPooledString( - cookie, data[index+AssetManager.STYLE_DATA]); + return mAssets.getPooledString(cookie, data[index+AssetManager.STYLE_DATA]); } /*package*/ TypedArray(Resources resources, int[] data, int[] indices, int len) { mResources = resources; + mMetrics = mResources.getDisplayMetrics(); + mAssets = mResources.getAssets(); mData = data; mIndices = indices; mLength = len; } + @Override public String toString() { return Arrays.toString(mData); } diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java index bea652911789..3ad357f28704 100644 --- a/core/java/android/content/res/XmlBlock.java +++ b/core/java/android/content/res/XmlBlock.java @@ -75,7 +75,7 @@ final class XmlBlock { } /*package*/ final class Parser implements XmlResourceParser { - Parser(int parseState, XmlBlock block) { + Parser(long parseState, XmlBlock block) { mParseState = parseState; mBlock = block; block.mOpenCount++; @@ -458,7 +458,7 @@ final class XmlBlock { return mStrings.get(id); } - /*package*/ int mParseState; + /*package*/ long mParseState; private final XmlBlock mBlock; private boolean mStarted = false; private boolean mDecNextDepth = false; @@ -476,41 +476,41 @@ final class XmlBlock { * are doing! The given native object must exist for the entire lifetime * of this newly creating XmlBlock. */ - XmlBlock(AssetManager assets, int xmlBlock) { + XmlBlock(AssetManager assets, long xmlBlock) { mAssets = assets; mNative = xmlBlock; mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false); } private final AssetManager mAssets; - private final int mNative; + private final long mNative; /*package*/ final StringBlock mStrings; private boolean mOpen = true; private int mOpenCount = 1; - private static final native int nativeCreate(byte[] data, + private static final native long nativeCreate(byte[] data, int offset, int size); - private static final native int nativeGetStringBlock(int obj); + private static final native long nativeGetStringBlock(long obj); - private static final native int nativeCreateParseState(int obj); - /*package*/ static final native int nativeNext(int state); - private static final native int nativeGetNamespace(int state); - /*package*/ static final native int nativeGetName(int state); - private static final native int nativeGetText(int state); - private static final native int nativeGetLineNumber(int state); - private static final native int nativeGetAttributeCount(int state); - private static final native int nativeGetAttributeNamespace(int state, int idx); - private static final native int nativeGetAttributeName(int state, int idx); - private static final native int nativeGetAttributeResource(int state, int idx); - private static final native int nativeGetAttributeDataType(int state, int idx); - private static final native int nativeGetAttributeData(int state, int idx); - private static final native int nativeGetAttributeStringValue(int state, int idx); - private static final native int nativeGetIdAttribute(int state); - private static final native int nativeGetClassAttribute(int state); - private static final native int nativeGetStyleAttribute(int state); - private static final native int nativeGetAttributeIndex(int state, String namespace, String name); - private static final native void nativeDestroyParseState(int state); + private static final native long nativeCreateParseState(long obj); + /*package*/ static final native int nativeNext(long state); + private static final native int nativeGetNamespace(long state); + /*package*/ static final native int nativeGetName(long state); + private static final native int nativeGetText(long state); + private static final native int nativeGetLineNumber(long state); + private static final native int nativeGetAttributeCount(long state); + private static final native int nativeGetAttributeNamespace(long state, int idx); + private static final native int nativeGetAttributeName(long state, int idx); + private static final native int nativeGetAttributeResource(long state, int idx); + private static final native int nativeGetAttributeDataType(long state, int idx); + private static final native int nativeGetAttributeData(long state, int idx); + private static final native int nativeGetAttributeStringValue(long state, int idx); + private static final native int nativeGetIdAttribute(long state); + private static final native int nativeGetClassAttribute(long state); + private static final native int nativeGetStyleAttribute(long state); + private static final native int nativeGetAttributeIndex(long state, String namespace, String name); + private static final native void nativeDestroyParseState(long state); - private static final native void nativeDestroy(int obj); + private static final native void nativeDestroy(long obj); } diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index 495bf51301d0..44caa6e478cb 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -262,13 +262,13 @@ public final class CameraCharacteristics extends CameraMetadata { new Key<Integer>("android.control.maxRegions", int.class); /** - * <p>Whether this camera has a - * flash</p> + * <p>Whether this camera device has a + * flash.</p> * <p>If no flash, none of the flash controls do - * anything. All other metadata should return 0</p> + * anything. All other metadata should return 0.</p> */ - public static final Key<Byte> FLASH_INFO_AVAILABLE = - new Key<Byte>("android.flash.info.available", byte.class); + public static final Key<Boolean> FLASH_INFO_AVAILABLE = + new Key<Boolean>("android.flash.info.available", boolean.class); /** * <p>Supported resolutions for the JPEG thumbnail</p> @@ -515,8 +515,9 @@ public final class CameraCharacteristics extends CameraMetadata { /** * <p>Area of raw data which corresponds to only - * active pixels; smaller or equal to - * pixelArraySize.</p> + * active pixels.</p> + * <p>It is smaller or equal to + * sensor full pixel array, which could include the black calibration pixels.</p> */ public static final Key<android.graphics.Rect> SENSOR_INFO_ACTIVE_ARRAY_SIZE = new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class); @@ -569,11 +570,11 @@ public final class CameraCharacteristics extends CameraMetadata { /** * <p>Maximum sensitivity that is implemented - * purely through analog gain</p> + * purely through analog gain.</p> * <p>For {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} values less than or * equal to this, all applied gain must be analog. For - * values above this, it can be a mix of analog and - * digital</p> + * values above this, the gain applied can be a mix of analog and + * digital.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Full capability</b> - * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index e839be32c178..a1f432db809f 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -1372,22 +1372,28 @@ public abstract class CameraMetadata { public static final int FLASH_STATE_UNAVAILABLE = 0; /** - * <p>if android.flash.available is true Flash is + * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash is * charging and cannot be fired</p> + * + * @see CameraCharacteristics#FLASH_INFO_AVAILABLE * @see CaptureResult#FLASH_STATE */ public static final int FLASH_STATE_CHARGING = 1; /** - * <p>if android.flash.available is true Flash is + * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash is * ready to fire</p> + * + * @see CameraCharacteristics#FLASH_INFO_AVAILABLE * @see CaptureResult#FLASH_STATE */ public static final int FLASH_STATE_READY = 2; /** - * <p>if android.flash.available is true Flash fired + * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash fired * for this capture</p> + * + * @see CameraCharacteristics#FLASH_INFO_AVAILABLE * @see CaptureResult#FLASH_STATE */ public static final int FLASH_STATE_FIRED = 3; @@ -1397,11 +1403,21 @@ public abstract class CameraMetadata { // /** + * <p>The lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, android.lens.focusDistance + * android.lens.filterDensity and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) are not changing.</p> + * + * @see CaptureRequest#LENS_APERTURE + * @see CaptureRequest#LENS_FOCAL_LENGTH * @see CaptureResult#LENS_STATE */ public static final int LENS_STATE_STATIONARY = 0; /** + * <p>Any of the lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, android.lens.focusDistance + * android.lens.filterDensity or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is changing.</p> + * + * @see CaptureRequest#LENS_APERTURE + * @see CaptureRequest#LENS_FOCAL_LENGTH * @see CaptureResult#LENS_STATE */ public static final int LENS_STATE_MOVING = 1; diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java index 56508e8e5e79..0988c629a4b4 100644 --- a/core/java/android/hardware/camera2/CaptureRequest.java +++ b/core/java/android/hardware/camera2/CaptureRequest.java @@ -826,7 +826,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { /** * <p>The desired mode for for the camera device's flash control.</p> * <p>This control is only effective when flash unit is available - * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} != 0</code>).</p> + * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == true</code>).</p> * <p>When this control is used, the {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} must be set to ON or OFF. * Otherwise, the camera device auto-exposure related flash control (ON_AUTO_FLASH, * ON_ALWAYS_FLASH, or ON_AUTO_FLASH_REDEYE) will override this control.</p> @@ -837,10 +837,12 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * ({@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}), otherwise, the image may be incorrectly exposed.</p> * <p>When set to TORCH, the flash will be on continuously. This mode can be used * for use cases such as preview, auto-focus assist, still capture, or video recording.</p> + * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p> * * @see CaptureRequest#CONTROL_AE_MODE * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER * @see CameraCharacteristics#FLASH_INFO_AVAILABLE + * @see CaptureResult#FLASH_STATE * @see #FLASH_MODE_OFF * @see #FLASH_MODE_SINGLE * @see #FLASH_MODE_TORCH @@ -913,7 +915,8 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * to achieve manual exposure control.</p> * <p>The requested aperture value may take several frames to reach the * requested value; the camera device will report the current (intermediate) - * aperture size in capture result metadata while the aperture is changing.</p> + * aperture size in capture result metadata while the aperture is changing. + * While the aperture is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p> * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of * the ON modes, this will be overridden by the camera device * auto-exposure algorithm, the overridden values are then provided @@ -921,6 +924,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * * @see CaptureRequest#CONTROL_AE_MODE * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES + * @see CaptureResult#LENS_STATE * @see CaptureRequest#SENSOR_EXPOSURE_TIME * @see CaptureRequest#SENSOR_SENSITIVITY */ @@ -940,8 +944,12 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * in no reduction of the incoming light, and setting this to 2 would * mean that the filter is set to reduce incoming light by two stops * (allowing 1/4 of the prior amount of light to the sensor).</p> + * <p>It may take several frames before the lens filter density changes + * to the requested value. While the filter density is still changing, + * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p> * * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES + * @see CaptureResult#LENS_STATE */ public static final Key<Float> LENS_FILTER_DENSITY = new Key<Float>("android.lens.filterDensity", float.class); @@ -953,7 +961,7 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { * view of the camera device, and is usually used for optical zoom.</p> * <p>Like {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, this * setting won't be applied instantaneously, and it may take several - * frames before the lens can move to the requested focal length. + * frames before the lens can change to the requested focal length. * While the focal length is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will * be set to MOVING.</p> * <p>This is expected not to be supported on most devices.</p> @@ -968,8 +976,16 @@ public final class CaptureRequest extends CameraMetadata implements Parcelable { /** * <p>Distance to plane of sharpest focus, * measured from frontmost surface of the lens</p> - * <p>0 = infinity focus. Used value should be clamped - * to (0,minimum focus distance)</p> + * <p>0 means infinity focus. Used value will be clamped + * to [0, {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance}].</p> + * <p>Like {@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, this setting won't be applied + * instantaneously, and it may take several frames before the lens + * can move to the requested focus distance. While the lens is still moving, + * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p> + * + * @see CaptureRequest#LENS_FOCAL_LENGTH + * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE + * @see CaptureResult#LENS_STATE */ public static final Key<Float> LENS_FOCUS_DISTANCE = new Key<Float>("android.lens.focusDistance", float.class); diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 0ded5bd2a3e7..1f65c1980934 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -965,7 +965,7 @@ public final class CaptureResult extends CameraMetadata { /** * <p>The desired mode for for the camera device's flash control.</p> * <p>This control is only effective when flash unit is available - * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} != 0</code>).</p> + * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == true</code>).</p> * <p>When this control is used, the {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} must be set to ON or OFF. * Otherwise, the camera device auto-exposure related flash control (ON_AUTO_FLASH, * ON_ALWAYS_FLASH, or ON_AUTO_FLASH_REDEYE) will override this control.</p> @@ -976,10 +976,12 @@ public final class CaptureResult extends CameraMetadata { * ({@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}), otherwise, the image may be incorrectly exposed.</p> * <p>When set to TORCH, the flash will be on continuously. This mode can be used * for use cases such as preview, auto-focus assist, still capture, or video recording.</p> + * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p> * * @see CaptureRequest#CONTROL_AE_MODE * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER * @see CameraCharacteristics#FLASH_INFO_AVAILABLE + * @see CaptureResult#FLASH_STATE * @see #FLASH_MODE_OFF * @see #FLASH_MODE_SINGLE * @see #FLASH_MODE_TORCH @@ -989,7 +991,12 @@ public final class CaptureResult extends CameraMetadata { /** * <p>Current state of the flash - * unit</p> + * unit.</p> + * <p>When the camera device doesn't have flash unit + * (i.e. <code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == false</code>), this state will always be UNAVAILABLE. + * Other states indicate the current flash status.</p> + * + * @see CameraCharacteristics#FLASH_INFO_AVAILABLE * @see #FLASH_STATE_UNAVAILABLE * @see #FLASH_STATE_CHARGING * @see #FLASH_STATE_READY @@ -1063,7 +1070,8 @@ public final class CaptureResult extends CameraMetadata { * to achieve manual exposure control.</p> * <p>The requested aperture value may take several frames to reach the * requested value; the camera device will report the current (intermediate) - * aperture size in capture result metadata while the aperture is changing.</p> + * aperture size in capture result metadata while the aperture is changing. + * While the aperture is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p> * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of * the ON modes, this will be overridden by the camera device * auto-exposure algorithm, the overridden values are then provided @@ -1071,6 +1079,7 @@ public final class CaptureResult extends CameraMetadata { * * @see CaptureRequest#CONTROL_AE_MODE * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES + * @see CaptureResult#LENS_STATE * @see CaptureRequest#SENSOR_EXPOSURE_TIME * @see CaptureRequest#SENSOR_SENSITIVITY */ @@ -1090,8 +1099,12 @@ public final class CaptureResult extends CameraMetadata { * in no reduction of the incoming light, and setting this to 2 would * mean that the filter is set to reduce incoming light by two stops * (allowing 1/4 of the prior amount of light to the sensor).</p> + * <p>It may take several frames before the lens filter density changes + * to the requested value. While the filter density is still changing, + * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p> * * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES + * @see CaptureResult#LENS_STATE */ public static final Key<Float> LENS_FILTER_DENSITY = new Key<Float>("android.lens.filterDensity", float.class); @@ -1103,7 +1116,7 @@ public final class CaptureResult extends CameraMetadata { * view of the camera device, and is usually used for optical zoom.</p> * <p>Like {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, this * setting won't be applied instantaneously, and it may take several - * frames before the lens can move to the requested focal length. + * frames before the lens can change to the requested focal length. * While the focal length is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will * be set to MOVING.</p> * <p>This is expected not to be supported on most devices.</p> @@ -1148,7 +1161,35 @@ public final class CaptureResult extends CameraMetadata { new Key<Integer>("android.lens.opticalStabilizationMode", int.class); /** - * <p>Current lens status</p> + * <p>Current lens status.</p> + * <p>For lens parameters {@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance}, + * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, when changes are requested, + * they may take several frames to reach the requested values. This state indicates + * the current status of the lens parameters.</p> + * <p>When the state is STATIONARY, the lens parameters are not changing. This could be + * either because the parameters are all fixed, or because the lens has had enough + * time to reach the most recently-requested values. + * If all these lens parameters are not changable for a camera device, as listed below:</p> + * <ul> + * <li>Fixed focus (<code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} == 0</code>), which means + * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} parameter will always be 0.</li> + * <li>Fixed focal length ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_FOCAL_LENGTHS android.lens.info.availableFocalLengths} contains single value), + * which means the optical zoom is not supported.</li> + * <li>No ND filter ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES android.lens.info.availableFilterDensities} contains only 0).</li> + * <li>Fixed aperture ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures} contains single value).</li> + * </ul> + * <p>Then this state will always be STATIONARY.</p> + * <p>When the state is MOVING, it indicates that at least one of the lens parameters + * is changing.</p> + * + * @see CaptureRequest#LENS_APERTURE + * @see CaptureRequest#LENS_FILTER_DENSITY + * @see CaptureRequest#LENS_FOCAL_LENGTH + * @see CaptureRequest#LENS_FOCUS_DISTANCE + * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES + * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES + * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FOCAL_LENGTHS + * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE * @see #LENS_STATE_STATIONARY * @see #LENS_STATE_MOVING */ @@ -1593,10 +1634,24 @@ public final class CaptureResult extends CameraMetadata { new Key<Rational[]>("android.statistics.predictedColorTransform", Rational[].class); /** - * <p>The HAL estimated scene illumination lighting - * frequency</p> - * <p>Report NONE if there doesn't appear to be flickering - * illumination</p> + * <p>The camera device estimated scene illumination lighting + * frequency.</p> + * <p>Many light sources, such as most fluorescent lights, flicker at a rate + * that depends on the local utility power standards. This flicker must be + * accounted for by auto-exposure routines to avoid artifacts in captured images. + * The camera device uses this entry to tell the application what the scene + * illuminant frequency is.</p> + * <p>When manual exposure control is enabled + * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == OFF</code>), + * the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't do the antibanding, and the + * application can ensure it selects exposure times that do not cause banding + * issues by looking into this metadata field. See android.control.aeAntibandingMode + * for more details.</p> + * <p>Report NONE if there doesn't appear to be flickering illumination.</p> + * + * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE + * @see CaptureRequest#CONTROL_AE_MODE + * @see CaptureRequest#CONTROL_MODE * @see #STATISTICS_SCENE_FLICKER_NONE * @see #STATISTICS_SCENE_FLICKER_50HZ * @see #STATISTICS_SCENE_FLICKER_60HZ diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index a9b2533a389a..6ac126efd45b 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -360,11 +360,17 @@ public class ConnectivityManager { */ public static final int TYPE_MOBILE_IA = 14; + /** + * The network that uses proxy to achieve connectivity. + * {@hide} + */ + public static final int TYPE_PROXY = 16; + /** {@hide} */ - public static final int MAX_RADIO_TYPE = TYPE_MOBILE_IA; + public static final int MAX_RADIO_TYPE = TYPE_PROXY; /** {@hide} */ - public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_IA; + public static final int MAX_NETWORK_TYPE = TYPE_PROXY; /** * If you want to set the default network preference,you can directly @@ -443,6 +449,8 @@ public class ConnectivityManager { return "WIFI_P2P"; case TYPE_MOBILE_IA: return "MOBILE_IA"; + case TYPE_PROXY: + return "PROXY"; default: return Integer.toString(type); } diff --git a/core/java/android/net/ProxyDataTracker.java b/core/java/android/net/ProxyDataTracker.java new file mode 100644 index 000000000000..a7d287bde27d --- /dev/null +++ b/core/java/android/net/ProxyDataTracker.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + +import android.content.Context; +import android.os.Handler; +import android.os.Message; +import android.util.Log; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A data tracker responsible for bringing up and tearing down the system proxy server. + * + * {@hide} + */ +public class ProxyDataTracker extends BaseNetworkStateTracker { + private static final String NETWORK_TYPE = "PROXY"; + private static final String TAG = "ProxyDataTracker"; + + // TODO: investigate how to get these DNS addresses from the system. + private static final String DNS1 = "8.8.8.8"; + private static final String DNS2 = "8.8.4.4"; + private static final String REASON_ENABLED = "enabled"; + + private final AtomicInteger mDefaultGatewayAddr = new AtomicInteger(0); + private final AtomicInteger mReconnectGeneration = new AtomicInteger(0); + + /** + * Create a new ProxyDataTracker + */ + public ProxyDataTracker() { + mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_PROXY, 0, NETWORK_TYPE, ""); + // TODO: update available state according to proxy state. + mNetworkInfo.setIsAvailable(true); + mLinkProperties = new LinkProperties(); + mLinkCapabilities = new LinkCapabilities(); + + try { + mLinkProperties.addDns(InetAddress.getByName(DNS1)); + mLinkProperties.addDns(InetAddress.getByName(DNS2)); + } catch (UnknownHostException e) { + Log.e(TAG, "Could not add DNS address", e); + } + } + + public Object Clone() throws CloneNotSupportedException { + throw new CloneNotSupportedException(); + } + + /** + * Disable connectivity to the network. + */ + public boolean teardown() { + // TODO: tell relevant service to tear down proxy. + return true; + } + + /** + * Re-enable proxy data connectivity after a {@link #teardown()}. + */ + public boolean reconnect() { + if (!isAvailable()) { + Log.w(TAG, "Reconnect requested even though network is disabled. Bailing."); + return false; + } + setTeardownRequested(false); + mReconnectGeneration.incrementAndGet(); + // TODO: tell relevant service to setup proxy. Set state to connected only if setup + // succeeds. + setDetailedState(NetworkInfo.DetailedState.CONNECTED, REASON_ENABLED, null); + + return true; + } + + /** + * Fetch default gateway address for the network + */ + public int getDefaultGatewayAddr() { + return mDefaultGatewayAddr.get(); + } + + /** + * Return the system properties name associated with the tcp buffer sizes + * for this network. + */ + public String getTcpBufferSizesPropName() { + return "net.tcp.buffersize.wifi"; + } + + /** + * Record the detailed state of a network, and if it is a + * change from the previous state, send a notification to + * any listeners. + * @param state the new @{code DetailedState} + * @param reason a {@code String} indicating a reason for the state change, + * if one was supplied. May be {@code null}. + * @param extraInfo optional {@code String} providing extra information about the state change + */ + private void setDetailedState(NetworkInfo.DetailedState state, String reason, + String extraInfo) { + mNetworkInfo.setDetailedState(state, reason, extraInfo); + Message msg = getTargetHandler().obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo); + msg.sendToTarget(); + } +} diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index f4a83910e652..ba716052d8fc 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -56,7 +56,7 @@ public class Binder implements IBinder { private static String sDumpDisabled = null; /* mObject is used by native code, do not remove or rename */ - private int mObject; + private long mObject; private IInterface mOwner; private String mDescriptor; @@ -390,7 +390,7 @@ public class Binder implements IBinder { private native final void destroy(); // Entry point from android_util_Binder.cpp's onTransact - private boolean execTransact(int code, int dataObj, int replyObj, + private boolean execTransact(int code, long dataObj, long replyObj, int flags) { Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); @@ -499,6 +499,6 @@ final class BinderProxy implements IBinder { } final private WeakReference mSelf; - private int mObject; - private int mOrgue; + private long mObject; + private long mOrgue; } diff --git a/core/java/android/os/CountDownTimer.java b/core/java/android/os/CountDownTimer.java index c5b1146dae8d..58acbcf5684b 100644 --- a/core/java/android/os/CountDownTimer.java +++ b/core/java/android/os/CountDownTimer.java @@ -54,6 +54,11 @@ public abstract class CountDownTimer { private final long mCountdownInterval; private long mStopTimeInFuture; + + /** + * boolean representing if the timer was cancelled + */ + private boolean mCancelled = false; /** * @param millisInFuture The number of millis in the future from the call @@ -70,7 +75,8 @@ public abstract class CountDownTimer { /** * Cancel the countdown. */ - public final void cancel() { + public synchronized final void cancel() { + mCancelled = true; mHandler.removeMessages(MSG); } @@ -78,6 +84,7 @@ public abstract class CountDownTimer { * Start the countdown. */ public synchronized final CountDownTimer start() { + mCancelled = false; if (mMillisInFuture <= 0) { onFinish(); return this; @@ -110,6 +117,10 @@ public abstract class CountDownTimer { public void handleMessage(Message msg) { synchronized (CountDownTimer.this) { + if (mCancelled) { + return; + } + final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 0ee11098cfc2..0deaea6cc679 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -183,7 +183,7 @@ public final class Parcel { private static final String TAG = "Parcel"; @SuppressWarnings({"UnusedDeclaration"}) - private int mNativePtr; // used by native code + private long mNativePtr; // used by native code /** * Flag indicating if {@link #mNativePtr} was allocated by this object, @@ -233,47 +233,47 @@ public final class Parcel { private static final int EX_NETWORK_MAIN_THREAD = -6; private static final int EX_HAS_REPLY_HEADER = -128; // special; see below - private static native int nativeDataSize(int nativePtr); - private static native int nativeDataAvail(int nativePtr); - private static native int nativeDataPosition(int nativePtr); - private static native int nativeDataCapacity(int nativePtr); - private static native void nativeSetDataSize(int nativePtr, int size); - private static native void nativeSetDataPosition(int nativePtr, int pos); - private static native void nativeSetDataCapacity(int nativePtr, int size); - - private static native boolean nativePushAllowFds(int nativePtr, boolean allowFds); - private static native void nativeRestoreAllowFds(int nativePtr, boolean lastValue); - - private static native void nativeWriteByteArray(int nativePtr, byte[] b, int offset, int len); - private static native void nativeWriteInt(int nativePtr, int val); - private static native void nativeWriteLong(int nativePtr, long val); - private static native void nativeWriteFloat(int nativePtr, float val); - private static native void nativeWriteDouble(int nativePtr, double val); - private static native void nativeWriteString(int nativePtr, String val); - private static native void nativeWriteStrongBinder(int nativePtr, IBinder val); - private static native void nativeWriteFileDescriptor(int nativePtr, FileDescriptor val); - - private static native byte[] nativeCreateByteArray(int nativePtr); - private static native int nativeReadInt(int nativePtr); - private static native long nativeReadLong(int nativePtr); - private static native float nativeReadFloat(int nativePtr); - private static native double nativeReadDouble(int nativePtr); - private static native String nativeReadString(int nativePtr); - private static native IBinder nativeReadStrongBinder(int nativePtr); - private static native FileDescriptor nativeReadFileDescriptor(int nativePtr); - - private static native int nativeCreate(); - private static native void nativeFreeBuffer(int nativePtr); - private static native void nativeDestroy(int nativePtr); - - private static native byte[] nativeMarshall(int nativePtr); + private static native int nativeDataSize(long nativePtr); + private static native int nativeDataAvail(long nativePtr); + private static native int nativeDataPosition(long nativePtr); + private static native int nativeDataCapacity(long nativePtr); + private static native void nativeSetDataSize(long nativePtr, int size); + private static native void nativeSetDataPosition(long nativePtr, int pos); + private static native void nativeSetDataCapacity(long nativePtr, int size); + + private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds); + private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue); + + private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len); + private static native void nativeWriteInt(long nativePtr, int val); + private static native void nativeWriteLong(long nativePtr, long val); + private static native void nativeWriteFloat(long nativePtr, float val); + private static native void nativeWriteDouble(long nativePtr, double val); + private static native void nativeWriteString(long nativePtr, String val); + private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); + private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); + + private static native byte[] nativeCreateByteArray(long nativePtr); + private static native int nativeReadInt(long nativePtr); + private static native long nativeReadLong(long nativePtr); + private static native float nativeReadFloat(long nativePtr); + private static native double nativeReadDouble(long nativePtr); + private static native String nativeReadString(long nativePtr); + private static native IBinder nativeReadStrongBinder(long nativePtr); + private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); + + private static native long nativeCreate(); + private static native void nativeFreeBuffer(long nativePtr); + private static native void nativeDestroy(long nativePtr); + + private static native byte[] nativeMarshall(long nativePtr); private static native void nativeUnmarshall( - int nativePtr, byte[] data, int offest, int length); + long nativePtr, byte[] data, int offest, int length); private static native void nativeAppendFrom( - int thisNativePtr, int otherNativePtr, int offset, int length); - private static native boolean nativeHasFileDescriptors(int nativePtr); - private static native void nativeWriteInterfaceToken(int nativePtr, String interfaceName); - private static native void nativeEnforceInterface(int nativePtr, String interfaceName); + long thisNativePtr, long otherNativePtr, int offset, int length); + private static native boolean nativeHasFileDescriptors(long nativePtr); + private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName); + private static native void nativeEnforceInterface(long nativePtr, String interfaceName); public final static Parcelable.Creator<String> STRING_CREATOR = new Parcelable.Creator<String>() { @@ -2248,6 +2248,11 @@ public final class Parcel { /** @hide for internal use only. */ static protected final Parcel obtain(int obj) { + throw new UnsupportedOperationException(); + } + + /** @hide */ + static protected final Parcel obtain(long obj) { final Parcel[] pool = sHolderPool; synchronized (pool) { Parcel p; @@ -2266,7 +2271,7 @@ public final class Parcel { return new Parcel(obj); } - private Parcel(int nativePtr) { + private Parcel(long nativePtr) { if (DEBUG_RECYCLE) { mStack = new RuntimeException(); } @@ -2274,7 +2279,7 @@ public final class Parcel { init(nativePtr); } - private void init(int nativePtr) { + private void init(long nativePtr) { if (nativePtr != 0) { mNativePtr = nativePtr; mOwnsNativeParcelObject = false; diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java index 17f88f1e6a38..5c8c8e93e736 100644 --- a/core/java/android/preference/PreferenceManager.java +++ b/core/java/android/preference/PreferenceManager.java @@ -800,8 +800,10 @@ public class PreferenceManager { * Interface definition for a callback to be invoked when a * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is * clicked. + * + * @hide */ - interface OnPreferenceTreeClickListener { + public interface OnPreferenceTreeClickListener { /** * Called when a preference in the tree rooted at this * {@link PreferenceScreen} has been clicked. diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 843a4687f4fa..b9a898e42b7b 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3468,6 +3468,14 @@ public final class Settings { "lock_screen_owner_info_enabled"; /** + * This preference enables expanding the notification panel even over a securely + * locked screen, showing only "public" notifications in this case. + * @hide + */ + public static final String LOCK_SCREEN_ALLOW_NOTIFICATIONS = + "lock_screen_allow_notifications"; + + /** * The Logging ID (a unique 64-bit value) as a hex string. * Used as a pseudonymous identifier for logging. * @deprecated This identifier is poorly initialized and has @@ -6041,6 +6049,16 @@ public final class Settings { public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout"; /** + * Milliseconds to wait before bouncing Wi-Fi after settings is restored. Note that after + * the caller is done with this, they should call {@link ContentResolver#delete(Uri)} to + * clean up any value that they may have written. + * + * @hide + */ + public static final String WIFI_BOUNCE_DELAY_OVERRIDE_MS = "wifi_bounce_delay_override_ms"; + + + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. * diff --git a/core/java/android/speech/tts/SynthesisRequestV2.java b/core/java/android/speech/tts/SynthesisRequestV2.java index ed268b7db87f..a1da49cfc568 100644 --- a/core/java/android/speech/tts/SynthesisRequestV2.java +++ b/core/java/android/speech/tts/SynthesisRequestV2.java @@ -32,6 +32,18 @@ public final class SynthesisRequestV2 implements Parcelable { private final Bundle mAudioParams; /** + * Constructor for test purposes. + */ + public SynthesisRequestV2(String text, String utteranceId, String voiceName, + Bundle voiceParams, Bundle audioParams) { + this.mText = text; + this.mUtteranceId = utteranceId; + this.mVoiceName = voiceName; + this.mVoiceParams = voiceParams; + this.mAudioParams = audioParams; + } + + /** * Parcel based constructor. * * @hide diff --git a/core/java/android/speech/tts/TextToSpeechClient.java b/core/java/android/speech/tts/TextToSpeechClient.java index 0d8d42ceacc8..c6a14f2937dd 100644 --- a/core/java/android/speech/tts/TextToSpeechClient.java +++ b/core/java/android/speech/tts/TextToSpeechClient.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; /** * Synthesizes speech from text for immediate playback or to create a sound @@ -292,7 +293,8 @@ public final class TextToSpeechClient { * @param msFromStart * Miliseconds from the start of the synthesis. */ - public void onSynthesisProgress(UtteranceId utteranceId, int charIndex, int msFromStart) {} + public void onSynthesisProgress(UtteranceId utteranceId, int charIndex, + int msFromStart) {} } /** @@ -366,38 +368,28 @@ public final class TextToSpeechClient { } /** Unique synthesis request identifier. */ - public static final class UtteranceId { - private final String mDescription; - /** - * Create new, unique UtteranceId instance. - */ - public UtteranceId() { - mDescription = null; - } + public static class UtteranceId { + /** Unique identifier */ + private final int id; + + /** Unique identifier generator */ + private static final AtomicInteger ID_GENERATOR = new AtomicInteger(); /** * Create new, unique UtteranceId instance. - * - * @param description Additional string, that will be appended to - * {@link #toUniqueString()} output, allowing easier identification of the utterance in - * callbacks. */ - public UtteranceId(String description) { - mDescription = description; + public UtteranceId() { + id = ID_GENERATOR.getAndIncrement(); } /** * Returns a unique string associated with an instance of this object. * - * If you subclass {@link UtteranceId} make sure that output of this method is - * consistent across multiple calls and unique for the instance. - * * This string will be used to identify the synthesis request/utterance inside the * TTS service. */ - public String toUniqueString() { - return mDescription == null ? "UtteranceId" + System.identityHashCode(this) : - "UtteranceId" + System.identityHashCode(this) + ": " + mDescription; + public final String toUniqueString() { + return "UID" + id; } } @@ -680,7 +672,8 @@ public final class TextToSpeechClient { public void onFallback(String utteranceIdStr) { synchronized (mLock) { - Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(utteranceIdStr); + Pair<UtteranceId, RequestCallbacks> callbacks = getCallback( + utteranceIdStr); callbacks.second.onSynthesisFallback(callbacks.first); } }; diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 439fc6c930aa..8b6335918ab9 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -17,6 +17,7 @@ package android.view; import android.graphics.Matrix; +import android.graphics.Path; import java.util.ArrayList; @@ -151,7 +152,7 @@ public class DisplayList { /** * Indicates that the display list is done drawing. - * + * * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) * * @hide @@ -160,7 +161,7 @@ public class DisplayList { /** * Indicates that the display list needs another drawing pass. - * + * * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) * * @hide @@ -169,9 +170,9 @@ public class DisplayList { /** * Indicates that the display list needs to re-execute its GL functors. - * - * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) - * @see HardwareCanvas#callDrawGLFunction(int) + * + * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) + * @see HardwareCanvas#callDrawGLFunction(long) * * @hide */ @@ -406,26 +407,40 @@ public class DisplayList { * Set whether the display list should collect and Z order all 3d composited descendents, and * draw them in order with the default Z=0 content. * - * @param isContainedVolume true if the display list should collect and Z order descendents. + * @param isolatedZVolume true if the display list should collect and Z order descendents. */ - public void setIsContainedVolume(boolean isContainedVolume) { + public void setIsolatedZVolume(boolean isolatedZVolume) { if (hasNativeDisplayList()) { - nSetIsContainedVolume(mFinalizer.mNativeDisplayList, isContainedVolume); + nSetIsolatedZVolume(mFinalizer.mNativeDisplayList, isolatedZVolume); } } /** * Sets whether the display list should be drawn immediately after the - * closest ancestor display list where isContainedVolume is true. If the + * closest ancestor display list where isolateZVolume is true. If the * display list itself satisfies this constraint, changing this attribute * has no effect on drawing order. * * @param shouldProject true if the display list should be projected onto a * containing volume. */ - public void setProjectToContainedVolume(boolean shouldProject) { + public void setProjectBackwards(boolean shouldProject) { + if (hasNativeDisplayList()) { + nSetProjectBackwards(mFinalizer.mNativeDisplayList, shouldProject); + } + } + + /** + * Sets the outline, defining the shape that casts a shadow. + * + * Deep copies the native path to simplify reference ownership. + * + * @param outline Convex, CW Path to store in the DisplayList. May be null. + */ + public void setOutline(Path outline) { if (hasNativeDisplayList()) { - nSetProjectToContainedVolume(mFinalizer.mNativeDisplayList, shouldProject); + long nativePath = (outline == null) ? 0 : outline.mNativePath; + nSetOutline(mFinalizer.mNativeDisplayList, nativePath); } } @@ -1049,8 +1064,9 @@ public class DisplayList { private static native void nSetPivotX(long displayList, float pivotX); private static native void nSetCaching(long displayList, boolean caching); private static native void nSetClipToBounds(long displayList, boolean clipToBounds); - private static native void nSetProjectToContainedVolume(long displayList, boolean shouldProject); - private static native void nSetIsContainedVolume(long displayList, boolean isContainedVolume); + private static native void nSetProjectBackwards(long displayList, boolean shouldProject); + private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume); + private static native void nSetOutline(long displayList, long nativePath); private static native void nSetAlpha(long displayList, float alpha); private static native void nSetHasOverlappingRendering(long displayList, boolean hasOverlappingRendering); diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java index ed758504855e..aaa8b8c9cc12 100644 --- a/core/java/android/view/LayoutInflater.java +++ b/core/java/android/view/LayoutInflater.java @@ -91,7 +91,8 @@ public abstract class LayoutInflater { private static final String TAG_1995 = "blink"; private static final String TAG_REQUEST_FOCUS = "requestFocus"; - private static final String ATTR_THEME = "theme"; + private static final int[] ATTRS_THEME = new int[] { + com.android.internal.R.attr.theme }; /** * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed @@ -689,10 +690,12 @@ public abstract class LayoutInflater { } // Apply a theme wrapper, if requested. - final int themeResId = attrs.getAttributeResourceValue(null, ATTR_THEME, 0); + final TypedArray ta = viewContext.obtainStyledAttributes(attrs, ATTRS_THEME); + final int themeResId = ta.getResourceId(0, 0); if (themeResId != 0) { viewContext = new ContextThemeWrapper(viewContext, themeResId); } + ta.recycle(); if (name.equals(TAG_1995)) { // Let's party like it's 1995! diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index a6f856cd7fe8..55dcbb27ab7c 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -102,18 +102,18 @@ public class SurfaceControl { * surfaces are pre-multiplied, which means that each color component is * already multiplied by its alpha value. In this case the blending * equation used is: - * - * DEST = SRC + DEST * (1-SRC_ALPHA) - * + * <p> + * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> + * <p> * By contrast, non pre-multiplied surfaces use the following equation: - * - * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) - * + * <p> + * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> + * <p> * pre-multiplied surfaces must always be used if transparent pixels are * composited on top of each-other into the surface. A pre-multiplied * surface can never lower the value of the alpha component of a given * pixel. - * + * <p> * In some rare situations, a non pre-multiplied surface is preferable. * */ @@ -124,7 +124,17 @@ public class SurfaceControl { * even if its pixel format is set to translucent. This can be useful if an * application needs full RGBA 8888 support for instance but will * still draw every pixel opaque. - * + * <p> + * This flag is ignored if setAlpha() is used to make the surface non-opaque. + * Combined effects are (assuming a buffer format with an alpha channel): + * <ul> + * <li>OPAQUE + alpha(1.0) == opaque composition + * <li>OPAQUE + alpha(0.x) == blended composition + * <li>!OPAQUE + alpha(1.0) == blended composition + * <li>!OPAQUE + alpha(0.x) == blended composition + * </ul> + * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively + * set automatically. */ public static final int OPAQUE = 0x00000400; @@ -165,9 +175,16 @@ public class SurfaceControl { /** * Surface flag: Hide the surface. * Equivalent to calling hide(). + * Updates the value set during Surface creation (see {@link #HIDDEN}). */ public static final int SURFACE_HIDDEN = 0x01; + /** + * Surface flag: composite without blending when possible. + * Updates the value set during Surface creation (see {@link #OPAQUE}). + */ + public static final int SURFACE_OPAQUE = 0x02; + /* built-in physical display ids (keep in sync with ISurfaceComposer.h) * these are different from the logical display ids used elsewhere in the framework */ @@ -188,14 +205,14 @@ public class SurfaceControl { /** * Create a surface with a name. - * + * <p> * The surface creation flags specify what kind of surface to create and * certain options such as whether the surface can be assumed to be opaque * and whether it should be initially hidden. Surfaces should always be * created with the {@link #HIDDEN} flag set to ensure that they are not * made visible prematurely before all of the surface's properties have been * configured. - * + * <p> * Good practice is to first create the surface with the {@link #HIDDEN} flag * specified, open a transaction, set the surface layer, layer stack, alpha, * and position, call {@link #show} if appropriate, and close the transaction. @@ -338,6 +355,10 @@ public class SurfaceControl { nativeSetTransparentRegionHint(mNativeObject, region); } + /** + * Sets an alpha value for the entire Surface. This value is combined with the + * per-pixel alpha. It may be used with opaque Surfaces. + */ public void setAlpha(float alpha) { checkNotReleased(); nativeSetAlpha(mNativeObject, alpha); @@ -348,6 +369,13 @@ public class SurfaceControl { nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy); } + /** + * Sets and clears flags, such as {@link #SURFACE_HIDDEN}. The new value will be: + * <p> + * <code>newFlags = (oldFlags & ~mask) | (flags & mask)</code> + * <p> + * Note this does not take the same set of flags as the constructor. + */ public void setFlags(int flags, int mask) { checkNotReleased(); nativeSetFlags(mNativeObject, flags, mask); @@ -368,6 +396,19 @@ public class SurfaceControl { nativeSetLayerStack(mNativeObject, layerStack); } + /** + * Sets the opacity of the surface. Setting the flag is equivalent to creating the + * Surface with the {@link #OPAQUE} flag. + */ + public void setOpaque(boolean isOpaque) { + checkNotReleased(); + if (isOpaque) { + nativeSetFlags(mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); + } else { + nativeSetFlags(mNativeObject, 0, SURFACE_OPAQUE); + } + } + /* * set display parameters. * needs to be inside open/closeTransaction block diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 52b1b39d0a7f..239eda44f3a2 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -32,6 +32,7 @@ import android.graphics.Interpolator; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.Path; import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.PorterDuff; @@ -3295,6 +3296,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int[] mDrawableState = null; /** + * Stores the outline of the view, passed down to the DisplayList level for shadow shape. + */ + private Path mOutline; + + /** * When this view has focus and the next focus is {@link #FOCUS_LEFT}, * the user may specify which view to go to next. */ @@ -10624,6 +10630,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @hide + */ + public final void getOutline(Path outline) { + if (mOutline == null) { + outline.reset(); + } else { + outline.set(mOutline); + } + } + + /** + * @hide + */ + public void setOutline(Path path) { + // always copy the path since caller may reuse + if (mOutline == null) { + mOutline = new Path(path); + } else { + mOutline.set(path); + } + + if (mDisplayList != null) { + mDisplayList.setOutline(path); + } + } + + /** * Hit rectangle in parent's coordinates * * @param outRect The hit rectangle of the view. @@ -14263,9 +14296,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0); } if (this instanceof ViewGroup) { - displayList.setIsContainedVolume( - (((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_IS_CONTAINED_VOLUME) != 0); + displayList.setIsolatedZVolume( + (((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_ISOLATED_Z_VOLUME) != 0); } + displayList.setOutline(mOutline); float alpha = 1; if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 241b1a7c1976..b91091fbcca4 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -358,7 +358,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * When true, indicates that all 3d composited descendents are contained within this group, and * will not be interleaved with other 3d composited content. */ - static final int FLAG_IS_CONTAINED_VOLUME = 0x1000000; + static final int FLAG_ISOLATED_Z_VOLUME = 0x1000000; /** * Indicates which types of drawing caches are to be kept in memory. @@ -492,7 +492,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager mGroupFlags |= FLAG_ANIMATION_DONE; mGroupFlags |= FLAG_ANIMATION_CACHE; mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE; - mGroupFlags |= FLAG_IS_CONTAINED_VOLUME; + mGroupFlags |= FLAG_ISOLATED_Z_VOLUME; if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) { mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS; @@ -520,6 +520,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager case R.styleable.ViewGroup_clipToPadding: setClipToPadding(a.getBoolean(attr, true)); break; + case R.styleable.ViewGroup_isolatedZVolume: + setIsolatedZVolume(a.getBoolean(attr, true)); + break; case R.styleable.ViewGroup_animationCache: setAnimationCacheEnabled(a.getBoolean(attr, true)); break; @@ -3115,34 +3118,29 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * independent Z volume. Views drawn in one contained volume will not * interleave with views in another, even if their Z values are interleaved. * The default value is true. - * @see #setIsContainedVolume(boolean) - * - * @return True if the ViewGroup is a contained volume. + * @see #setIsolatedZVolume(boolean) * - * @hide + * @return True if the ViewGroup has an isolated Z volume. */ - public boolean isContainedVolume() { - return ((mGroupFlags & FLAG_IS_CONTAINED_VOLUME) != 0); + public boolean hasIsolatedZVolume() { + return ((mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0); } /** - * By default, only direct children of a group can interleave with - * interleaved Z values. Set to false on individual groups to enable Z + * By default, only direct children of a group can interleave drawing order + * by interleaving Z values. Set to false on individual groups to enable Z * interleaving of views that aren't direct siblings. * - * @return True if the group should be a contained volume with its own Z - * ordering space, false if its decendents should join the current Z - * ordering volume. - * @attr ref android.R.styleable#ViewGroup_isContainedVolume - * - * @hide + * @return True if the group should be an isolated Z volume with its own Z + * ordering space, false if its decendents should inhabit the + * inherited Z ordering volume. */ - public void setIsContainedVolume(boolean isContainedVolume) { - boolean previousValue = (mGroupFlags & FLAG_IS_CONTAINED_VOLUME) == FLAG_IS_CONTAINED_VOLUME; - if (isContainedVolume != previousValue) { - setBooleanFlag(FLAG_IS_CONTAINED_VOLUME, isContainedVolume); + public void setIsolatedZVolume(boolean isolateZVolume) { + boolean previousValue = (mGroupFlags & FLAG_ISOLATED_Z_VOLUME) == FLAG_ISOLATED_Z_VOLUME; + if (isolateZVolume != previousValue) { + setBooleanFlag(FLAG_ISOLATED_Z_VOLUME, isolateZVolume); if (mDisplayList != null) { - mDisplayList.setIsContainedVolume(isContainedVolume); + mDisplayList.setIsolatedZVolume(isolateZVolume); } } } diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index 38043b2ba763..1d1fa1e6f398 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -324,6 +324,8 @@ public class AnimationUtils { interpolator = new AnticipateOvershootInterpolator(c, attrs); } else if (name.equals("bounceInterpolator")) { interpolator = new BounceInterpolator(c, attrs); + } else if (name.equals("pathInterpolator")) { + interpolator = new PathInterpolator(c, attrs); } else { throw new RuntimeException("Unknown interpolator name: " + parser.getName()); } diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java new file mode 100644 index 000000000000..a3695090ea56 --- /dev/null +++ b/core/java/android/view/animation/PathInterpolator.java @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package android.view.animation; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Path; +import android.util.AttributeSet; +import android.view.InflateException; + +/** + * An interpolator that can traverse a Path that extends from <code>Point</code> + * <code>(0, 0)</code> to <code>(1, 1)</code>. The x coordinate along the <code>Path</code> + * is the input value and the output is the y coordinate of the line at that point. + * This means that the Path must conform to a function <code>y = f(x)</code>. + * + * <p>The <code>Path</code> must not have gaps in the x direction and must not + * loop back on itself such that there can be two points sharing the same x coordinate. + * It is alright to have a disjoint line in the vertical direction:</p> + * <p><blockquote><pre> + * Path path = new Path(); + * path.lineTo(0.25f, 0.25f); + * path.moveTo(0.25f, 0.5f); + * path.lineTo(1f, 1f); + * </pre></blockquote></p> + */ +public class PathInterpolator implements Interpolator { + + // This governs how accurate the approximation of the Path is. + private static final float PRECISION = 0.002f; + + private float[] mX; // x coordinates in the line + + private float[] mY; // y coordinates in the line + + /** + * Create an interpolator for an arbitrary <code>Path</code>. The <code>Path</code> + * must begin at <code>(0, 0)</code> and end at <code>(1, 1)</code>. + * + * @param path The <code>Path</code> to use to make the line representing the interpolator. + */ + public PathInterpolator(Path path) { + initPath(path); + } + + /** + * Create an interpolator for a quadratic Bezier curve. The end points + * <code>(0, 0)</code> and <code>(1, 1)</code> are assumed. + * + * @param controlX The x coordinate of the quadratic Bezier control point. + * @param controlY The y coordinate of the quadratic Bezier control point. + */ + public PathInterpolator(float controlX, float controlY) { + initQuad(controlX, controlY); + } + + /** + * Create an interpolator for a cubic Bezier curve. The end points + * <code>(0, 0)</code> and <code>(1, 1)</code> are assumed. + * + * @param controlX1 The x coordinate of the first control point of the cubic Bezier. + * @param controlY1 The y coordinate of the first control point of the cubic Bezier. + * @param controlX2 The x coordinate of the second control point of the cubic Bezier. + * @param controlY2 The y coordinate of the second control point of the cubic Bezier. + */ + public PathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) { + initCubic(controlX1, controlY1, controlX2, controlY2); + } + + public PathInterpolator(Context context, AttributeSet attrs) { + TypedArray a = context.obtainStyledAttributes(attrs, + com.android.internal.R.styleable.PathInterpolator); + if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX1)) { + throw new InflateException("pathInterpolator requires the controlX1 attribute"); + } else if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY1)) { + throw new InflateException("pathInterpolator requires the controlY1 attribute"); + } + float x1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX1, 0); + float y1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY1, 0); + + boolean hasX2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX2); + boolean hasY2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY2); + + if (hasX2 != hasY2) { + throw new InflateException( + "pathInterpolator requires both controlX2 and controlY2 for cubic Beziers."); + } + + if (!hasX2) { + initQuad(x1, y1); + } else { + float x2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX2, 0); + float y2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY2, 0); + initCubic(x1, y1, x2, y2); + } + + a.recycle(); + } + + private void initQuad(float controlX, float controlY) { + Path path = new Path(); + path.moveTo(0, 0); + path.quadTo(controlX, controlY, 1f, 1f); + initPath(path); + } + + private void initCubic(float x1, float y1, float x2, float y2) { + Path path = new Path(); + path.moveTo(0, 0); + path.cubicTo(x1, y1, x2, y2, 1f, 1f); + initPath(path); + } + + private void initPath(Path path) { + float[] pointComponents = path.approximate(PRECISION); + + int numPoints = pointComponents.length / 3; + if (pointComponents[1] != 0 || pointComponents[2] != 0 + || pointComponents[pointComponents.length - 2] != 1 + || pointComponents[pointComponents.length - 1] != 1) { + throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)"); + } + + mX = new float[numPoints]; + mY = new float[numPoints]; + float prevX = 0; + float prevFraction = 0; + int componentIndex = 0; + for (int i = 0; i < numPoints; i++) { + float fraction = pointComponents[componentIndex++]; + float x = pointComponents[componentIndex++]; + float y = pointComponents[componentIndex++]; + if (fraction == prevFraction && x != prevX) { + throw new IllegalArgumentException( + "The Path cannot have discontinuity in the X axis."); + } + if (x < prevX) { + throw new IllegalArgumentException("The Path cannot loop back on itself."); + } + mX[i] = x; + mY[i] = y; + prevX = x; + prevFraction = fraction; + } + } + + /** + * Using the line in the Path in this interpolator that can be described as + * <code>y = f(x)</code>, finds the y coordinate of the line given <code>t</code> + * as the x coordinate. Values less than 0 will always return 0 and values greater + * than 1 will always return 1. + * + * @param t Treated as the x coordinate along the line. + * @return The y coordinate of the Path along the line where x = <code>t</code>. + * @see Interpolator#getInterpolation(float) + */ + @Override + public float getInterpolation(float t) { + if (t <= 0) { + return 0; + } else if (t >= 1) { + return 1; + } + // Do a binary search for the correct x to interpolate between. + int startIndex = 0; + int endIndex = mX.length - 1; + + while (endIndex - startIndex > 1) { + int midIndex = (startIndex + endIndex) / 2; + if (t < mX[midIndex]) { + endIndex = midIndex; + } else { + startIndex = midIndex; + } + } + + float xRange = mX[endIndex] - mX[startIndex]; + if (xRange == 0) { + return mY[startIndex]; + } + + float tInRange = t - mX[startIndex]; + float fraction = tInRange / xRange; + + float startY = mY[startIndex]; + float endY = mY[endIndex]; + return startY + (fraction * (endY - startY)); + } + +} diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java index 746d34a6585a..c6be6ddfa27b 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -1488,34 +1488,36 @@ public class CalendarView extends FrameLayout { child = (WeekView) view.getChildAt(offset); } - // Find out which month we're moving into - int month; - if (mIsScrollingUp) { - month = child.getMonthOfFirstWeekDay(); - } else { - month = child.getMonthOfLastWeekDay(); - } - - // And how it relates to our current highlighted month - int monthDiff; - if (mCurrentMonthDisplayed == 11 && month == 0) { - monthDiff = 1; - } else if (mCurrentMonthDisplayed == 0 && month == 11) { - monthDiff = -1; - } else { - monthDiff = month - mCurrentMonthDisplayed; - } - - // Only switch months if we're scrolling away from the currently - // selected month - if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) { - Calendar firstDay = child.getFirstDay(); + if (child != null) { + // Find out which month we're moving into + int month; if (mIsScrollingUp) { - firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK); + month = child.getMonthOfFirstWeekDay(); } else { - firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK); + month = child.getMonthOfLastWeekDay(); + } + + // And how it relates to our current highlighted month + int monthDiff; + if (mCurrentMonthDisplayed == 11 && month == 0) { + monthDiff = 1; + } else if (mCurrentMonthDisplayed == 0 && month == 11) { + monthDiff = -1; + } else { + monthDiff = month - mCurrentMonthDisplayed; + } + + // Only switch months if we're scrolling away from the currently + // selected month + if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) { + Calendar firstDay = child.getFirstDay(); + if (mIsScrollingUp) { + firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK); + } else { + firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK); + } + setMonthDisplayed(firstDay); } - setMonthDisplayed(firstDay); } mPreviousScrollPosition = currScroll; mPreviousScrollState = mCurrentScrollState; diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index 0f51fab05712..62f9b0b14b85 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -570,7 +570,7 @@ public class ImageView extends View { } /** Return the view's optional matrix. This is applied to the - view's drawable when it is drawn. If there is not matrix, + view's drawable when it is drawn. If there is no matrix, this method will return an identity matrix. Do not change this matrix in place but make a copy. If you want a different matrix applied to the drawable, diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java index eda1db2a2bc6..4dd4a45fe21b 100644 --- a/core/java/com/android/internal/app/ProcessStats.java +++ b/core/java/com/android/internal/app/ProcessStats.java @@ -1097,7 +1097,7 @@ public final class ProcessStats implements Parcelable { public boolean evaluateSystemProperties(boolean update) { boolean changed = false; - String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib", + String runtime = SystemProperties.get("persist.sys.dalvik.vm.lib.1", VMRuntime.getRuntime().vmLibrary()); if (!Objects.equals(runtime, mRuntime)) { changed = true; diff --git a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java index 726065655d19..961e471706d6 100644 --- a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java +++ b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java @@ -154,6 +154,10 @@ public class SizeAdaptiveLayout extends ViewGroup { if (DEBUG) Log.d(TAG, this + " measure spec: " + MeasureSpec.toString(heightMeasureSpec)); View model = selectActiveChild(heightMeasureSpec); + if (model == null) { + setMeasuredDimension(0, 0); + return; + } SizeAdaptiveLayout.LayoutParams lp = (SizeAdaptiveLayout.LayoutParams) model.getLayoutParams(); if (DEBUG) Log.d(TAG, "active min: " + lp.minHeight + " max: " + lp.maxHeight); @@ -242,6 +246,8 @@ public class SizeAdaptiveLayout extends ViewGroup { int measureSpec = View.MeasureSpec.makeMeasureSpec(bottom - top, View.MeasureSpec.EXACTLY); mActiveChild = selectActiveChild(measureSpec); + if (mActiveChild == null) return; + mActiveChild.setVisibility(View.VISIBLE); if (mLastActive != mActiveChild && mLastActive != null) { diff --git a/core/jni/android/graphics/Interpolator.cpp b/core/jni/android/graphics/Interpolator.cpp index aa33c3dcbc11..ca04dfec52e1 100644 --- a/core/jni/android/graphics/Interpolator.cpp +++ b/core/jni/android/graphics/Interpolator.cpp @@ -5,23 +5,26 @@ #include "SkInterpolator.h" #include "SkTemplates.h" -static SkInterpolator* Interpolator_constructor(JNIEnv* env, jobject clazz, int valueCount, int frameCount) +static jlong Interpolator_constructor(JNIEnv* env, jobject clazz, jint valueCount, jint frameCount) { - return new SkInterpolator(valueCount, frameCount); + return reinterpret_cast<jlong>(new SkInterpolator(valueCount, frameCount)); } -static void Interpolator_destructor(JNIEnv* env, jobject clazz, SkInterpolator* interp) +static void Interpolator_destructor(JNIEnv* env, jobject clazz, jlong interpHandle) { + SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle); delete interp; } -static void Interpolator_reset(JNIEnv* env, jobject clazz, SkInterpolator* interp, int valueCount, int frameCount) +static void Interpolator_reset(JNIEnv* env, jobject clazz, jlong interpHandle, jint valueCount, jint frameCount) { + SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle); interp->reset(valueCount, frameCount); } -static void Interpolator_setKeyFrame(JNIEnv* env, jobject clazz, SkInterpolator* interp, int index, int msec, jfloatArray valueArray, jfloatArray blendArray) +static void Interpolator_setKeyFrame(JNIEnv* env, jobject clazz, jlong interpHandle, jint index, jint msec, jfloatArray valueArray, jfloatArray blendArray) { + SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle); SkScalar blendStorage[4]; SkScalar* blend = NULL; @@ -46,8 +49,9 @@ static void Interpolator_setKeyFrame(JNIEnv* env, jobject clazz, SkInterpolator* interp->setKeyFrame(index, msec, scalars, blend); } -static void Interpolator_setRepeatMirror(JNIEnv* env, jobject clazz, SkInterpolator* interp, float repeatCount, jboolean mirror) +static void Interpolator_setRepeatMirror(JNIEnv* env, jobject clazz, jlong interpHandle, jfloat repeatCount, jboolean mirror) { + SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle); if (repeatCount > 32000) repeatCount = 32000; @@ -55,8 +59,9 @@ static void Interpolator_setRepeatMirror(JNIEnv* env, jobject clazz, SkInterpola interp->setMirror(mirror != 0); } -static int Interpolator_timeToValues(JNIEnv* env, jobject clazz, SkInterpolator* interp, int msec, jfloatArray valueArray) +static jint Interpolator_timeToValues(JNIEnv* env, jobject clazz, jlong interpHandle, jint msec, jfloatArray valueArray) { + SkInterpolator* interp = reinterpret_cast<SkInterpolator*>(interpHandle); SkInterpolatorBase::Result result; float* values = valueArray ? env->GetFloatArrayElements(valueArray, NULL) : NULL; @@ -70,7 +75,7 @@ static int Interpolator_timeToValues(JNIEnv* env, jobject clazz, SkInterpolator* env->ReleaseFloatArrayElements(valueArray, values, 0); } - return result; + return static_cast<jint>(result); } // ---------------------------------------------------------------------------- @@ -79,12 +84,12 @@ static int Interpolator_timeToValues(JNIEnv* env, jobject clazz, SkInterpolator* * JNI registration. */ static JNINativeMethod gInterpolatorMethods[] = { - { "nativeConstructor", "(II)I", (void*)Interpolator_constructor }, - { "nativeDestructor", "(I)V", (void*)Interpolator_destructor }, - { "nativeReset", "(III)V", (void*)Interpolator_reset }, - { "nativeSetKeyFrame", "(III[F[F)V", (void*)Interpolator_setKeyFrame }, - { "nativeSetRepeatMirror", "(IFZ)V", (void*)Interpolator_setRepeatMirror }, - { "nativeTimeToValues", "(II[F)I", (void*)Interpolator_timeToValues } + { "nativeConstructor", "(II)J", (void*)Interpolator_constructor }, + { "nativeDestructor", "(J)V", (void*)Interpolator_destructor }, + { "nativeReset", "(JII)V", (void*)Interpolator_reset }, + { "nativeSetKeyFrame", "(JII[F[F)V", (void*)Interpolator_setKeyFrame }, + { "nativeSetRepeatMirror", "(JFZ)V", (void*)Interpolator_setRepeatMirror }, + { "nativeTimeToValues", "(JI[F)I", (void*)Interpolator_timeToValues } }; int register_android_graphics_Interpolator(JNIEnv* env) diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index c4d728fdb2ad..6bbf45a50bb2 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -515,54 +515,6 @@ public: delete[] approximation; return result; } - - static SkPathMeasure* trim(JNIEnv* env, jobject clazz, jlong inPathPtr, jlong outPathPtr, - jlong pathMeasurePtr, jfloat trimStart, jfloat trimEnd, jfloat trimOffset) { - SkPath* inPath = reinterpret_cast<SkPath*>(inPathPtr); - SkPath* outPath = reinterpret_cast<SkPath*>(outPathPtr); - SkPathMeasure* pathMeasure = reinterpret_cast<SkPathMeasure*>(pathMeasurePtr); - if (trimStart == 0 && trimEnd == 1) { - if (outPath != NULL) { - *outPath = *inPath; - } - return pathMeasure; - } - - bool modifyPath = (outPath == NULL); - if (modifyPath) { - outPath = new SkPath(); - } else { - outPath->reset(); - } - if (pathMeasure == NULL) { - pathMeasure = new SkPathMeasure(*inPath, false); - } - float length = pathMeasure->getLength(); - float start = (trimStart + trimOffset) * length; - float end = (trimEnd + trimOffset) * length; - - if (end > length && start <= length) { - pathMeasure->getSegment(start, length, outPath, true); - pathMeasure->getSegment(0, end - length, outPath, true); - } else { - if (start > length) { - start -= length; - end -= length; - } - pathMeasure->getSegment(start, end, outPath, true); - } - if (modifyPath) { - delete pathMeasure; - pathMeasure = NULL; - *inPath = *outPath; - delete outPath; - } - return pathMeasure; - } - - static void destroyMeasure(JNIEnv* env, jobject clazz, jlong measure) { - delete reinterpret_cast<SkPathMeasure*>(measure); - } }; static JNINativeMethod methods[] = { @@ -605,8 +557,6 @@ static JNINativeMethod methods[] = { {"native_transform","(JJ)V", (void*) SkPathGlue::transform__Matrix}, {"native_op","(JJIJ)Z", (void*) SkPathGlue::op}, {"native_approximate", "(JF)[F", (void*) SkPathGlue::approximate}, - {"native_destroyMeasure","(J)V", (void*) SkPathGlue::destroyMeasure}, - {"native_trim","(JJJFFF)I", (void*) SkPathGlue::trim}, }; int register_android_graphics_Path(JNIEnv* env) { diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 0c9b3bcac270..311695584764 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -55,28 +55,28 @@ static void SurfaceTexture_setSurfaceTexture(JNIEnv* env, jobject thiz, const sp<GLConsumer>& surfaceTexture) { GLConsumer* const p = - (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture); + (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture); if (surfaceTexture.get()) { surfaceTexture->incStrong((void*)SurfaceTexture_setSurfaceTexture); } if (p) { p->decStrong((void*)SurfaceTexture_setSurfaceTexture); } - env->SetIntField(thiz, fields.surfaceTexture, (int)surfaceTexture.get()); + env->SetLongField(thiz, fields.surfaceTexture, (jlong)surfaceTexture.get()); } static void SurfaceTexture_setBufferQueue(JNIEnv* env, jobject thiz, const sp<BufferQueue>& bq) { BufferQueue* const p = - (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue); + (BufferQueue*)env->GetLongField(thiz, fields.bufferQueue); if (bq.get()) { bq->incStrong((void*)SurfaceTexture_setBufferQueue); } if (p) { p->decStrong((void*)SurfaceTexture_setBufferQueue); } - env->SetIntField(thiz, fields.bufferQueue, (int)bq.get()); + env->SetLongField(thiz, fields.bufferQueue, (jlong)bq.get()); } static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env, @@ -84,22 +84,22 @@ static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env, { GLConsumer::FrameAvailableListener* const p = (GLConsumer::FrameAvailableListener*) - env->GetIntField(thiz, fields.frameAvailableListener); + env->GetLongField(thiz, fields.frameAvailableListener); if (listener.get()) { listener->incStrong((void*)SurfaceTexture_setSurfaceTexture); } if (p) { p->decStrong((void*)SurfaceTexture_setSurfaceTexture); } - env->SetIntField(thiz, fields.frameAvailableListener, (int)listener.get()); + env->SetLongField(thiz, fields.frameAvailableListener, (jlong)listener.get()); } sp<GLConsumer> SurfaceTexture_getSurfaceTexture(JNIEnv* env, jobject thiz) { - return (GLConsumer*)env->GetIntField(thiz, fields.surfaceTexture); + return (GLConsumer*)env->GetLongField(thiz, fields.surfaceTexture); } sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) { - return (BufferQueue*)env->GetIntField(thiz, fields.bufferQueue); + return (BufferQueue*)env->GetLongField(thiz, fields.bufferQueue); } sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) { @@ -201,19 +201,19 @@ void JNISurfaceTextureContext::onFrameAvailable() static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) { fields.surfaceTexture = env->GetFieldID(clazz, - ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "I"); + ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID, "J"); if (fields.surfaceTexture == NULL) { ALOGE("can't find android/graphics/SurfaceTexture.%s", ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID); } fields.bufferQueue = env->GetFieldID(clazz, - ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "I"); + ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "J"); if (fields.bufferQueue == NULL) { ALOGE("can't find android/graphics/SurfaceTexture.%s", ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID); } fields.frameAvailableListener = env->GetFieldID(clazz, - ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "I"); + ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "J"); if (fields.frameAvailableListener == NULL) { ALOGE("can't find android/graphics/SurfaceTexture.%s", ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID); diff --git a/core/jni/android_animation_PropertyValuesHolder.cpp b/core/jni/android_animation_PropertyValuesHolder.cpp index 73347ea5226f..ef1c4eda1d1e 100644 --- a/core/jni/android_animation_PropertyValuesHolder.cpp +++ b/core/jni/android_animation_PropertyValuesHolder.cpp @@ -29,25 +29,25 @@ namespace android { const char* const kClassPathName = "android/animation/PropertyValuesHolder"; -static jmethodID android_animation_PropertyValuesHolder_getIntMethod( +static jlong android_animation_PropertyValuesHolder_getIntMethod( JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName) { const char *nativeString = env->GetStringUTFChars(methodName, 0); jmethodID mid = env->GetMethodID(targetClass, nativeString, "(I)V"); env->ReleaseStringUTFChars(methodName, nativeString); - return mid; + return reinterpret_cast<jlong>(mid); } -static jmethodID android_animation_PropertyValuesHolder_getFloatMethod( +static jlong android_animation_PropertyValuesHolder_getFloatMethod( JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName) { const char *nativeString = env->GetStringUTFChars(methodName, 0); jmethodID mid = env->GetMethodID(targetClass, nativeString, "(F)V"); env->ReleaseStringUTFChars(methodName, nativeString); - return mid; + return reinterpret_cast<jlong>(mid); } -static jmethodID getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName, +static jlong getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName, jint parameterCount, char parameterType) { const char *nativeString = env->GetStringUTFChars(methodName, 0); @@ -58,48 +58,48 @@ static jmethodID getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstrin jmethodID mid = env->GetMethodID(targetClass, nativeString, signature); delete[] signature; env->ReleaseStringUTFChars(methodName, nativeString); - return mid; + return reinterpret_cast<jlong>(mid); } -static jmethodID android_animation_PropertyValuesHolder_getMultipleFloatMethod( +static jlong android_animation_PropertyValuesHolder_getMultipleFloatMethod( JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount) { return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'F'); } -static jmethodID android_animation_PropertyValuesHolder_getMultipleIntMethod( +static jlong android_animation_PropertyValuesHolder_getMultipleIntMethod( JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount) { return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'I'); } static void android_animation_PropertyValuesHolder_callIntMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jint arg) { - env->CallVoidMethod(target, methodID, arg); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg); } static void android_animation_PropertyValuesHolder_callFloatMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jfloat arg) { - env->CallVoidMethod(target, methodID, arg); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg); } static void android_animation_PropertyValuesHolder_callTwoFloatMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2) { - env->CallVoidMethod(target, methodID, arg1, arg2); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2); } static void android_animation_PropertyValuesHolder_callFourFloatMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg1, float arg2, + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2, float arg3, float arg4) { - env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4); } static void android_animation_PropertyValuesHolder_callMultipleFloatMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jfloatArray arg) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jfloatArray arg) { jsize parameterCount = env->GetArrayLength(arg); jfloat *floatValues = env->GetFloatArrayElements(arg, NULL); @@ -107,26 +107,26 @@ static void android_animation_PropertyValuesHolder_callMultipleFloatMethod( for (int i = 0; i < parameterCount; i++) { values[i].f = floatValues[i]; } - env->CallVoidMethodA(target, methodID, values); + env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values); delete[] values; env->ReleaseFloatArrayElements(arg, floatValues, JNI_ABORT); } static void android_animation_PropertyValuesHolder_callTwoIntMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2) { - env->CallVoidMethod(target, methodID, arg1, arg2); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2); } static void android_animation_PropertyValuesHolder_callFourIntMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg1, int arg2, + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2, int arg3, int arg4) { - env->CallVoidMethod(target, methodID, arg1, arg2, arg3, arg4); + env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4); } static void android_animation_PropertyValuesHolder_callMultipleIntMethod( - JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, jintArray arg) + JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jintArray arg) { jsize parameterCount = env->GetArrayLength(arg); jint *intValues = env->GetIntArrayElements(arg, NULL); @@ -134,35 +134,35 @@ static void android_animation_PropertyValuesHolder_callMultipleIntMethod( for (int i = 0; i < parameterCount; i++) { values[i].i = intValues[i]; } - env->CallVoidMethodA(target, methodID, values); + env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values); delete[] values; env->ReleaseIntArrayElements(arg, intValues, JNI_ABORT); } static JNINativeMethod gMethods[] = { - { "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)I", + { "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)J", (void*)android_animation_PropertyValuesHolder_getIntMethod }, - { "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)I", + { "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)J", (void*)android_animation_PropertyValuesHolder_getFloatMethod }, - { "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I", + { "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J", (void*)android_animation_PropertyValuesHolder_getMultipleFloatMethod }, - { "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)I", + { "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J", (void*)android_animation_PropertyValuesHolder_getMultipleIntMethod }, - { "nCallIntMethod", "(Ljava/lang/Object;II)V", + { "nCallIntMethod", "(Ljava/lang/Object;JI)V", (void*)android_animation_PropertyValuesHolder_callIntMethod }, - { "nCallFloatMethod", "(Ljava/lang/Object;IF)V", + { "nCallFloatMethod", "(Ljava/lang/Object;JF)V", (void*)android_animation_PropertyValuesHolder_callFloatMethod }, - { "nCallTwoFloatMethod", "(Ljava/lang/Object;IFF)V", + { "nCallTwoFloatMethod", "(Ljava/lang/Object;JFF)V", (void*)android_animation_PropertyValuesHolder_callTwoFloatMethod }, - { "nCallFourFloatMethod", "(Ljava/lang/Object;IFFFF)V", + { "nCallFourFloatMethod", "(Ljava/lang/Object;JFFFF)V", (void*)android_animation_PropertyValuesHolder_callFourFloatMethod }, - { "nCallMultipleFloatMethod", "(Ljava/lang/Object;I[F)V", + { "nCallMultipleFloatMethod", "(Ljava/lang/Object;J[F)V", (void*)android_animation_PropertyValuesHolder_callMultipleFloatMethod }, - { "nCallTwoIntMethod", "(Ljava/lang/Object;III)V", + { "nCallTwoIntMethod", "(Ljava/lang/Object;JII)V", (void*)android_animation_PropertyValuesHolder_callTwoIntMethod }, - { "nCallFourIntMethod", "(Ljava/lang/Object;IIIII)V", + { "nCallFourIntMethod", "(Ljava/lang/Object;JIIII)V", (void*)android_animation_PropertyValuesHolder_callFourIntMethod }, - { "nCallMultipleIntMethod", "(Ljava/lang/Object;I[I)V", + { "nCallMultipleIntMethod", "(Ljava/lang/Object;J[I)V", (void*)android_animation_PropertyValuesHolder_callMultipleIntMethod }, }; diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index 1fe4b08d9721..5b0a4b2e4039 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -630,7 +630,7 @@ not_valid_surface: if (producer == NULL) goto not_valid_surface; - window = new android::Surface(producer); + window = new android::Surface(producer, true); if (window == NULL) goto not_valid_surface; diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index aa451e3a12a8..50f6c73fa0da 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -69,7 +69,7 @@ static struct parcel_offsets_t Parcel* parcelForJavaObject(JNIEnv* env, jobject obj) { if (obj) { - Parcel* p = (Parcel*)env->GetIntField(obj, gParcelOffsets.mNativePtr); + Parcel* p = (Parcel*)env->GetLongField(obj, gParcelOffsets.mNativePtr); if (p != NULL) { return p; } @@ -88,31 +88,31 @@ void recycleJavaParcelObject(JNIEnv* env, jobject parcelObj) env->CallVoidMethod(parcelObj, gParcelOffsets.recycle); } -static jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jint nativePtr) +static jint android_os_Parcel_dataSize(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataSize() : 0; } -static jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jint nativePtr) +static jint android_os_Parcel_dataAvail(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataAvail() : 0; } -static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jint nativePtr) +static jint android_os_Parcel_dataPosition(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataPosition() : 0; } -static jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jint nativePtr) +static jint android_os_Parcel_dataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataCapacity() : 0; } -static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jint nativePtr, jint size) +static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativePtr, jint size) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -123,7 +123,7 @@ static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jint native } } -static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jint nativePtr, jint pos) +static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jlong nativePtr, jint pos) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -131,7 +131,7 @@ static void android_os_Parcel_setDataPosition(JNIEnv* env, jclass clazz, jint na } } -static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jint nativePtr, jint size) +static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong nativePtr, jint size) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -142,7 +142,7 @@ static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jint na } } -static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean allowFds) +static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean allowFds) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); jboolean ret = JNI_TRUE; @@ -152,7 +152,7 @@ static jboolean android_os_Parcel_pushAllowFds(JNIEnv* env, jclass clazz, jint n return ret; } -static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jint nativePtr, jboolean lastValue) +static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jlong nativePtr, jboolean lastValue) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -160,7 +160,7 @@ static void android_os_Parcel_restoreAllowFds(JNIEnv* env, jclass clazz, jint na } } -static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jint nativePtr, jobject data, +static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jlong nativePtr, jobject data, jint offset, jint length) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); @@ -187,7 +187,7 @@ static void android_os_Parcel_writeNative(JNIEnv* env, jclass clazz, jint native } } -static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jint nativePtr, jint val) { +static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); const status_t err = parcel->writeInt32(val); if (err != NO_ERROR) { @@ -195,7 +195,7 @@ static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jint nativePtr } } -static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jint nativePtr, jlong val) +static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jlong nativePtr, jlong val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -206,7 +206,7 @@ static void android_os_Parcel_writeLong(JNIEnv* env, jclass clazz, jint nativePt } } -static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jint nativePtr, jfloat val) +static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jlong nativePtr, jfloat val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -217,7 +217,7 @@ static void android_os_Parcel_writeFloat(JNIEnv* env, jclass clazz, jint nativeP } } -static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jint nativePtr, jdouble val) +static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jlong nativePtr, jdouble val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -228,7 +228,7 @@ static void android_os_Parcel_writeDouble(JNIEnv* env, jclass clazz, jint native } } -static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint nativePtr, jstring val) +static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jlong nativePtr, jstring val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -248,7 +248,7 @@ static void android_os_Parcel_writeString(JNIEnv* env, jclass clazz, jint native } } -static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr, jobject object) +static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -259,7 +259,7 @@ static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jint } } -static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr, jobject object) +static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -271,7 +271,7 @@ static void android_os_Parcel_writeFileDescriptor(JNIEnv* env, jclass clazz, jin } } -static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jint nativePtr) +static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, jlong nativePtr) { jbyteArray ret = NULL; @@ -297,7 +297,7 @@ static jbyteArray android_os_Parcel_createByteArray(JNIEnv* env, jclass clazz, j return ret; } -static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jint nativePtr) +static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -306,7 +306,7 @@ static jint android_os_Parcel_readInt(JNIEnv* env, jclass clazz, jint nativePtr) return 0; } -static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jint nativePtr) +static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -315,7 +315,7 @@ static jlong android_os_Parcel_readLong(JNIEnv* env, jclass clazz, jint nativePt return 0; } -static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jint nativePtr) +static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -324,7 +324,7 @@ static jfloat android_os_Parcel_readFloat(JNIEnv* env, jclass clazz, jint native return 0; } -static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jint nativePtr) +static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -333,7 +333,7 @@ static jdouble android_os_Parcel_readDouble(JNIEnv* env, jclass clazz, jint nati return 0; } -static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nativePtr) +static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -347,7 +347,7 @@ static jstring android_os_Parcel_readString(JNIEnv* env, jclass clazz, jint nati return NULL; } -static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jint nativePtr) +static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -356,7 +356,7 @@ static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jin return NULL; } -static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jint nativePtr) +static jobject android_os_Parcel_readFileDescriptor(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -468,13 +468,13 @@ static void android_os_Parcel_clearFileDescriptor(JNIEnv* env, jclass clazz, job } } -static jint android_os_Parcel_create(JNIEnv* env, jclass clazz) +static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz) { Parcel* parcel = new Parcel(); - return reinterpret_cast<jint>(parcel); + return reinterpret_cast<jlong>(parcel); } -static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativePtr) +static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -482,13 +482,13 @@ static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jint nativeP } } -static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jint nativePtr) +static void android_os_Parcel_destroy(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); delete parcel; } -static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jint nativePtr) +static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel == NULL) { @@ -517,7 +517,7 @@ static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jint nat return ret; } -static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jint nativePtr, +static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr, jbyteArray data, jint offset, jint length) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); @@ -538,8 +538,8 @@ static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jint nativeP } } -static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jint thisNativePtr, - jint otherNativePtr, jint offset, jint length) +static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr, + jlong otherNativePtr, jint offset, jint length) { Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr); if (thisParcel == NULL) { @@ -556,7 +556,7 @@ static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jint thisNat } } -static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jint nativePtr) +static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, jlong nativePtr) { jboolean ret = JNI_FALSE; Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); @@ -568,7 +568,7 @@ static jboolean android_os_Parcel_hasFileDescriptors(JNIEnv* env, jclass clazz, return ret; } -static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jint nativePtr, +static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); @@ -583,7 +583,7 @@ static void android_os_Parcel_writeInterfaceToken(JNIEnv* env, jclass clazz, jin } } -static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint nativePtr, jstring name) +static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jlong nativePtr, jstring name) { jboolean ret = JNI_FALSE; @@ -622,50 +622,50 @@ static void android_os_Parcel_enforceInterface(JNIEnv* env, jclass clazz, jint n // ---------------------------------------------------------------------------- static const JNINativeMethod gParcelMethods[] = { - {"nativeDataSize", "(I)I", (void*)android_os_Parcel_dataSize}, - {"nativeDataAvail", "(I)I", (void*)android_os_Parcel_dataAvail}, - {"nativeDataPosition", "(I)I", (void*)android_os_Parcel_dataPosition}, - {"nativeDataCapacity", "(I)I", (void*)android_os_Parcel_dataCapacity}, - {"nativeSetDataSize", "(II)V", (void*)android_os_Parcel_setDataSize}, - {"nativeSetDataPosition", "(II)V", (void*)android_os_Parcel_setDataPosition}, - {"nativeSetDataCapacity", "(II)V", (void*)android_os_Parcel_setDataCapacity}, - - {"nativePushAllowFds", "(IZ)Z", (void*)android_os_Parcel_pushAllowFds}, - {"nativeRestoreAllowFds", "(IZ)V", (void*)android_os_Parcel_restoreAllowFds}, - - {"nativeWriteByteArray", "(I[BII)V", (void*)android_os_Parcel_writeNative}, - {"nativeWriteInt", "(II)V", (void*)android_os_Parcel_writeInt}, - {"nativeWriteLong", "(IJ)V", (void*)android_os_Parcel_writeLong}, - {"nativeWriteFloat", "(IF)V", (void*)android_os_Parcel_writeFloat}, - {"nativeWriteDouble", "(ID)V", (void*)android_os_Parcel_writeDouble}, - {"nativeWriteString", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeString}, - {"nativeWriteStrongBinder", "(ILandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, - {"nativeWriteFileDescriptor", "(ILjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, - - {"nativeCreateByteArray", "(I)[B", (void*)android_os_Parcel_createByteArray}, - {"nativeReadInt", "(I)I", (void*)android_os_Parcel_readInt}, - {"nativeReadLong", "(I)J", (void*)android_os_Parcel_readLong}, - {"nativeReadFloat", "(I)F", (void*)android_os_Parcel_readFloat}, - {"nativeReadDouble", "(I)D", (void*)android_os_Parcel_readDouble}, - {"nativeReadString", "(I)Ljava/lang/String;", (void*)android_os_Parcel_readString}, - {"nativeReadStrongBinder", "(I)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, - {"nativeReadFileDescriptor", "(I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, + {"nativeDataSize", "(J)I", (void*)android_os_Parcel_dataSize}, + {"nativeDataAvail", "(J)I", (void*)android_os_Parcel_dataAvail}, + {"nativeDataPosition", "(J)I", (void*)android_os_Parcel_dataPosition}, + {"nativeDataCapacity", "(J)I", (void*)android_os_Parcel_dataCapacity}, + {"nativeSetDataSize", "(JI)V", (void*)android_os_Parcel_setDataSize}, + {"nativeSetDataPosition", "(JI)V", (void*)android_os_Parcel_setDataPosition}, + {"nativeSetDataCapacity", "(JI)V", (void*)android_os_Parcel_setDataCapacity}, + + {"nativePushAllowFds", "(JZ)Z", (void*)android_os_Parcel_pushAllowFds}, + {"nativeRestoreAllowFds", "(JZ)V", (void*)android_os_Parcel_restoreAllowFds}, + + {"nativeWriteByteArray", "(J[BII)V", (void*)android_os_Parcel_writeNative}, + {"nativeWriteInt", "(JI)V", (void*)android_os_Parcel_writeInt}, + {"nativeWriteLong", "(JJ)V", (void*)android_os_Parcel_writeLong}, + {"nativeWriteFloat", "(JF)V", (void*)android_os_Parcel_writeFloat}, + {"nativeWriteDouble", "(JD)V", (void*)android_os_Parcel_writeDouble}, + {"nativeWriteString", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeString}, + {"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder}, + {"nativeWriteFileDescriptor", "(JLjava/io/FileDescriptor;)V", (void*)android_os_Parcel_writeFileDescriptor}, + + {"nativeCreateByteArray", "(J)[B", (void*)android_os_Parcel_createByteArray}, + {"nativeReadInt", "(J)I", (void*)android_os_Parcel_readInt}, + {"nativeReadLong", "(J)J", (void*)android_os_Parcel_readLong}, + {"nativeReadFloat", "(J)F", (void*)android_os_Parcel_readFloat}, + {"nativeReadDouble", "(J)D", (void*)android_os_Parcel_readDouble}, + {"nativeReadString", "(J)Ljava/lang/String;", (void*)android_os_Parcel_readString}, + {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}, + {"nativeReadFileDescriptor", "(J)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_readFileDescriptor}, {"openFileDescriptor", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_openFileDescriptor}, {"dupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;", (void*)android_os_Parcel_dupFileDescriptor}, {"closeFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_closeFileDescriptor}, {"clearFileDescriptor", "(Ljava/io/FileDescriptor;)V", (void*)android_os_Parcel_clearFileDescriptor}, - {"nativeCreate", "()I", (void*)android_os_Parcel_create}, - {"nativeFreeBuffer", "(I)V", (void*)android_os_Parcel_freeBuffer}, - {"nativeDestroy", "(I)V", (void*)android_os_Parcel_destroy}, + {"nativeCreate", "()J", (void*)android_os_Parcel_create}, + {"nativeFreeBuffer", "(J)V", (void*)android_os_Parcel_freeBuffer}, + {"nativeDestroy", "(J)V", (void*)android_os_Parcel_destroy}, - {"nativeMarshall", "(I)[B", (void*)android_os_Parcel_marshall}, - {"nativeUnmarshall", "(I[BII)V", (void*)android_os_Parcel_unmarshall}, - {"nativeAppendFrom", "(IIII)V", (void*)android_os_Parcel_appendFrom}, - {"nativeHasFileDescriptors", "(I)Z", (void*)android_os_Parcel_hasFileDescriptors}, - {"nativeWriteInterfaceToken", "(ILjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, - {"nativeEnforceInterface", "(ILjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, + {"nativeMarshall", "(J)[B", (void*)android_os_Parcel_marshall}, + {"nativeUnmarshall", "(J[BII)V", (void*)android_os_Parcel_unmarshall}, + {"nativeAppendFrom", "(JJII)V", (void*)android_os_Parcel_appendFrom}, + {"nativeHasFileDescriptors", "(J)Z", (void*)android_os_Parcel_hasFileDescriptors}, + {"nativeWriteInterfaceToken", "(JLjava/lang/String;)V", (void*)android_os_Parcel_writeInterfaceToken}, + {"nativeEnforceInterface", "(JLjava/lang/String;)V", (void*)android_os_Parcel_enforceInterface}, }; const char* const kParcelPathName = "android/os/Parcel"; @@ -678,7 +678,7 @@ int register_android_os_Parcel(JNIEnv* env) LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Parcel"); gParcelOffsets.clazz = (jclass) env->NewGlobalRef(clazz); - gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "I"); + gParcelOffsets.mNativePtr = env->GetFieldID(clazz, "mNativePtr", "J"); gParcelOffsets.obtain = env->GetStaticMethodID(clazz, "obtain", "()Landroid/os/Parcel;"); gParcelOffsets.recycle = env->GetMethodID(clazz, "recycle", "()V"); diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp index ca278cf00d4f..2b85fefbd8e5 100644 --- a/core/jni/android_os_SELinux.cpp +++ b/core/jni/android_os_SELinux.cpp @@ -443,8 +443,21 @@ static JNINativeMethod method_table[] = { static int log_callback(int type, const char *fmt, ...) { va_list ap; + int priority; + + switch (type) { + case SELINUX_WARNING: + priority = ANDROID_LOG_WARN; + break; + case SELINUX_INFO: + priority = ANDROID_LOG_INFO; + break; + default: + priority = ANDROID_LOG_ERROR; + break; + } va_start(ap, fmt); - LOG_PRI_VA(ANDROID_LOG_ERROR, "SELinux", fmt, ap); + LOG_PRI_VA(priority, "SELinux", fmt, ap); va_end(ap); return 0; } diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 883691856bbe..f96aef857757 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -88,7 +88,7 @@ jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table, { env->SetIntField(outValue, gTypedValueOffsets.mType, value.dataType); env->SetIntField(outValue, gTypedValueOffsets.mAssetCookie, - (jint)table->getTableCookie(block)); + static_cast<jint>(table->getTableCookie(block))); env->SetIntField(outValue, gTypedValueOffsets.mData, value.data); env->SetObjectField(outValue, gTypedValueOffsets.mString, NULL); env->SetIntField(outValue, gTypedValueOffsets.mResourceId, ref); @@ -105,7 +105,8 @@ jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table, // this guy is exported to other jni routines AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj) { - AssetManager* am = (AssetManager*)env->GetIntField(obj, gAssetManagerOffsets.mObject); + jlong amHandle = env->GetLongField(obj, gAssetManagerOffsets.mObject); + AssetManager* am = reinterpret_cast<AssetManager*>(amHandle); if (am != NULL) { return am; } @@ -113,7 +114,7 @@ AssetManager* assetManagerForJavaObject(JNIEnv* env, jobject obj) return NULL; } -static jint android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, +static jlong android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, jstring fileName, jint mode) { AssetManager* am = assetManagerForJavaObject(env, clazz); @@ -125,6 +126,7 @@ static jint android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, ScopedUtfChars fileName8(env, fileName); if (fileName8.c_str() == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", "Empty file name"); return -1; } @@ -143,7 +145,7 @@ static jint android_content_AssetManager_openAsset(JNIEnv* env, jobject clazz, //printf("Created Asset Stream: %p\n", a); - return (jint)a; + return reinterpret_cast<jlong>(a); } static jobject returnParcelFileDescriptor(JNIEnv* env, Asset* a, jlongArray outOffsets) @@ -205,7 +207,7 @@ static jobject android_content_AssetManager_openAssetFd(JNIEnv* env, jobject cla return returnParcelFileDescriptor(env, a, outOffsets); } -static jint android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz, +static jlong android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject clazz, jint cookie, jstring fileName, jint mode) @@ -240,7 +242,7 @@ static jint android_content_AssetManager_openNonAssetNative(JNIEnv* env, jobject //printf("Created Asset Stream: %p\n", a); - return (jint)a; + return reinterpret_cast<jlong>(a); } static jobject android_content_AssetManager_openNonAssetFdNative(JNIEnv* env, jobject clazz, @@ -320,9 +322,9 @@ static jobjectArray android_content_AssetManager_list(JNIEnv* env, jobject clazz } static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz, - jint asset) + jlong assetHandle) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); //printf("Destroying Asset Stream: %p\n", a); @@ -335,9 +337,9 @@ static void android_content_AssetManager_destroyAsset(JNIEnv* env, jobject clazz } static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject clazz, - jint asset) + jlong assetHandle) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); if (a == NULL) { jniThrowNullPointerException(env, "asset"); @@ -350,10 +352,10 @@ static jint android_content_AssetManager_readAssetChar(JNIEnv* env, jobject claz } static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz, - jint asset, jbyteArray bArray, + jlong assetHandle, jbyteArray bArray, jint off, jint len) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); if (a == NULL || bArray == NULL) { jniThrowNullPointerException(env, "asset"); @@ -374,7 +376,7 @@ static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz, ssize_t res = a->read(b+off, len); env->ReleaseByteArrayElements(bArray, b, 0); - if (res > 0) return res; + if (res > 0) return static_cast<jint>(res); if (res < 0) { jniThrowException(env, "java/io/IOException", ""); @@ -383,10 +385,10 @@ static jint android_content_AssetManager_readAsset(JNIEnv* env, jobject clazz, } static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz, - jint asset, + jlong assetHandle, jlong offset, jint whence) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); if (a == NULL) { jniThrowNullPointerException(env, "asset"); @@ -398,9 +400,9 @@ static jlong android_content_AssetManager_seekAsset(JNIEnv* env, jobject clazz, } static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject clazz, - jint asset) + jlong assetHandle) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); if (a == NULL) { jniThrowNullPointerException(env, "asset"); @@ -411,9 +413,9 @@ static jlong android_content_AssetManager_getAssetLength(JNIEnv* env, jobject cl } static jlong android_content_AssetManager_getAssetRemainingLength(JNIEnv* env, jobject clazz, - jint asset) + jlong assetHandle) { - Asset* a = (Asset*)asset; + Asset* a = reinterpret_cast<Asset*>(assetHandle); if (a == NULL) { jniThrowNullPointerException(env, "asset"); @@ -725,7 +727,11 @@ static jint android_content_AssetManager_loadResourceValue(JNIEnv* env, jobject } #endif } - return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config) : block; + if (block >= 0) { + return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags, &config); + } + + return static_cast<jint>(block); } static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobject clazz, @@ -759,7 +765,7 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje res.unlock(); if (block < 0) { - return block; + return static_cast<jint>(block); } uint32_t ref = ident; @@ -772,7 +778,11 @@ static jint android_content_AssetManager_loadResourceBagValue(JNIEnv* env, jobje } #endif } - return block >= 0 ? copyValue(env, outValue, &res, value, ref, block, typeSpecFlags) : block; + if (block >= 0) { + return copyValue(env, outValue, &res, value, ref, block, typeSpecFlags); + } + + return static_cast<jint>(block); } static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobject clazz) @@ -784,14 +794,14 @@ static jint android_content_AssetManager_getStringBlockCount(JNIEnv* env, jobjec return am->getResources().getTableCount(); } -static jint android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz, +static jlong android_content_AssetManager_getNativeStringBlock(JNIEnv* env, jobject clazz, jint block) { AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return 0; } - return (jint)am->getResources().getTableStringBlock(block); + return reinterpret_cast<jlong>(am->getResources().getTableStringBlock(block)); } static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject clazz, @@ -810,43 +820,43 @@ static jstring android_content_AssetManager_getCookieName(JNIEnv* env, jobject c return str; } -static jint android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz) +static jlong android_content_AssetManager_newTheme(JNIEnv* env, jobject clazz) { AssetManager* am = assetManagerForJavaObject(env, clazz); if (am == NULL) { return 0; } - return (jint)(new ResTable::Theme(am->getResources())); + return reinterpret_cast<jlong>(new ResTable::Theme(am->getResources())); } static void android_content_AssetManager_deleteTheme(JNIEnv* env, jobject clazz, - jint themeInt) + jlong themeHandle) { - ResTable::Theme* theme = (ResTable::Theme*)themeInt; + ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle); delete theme; } static void android_content_AssetManager_applyThemeStyle(JNIEnv* env, jobject clazz, - jint themeInt, + jlong themeHandle, jint styleRes, jboolean force) { - ResTable::Theme* theme = (ResTable::Theme*)themeInt; + ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle); theme->applyStyle(styleRes, force ? true : false); } static void android_content_AssetManager_copyTheme(JNIEnv* env, jobject clazz, - jint destInt, jint srcInt) + jlong destHandle, jlong srcHandle) { - ResTable::Theme* dest = (ResTable::Theme*)destInt; - ResTable::Theme* src = (ResTable::Theme*)srcInt; + ResTable::Theme* dest = reinterpret_cast<ResTable::Theme*>(destHandle); + ResTable::Theme* src = reinterpret_cast<ResTable::Theme*>(srcHandle); dest->setTo(*src); } static jint android_content_AssetManager_loadThemeAttributeValue( - JNIEnv* env, jobject clazz, jint themeInt, jint ident, jobject outValue, jboolean resolve) + JNIEnv* env, jobject clazz, jlong themeHandle, jint ident, jobject outValue, jboolean resolve) { - ResTable::Theme* theme = (ResTable::Theme*)themeInt; + ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle); const ResTable& res(theme->getResTable()); Res_value value; @@ -867,10 +877,10 @@ static jint android_content_AssetManager_loadThemeAttributeValue( } static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz, - jint themeInt, jint pri, + jlong themeHandle, jint pri, jstring tag, jstring prefix) { - ResTable::Theme* theme = (ResTable::Theme*)themeInt; + ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeHandle); const ResTable& res(theme->getResTable()); // XXX Need to use params. @@ -878,10 +888,10 @@ static void android_content_AssetManager_dumpTheme(JNIEnv* env, jobject clazz, } static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject clazz, - jint themeToken, + jlong themeToken, jint defStyleAttr, jint defStyleRes, - jint xmlParserToken, + jlong xmlParserToken, jintArray attrs, jintArray outValues, jintArray outIndices) @@ -902,9 +912,9 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla DEBUG_STYLES(LOGI("APPLY STYLE: theme=0x%x defStyleAttr=0x%x defStyleRes=0x%x xml=0x%x", themeToken, defStyleAttr, defStyleRes, xmlParserToken)); - ResTable::Theme* theme = (ResTable::Theme*)themeToken; + ResTable::Theme* theme = reinterpret_cast<ResTable::Theme*>(themeToken); const ResTable& res = theme->getResTable(); - ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken; + ResXMLParser* xmlParser = reinterpret_cast<ResXMLParser*>(xmlParserToken); ResTable_config config; Res_value value; @@ -1097,7 +1107,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla dest[STYLE_TYPE] = value.dataType; dest[STYLE_DATA] = value.data; dest[STYLE_ASSET_COOKIE] = - block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1; + block != kXmlBlock ? reinterpret_cast<jint>(res.getTableCookie(block)) : (jint)-1; dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; @@ -1123,7 +1133,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla } static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, jobject clazz, - jint xmlParserToken, + jlong xmlParserToken, jintArray attrs, jintArray outValues, jintArray outIndices) @@ -1240,7 +1250,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job dest[STYLE_TYPE] = value.dataType; dest[STYLE_DATA] = value.data; dest[STYLE_ASSET_COOKIE] = - block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1; + block != kXmlBlock ? reinterpret_cast<jint>(res.getTableCookie(block)) : (jint)-1; dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; @@ -1280,7 +1290,7 @@ static jint android_content_AssetManager_getArraySize(JNIEnv* env, jobject clazz ssize_t bagOff = res.getBagLocked(id, &defStyleEnt); res.unlock(); - return bagOff; + return static_cast<jint>(bagOff); } static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject clazz, @@ -1352,7 +1362,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz // Write the final value back to Java. dest[STYLE_TYPE] = value.dataType; dest[STYLE_DATA] = value.data; - dest[STYLE_ASSET_COOKIE] = (jint)res.getTableCookie(block); + dest[STYLE_ASSET_COOKIE] = reinterpret_cast<jint>(res.getTableCookie(block)); dest[STYLE_RESOURCE_ID] = resid; dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags; dest[STYLE_DENSITY] = config.density; @@ -1370,7 +1380,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz return i; } -static jint android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz, +static jlong android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject clazz, jint cookie, jstring fileName) { @@ -1405,7 +1415,7 @@ static jint android_content_AssetManager_openXmlAssetNative(JNIEnv* env, jobject return 0; } - return (jint)block; + return reinterpret_cast<jlong>(block); } static jintArray android_content_AssetManager_getArrayStringInfo(JNIEnv* env, jobject clazz, @@ -1580,17 +1590,17 @@ static void android_content_AssetManager_init(JNIEnv* env, jobject clazz) am->addDefaultAssets(); ALOGV("Created AssetManager %p for Java object %p\n", am, clazz); - env->SetIntField(clazz, gAssetManagerOffsets.mObject, (jint)am); + env->SetLongField(clazz, gAssetManagerOffsets.mObject, reinterpret_cast<jlong>(am)); } static void android_content_AssetManager_destroy(JNIEnv* env, jobject clazz) { AssetManager* am = (AssetManager*) - (env->GetIntField(clazz, gAssetManagerOffsets.mObject)); + (env->GetLongField(clazz, gAssetManagerOffsets.mObject)); ALOGV("Destroying AssetManager %p for Java object %p\n", am, clazz); if (am != NULL) { delete am; - env->SetIntField(clazz, gAssetManagerOffsets.mObject, 0); + env->SetLongField(clazz, gAssetManagerOffsets.mObject, 0); } } @@ -1624,27 +1634,27 @@ static JNINativeMethod gAssetManagerMethods[] = { /* name, signature, funcPtr */ // Basic asset stuff. - { "openAsset", "(Ljava/lang/String;I)I", + { "openAsset", "(Ljava/lang/String;I)J", (void*) android_content_AssetManager_openAsset }, { "openAssetFd", "(Ljava/lang/String;[J)Landroid/os/ParcelFileDescriptor;", (void*) android_content_AssetManager_openAssetFd }, - { "openNonAssetNative", "(ILjava/lang/String;I)I", + { "openNonAssetNative", "(ILjava/lang/String;I)J", (void*) android_content_AssetManager_openNonAssetNative }, { "openNonAssetFdNative", "(ILjava/lang/String;[J)Landroid/os/ParcelFileDescriptor;", (void*) android_content_AssetManager_openNonAssetFdNative }, { "list", "(Ljava/lang/String;)[Ljava/lang/String;", (void*) android_content_AssetManager_list }, - { "destroyAsset", "(I)V", + { "destroyAsset", "(J)V", (void*) android_content_AssetManager_destroyAsset }, - { "readAssetChar", "(I)I", + { "readAssetChar", "(J)I", (void*) android_content_AssetManager_readAssetChar }, - { "readAsset", "(I[BII)I", + { "readAsset", "(J[BII)I", (void*) android_content_AssetManager_readAsset }, - { "seekAsset", "(IJI)J", + { "seekAsset", "(JJI)J", (void*) android_content_AssetManager_seekAsset }, - { "getAssetLength", "(I)J", + { "getAssetLength", "(J)J", (void*) android_content_AssetManager_getAssetLength }, - { "getAssetRemainingLength", "(I)J", + { "getAssetRemainingLength", "(J)J", (void*) android_content_AssetManager_getAssetRemainingLength }, { "addAssetPathNative", "(Ljava/lang/String;)I", (void*) android_content_AssetManager_addAssetPath }, @@ -1674,27 +1684,27 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_loadResourceBagValue }, { "getStringBlockCount","()I", (void*) android_content_AssetManager_getStringBlockCount }, - { "getNativeStringBlock","(I)I", + { "getNativeStringBlock","(I)J", (void*) android_content_AssetManager_getNativeStringBlock }, { "getCookieName","(I)Ljava/lang/String;", (void*) android_content_AssetManager_getCookieName }, // Themes. - { "newTheme", "()I", + { "newTheme", "()J", (void*) android_content_AssetManager_newTheme }, - { "deleteTheme", "(I)V", + { "deleteTheme", "(J)V", (void*) android_content_AssetManager_deleteTheme }, - { "applyThemeStyle", "(IIZ)V", + { "applyThemeStyle", "(JIZ)V", (void*) android_content_AssetManager_applyThemeStyle }, - { "copyTheme", "(II)V", + { "copyTheme", "(JJ)V", (void*) android_content_AssetManager_copyTheme }, - { "loadThemeAttributeValue", "(IILandroid/util/TypedValue;Z)I", + { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I", (void*) android_content_AssetManager_loadThemeAttributeValue }, - { "dumpTheme", "(IILjava/lang/String;Ljava/lang/String;)V", + { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V", (void*) android_content_AssetManager_dumpTheme }, - { "applyStyle","(IIII[I[I[I)Z", + { "applyStyle","(JIIJ[I[I[I)Z", (void*) android_content_AssetManager_applyStyle }, - { "retrieveAttributes","(I[I[I[I)Z", + { "retrieveAttributes","(J[I[I[I)Z", (void*) android_content_AssetManager_retrieveAttributes }, { "getArraySize","(I)I", (void*) android_content_AssetManager_getArraySize }, @@ -1702,7 +1712,7 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_retrieveArray }, // XML files. - { "openXmlAssetNative", "(ILjava/lang/String;)I", + { "openXmlAssetNative", "(ILjava/lang/String;)J", (void*) android_content_AssetManager_openXmlAssetNative }, // Arrays. @@ -1766,7 +1776,7 @@ int register_android_content_AssetManager(JNIEnv* env) jclass assetManager = env->FindClass("android/content/res/AssetManager"); LOG_FATAL_IF(assetManager == NULL, "Unable to find class android/content/res/AssetManager"); gAssetManagerOffsets.mObject - = env->GetFieldID(assetManager, "mObject", "I"); + = env->GetFieldID(assetManager, "mObject", "J"); LOG_FATAL_IF(gAssetManagerOffsets.mObject == NULL, "Unable to find AssetManager.mObject"); jclass stringClass = env->FindClass("java/lang/String"); diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 259d0303c532..475e926eafc4 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -267,7 +267,7 @@ protected: //data.print(); //printf("\n"); jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, - code, (int32_t)&data, (int32_t)reply, flags); + code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags); jthrowable excep = env->ExceptionOccurred(); if (excep) { @@ -577,7 +577,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) if (object != NULL) { LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object); // The proxy holds a reference to the native object. - env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); + env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get()); val->incStrong((void*)javaObjectForIBinder); // The native object needs to hold a weak reference back to the @@ -590,7 +590,7 @@ jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) // Also remember the death recipients registered on this proxy sp<DeathRecipientList> drl = new DeathRecipientList; drl->incStrong((void*)javaObjectForIBinder); - env->SetIntField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jint>(drl.get())); + env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get())); // Note that a new object reference has been created. android_atomic_inc(&gNumProxyRefs); @@ -606,13 +606,13 @@ sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) - env->GetIntField(obj, gBinderOffsets.mObject); + env->GetLongField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env, obj) : NULL; } if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); } ALOGW("ibinderForJavaObject: %p is not a Binder object", obj); @@ -764,15 +764,15 @@ static void android_os_Binder_init(JNIEnv* env, jobject obj) } ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh); jbh->incStrong((void*)android_os_Binder_init); - env->SetIntField(obj, gBinderOffsets.mObject, (int)jbh); + env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh); } static void android_os_Binder_destroy(JNIEnv* env, jobject obj) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) - env->GetIntField(obj, gBinderOffsets.mObject); + env->GetLongField(obj, gBinderOffsets.mObject); if (jbh != NULL) { - env->SetIntField(obj, gBinderOffsets.mObject, 0); + env->SetLongField(obj, gBinderOffsets.mObject, 0); ALOGV("Java Binder %p: removing ref on holder %p", obj, jbh); jbh->decStrong((void*)android_os_Binder_init); } else { @@ -812,11 +812,11 @@ static int int_register_android_os_Binder(JNIEnv* env) gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderOffsets.mExecTransact - = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); + = env->GetMethodID(clazz, "execTransact", "(IJJI)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject - = env->GetFieldID(clazz, "mObject", "I"); + = env->GetFieldID(clazz, "mObject", "J"); assert(gBinderOffsets.mObject); return AndroidRuntime::registerNativeMethods( @@ -911,7 +911,7 @@ static int int_register_android_os_BinderInternal(JNIEnv* env) static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) { IBinder* target = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { return JNI_FALSE; } @@ -921,7 +921,7 @@ static jboolean android_os_BinderProxy_pingBinder(JNIEnv* env, jobject obj) static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobject obj) { - IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); + IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target != NULL) { const String16& desc = target->getInterfaceDescriptor(); return env->NewString(desc.string(), desc.size()); @@ -934,7 +934,7 @@ static jstring android_os_BinderProxy_getInterfaceDescriptor(JNIEnv* env, jobjec static jboolean android_os_BinderProxy_isBinderAlive(JNIEnv* env, jobject obj) { IBinder* target = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { return JNI_FALSE; } @@ -1062,7 +1062,7 @@ static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, } IBinder* target = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; @@ -1109,7 +1109,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, } IBinder* target = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); assert(false); @@ -1119,7 +1119,7 @@ static void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj, if (!target->localBinder()) { DeathRecipientList* list = (DeathRecipientList*) - env->GetIntField(obj, gBinderProxyOffsets.mOrgue); + env->GetLongField(obj, gBinderProxyOffsets.mOrgue); sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list); status_t err = target->linkToDeath(jdr, NULL, flags); if (err != NO_ERROR) { @@ -1141,7 +1141,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, } IBinder* target = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { ALOGW("Binder has been finalized when calling linkToDeath() with recip=%p)\n", recipient); return JNI_FALSE; @@ -1154,7 +1154,7 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, // If we find the matching recipient, proceed to unlink using that DeathRecipientList* list = (DeathRecipientList*) - env->GetIntField(obj, gBinderProxyOffsets.mOrgue); + env->GetLongField(obj, gBinderProxyOffsets.mOrgue); sp<JavaDeathRecipient> origJDR = list->find(recipient); LOGDEATH(" unlink found list %p and JDR %p", list, origJDR.get()); if (origJDR != NULL) { @@ -1183,13 +1183,13 @@ static jboolean android_os_BinderProxy_unlinkToDeath(JNIEnv* env, jobject obj, static void android_os_BinderProxy_destroy(JNIEnv* env, jobject obj) { IBinder* b = (IBinder*) - env->GetIntField(obj, gBinderProxyOffsets.mObject); + env->GetLongField(obj, gBinderProxyOffsets.mObject); DeathRecipientList* drl = (DeathRecipientList*) - env->GetIntField(obj, gBinderProxyOffsets.mOrgue); + env->GetLongField(obj, gBinderProxyOffsets.mOrgue); LOGDEATH("Destroying BinderProxy %p: binder=%p drl=%p\n", obj, b, drl); - env->SetIntField(obj, gBinderProxyOffsets.mObject, 0); - env->SetIntField(obj, gBinderProxyOffsets.mOrgue, 0); + env->SetLongField(obj, gBinderProxyOffsets.mObject, 0); + env->SetLongField(obj, gBinderProxyOffsets.mOrgue, 0); drl->decStrong((void*)javaObjectForIBinder); b->decStrong((void*)javaObjectForIBinder); @@ -1231,13 +1231,13 @@ static int int_register_android_os_BinderProxy(JNIEnv* env) assert(gBinderProxyOffsets.mSendDeathNotice); gBinderProxyOffsets.mObject - = env->GetFieldID(clazz, "mObject", "I"); + = env->GetFieldID(clazz, "mObject", "J"); assert(gBinderProxyOffsets.mObject); gBinderProxyOffsets.mSelf = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); assert(gBinderProxyOffsets.mSelf); gBinderProxyOffsets.mOrgue - = env->GetFieldID(clazz, "mOrgue", "I"); + = env->GetFieldID(clazz, "mOrgue", "J"); assert(gBinderProxyOffsets.mOrgue); clazz = env->FindClass("java/lang/Class"); diff --git a/core/jni/android_util_StringBlock.cpp b/core/jni/android_util_StringBlock.cpp index 463d3c0bd5cf..f29250f4619d 100644 --- a/core/jni/android_util_StringBlock.cpp +++ b/core/jni/android_util_StringBlock.cpp @@ -31,7 +31,7 @@ namespace android { // ---------------------------------------------------------------------------- -static jint android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz, +static jlong android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz, jbyteArray bArray, jint off, jint len) { @@ -56,13 +56,13 @@ static jint android_content_StringBlock_nativeCreate(JNIEnv* env, jobject clazz, return 0; } - return (jint)osb; + return reinterpret_cast<jlong>(osb); } static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResStringPool* osb = (ResStringPool*)token; + ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; @@ -72,9 +72,9 @@ static jint android_content_StringBlock_nativeGetSize(JNIEnv* env, jobject clazz } static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResStringPool* osb = (ResStringPool*)token; + ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; @@ -96,9 +96,9 @@ static jstring android_content_StringBlock_nativeGetString(JNIEnv* env, jobject } static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResStringPool* osb = (ResStringPool*)token; + ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return NULL; @@ -139,9 +139,9 @@ static jintArray android_content_StringBlock_nativeGetStyle(JNIEnv* env, jobject } static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResStringPool* osb = (ResStringPool*)token; + ResStringPool* osb = reinterpret_cast<ResStringPool*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return; @@ -157,15 +157,15 @@ static void android_content_StringBlock_nativeDestroy(JNIEnv* env, jobject clazz */ static JNINativeMethod gStringBlockMethods[] = { /* name, signature, funcPtr */ - { "nativeCreate", "([BII)I", + { "nativeCreate", "([BII)J", (void*) android_content_StringBlock_nativeCreate }, - { "nativeGetSize", "(I)I", + { "nativeGetSize", "(J)I", (void*) android_content_StringBlock_nativeGetSize }, - { "nativeGetString", "(II)Ljava/lang/String;", + { "nativeGetString", "(JI)Ljava/lang/String;", (void*) android_content_StringBlock_nativeGetString }, - { "nativeGetStyle", "(II)[I", + { "nativeGetStyle", "(JI)[I", (void*) android_content_StringBlock_nativeGetStyle }, - { "nativeDestroy", "(I)V", + { "nativeDestroy", "(J)V", (void*) android_content_StringBlock_nativeDestroy }, }; diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp index ad6033b1c175..03de5c0a1cd9 100644 --- a/core/jni/android_util_XmlBlock.cpp +++ b/core/jni/android_util_XmlBlock.cpp @@ -31,7 +31,7 @@ namespace android { // ---------------------------------------------------------------------------- -static jint android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz, +static jlong android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz, jbyteArray bArray, jint off, jint len) { @@ -55,25 +55,25 @@ static jint android_content_XmlBlock_nativeCreate(JNIEnv* env, jobject clazz, return 0; } - return (jint)osb; + return reinterpret_cast<jlong>(osb); } -static jint android_content_XmlBlock_nativeGetStringBlock(JNIEnv* env, jobject clazz, - jint token) +static jlong android_content_XmlBlock_nativeGetStringBlock(JNIEnv* env, jobject clazz, + jlong token) { - ResXMLTree* osb = (ResXMLTree*)token; + ResXMLTree* osb = reinterpret_cast<ResXMLTree*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)&osb->getStrings(); + return reinterpret_cast<jlong>(&osb->getStrings()); } -static jint android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz, - jint token) +static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject clazz, + jlong token) { - ResXMLTree* osb = (ResXMLTree*)token; + ResXMLTree* osb = reinterpret_cast<ResXMLTree*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return 0; @@ -87,19 +87,19 @@ static jint android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobject st->restart(); - return (jint)st; + return reinterpret_cast<jlong>(st); } static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return ResXMLParser::END_DOCUMENT; } do { - jint code = (jint)st->next(); + ResXMLParser::event_code_t code = st->next(); switch (code) { case ResXMLParser::START_TAG: return 2; @@ -123,139 +123,139 @@ bad: } static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; } - return (jint)st->getElementNamespaceID(); + return static_cast<jint>(st->getElementNamespaceID()); } static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; } - return (jint)st->getElementNameID(); + return static_cast<jint>(st->getElementNameID()); } static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; } - return (jint)st->getTextID(); + return static_cast<jint>(st->getTextID()); } static jint android_content_XmlBlock_nativeGetLineNumber(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getLineNumber(); + return static_cast<jint>(st->getLineNumber()); } static jint android_content_XmlBlock_nativeGetAttributeCount(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeCount(); + return static_cast<jint>(st->getAttributeCount()); } static jint android_content_XmlBlock_nativeGetAttributeNamespace(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeNamespaceID(idx); + return static_cast<jint>(st->getAttributeNamespaceID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeName(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeNameID(idx); + return static_cast<jint>(st->getAttributeNameID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeResource(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeNameResID(idx); + return static_cast<jint>(st->getAttributeNameResID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeDataType(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeDataType(idx); + return static_cast<jint>(st->getAttributeDataType(idx)); } static jint android_content_XmlBlock_nativeGetAttributeData(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeData(idx); + return static_cast<jint>(st->getAttributeData(idx)); } static jint android_content_XmlBlock_nativeGetAttributeStringValue(JNIEnv* env, jobject clazz, - jint token, jint idx) + jlong token, jint idx) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } - return (jint)st->getAttributeValueStringID(idx); + return static_cast<jint>(st->getAttributeValueStringID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobject clazz, - jint token, + jlong token, jstring ns, jstring name) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL || name == NULL) { jniThrowNullPointerException(env, NULL); return 0; @@ -271,7 +271,7 @@ static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobjec const char16_t* name16 = env->GetStringChars(name, NULL); jsize nameLen = env->GetStringLength(name); - jint idx = (jint)st->indexOfAttribute(ns16, nsLen, name16, nameLen); + jint idx = static_cast<jint>(st->indexOfAttribute(ns16, nsLen, name16, nameLen)); if (ns) { env->ReleaseStringChars(ns, ns16); @@ -282,35 +282,35 @@ static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobjec } static jint android_content_XmlBlock_nativeGetIdAttribute(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ssize_t idx = st->indexOfID(); - return idx >= 0 ? (jint)st->getAttributeValueStringID(idx) : -1; + return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetClassAttribute(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; } ssize_t idx = st->indexOfClass(); - return idx >= 0 ? (jint)st->getAttributeValueStringID(idx) : -1; + return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; @@ -332,9 +332,9 @@ static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobjec } static void android_content_XmlBlock_nativeDestroyParseState(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLParser* st = (ResXMLParser*)token; + ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return; @@ -344,9 +344,9 @@ static void android_content_XmlBlock_nativeDestroyParseState(JNIEnv* env, jobjec } static void android_content_XmlBlock_nativeDestroy(JNIEnv* env, jobject clazz, - jint token) + jlong token) { - ResXMLTree* osb = (ResXMLTree*)token; + ResXMLTree* osb = reinterpret_cast<ResXMLTree*>(token); if (osb == NULL) { jniThrowNullPointerException(env, NULL); return; @@ -362,47 +362,47 @@ static void android_content_XmlBlock_nativeDestroy(JNIEnv* env, jobject clazz, */ static JNINativeMethod gXmlBlockMethods[] = { /* name, signature, funcPtr */ - { "nativeCreate", "([BII)I", + { "nativeCreate", "([BII)J", (void*) android_content_XmlBlock_nativeCreate }, - { "nativeGetStringBlock", "(I)I", + { "nativeGetStringBlock", "(J)J", (void*) android_content_XmlBlock_nativeGetStringBlock }, - { "nativeCreateParseState", "(I)I", + { "nativeCreateParseState", "(J)J", (void*) android_content_XmlBlock_nativeCreateParseState }, - { "nativeNext", "(I)I", + { "nativeNext", "(J)I", (void*) android_content_XmlBlock_nativeNext }, - { "nativeGetNamespace", "(I)I", + { "nativeGetNamespace", "(J)I", (void*) android_content_XmlBlock_nativeGetNamespace }, - { "nativeGetName", "(I)I", + { "nativeGetName", "(J)I", (void*) android_content_XmlBlock_nativeGetName }, - { "nativeGetText", "(I)I", + { "nativeGetText", "(J)I", (void*) android_content_XmlBlock_nativeGetText }, - { "nativeGetLineNumber", "(I)I", + { "nativeGetLineNumber", "(J)I", (void*) android_content_XmlBlock_nativeGetLineNumber }, - { "nativeGetAttributeCount", "(I)I", + { "nativeGetAttributeCount", "(J)I", (void*) android_content_XmlBlock_nativeGetAttributeCount }, - { "nativeGetAttributeNamespace","(II)I", + { "nativeGetAttributeNamespace","(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeNamespace }, - { "nativeGetAttributeName", "(II)I", + { "nativeGetAttributeName", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeName }, - { "nativeGetAttributeResource", "(II)I", + { "nativeGetAttributeResource", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeResource }, - { "nativeGetAttributeDataType", "(II)I", + { "nativeGetAttributeDataType", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeDataType }, - { "nativeGetAttributeData", "(II)I", + { "nativeGetAttributeData", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeData }, - { "nativeGetAttributeStringValue", "(II)I", + { "nativeGetAttributeStringValue", "(JI)I", (void*) android_content_XmlBlock_nativeGetAttributeStringValue }, - { "nativeGetAttributeIndex", "(ILjava/lang/String;Ljava/lang/String;)I", + { "nativeGetAttributeIndex", "(JLjava/lang/String;Ljava/lang/String;)I", (void*) android_content_XmlBlock_nativeGetAttributeIndex }, - { "nativeGetIdAttribute", "(I)I", + { "nativeGetIdAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetIdAttribute }, - { "nativeGetClassAttribute", "(I)I", + { "nativeGetClassAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetClassAttribute }, - { "nativeGetStyleAttribute", "(I)I", + { "nativeGetStyleAttribute", "(J)I", (void*) android_content_XmlBlock_nativeGetStyleAttribute }, - { "nativeDestroyParseState", "(I)V", + { "nativeDestroyParseState", "(J)V", (void*) android_content_XmlBlock_nativeDestroyParseState }, - { "nativeDestroy", "(I)V", + { "nativeDestroy", "(J)V", (void*) android_content_XmlBlock_nativeDestroy }, }; diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp index a796302c9a9a..9379375108be 100644 --- a/core/jni/android_view_DisplayList.cpp +++ b/core/jni/android_view_DisplayList.cpp @@ -105,16 +105,23 @@ static void android_view_DisplayList_setClipToBounds(JNIEnv* env, displayList->setClipToBounds(clipToBounds); } -static void android_view_DisplayList_setIsContainedVolume(JNIEnv* env, - jobject clazz, jlong displayListPtr, jboolean isContainedVolume) { +static void android_view_DisplayList_setIsolatedZVolume(JNIEnv* env, + jobject clazz, jlong displayListPtr, jboolean shouldIsolate) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - displayList->setIsContainedVolume(isContainedVolume); + displayList->setIsolatedZVolume(shouldIsolate); } -static void android_view_DisplayList_setProjectToContainedVolume(JNIEnv* env, +static void android_view_DisplayList_setProjectBackwards(JNIEnv* env, jobject clazz, jlong displayListPtr, jboolean shouldProject) { DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); - displayList->setProjectToContainedVolume(shouldProject); + displayList->setProjectBackwards(shouldProject); +} + +static void android_view_DisplayList_setOutline(JNIEnv* env, + jobject clazz, jlong displayListPtr, jlong outlinePathPtr) { + DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr); + SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr); + displayList->setOutline(outline); } static void android_view_DisplayList_setAlpha(JNIEnv* env, @@ -383,9 +390,9 @@ static JNINativeMethod gMethods[] = { { "nSetStaticMatrix", "(JJ)V", (void*) android_view_DisplayList_setStaticMatrix }, { "nSetAnimationMatrix", "(JJ)V", (void*) android_view_DisplayList_setAnimationMatrix }, { "nSetClipToBounds", "(JZ)V", (void*) android_view_DisplayList_setClipToBounds }, - { "nSetIsContainedVolume", "(JZ)V", (void*) android_view_DisplayList_setIsContainedVolume }, - { "nSetProjectToContainedVolume", "(JZ)V", - (void*) android_view_DisplayList_setProjectToContainedVolume }, + { "nSetIsolatedZVolume", "(JZ)V", (void*) android_view_DisplayList_setIsolatedZVolume }, + { "nSetProjectBackwards", "(JZ)V", (void*) android_view_DisplayList_setProjectBackwards }, + { "nSetOutline", "(JJ)V", (void*) android_view_DisplayList_setOutline }, { "nSetAlpha", "(JF)V", (void*) android_view_DisplayList_setAlpha }, { "nSetHasOverlappingRendering", "(JZ)V", (void*) android_view_DisplayList_setHasOverlappingRendering }, diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 19ee8a69f032..ab6c1e0c3d9a 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -114,7 +114,8 @@ jobject android_view_Surface_createFromIGraphicBufferProducer(JNIEnv* env, return NULL; } - jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor, surface.get()); + jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, + gSurfaceClassInfo.ctor, (jlong)surface.get()); if (surfaceObj == NULL) { if (env->ExceptionCheck()) { ALOGE("Could not create instance of Surface from IGraphicBufferProducer."); diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index 835615ef8009..77ede33ca150 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -128,7 +128,7 @@ static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject te static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( - env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); + env->GetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas)); env->SetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas, (jlong)newCanvas); env->SetLongField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (jlong)newCanvas); SkSafeUnref(previousCanvas); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 2151d4cf8950..315b11910857 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1727,6 +1727,13 @@ android:label="@string/permlab_recovery" android:description="@string/permdesc_recovery" /> + <!-- Allows the system to bind to an application's idle services + @hide --> + <permission android:name="android.permission.BIND_IDLE_SERVICE" + android:protectionLevel="signature" + android:label="@string/permlab_bindIdleService" + android:description="@string/permdesc_bindIdleService" /> + <!-- ========================================= --> <!-- Permissions for special development tools --> <!-- ========================================= --> @@ -2386,13 +2393,13 @@ @hide --> <permission android:name="android.permission.READ_DREAM_STATE" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|system" /> <!-- Allows applications to write dream settings, and start or stop dreaming. @hide --> <permission android:name="android.permission.WRITE_DREAM_STATE" android:permissionGroup="android.permission-group.SYSTEM_TOOLS" - android:protectionLevel="signature" /> + android:protectionLevel="signature|system" /> <!-- Allow an application to read and write the cache partition. @hide --> @@ -2728,6 +2735,14 @@ </intent-filter> </service> + <service android:name="com.android.server.MountServiceIdler" + android:exported="false" + android:permission="android.permission.BIND_IDLE_SERVICE" > + <intent-filter> + <action android:name="android.service.idle.IdleService" /> + </intent-filter> + </service> + </application> </manifest> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 25c6f99da9b9..b55054503ecb 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ontsluit tans SIM-kaart…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Verkeerde PIN-kode."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Tik \'n PIN in wat 4 tot 8 syfers lank is."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-kode moet 8 syfers wees."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Voer weer die korrekte PUK-kode in. Herhaalde pogings sal die SIM permanent deaktiveer."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodes stem nie ooreen nie"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogings"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index be8f7131d4b1..861ae68f7305 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ሲም ካርዱን በመክፈት ላይ…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ትክክል ያልሆነ ፒን ኮድ።"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"የፒዩኬ ኮድ 8 ቁጥሮች ነው መሆን ያለበት።"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"ትክክለኛውን የPUK ኮድ እንደገና ያስገቡ። ተደጋጋሚ ሙከራዎች ሲም ካርዱን እስከመጨረሻው ያሰናክሉታል።"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ፒን ኮዶች አይገጣጠሙም"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"በጣም ብዙ የስርዓተ ጥለት ሙከራዎች"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index a58d8b7dd290..e20b7b493d14 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"جارٍ إلغاء تأمين بطاقة SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"رمز PIN غير صحيح."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"اكتب رمز PIN المكون من 4 إلى 8 أرقام."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"يجب أن يتكون رمز PUK من 8 أرقام."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"أعد إدخال رمز PUK الصحيح. وستؤدي المحاولات المتكررة إلى تعطيل بطاقة SIM نهائيًا."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"لا يتطابق رمزا رمز PIN"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"محاولات النقش كثيرة جدًا"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index c28550c69488..1dbb05057746 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картата се отключва…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправилен ПИН код."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Въведете ПИН код с четири до осем цифри."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK кодът трябва да е с осем цифри."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Въведете отново правилния PUK код. Многократните опити ще деактивират за постоянно SIM картата."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ПИН кодовете не съвпадат"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Опитите за фигурата са твърде много"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index a1b4aed7b9a9..8eadf2c1c07c 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"S\'està desbloquejant la targeta SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codi PIN incorrecte."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escriu un PIN que tingui de 4 a 8 números."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El codi PUK ha de tenir 8 números."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Torna a introduir el codi PUK correcte. Els intents repetits faran que es desactivi la SIM de manera permanent."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Els codis PIN no coincideixen"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Massa intents incorrectes"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 906d352c9dcc..8cf6d8d55d16 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokování SIM karty..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávný kód PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadejte kód PIN o délce 4–8 číslic."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Kód PUK by měl obsahovat 8 číslic."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Znovu zadejte správný kód PUK. Opakovanými pokusy SIM kartu trvale deaktivujete."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN se neshodují."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Příliš mnoho pokusů o nakreslení gesta"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 4ab3d711c029..565578fba74b 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortet låses op…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Forkert pinkode."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Indtast en pinkode på mellem 4 og 8 tal."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-koden skal være på 8 tal."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Indtast den korrekte PUK-kode. Gentagne forsøg vil permanent deaktivere SIM-kortet."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pinkoderne stemmer ikke overens"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøg på at tegne mønstret korrekt"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 8e681f1dfa1e..b244fd9b6906 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-Karte wird entsperrt…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Falscher PIN-Code"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Geben Sie eine 4- bis 8-stellige PIN ein."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Der PUK-Code muss 8 Ziffern aufweisen."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Geben Sie den richtigen PUK-Code ein. Bei wiederholten Versuchen wird die SIM-Karte dauerhaft deaktiviert."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-Codes stimmen nicht überein"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zu viele Musterversuche"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 64d7233480fd..b7050dc9641c 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ξεκλείδωμα κάρτας SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Εσφαλμένος κωδικός PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Πληκτρολογήστε έναν αριθμό PIN που να αποτελείται από 4 έως 8 αριθμούς."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Ο κωδικός PUK θα πρέπει να αποτελείται από 8 αριθμούς."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Εισαγάγετε ξανά τον κωδικό PUK. Οι επαναλαμβανόμενες προσπάθειες θα απενεργοποιήσουν οριστικά την κάρτα SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Δεν υπάρχει αντιστοιχία των κωδικών PIN"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Πάρα πολλές προσπάθειες μοτίβου"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index b75e16919760..fdaae8be5bf3 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index b75e16919760..fdaae8be5bf3 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Unlocking SIM card…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Incorrect PIN code."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Type a PIN that is 4 to 8 numbers."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Re-enter the correct PUK code. Repeated attempts will permanently disable the SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN codes do not match"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Too many pattern attempts"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index bb03deaab79c..1e94bd93e2cb 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Escribe un PIN que tenga de cuatro a ocho números."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener 8 números."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a ingresar el código PUK correcto. Si ingresas un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de ingresar el patrón"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 16768ced2ae7..75f1c6dff4fc 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando tarjeta SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorrecto"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduce un código PIN con una longitud comprendida entre cuatro y ocho dígitos."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener ocho números."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Vuelve a introducir el código PUK correcto. Si introduces un código incorrecto varias veces, se inhabilitará la tarjeta SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Los códigos PIN no coinciden."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiados intentos incorrectos de crear el patrón"</string> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index f79c905699dc..dcf38acda18b 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kaardi avamine ..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Vale PIN-kood."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Sisestage 4–8-numbriline PIN-kood."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-kood peab sisaldama 8 numbrit."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Sisestage uuesti õige PUK-kood. Korduvkatsete korral keelatakse SIM jäädavalt."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodid ei ole vastavuses"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liiga palju mustrikatseid"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 9c85499ea0ec..465d1e25f1b7 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"بازگشایی قفل سیم کارت..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"پین کد اشتباه است."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"یک پین ۴ تا ۸ رقمی را تایپ کنید."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"کد PUK باید ۸ عدد داشته باشد."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"پین کد صحیح را دوباره وارد کنید. تلاشهای مکرر بهطور دائم سیم کارت را غیرفعال خواهد کرد."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"پین کدها منطبق نیستند"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 350919854756..5f1ecbd16656 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM-kortin lukitusta poistetaan…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Virheellinen PIN-koodi."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Anna 4–8-numeroinen PIN-koodi."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-koodissa tulee olla 8 numeroa."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Anna uudelleen oikea PUK-koodi. Jos teet liian monta yritystä, SIM-kortti poistetaan käytöstä pysyvästi."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koodit eivät täsmää"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Liikaa kuvionpiirtoyrityksiä"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 46faca5ab4da..237519468ecc 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"NIP erroné."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Saisissez un NIP comprenant entre quatre et huit chiffres"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Le code PUK doit contenir 8 chiffres."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 349d4b8bb8b0..685ed0484ea1 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Déblocage de la carte SIM en cours…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Le code PIN est erroné."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Veuillez saisir un code PIN comprenant entre quatre et huit chiffres."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"La clé PUK doit contenir 8 chiffres."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Veuillez saisir de nouveau le code PUK correct. Des tentatives répétées désactivent définitivement la carte SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Les codes PIN ne correspondent pas."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Trop de tentatives."</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index feeac91fb4db..264a0e5ff6bc 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM कार्ड अनलॉक कर रहा है…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"गलत PIN कोड."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ऐसा PIN लिखें, जो 4 से 8 अंकों का हो."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK कोड 8 अंकों का होना चाहिए."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड का मिलान नहीं होता"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बहुत अधिक आकार प्रयास"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 383d0e19753f..0880d2f8d330 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Otključavanje SIM kartice…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netočan PIN kôd."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Unesite PIN koji ima od 4 do 8 brojeva."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kôd mora se sastojati od 8 brojeva."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji trajno će onemogućiti SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodovi nisu jednaki"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Previše pokušaja iscrtavanja obrasca"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 712ffb17975c..5eadb47208e3 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kártya feloldása..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Helytelen PIN kód."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4–8 számjegyű PIN kódot írjon be."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"A PUK kód 8 karakter hosszú kell, hogy legyen."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Adja meg újra a helyes PUK kódot. Az ismételt próbálkozással véglegesen letiltja a SIM kártyát."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"A PIN kódok nem egyeznek."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Túl sok mintarajzolási próbálkozás"</string> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index 85efbf6200cd..1a5228d1342f 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ապակողպում է SIM քարտը ..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Սխալ PIN ծածկագիր:"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Մուտքագրեք PIN, որը 4-ից 8 թիվ է:"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK կոդը պետք է լինի 8 թիվ:"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Վերամուտքագրեք ճիշտ PUK ծածկագիրը: Կրկնվող փորձերը ընդմիշտ կկասեցնեն SIM քարտը:"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ծածկագրերը չեն համընկնում"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Չափից շատ սխեմայի փորձեր"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 0c42580c0662..0e1d5b6fe195 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kartu SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kode PIN salah."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ketik PIN yang terdiri dari 4 sampai 8 angka."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Kode PUK seharusnya terdiri dari 8 angka."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan kembali kode PUK yang benar. Jika berulang kali gagal, SIM akan dinonaktifkan secara permanen."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kode PIN tidak cocok"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak upaya pola"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index d48c88a705c4..75c887ef2245 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Sblocco scheda SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Codice PIN errato."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Il PIN deve essere di 4-8 numeri."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Il codice PUK deve essere di 8 cifre."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Inserisci di nuovo il codice PUK corretto. Ripetuti tentativi comportano la disattivazione definitiva della scheda SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"I codici PIN non corrispondono"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Troppi tentativi di inserimento della sequenza"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index a4ed51c94956..008d0789af78 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"מבטל נעילה של כרטיס SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"קוד PIN שגוי."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"הקלד מספר PIN שאורכו 4 עד 8 ספרות."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"קוד PUK צריך להיות בן 8 ספרות."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"הזן מחדש את קוד PUK הנכון. ניסיונות חוזרים ישביתו לצמיתות את כרטיס ה-SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"קודי ה-PIN אינם תואמים"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index b0c15832cced..4a994b2daf7d 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIMカードのロック解除中…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PINコードが正しくありません。"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"PINは4~8桁の数字で入力してください。"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUKコードは8桁の番号です。"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"正しいPUKコードを再入力してください。誤入力を繰り返すと、SIMが永久に無効になるおそれがあります。"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PINコードが一致しません"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"パターンの入力を所定の回数以上間違えました。"</string> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 49f5cdeb71cb..7e13e967e3f8 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ბარათის განბლოკვა…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"არასწორი PIN კოდი."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"აკრიფეთ PIN, რომელიც შედგება 4-დან 8 ციფრამდე."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-კოდი 8 ციფრისგან უნდა შედგებოდეს."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"ხელახლა შეიყვანეთ სწორი PUK კოდი. რამდენიმე წარუმატებელი მცდელობა გამოიწვევს SIM ბარათის დაბლოკვას."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN კოდები არ ემთხვევა"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ნახატი ნიმუშის ძალიან ბევრი მცდელობა"</string> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index cb032a2e6bbb..38d518a34480 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -1200,7 +1200,7 @@ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"មិនអាចតភ្ជាប់វ៉ាយហ្វាយ"</string> <string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" មានការតភ្ជាប់អ៊ីនធឺណិតមិនល្អ។"</string> <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"វ៉ាយហ្វាយផ្ទាល់"</string> - <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ចាប់ផ្ដើមវ៉ាយហ្វាយដោយផ្ទាល់។ វានឹងបិទវ៉ាយហ្វាយ ។"</string> + <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ចាប់ផ្ដើមវ៉ាយហ្វាយផ្ទាល់។ វានឹងបិទវ៉ាយហ្វាយហតស្ពត។"</string> <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"មិនអាចចាប់ផ្ដើមវ៉ាយហ្វាដោយផ្ទាល់។"</string> <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"បើកវ៉ាយហ្វាយផ្ទាល់"</string> <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"ប៉ះ ដើម្បីកំណត់"</string> @@ -1357,7 +1357,7 @@ <string name="submit" msgid="1602335572089911941">"ដាក់ស្នើ"</string> <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"បានបើករបៀបរថយន្ត"</string> <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"ប៉ះ ដើម្បីចេញពីរបៀបរថយន្ត។"</string> - <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬ hotspot សកម្ម"</string> + <string name="tethered_notification_title" msgid="3146694234398202601">"ភ្ជាប់ ឬហតស្ពតសកម្ម"</string> <string name="tethered_notification_message" msgid="6857031760103062982">"ប៉ះ ដើម្បីរៀបចំ។"</string> <string name="back_button_label" msgid="2300470004503343439">"ថយក្រោយ"</string> <string name="next_button_label" msgid="1080555104677992408">"បន្ទាប់"</string> @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"កំពុងដោះសោស៊ីមកាត..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"កូដ PIN មិនត្រឹមត្រូវ។"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"បញ្ចូលកូដ PIN ដែលមានពី ៤ ដល់ ៨ លេខ។"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"លេខកូដ PUK គួរតែមាន ៨ខ្ទង់"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"បញ្ចូលកូដ PUK ម្ដងទៀត។ ការព្យាយាមដដែលច្រើនដឹងនឹងបិទស៊ីមកាតជាអចិន្ត្រៃយ៍។"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិនដូចគ្នា"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 7d1b7be3588d..a51e605b8de5 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM 카드 잠금해제 중..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 코드가 잘못되었습니다."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4~8자리 숫자로 된 PIN을 입력하세요."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK 코드는 8자리 숫자여야 합니다."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"올바른 PUK 코드를 다시 입력하세요. 입력을 반복해서 시도하면 SIM을 영구적으로 사용할 수 없게 됩니다."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 코드가 일치하지 않음"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"패턴 시도 횟수가 너무 많음"</string> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index db595e84a435..c7aed5176676 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ປົດລັອກ SIM card..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ລະຫັດ PIN ບໍ່ຖືກຕ້ອງ."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ພິມລະຫັດ PIN ຄວາມຍາວ 4 ເຖິງ 8 ໂຕເລກ."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"ລະຫັດ PUK ຄວນມີ 8 ໂຕເລກ"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 2d92c1775730..6b5191d49be6 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Atrakinama SIM kortelė…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Netinkamas PIN kodas."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Įveskite PIN kodą, sudarytą iš 4–8 skaičių."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kodą turi sudaryti 8 skaičiai."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Pakartotinai įveskite tinkamą PUK kodą. Pakartotinai bandant SIM bus neleidžiama visam laikui."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodai neatitinka"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Per daug atrakinimo piešinių bandymų"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 9fd25a5cddf7..74022a98e8a1 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Notiek SIM kartes atbloķēšana..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN kods nav pareizs."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ievadiet PIN, kas sastāv no 4 līdz 8 cipariem."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kodā ir jābūt 8 cipariem."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Atkārtoti ievadiet pareizo PUK kodu. Ja vairākas reizes ievadīsiet to nepareizi, SIM karte tiks neatgriezeniski atspējota."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodi neatbilst."</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Pārāk daudz kombinācijas mēģinājumu"</string> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index 59c87f722ed3..82cdab6516c5 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картны түгжээг гаргаж байна…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Буруу PIN код."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 тооноос бүтэх PIN-г бичнэ үү."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK код 8 тоотой байх ёстой."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Зөв PUK кодыг дахин оруулна уу. Давтан оролдвол SIM нь бүрмөсөн идэвхгүй болгоно."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодууд таарахгүй байна"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Хээ оруулах оролдлого хэт олон"</string> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 62cdcaf851b9..f9d005db3770 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Kod PUK mestilah 8 nombor."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 26074f79abb4..e6b29c235522 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser opp SIM-kortet ..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Feil PIN-kode."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Skriv inn en PIN-kode på fire til åtte sifre."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-koden skal være på åtte sifre."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Skriv inn den korrekte PUK-koden på nytt. Gjentatte forsøk kommer til å deaktivere SIM-kortet."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodene stemmer ikke overens"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøk på tegning av mønster"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index da0277e99cc1..3c0ba73b9e9b 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Simkaart ontgrendelen..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Onjuiste pincode."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Voer een pincode van 4 tot 8 cijfers in."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"De PUK-code is acht cijfers lang."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Geef de juiste PUK-code opnieuw op. Bij herhaalde pogingen wordt de simkaart permanent uitgeschakeld."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Pincodes komen niet overeen"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Te veel patroonpogingen"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 5838a0b08a81..96f3b39afaf4 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odblokowuję kartę SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nieprawidłowy PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Wpisz PIN o długości od 4 do 8 cyfr."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK musi mieć 8 cyfr."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Ponownie podaj poprawny kod PUK. Nieudane próby spowodują trwałe wyłączenie karty SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kody PIN nie pasują"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Zbyt wiele prób narysowania wzoru"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 238f161cf7de..261525c6a1f5 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"A desbloquear cartão SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduza um PIN entre 4 e 8 números."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"O código PUK deve ter 8 números."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Volte a introduzir o código PUK correto. Demasiadas tentativas consecutivas irão desativar permanentemente o SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não correspondem"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Demasiadas tentativas para desenhar sequência"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 2969a3fb98e2..6a80a78f0b1a 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Desbloqueando o cartão SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Código PIN incorreto."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Digite um PIN com quatro a oito números."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"O código PUK deve ter oito números."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Introduza novamente o código PUK correto. Muitas tentativas malsucedidas desativarão permanentemente o SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Os códigos PIN não coincidem"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Muitas tentativas de padrão"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 4d6f45914a59..b222103a500b 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Cod PIN incorect."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Codul PUK trebuie să conțină 8 numere."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Reintroduceţi codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Codurile PIN nu coincid"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Prea multe încercări de desenare a modelului"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 330b6d37f62d..c28a019b1f54 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Разблокировка SIM-карты…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неверный PIN-код."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введите PIN-код (от 4 до 8 цифр)."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-код должен содержать 8 символов."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Введите правильный PUK-код. После нескольких неудачных попыток SIM-карта будет заблокирована."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коды не совпадают"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Слишком много попыток ввода графического ключа"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 1137fbfe0bfa..399eeee5480a 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Prebieha odomykanie karty SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávny kód PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Kód PUK musí obsahovať 8 číslic."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Znova zadajte správny kód PUK. Opakované pokusy zakážu kartu SIM natrvalo."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN sa nezhodujú"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Príliš veľa pokusov o nakreslenie vzoru"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 4064d2890c0f..7c0dc6314be8 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Odklepanje kartice SIM ..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Napačna koda PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Vnesite PIN, ki vsebuje od štiri do osem številk."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Koda PUK mora biti 8-mestno število."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Vnovič vnesite pravilno kodo PUK. Večkratni poskusi bodo trajno onemogočili kartico SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kodi PIN se ne ujemata"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Preveč poskusov vzorca"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 3ec4982f7121..5b5f451aab9b 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Откључавање SIM картице…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN кôд је нетачан."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Унесите PIN који има од 4 до 8 бројева."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK кôд треба да има 8 бројева."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Поново унесите исправни PUK кôд. Поновљени покушаји ће трајно онемогућити SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN кодови се не подударају"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Превише покушаја уноса шаблона"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 33a9a18b185d..bdd8e7699dcd 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -157,7 +157,7 @@ <string name="reboot_safemode_title" msgid="7054509914500140361">"Starta om i felsäkert läge"</string> <string name="reboot_safemode_confirm" msgid="55293944502784668">"Vill du starta om datorn i felsäkert läge? Då inaktiveras alla appar från tredje part som du har installerat. Apparna återställs när du startar om datorn igen."</string> <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string> - <string name="no_recent_tasks" msgid="8794906658732193473">"Inga nya appar."</string> + <string name="no_recent_tasks" msgid="8794906658732193473">"Inga aktiva appar."</string> <string name="global_actions" product="tablet" msgid="408477140088053665">"Alternativ för surfplattan"</string> <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonalternativ"</string> <string name="global_action_lock" msgid="2844945191792119712">"Skärmlås"</string> @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser upp SIM-kort …"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Fel PIN-kod."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Ange en PIN-kod med 4 till 8 siffror."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-koden ska vara åtta siffror."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Ange rätt PUK-kod igen. Om försöken upprepas inaktiveras SIM-kortet permanent."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-koderna stämmer inte överens"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"För många försök med grafiskt lösenord"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 45a36f259616..d0fcc09ae928 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -891,8 +891,8 @@ <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Ruwaza imefutwa"</string> <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kiini kimeongezwa"</string> <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Ruwaza imekamilika"</string> - <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wiji %2$d ya %3$d."</string> - <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wiji"</string> + <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string> + <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string> <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Eneo la kufungua limepanuliwa."</string> <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Eneo la kufungua limekunjwa."</string> @@ -901,7 +901,7 @@ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Hali"</string> <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string> <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Vidhibiti vya media"</string> - <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wiji umeanza."</string> + <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wijeti umeanza."</string> <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Upangaji upya wa wiji umekamilika."</string> <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Wiji <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> imefutwa."</string> <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Panua eneo la kufungua."</string> @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Inafungua SIM kadi..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Msimbo wa PIN usio sahihi."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Charaza PIN iliyo na tarakimu kati ya 4 na 8."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Msimbo wa PUK lazima uwe na tarakimu 8."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Ingiza upya msimbo sahihi wa PUK. Majaribio yanayorudiwa yatalemaza SIM kabisa."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Misimbo ya PIN haifanani"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Majaribio mengi mno ya mchoro"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 05cddc5f97ae..a0b2ee47ee5d 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"กำลังปลดล็อกซิมการ์ด…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"รหัส PIN ไม่ถูกต้อง"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"พิมพ์ PIN ซึ่งเป็นเลข 4 ถึง 8 หลัก"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"รหัส PUK ต้องเป็นตัวเลข 8 ตัว"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"รหัส PIN ไม่ตรง"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ลองหลายรูปแบบมากเกินไป"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 1cb0336b97d1..af36cee8b35b 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ina-unlock ang SIM card…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Hindi tamang PIN code."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Mag-type ng PIN na 4 hanggang 8 numero."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"8 numero dapat ang PUK code."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Muling ilagay ang tamang PUK code. Permanenteng hindi pagaganahin ang SIM ng mga paulit-ulit na pagtatangka."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Hindi tumutugma ang mga PIN code"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Masyadong maraming pagtatangka sa pattern"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 7ccf960c522b..99d415a42002 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM kart kilidi açılıyor…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Yanlış PIN kodu."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4-8 rakamdan oluşan bir PIN girin."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK kodu 8 basamaklı bir sayı olmalıdır."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Doğru PUK kodunu tekrar girin. Çok sayıda deneme yapılırsa SIM kart kalıcı olarak devre dışı bırakılır."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN kodları eşleşmiyor"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Çok fazla sayıda desen denemesi yapıldı"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index a707a032896d..da50f734d542 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Розблокування SIM-карти…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправильний PIN-код."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Введіть PIN-код із 4–8 цифр."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK-код має складатися з 8 цифр."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Повторно введіть правильний PUK-код. Численні спроби назавжди вимкнуть SIM-карту."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-коди не збігаються"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Забагато спроб намалювати ключ"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index d3295a2cdded..0cabb12a52e6 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Đang mở khóa thẻ SIM…"</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Mã PIN không chính xác."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Nhập mã PIN có từ 4 đến 8 số."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Mã PUK phải có 8 số."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Hãy nhập lại mã PUK chính xác. Nhiều lần lặp lại sẽ vô hiệu hóa vĩnh viễn thẻ SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Mã PIN không khớp"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Quá nhiều lần nhập hình"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index a9900ecd783f..507b29b4ede7 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解锁 SIM 卡..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 码有误。"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"请输入 4 至 8 位数的 PIN。"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK码应包含8位数字。"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"请重新输入正确的 PUK 码。如果尝试错误次数过多,SIM 卡将永久停用。"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 码不匹配"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"图案尝试次数过多"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index eb5c05b5bb57..e5441a2e8858 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解開上鎖的 SIM 卡..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入一個 4 至 8 位數的 PIN 碼。"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK 碼應由 8 位數字組成。"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"請重新輸入正確的 PUK 碼。如果嘗試輸入的次數過多,SIM 卡將永久停用。"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖案嘗試次數過多"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index 00254e201453..153f85fd1a14 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"正在解除 SIM 卡鎖定..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"PIN 碼不正確。"</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"請輸入 4 到 8 碼的 PIN。"</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK 碼必須為 8 碼。"</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"重新輸入正確的 PUK 碼。如果錯誤次數過多,SIM 卡將會永久停用。"</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN 碼不符"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"圖形嘗試次數過多"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 4218dd505520..268760310acd 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1526,8 +1526,7 @@ <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Ivula ikhadi le-SIM..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Iphinikhodi engalungile."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Thayipha iphinikhodi enezinombolo ezingu-4 kuya kwezingu-8."</string> - <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) --> - <skip /> + <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Ikhodi ye-PUK kumele ibe yizinombolo ezingu-8."</string> <string name="kg_invalid_puk" msgid="3638289409676051243">"Faka kabusha ikhodi ye-PUK elungile. Imizamo ephindiwe izokhubaza unaphakade i-SIM."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Iphinikhodi ayifani"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Kunemizamo eminingi kakhulu yephathini"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index c603418c0f0a..f77d66b19c22 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2244,6 +2244,12 @@ Hence, the TextView is a label for the EditText. --> <attr name="labelFor" format="integer" /> + <!-- Specifies a theme override for a view. When a theme override is set, the + view will be inflated using a {@link android.content.Context} themed with + the specified resource. During XML inflation, any child views under the + view with a theme override will inherit the themed context. --> + <attr name="theme" /> + </declare-styleable> <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any @@ -2264,6 +2270,9 @@ <!-- Defines whether the ViewGroup will clip its drawing surface so as to exclude the padding area. This property is set to true by default. --> <attr name="clipToPadding" format="boolean" /> + <!-- Defines whether 3d composited descendents of the ViewGroup will be reordered into their + own independent Z volume. This property is set to true by default. --> + <attr name="isolatedZVolume" format="boolean" /> <!-- Defines the layout animation to use the first time the ViewGroup is laid out. Layout animations can also be started manually after the first layout. --> <attr name="layoutAnimation" format="reference" /> @@ -4648,6 +4657,13 @@ <attr name="extraTension" format="float" /> </declare-styleable> + <declare-styleable name="PathInterpolator"> + <attr name="controlX1" format="float" /> + <attr name="controlY1" format="float" /> + <attr name="controlX2" format="float" /> + <attr name="controlY2" format="float" /> + </declare-styleable> + <!-- ========================== --> <!-- Transition attributes --> <!-- ========================== --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 6969d2ccc21b..e99b5bad4332 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2099,6 +2099,11 @@ <public type="attr" name="translationZ" /> <public type="attr" name="colorFilterColor" /> <public type="attr" name="colorFilterMode" /> + <public type="attr" name="isolatedZVolume" /> + <public type="attr" name="controlX1" /> + <public type="attr" name="controlY1" /> + <public type="attr" name="controlX2" /> + <public type="attr" name="controlY2" /> <public type="style" name="Widget.Holo.FragmentBreadCrumbs" /> <public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 785e788c5c3e..ee6819903c44 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1176,6 +1176,11 @@ <string name="permdesc_manageCaCertificates">Allows the app to install and uninstall CA certificates as trusted credentials.</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_bindIdleService">bind to idle services</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_bindIdleService">Allows the app to interact with application-defined idle services.</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_diagnostic">read/write to resources owned by diag</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_diagnostic">Allows the app to read and write to diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd index f3027a95c064..5a7e27049b1d 100644 --- a/docs/html/sdk/installing/studio.jd +++ b/docs/html/sdk/installing/studio.jd @@ -253,36 +253,36 @@ download (or continue to use) the <td>Windows</td> <td> <a onclick="return onDownload(this)" id="win-studio" - href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-windows.exe"> - android-studio-bundle-132.893413-windows.exe + href="http://dl.google.com/android/studio/install/0.4.2/android-studio-bundle-133.970939-windows.exe"> + android-studio-bundle-133.970939-windows.exe </a> </td> - <td>484345454 bytes</td> - <td>14cbf0109a822688f4e2f886c0b0c85a</td> + <td>515261701 bytes</td> + <td>1e1ae28b1c00f43d55f17ee35bd4f5d2</td> </tr> <tr> <td><nobr>Mac OS X</nobr></td> <td> <a onclick="return onDownload(this)" id="mac-studio" - href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-mac.dmg"> - android-studio-bundle-132.893413-mac.dmg + href="http://dl.google.com/android/studio/install/0.4.2/android-studio-bundle-133.970939-mac.dmg"> + android-studio-bundle-133.970939-mac.dmg </a> </td> - <td>463332508 bytes</td> - <td>0cd4ac59864890f7de57314bcc7ea5aa</td> + <td>491773471 bytes</td> + <td>6753f67c56acb17617bfbc5bc56384e7</td> </tr> <tr> <td>Linux</td> <td> <a onclick="return onDownload(this)" id="linux-studio" - href="http://dl.google.com/android/studio/install/0.3.2/android-studio-bundle-132.893413-linux.tgz"> - android-studio-bundle-132.893413-linux.tgz + href="http://dl.google.com/android/studio/install/0.4.2/android-studio-bundle-133.970939-linux.tgz"> + android-studio-bundle-133.970939-linux.tgz </a> </td> - <td>487694946 bytes</td> - <td>9f1306100314b03ff5b691b94f154501</td> + <td>516080363 bytes</td> + <td>25455787d76e61baf34bf93eaa00ded6</td> </tr> </table> @@ -424,6 +424,19 @@ style="vertical-align:bottom;margin:0;height:19px" /> in the toolbar.</p> <div class="toggle-content opened"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" + alt=""/>Android Studio v0.4.2</a> <em>(Jan 2014)</em> + </p> + + <div class="toggle-content-toggleme"> + <ul> + <li>See <a href="http://tools.android.com/recent">tools.android.com</a> for a full list of changes.</li> + </ul> + </div> +</div> + +<div class="toggle-content closed"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""/>Android Studio v0.3.2</a> <em>(Oct 2013)</em> </p> @@ -618,7 +631,7 @@ for possible resolutions to known issues: <a href="http://tools.android.com/know if (os) { /* set up primary ACE download button */ $('#download-ide-button').show(); - $('#download-ide-button').append("Download Android Studio <span class='small'>v0.3.2</span>" + $('#download-ide-button').append("Download Android Studio <span class='small'>v0.4.2</span>" + "<br/> <span class='small'>for " + os + "</span>"); $('#download-ide-button').click(function() {return onDownload(this,true);}).attr('href', bundlename); diff --git a/docs/html/training/displaying-bitmaps/process-bitmap.jd b/docs/html/training/displaying-bitmaps/process-bitmap.jd index 272b8bcb8f15..ed0b368623d0 100644 --- a/docs/html/training/displaying-bitmaps/process-bitmap.jd +++ b/docs/html/training/displaying-bitmaps/process-bitmap.jd @@ -172,7 +172,8 @@ public static boolean cancelPotentialWork(int data, ImageView imageView) { if (bitmapWorkerTask != null) { final int bitmapData = bitmapWorkerTask.data; - if (bitmapData != data) { + // If bitmapData is not yet set or it differs from the new data + if (bitmapData == 0 || bitmapData != data) { // Cancel previous task bitmapWorkerTask.cancel(true); } else { diff --git a/drm/java/android/drm/DrmManagerClient.java b/drm/java/android/drm/DrmManagerClient.java index 10cdab0c223c..c05ea2e1a1e5 100644 --- a/drm/java/android/drm/DrmManagerClient.java +++ b/drm/java/android/drm/DrmManagerClient.java @@ -116,7 +116,7 @@ public class DrmManagerClient { private static final int ACTION_PROCESS_DRM_INFO = 1002; private int mUniqueId; - private int mNativeContext; + private long mNativeContext; private volatile boolean mReleased; private Context mContext; private InfoHandler mInfoHandler; diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp index baddf6226018..de8531b74571 100644 --- a/drm/jni/android_drm_DrmManagerClient.cpp +++ b/drm/jni/android_drm_DrmManagerClient.cpp @@ -182,25 +182,27 @@ static sp<DrmManagerClientImpl> setDrmManagerClientImpl( JNIEnv* env, jobject thiz, const sp<DrmManagerClientImpl>& client) { Mutex::Autolock l(sLock); jclass clazz = env->FindClass("android/drm/DrmManagerClient"); - jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I"); + jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J"); - sp<DrmManagerClientImpl> old = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId); + jlong oldHandle = env->GetLongField(thiz, fieldId); + sp<DrmManagerClientImpl> old = reinterpret_cast<DrmManagerClientImpl*>(oldHandle); if (client.get()) { client->incStrong(thiz); } if (old != 0) { old->decStrong(thiz); } - env->SetIntField(thiz, fieldId, (int)client.get()); + env->SetLongField(thiz, fieldId, reinterpret_cast<jlong>(client.get())); return old; } static sp<DrmManagerClientImpl> getDrmManagerClientImpl(JNIEnv* env, jobject thiz) { Mutex::Autolock l(sLock); jclass clazz = env->FindClass("android/drm/DrmManagerClient"); - jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "I"); + jfieldID fieldId = env->GetFieldID(clazz, "mNativeContext", "J"); - DrmManagerClientImpl* const client = (DrmManagerClientImpl*)env->GetIntField(thiz, fieldId); + jlong clientHandle = env->GetLongField(thiz, fieldId); + DrmManagerClientImpl* const client = reinterpret_cast<DrmManagerClientImpl*>(clientHandle); return sp<DrmManagerClientImpl>(client); } @@ -214,7 +216,7 @@ static jint android_drm_DrmManagerClient_initialize( setDrmManagerClientImpl(env, thiz, drmManager); ALOGV("initialize - Exit"); - return uniqueId; + return static_cast<jint>(uniqueId); } static void android_drm_DrmManagerClient_setListeners( @@ -406,7 +408,7 @@ static jint android_drm_DrmManagerClient_saveRights( delete[] mData; mData = NULL; ALOGV("saveRights - Exit"); - return result; + return static_cast<jint>(result); } static jboolean android_drm_DrmManagerClient_canHandle( @@ -583,7 +585,7 @@ static jint android_drm_DrmManagerClient_getDrmObjectType( ->getDrmObjectType(uniqueId, Utility::getStringValue(env, path), Utility::getStringValue(env, mimeType)); ALOGV("getDrmObjectType Exit"); - return drmObjectType; + return static_cast<jint>(drmObjectType); } static jstring android_drm_DrmManagerClient_getOriginalMimeType( @@ -609,20 +611,21 @@ static jint android_drm_DrmManagerClient_checkRightsStatus( = getDrmManagerClientImpl(env, thiz) ->checkRightsStatus(uniqueId, Utility::getStringValue(env, path), action); ALOGV("checkRightsStatus Exit"); - return rightsStatus; + return static_cast<jint>(rightsStatus); } static jint android_drm_DrmManagerClient_removeRights( JNIEnv* env, jobject thiz, jint uniqueId, jstring path) { ALOGV("removeRights"); - return getDrmManagerClientImpl(env, thiz) - ->removeRights(uniqueId, Utility::getStringValue(env, path)); + return static_cast<jint>(getDrmManagerClientImpl(env, thiz) + ->removeRights(uniqueId, Utility::getStringValue(env, path))); } static jint android_drm_DrmManagerClient_removeAllRights( JNIEnv* env, jobject thiz, jint uniqueId) { ALOGV("removeAllRights"); - return getDrmManagerClientImpl(env, thiz)->removeAllRights(uniqueId); + return static_cast<jint>(getDrmManagerClientImpl(env, thiz) + ->removeAllRights(uniqueId)); } static jint android_drm_DrmManagerClient_openConvertSession( @@ -632,7 +635,7 @@ static jint android_drm_DrmManagerClient_openConvertSession( = getDrmManagerClientImpl(env, thiz) ->openConvertSession(uniqueId, Utility::getStringValue(env, mimeType)); ALOGV("openConvertSession Exit"); - return convertId; + return static_cast<jint>(convertId); } static jobject GetConvertedStatus(JNIEnv* env, DrmConvertedStatus* pDrmConvertedStatus) { @@ -686,7 +689,7 @@ static jobject android_drm_DrmManagerClient_convertData( } static jobject android_drm_DrmManagerClient_closeConvertSession( - JNIEnv* env, jobject thiz, int uniqueId, jint convertId) { + JNIEnv* env, jobject thiz, jint uniqueId, jint convertId) { ALOGV("closeConvertSession Enter"); diff --git a/graphics/java/android/graphics/Interpolator.java b/graphics/java/android/graphics/Interpolator.java index 75851a636380..f695a9ea2cf4 100644 --- a/graphics/java/android/graphics/Interpolator.java +++ b/graphics/java/android/graphics/Interpolator.java @@ -151,13 +151,13 @@ public class Interpolator { private int mValueCount; private int mFrameCount; - private final int native_instance; + private final long native_instance; - private static native int nativeConstructor(int valueCount, int frameCount); - private static native void nativeDestructor(int native_instance); - private static native void nativeReset(int native_instance, int valueCount, int frameCount); - private static native void nativeSetKeyFrame(int native_instance, int index, int msec, float[] values, float[] blend); - private static native void nativeSetRepeatMirror(int native_instance, float repeatCount, boolean mirror); - private static native int nativeTimeToValues(int native_instance, int msec, float[] values); + private static native long nativeConstructor(int valueCount, int frameCount); + private static native void nativeDestructor(long native_instance); + private static native void nativeReset(long native_instance, int valueCount, int frameCount); + private static native void nativeSetKeyFrame(long native_instance, int index, int msec, float[] values, float[] blend); + private static native void nativeSetRepeatMirror(long native_instance, float repeatCount, boolean mirror); + private static native int nativeTimeToValues(long native_instance, int msec, float[] values); } diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java index 5ac3f8549aef..2ce73acd12d3 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -28,7 +28,6 @@ public class Path { * @hide */ public final long mNativePath; - private long mNativePathMeasure; /** * @hide @@ -77,14 +76,6 @@ public class Path { final FillType fillType = getFillType(); native_reset(mNativePath); setFillType(fillType); - clearMeasure(); - } - - private void clearMeasure() { - if (mNativePathMeasure != 0) { - native_destroyMeasure(mNativePathMeasure); - mNativePathMeasure = 0; - } } /** @@ -96,7 +87,6 @@ public class Path { mLastDirection = null; if (rects != null) rects.setEmpty(); native_rewind(mNativePath); - clearMeasure(); } /** Replace the contents of this with the contents of src. @@ -105,7 +95,6 @@ public class Path { if (this != src) { isSimplePath = src.isSimplePath; native_set(mNativePath, src.mNativePath); - clearMeasure(); } } @@ -234,7 +223,6 @@ public class Path { */ public void setFillType(FillType ft) { native_setFillType(mNativePath, ft.nativeInt); - clearMeasure(); } /** @@ -254,7 +242,6 @@ public class Path { int ft = native_getFillType(mNativePath); ft ^= 2; native_setFillType(mNativePath, ft); - clearMeasure(); } /** @@ -311,7 +298,6 @@ public class Path { */ public void moveTo(float x, float y) { native_moveTo(mNativePath, x, y); - clearMeasure(); } /** @@ -326,7 +312,6 @@ public class Path { */ public void rMoveTo(float dx, float dy) { native_rMoveTo(mNativePath, dx, dy); - clearMeasure(); } /** @@ -340,7 +325,6 @@ public class Path { public void lineTo(float x, float y) { isSimplePath = false; native_lineTo(mNativePath, x, y); - clearMeasure(); } /** @@ -356,7 +340,6 @@ public class Path { public void rLineTo(float dx, float dy) { isSimplePath = false; native_rLineTo(mNativePath, dx, dy); - clearMeasure(); } /** @@ -372,7 +355,6 @@ public class Path { public void quadTo(float x1, float y1, float x2, float y2) { isSimplePath = false; native_quadTo(mNativePath, x1, y1, x2, y2); - clearMeasure(); } /** @@ -392,7 +374,6 @@ public class Path { public void rQuadTo(float dx1, float dy1, float dx2, float dy2) { isSimplePath = false; native_rQuadTo(mNativePath, dx1, dy1, dx2, dy2); - clearMeasure(); } /** @@ -411,7 +392,6 @@ public class Path { float x3, float y3) { isSimplePath = false; native_cubicTo(mNativePath, x1, y1, x2, y2, x3, y3); - clearMeasure(); } /** @@ -423,7 +403,6 @@ public class Path { float x3, float y3) { isSimplePath = false; native_rCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); - clearMeasure(); } /** @@ -443,7 +422,6 @@ public class Path { boolean forceMoveTo) { isSimplePath = false; native_arcTo(mNativePath, oval, startAngle, sweepAngle, forceMoveTo); - clearMeasure(); } /** @@ -460,7 +438,6 @@ public class Path { public void arcTo(RectF oval, float startAngle, float sweepAngle) { isSimplePath = false; native_arcTo(mNativePath, oval, startAngle, sweepAngle, false); - clearMeasure(); } /** @@ -470,7 +447,6 @@ public class Path { public void close() { isSimplePath = false; native_close(mNativePath); - clearMeasure(); } /** @@ -513,7 +489,6 @@ public class Path { } detectSimplePath(rect.left, rect.top, rect.right, rect.bottom, dir); native_addRect(mNativePath, rect, dir.nativeInt); - clearMeasure(); } /** @@ -528,7 +503,6 @@ public class Path { public void addRect(float left, float top, float right, float bottom, Direction dir) { detectSimplePath(left, top, right, bottom, dir); native_addRect(mNativePath, left, top, right, bottom, dir.nativeInt); - clearMeasure(); } /** @@ -543,7 +517,6 @@ public class Path { } isSimplePath = false; native_addOval(mNativePath, oval, dir.nativeInt); - clearMeasure(); } /** @@ -557,7 +530,6 @@ public class Path { public void addCircle(float x, float y, float radius, Direction dir) { isSimplePath = false; native_addCircle(mNativePath, x, y, radius, dir.nativeInt); - clearMeasure(); } /** @@ -573,7 +545,6 @@ public class Path { } isSimplePath = false; native_addArc(mNativePath, oval, startAngle, sweepAngle); - clearMeasure(); } /** @@ -590,7 +561,6 @@ public class Path { } isSimplePath = false; native_addRoundRect(mNativePath, rect, rx, ry, dir.nativeInt); - clearMeasure(); } /** @@ -611,7 +581,6 @@ public class Path { } isSimplePath = false; native_addRoundRect(mNativePath, rect, radii, dir.nativeInt); - clearMeasure(); } /** @@ -623,7 +592,6 @@ public class Path { public void addPath(Path src, float dx, float dy) { isSimplePath = false; native_addPath(mNativePath, src.mNativePath, dx, dy); - clearMeasure(); } /** @@ -634,7 +602,6 @@ public class Path { public void addPath(Path src) { isSimplePath = false; native_addPath(mNativePath, src.mNativePath); - clearMeasure(); } /** @@ -645,7 +612,6 @@ public class Path { public void addPath(Path src, Matrix matrix) { if (!src.isSimplePath) isSimplePath = false; native_addPath(mNativePath, src.mNativePath, matrix.native_instance); - clearMeasure(); } /** @@ -663,11 +629,6 @@ public class Path { dst.isSimplePath = false; } native_offset(mNativePath, dx, dy, dstNative); - if (dst != null) { - dst.clearMeasure(); - } else { - clearMeasure(); - } } /** @@ -679,7 +640,6 @@ public class Path { public void offset(float dx, float dy) { isSimplePath = false; native_offset(mNativePath, dx, dy); - clearMeasure(); } /** @@ -691,7 +651,6 @@ public class Path { public void setLastPoint(float dx, float dy) { isSimplePath = false; native_setLastPoint(mNativePath, dx, dy); - clearMeasure(); } /** @@ -709,11 +668,6 @@ public class Path { dstNative = dst.mNativePath; } native_transform(mNativePath, matrix.native_instance, dstNative); - if (dst != null) { - dst.clearMeasure(); - } else { - clearMeasure(); - } } /** @@ -724,14 +678,10 @@ public class Path { public void transform(Matrix matrix) { isSimplePath = false; native_transform(mNativePath, matrix.native_instance); - clearMeasure(); } protected void finalize() throws Throwable { try { - if (mNativePathMeasure != 0) { - native_destroyMeasure(mNativePathMeasure); - } finalizer(mNativePath); } finally { super.finalize(); @@ -764,70 +714,6 @@ public class Path { return native_approximate(mNativePath, acceptableError); } - /** - * Modifies the <code>Path</code> by extracting a portion of it. - * The portion of the <code>Path</code> used is between <code>trimStart</code> and - * <code>trimEnd</code> with the value offset by <code>trimOffset</code>. When - * <code>trimOffset</code> added to <code>trimEnd</code> is greater than 1, the - * trimmed portion "wraps" to the start of the <code>Path</code>. - * <p>For example, if <code>Path</code> is a circle and <code>trimStart</code> is 0 - * and <code>trimEnd</code> is 0.5, the resulting <code>Path</code> is the arc of - * a semicircle. If <code>trimOffset</code> is set to 0.75, the arc will start at - * 3/4 of the circle and continue to the end of the circle, then start again at the - * beginning of the circle and end at 1/4 of the way around. It will appear as if - * the semicircle arc wrapped around the <code>Path</code> start and end.</p> - * @param trimStart A number between 0 and <code>trimEnd</code> indicating the fraction of the - * <code>Path</code> to start. A value of 0 trims nothing from the start. - * @param trimEnd A number between <code>trimStart</code> and 1 indicating the fraction of the - * <code>Path</code> to end. A value of 1 trims nothing from the end. - * @param trimOffset A fraction between 0 and 1 indicating the offset of the trimmed - * portion of the <code>Path</code>. - * @see #trim(float, float, float, Path) - */ - public void trim(float trimStart, float trimEnd, float trimOffset) { - trim(trimStart, trimEnd, trimOffset, null); - } - - /** - * Extracts a portion of the <code>Path</code> and writes it to <code>dst</code>. - * The portion of the <code>Path</code> used is between <code>trimStart</code> and - * <code>trimEnd</code> with the value offset by <code>trimOffset</code>. When - * <code>trimOffset</code> added to <code>trimEnd</code> is greater than 1, the - * trimmed portion "wraps" to the start of the <code>Path</code>. - * <p>For example, if <code>Path</code> is a circle and <code>trimStart</code> is 0 - * and <code>trimEnd</code> is 0.5, the resulting <code>Path</code> is the arc of - * a semicircle. If <code>trimOffset</code> is set to 0.75, the arc will start at - * 3/4 of the circle and continue to the end of the circle, then start again at the - * beginning of the circle and end at 1/4 of the way around. It will appear as if - * the semicircle arc wrapped around the <code>Path</code> start and end.</p> - * @param trimStart A number between 0 and <code>trimEnd</code> indicating the fraction of the - * <code>Path</code> to start. A value of 0 trims nothing from the start. - * @param trimEnd A number between <code>trimStart</code> and 1 indicating the fraction of the - * <code>Path</code> to end. A value of 1 trims nothing from the end. - * @param trimOffset A fraction between 0 and 1 indicating the offset of the trimmed - * portion of the <code>Path</code>. - * @param dst The trimmed <code>Path</code> is written here. If <code>dst</code> is null, - * then the original <code>Path</code> is modified. - * @see #trim(float, float, float) - */ - public void trim(float trimStart, float trimEnd, float trimOffset, Path dst) { - if (trimStart > 1 || trimEnd > 1 || trimOffset > 1 - || trimStart < 0 || trimEnd < 0 || trimOffset < 0) { - throw new IllegalArgumentException("trim must be between 0 and 1"); - } - if (trimStart > trimEnd) { - throw new IllegalArgumentException("trim end cannot be less than start"); - } - long dstNative = 0; - if (dst != null) { - dstNative = dst.mNativePath; - dst.isSimplePath = false; - dst.clearMeasure(); - } - mNativePathMeasure = native_trim(mNativePath, dstNative, mNativePathMeasure, - trimStart, trimEnd, trimOffset); - } - private static native long init1(); private static native long init2(long nPath); private static native void native_reset(long nPath); @@ -875,7 +761,4 @@ public class Path { private static native boolean native_op(long path1, long path2, int op, long result); private static native void finalizer(long nPath); private static native float[] native_approximate(long nPath, float error); - private static native int native_trim(long nPath, long nTargetPath, long nPathMeasure, - float trimStart, float trimEnd, float trimOffset); - private static native void native_destroyMeasure(long nPathMeasure); } diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index b910a24d9292..1f8e2231a85c 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -69,9 +69,9 @@ public class SurfaceTexture { /** * These fields are used by native code, do not access or modify. */ - private int mSurfaceTexture; - private int mBufferQueue; - private int mFrameAvailableListener; + private long mSurfaceTexture; + private long mBufferQueue; + private long mFrameAvailableListener; /** * Callback interface for being notified that a new stream frame is available. diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 52e5b5be5c15..936055889d45 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -456,7 +456,7 @@ public class BitmapDrawable extends Drawable { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas canvas) { Bitmap bitmap = mBitmap; if (bitmap != null) { final BitmapState state = mBitmapState; diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 2ec428419c9e..b8365aab655c 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -39,9 +39,6 @@ import android.util.DisplayMetrics; import android.util.StateSet; import android.util.TypedValue; import android.util.Xml; -import android.view.DisplayList; -import android.view.HardwareCanvas; -import android.view.HardwareRenderer; import android.view.View; import java.io.IOException; @@ -142,96 +139,16 @@ public abstract class Drawable { private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect() private WeakReference<Callback> mCallback = null; private boolean mVisible = true; - private DisplayList mDisplayList; private int mLayoutDirection; /** * Draw in its bounds (set via setBounds) respecting optional effects such * as alpha (set via setAlpha) and color filter (set via setColorFilter). - * <p> - * Overriding this method will prevent caching optimizations. To enable - * optimizations, override {@link #onDraw} instead. - * - * @param canvas The canvas to draw into - */ - public void draw(Canvas canvas) { - if (canvas != null && canvas.isHardwareAccelerated() && false) { // temporarily disabled - final HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas; - final DisplayList displayList = getDisplayList(hardwareCanvas); - if (displayList != null) { - final int restoreCount = hardwareCanvas.save(Canvas.MATRIX_SAVE_FLAG); - hardwareCanvas.translate(mBounds.left, mBounds.top); - hardwareCanvas.drawDisplayList(displayList); - hardwareCanvas.restoreToCount(restoreCount); - return; - } - } - - onDraw(canvas); - } - - /** - * Draw in its bounds (set via setBounds) respecting optional effects such - * as alpha (set via setAlpha) and color filter (set via setColorFilter). - * <p> - * Overriding this method, rather than {@link #draw}, enables caching - * optimizations that avoid re-drawing when unnecessary. * * @param canvas The canvas to draw into */ - protected void onDraw(Canvas canvas) { - throw new UnsupportedOperationException( - "Drawable subclasses must implement either draw or onDraw"); - } - - /** - * Gets a display list that can be used to draw this drawable again without - * invoking its draw method. - * - * @param hardwareCanvas The hardware canvas. - * @return A DisplayList ready to replay, or null if caching is not enabled. - * @hide - */ - private DisplayList getDisplayList(HardwareCanvas hardwareCanvas) { - DisplayList displayList = mDisplayList; - if (displayList != null && displayList.isValid()) { - // Note: This code assumes that the display list previously generated - // is compatible with the given hardware canvas. That might not be true - // if we start using multiple different types of hardware canvas - // in the system someday. - return displayList; - } - - displayList = DisplayList.create(getClass().getName()); - mDisplayList = displayList; - - final Rect bounds = mBounds; - final int width = bounds.width(); - final int height = bounds.height(); - final HardwareCanvas canvas = displayList.start(width, height); - canvas.onPreDraw(null); - - // Draw the display list with origin (0,0) so that if the position - // changes then we can translate without recreating the display list. - final int restoreCount = canvas.save(); - try { - canvas.translate(-bounds.left, -bounds.top); - onDraw(canvas); - } finally { - canvas.restoreToCount(restoreCount); - canvas.onPostDraw(); - displayList.end(); - } - - displayList.setLeftTopRightBottom(0, 0, width, height); - displayList.setClipToBounds(false); - return displayList; - } - - private void invalidateDisplayList() { - mDisplayList = null; - } + public abstract void draw(Canvas canvas); /** * Specify a bounding rectangle for the Drawable. This is where the drawable @@ -246,11 +163,10 @@ public abstract class Drawable { if (oldBounds.left != left || oldBounds.top != top || oldBounds.right != right || oldBounds.bottom != bottom) { - if (oldBounds.right - oldBounds.left != right - left - || oldBounds.bottom - oldBounds.top != bottom - top) { - invalidateDisplayList(); + if (!oldBounds.isEmpty()) { + // first invalidate the previous bounds + invalidateSelf(); } - mBounds.set(left, top, right, bottom); onBoundsChange(mBounds); } @@ -438,8 +354,6 @@ public abstract class Drawable { * @see #setCallback(android.graphics.drawable.Drawable.Callback) */ public void invalidateSelf() { - invalidateDisplayList(); - final Callback callback = getCallback(); if (callback != null) { callback.invalidateDrawable(this); diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 6a9454c1d2cb..e654db118fc9 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -266,7 +266,7 @@ public class GradientDrawable extends Drawable { * @see #setStroke(int, int) */ public void setStroke(int width, int color, float dashWidth, float dashGap) { - mGradientState.setStroke(width, color, dashWidth, dashGap); + mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap); setStrokeInternal(width, color, dashWidth, dashGap); } @@ -288,15 +288,15 @@ public class GradientDrawable extends Drawable { */ public void setStroke( int width, ColorStateList colorStateList, float dashWidth, float dashGap) { + mGradientState.setStroke(width, colorStateList, dashWidth, dashGap); + final int color; if (colorStateList == null) { - setStroke(width, Color.TRANSPARENT, dashWidth, dashGap); + color = Color.TRANSPARENT; } else { - mGradientState.setStroke(width, colorStateList, dashWidth, dashGap); - final int[] stateSet = getState(); - final int color = colorStateList.getColorForState(stateSet, 0); - setStrokeInternal(width, color, dashWidth, dashGap); + color = colorStateList.getColorForState(stateSet, 0); } + setStrokeInternal(width, color, dashWidth, dashGap); } private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) { @@ -472,7 +472,7 @@ public class GradientDrawable extends Drawable { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas canvas) { if (!ensureValidRect()) { // nothing to draw return; @@ -529,8 +529,7 @@ public class GradientDrawable extends Drawable { mFillPaint.setAlpha(currFillAlpha); mFillPaint.setDither(mDither); mFillPaint.setColorFilter(mColorFilter); - if (mColorFilter != null && !mGradientState.mHasSolidColor - && mGradientState.mColorStateList == null) { + if (mColorFilter != null && mGradientState.mColorStateList == null) { mFillPaint.setColor(mAlpha << 24); } if (haveStroke) { @@ -672,7 +671,7 @@ public class GradientDrawable extends Drawable { * @see #setColors(int[]) */ public void setColor(int argb) { - mGradientState.setSolidColor(argb); + mGradientState.setColorStateList(ColorStateList.valueOf(argb)); mFillPaint.setColor(argb); invalidateSelf(); } @@ -691,14 +690,16 @@ public class GradientDrawable extends Drawable { * @see #mutate() */ public void setColor(ColorStateList colorStateList) { + mGradientState.setColorStateList(colorStateList); + final int color; if (colorStateList == null) { - setColor(Color.TRANSPARENT); + color = Color.TRANSPARENT; } else { - final int color = colorStateList.getColorForState(getState(), 0); - mGradientState.setColorStateList(colorStateList); - mFillPaint.setColor(color); - invalidateSelf(); + final int[] stateSet = getState(); + color = colorStateList.getColorForState(stateSet, 0); } + mFillPaint.setColor(color); + invalidateSelf(); } @Override @@ -910,7 +911,7 @@ public class GradientDrawable extends Drawable { // If we don't have a solid color, the alpha channel must be // maxed out so that alpha modulation works correctly. - if (!st.mHasSolidColor && st.mColorStateList == null) { + if (st.mColorStateList == null) { mFillPaint.setColor(Color.BLACK); } } @@ -1202,10 +1203,7 @@ public class GradientDrawable extends Drawable { public int[] mTempColors; // no need to copy public float[] mTempPositions; // no need to copy public float[] mPositions; - public boolean mHasSolidColor; - public int mSolidColor; public int mStrokeWidth = -1; // if >= 0 use stroking. - public int mStrokeColor; public float mStrokeDashWidth; public float mStrokeDashGap; public float mRadius; // use this if mRadiusArray is null @@ -1241,10 +1239,8 @@ public class GradientDrawable extends Drawable { if (state.mPositions != null) { mPositions = state.mPositions.clone(); } - mHasSolidColor = state.mHasSolidColor; - mSolidColor = state.mSolidColor; + mStrokeColorStateList = state.mStrokeColorStateList; mStrokeWidth = state.mStrokeWidth; - mStrokeColor = state.mStrokeColor; mStrokeDashWidth = state.mStrokeDashWidth; mStrokeDashGap = state.mStrokeDashGap; mRadius = state.mRadius; @@ -1298,22 +1294,12 @@ public class GradientDrawable extends Drawable { } public void setColors(int[] colors) { - mHasSolidColor = false; mColors = colors; mColorStateList = null; computeOpacity(); } - - public void setSolidColor(int argb) { - mHasSolidColor = argb != Color.TRANSPARENT; - mSolidColor = argb; - mColors = null; - mColorStateList = null; - computeOpacity(); - } public void setColorStateList(ColorStateList colorStateList) { - mHasSolidColor = false; mColors = null; mColorStateList = colorStateList; computeOpacity(); @@ -1336,9 +1322,6 @@ public class GradientDrawable extends Drawable { mOpaque = false; return; } - } else if (!isOpaque(mStrokeColor)) { - mOpaque = false; - return; } } @@ -1347,11 +1330,6 @@ public class GradientDrawable extends Drawable { return; } - if (mHasSolidColor) { - mOpaque = isOpaque(mSolidColor); - return; - } - if (mColors != null) { for (int i = 0; i < mColors.length; i++) { if (!isOpaque(mColors[i])) { @@ -1368,22 +1346,6 @@ public class GradientDrawable extends Drawable { return ((color >> 24) & 0xff) == 0xff; } - public void setStroke(int width, int color) { - mStrokeWidth = width; - mStrokeColor = color; - mStrokeColorStateList = null; - computeOpacity(); - } - - public void setStroke(int width, int color, float dashWidth, float dashGap) { - mStrokeWidth = width; - mStrokeColor = color; - mStrokeColorStateList = null; - mStrokeDashWidth = dashWidth; - mStrokeDashGap = dashGap; - computeOpacity(); - } - public void setStroke( int width, ColorStateList colorStateList, float dashWidth, float dashGap) { mStrokeWidth = width; @@ -1426,9 +1388,7 @@ public class GradientDrawable extends Drawable { } private void initializeWithState(GradientState state) { - if (state.mHasSolidColor) { - mFillPaint.setColor(state.mSolidColor); - } else if (state.mColorStateList != null) { + if (state.mColorStateList != null) { final int[] currentState = getState(); final int stateColor = state.mColorStateList.getColorForState(currentState, 0); mFillPaint.setColor(stateColor); @@ -1451,8 +1411,6 @@ public class GradientDrawable extends Drawable { final int strokeStateColor = state.mStrokeColorStateList.getColorForState( currentState, 0); mStrokePaint.setColor(strokeStateColor); - } else { - mStrokePaint.setColor(state.mStrokeColor); } if (state.mStrokeDashWidth != 0.0f) { diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index ee64d7aa6e01..515d3c1e10d0 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -223,7 +223,7 @@ public class NinePatchDrawable extends Drawable { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas canvas) { final Rect bounds = getBounds(); final boolean needsMirroring = needsMirroring(); if (needsMirroring) { diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java index 2118b2390870..cb2d8f67a4ba 100644 --- a/graphics/java/android/graphics/drawable/PictureDrawable.java +++ b/graphics/java/android/graphics/drawable/PictureDrawable.java @@ -60,7 +60,7 @@ public class PictureDrawable extends Drawable { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas canvas) { if (mPicture != null) { Rect bounds = getBounds(); canvas.save(); diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 9ca3bbfd3f5e..93f2dc603ee9 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -210,7 +210,7 @@ public class ShapeDrawable extends Drawable { } @Override - protected void onDraw(Canvas canvas) { + public void draw(Canvas canvas) { Rect r = getBounds(); Paint paint = mShapeState.mPaint; diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 5151b06aec5b..679976649733 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -1279,14 +1279,13 @@ class ResTable { public: ResTable(); - ResTable(const void* data, size_t size, void* cookie, + ResTable(const void* data, size_t size, const int32_t cookie, bool copyData=false); ~ResTable(); - status_t add(const void* data, size_t size, void* cookie, - bool copyData=false, const void* idmap = NULL); - status_t add(Asset* asset, void* cookie, - bool copyData=false, const void* idmap = NULL); + status_t add(Asset* asset, const int32_t cookie, bool copyData, + const void* idmap); + status_t add(const void *data, size_t size); status_t add(ResTable* src); status_t getError() const; @@ -1534,7 +1533,7 @@ public: // but not the names their entries or types. const ResStringPool* getTableStringBlock(size_t index) const; // Return unique cookie identifier for the given resource table. - void* getTableCookie(size_t index) const; + int32_t getTableCookie(size_t index) const; // Return the configurations (ResTable_config) that we know about void getConfigurations(Vector<ResTable_config>* configs) const; @@ -1569,7 +1568,7 @@ private: struct PackageGroup; struct bag_set; - status_t add(const void* data, size_t size, void* cookie, + status_t addInternal(const void* data, size_t size, const int32_t cookie, Asset* asset, bool copyData, const Asset* idmap); ssize_t getResourcePackageIndex(uint32_t resID) const; diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp index 785e5d4ae33d..501b83e3cc98 100644 --- a/libs/androidfw/AssetManager.cpp +++ b/libs/androidfw/AssetManager.cpp @@ -335,7 +335,7 @@ bool AssetManager::createIdmapFileLocked(const String8& originalPath, const Stri ALOGW("failed to find resources.arsc in %s\n", ap.path.string()); goto error; } - tables[i].add(ass, (void*)1, false); + tables[i].add(ass, 1, false /* copyData */, NULL /* idMap */); } if (!getZipEntryCrcLocked(originalPath, "resources.arsc", &originalCrc)) { @@ -682,7 +682,7 @@ const ResTable* AssetManager::getResTable(bool required) const // can quickly copy it out for others. ALOGV("Creating shared resources for %s", ap.path.string()); sharedRes = new ResTable(); - sharedRes->add(ass, (void*)(i+1), false, idmap); + sharedRes->add(ass, i + 1, false, idmap); sharedRes = const_cast<AssetManager*>(this)-> mZipSet.setZipResourceTable(ap.path, sharedRes); } @@ -706,7 +706,7 @@ const ResTable* AssetManager::getResTable(bool required) const rt->add(sharedRes); } else { ALOGV("Parsing resources for %s", ap.path.string()); - rt->add(ass, (void*)(i+1), !shared, idmap); + rt->add(ass, i + 1, !shared, idmap); } if (!shared) { diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 1cc3563e0f3d..72d331c520a7 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -66,9 +66,9 @@ namespace android { // size measured in sizeof(uint32_t) #define IDMAP_HEADER_SIZE (ResTable::IDMAP_HEADER_SIZE_BYTES / sizeof(uint32_t)) -static void printToLogFunc(void* cookie, const char* txt) +static void printToLogFunc(int32_t cookie, const char* txt) { - ALOGV("%s", txt); + ALOGV("[cookie=%d] %s", cookie, txt); } // Standard C isspace() is only required to look at the low byte of its input, so @@ -2461,7 +2461,7 @@ struct ResTable::Header size_t size; const uint8_t* dataEnd; size_t index; - void* cookie; + int32_t cookie; ResStringPool values; uint32_t* resourceIDMap; @@ -2860,12 +2860,12 @@ ResTable::ResTable() //ALOGI("Creating ResTable %p\n", this); } -ResTable::ResTable(const void* data, size_t size, void* cookie, bool copyData) +ResTable::ResTable(const void* data, size_t size, const int32_t cookie, bool copyData) : mError(NO_INIT) { memset(&mParams, 0, sizeof(mParams)); memset(mPackageMap, 0, sizeof(mPackageMap)); - add(data, size, cookie, copyData); + addInternal(data, size, cookie, NULL /* asset */, copyData, NULL /* idMap */); LOG_FATAL_IF(mError != NO_ERROR, "Error parsing resource table"); //ALOGI("Creating ResTable %p\n", this); } @@ -2881,13 +2881,12 @@ inline ssize_t ResTable::getResourcePackageIndex(uint32_t resID) const return ((ssize_t)mPackageMap[Res_GETPACKAGE(resID)+1])-1; } -status_t ResTable::add(const void* data, size_t size, void* cookie, bool copyData, - const void* idmap) -{ - return add(data, size, cookie, NULL, copyData, reinterpret_cast<const Asset*>(idmap)); +status_t ResTable::add(const void* data, size_t size) { + return addInternal(data, size, 0 /* cookie */, NULL /* asset */, + false /* copyData */, NULL /* idMap */); } -status_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* idmap) +status_t ResTable::add(Asset* asset, const int32_t cookie, bool copyData, const void* idmap) { const void* data = asset->getBuffer(true); if (data == NULL) { @@ -2895,7 +2894,8 @@ status_t ResTable::add(Asset* asset, void* cookie, bool copyData, const void* id return UNKNOWN_ERROR; } size_t size = (size_t)asset->getLength(); - return add(data, size, cookie, asset, copyData, reinterpret_cast<const Asset*>(idmap)); + return addInternal(data, size, cookie, asset, copyData, + reinterpret_cast<const Asset*>(idmap)); } status_t ResTable::add(ResTable* src) @@ -2922,7 +2922,7 @@ status_t ResTable::add(ResTable* src) return mError; } -status_t ResTable::add(const void* data, size_t size, void* cookie, +status_t ResTable::addInternal(const void* data, size_t size, const int32_t cookie, Asset* asset, bool copyData, const Asset* idmap) { if (!data) return NO_ERROR; @@ -2945,7 +2945,7 @@ status_t ResTable::add(const void* data, size_t size, void* cookie, const bool notDeviceEndian = htods(0xf0) != 0xf0; LOAD_TABLE_NOISY( - ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d " + ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%d, asset=%p, copy=%d " "idmap=%p\n", data, size, cookie, asset, copyData, idmap)); if (copyData || notDeviceEndian) { @@ -4930,7 +4930,7 @@ const ResStringPool* ResTable::getTableStringBlock(size_t index) const return &mHeaders[index]->values; } -void* ResTable::getTableCookie(size_t index) const +int32_t ResTable::getTableCookie(size_t index) const { return mHeaders[index]->cookie; } diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index ee24a177fef7..fd3dae7dfd71 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -238,8 +238,9 @@ void DisplayList::init() { mRight = 0; mBottom = 0; mClipToBounds = true; - mIsContainedVolume = true; - mProjectToContainedVolume = false; + mIsolatedZVolume = true; + mProjectBackwards = false; + mOutline.rewind(); mAlpha = 1; mHasOverlappingRendering = true; mTranslationX = 0; @@ -542,7 +543,7 @@ void DisplayList::computeOrderingImpl( applyViewPropertyTransforms(totalTransform); totalTransform.mapPoint3d(pivot); compositedChildrenOf3dRoot->add(ZDrawDisplayListOpPair(pivot.z, opState)); - } else if (mProjectToContainedVolume) { + } else if (mProjectBackwards) { // composited projectee, flag for out of order draw, save matrix, and store in proj surface opState->mSkipInOrderDraw = true; opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface); @@ -552,7 +553,7 @@ void DisplayList::computeOrderingImpl( opState->mSkipInOrderDraw = false; } - if (mIsContainedVolume) { + if (mIsolatedZVolume) { // create a new 3d space for descendents by collecting them compositedChildrenOf3dRoot = &m3dNodes; transformFrom3dRoot = &mat4::identity(); @@ -654,16 +655,15 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren /* draw shadow with parent matrix applied, passing in the child's total matrix * * TODO: - * -determine and pass background shape (and possibly drawable alpha) * -view must opt-in to shadows - * -consider shadows for other content - * -inform shadow system of ancestor transform (for use in lighting) + * -consider depth in more complex scenarios (neg z, added shadow depth) */ mat4 shadowMatrix(childOp->mTransformFromCompositingAncestor); childOp->mDisplayList->applyViewPropertyTransforms(shadowMatrix); + DisplayList* child = childOp->mDisplayList; + DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix, - childOp->mDisplayList->mAlpha, - childOp->mDisplayList->getWidth(), childOp->mDisplayList->getHeight()); + child->mAlpha, &(child->mOutline), child->mWidth, child->mHeight); handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds); } diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 6e6e596fc1cb..8622d619629e 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -190,12 +190,20 @@ public: mClipToBounds = clipToBounds; } - void setIsContainedVolume(bool isContainedVolume) { - mIsContainedVolume = isContainedVolume; + void setIsolatedZVolume(bool shouldIsolate) { + mIsolatedZVolume = shouldIsolate; } - void setProjectToContainedVolume(bool shouldProject) { - mProjectToContainedVolume = shouldProject; + void setProjectBackwards(bool shouldProject) { + mProjectBackwards = shouldProject; + } + + void setOutline(const SkPath* outline) { + if (!outline) { + mOutline.reset(); + } else { + mOutline = *outline; + } } void setStaticMatrix(SkMatrix* matrix) { @@ -590,8 +598,9 @@ private: // Rendering properties bool mClipToBounds; - bool mIsContainedVolume; - bool mProjectToContainedVolume; + bool mIsolatedZVolume; + bool mProjectBackwards; + SkPath mOutline; float mAlpha; bool mHasOverlappingRendering; float mTranslationX, mTranslationY, mTranslationZ; diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 5024880889de..20bc93d39626 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1584,27 +1584,33 @@ private: */ class DrawShadowOp : public DrawOp { public: - DrawShadowOp(const mat4& casterTransform, float casterAlpha, float width, float height) - : DrawOp(NULL), mCasterTransform(casterTransform), mCasterAlpha(casterAlpha), - mWidth(width), mHeight(height) {} + DrawShadowOp(const mat4& transform, float alpha, const SkPath* outline, + float fallbackWidth, float fallbackHeight) + : DrawOp(NULL), mTransform(transform), mAlpha(alpha), mOutline(outline), + mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { - SkPath casterOutline; // TODO: drive with path from view - casterOutline.addRect(0, 0, mWidth, mHeight); - return renderer.drawShadow(mCasterTransform, mCasterAlpha, &casterOutline); + if (!mOutline->isEmpty()) { + return renderer.drawShadow(mTransform, mAlpha, mOutline); + } + + SkPath fakeOutline; + fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight); + return renderer.drawShadow(mTransform, mAlpha, &fakeOutline); } virtual void output(int level, uint32_t logFlags) const { - OP_LOG("DrawShadow of width %.2f, height %.2f", mWidth, mHeight); + OP_LOG("DrawShadow of outline %p", mOutline); } virtual const char* name() { return "DrawShadow"; } private: - const mat4 mCasterTransform; - const float mCasterAlpha; - const float mWidth; - const float mHeight; + const mat4 mTransform; + const float mAlpha; + const SkPath* mOutline; + const float mFallbackWidth; + const float mFallbackHeight; }; class DrawLayerOp : public DrawOp { diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7a1194870d57..b71082572ce2 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -3199,6 +3199,11 @@ status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlp PathTessellator::approximatePathOutlineVertices(*casterOutline, casterRefinementThresholdSquared, casterVertices2d); + if (casterVertices2d.size() == 0) { + // empty caster polygon computed from path + return DrawGlInfo::kStatusDone; + } + // map 2d caster poly into 3d const int casterVertexCount = casterVertices2d.size(); Vector3 casterPolygon[casterVertexCount]; diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp index a679552aa757..ee7789755609 100644 --- a/libs/hwui/Program.cpp +++ b/libs/hwui/Program.cpp @@ -163,7 +163,7 @@ GLuint Program::buildShader(const char* source, GLenum type) { void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix, const mat4& transformMatrix, bool offset) { - if (projectionMatrix != mProjection) { + if (projectionMatrix != mProjection || offset != mOffset) { if (CC_LIKELY(!offset)) { glUniformMatrix4fv(projection, 1, GL_FALSE, &projectionMatrix.data[0]); } else { @@ -177,6 +177,7 @@ void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix, glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]); } mProjection = projectionMatrix; + mOffset = offset; } mat4 t(transformMatrix); diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index bc0f2114d203..5dfb2fa5a37d 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -431,6 +431,7 @@ private: bool mHasSampler; mat4 mProjection; + bool mOffset; }; // class Program }; // namespace uirenderer diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index 5d489a75bde1..09e20588e2bf 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -19,6 +19,7 @@ #define SHADOW_SHRINK_SCALE 0.1f #include <math.h> +#include <stdlib.h> #include <utils/Log.h> #include "SpotShadow.h" @@ -128,10 +129,10 @@ int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) { lUpper[lUpperSize] = points[i]; lUpperSize++; - while (lUpperSize > 2 && !rightTurn( - (double)lUpper[lUpperSize - 3].x, (double)lUpper[lUpperSize - 3].y, - (double)lUpper[lUpperSize - 2].x, (double)lUpper[lUpperSize - 2].y, - (double)lUpper[lUpperSize - 1].x, (double)lUpper[lUpperSize - 1].y)) { + while (lUpperSize > 2 && !ccw( + lUpper[lUpperSize - 3].x, lUpper[lUpperSize - 3].y, + lUpper[lUpperSize - 2].x, lUpper[lUpperSize - 2].y, + lUpper[lUpperSize - 1].x, lUpper[lUpperSize - 1].y)) { // Remove the middle point of the three last lUpper[lUpperSize - 2].x = lUpper[lUpperSize - 1].x; lUpper[lUpperSize - 2].y = lUpper[lUpperSize - 1].y; @@ -149,10 +150,10 @@ int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) { lLower[lLowerSize] = points[i]; lLowerSize++; - while (lLowerSize > 2 && !rightTurn( - (double)lLower[lLowerSize - 3].x, (double)lLower[lLowerSize - 3].y, - (double)lLower[lLowerSize - 2].x, (double)lLower[lLowerSize - 2].y, - (double)lLower[lLowerSize - 1].x, (double)lLower[lLowerSize - 1].y)) { + while (lLowerSize > 2 && !ccw( + lLower[lLowerSize - 3].x, lLower[lLowerSize - 3].y, + lLower[lLowerSize - 2].x, lLower[lLowerSize - 2].y, + lLower[lLowerSize - 1].x, lLower[lLowerSize - 1].y)) { // Remove the middle point of the three last lLower[lLowerSize - 2] = lLower[lLowerSize - 1]; lLowerSize--; @@ -174,7 +175,7 @@ int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) { } /** - * Test whether the 3 points form a right hand turn + * Test whether the 3 points form a counter clockwise turn. * * @param ax the x coordinate of point a * @param ay the y coordinate of point a @@ -184,7 +185,7 @@ int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) { * @param cy the y coordinate of point c * @return true if a right hand turn */ -bool SpotShadow::rightTurn(double ax, double ay, double bx, double by, +bool SpotShadow::ccw(double ax, double ay, double bx, double by, double cx, double cy) { return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > EPSILON; } @@ -203,6 +204,7 @@ int SpotShadow::intersection(Vector2* poly1, int poly1Length, Vector2* poly2, int poly2Length) { makeClockwise(poly1, poly1Length); makeClockwise(poly2, poly2Length); + Vector2 poly[poly1Length * poly2Length + 2]; int count = 0; int pcount = 0; @@ -259,7 +261,7 @@ int SpotShadow::intersection(Vector2* poly1, int poly1Length, count++; } else { Vector2 delta = poly2[i] - poly1[j]; - if (delta.lengthSquared() < 0.01) { + if (delta.lengthSquared() < EPSILON) { poly[count] = poly2[i]; count++; } @@ -279,20 +281,40 @@ int SpotShadow::intersection(Vector2* poly1, int poly1Length, center /= count; sort(poly, count, center); - // TODO: Verify the intersection works correctly, like any random point - // inside both poly1 and poly2 should be inside the intersection, and the - // result intersection polygon is convex. +#if DEBUG_SHADOW + // Since poly2 is overwritten as the result, we need to save a copy to do + // our verification. + Vector2 oldPoly2[poly2Length]; + int oldPoly2Length = poly2Length; + memcpy(oldPoly2, poly2, sizeof(Vector2) * poly2Length); +#endif - // Merge the vertices if they are too close. + // Filter the result out from poly and put it into poly2. poly2[0] = poly[0]; - int resultLength = 1; + int lastOutputIndex = 0; for (int i = 1; i < count; i++) { - Vector2 delta = poly[i] - poly[i - 1]; - if (delta.lengthSquared() >= 0.01) { - poly2[resultLength] = poly[i]; - resultLength++; + Vector2 delta = poly[i] - poly2[lastOutputIndex]; + if (delta.lengthSquared() >= EPSILON) { + poly2[++lastOutputIndex] = poly[i]; + } else { + // If the vertices are too close, pick the inner one, because the + // inner one is more likely to be an intersection point. + Vector2 delta1 = poly[i] - center; + Vector2 delta2 = poly2[lastOutputIndex] - center; + if (delta1.lengthSquared() < delta2.lengthSquared()) { + poly2[lastOutputIndex] = poly[i]; + } } } + int resultLength = lastOutputIndex + 1; + +#if DEBUG_SHADOW + testConvex(poly2, resultLength, "intersection"); + testConvex(poly1, poly1Length, "input poly1"); + testConvex(oldPoly2, oldPoly2Length, "input poly2"); + + testIntersection(poly1, poly1Length, oldPoly2, oldPoly2Length, poly2, resultLength); +#endif return resultLength; } @@ -309,10 +331,12 @@ void SpotShadow::sort(Vector2* poly, int polyLength, const Vector2& center) { } /** - * Calculate the angle between and x and a y coordinate + * Calculate the angle between and x and a y coordinate. + * The atan2 range from -PI to PI, if we want to sort the vertices as clockwise, + * we just negate the return angle. */ float SpotShadow::angle(const Vector2& point, const Vector2& center) { - return -(float)atan2(point.x - center.x, point.y - center.y); + return -(float)atan2(point.y - center.y, point.x - center.x); } /** @@ -719,9 +743,10 @@ void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLeng int stripSize = getStripSize(rays, layers); AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(stripSize); int currentIndex = 0; + int firstInLayer = 0; // Calculate the vertex values in the penumbra area. for (int r = 0; r < layers; r++) { - int firstInEachLayer = currentIndex; + firstInLayer = currentIndex; for (int i = 0; i < rays; i++) { float dx = sinf(step * i); float dy = cosf(step * i); @@ -731,19 +756,17 @@ void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLeng float deltaDist = layerRatio * (umbraDistPerRay[i] - penumbraDistPerRay[i]); float currentDist = penumbraDistPerRay[i] + deltaDist; float op = calculateOpacity(layerRatio, deltaDist); - AlphaVertex::set(&shadowVertices[currentIndex], + AlphaVertex::set(&shadowVertices[currentIndex++], dx * currentDist + centroid.x, dy * currentDist + centroid.y, layerRatio * op * strength); - currentIndex++; } } // Duplicate the vertices from one layer to another one to make triangle // strip. - shadowVertices[currentIndex++] = shadowVertices[firstInEachLayer]; - firstInEachLayer++; - shadowVertices[currentIndex++] = shadowVertices[firstInEachLayer]; + shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 0]; + shadowVertices[currentIndex++] = shadowVertices[firstInLayer + 1]; } int lastInPenumbra = currentIndex - 1; @@ -755,23 +778,14 @@ void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLeng int firstInUmbra = currentIndex; // traverse the umbra area in a zig zag pattern for strips. + const int innerRingStartIndex = firstInLayer + 1; for (int k = 0; k < rays; k++) { int i = k / 2; if ((k & 1) == 1) { i = rays - i - 1; } - float dx = sinf(step * i); - float dy = cosf(step * i); - - float ratio = 1.0; - float deltaDist = ratio * (umbraDistPerRay[i] - penumbraDistPerRay[i]); - float currentDist = penumbraDistPerRay[i] + deltaDist; - float op = calculateOpacity(ratio, deltaDist); - AlphaVertex::set(&shadowVertices[currentIndex], - dx * currentDist + centroid.x, dy * currentDist + centroid.y, - ratio * op * strength); - currentIndex++; - + // copy already computed values for umbra vertices + shadowVertices[currentIndex++] = shadowVertices[innerRingStartIndex + i * 2]; } // Back fill the one vertex for jumping from penumbra to umbra. @@ -831,6 +845,126 @@ int SpotShadow::getStripSize(int rays, int layers) { return (2 + rays + ((layers) * 2 * (rays + 1))); } +#if DEBUG_SHADOW + +#define TEST_POINT_NUMBER 128 + +/** + * Calculate the bounds for generating random test points. + */ +void SpotShadow::updateBound(const Vector2 inVector, Vector2& lowerBound, + Vector2& upperBound ) { + if (inVector.x < lowerBound.x) { + lowerBound.x = inVector.x; + } + + if (inVector.y < lowerBound.y) { + lowerBound.y = inVector.y; + } + + if (inVector.x > upperBound.x) { + upperBound.x = inVector.x; + } + + if (inVector.y > upperBound.y) { + upperBound.y = inVector.y; + } +} + +/** + * For debug purpose, when things go wrong, dump the whole polygon data. + */ +static void dumpPolygon(const Vector2* poly, int polyLength, const char* polyName) { + for (int i = 0; i < polyLength; i++) { + ALOGD("polygon %s i %d x %f y %f", polyName, i, poly[i].x, poly[i].y); + } +} + +/** + * Test whether the polygon is convex. + */ +bool SpotShadow::testConvex(const Vector2* polygon, int polygonLength, + const char* name) { + bool isConvex = true; + for (int i = 0; i < polygonLength; i++) { + Vector2 start = polygon[i]; + Vector2 middle = polygon[(i + 1) % polygonLength]; + Vector2 end = polygon[(i + 2) % polygonLength]; + + double delta = (double(middle.x) - start.x) * (double(end.y) - start.y) - + (double(middle.y) - start.y) * (double(end.x) - start.x); + bool isCCWOrCoLinear = (delta >= EPSILON); + + if (isCCWOrCoLinear) { + ALOGE("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f)," + "middle (x %f, y %f) and end (x %f, y %f) , delta is %f !!!", + name, start.x, start.y, middle.x, middle.y, end.x, end.y, delta); + isConvex = false; + break; + } + } + return isConvex; +} + +/** + * Test whether or not the polygon (intersection) is within the 2 input polygons. + * Using Marte Carlo method, we generate a random point, and if it is inside the + * intersection, then it must be inside both source polygons. + */ +void SpotShadow::testIntersection(const Vector2* poly1, int poly1Length, + const Vector2* poly2, int poly2Length, + const Vector2* intersection, int intersectionLength) { + // Find the min and max of x and y. + Vector2 lowerBound(FLT_MAX, FLT_MAX); + Vector2 upperBound(-FLT_MAX, -FLT_MAX); + for (int i = 0; i < poly1Length; i++) { + updateBound(poly1[i], lowerBound, upperBound); + } + for (int i = 0; i < poly2Length; i++) { + updateBound(poly2[i], lowerBound, upperBound); + } + + bool dumpPoly = false; + for (int k = 0; k < TEST_POINT_NUMBER; k++) { + // Generate a random point between minX, minY and maxX, maxY. + double randomX = rand() / double(RAND_MAX); + double randomY = rand() / double(RAND_MAX); + + Vector2 testPoint; + testPoint.x = lowerBound.x + randomX * (upperBound.x - lowerBound.x); + testPoint.y = lowerBound.y + randomY * (upperBound.y - lowerBound.y); + + // If the random point is in both poly 1 and 2, then it must be intersection. + if (testPointInsidePolygon(testPoint, intersection, intersectionLength)) { + if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) { + dumpPoly = true; + ALOGE("(Error Type 1): one point (%f, %f) in the intersection is" + " not in the poly1", + testPoint.x, testPoint.y); + } + + if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) { + dumpPoly = true; + ALOGE("(Error Type 1): one point (%f, %f) in the intersection is" + " not in the poly2", + testPoint.x, testPoint.y); + } + } + } + + if (dumpPoly) { + dumpPolygon(intersection, intersectionLength, "intersection"); + for (int i = 1; i < intersectionLength; i++) { + Vector2 delta = intersection[i] - intersection[i - 1]; + ALOGD("Intersetion i, %d Vs i-1 is delta %f", i, delta.lengthSquared()); + } + + dumpPolygon(poly1, poly1Length, "poly 1"); + dumpPolygon(poly2, poly2Length, "poly 2"); + } +} +#endif + }; // namespace uirenderer }; // namespace android diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h index d8db43bf630a..a50d110dfcee 100644 --- a/libs/hwui/SpotShadow.h +++ b/libs/hwui/SpotShadow.h @@ -48,7 +48,7 @@ private: static void xsort(Vector2* points, int pointsLength); static int hull(Vector2* points, int pointsLength, Vector2* retPoly); - static bool rightTurn(double ax, double ay, double bx, double by, double cx, double cy); + static bool ccw(double ax, double ay, double bx, double by, double cx, double cy); static int intersection(Vector2* poly1, int poly1length, Vector2* poly2, int poly2length); static void sort(Vector2* poly, int polyLength, const Vector2& center); @@ -69,6 +69,17 @@ private: float strength, VertexBuffer& retstrips); static const double EPSILON = 1e-7; + +#if DEBUG_SHADOW + // Verification utility function. + static bool testConvex(const Vector2* polygon, int polygonLength, + const char* name); + static void testIntersection(const Vector2* poly1, int poly1Length, + const Vector2* poly2, int poly2Length, + const Vector2* intersection, int intersectionLength); + static void updateBound(const Vector2 inVector, Vector2& lowerBound, Vector2& upperBound ); +#endif + }; // SpotShadow }; // namespace uirenderer diff --git a/libs/hwui/renderthread/RenderTask.h b/libs/hwui/renderthread/RenderTask.h index 9fe7573f71b7..1554a167e10c 100644 --- a/libs/hwui/renderthread/RenderTask.h +++ b/libs/hwui/renderthread/RenderTask.h @@ -53,7 +53,7 @@ public: ANDROID_API virtual void run() = 0; RenderTask* mNext; - nsecs_t mRunAt; + nsecs_t mRunAt; // nano-seconds on the SYSTEM_TIME_MONOTONIC clock }; class SignalingRenderTask : public RenderTask { diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index e4ec164ff02b..212f475e2aa7 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -128,7 +128,8 @@ bool RenderThread::threadLoop() { if (nextWakeup == LLONG_MAX) { timeoutMillis = -1; } else { - timeoutMillis = nextWakeup - systemTime(SYSTEM_TIME_MONOTONIC); + nsecs_t timeoutNanos = nextWakeup - systemTime(SYSTEM_TIME_MONOTONIC); + timeoutMillis = nanoseconds_to_milliseconds(timeoutNanos); if (timeoutMillis < 0) { timeoutMillis = 0; } @@ -149,7 +150,7 @@ void RenderThread::queue(RenderTask* task) { void RenderThread::queueDelayed(RenderTask* task, int delayMs) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); - task->mRunAt = now + delayMs; + task->mRunAt = now + milliseconds_to_nanoseconds(delayMs); queue(task); } diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 0030dbdafee2..d475eeef06b8 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -707,6 +707,7 @@ static jint ImageReader_imageSetup(JNIEnv* env, jobject thiz, } status_t res = consumer->lockNextBuffer(buffer); if (res != NO_ERROR) { + ctx->returnLockedBuffer(buffer); if (res != BAD_VALUE /*no buffers*/) { if (res == NOT_ENOUGH_DATA) { return ACQUIRE_MAX_IMAGES; diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp index 01db1d3cace4..dee3f8c700ed 100644 --- a/native/android/asset_manager.cpp +++ b/native/android/asset_manager.cpp @@ -76,12 +76,12 @@ AAssetManager* AAssetManager_fromJava(JNIEnv* env, jobject assetManager) if (gJNIConfigured == false) { jclass amClass = env->FindClass("android/content/res/AssetManager"); - gAssetManagerOffsets.mObject = env->GetFieldID(amClass, "mObject", "I"); + gAssetManagerOffsets.mObject = env->GetFieldID(amClass, "mObject", "J"); gJNIConfigured = true; } } - return (AAssetManager*) env->GetIntField(assetManager, gAssetManagerOffsets.mObject); + return (AAssetManager*) env->GetLongField(assetManager, gAssetManagerOffsets.mObject); } AAsset* AAssetManager_open(AAssetManager* amgr, const char* filename, int mode) diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml index c7abd987351e..1d60a137bc9a 100644 --- a/packages/Keyguard/res/values-sw/strings.xml +++ b/packages/Keyguard/res/values-sw/strings.xml @@ -30,7 +30,7 @@ <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"Msimbo wa PIN usio sahihi."</string> <string name="keyguard_label_text" msgid="861796461028298424">"Ili kufungua, bofya Menyu kisha 0."</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string> - <string name="keyguard_charged" msgid="3272223906073492454">"Imechajiwa"</string> + <string name="keyguard_charged" msgid="3272223906073492454">"Betri imejaa"</string> <string name="keyguard_plugged_in" msgid="8117572000639998388">"Inachaji, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string> <string name="keyguard_low_battery" msgid="8143808018719173859">"Unganisha chaja yako."</string> <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Bonyeza Menyu ili kufungua."</string> @@ -45,8 +45,8 @@ <string name="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kadi imefungwa."</string> <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SIM kadi imefungwa na PUK."</string> <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"Inafungua SIM kadi..."</string> - <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wiji %2$d ya %3$d."</string> - <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wiji"</string> + <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string> + <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</string> <string name="keyguard_accessibility_widget_empty_slot" msgid="1281505703307930757">"Tupu"</string> <string name="keyguard_accessibility_unlock_area_expanded" msgid="2278106022311170299">"Eneo la kufungua limepanuliwa."</string> <string name="keyguard_accessibility_unlock_area_collapsed" msgid="6366992066936076396">"Eneo la kufungua limekunjwa."</string> @@ -55,7 +55,7 @@ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Hali"</string> <string name="keyguard_accessibility_camera" msgid="8904231194181114603">"Kamera"</string> <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Vidhibiti vya media"</string> - <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wiji umeanza."</string> + <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"Upangaji upya wa wijeti umeanza."</string> <string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"Upangaji upya wa wiji umekamilika."</string> <string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"Wiji <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> imefutwa."</string> <string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"Panua eneo la kufungua."</string> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java index e2219d439a86..914fdc4fd89b 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java @@ -149,6 +149,18 @@ public class KeyguardViewMediator { */ private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true; + /** + * Allow the user to expand the status bar when a SECURE keyguard is engaged + * and {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS} is set + * (private notifications will be masked). + */ + private static final boolean ENABLE_SECURE_STATUS_BAR_EXPAND = true; + + /** + * Default value of {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS}. + */ + private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false; + /** The stream type that the lock sounds are tied to. */ private int mMasterStreamType; @@ -246,6 +258,11 @@ public class KeyguardViewMediator { private int mLockSoundStreamId; /** + * Tracks value of {@link Settings.Secure#LOCK_SCREEN_ALLOW_NOTIFICATIONS}. + */ + private boolean mAllowNotificationsWhenSecure; + + /** * The volume applied to the lock/unlock sounds. */ private final float mLockSoundVolume; @@ -894,6 +911,13 @@ public class KeyguardViewMediator { return; } + // note whether notification access should be allowed + mAllowNotificationsWhenSecure = ENABLE_SECURE_STATUS_BAR_EXPAND + && 0 != Settings.Secure.getInt( + mContext.getContentResolver(), + Settings.Secure.LOCK_SCREEN_ALLOW_NOTIFICATIONS, + ALLOW_NOTIFICATIONS_DEFAULT ? 1 : 0); + // if the keyguard is already showing, don't bother if (mKeyguardViewManager.isShowing()) { if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); @@ -1278,13 +1302,15 @@ public class KeyguardViewMediator { // (like recents). Temporary enable/disable (e.g. the "back" button) are // done in KeyguardHostView. flags |= StatusBarManager.DISABLE_RECENT; - if (isSecure() || !ENABLE_INSECURE_STATUS_BAR_EXPAND) { + if ((isSecure() && !mAllowNotificationsWhenSecure) + || !ENABLE_INSECURE_STATUS_BAR_EXPAND) { // showing secure lockscreen; disable expanding. flags |= StatusBarManager.DISABLE_EXPAND; } if (isSecure()) { - // showing secure lockscreen; disable ticker. - flags |= StatusBarManager.DISABLE_NOTIFICATION_TICKER; + // showing secure lockscreen; disable ticker and switch private notifications + // to show their public versions, if available. + flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS; } if (!isAssistantAvailable()) { flags |= StatusBarManager.DISABLE_SEARCH; diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 7b09092508ad..45957a49763d 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -422,7 +422,11 @@ public class SettingsBackupAgent extends BackupAgentHelper { // If we have wifi data to restore, post a runnable to perform the // bounce-and-update operation a little ways in the future. if (mWifiRestore != null) { - new Handler(getMainLooper()).postDelayed(mWifiRestore, WIFI_BOUNCE_DELAY_MILLIS); + long wifiBounceDelayMillis = Settings.Global.getLong( + getContentResolver(), + Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS, + WIFI_BOUNCE_DELAY_MILLIS); + new Handler(getMainLooper()).postDelayed(mWifiRestore, wifiBounceDelayMillis); } } diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml index f8279672efff..e74e5684710d 100644 --- a/packages/SystemUI/res/layout/status_bar_notification_row.xml +++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml @@ -25,7 +25,7 @@ android:paddingStart="8dp" /> - <com.android.systemui.statusbar.LatestItemView android:id="@+id/content" + <com.android.systemui.statusbar.LatestItemView android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/notification_divider_height" @@ -34,10 +34,13 @@ android:clickable="true" > - <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/adaptive" + <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded" android:layout_width="match_parent" android:layout_height="wrap_content" /> + <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> </com.android.systemui.statusbar.LatestItemView> <View diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index f5e2568eacad..efe7fcb5b919 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -23,7 +23,7 @@ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</string> <string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"Ta bort från listan"</string> <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"Info om appen"</string> - <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Inga nya appar"</string> + <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Inga aktiva appar"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvisa nya appar"</string> <plurals name="status_bar_accessibility_recent_apps"> <item quantity="one" msgid="5854176083865845541">"1 ny app"</item> diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index 74d982ad718b..e516bb854c93 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -98,7 +98,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi private final int mNotificationId; private final NotificationManager mNotificationManager; - private final Notification.Builder mNotificationBuilder; + private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder; private final File mScreenshotDir; private final String mImageFileName; private final String mImageFilePath; @@ -152,18 +152,30 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi mTickerAddSpace = !mTickerAddSpace; mNotificationId = nId; mNotificationManager = nManager; + final long now = System.currentTimeMillis(); + mNotificationBuilder = new Notification.Builder(context) .setTicker(r.getString(R.string.screenshot_saving_ticker) + (mTickerAddSpace ? " " : "")) .setContentTitle(r.getString(R.string.screenshot_saving_title)) .setContentText(r.getString(R.string.screenshot_saving_text)) .setSmallIcon(R.drawable.stat_notify_image) - .setWhen(System.currentTimeMillis()); + .setWhen(now); mNotificationStyle = new Notification.BigPictureStyle() .bigPicture(preview); mNotificationBuilder.setStyle(mNotificationStyle); + // For "public" situations we want to show all the same info but + // omit the actual screenshot image. + mPublicNotificationBuilder = new Notification.Builder(context) + .setContentTitle(r.getString(R.string.screenshot_saving_title)) + .setContentText(r.getString(R.string.screenshot_saving_text)) + .setSmallIcon(R.drawable.stat_notify_image) + .setWhen(now); + + mNotificationBuilder.setPublicVersion(mPublicNotificationBuilder.build()); + Notification n = mNotificationBuilder.build(); n.flags |= Notification.FLAG_NO_CLEAR; mNotificationManager.notify(nId, n); @@ -280,13 +292,25 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi launchIntent.setDataAndType(params.imageUri, "image/png"); launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + final long now = System.currentTimeMillis(); + mNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0)) - .setWhen(System.currentTimeMillis()) + .setWhen(now) + .setAutoCancel(true); + + // Update the text in the public version as well + mPublicNotificationBuilder + .setContentTitle(r.getString(R.string.screenshot_saved_title)) + .setContentText(r.getString(R.string.screenshot_saved_text)) + .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0)) + .setWhen(now) .setAutoCancel(true); + mNotificationBuilder.setPublicVersion(mPublicNotificationBuilder.build()); + Notification n = mNotificationBuilder.build(); n.flags &= ~Notification.FLAG_NO_CLEAR; mNotificationManager.notify(mNotificationId, n); @@ -669,6 +693,7 @@ class GlobalScreenshot { .setContentText(r.getString(R.string.screenshot_failed_text)) .setSmallIcon(R.drawable.stat_notify_image_error) .setWhen(System.currentTimeMillis()) + .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen .setAutoCancel(true); Notification n = new Notification.BigTextStyle(b) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index ed00398b6531..a7cfaba8b190 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.database.ContentObserver; @@ -130,6 +131,7 @@ public abstract class BaseStatusBar extends SystemUI implements protected IDreamManager mDreamManager; PowerManager mPowerManager; protected int mRowHeight; + private boolean mPublicMode = false; // UI-specific methods @@ -548,6 +550,14 @@ public abstract class BaseStatusBar extends SystemUI implements public abstract void resetHeadsUpDecayTimer(); + public void setPublicMode(boolean publicMode) { + mPublicMode = publicMode; + } + + public boolean isPublicMode() { + return mPublicMode; + } + protected class H extends Handler { public void handleMessage(Message m) { Intent intent; @@ -625,6 +635,11 @@ public abstract class BaseStatusBar extends SystemUI implements return false; } + Log.v(TAG, "publicNotification: " + + sbn.getNotification().publicVersion); + + Notification publicNotification = sbn.getNotification().publicVersion; + // create the row view LayoutInflater inflater = (LayoutInflater)mContext.getSystemService( Context.LAYOUT_INFLATER_SERVICE); @@ -642,8 +657,10 @@ public abstract class BaseStatusBar extends SystemUI implements // NB: the large icon is now handled entirely by the template // bind the click event to the content area - ViewGroup content = (ViewGroup)row.findViewById(R.id.content); - ViewGroup adaptive = (ViewGroup)row.findViewById(R.id.adaptive); + ViewGroup content = (ViewGroup)row.findViewById(R.id.container); + SizeAdaptiveLayout expanded = (SizeAdaptiveLayout)row.findViewById(R.id.expanded); + SizeAdaptiveLayout expandedPublic + = (SizeAdaptiveLayout)row.findViewById(R.id.expandedPublic); content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); @@ -656,12 +673,13 @@ public abstract class BaseStatusBar extends SystemUI implements content.setOnClickListener(null); } + // set up the adaptive layout View contentViewLocal = null; View bigContentViewLocal = null; try { - contentViewLocal = contentView.apply(mContext, adaptive, mOnClickHandler); + contentViewLocal = contentView.apply(mContext, expanded, mOnClickHandler); if (bigContentView != null) { - bigContentViewLocal = bigContentView.apply(mContext, adaptive, mOnClickHandler); + bigContentViewLocal = bigContentView.apply(mContext, expanded, mOnClickHandler); } } catch (RuntimeException e) { @@ -675,15 +693,70 @@ public abstract class BaseStatusBar extends SystemUI implements new SizeAdaptiveLayout.LayoutParams(contentViewLocal.getLayoutParams()); params.minHeight = minHeight; params.maxHeight = minHeight; - adaptive.addView(contentViewLocal, params); + expanded.addView(contentViewLocal, params); } if (bigContentViewLocal != null) { SizeAdaptiveLayout.LayoutParams params = new SizeAdaptiveLayout.LayoutParams(bigContentViewLocal.getLayoutParams()); params.minHeight = minHeight+1; params.maxHeight = maxHeight; - adaptive.addView(bigContentViewLocal, params); + expanded.addView(bigContentViewLocal, params); + } + + PackageManager pm = mContext.getPackageManager(); + + // now the public version + View publicViewLocal = null; + if (publicNotification != null) { + try { + publicViewLocal = publicNotification.contentView.apply(mContext, + expandedPublic, mOnClickHandler); + + if (publicViewLocal != null) { + SizeAdaptiveLayout.LayoutParams params = + new SizeAdaptiveLayout.LayoutParams(publicViewLocal.getLayoutParams()); + params.minHeight = minHeight; + params.maxHeight = minHeight; + expandedPublic.addView(publicViewLocal, params); + } + } + catch (RuntimeException e) { + final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()); + Log.e(TAG, "couldn't inflate public view for notification " + ident, e); + publicViewLocal = null; + } } + + if (publicViewLocal == null) { + // Add a basic notification template + publicViewLocal = LayoutInflater.from(mContext).inflate( + com.android.internal.R.layout.notification_template_base, expandedPublic, true); + + final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title); + try { + title.setText(pm.getApplicationLabel( + pm.getApplicationInfo(entry.notification.getPackageName(), 0))); + } catch (NameNotFoundException e) { + title.setText(entry.notification.getPackageName()); + } + + final ImageView icon = (ImageView) publicViewLocal.findViewById(com.android.internal.R.id.icon); + + final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(), + entry.notification.getUser(), + entry.notification.getNotification().icon, + entry.notification.getNotification().iconLevel, + entry.notification.getNotification().number, + entry.notification.getNotification().tickerText); + + icon.setImageDrawable(StatusBarIconView.getIcon(mContext, ic)); + + final TextView text = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.text); + text.setText("Unlock your device to see this notification."); + + // TODO: fill out "time" as well + } + row.setDrawingCacheEnabled(true); applyLegacyRowBackground(sbn, content); @@ -699,6 +772,7 @@ public abstract class BaseStatusBar extends SystemUI implements entry.row.setRowHeight(mRowHeight); entry.content = content; entry.expanded = contentViewLocal; + entry.expandedPublic = publicViewLocal; entry.setBigContentView(bigContentViewLocal); return true; @@ -904,6 +978,12 @@ public abstract class BaseStatusBar extends SystemUI implements final RemoteViews contentView = notification.getNotification().contentView; final RemoteViews oldBigContentView = oldNotification.getNotification().bigContentView; final RemoteViews bigContentView = notification.getNotification().bigContentView; + final Notification oldPublicNotification = oldNotification.getNotification().publicVersion; + final RemoteViews oldPublicContentView = oldPublicNotification != null + ? oldPublicNotification.contentView : null; + final Notification publicNotification = notification.getNotification().publicVersion; + final RemoteViews publicContentView = publicNotification != null + ? publicNotification.contentView : null; if (DEBUG) { Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when @@ -911,11 +991,13 @@ public abstract class BaseStatusBar extends SystemUI implements + " expanded=" + oldEntry.expanded + " contentView=" + oldContentView + " bigContentView=" + oldBigContentView + + " publicView=" + oldPublicContentView + " rowParent=" + oldEntry.row.getParent()); Log.d(TAG, "new notification: when=" + notification.getNotification().when + " ongoing=" + oldNotification.isOngoing() + " contentView=" + contentView - + " bigContentView=" + bigContentView); + + " bigContentView=" + bigContentView + + " publicView=" + publicContentView); } // Can we just reapply the RemoteViews in place? If when didn't change, the order @@ -935,8 +1017,17 @@ public abstract class BaseStatusBar extends SystemUI implements && oldBigContentView.getPackage() != null && oldBigContentView.getPackage().equals(bigContentView.getPackage()) && oldBigContentView.getLayoutId() == bigContentView.getLayoutId()); + boolean publicUnchanged = + (oldPublicContentView == null && publicContentView == null) + || ((oldPublicContentView != null && publicContentView != null) + && publicContentView.getPackage() != null + && oldPublicContentView.getPackage() != null + && oldPublicContentView.getPackage().equals(publicContentView.getPackage()) + && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId()); + ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent(); - boolean orderUnchanged = notification.getNotification().when== oldNotification.getNotification().when + boolean orderUnchanged = + notification.getNotification().when == oldNotification.getNotification().when && notification.getScore() == oldNotification.getScore(); // score now encompasses/supersedes isOngoing() @@ -944,7 +1035,8 @@ public abstract class BaseStatusBar extends SystemUI implements && !TextUtils.equals(notification.getNotification().tickerText, oldEntry.notification.getNotification().tickerText); boolean isTopAnyway = isTopNotification(rowParent, oldEntry); - if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) { + if (contentsUnchanged && bigContentsUnchanged && publicUnchanged + && (orderUnchanged || isTopAnyway)) { if (DEBUG) Log.d(TAG, "reusing notification for key: " + key); oldEntry.notification = notification; try { @@ -1018,11 +1110,17 @@ public abstract class BaseStatusBar extends SystemUI implements StatusBarNotification notification) { final RemoteViews contentView = notification.getNotification().contentView; final RemoteViews bigContentView = notification.getNotification().bigContentView; + final RemoteViews publicContentView + = notification.getNotification().publicVersion.contentView; + // Reapply the RemoteViews contentView.reapply(mContext, entry.expanded, mOnClickHandler); if (bigContentView != null && entry.getBigContentView() != null) { bigContentView.reapply(mContext, entry.getBigContentView(), mOnClickHandler); } + if (publicContentView != null && entry.getPublicContentView() != null) { + publicContentView.reapply(mContext, entry.getPublicContentView(), mOnClickHandler); + } // update the contentIntent final PendingIntent contentIntent = notification.getNotification().contentIntent; if (contentIntent != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index cd6495f084df..b3d8688d4b42 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -18,9 +18,12 @@ package com.android.systemui.statusbar; import android.content.Context; import android.util.AttributeSet; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import com.android.systemui.R; + public class ExpandableNotificationRow extends FrameLayout { private int mRowHeight; @@ -30,6 +33,8 @@ public class ExpandableNotificationRow extends FrameLayout { private boolean mUserExpanded; /** is the user touching this row */ private boolean mUserLocked; + /** are we showing the "public" version */ + private boolean mShowingPublic; public ExpandableNotificationRow(Context context, AttributeSet attrs) { super(context, attrs); @@ -76,4 +81,16 @@ public class ExpandableNotificationRow extends FrameLayout { } setLayoutParams(lp); } + + public void setShowingPublic(boolean show) { + mShowingPublic = show; + final ViewGroup publicLayout = (ViewGroup) findViewById(R.id.expandedPublic); + + // bail out if no public version + if (publicLayout.getChildCount() == 0) return; + + // TODO: animation? + publicLayout.setVisibility(show ? View.VISIBLE : View.GONE); + findViewById(R.id.expanded).setVisibility(show ? View.GONE : View.VISIBLE); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index 44b38430fde8..4427466a45a4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -35,6 +35,7 @@ public class NotificationData { public ExpandableNotificationRow row; // the outer expanded view public View content; // takes the click events and sends the PendingIntent public View expanded; // the inflated RemoteViews + public View expandedPublic; // for insecure lockscreens public ImageView largeIcon; private View expandedBig; private boolean interruption; @@ -51,6 +52,7 @@ public class NotificationData { public View getBigContentView() { return expandedBig; } + public View getPublicContentView() { return expandedPublic; } /** * Set the flag indicating that this is being touched by the user. */ @@ -108,19 +110,6 @@ public class NotificationData { return i; } - public int add(IBinder key, StatusBarNotification notification, ExpandableNotificationRow row, - View content, View expanded, StatusBarIconView icon) { - Entry entry = new Entry(); - entry.key = key; - entry.notification = notification; - entry.row = row; - entry.content = content; - entry.expanded = expanded; - entry.icon = icon; - entry.largeIcon = null; // TODO add support for large icons - return add(entry); - } - public Entry remove(IBinder key) { Entry e = findByKey(key); if (e != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 0f3add358a0e..d9e09034eb2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -543,6 +543,11 @@ public class NavigationBarView extends LinearLayout { Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation()); } + // swap to x coordinate if orientation is not in vertical + if (mDelegateHelper != null) { + mDelegateHelper.setSwapXY(!mVertical); + } + setNavigationIconHints(mNavigationIconHints, true); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 124a6bc2b82a..b72c25d2d7b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -514,7 +514,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns if (!mNotificationPanelIsFullScreenWidth) { mScrollView.setSystemUiVisibility( - View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS | View.STATUS_BAR_DISABLE_CLOCK); } @@ -621,7 +620,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { mQS = new QuickSettings(mContext, mSettingsContainer); if (!mNotificationPanelIsFullScreenWidth) { mSettingsContainer.setSystemUiVisibility( - View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER + View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS | View.STATUS_BAR_DISABLE_SYSTEM_INFO); } if (mSettingsPanel != null) { @@ -1031,7 +1030,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { Entry ent = mNotificationData.get(N-i-1); if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue; if (!notificationIsForCurrentUser(ent.notification)) continue; - toShow.add(ent.row); + final int vis = ent.notification.getNotification().visibility; + if (vis != Notification.VISIBILITY_SECRET) { + // when isPublicMode() we show the public form of VISIBILITY_PRIVATE notifications + ent.row.setShowingPublic(isPublicMode() && vis == Notification.VISIBILITY_PRIVATE); + toShow.add(ent.row); + } } ArrayList<View> toRemove = new ArrayList<View>(); @@ -1082,6 +1086,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE) || showNotificationEvenIfUnprovisioned(ent.notification))) continue; if (!notificationIsForCurrentUser(ent.notification)) continue; + if (isPublicMode() + && ent.notification.getNotification().visibility + == Notification.VISIBILITY_SECRET) { + // in "public" mode (atop a secure keyguard), secret notifs are totally hidden + continue; + } toShow.add(ent.icon); } @@ -1243,8 +1253,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " "); flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts"); flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " "); - flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker"); - flagdbg.append(((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " "); + flagdbg.append(((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "PRIVATE" : "private"); + flagdbg.append(((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "* " : " "); flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info"); flagdbg.append(((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " "); flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back"); @@ -1329,10 +1339,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode { .setDuration(175) .start(); } - } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - haltTicker(); + } else if ((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) { + if ((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) { + // we are outside a secure keyguard, so we need to switch to "public" mode + setPublicMode(true); + } else { + // user has authenticated the device; full notifications may be shown + setPublicMode(false); } + updateNotificationIcons(); } } diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java index cbf0c524088f..b9b87b17348a 100644 --- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java +++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java @@ -285,7 +285,6 @@ public class WallpaperCropActivity extends Activity { final Point bounds = cropTask.getImageBounds(); Runnable onEndCrop = new Runnable() { public void run() { - updateWallpaperDimensions(bounds.x, bounds.y); if (finishActivityWhenDone) { setResult(Activity.RESULT_OK); finish(); @@ -309,9 +308,6 @@ public class WallpaperCropActivity extends Activity { inSize.x, inSize.y, outSize.x, outSize.y, false); Runnable onEndCrop = new Runnable() { public void run() { - // Passing 0, 0 will cause launcher to revert to using the - // default wallpaper size - updateWallpaperDimensions(0, 0); if (finishActivityWhenDone) { setResult(Activity.RESULT_OK); finish(); @@ -396,7 +392,6 @@ public class WallpaperCropActivity extends Activity { Runnable onEndCrop = new Runnable() { public void run() { - updateWallpaperDimensions(outWidth, outHeight); if (finishActivityWhenDone) { setResult(Activity.RESULT_OK); finish(); @@ -777,37 +772,6 @@ public class WallpaperCropActivity extends Activity { } } - protected void updateWallpaperDimensions(int width, int height) { - String spKey = getSharedPreferencesKey(); - SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS); - SharedPreferences.Editor editor = sp.edit(); - if (width != 0 && height != 0) { - editor.putInt(WALLPAPER_WIDTH_KEY, width); - editor.putInt(WALLPAPER_HEIGHT_KEY, height); - } else { - editor.remove(WALLPAPER_WIDTH_KEY); - editor.remove(WALLPAPER_HEIGHT_KEY); - } - editor.commit(); - - suggestWallpaperDimension(getResources(), - sp, getWindowManager(), WallpaperManager.getInstance(this)); - } - - static public void suggestWallpaperDimension(Resources res, - final SharedPreferences sharedPrefs, - WindowManager windowManager, - final WallpaperManager wallpaperManager) { - final Point defaultWallpaperSize = getDefaultWallpaperSize(res, windowManager); - // If we have saved a wallpaper width/height, use that instead - int savedWidth = sharedPrefs.getInt(WALLPAPER_WIDTH_KEY, defaultWallpaperSize.x); - int savedHeight = sharedPrefs.getInt(WALLPAPER_HEIGHT_KEY, defaultWallpaperSize.y); - if (savedWidth != wallpaperManager.getDesiredMinimumWidth() || - savedHeight != wallpaperManager.getDesiredMinimumHeight()) { - wallpaperManager.suggestDesiredDimensions(savedWidth, savedHeight); - } - } - protected static RectF getMaxCropRect( int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) { RectF cropRect = new RectF(); diff --git a/preloaded-classes b/preloaded-classes index 42412c6178d0..4d79e4b8c967 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -2455,8 +2455,6 @@ org.apache.harmony.security.fortress.Engine$ServiceCacheEntry org.apache.harmony.security.fortress.Engine$SpiAndProvider org.apache.harmony.security.fortress.SecurityAccess org.apache.harmony.security.fortress.Services -org.apache.harmony.security.provider.cert.DRLCertFactory -org.apache.harmony.security.provider.cert.X509CertImpl org.apache.harmony.security.provider.crypto.CryptoProvider org.apache.harmony.security.utils.AlgNameMapper org.apache.harmony.security.utils.ObjectIdentifier diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 9277cce2374a..1e7c18a956b5 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -83,7 +83,6 @@ import com.android.internal.backup.BackupConstants; import com.android.internal.backup.IBackupTransport; import com.android.internal.backup.IObbBackupService; import com.android.server.EventLogTags; -import com.android.server.SystemService; import com.android.server.backup.PackageManagerBackupAgent.Metadata; import java.io.BufferedInputStream; @@ -142,11 +141,16 @@ public class BackupManagerService extends IBackupManager.Stub { private static final boolean DEBUG = true; private static final boolean MORE_DEBUG = false; + // Historical and current algorithm names + static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1"; + static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit"; + // Name and current contents version of the full-backup manifest file static final String BACKUP_MANIFEST_FILENAME = "_manifest"; static final int BACKUP_MANIFEST_VERSION = 1; static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n"; - static final int BACKUP_FILE_VERSION = 1; + static final int BACKUP_FILE_VERSION = 2; + static final int BACKUP_PW_FILE_VERSION = 2; static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup"; @@ -452,6 +456,8 @@ public class BackupManagerService extends IBackupManager.Stub { private final SecureRandom mRng = new SecureRandom(); private String mPasswordHash; private File mPasswordHashFile; + private int mPasswordVersion; + private File mPasswordVersionFile; private byte[] mPasswordSalt; // Configuration of PBKDF2 that we use for generating pw hashes and intermediate keys @@ -812,6 +818,27 @@ public class BackupManagerService extends IBackupManager.Stub { } mDataDir = Environment.getDownloadCacheDirectory(); + mPasswordVersion = 1; // unless we hear otherwise + mPasswordVersionFile = new File(mBaseStateDir, "pwversion"); + if (mPasswordVersionFile.exists()) { + FileInputStream fin = null; + DataInputStream in = null; + try { + fin = new FileInputStream(mPasswordVersionFile); + in = new DataInputStream(fin); + mPasswordVersion = in.readInt(); + } catch (IOException e) { + Slog.e(TAG, "Unable to read backup pw version"); + } finally { + try { + if (in != null) in.close(); + if (fin != null) fin.close(); + } catch (IOException e) { + Slog.w(TAG, "Error closing pw version files"); + } + } + } + mPasswordHashFile = new File(mBaseStateDir, "pwhash"); if (mPasswordHashFile.exists()) { FileInputStream fin = null; @@ -1112,13 +1139,13 @@ public class BackupManagerService extends IBackupManager.Stub { } } - private SecretKey buildPasswordKey(String pw, byte[] salt, int rounds) { - return buildCharArrayKey(pw.toCharArray(), salt, rounds); + private SecretKey buildPasswordKey(String algorithm, String pw, byte[] salt, int rounds) { + return buildCharArrayKey(algorithm, pw.toCharArray(), salt, rounds); } - private SecretKey buildCharArrayKey(char[] pwArray, byte[] salt, int rounds) { + private SecretKey buildCharArrayKey(String algorithm, char[] pwArray, byte[] salt, int rounds) { try { - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm); KeySpec ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE); return keyFactory.generateSecret(ks); } catch (InvalidKeySpecException e) { @@ -1129,8 +1156,8 @@ public class BackupManagerService extends IBackupManager.Stub { return null; } - private String buildPasswordHash(String pw, byte[] salt, int rounds) { - SecretKey key = buildPasswordKey(pw, salt, rounds); + private String buildPasswordHash(String algorithm, String pw, byte[] salt, int rounds) { + SecretKey key = buildPasswordKey(algorithm, pw, salt, rounds); if (key != null) { return byteArrayToHex(key.getEncoded()); } @@ -1158,13 +1185,13 @@ public class BackupManagerService extends IBackupManager.Stub { return result; } - private byte[] makeKeyChecksum(byte[] pwBytes, byte[] salt, int rounds) { + private byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt, int rounds) { char[] mkAsChar = new char[pwBytes.length]; for (int i = 0; i < pwBytes.length; i++) { mkAsChar[i] = (char) pwBytes[i]; } - Key checksum = buildCharArrayKey(mkAsChar, salt, rounds); + Key checksum = buildCharArrayKey(algorithm, mkAsChar, salt, rounds); return checksum.getEncoded(); } @@ -1176,7 +1203,7 @@ public class BackupManagerService extends IBackupManager.Stub { } // Backup password management - boolean passwordMatchesSaved(String candidatePw, int rounds) { + boolean passwordMatchesSaved(String algorithm, String candidatePw, int rounds) { // First, on an encrypted device we require matching the device pw final boolean isEncrypted; try { @@ -1220,7 +1247,7 @@ public class BackupManagerService extends IBackupManager.Stub { } else { // hash the stated current pw and compare to the stored one if (candidatePw != null && candidatePw.length() > 0) { - String currentPwHash = buildPasswordHash(candidatePw, mPasswordSalt, rounds); + String currentPwHash = buildPasswordHash(algorithm, candidatePw, mPasswordSalt, rounds); if (mPasswordHash.equalsIgnoreCase(currentPwHash)) { // candidate hash matches the stored hash -- the password matches return true; @@ -1235,11 +1262,37 @@ public class BackupManagerService extends IBackupManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupPassword"); - // If the supplied pw doesn't hash to the the saved one, fail - if (!passwordMatchesSaved(currentPw, PBKDF2_HASH_ROUNDS)) { + // When processing v1 passwords we may need to try two different PBKDF2 checksum regimes + final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION); + + // If the supplied pw doesn't hash to the the saved one, fail. The password + // might be caught in the legacy crypto mismatch; verify that too. + if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PBKDF2_HASH_ROUNDS) + && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK, + currentPw, PBKDF2_HASH_ROUNDS))) { return false; } + // Snap up to current on the pw file version + mPasswordVersion = BACKUP_PW_FILE_VERSION; + FileOutputStream pwFout = null; + DataOutputStream pwOut = null; + try { + pwFout = new FileOutputStream(mPasswordVersionFile); + pwOut = new DataOutputStream(pwFout); + pwOut.writeInt(mPasswordVersion); + } catch (IOException e) { + Slog.e(TAG, "Unable to write backup pw version; password not changed"); + return false; + } finally { + try { + if (pwOut != null) pwOut.close(); + if (pwFout != null) pwFout.close(); + } catch (IOException e) { + Slog.w(TAG, "Unable to close pw version record"); + } + } + // Clearing the password is okay if (newPw == null || newPw.isEmpty()) { if (mPasswordHashFile.exists()) { @@ -1257,7 +1310,7 @@ public class BackupManagerService extends IBackupManager.Stub { try { // Okay, build the hash of the new backup password byte[] salt = randomBytes(PBKDF2_SALT_SIZE); - String newPwHash = buildPasswordHash(newPw, salt, PBKDF2_HASH_ROUNDS); + String newPwHash = buildPasswordHash(PBKDF_CURRENT, newPw, salt, PBKDF2_HASH_ROUNDS); OutputStream pwf = null, buffer = null; DataOutputStream out = null; @@ -1300,6 +1353,19 @@ public class BackupManagerService extends IBackupManager.Stub { } } + private boolean backupPasswordMatches(String currentPw) { + if (hasBackupPassword()) { + final boolean pbkdf2Fallback = (mPasswordVersion < BACKUP_PW_FILE_VERSION); + if (!passwordMatchesSaved(PBKDF_CURRENT, currentPw, PBKDF2_HASH_ROUNDS) + && !(pbkdf2Fallback && passwordMatchesSaved(PBKDF_FALLBACK, + currentPw, PBKDF2_HASH_ROUNDS))) { + if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting"); + return false; + } + } + return true; + } + // Maintain persistent state around whether need to do an initialize operation. // Must be called with the queue lock held. void recordInitPendingLocked(boolean isPending, String transportName) { @@ -2721,11 +2787,9 @@ public class BackupManagerService extends IBackupManager.Stub { // Verify that the given password matches the currently-active // backup password, if any - if (hasBackupPassword()) { - if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) { - if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting"); - return; - } + if (!backupPasswordMatches(mCurrentPassword)) { + if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting"); + return; } // Write the global file header. All strings are UTF-8 encoded; lines end @@ -2733,7 +2797,7 @@ public class BackupManagerService extends IBackupManager.Stub { // final '\n'. // // line 1: "ANDROID BACKUP" - // line 2: backup file format version, currently "1" + // line 2: backup file format version, currently "2" // line 3: compressed? "0" if not compressed, "1" if compressed. // line 4: name of encryption algorithm [currently only "none" or "AES-256"] // @@ -2841,7 +2905,7 @@ public class BackupManagerService extends IBackupManager.Stub { OutputStream ofstream) throws Exception { // User key will be used to encrypt the master key. byte[] newUserSalt = randomBytes(PBKDF2_SALT_SIZE); - SecretKey userKey = buildPasswordKey(mEncryptPassword, newUserSalt, + SecretKey userKey = buildPasswordKey(PBKDF_CURRENT, mEncryptPassword, newUserSalt, PBKDF2_HASH_ROUNDS); // the master key is random for each backup @@ -2888,7 +2952,7 @@ public class BackupManagerService extends IBackupManager.Stub { // stated number of PBKDF2 rounds IV = c.getIV(); byte[] mk = masterKeySpec.getEncoded(); - byte[] checksum = makeKeyChecksum(masterKeySpec.getEncoded(), + byte[] checksum = makeKeyChecksum(PBKDF_CURRENT, masterKeySpec.getEncoded(), checksumSalt, PBKDF2_HASH_ROUNDS); ByteArrayOutputStream blob = new ByteArrayOutputStream(IV.length + mk.length @@ -3231,11 +3295,9 @@ public class BackupManagerService extends IBackupManager.Stub { FileInputStream rawInStream = null; DataInputStream rawDataIn = null; try { - if (hasBackupPassword()) { - if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) { - if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting"); - return; - } + if (!backupPasswordMatches(mCurrentPassword)) { + if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting"); + return; } mBytes = 0; @@ -3256,8 +3318,12 @@ public class BackupManagerService extends IBackupManager.Stub { if (Arrays.equals(magicBytes, streamHeader)) { // okay, header looks good. now parse out the rest of the fields. String s = readHeaderLine(rawInStream); - if (Integer.parseInt(s) == BACKUP_FILE_VERSION) { - // okay, it's a version we recognize + final int archiveVersion = Integer.parseInt(s); + if (archiveVersion <= BACKUP_FILE_VERSION) { + // okay, it's a version we recognize. if it's version 1, we may need + // to try two different PBKDF2 regimes to compare checksums. + final boolean pbkdf2Fallback = (archiveVersion == 1); + s = readHeaderLine(rawInStream); compressed = (Integer.parseInt(s) != 0); s = readHeaderLine(rawInStream); @@ -3265,7 +3331,8 @@ public class BackupManagerService extends IBackupManager.Stub { // no more header to parse; we're good to go okay = true; } else if (mDecryptPassword != null && mDecryptPassword.length() > 0) { - preCompressStream = decodeAesHeaderAndInitialize(s, rawInStream); + preCompressStream = decodeAesHeaderAndInitialize(s, pbkdf2Fallback, + rawInStream); if (preCompressStream != null) { okay = true; } @@ -3325,7 +3392,71 @@ public class BackupManagerService extends IBackupManager.Stub { return buffer.toString(); } - InputStream decodeAesHeaderAndInitialize(String encryptionName, InputStream rawInStream) { + InputStream attemptMasterKeyDecryption(String algorithm, byte[] userSalt, byte[] ckSalt, + int rounds, String userIvHex, String masterKeyBlobHex, InputStream rawInStream, + boolean doLog) { + InputStream result = null; + + try { + Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); + SecretKey userKey = buildPasswordKey(algorithm, mDecryptPassword, userSalt, + rounds); + byte[] IV = hexToByteArray(userIvHex); + IvParameterSpec ivSpec = new IvParameterSpec(IV); + c.init(Cipher.DECRYPT_MODE, + new SecretKeySpec(userKey.getEncoded(), "AES"), + ivSpec); + byte[] mkCipher = hexToByteArray(masterKeyBlobHex); + byte[] mkBlob = c.doFinal(mkCipher); + + // first, the master key IV + int offset = 0; + int len = mkBlob[offset++]; + IV = Arrays.copyOfRange(mkBlob, offset, offset + len); + offset += len; + // then the master key itself + len = mkBlob[offset++]; + byte[] mk = Arrays.copyOfRange(mkBlob, + offset, offset + len); + offset += len; + // and finally the master key checksum hash + len = mkBlob[offset++]; + byte[] mkChecksum = Arrays.copyOfRange(mkBlob, + offset, offset + len); + + // now validate the decrypted master key against the checksum + byte[] calculatedCk = makeKeyChecksum(algorithm, mk, ckSalt, rounds); + if (Arrays.equals(calculatedCk, mkChecksum)) { + ivSpec = new IvParameterSpec(IV); + c.init(Cipher.DECRYPT_MODE, + new SecretKeySpec(mk, "AES"), + ivSpec); + // Only if all of the above worked properly will 'result' be assigned + result = new CipherInputStream(rawInStream, c); + } else if (doLog) Slog.w(TAG, "Incorrect password"); + } catch (InvalidAlgorithmParameterException e) { + if (doLog) Slog.e(TAG, "Needed parameter spec unavailable!", e); + } catch (BadPaddingException e) { + // This case frequently occurs when the wrong password is used to decrypt + // the master key. Use the identical "incorrect password" log text as is + // used in the checksum failure log in order to avoid providing additional + // information to an attacker. + if (doLog) Slog.w(TAG, "Incorrect password"); + } catch (IllegalBlockSizeException e) { + if (doLog) Slog.w(TAG, "Invalid block size in master key"); + } catch (NoSuchAlgorithmException e) { + if (doLog) Slog.e(TAG, "Needed decryption algorithm unavailable!"); + } catch (NoSuchPaddingException e) { + if (doLog) Slog.e(TAG, "Needed padding mechanism unavailable!"); + } catch (InvalidKeyException e) { + if (doLog) Slog.w(TAG, "Illegal password; aborting"); + } + + return result; + } + + InputStream decodeAesHeaderAndInitialize(String encryptionName, boolean pbkdf2Fallback, + InputStream rawInStream) { InputStream result = null; try { if (encryptionName.equals(ENCRYPTION_ALGORITHM_NAME)) { @@ -3342,59 +3473,13 @@ public class BackupManagerService extends IBackupManager.Stub { String masterKeyBlobHex = readHeaderLine(rawInStream); // 9 // decrypt the master key blob - Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); - SecretKey userKey = buildPasswordKey(mDecryptPassword, userSalt, - rounds); - byte[] IV = hexToByteArray(userIvHex); - IvParameterSpec ivSpec = new IvParameterSpec(IV); - c.init(Cipher.DECRYPT_MODE, - new SecretKeySpec(userKey.getEncoded(), "AES"), - ivSpec); - byte[] mkCipher = hexToByteArray(masterKeyBlobHex); - byte[] mkBlob = c.doFinal(mkCipher); - - // first, the master key IV - int offset = 0; - int len = mkBlob[offset++]; - IV = Arrays.copyOfRange(mkBlob, offset, offset + len); - offset += len; - // then the master key itself - len = mkBlob[offset++]; - byte[] mk = Arrays.copyOfRange(mkBlob, - offset, offset + len); - offset += len; - // and finally the master key checksum hash - len = mkBlob[offset++]; - byte[] mkChecksum = Arrays.copyOfRange(mkBlob, - offset, offset + len); - - // now validate the decrypted master key against the checksum - byte[] calculatedCk = makeKeyChecksum(mk, ckSalt, rounds); - if (Arrays.equals(calculatedCk, mkChecksum)) { - ivSpec = new IvParameterSpec(IV); - c.init(Cipher.DECRYPT_MODE, - new SecretKeySpec(mk, "AES"), - ivSpec); - // Only if all of the above worked properly will 'result' be assigned - result = new CipherInputStream(rawInStream, c); - } else Slog.w(TAG, "Incorrect password"); + result = attemptMasterKeyDecryption(PBKDF_CURRENT, userSalt, ckSalt, + rounds, userIvHex, masterKeyBlobHex, rawInStream, false); + if (result == null && pbkdf2Fallback) { + result = attemptMasterKeyDecryption(PBKDF_FALLBACK, userSalt, ckSalt, + rounds, userIvHex, masterKeyBlobHex, rawInStream, true); + } } else Slog.w(TAG, "Unsupported encryption method: " + encryptionName); - } catch (InvalidAlgorithmParameterException e) { - Slog.e(TAG, "Needed parameter spec unavailable!", e); - } catch (BadPaddingException e) { - // This case frequently occurs when the wrong password is used to decrypt - // the master key. Use the identical "incorrect password" log text as is - // used in the checksum failure log in order to avoid providing additional - // information to an attacker. - Slog.w(TAG, "Incorrect password"); - } catch (IllegalBlockSizeException e) { - Slog.w(TAG, "Invalid block size in master key"); - } catch (NoSuchAlgorithmException e) { - Slog.e(TAG, "Needed decryption algorithm unavailable!"); - } catch (NoSuchPaddingException e) { - Slog.e(TAG, "Needed padding mechanism unavailable!"); - } catch (InvalidKeyException e) { - Slog.w(TAG, "Illegal password; aborting"); } catch (NumberFormatException e) { Slog.w(TAG, "Can't parse restore data header"); } catch (IOException e) { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 64ab3e414b1d..015185f81983 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -26,6 +26,7 @@ import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIMAX; +import static android.net.ConnectivityManager.TYPE_PROXY; import static android.net.ConnectivityManager.getNetworkTypeName; import static android.net.ConnectivityManager.isNetworkTypeValid; import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; @@ -69,6 +70,7 @@ import android.net.NetworkState; import android.net.NetworkStateTracker; import android.net.NetworkUtils; import android.net.Proxy; +import android.net.ProxyDataTracker; import android.net.ProxyProperties; import android.net.RouteInfo; import android.net.SamplingDataTracker; @@ -729,6 +731,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { return makeWimaxStateTracker(mContext, mTrackerHandler); case TYPE_ETHERNET: return EthernetDataTracker.getInstance(); + case TYPE_PROXY: + return new ProxyDataTracker(); default: throw new IllegalArgumentException( "Trying to create a NetworkStateTracker for an unknown radio type: " diff --git a/services/core/java/com/android/server/IdleMaintenanceService.java b/services/core/java/com/android/server/IdleMaintenanceService.java index b0a1aca37d7c..acc6abe89b33 100644 --- a/services/core/java/com/android/server/IdleMaintenanceService.java +++ b/services/core/java/com/android/server/IdleMaintenanceService.java @@ -16,22 +16,38 @@ package com.android.server; -import android.app.Activity; -import android.app.ActivityManagerNative; import android.app.AlarmManager; import android.app.PendingIntent; +import android.app.maintenance.IIdleCallback; +import android.app.maintenance.IIdleService; +import android.app.maintenance.IdleService; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager.WakeLock; +import android.os.IBinder; +import android.os.Looper; +import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; +import android.os.WorkSource; +import android.util.ArrayMap; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; /** * This service observes the device state and when applicable sends @@ -47,12 +63,15 @@ import android.util.Slog; * * The end of a maintenance window is announced only if: a start was * announced AND the screen turned on or a dream was stopped. + * + * Method naming note: + * Methods whose name ends with "Tm" must only be called from the main thread. */ public class IdleMaintenanceService extends BroadcastReceiver { private static final boolean DEBUG = false; - private static final String LOG_TAG = IdleMaintenanceService.class.getSimpleName(); + private static final String TAG = IdleMaintenanceService.class.getSimpleName(); private static final int LAST_USER_ACTIVITY_TIME_INVALID = -1; @@ -74,36 +93,480 @@ public class IdleMaintenanceService extends BroadcastReceiver { private static final String ACTION_FORCE_IDLE_MAINTENANCE = "com.android.server.IdleMaintenanceService.action.FORCE_IDLE_MAINTENANCE"; - private static final Intent sIdleMaintenanceStartIntent; - static { - sIdleMaintenanceStartIntent = new Intent(Intent.ACTION_IDLE_MAINTENANCE_START); - sIdleMaintenanceStartIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - }; + static final int MSG_OP_COMPLETE = 1; + static final int MSG_IDLE_FINISHED = 2; + static final int MSG_TIMEOUT = 3; - private static final Intent sIdleMaintenanceEndIntent; - static { - sIdleMaintenanceEndIntent = new Intent(Intent.ACTION_IDLE_MAINTENANCE_END); - sIdleMaintenanceEndIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - } + // when a timeout happened, what were we expecting? + static final int VERB_BINDING = 1; + static final int VERB_IDLING = 2; + static final int VERB_ENDING = 3; - private final AlarmManager mAlarmService; + // What are our relevant timeouts / allocated slices? + static final long OP_TIMEOUT = 8 * 1000; // 8 seconds to bind or ack the start + static final long IDLE_TIMESLICE = 10 * 60 * 1000; // ten minutes for each idler + private final AlarmManager mAlarmService; private final BatteryService mBatteryService; - private final PendingIntent mUpdateIdleMaintenanceStatePendingIntent; - private final Context mContext; - private final WakeLock mWakeLock; - - private final Handler mHandler; + private final WorkSource mSystemWorkSource = new WorkSource(Process.myUid()); private long mLastIdleMaintenanceStartTimeMillis; - private long mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID; - private boolean mIdleMaintenanceStarted; + final IdleCallback mCallback; + final Handler mHandler; + + final Random mTokenGenerator = new Random(); + + int makeToken() { + int token; + do { + token = mTokenGenerator.nextInt(Integer.MAX_VALUE); + } while (token == 0); + return token; + } + + class ActiveTask { + public IdleServiceInfo who; + public int verb; + public int token; + + ActiveTask(IdleServiceInfo target, int action) { + who = target; + verb = action; + token = makeToken(); + } + + @Override + public String toString() { + return "ActiveTask{" + Integer.toHexString(this.hashCode()) + + " : verb=" + verb + + " : token=" + token + + " : "+ who + "}"; + } + } + + // What operations are in flight? + final SparseArray<ActiveTask> mPendingOperations = new SparseArray<ActiveTask>(); + + // Idle service queue management + class IdleServiceInfo { + public final ComponentName componentName; + public final int uid; + public IIdleService service; + + IdleServiceInfo(ResolveInfo info, ComponentName cname) { + componentName = cname; // derived from 'info' but this avoids an extra object + uid = info.serviceInfo.applicationInfo.uid; + service = null; + } + + @Override + public int hashCode() { + return componentName.hashCode(); + } + + @Override + public String toString() { + return "IdleServiceInfo{" + componentName + + " / " + (service == null ? "null" : service.asBinder()) + "}"; + } + } + + final ArrayMap<ComponentName, IdleServiceInfo> mIdleServices = + new ArrayMap<ComponentName, IdleServiceInfo>(); + final LinkedList<IdleServiceInfo> mIdleServiceQueue = new LinkedList<IdleServiceInfo>(); + IdleServiceInfo mCurrentIdler; // set when we've committed to launching an idler + IdleServiceInfo mLastIdler; // end of queue when idling begins + + void reportNoTimeout(int token, boolean result) { + final Message msg = mHandler.obtainMessage(MSG_OP_COMPLETE, result ? 1 : 0, token); + mHandler.sendMessage(msg); + } + + // Binder acknowledgment trampoline + class IdleCallback extends IIdleCallback.Stub { + @Override + public void acknowledgeStart(int token, boolean result) throws RemoteException { + reportNoTimeout(token, result); + } + + @Override + public void acknowledgeStop(int token) throws RemoteException { + reportNoTimeout(token, false); + } + + @Override + public void idleFinished(int token) throws RemoteException { + if (DEBUG) { + Slog.v(TAG, "idleFinished: " + token); + } + final Message msg = mHandler.obtainMessage(MSG_IDLE_FINISHED, 0, token); + mHandler.sendMessage(msg); + } + } + + // Stuff that we run on a Handler + class IdleHandler extends Handler { + public IdleHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message msg) { + final int token = msg.arg2; + + switch (msg.what) { + case MSG_OP_COMPLETE: { + if (DEBUG) { + Slog.i(TAG, "MSG_OP_COMPLETE of " + token); + } + ActiveTask task = mPendingOperations.get(token); + if (task != null) { + mPendingOperations.remove(token); + removeMessages(MSG_TIMEOUT); + + handleOpCompleteTm(task, msg.arg1); + } else { + // Can happen in a race between timeout and actual + // (belated) completion of a "begin idling" or similar + // operation. In that state we've already processed the + // timeout, so we intentionally no-op here. + if (DEBUG) { + Slog.w(TAG, "Belated op-complete of " + token); + } + } + break; + } + + case MSG_IDLE_FINISHED: { + if (DEBUG) { + Slog.i(TAG, "MSG_IDLE_FINISHED of " + token); + } + ActiveTask task = mPendingOperations.get(token); + if (task != null) { + if (DEBUG) { + Slog.i(TAG, "... removing task " + token); + } + mPendingOperations.remove(token); + removeMessages(MSG_TIMEOUT); + + handleIdleFinishedTm(task); + } else { + // Can happen "legitimately" from an app explicitly calling + // idleFinished() after already having been told that its slice + // has ended. + if (DEBUG) { + Slog.w(TAG, "Belated idle-finished of " + token); + } + } + break; + } + + case MSG_TIMEOUT: { + if (DEBUG) { + Slog.i(TAG, "MSG_TIMEOUT of " + token); + } + ActiveTask task = mPendingOperations.get(token); + if (task != null) { + mPendingOperations.remove(token); + removeMessages(MSG_OP_COMPLETE); + + handleTimeoutTm(task); + } else { + // This one should not happen; we flushed timeout messages + // whenever we entered a state after which we have established + // that they are not appropriate. + Slog.w(TAG, "Unexpected timeout of " + token); + } + break; + } + + default: + Slog.w(TAG, "Unknown message: " + msg.what); + } + } + } + + void handleTimeoutTm(ActiveTask task) { + switch (task.verb) { + case VERB_BINDING: { + // We were trying to bind to this service, but it wedged or otherwise + // failed to respond in time. Let it stay in the queue for the next + // time around, but just give up on it for now and go on to the next. + startNextIdleServiceTm(); + break; + } + case VERB_IDLING: { + // The service has reached the end of its designated idle timeslice. + // This is not considered an error. + if (DEBUG) { + Slog.i(TAG, "Idler reached end of timeslice: " + task.who); + } + sendEndIdleTm(task.who); + break; + } + case VERB_ENDING: { + if (mCurrentIdler == task.who) { + if (DEBUG) { + Slog.i(TAG, "Task timed out when ending; unbind needed"); + } + handleIdleFinishedTm(task); + } else { + if (DEBUG) { + Slog.w(TAG, "Ending timeout for non-current idle service!"); + } + } + break; + } + default: { + Slog.w(TAG, "Unknown timeout state " + task.verb); + break; + } + } + } + + void handleOpCompleteTm(ActiveTask task, int result) { + if (DEBUG) { + Slog.i(TAG, "handleOpComplete : task=" + task + " result=" + result); + } + if (task.verb == VERB_IDLING) { + // If the service was told to begin idling and responded positively, then + // it has begun idling and will eventually either explicitly finish, or + // reach the end of its allotted timeslice. It's running free now, so we + // just schedule the idle-expiration timeout under the token it's already been + // given and let it keep going. + if (result != 0) { + scheduleOpTimeoutTm(task); + } else { + // The idle service has indicated that it does not, in fact, + // need to run at present, so we immediately indicate that it's + // to finish idling, and go on to the next idler. + if (DEBUG) { + Slog.i(TAG, "Idler declined idling; moving along"); + } + sendEndIdleTm(task.who); + } + } else { + // In the idling case, the task will be cleared either as the result of a timeout + // or of an explicit idleFinished(). For all other operations (binding, ending) we + // are done with the task as such, so we remove it from our bookkeeping. + if (DEBUG) { + Slog.i(TAG, "Clearing task " + task); + } + mPendingOperations.remove(task.token); + if (task.verb == VERB_ENDING) { + // The last bit of handshaking around idle cessation for this target + handleIdleFinishedTm(task); + } + } + } + + void handleIdleFinishedTm(ActiveTask task) { + final IdleServiceInfo who = task.who; + if (who == mCurrentIdler) { + if (DEBUG) { + Slog.i(TAG, "Current idler has finished: " + who); + Slog.i(TAG, "Attributing wakelock to system work source"); + } + mContext.unbindService(mConnection); + startNextIdleServiceTm(); + } else { + Slog.w(TAG, "finish from non-current idle service? " + who); + } + } + + void updateIdleServiceQueueTm() { + if (DEBUG) { + Slog.i(TAG, "Updating idle service queue"); + } + PackageManager pm = mContext.getPackageManager(); + Intent idleIntent = new Intent(IdleService.SERVICE_INTERFACE); + List<ResolveInfo> services = pm.queryIntentServices(idleIntent, 0); + for (ResolveInfo info : services) { + if (info.serviceInfo != null) { + if (IdleService.PERMISSION_BIND.equals(info.serviceInfo.permission)) { + final ComponentName componentName = new ComponentName( + info.serviceInfo.packageName, + info.serviceInfo.name); + if (DEBUG) { + Slog.i(TAG, " - " + componentName); + } + if (!mIdleServices.containsKey(componentName)) { + if (DEBUG) { + Slog.i(TAG, " + not known; adding"); + } + IdleServiceInfo serviceInfo = new IdleServiceInfo(info, componentName); + mIdleServices.put(componentName, serviceInfo); + mIdleServiceQueue.add(serviceInfo); + } + } else { + if (DEBUG) { + Slog.i(TAG, "Idle service " + info.serviceInfo + + " does not have required permission; ignoring"); + } + } + } + } + } + + void startNextIdleServiceTm() { + mWakeLock.setWorkSource(mSystemWorkSource); + + if (mLastIdler == null) { + // we've run the queue; nothing more to do until the next idle interval. + if (DEBUG) { + Slog.i(TAG, "Queue already drained; nothing more to do"); + } + return; + } + + if (DEBUG) { + Slog.i(TAG, "startNextIdleService : last=" + mLastIdler + " cur=" + mCurrentIdler); + if (mIdleServiceQueue.size() > 0) { + int i = 0; + Slog.i(TAG, "Queue (" + mIdleServiceQueue.size() + "):"); + for (IdleServiceInfo info : mIdleServiceQueue) { + Slog.i(TAG, " " + i + " : " + info); + i++; + } + } + } + if (mCurrentIdler != mLastIdler) { + if (mIdleServiceQueue.size() > 0) { + IdleServiceInfo target = mIdleServiceQueue.pop(); + if (DEBUG) { + Slog.i(TAG, "starting next idle service " + target); + } + Intent idleIntent = new Intent(IdleService.SERVICE_INTERFACE); + idleIntent.setComponent(target.componentName); + mCurrentIdler = target; + ActiveTask task = new ActiveTask(target, VERB_BINDING); + scheduleOpTimeoutTm(task); + boolean bindOk = mContext.bindServiceAsUser(idleIntent, mConnection, + Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY, UserHandle.OWNER); + if (!bindOk) { + if (DEBUG) { + Slog.w(TAG, "bindService() to " + target.componentName + + " failed"); + } + } else { + mIdleServiceQueue.add(target); // at the end for next time + if (DEBUG) { Slog.i(TAG, "Attributing wakelock to target uid " + target.uid); } + mWakeLock.setWorkSource(new WorkSource(target.uid)); + } + } else { + // Queue is empty but mLastIdler is non-null -- eeep. Clear *everything* + // and wind up until the next time around. + Slog.e(TAG, "Queue unexpectedly empty; resetting. last=" + + mLastIdler + " cur=" + mCurrentIdler); + mHandler.removeMessages(MSG_TIMEOUT); + mPendingOperations.clear(); + stopIdleMaintenanceTm(); + } + } else { + // we've reached the place we started, so mark the queue as drained + if (DEBUG) { + Slog.i(TAG, "Reached end of queue."); + } + stopIdleMaintenanceTm(); + } + } + + void sendStartIdleTm(IdleServiceInfo who) { + ActiveTask task = new ActiveTask(who, VERB_IDLING); + scheduleOpTimeoutTm(task); + try { + who.service.startIdleMaintenance(mCallback, task.token); + } catch (RemoteException e) { + // We bound to it, but now we can't reach it. Bail and go on to the + // next service. + mContext.unbindService(mConnection); + if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); } + mHandler.removeMessages(MSG_TIMEOUT); + startNextIdleServiceTm(); + } + } + + void sendEndIdleTm(IdleServiceInfo who) { + ActiveTask task = new ActiveTask(who, VERB_ENDING); + scheduleOpTimeoutTm(task); + if (DEBUG) { + Slog.i(TAG, "Sending end-idle to " + who); + } + try { + who.service.stopIdleMaintenance(mCallback, task.token); + } catch (RemoteException e) { + // We bound to it, but now we can't reach it. Bail and go on to the + // next service. + mContext.unbindService(mConnection); + if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); } + mHandler.removeMessages(MSG_TIMEOUT); + startNextIdleServiceTm(); + } + } + + ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) { + Slog.i(TAG, "onServiceConnected(" + name + ")"); + } + IdleServiceInfo info = mIdleServices.get(name); + if (info != null) { + // Bound! Cancel the bind timeout + mHandler.removeMessages(MSG_TIMEOUT); + // Now tell it to start its idle work + info.service = IIdleService.Stub.asInterface(service); + sendStartIdleTm(info); + } else { + // We bound to a service we don't know about. That's ungood. + Slog.e(TAG, "Connected to unexpected component " + name); + mContext.unbindService(this); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (DEBUG) { + Slog.i(TAG, "onServiceDisconnected(" + name + ")"); + } + IdleServiceInfo who = mIdleServices.get(name); + if (who == mCurrentIdler) { + // Hm, okay; they didn't tell us they were finished but they + // went away. Crashed, probably. Oh well. They're gone, so + // we can't finish them cleanly; just force things along. + Slog.w(TAG, "Idler unexpectedly vanished: " + mCurrentIdler); + mContext.unbindService(this); + mHandler.removeMessages(MSG_TIMEOUT); + startNextIdleServiceTm(); + } else { + // Not the current idler, so we don't interrupt our process... + if (DEBUG) { + Slog.w(TAG, "Disconnect of abandoned or unexpected service " + name); + } + } + } + }; + + // Schedules a timeout / end-of-work based on the task verb + void scheduleOpTimeoutTm(ActiveTask task) { + final long timeoutMillis = (task.verb == VERB_IDLING) ? IDLE_TIMESLICE : OP_TIMEOUT; + if (DEBUG) { + Slog.i(TAG, "Scheduling timeout (token " + task.token + + " : verb " + task.verb + ") for " + task + " in " + timeoutMillis); + } + mPendingOperations.put(task.token, task); + mHandler.removeMessages(MSG_TIMEOUT); + final Message msg = mHandler.obtainMessage(MSG_TIMEOUT, 0, task.token); + mHandler.sendMessageDelayed(msg, timeoutMillis); + } + + // ------------------------------------------------------------------------------- public IdleMaintenanceService(Context context, BatteryService batteryService) { mContext = context; mBatteryService = batteryService; @@ -111,9 +574,10 @@ public class IdleMaintenanceService extends BroadcastReceiver { mAlarmService = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - mHandler = new Handler(mContext.getMainLooper()); + mHandler = new IdleHandler(mContext.getMainLooper()); + mCallback = new IdleCallback(); Intent intent = new Intent(ACTION_UPDATE_IDLE_MAINTENANCE_STATE); intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); @@ -159,26 +623,28 @@ public class IdleMaintenanceService extends BroadcastReceiver { mAlarmService.cancel(mUpdateIdleMaintenanceStatePendingIntent); } - private void updateIdleMaintenanceState(boolean noisy) { + private void updateIdleMaintenanceStateTm(boolean noisy) { if (mIdleMaintenanceStarted) { // Idle maintenance can be interrupted by user activity, or duration // time out, or low battery. - if (!lastUserActivityPermitsIdleMaintenanceRunning() - || !batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning()) { + final boolean batteryOk + = batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning(); + if (!lastUserActivityPermitsIdleMaintenanceRunning() || !batteryOk) { unscheduleUpdateIdleMaintenanceState(); mIdleMaintenanceStarted = false; - EventLogTags.writeIdleMaintenanceWindowFinish(SystemClock.elapsedRealtime(), - mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(), - isBatteryCharging() ? 1 : 0); - sendIdleMaintenanceEndIntent(); // We stopped since we don't have enough battery or timed out but the // user is not using the device, so we should be able to run maintenance // in the next maintenance window since the battery may be charged // without interaction and the min interval between maintenances passed. - if (!batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning()) { + if (!batteryOk) { scheduleUpdateIdleMaintenanceState( getNextIdleMaintenanceIntervalStartFromNow()); } + + EventLogTags.writeIdleMaintenanceWindowFinish(SystemClock.elapsedRealtime(), + mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(), + isBatteryCharging() ? 1 : 0); + scheduleIdleFinishTm(); } } else if (deviceStatePermitsIdleMaintenanceStart(noisy) && lastUserActivityPermitsIdleMaintenanceStart(noisy) @@ -191,7 +657,7 @@ public class IdleMaintenanceService extends BroadcastReceiver { mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(), isBatteryCharging() ? 1 : 0); mLastIdleMaintenanceStartTimeMillis = SystemClock.elapsedRealtime(); - sendIdleMaintenanceStartIntent(); + startIdleMaintenanceTm(); } else if (lastUserActivityPermitsIdleMaintenanceStart(noisy)) { if (lastRunPermitsIdleMaintenanceStart(noisy)) { // The user does not use the device and we did not run maintenance in more @@ -207,25 +673,55 @@ public class IdleMaintenanceService extends BroadcastReceiver { } } - private long getNextIdleMaintenanceIntervalStartFromNow() { - return mLastIdleMaintenanceStartTimeMillis + MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS - - SystemClock.elapsedRealtime(); + void startIdleMaintenanceTm() { + if (DEBUG) { + Slog.i(TAG, "*** Starting idle maintenance ***"); + } + if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); } + mWakeLock.setWorkSource(mSystemWorkSource); + mWakeLock.acquire(); + updateIdleServiceQueueTm(); + mCurrentIdler = null; + mLastIdler = (mIdleServiceQueue.size() > 0) ? mIdleServiceQueue.peekLast() : null; + startNextIdleServiceTm(); } - private void sendIdleMaintenanceStartIntent() { - mWakeLock.acquire(); - try { - ActivityManagerNative.getDefault().performIdleMaintenance(); - } catch (RemoteException e) { + // Start a graceful wind-down of the idle maintenance state: end the current idler + // and pretend that we've finished running the queue. If there's no current idler, + // this is a no-op. + void scheduleIdleFinishTm() { + if (mCurrentIdler != null) { + if (DEBUG) { + Slog.i(TAG, "*** Finishing idle maintenance ***"); + } + mLastIdler = mCurrentIdler; + sendEndIdleTm(mCurrentIdler); + } else { + if (DEBUG) { + Slog.w(TAG, "Asked to finish idle maintenance but we're done already"); + } } - mContext.sendOrderedBroadcastAsUser(sIdleMaintenanceStartIntent, UserHandle.ALL, - null, this, mHandler, Activity.RESULT_OK, null, null); } - private void sendIdleMaintenanceEndIntent() { - mWakeLock.acquire(); - mContext.sendOrderedBroadcastAsUser(sIdleMaintenanceEndIntent, UserHandle.ALL, - null, this, mHandler, Activity.RESULT_OK, null, null); + // Actual finalization of the idle maintenance sequence + void stopIdleMaintenanceTm() { + if (mLastIdler != null) { + if (DEBUG) { + Slog.i(TAG, "*** Idle maintenance shutdown ***"); + } + mWakeLock.setWorkSource(mSystemWorkSource); + mLastIdler = mCurrentIdler = null; + updateIdleMaintenanceStateTm(false); // resets 'started' and schedules next window + mWakeLock.release(); + } else { + Slog.e(TAG, "ERROR: idle shutdown but invariants not held. last=" + mLastIdler + + " cur=" + mCurrentIdler + " size=" + mIdleServiceQueue.size()); + } + } + + private long getNextIdleMaintenanceIntervalStartFromNow() { + return mLastIdleMaintenanceStartTimeMillis + MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS + - SystemClock.elapsedRealtime(); } private boolean deviceStatePermitsIdleMaintenanceStart(boolean noisy) { @@ -281,7 +777,7 @@ public class IdleMaintenanceService extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (DEBUG) { - Log.i(LOG_TAG, intent.getAction()); + Log.i(TAG, intent.getAction()); } String action = intent.getAction(); if (Intent.ACTION_BATTERY_CHANGED.equals(action)) { @@ -292,7 +788,7 @@ public class IdleMaintenanceService extends BroadcastReceiver { // next release. The only client for this for now is internal an holds // a wake lock correctly. if (mIdleMaintenanceStarted) { - updateIdleMaintenanceState(false); + updateIdleMaintenanceStateTm(false); } } else if (Intent.ACTION_SCREEN_ON.equals(action) || Intent.ACTION_DREAMING_STOPPED.equals(action)) { @@ -302,7 +798,7 @@ public class IdleMaintenanceService extends BroadcastReceiver { unscheduleUpdateIdleMaintenanceState(); // If the screen went on/stopped dreaming, we know the user is using the // device which means that idle maintenance should be stopped if running. - updateIdleMaintenanceState(false); + updateIdleMaintenanceStateTm(false); } else if (Intent.ACTION_SCREEN_OFF.equals(action) || Intent.ACTION_DREAMING_STARTED.equals(action)) { mLastUserActivityElapsedTimeMillis = SystemClock.elapsedRealtime(); @@ -311,17 +807,12 @@ public class IdleMaintenanceService extends BroadcastReceiver { // this timeout elapses since the device may go to sleep by then. scheduleUpdateIdleMaintenanceState(MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START); } else if (ACTION_UPDATE_IDLE_MAINTENANCE_STATE.equals(action)) { - updateIdleMaintenanceState(false); + updateIdleMaintenanceStateTm(false); } else if (ACTION_FORCE_IDLE_MAINTENANCE.equals(action)) { long now = SystemClock.elapsedRealtime() - 1; mLastUserActivityElapsedTimeMillis = now - MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START; mLastIdleMaintenanceStartTimeMillis = now - MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS; - updateIdleMaintenanceState(true); - } else if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action) - || Intent.ACTION_IDLE_MAINTENANCE_END.equals(action)) { - // We were holding a wake lock while broadcasting the idle maintenance - // intents but now that we finished the broadcast release the wake lock. - mWakeLock.release(); + updateIdleMaintenanceStateTm(true); } } } diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 816ae6967cfd..e6e4bca4f966 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -107,6 +107,9 @@ import javax.crypto.spec.PBEKeySpec; class MountService extends IMountService.Stub implements INativeDaemonConnectorCallbacks, Watchdog.Monitor { + // Static direct instance pointer for the tightly-coupled idle service to use + static MountService sSelf = null; + // TODO: listen for user creation/deletion private static final boolean LOCAL_LOGD = false; @@ -345,6 +348,7 @@ class MountService extends IMountService.Stub private static final int H_UNMOUNT_PM_DONE = 2; private static final int H_UNMOUNT_MS = 3; private static final int H_SYSTEM_READY = 4; + private static final int H_FSTRIM = 5; private static final int RETRY_UNMOUNT_DELAY = 30; // in ms private static final int MAX_UNMOUNT_RETRIES = 4; @@ -494,6 +498,24 @@ class MountService extends IMountService.Stub } break; } + case H_FSTRIM: { + waitForReady(); + Slog.i(TAG, "Running fstrim idle maintenance"); + try { + // This method must be run on the main (handler) thread, + // so it is safe to directly call into vold. + mConnector.execute("fstrim", "dotrim"); + EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime()); + } catch (NativeDaemonConnectorException ndce) { + Slog.e(TAG, "Failed to run fstrim!"); + } + // invoke the completion callback, if any + Runnable callback = (Runnable) msg.obj; + if (callback != null) { + callback.run(); + } + break; + } } } }; @@ -608,27 +630,6 @@ class MountService extends IMountService.Stub } }; - private final BroadcastReceiver mIdleMaintenanceReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - waitForReady(); - String action = intent.getAction(); - // Since fstrim will be run on a daily basis we do not expect - // fstrim to be too long, so it is not interruptible. We will - // implement interruption only in case we see issues. - if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action)) { - try { - // This method runs on the handler thread, - // so it is safe to directly call into vold. - mConnector.execute("fstrim", "dotrim"); - EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime()); - } catch (NativeDaemonConnectorException ndce) { - Slog.e(TAG, "Failed to run fstrim!"); - } - } - } - }; - private final class MountServiceBinderListener implements IBinder.DeathRecipient { final IMountServiceListener mListener; @@ -646,6 +647,10 @@ class MountService extends IMountService.Stub } } + void runIdleMaintenance(Runnable callback) { + mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback)); + } + private void doShareUnshareVolume(String path, String method, boolean enable) { // TODO: Add support for multiple share methods if (!method.equals("ums")) { @@ -1337,6 +1342,8 @@ class MountService extends IMountService.Stub * @param context Binder context for this service */ public MountService(Context context) { + sSelf = this; + mContext = context; synchronized (mVolumesLock) { @@ -1363,12 +1370,6 @@ class MountService extends IMountService.Stub mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE), null, mHandler); } - // Watch for idle maintenance changes - IntentFilter idleMaintenanceFilter = new IntentFilter(); - idleMaintenanceFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START); - mContext.registerReceiverAsUser(mIdleMaintenanceReceiver, UserHandle.ALL, - idleMaintenanceFilter, null, mHandler); - // Add OBB Action Handler to MountService thread. mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper()); diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java new file mode 100644 index 000000000000..8b1932143eab --- /dev/null +++ b/services/core/java/com/android/server/MountServiceIdler.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server; + +import android.app.maintenance.IdleService; +import android.util.Slog; + +public class MountServiceIdler extends IdleService { + private static final String TAG = "MountServiceIdler"; + + private Runnable mFinishCallback = new Runnable() { + @Override + public void run() { + Slog.i(TAG, "Got mount service completion callback"); + finishIdle(); + } + }; + + @Override + public boolean onIdleStart() { + // The mount service will run an fstrim operation asynchronously + // on a designated separate thread, so we provide it with a callback + // that lets us cleanly end our idle timeslice. It's safe to call + // finishIdle() from any thread. + MountService ms = MountService.sSelf; + if (ms != null) { + ms.runIdleMaintenance(mFinishCallback); + } + return ms != null; + } + + @Override + public void onIdleStop() { + } +} diff --git a/services/core/java/com/android/server/SystemServer.java b/services/core/java/com/android/server/SystemServer.java index b04fc1598340..1f6235fe0be8 100644 --- a/services/core/java/com/android/server/SystemServer.java +++ b/services/core/java/com/android/server/SystemServer.java @@ -163,7 +163,7 @@ public final class SystemServer { // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 - SystemProperties.set("persist.sys.dalvik.vm.lib", VMRuntime.getRuntime().vmLibrary()); + SystemProperties.set("persist.sys.dalvik.vm.lib.1", VMRuntime.getRuntime().vmLibrary()); // Enable the sampling profiler. if (SamplingProfilerIntegration.isEnabled()) { diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 5add5b01777c..0185a21645c1 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -3215,6 +3215,7 @@ public class SyncManager { totalLength += maxLength; formats[col] = String.format("%%-%ds", maxLength); } + formats[mCols - 1] = "%s"; printRow(out, formats, mTable.get(0)); totalLength += (mCols - 1) * 2; for (int i = 0; i < totalLength; ++i) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 0ad345610deb..c8eefe05cc4c 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -867,5 +867,14 @@ </intent-filter> </activity> + <activity + android:name="IsolationVolumeActivity" + android:label="Reordering/IsolationVolume"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.test.hwui.TEST" /> + </intent-filter> + </activity> + </application> </manifest> diff --git a/tests/HwAccelerationTest/res/layout/isolation.xml b/tests/HwAccelerationTest/res/layout/isolation.xml new file mode 100644 index 000000000000..802ac7fc7aca --- /dev/null +++ b/tests/HwAccelerationTest/res/layout/isolation.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#f55"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <LinearLayout + android:layout_width="0dp" + android:layout_height="150dp" + android:layout_weight="1" + android:isolatedZVolume="false" + android:orientation="vertical"> + <TextView style="@style/TopLeftReorderTextView"/> + <TextView style="@style/BottomLeftReorderTextView"/> + </LinearLayout> + <LinearLayout + android:layout_width="0dp" + android:layout_height="150dp" + android:layout_weight="1" + android:isolatedZVolume="false" + android:orientation="vertical"> + <TextView style="@style/TopRightReorderTextView"/> + <TextView style="@style/BottomRightReorderTextView"/> + </LinearLayout> + </LinearLayout> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <LinearLayout + android:layout_width="0dp" + android:layout_height="150dp" + android:layout_weight="1" + android:orientation="vertical"> + <TextView style="@style/TopLeftReorderTextView"/> + <TextView style="@style/BottomLeftReorderTextView"/> + </LinearLayout> + <LinearLayout + android:layout_width="0dp" + android:layout_height="150dp" + android:layout_weight="1" + android:orientation="vertical"> + <TextView style="@style/TopRightReorderTextView"/> + <TextView style="@style/BottomRightReorderTextView"/> + </LinearLayout> + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/tests/HwAccelerationTest/res/values/styles.xml b/tests/HwAccelerationTest/res/values/styles.xml new file mode 100644 index 000000000000..0ffd3d7d6ce4 --- /dev/null +++ b/tests/HwAccelerationTest/res/values/styles.xml @@ -0,0 +1,34 @@ +<resources> + <style name="ReorderTextView" parent="@android:style/TextAppearance.Medium"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">75dp</item> + <item name="android:gravity">center</item> + </style> + <style name="LeftReorderTextView" parent="@style/ReorderTextView"> + <item name="android:translationX">50dp</item> + </style> + <style name="RightReorderTextView" parent="@style/ReorderTextView"> + <item name="android:translationX">-50dp</item> + </style> + + <style name="TopLeftReorderTextView" parent="@style/LeftReorderTextView"> + <item name="android:background">#666</item> + <item name="android:text">100</item> + <item name="android:translationZ">100dp</item> + </style> + <style name="BottomLeftReorderTextView" parent="@style/LeftReorderTextView"> + <item name="android:background">#bbb</item> + <item name="android:text">300</item> + <item name="android:translationZ">300dp</item> + </style> + <style name="TopRightReorderTextView" parent="@style/RightReorderTextView"> + <item name="android:background">#888</item> + <item name="android:text">200</item> + <item name="android:translationZ">200dp</item> + </style> + <style name="BottomRightReorderTextView" parent="@style/RightReorderTextView"> + <item name="android:background">#ccc</item> + <item name="android:text">400</item> + <item name="android:translationZ">400dp</item> + </style> +</resources> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java new file mode 100644 index 000000000000..d5c93f2ef4f2 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java @@ -0,0 +1,12 @@ +package com.android.test.hwui; + +import android.os.Bundle; +import android.app.Activity; + +public class IsolationVolumeActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.isolation); + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java index 51a680330245..f27652dc96ca 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java @@ -48,7 +48,7 @@ public class ProjectionActivity extends Activity { private void setProject(boolean value) { DisplayList displayList = getDisplayList(); if (displayList != null) { - displayList.setProjectToContainedVolume(value); + displayList.setProjectBackwards(value); } // NOTE: we can't invalidate ProjectedView for the redraw because: // 1) the view won't preserve displayList properties that it doesn't know about diff --git a/tests/IdleServiceTest/Android.mk b/tests/IdleServiceTest/Android.mk new file mode 100644 index 000000000000..a7879c591840 --- /dev/null +++ b/tests/IdleServiceTest/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := IdleServiceTest +LOCAL_CERTIFICATE := platform + +LOCAL_PROGUARD_ENABLED := disabled + +include $(BUILD_PACKAGE) diff --git a/tests/IdleServiceTest/AndroidManifest.xml b/tests/IdleServiceTest/AndroidManifest.xml new file mode 100644 index 000000000000..16d2324dcd04 --- /dev/null +++ b/tests/IdleServiceTest/AndroidManifest.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.idleservicetest"> + + <application> + <service android:name="TestService" + android:exported="true" + android:enabled="true" + android:permission="android.permission.BIND_IDLE_SERVICE" > + <intent-filter> + <action android:name="android.service.idle.IdleService" /> + </intent-filter> + </service> + + <service android:name="CrashingTestService" + android:exported="true" + android:enabled="true" + android:permission="android.permission.BIND_IDLE_SERVICE" > + <intent-filter> + <action android:name="android.service.idle.IdleService" /> + </intent-filter> + </service> + + <service android:name="TimeoutTestService" + android:exported="true" + android:enabled="true" + android:permission="android.permission.BIND_IDLE_SERVICE" > + <intent-filter> + <action android:name="android.service.idle.IdleService" /> + </intent-filter> + </service> + + <!-- UnpermissionedTestService should never run because it does + not require the necessary permission in its <service> block --> + <service android:name="UnpermissionedTestService" + android:exported="true" + android:enabled="true" > + <intent-filter> + <action android:name="android.service.idle.IdleService" /> + </intent-filter> + </service> + + </application> +</manifest> diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java new file mode 100644 index 000000000000..022ebcf6e927 --- /dev/null +++ b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.idleservicetest; + +import android.app.maintenance.IdleService; +import android.os.Handler; +import android.util.Log; + +public class CrashingTestService extends IdleService { + static final String TAG = "CrashingTestService"; + + String mNull = null; + + @Override + public boolean onIdleStart() { + Log.i(TAG, "Idle maintenance: onIdleStart()"); + + Handler h = new Handler(); + Runnable r = new Runnable() { + @Override + public void run() { + Log.i(TAG, "Explicitly crashing"); + if (mNull.equals("")) { + Log.i(TAG, "won't happen"); + } + } + }; + Log.i(TAG, "Posting explicit crash in 15 seconds"); + h.postDelayed(r, 15 * 1000); + return true; + } + + @Override + public void onIdleStop() { + Log.i(TAG, "Idle maintenance: onIdleStop()"); + } + +} diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java new file mode 100644 index 000000000000..7e9805fb913c --- /dev/null +++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.idleservicetest; + +import android.app.maintenance.IdleService; +import android.os.Handler; +import android.util.Log; + +public class TestService extends IdleService { + static final String TAG = "TestService"; + + @Override + public boolean onIdleStart() { + Log.i(TAG, "Idle maintenance: onIdleStart()"); + + Handler h = new Handler(); + Runnable r = new Runnable() { + @Override + public void run() { + Log.i(TAG, "Explicitly finishing idle"); + finishIdle(); + } + }; + Log.i(TAG, "Posting explicit finish in 15 seconds"); + h.postDelayed(r, 15 * 1000); + return true; + } + + @Override + public void onIdleStop() { + Log.i(TAG, "Idle maintenance: onIdleStop()"); + } + +} diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java new file mode 100644 index 000000000000..b2ba21b542b2 --- /dev/null +++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.idleservicetest; + +import android.app.maintenance.IdleService; +import android.util.Log; + +public class TimeoutTestService extends IdleService { + private static final String TAG = "TimeoutTestService"; + + @Override + public boolean onIdleStart() { + Log.i(TAG, "onIdleStart() but anticipating time-slice timeout"); + return true; + } + + @Override + public void onIdleStop() { + Log.i(TAG, "onIdleStop() so we're done"); + } + +} diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java new file mode 100644 index 000000000000..b9fe32bf3923 --- /dev/null +++ b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.idleservicetest; + +import android.app.maintenance.IdleService; +import android.util.Log; + +// Should never be invoked because its manifest declaration does not +// require the necessary permission. +public class UnpermissionedTestService extends IdleService { + private static final String TAG = "UnpermissionedTestService"; + + @Override + public boolean onIdleStart() { + Log.e(TAG, "onIdleStart() for this service should never be called!"); + return false; + } + + @Override + public void onIdleStop() { + Log.e(TAG, "onIdleStop() for this service should never be called!"); + } + +} diff --git a/tests/LegacyRestoreTest/README b/tests/LegacyRestoreTest/README new file mode 100644 index 000000000000..cdd157e58295 --- /dev/null +++ b/tests/LegacyRestoreTest/README @@ -0,0 +1,18 @@ +The file "jbmr2-encrypted-settings-abcd.ab" in this directory is an encrypted +"adb backup" archive of the settings provider package. It was generated on a +Nexus 4 running Android 4.3 (API 18), and so predates the Android 4.4 changes +to the PBKDF2 implementation. The archive's encryption password, entered on-screen, +is "abcd" (with no quotation marks). + +'adb restore' decrypts and applies the restored archive successfully on a device +running Android 4.3, but fails to restore correctly on a device running Android 4.4, +reporting an invalid password in logcat. This is the situation reported in bug +<https://code.google.com/p/android/issues/detail?id=63880>. + +The file "kk-fixed-encrypted-settings-abcd.ab" is a similar encrypted "adb backup" +archive, using the same key, generated on a Nexus 4 running Android 4.4 with a fix +to this bug in place. This archive should be successfully restorable on any +version of Android which incorporates the fix. + +These archives can be used as an ongoing test to verify that historical encrypted +archives from various points in Android's history can be successfully restored. diff --git a/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab b/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab Binary files differnew file mode 100644 index 000000000000..192dcf5d4c52 --- /dev/null +++ b/tests/LegacyRestoreTest/jbmr2-encrypted-settings-abcd.ab diff --git a/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab Binary files differnew file mode 100644 index 000000000000..bf2b558d49b9 --- /dev/null +++ b/tests/LegacyRestoreTest/kk-fixed-encrypted-settings-abcd.ab diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index f11e9c20b464..e412c2732c20 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -2654,7 +2654,7 @@ status_t AaptAssets::addIncludedResources(const sp<AaptFile>& file) { const ResTable& res = getIncludedResources(); // XXX dirty! - return const_cast<ResTable&>(res).add(file->getData(), file->getSize(), NULL); + return const_cast<ResTable&>(res).add(file->getData(), file->getSize()); } const ResTable& AaptAssets::getIncludedResources() const diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 8f43661ceef8..a390e42b46e4 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1320,7 +1320,7 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) } // Read resources back in, - finalResTable.add(resFile->getData(), resFile->getSize(), NULL); + finalResTable.add(resFile->getData(), resFile->getSize()); #if 0 NOISY( diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk index 4e735686d4fd..ed497a5c0f34 100644 --- a/tools/layoutlib/Android.mk +++ b/tools/layoutlib/Android.mk @@ -31,6 +31,9 @@ built_framework_classes := $(call java-lib-files,framework-base) built_core_dep := $(call java-lib-deps,core) built_core_classes := $(call java-lib-files,core) +built_ext_dep := $(call java-lib-deps,ext) +built_ext_classes := $(call java-lib-files,ext) + built_layoutlib_create_jar := $(call intermediates-dir-for, \ JAVA_LIBRARIES,layoutlib_create,HOST)/javalib.jar @@ -47,6 +50,7 @@ include $(BUILD_SYSTEM)/base_rules.mk $(LOCAL_BUILT_MODULE): $(built_core_dep) \ $(built_framework_dep) \ + $(built_ext_dep) \ $(built_layoutlib_create_jar) $(hide) echo "host layoutlib_create: $@" $(hide) mkdir -p $(dir $@) @@ -55,7 +59,8 @@ $(LOCAL_BUILT_MODULE): $(built_core_dep) \ $(hide) java -jar $(built_layoutlib_create_jar) \ $@ \ $(built_core_classes) \ - $(built_framework_classes) + $(built_framework_classes) \ + $(built_ext_classes) $(hide) ls -l $(built_framework_classes) diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java index 7b444aadb303..ca710cd47022 100644 --- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java +++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java @@ -36,24 +36,74 @@ import com.android.tools.layoutlib.annotations.LayoutlibDelegate; /*package*/ class PropertyValuesHolder_Delegate { @LayoutlibDelegate - /*package*/ static int nGetIntMethod(Class<?> targetClass, String methodName) { + /*package*/ static long nGetIntMethod(Class<?> targetClass, String methodName) { // return 0 to force PropertyValuesHolder to use Java reflection. return 0; } @LayoutlibDelegate - /*package*/ static int nGetFloatMethod(Class<?> targetClass, String methodName) { + /*package*/ static long nGetFloatMethod(Class<?> targetClass, String methodName) { // return 0 to force PropertyValuesHolder to use Java reflection. return 0; } @LayoutlibDelegate - /*package*/ static void nCallIntMethod(Object target, int methodID, int arg) { + /*package*/ static int nGetMultipleIntMethod(Class<?> targetClass, String methodName, + int numParams) { + // TODO: return the right thing. + return 0; + } + + @LayoutlibDelegate + /*package*/ static int nGetMultipleFloatMethod(Class<?> targetClass, String methodName, + int numParams) { + // TODO: return the right thing. + return 0; + } + + @LayoutlibDelegate + /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1, + int arg2) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1, + int arg2, int arg3, int arg4) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallMultipleIntMethod(Object target, long methodID, + int[] args) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1, + float arg2) { + // do nothing + } + + @LayoutlibDelegate + /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1, + float arg2, float arg3, float arg4) { // do nothing } @LayoutlibDelegate - /*package*/ static void nCallFloatMethod(Object target, int methodID, float arg) { + /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID, + float[] args) { // do nothing } } diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java index 879445297ed4..c3e06d201ada 100644 --- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java +++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java @@ -51,6 +51,7 @@ public final class BridgeResources extends Resources { private BridgeContext mContext; private IProjectCallback mProjectCallback; private boolean[] mPlatformResourceFlag = new boolean[1]; + private TypedValue mTmpValue = new TypedValue(); /** * Simpler wrapper around FileInputStream. This is used when the input stream represent diff --git a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java index 04ce9d077b53..06673c1df338 100644 --- a/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/BitmapFactory_Delegate.java @@ -44,62 +44,13 @@ import java.util.Set; */ /*package*/ class BitmapFactory_Delegate { - // ------ Java delegates ------ - - @LayoutlibDelegate - /*package*/ static Bitmap finishDecode(Bitmap bm, Rect outPadding, Options opts) { - if (bm == null || opts == null) { - return bm; - } - - final int density = opts.inDensity; - if (density == 0) { - return bm; - } - - bm.setDensity(density); - final int targetDensity = opts.inTargetDensity; - if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) { - return bm; - } - - byte[] np = bm.getNinePatchChunk(); - final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np); - // DELEGATE CHANGE: never scale 9-patch - if (opts.inScaled && isNinePatch == false) { - float scale = targetDensity / (float)density; - // TODO: This is very inefficient and should be done in native by Skia - final Bitmap oldBitmap = bm; - bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f), - (int) (bm.getHeight() * scale + 0.5f), true); - oldBitmap.recycle(); - - if (isNinePatch) { - np = nativeScaleNinePatch(np, scale, outPadding); - bm.setNinePatchChunk(np); - } - bm.setDensity(targetDensity); - } - - return bm; - } - - // ------ Native Delegates ------ @LayoutlibDelegate /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage, Rect padding, Options opts) { - return nativeDecodeStream(is, storage, padding, opts, false, 1.f); - } - - @LayoutlibDelegate - /*package*/ static Bitmap nativeDecodeStream(InputStream is, byte[] storage, - Rect padding, Options opts, boolean applyScale, float scale) { Bitmap bm = null; - //TODO support rescaling - Density density = Density.MEDIUM; Set<BitmapCreateFlags> bitmapCreateFlags = EnumSet.of(BitmapCreateFlags.MUTABLE); if (opts != null) { @@ -151,14 +102,7 @@ import java.util.Set; } @LayoutlibDelegate - /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts) { - opts.inBitmap = null; - return null; - } - - @LayoutlibDelegate - /*package*/ static Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts, - boolean applyScale, float scale) { + /*package*/ static Bitmap nativeDecodeAsset(long asset, Rect padding, Options opts) { opts.inBitmap = null; return null; } @@ -171,13 +115,6 @@ import java.util.Set; } @LayoutlibDelegate - /*package*/ static byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad) { - // don't scale for now. This should not be called anyway since we re-implement - // BitmapFactory.finishDecode(); - return chunk; - } - - @LayoutlibDelegate /*package*/ static boolean nativeIsSeekable(FileDescriptor fd) { return true; } diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index 0bdc28d6c299..701613611e34 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -101,13 +101,14 @@ public final class Bitmap_Delegate { throws IOException { return createBitmap(input, getPremultipliedBitmapCreateFlags(isMutable), density); } + /** * Creates and returns a {@link Bitmap} initialized with the given file content. * * @param input the file from which to read the bitmap content * @param density the density associated with the bitmap * - * @see Bitmap#isPremultiplied() + * @see Bitmap#isPremultiplied() * @see Bitmap#isMutable() * @see Bitmap#getDensity() */ @@ -115,7 +116,7 @@ public final class Bitmap_Delegate { Density density) throws IOException { // create a delegate with the content of the file. Bitmap_Delegate delegate = new Bitmap_Delegate(ImageIO.read(input), Config.ARGB_8888); - + return createBitmap(delegate, createFlags, density.getDpiValue()); } @@ -141,7 +142,7 @@ public final class Bitmap_Delegate { * @param createFlags * @param density the density associated with the bitmap * - * @see Bitmap#isPremultiplied() + * @see Bitmap#isPremultiplied() * @see Bitmap#isMutable() * @see Bitmap#getDensity() */ @@ -175,6 +176,7 @@ public final class Bitmap_Delegate { * @param createFlags * @param density the density associated with the bitmap * + * @see Bitmap#isPremultiplied() * @see Bitmap#isMutable() * @see Bitmap#getDensity() */ @@ -268,7 +270,7 @@ public final class Bitmap_Delegate { Bitmap_Delegate delegate = new Bitmap_Delegate(image, Config.nativeToConfig(nativeConfig)); return createBitmap(delegate, getPremultipliedBitmapCreateFlags(isMutable), - Bitmap.getDefaultDensity()); + Bitmap.getDefaultDensity()); } @LayoutlibDelegate @@ -306,8 +308,16 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeRecycle(long nativeBitmap) { + /*package*/ static boolean nativeRecycle(long nativeBitmap) { sManager.removeJavaReferenceFor(nativeBitmap); + return true; + } + + @LayoutlibDelegate + /*package*/ static void nativeReconfigure(long nativeBitmap, int width, int height, + int config, int allocSize) { + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, + "Bitmap.reconfigure() is not supported", null /*data*/); } @LayoutlibDelegate @@ -339,28 +349,6 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static int nativeWidth(long nativeBitmap) { - // get the delegate from the native int. - Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); - if (delegate == null) { - return 0; - } - - return delegate.mImage.getWidth(); - } - - @LayoutlibDelegate - /*package*/ static int nativeHeight(long nativeBitmap) { - // get the delegate from the native int. - Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); - if (delegate == null) { - return 0; - } - - return delegate.mImage.getHeight(); - } - - @LayoutlibDelegate /*package*/ static int nativeRowBytes(long nativeBitmap) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); @@ -405,19 +393,21 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y) { + /*package*/ static int nativeGetPixel(long nativeBitmap, int x, int y, + boolean isPremultiplied) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { return 0; } + // TODO: Support isPremultiplied. return delegate.mImage.getRGB(x, y); } @LayoutlibDelegate /*package*/ static void nativeGetPixels(long nativeBitmap, int[] pixels, int offset, - int stride, int x, int y, int width, int height) { + int stride, int x, int y, int width, int height, boolean isPremultiplied) { Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { return; @@ -428,7 +418,8 @@ public final class Bitmap_Delegate { @LayoutlibDelegate - /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color) { + /*package*/ static void nativeSetPixel(long nativeBitmap, int x, int y, int color, + boolean isPremultiplied) { Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { return; @@ -439,7 +430,7 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static void nativeSetPixels(long nativeBitmap, int[] colors, int offset, - int stride, int x, int y, int width, int height) { + int stride, int x, int y, int width, int height, boolean isPremultiplied) { Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { return; @@ -527,7 +518,8 @@ public final class Bitmap_Delegate { } @LayoutlibDelegate - /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha) { + /*package*/ static void nativeSetAlphaAndPremultiplied(long nativeBitmap, boolean hasAlpha, + boolean isPremul) { // get the delegate from the native int. Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap); if (delegate == null) { @@ -615,12 +607,13 @@ public final class Bitmap_Delegate { } private static Set<BitmapCreateFlags> getPremultipliedBitmapCreateFlags(boolean isMutable) { - Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED); + Set<BitmapCreateFlags> createFlags = EnumSet.of(BitmapCreateFlags.PREMULTIPLIED); if (isMutable) { createFlags.add(BitmapCreateFlags.MUTABLE); } return createFlags; } + /** * Creates and returns a copy of a given BufferedImage. * <p/> diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java index ba771dd2dcb9..602717b62f1b 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java @@ -786,7 +786,7 @@ public final class Canvas_Delegate { } @LayoutlibDelegate - /*package*/ static void native_drawPath(long nativeCanvas, int path, long paint) { + /*package*/ static void native_drawPath(long nativeCanvas, long path, long paint) { final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path); if (pathDelegate == null) { return; @@ -975,8 +975,10 @@ public final class Canvas_Delegate { @LayoutlibDelegate /*package*/ static void native_drawText(long nativeCanvas, final char[] text, final int index, final int count, - final float startX, final float startY, final int flags, long paint) { + final float startX, final float startY, final int flags, long paint, + long typeface) { + // TODO: use typeface. draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/, new GcSnapshot.Drawable() { @Override @@ -1005,30 +1007,31 @@ public final class Canvas_Delegate { @LayoutlibDelegate /*package*/ static void native_drawText(long nativeCanvas, String text, - int start, int end, float x, float y, final int flags, long paint) { + int start, int end, float x, float y, final int flags, long paint, + long typeface) { int count = end - start; char[] buffer = TemporaryBuffer.obtain(count); TextUtils.getChars(text, start, end, buffer, 0); - native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint); + native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface); } @LayoutlibDelegate /*package*/ static void native_drawTextRun(long nativeCanvas, String text, int start, int end, int contextStart, int contextEnd, - float x, float y, int flags, long paint) { + float x, float y, int flags, long paint, long typeface) { int count = end - start; char[] buffer = TemporaryBuffer.obtain(count); TextUtils.getChars(text, start, end, buffer, 0); - native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint); + native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface); } @LayoutlibDelegate /*package*/ static void native_drawTextRun(long nativeCanvas, char[] text, int start, int count, int contextStart, int contextCount, - float x, float y, int flags, long paint) { - native_drawText(nativeCanvas, text, start, count, x, y, flags, paint); + float x, float y, int flags, long paint, long typeface) { + native_drawText(nativeCanvas, text, start, count, x, y, flags, paint, typeface); } @LayoutlibDelegate diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java index d6b3da19a6d8..38174f184756 100644 --- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java @@ -56,7 +56,7 @@ public abstract class ColorFilter_Delegate { // ---- native methods ---- @LayoutlibDelegate - /*package*/ static void finalizer(long native_instance, long nativeColorFilter) { + /*package*/ static void destroyFilter(long native_instance, long nativeColorFilter) { sManager.removeJavaReferenceFor(native_instance); } diff --git a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java index 1d66586cc7cf..ebfe9bc3ab2c 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Matrix_Delegate.java @@ -654,7 +654,7 @@ public final class Matrix_Delegate { } @LayoutlibDelegate - /*package*/ static boolean native_invert(long native_object, int inverse) { + /*package*/ static boolean native_invert(long native_object, long inverse) { Matrix_Delegate d = sManager.getDelegate(native_object); if (d == null) { return false; diff --git a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java index a5c52e551365..38745ce65bf2 100644 --- a/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/NinePatch_Delegate.java @@ -167,6 +167,7 @@ public final class NinePatch_Delegate { return sManager.addNewDelegate(newDelegate); } + @LayoutlibDelegate /*package*/ static void nativeFinalize(long chunk) { sManager.removeJavaReferenceFor(chunk); } diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index f3b56d91e577..49f314c40308 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -401,17 +401,17 @@ public final class Path_Delegate { } @LayoutlibDelegate - /*package*/ static void native_addPath(long nPath, int src, float dx, float dy) { + /*package*/ static void native_addPath(long nPath, long src, float dx, float dy) { addPath(nPath, src, AffineTransform.getTranslateInstance(dx, dy)); } @LayoutlibDelegate - /*package*/ static void native_addPath(long nPath, int src) { + /*package*/ static void native_addPath(long nPath, long src) { addPath(nPath, src, null /*transform*/); } @LayoutlibDelegate - /*package*/ static void native_addPath(long nPath, int src, long matrix) { + /*package*/ static void native_addPath(long nPath, long src, long matrix) { Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix); if (matrixDelegate == null) { return; @@ -474,10 +474,35 @@ public final class Path_Delegate { } @LayoutlibDelegate + /*package*/ static boolean native_op(long nPath1, long nPath2, int op, long result) { + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.op() not supported", null); + return false; + } + + @LayoutlibDelegate /*package*/ static void finalizer(long nPath) { sManager.removeJavaReferenceFor(nPath); } + @LayoutlibDelegate + /*package*/ static float[] native_approximate(long nPath, float error) { + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null); + return new float[0]; + } + + @LayoutlibDelegate + /*package*/ static long native_trim(long nPath, long nTargetPath, long nPathMeasure, + float trimStart, float trimEnd, float trimOffset) { + // TODO: add trim. + Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.trim() not supported", null); + return nPathMeasure; + + } + + @LayoutlibDelegate + private static void native_destroyMeasure(long nPathMeasure) { + // Do nothing. + } // ---- Private helper methods ---- diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java index 23d08e343bdb..60f5331aefdb 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderAction.java @@ -273,7 +273,6 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso mContext.getRenderResources().setLogger(null); } - mContext = null; } public static BridgeContext getCurrentContext() { diff --git a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java index a773d93602d9..d94c205df5f5 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/DateIntervalFormat_Delegate.java @@ -21,6 +21,7 @@ import java.text.FieldPosition; import com.android.ide.common.rendering.api.LayoutLog; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.impl.DelegateManager; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; import com.ibm.icu.text.DateIntervalFormat; import com.ibm.icu.util.DateInterval; import com.ibm.icu.util.TimeZone; @@ -38,6 +39,7 @@ public class DateIntervalFormat_Delegate { // ---- native methods ---- + @LayoutlibDelegate /*package*/static String formatDateInterval(long address, long fromDate, long toDate) { DateIntervalFormat_Delegate delegate = sManager.getDelegate((int)address); if (delegate == null) { @@ -52,6 +54,7 @@ public class DateIntervalFormat_Delegate { return sb.toString(); } + @LayoutlibDelegate /*package*/ static long createDateIntervalFormat(String skeleton, String localeName, String tzName) { TimeZone prevDefaultTz = TimeZone.getDefault(); @@ -63,6 +66,7 @@ public class DateIntervalFormat_Delegate { return sManager.addNewDelegate(newDelegate); } + @LayoutlibDelegate /*package*/ static void destroyDateIntervalFormat(long address) { sManager.removeJavaReferenceFor((int)address); } diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java index 06ae804aa7c6..d40352f4b582 100644 --- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java +++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java @@ -46,7 +46,7 @@ public class ICU_Delegate { // --- Native methods accessing ICU's database. @LayoutlibDelegate - /*package*/ static String getBestDateTimePattern(String skeleton, String localeName) { + /*package*/ static String getBestDateTimePatternNative(String skeleton, String localeName) { return DateTimePatternGenerator.getInstance(new ULocale(localeName)) .getBestPattern(skeleton); } @@ -137,6 +137,11 @@ public class ICU_Delegate { } @LayoutlibDelegate + /*package*/ static String getDisplayScriptNative(String variantCode, String locale) { + return ""; + } + + @LayoutlibDelegate /*package*/ static String getISO3CountryNative(String locale) { return ""; } @@ -166,8 +171,19 @@ public class ICU_Delegate { return Locale.getISOCountries(); } + + @LayoutlibDelegate + /*package*/ static String localeForLanguageTag(String languageTag, boolean strict) { + return ""; + } + + @LayoutlibDelegate + /*package*/ static String languageTagForLocale(String locale) { + return ""; + } + @LayoutlibDelegate - /*package*/ static boolean initLocaleDataImpl(String locale, LocaleData result) { + /*package*/ static boolean initLocaleDataNative(String locale, LocaleData result) { // Used by Calendar. result.firstDayOfWeek = Integer.valueOf(1); diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java index ba23048aee7b..ee501d234d01 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java @@ -113,6 +113,7 @@ public class Main { "android.pim.*", // for datepicker "android.os.*", // for android.os.Handler "android.database.ContentObserver", // for Digital clock + "com.android.i18n.phonenumbers.*", // for TextView with autolink attribute }, excludeClasses); aa.analyze(); |