diff options
49 files changed, 1483 insertions, 494 deletions
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index a7ced44..125bea6 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -52,7 +52,6 @@ #include "BootAnimation.h" -#define USER_BOOTANIMATION_FILE "/data/local/bootanimation.zip" #define SYSTEM_BOOTANIMATION_FILE "/system/media/bootanimation.zip" #define SYSTEM_ENCRYPTED_BOOTANIMATION_FILE "/system/media/bootanimation-encrypted.zip" #define EXIT_PROP_NAME "service.bootanim.exit" @@ -285,9 +284,6 @@ status_t BootAnimation::readyToRun() { (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0) && ((zipFile = ZipFileRO::open(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE)) != NULL)) || - ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) && - ((zipFile = ZipFileRO::open(USER_BOOTANIMATION_FILE)) != NULL)) || - ((access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) && ((zipFile = ZipFileRO::open(SYSTEM_BOOTANIMATION_FILE)) != NULL))) { mZip = zipFile; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d7a67f4..40899c0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -97,7 +97,6 @@ import com.android.internal.os.BinderInternal; import com.android.internal.os.RuntimeInit; import com.android.internal.os.SamplingProfilerIntegration; import com.android.internal.util.FastPrintWriter; -import com.android.internal.util.Objects; import com.android.org.conscrypt.OpenSSLSocketImpl; import com.google.android.collect.Lists; @@ -113,6 +112,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.TimeZone; import java.util.regex.Pattern; @@ -226,7 +226,7 @@ public final class ActivityThread { public boolean equals(Object o) { if (o instanceof ProviderKey) { final ProviderKey other = (ProviderKey) o; - return Objects.equal(authority, other.authority) && userId == other.userId; + return Objects.equals(authority, other.authority) && userId == other.userId; } return false; } diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java index 3c67bf9..36dd2fdfb 100644 --- a/core/java/android/net/NetworkIdentity.java +++ b/core/java/android/net/NetworkIdentity.java @@ -26,7 +26,7 @@ import android.net.wifi.WifiManager; import android.os.Build; import android.telephony.TelephonyManager; -import com.android.internal.util.Objects; +import java.util.Objects; /** * Network definition that includes strong identity. Analogous to combining @@ -60,7 +60,7 @@ public class NetworkIdentity { @Override public int hashCode() { - return Objects.hashCode(mType, mSubType, mSubscriberId, mNetworkId, mRoaming); + return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming); } @Override @@ -68,8 +68,8 @@ public class NetworkIdentity { if (obj instanceof NetworkIdentity) { final NetworkIdentity ident = (NetworkIdentity) obj; return mType == ident.mType && mSubType == ident.mSubType && mRoaming == ident.mRoaming - && Objects.equal(mSubscriberId, ident.mSubscriberId) - && Objects.equal(mNetworkId, ident.mNetworkId); + && Objects.equals(mSubscriberId, ident.mSubscriberId) + && Objects.equals(mNetworkId, ident.mNetworkId); } return false; } diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 441db7a..10c686b 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -21,7 +21,7 @@ import static com.android.internal.util.Preconditions.checkNotNull; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.util.Objects; +import java.util.Objects; /** * Policy for networks matching a {@link NetworkTemplate}, including usage cycle @@ -146,7 +146,7 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { @Override public int hashCode() { - return Objects.hashCode(template, cycleDay, cycleTimezone, warningBytes, limitBytes, + return Objects.hash(template, cycleDay, cycleTimezone, warningBytes, limitBytes, lastWarningSnooze, lastLimitSnooze, metered, inferred); } @@ -159,8 +159,8 @@ public class NetworkPolicy implements Parcelable, Comparable<NetworkPolicy> { && lastWarningSnooze == other.lastWarningSnooze && lastLimitSnooze == other.lastLimitSnooze && metered == other.metered && inferred == other.inferred - && Objects.equal(cycleTimezone, other.cycleTimezone) - && Objects.equal(template, other.template); + && Objects.equals(cycleTimezone, other.cycleTimezone) + && Objects.equals(template, other.template); } return false; } diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java index 9cb904d..a7aae2a 100644 --- a/core/java/android/net/NetworkStats.java +++ b/core/java/android/net/NetworkStats.java @@ -23,12 +23,12 @@ import android.util.SparseBooleanArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.Objects; import java.io.CharArrayWriter; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashSet; +import java.util.Objects; /** * Collection of active network statistics. Can contain summary details across @@ -337,7 +337,7 @@ public class NetworkStats implements Parcelable { public int findIndex(String iface, int uid, int set, int tag) { for (int i = 0; i < size; i++) { if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] - && Objects.equal(iface, this.iface[i])) { + && Objects.equals(iface, this.iface[i])) { return i; } } @@ -362,7 +362,7 @@ public class NetworkStats implements Parcelable { } if (uid == this.uid[i] && set == this.set[i] && tag == this.tag[i] - && Objects.equal(iface, this.iface[i])) { + && Objects.equals(iface, this.iface[i])) { return i; } } diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java index c189ba4..27197cc 100644 --- a/core/java/android/net/NetworkTemplate.java +++ b/core/java/android/net/NetworkTemplate.java @@ -34,8 +34,9 @@ import android.content.res.Resources; import android.os.Parcel; import android.os.Parcelable; +import java.util.Objects; + import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.Objects; /** * Template definition used to generically match {@link NetworkIdentity}, @@ -176,7 +177,7 @@ public class NetworkTemplate implements Parcelable { @Override public int hashCode() { - return Objects.hashCode(mMatchRule, mSubscriberId, mNetworkId); + return Objects.hash(mMatchRule, mSubscriberId, mNetworkId); } @Override @@ -184,8 +185,8 @@ public class NetworkTemplate implements Parcelable { if (obj instanceof NetworkTemplate) { final NetworkTemplate other = (NetworkTemplate) obj; return mMatchRule == other.mMatchRule - && Objects.equal(mSubscriberId, other.mSubscriberId) - && Objects.equal(mNetworkId, other.mNetworkId); + && Objects.equals(mSubscriberId, other.mSubscriberId) + && Objects.equals(mNetworkId, other.mNetworkId); } return false; } @@ -235,7 +236,7 @@ public class NetworkTemplate implements Parcelable { return true; } else { return ((sForceAllNetworkTypes || contains(DATA_USAGE_NETWORK_TYPES, ident.mType)) - && Objects.equal(mSubscriberId, ident.mSubscriberId)); + && Objects.equals(mSubscriberId, ident.mSubscriberId)); } } @@ -280,7 +281,7 @@ public class NetworkTemplate implements Parcelable { private boolean matchesWifi(NetworkIdentity ident) { switch (ident.mType) { case TYPE_WIFI: - return Objects.equal( + return Objects.equals( removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId)); default: return false; diff --git a/core/java/android/view/DisplayAdjustments.java b/core/java/android/view/DisplayAdjustments.java index 041d9e0..35fb504 100644 --- a/core/java/android/view/DisplayAdjustments.java +++ b/core/java/android/view/DisplayAdjustments.java @@ -19,7 +19,7 @@ package android.view; import android.content.res.CompatibilityInfo; import android.os.IBinder; -import com.android.internal.util.Objects; +import java.util.Objects; /** @hide */ public class DisplayAdjustments { @@ -91,7 +91,7 @@ public class DisplayAdjustments { return false; } DisplayAdjustments daj = (DisplayAdjustments)o; - return Objects.equal(daj.mCompatInfo, mCompatInfo) && - Objects.equal(daj.mActivityToken, mActivityToken); + return Objects.equals(daj.mCompatInfo, mCompatInfo) && + Objects.equals(daj.mActivityToken, mActivityToken); } } diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java index 2829215..e53ce8b 100644 --- a/core/java/android/view/DisplayList.java +++ b/core/java/android/view/DisplayList.java @@ -438,6 +438,21 @@ public abstract class DisplayList { public abstract float getTranslationY(); /** + * Sets the translation value for the display list on the Z axis + * + * @see View#setTranslationZ(float) + * @see #getTranslationZ() + */ + public abstract void setTranslationZ(float translationZ); + + /** + * Returns the translation value for this display list on the Z axis. + * + * @see #setTranslationZ(float) + */ + public abstract float getTranslationZ(); + + /** * Sets the rotation value for the display list around the Z axis * * @param rotation The rotation value of the display list, in degrees @@ -536,7 +551,8 @@ public abstract class DisplayList { * * @hide */ - public abstract void setTransformationInfo(float alpha, float translationX, float translationY, + public abstract void setTransformationInfo(float alpha, + float translationX, float translationY, float translationZ, float rotation, float rotationX, float rotationY, float scaleX, float scaleY); /** diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java index 574b7bb..7944e66 100644 --- a/core/java/android/view/GLES20DisplayList.java +++ b/core/java/android/view/GLES20DisplayList.java @@ -231,6 +231,21 @@ class GLES20DisplayList extends DisplayList { } @Override + public void setTranslationZ(float translationZ) { + if (hasNativeDisplayList()) { + nSetTranslationZ(mFinalizer.mNativeDisplayList, translationZ); + } + } + + @Override + public float getTranslationZ() { + if (hasNativeDisplayList()) { + return nGetTranslationZ(mFinalizer.mNativeDisplayList); + } + return 0.0f; + } + + @Override public void setRotation(float rotation) { if (hasNativeDisplayList()) { nSetRotation(mFinalizer.mNativeDisplayList, rotation); @@ -306,10 +321,12 @@ class GLES20DisplayList extends DisplayList { } @Override - public void setTransformationInfo(float alpha, float translationX, float translationY, + public void setTransformationInfo(float alpha, + float translationX, float translationY, float translationZ, float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { if (hasNativeDisplayList()) { - nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, translationX, translationY, + nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, + translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY); } } @@ -466,14 +483,15 @@ class GLES20DisplayList extends DisplayList { boolean hasOverlappingRendering); private static native void nSetTranslationX(int displayList, float translationX); private static native void nSetTranslationY(int displayList, float translationY); + private static native void nSetTranslationZ(int displayList, float translationZ); private static native void nSetRotation(int displayList, float rotation); private static native void nSetRotationX(int displayList, float rotationX); private static native void nSetRotationY(int displayList, float rotationY); private static native void nSetScaleX(int displayList, float scaleX); private static native void nSetScaleY(int displayList, float scaleY); private static native void nSetTransformationInfo(int displayList, float alpha, - float translationX, float translationY, float rotation, float rotationX, - float rotationY, float scaleX, float scaleY); + float translationX, float translationY, float translationZ, + float rotation, float rotationX, float rotationY, float scaleX, float scaleY); private static native void nSetStaticMatrix(int displayList, int nativeMatrix); private static native void nSetAnimationMatrix(int displayList, int animationMatrix); @@ -489,6 +507,7 @@ class GLES20DisplayList extends DisplayList { private static native float nGetScaleY(int displayList); private static native float nGetTranslationX(int displayList); private static native float nGetTranslationY(int displayList); + private static native float nGetTranslationZ(int displayList); private static native float nGetRotation(int displayList); private static native float nGetRotationX(int displayList); private static native float nGetRotationY(int displayList); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 0439b50..a0e6924 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2981,6 +2981,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, @ViewDebug.ExportedProperty float mTranslationY = 0f; + @ViewDebug.ExportedProperty + float mTranslationZ = 0f; + /** * The amount of scale in the x direction around the pivot point. A * value of 1 means no scaling is applied. @@ -10508,6 +10511,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** + * @hide + */ + @ViewDebug.ExportedProperty(category = "drawing") + public float getTranslationZ() { + return mTransformationInfo != null ? mTransformationInfo.mTranslationZ : 0; + } + + /** + * @hide + */ + public void setTranslationZ(float translationZ) { + ensureTransformationInfo(); + final TransformationInfo info = mTransformationInfo; + if (info.mTranslationZ != translationZ) { + invalidateViewProperty(true, false); + info.mTranslationZ = translationZ; + info.mMatrixDirty = true; + invalidateViewProperty(false, true); + if (mDisplayList != null) { + mDisplayList.setTranslationZ(translationZ); + } + if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) { + // View was rejected last time it was drawn by its parent; this may have changed + invalidateParentIfNeeded(); + } + } + } + + /** * Hit rectangle in parent's coordinates * * @param outRect The hit rectangle of the view. @@ -14173,6 +14205,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } displayList.setTransformationInfo(alpha, mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY, + mTransformationInfo.mTranslationZ, mTransformationInfo.mRotation, mTransformationInfo.mRotationX, mTransformationInfo.mRotationY, mTransformationInfo.mScaleX, mTransformationInfo.mScaleY); diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 67a94be..391b345 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -144,9 +144,10 @@ public class ViewPropertyAnimator { private static final int X = 0x0080; private static final int Y = 0x0100; private static final int ALPHA = 0x0200; + private static final int TRANSLATION_Z = 0x0400; - private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y | - ROTATION | ROTATION_X | ROTATION_Y | X | Y; + private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | TRANSLATION_Z | + SCALE_X | SCALE_Y | ROTATION | ROTATION_X | ROTATION_Y | X | Y; /** * The mechanism by which the user can request several properties that are then animated @@ -573,6 +574,22 @@ public class ViewPropertyAnimator { } /** + * @hide + */ + public ViewPropertyAnimator translationZ(float value) { + animateProperty(TRANSLATION_Z, value); + return this; + } + + /** + * @hide + */ + public ViewPropertyAnimator translationZBy(float value) { + animatePropertyBy(TRANSLATION_Z, value); + return this; + } + + /** * This method will cause the View's <code>translationY</code> property to be animated to the * specified value. Animations already running on the property will be canceled. * @@ -909,6 +926,10 @@ public class ViewPropertyAnimator { info.mTranslationY = value; if (displayList != null) displayList.setTranslationY(value); break; + case TRANSLATION_Z: + info.mTranslationZ = value; + if (displayList != null) displayList.setTranslationZ(value); + break; case ROTATION: info.mRotation = value; if (displayList != null) displayList.setRotation(value); @@ -957,6 +978,8 @@ public class ViewPropertyAnimator { return info.mTranslationX; case TRANSLATION_Y: return info.mTranslationY; + case TRANSLATION_Z: + return info.mTranslationZ; case ROTATION: return info.mRotation; case ROTATION_X: diff --git a/core/java/com/android/internal/util/Objects.java b/core/java/com/android/internal/util/Objects.java deleted file mode 100644 index 2664182..0000000 --- a/core/java/com/android/internal/util/Objects.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2007 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.internal.util; - -import java.util.Arrays; - -/** - * Object utility methods. - */ -public class Objects { - - /** - * Determines whether two possibly-null objects are equal. Returns: - * - * <ul> - * <li>{@code true} if {@code a} and {@code b} are both null. - * <li>{@code true} if {@code a} and {@code b} are both non-null and they are - * equal according to {@link Object#equals(Object)}. - * <li>{@code false} in all other situations. - * </ul> - * - * <p>This assumes that any non-null objects passed to this function conform - * to the {@code equals()} contract. - */ - public static boolean equal(Object a, Object b) { - return a == b || (a != null && a.equals(b)); - } - - /** - * Generates a hash code for multiple values. The hash code is generated by - * calling {@link Arrays#hashCode(Object[])}. - * - * <p>This is useful for implementing {@link Object#hashCode()}. For example, - * in an object that has three properties, {@code x}, {@code y}, and - * {@code z}, one could write: - * <pre> - * public int hashCode() { - * return Objects.hashCode(getX(), getY(), getZ()); - * }</pre> - * - * <b>Warning</b>: When a single object is supplied, the returned hash code - * does not equal the hash code of that object. - */ - public static int hashCode(Object... objects) { - return Arrays.hashCode(objects); - } - -} diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp index d63a410..d6cddb2 100644 --- a/core/jni/android_view_GLES20DisplayList.cpp +++ b/core/jni/android_view_GLES20DisplayList.cpp @@ -114,6 +114,11 @@ static void android_view_GLES20DisplayList_setTranslationY(JNIEnv* env, displayList->setTranslationY(ty); } +static void android_view_GLES20DisplayList_setTranslationZ(JNIEnv* env, + jobject clazz, DisplayList* displayList, float tz) { + displayList->setTranslationZ(tz); +} + static void android_view_GLES20DisplayList_setRotation(JNIEnv* env, jobject clazz, DisplayList* displayList, float rotation) { displayList->setRotation(rotation); @@ -141,11 +146,12 @@ static void android_view_GLES20DisplayList_setScaleY(JNIEnv* env, static void android_view_GLES20DisplayList_setTransformationInfo(JNIEnv* env, jobject clazz, DisplayList* displayList, float alpha, - float translationX, float translationY, float rotation, float rotationX, float rotationY, - float scaleX, float scaleY) { + float translationX, float translationY, float translationZ, + float rotation, float rotationX, float rotationY, float scaleX, float scaleY) { displayList->setAlpha(alpha); displayList->setTranslationX(translationX); displayList->setTranslationY(translationY); + displayList->setTranslationZ(translationZ); displayList->setRotation(rotation); displayList->setRotationX(rotationX); displayList->setRotationY(rotationY); @@ -320,12 +326,13 @@ static JNINativeMethod gMethods[] = { (void*) android_view_GLES20DisplayList_setHasOverlappingRendering }, { "nSetTranslationX", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationX }, { "nSetTranslationY", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationY }, + { "nSetTranslationZ", "(IF)V", (void*) android_view_GLES20DisplayList_setTranslationZ }, { "nSetRotation", "(IF)V", (void*) android_view_GLES20DisplayList_setRotation }, { "nSetRotationX", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationX }, { "nSetRotationY", "(IF)V", (void*) android_view_GLES20DisplayList_setRotationY }, { "nSetScaleX", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleX }, { "nSetScaleY", "(IF)V", (void*) android_view_GLES20DisplayList_setScaleY }, - { "nSetTransformationInfo","(IFFFFFFFF)V", + { "nSetTransformationInfo","(IFFFFFFFFF)V", (void*) android_view_GLES20DisplayList_setTransformationInfo }, { "nSetPivotX", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotX }, { "nSetPivotY", "(IF)V", (void*) android_view_GLES20DisplayList_setPivotY }, diff --git a/docs/html/training/system-ui/navigation.jd b/docs/html/training/system-ui/navigation.jd index 3907bb2..1c73c70 100644 --- a/docs/html/training/system-ui/navigation.jd +++ b/docs/html/training/system-ui/navigation.jd @@ -63,6 +63,9 @@ user experience. </p> the navigation bar and the status bar:</p> <pre>View decorView = getWindow().getDecorView(); // Hide both the navigation bar and the status bar. +// SYSTEM_UI_FLAG_FULLSCREEN is only available on Android 4.1 and higher, but as +// a general rule, you should design your app to hide the status bar whenever you +// hide the navigation bar. int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; decorView.setSystemUiVisibility(uiOptions);</pre> diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp new file mode 100644 index 0000000..923571e --- /dev/null +++ b/libs/hwui/AmbientShadow.cpp @@ -0,0 +1,306 @@ +/* + * 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. + */ + +#define LOG_TAG "OpenGLRenderer" + +#include <math.h> +#include <utils/Log.h> + +#include "AmbientShadow.h" +#include "Vertex.h" + +namespace android { +namespace uirenderer { + +/** + * Calculate the shadows as a triangle strips while alpha value as the + * shadow values. + * + * @param vertices The shadow caster's polygon, which is represented in a Vector3 + * array. + * @param vertexCount The length of caster's polygon in terms of number of + * vertices. + * @param rays The number of rays shooting out from the centroid. + * @param layers The number of rings outside the polygon. + * @param strength The darkness of the shadow, the higher, the darker. + * @param heightFactor The factor showing the higher the object, the lighter the + * shadow. + * @param geomFactor The factor scaling the geometry expansion along the normal. + * + * @param shadowVertexBuffer Return an floating point array of (x, y, a) + * triangle strips mode. + */ +void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount, + int rays, int layers, float strength, float heightFactor, float geomFactor, + VertexBuffer& shadowVertexBuffer) { + + // Validate the inputs. + if (strength <= 0 || heightFactor <= 0 || layers <= 0 || rays <= 0 + || geomFactor <= 0) { +#if DEBUG_SHADOW + ALOGE("Invalid input for createAmbientShadow(), early return!"); +#endif + return; + } + int rings = layers + 1; + int size = rays * rings; + Vector2 centroid; + calculatePolygonCentroid(vertices, vertexCount, centroid); + + Vector2 dir[rays]; + float rayDist[rays]; + float rayHeight[rays]; + calculateRayDirections(rays, dir); + + // Calculate the length and height of the points along the edge. + // + // The math here is: + // Intersect each ray (starting from the centroid) with the polygon. + for (int i = 0; i < rays; i++) { + int edgeIndex; + float edgeFraction; + float rayDistance; + calculateIntersection(vertices, vertexCount, centroid, dir[i], edgeIndex, + edgeFraction, rayDistance); + rayDist[i] = rayDistance; + if (edgeIndex < 0 || edgeIndex >= vertexCount) { +#if DEBUG_SHADOW + ALOGE("Invalid edgeIndex!"); +#endif + edgeIndex = 0; + } + float h1 = vertices[edgeIndex].z; + float h2 = vertices[((edgeIndex + 1) % vertexCount)].z; + rayHeight[i] = h1 + edgeFraction * (h2 - h1); + } + + // The output buffer length basically is roughly rays * layers, but since we + // need triangle strips, so we need to duplicate vertices to accomplish that. + const int shadowVertexCount = (2 + rays + ((layers) * 2 * (rays + 1))); + AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(shadowVertexCount); + + // Calculate the vertex of the shadows. + // + // The math here is: + // Along the edges of the polygon, for each intersection point P (generated above), + // calculate the normal N, which should be perpendicular to the edge of the + // polygon (represented by the neighbor intersection points) . + // Shadow's vertices will be generated as : P + N * scale. + int currentIndex = 0; + for (int r = 0; r < layers; r++) { + int firstInLayer = currentIndex; + for (int i = 0; i < rays; i++) { + + Vector2 normal(1.0f, 0.0f); + calculateNormal(rays, i, dir, rayDist, normal); + + float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor); + + // The vertex should be start from rayDist[i] then scale the + // normalizeNormal! + Vector2 intersection = dir[i] * rayDist[i] + centroid; + + // Use 2 rings' vertices to complete one layer's strip + for (int j = r; j < (r + 2); j++) { + float jf = j / (float)(rings - 1); + + float expansionDist = rayHeight[i] / heightFactor * geomFactor * jf; + AlphaVertex::set(&shadowVertices[currentIndex], + intersection.x + normal.x * expansionDist, + intersection.y + normal.y * expansionDist, + (1 - jf) * opacity); + currentIndex++; + } + } + + // From one layer to the next, we need to duplicate the vertex to + // continue as a single strip. + shadowVertices[currentIndex] = shadowVertices[firstInLayer]; + currentIndex++; + shadowVertices[currentIndex] = shadowVertices[firstInLayer + 1]; + currentIndex++; + } + + // After all rings are done, we need to jump into the polygon. + // In order to keep everything in a strip, we need to duplicate the last one + // of the rings and the first one inside the polygon. + int lastInRings = currentIndex - 1; + shadowVertices[currentIndex] = shadowVertices[lastInRings]; + currentIndex++; + + // We skip one and fill it back after we finish the internal triangles. + currentIndex++; + int firstInternal = currentIndex; + + // Combine the internal area of the polygon into a triangle strip, too. + // The basic idea is zig zag between the intersection points. + // 0 -> (n - 1) -> 1 -> (n - 2) ... + for (int k = 0; k < rays; k++) { + int i = k / 2; + if ((k & 1) == 1) { // traverse the inside in a zig zag pattern for strips + i = rays - i - 1; + } + float cast = rayDist[i] * (1 + rayHeight[i] / heightFactor); + float opacity = strength * (0.5f) / (1 + rayHeight[i] / heightFactor); + float t = rayDist[i]; + + AlphaVertex::set(&shadowVertices[currentIndex], dir[i].x * t + centroid.x, + dir[i].y * t + centroid.y, opacity); + currentIndex++; + } + + currentIndex = firstInternal - 1; + shadowVertices[currentIndex] = shadowVertices[firstInternal]; +} + +/** + * Calculate the centroid of a given polygon. + * + * @param vertices The shadow caster's polygon, which is represented in a + * straight Vector3 array. + * @param vertexCount The length of caster's polygon in terms of number of vertices. + * + * @param centroid Return the centroid of the polygon. + */ +void AmbientShadow::calculatePolygonCentroid(const Vector3* vertices, int vertexCount, + Vector2& centroid) { + float sumx = 0; + float sumy = 0; + int p1 = vertexCount - 1; + float area = 0; + for (int p2 = 0; p2 < vertexCount; p2++) { + float x1 = vertices[p1].x; + float y1 = vertices[p1].y; + float x2 = vertices[p2].x; + float y2 = vertices[p2].y; + float a = (x1 * y2 - x2 * y1); + sumx += (x1 + x2) * a; + sumy += (y1 + y2) * a; + area += a; + p1 = p2; + } + + if (area == 0) { +#if DEBUG_SHADOW + ALOGE("Area is 0!"); +#endif + centroid.x = vertices[0].x; + centroid.y = vertices[0].y; + } else { + centroid.x = sumx / (3 * area); + centroid.y = sumy / (3 * area); + } +} + +/** + * Generate an array of rays' direction vectors. + * + * @param rays The number of rays shooting out from the centroid. + * @param dir Return the array of ray vectors. + */ +void AmbientShadow::calculateRayDirections(int rays, Vector2* dir) { + float deltaAngle = 2 * M_PI / rays; + + for (int i = 0; i < rays; i++) { + dir[i].x = sinf(deltaAngle * i); + dir[i].y = cosf(deltaAngle * i); + } +} + +/** + * Calculate the intersection of a ray hitting the polygon. + * + * @param vertices The shadow caster's polygon, which is represented in a + * Vector3 array. + * @param vertexCount The length of caster's polygon in terms of number of vertices. + * @param start The starting point of the ray. + * @param dir The direction vector of the ray. + * + * @param outEdgeIndex Return the index of the segment (or index of the starting + * vertex) that ray intersect with. + * @param outEdgeFraction Return the fraction offset from the segment starting + * index. + * @param outRayDist Return the ray distance from centroid to the intersection. + */ +void AmbientShadow::calculateIntersection(const Vector3* vertices, int vertexCount, + const Vector2& start, const Vector2& dir, int& outEdgeIndex, + float& outEdgeFraction, float& outRayDist) { + float startX = start.x; + float startY = start.y; + float dirX = dir.x; + float dirY = dir.y; + // Start the search from the last edge from poly[len-1] to poly[0]. + int p1 = vertexCount - 1; + + for (int p2 = 0; p2 < vertexCount; p2++) { + float p1x = vertices[p1].x; + float p1y = vertices[p1].y; + float p2x = vertices[p2].x; + float p2y = vertices[p2].y; + + // The math here is derived from: + // f(t, v) = p1x * (1 - t) + p2x * t - (startX + dirX * v) = 0; + // g(t, v) = p1y * (1 - t) + p2y * t - (startY + dirY * v) = 0; + float div = (dirX * (p1y - p2y) + dirY * p2x - dirY * p1x); + if (div != 0) { + float t = (dirX * (p1y - startY) + dirY * startX - dirY * p1x) / (div); + if (t > 0 && t <= 1) { + float t2 = (p1x * (startY - p2y) + + p2x * (p1y - startY) + + startX * (p2y - p1y)) / div; + if (t2 > 0) { + outEdgeIndex = p1; + outRayDist = t2; + outEdgeFraction = t; + return; + } + } + } + p1 = p2; + } + return; +}; + +/** + * Calculate the normal at the intersection point between a ray and the polygon. + * + * @param rays The total number of rays. + * @param currentRayIndex The index of the ray which the normal is based on. + * @param dir The array of the all the rays directions. + * @param rayDist The pre-computed ray distances array. + * + * @param normal Return the normal. + */ +void AmbientShadow::calculateNormal(int rays, int currentRayIndex, + const Vector2* dir, const float* rayDist, Vector2& normal) { + int preIndex = (currentRayIndex - 1 + rays) % rays; + int postIndex = (currentRayIndex + 1) % rays; + Vector2 p1 = dir[preIndex] * rayDist[preIndex]; + Vector2 p2 = dir[postIndex] * rayDist[postIndex]; + + // Now the V (deltaX, deltaY) is the vector going CW around the poly. + Vector2 delta = p2 - p1; + if (delta.length() != 0) { + delta.normalize(); + // Calculate the normal , which is CCW 90 rotate to the V. + // 90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z) + normal.x = -delta.y; + normal.y = delta.x; + } +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h new file mode 100644 index 0000000..079bdb7 --- /dev/null +++ b/libs/hwui/AmbientShadow.h @@ -0,0 +1,57 @@ + +/* + * 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. + */ + +#ifndef ANDROID_HWUI_AMBIENT_SHADOW_H +#define ANDROID_HWUI_AMBIENT_SHADOW_H + +#include "Debug.h" +#include "Vector.h" +#include "VertexBuffer.h" + +namespace android { +namespace uirenderer { + +/** + * AmbientShadow is used to calculate the ambient shadow value around a polygon. + * + * TODO: calculateIntersection() now is O(N*M), where N is the number of + * polygon's vertics and M is the number of rays. In fact, by staring tracing + * the vertex from the previous intersection, the algorithm can be O(N + M); + */ +class AmbientShadow { +public: + static void createAmbientShadow(const Vector3* poly, int polyLength, int rays, + int layers, float strength, float heightFactor, float geomFactor, + VertexBuffer& shadowVertexBuffer); + +private: + static void calculatePolygonCentroid(const Vector3* poly, int len, Vector2& centroid); + + static void calculateRayDirections(int rays, Vector2* dir); + + static void calculateIntersection(const Vector3* poly, int nbVertices, + const Vector2& start, const Vector2& dir, int& outEdgeIndex, + float& outEdgeFraction, float& outRayDist); + + static void calculateNormal(int rays, int currentRayIndex, const Vector2* dir, + const float* rayDist, Vector2& normal); +}; // AmbientShadow + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_AMBIENT_SHADOW_H diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 1f37925..962d726 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -10,6 +10,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) thread/TaskManager.cpp \ font/CacheTexture.cpp \ font/Font.cpp \ + AmbientShadow.cpp \ AssetAtlas.cpp \ FontRenderer.cpp \ GammaFontRenderer.cpp \ @@ -37,6 +38,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) ProgramCache.cpp \ RenderBufferCache.cpp \ ResourceCache.cpp \ + ShadowTessellator.cpp \ SkiaColorFilter.cpp \ SkiaShader.cpp \ Snapshot.cpp \ diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index f8d3589..5b751b9 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -473,7 +473,7 @@ bool Caches::unbindPixelBuffer() { // Meshes and textures /////////////////////////////////////////////////////////////////////////////// -void Caches::bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei stride) { +void Caches::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) { GLuint slot = currentProgram->position; glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); @@ -482,7 +482,7 @@ void Caches::bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei str } } -void Caches::bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride) { +void Caches::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) { if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) { GLuint slot = currentProgram->texCoords; glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices); diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index f8f2284..963965d 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -208,13 +208,13 @@ public: * Binds an attrib to the specified float vertex pointer. * Assumes a stride of gMeshStride and a size of 2. */ - void bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei stride = gMeshStride); + void bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride); /** * Binds an attrib to the specified float vertex pointer. * Assumes a stride of gMeshStride and a size of 2. */ - void bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride = gMeshStride); + void bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride); /** * Resets the vertex pointers. @@ -379,9 +379,9 @@ private: GLuint mCurrentBuffer; GLuint mCurrentIndicesBuffer; GLuint mCurrentPixelBuffer; - void* mCurrentPositionPointer; + const void* mCurrentPositionPointer; GLsizei mCurrentPositionStride; - void* mCurrentTexCoordsPointer; + const void* mCurrentTexCoordsPointer; GLsizei mCurrentTexCoordsStride; bool mTexCoordsArrayEnabled; diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h index 786f12a..f619205 100644 --- a/libs/hwui/Debug.h +++ b/libs/hwui/Debug.h @@ -85,6 +85,12 @@ // Turn on to highlight drawing batches and merged batches with different colors #define DEBUG_MERGE_BEHAVIOR 0 +// Turn on to enable 3D support in the renderer (off by default until API for control exists) +#define DEBUG_ENABLE_3D 0 + +// Turn on to enable debugging shadow +#define DEBUG_SHADOW 0 + #if DEBUG_INIT #define INIT_LOGD(...) ALOGD(__VA_ARGS__) #else diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h index 3dcbd0b..fca3588 100644 --- a/libs/hwui/DeferredDisplayList.h +++ b/libs/hwui/DeferredDisplayList.h @@ -79,13 +79,13 @@ public: }; class DeferredDisplayList { + friend class DeferStateStruct; // used to give access to allocator public: DeferredDisplayList(const Rect& bounds, bool avoidOverdraw = true) : mBounds(bounds), mAvoidOverdraw(avoidOverdraw) { clear(); } ~DeferredDisplayList() { clear(); } - void reset(const Rect& bounds) { mBounds.set(bounds); } enum OpBatchId { kOpBatch_None = 0, // Don't batch @@ -120,6 +120,8 @@ public: void addDrawOp(OpenGLRenderer& renderer, DrawOp* op); private: + DeferredDisplayList(const DeferredDisplayList& other); // disallow copy + DeferredDisplayState* createState() { return new (mAllocator) DeferredDisplayState(); } diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index a3e4bb4..c616cd8 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -14,8 +14,12 @@ * limitations under the License. */ +#define ATRACE_TAG ATRACE_TAG_VIEW + #include <SkCanvas.h> +#include <utils/Trace.h> + #include "Debug.h" #include "DisplayList.h" #include "DisplayListOp.h" @@ -65,11 +69,6 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { void DisplayList::clearResources() { mDisplayListData = NULL; - mClipRectOp = NULL; - mSaveLayerOp = NULL; - mSaveOp = NULL; - mRestoreToCountOp = NULL; - delete mTransformMatrix; delete mTransformCamera; delete mTransformMatrix3D; @@ -168,17 +167,6 @@ void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorde return; } - // allocate reusable ops for state-deferral - LinearAllocator& alloc = mDisplayListData->allocator; - mClipRectOp = new (alloc) ClipRectOp(); - mSaveLayerOp = new (alloc) SaveLayerOp(); - mSaveOp = new (alloc) SaveOp(); - mRestoreToCountOp = new (alloc) RestoreToCountOp(); - if (CC_UNLIKELY(!mSaveOp)) { // temporary debug logging - ALOGW("Error: %s's SaveOp not allocated, size %d", getName(), mSize); - CRASH(); - } - mFunctorCount = recorder.getFunctorCount(); Caches& caches = Caches::getInstance(); @@ -253,6 +241,7 @@ void DisplayList::init() { mHasOverlappingRendering = true; mTranslationX = 0; mTranslationY = 0; + mTranslationZ = 0; mRotation = 0; mRotationX = 0; mRotationY= 0; @@ -269,6 +258,7 @@ void DisplayList::init() { mHeight = 0; mPivotExplicitlySet = false; mCaching = false; + mIs3dRoot = true; // TODO: setter, java side impl } size_t DisplayList::getSize() { @@ -320,27 +310,38 @@ void DisplayList::updateMatrix() { mPivotY = mPrevHeight / 2.0f; } } - if ((mMatrixFlags & ROTATION_3D) == 0) { + if (!DEBUG_ENABLE_3D && (mMatrixFlags & ROTATION_3D) == 0) { mTransformMatrix->setTranslate(mTranslationX, mTranslationY); mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY); mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); } else { - if (!mTransformCamera) { - mTransformCamera = new Sk3DView(); - mTransformMatrix3D = new SkMatrix(); + if (DEBUG_ENABLE_3D) { + mTransform.loadTranslate(mPivotX + mTranslationX, mPivotY + mTranslationY, + mTranslationZ); + mTransform.rotate(mRotationX, 1, 0, 0); + mTransform.rotate(mRotationY, 0, 1, 0); + mTransform.rotate(mRotation, 0, 0, 1); + mTransform.scale(mScaleX, mScaleY, 1); + mTransform.translate(-mPivotX, -mPivotY); + } else { + /* TODO: support this old transform approach, based on API level */ + if (!mTransformCamera) { + mTransformCamera = new Sk3DView(); + mTransformMatrix3D = new SkMatrix(); + } + mTransformMatrix->reset(); + mTransformCamera->save(); + mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); + mTransformCamera->rotateX(mRotationX); + mTransformCamera->rotateY(mRotationY); + mTransformCamera->rotateZ(-mRotation); + mTransformCamera->getMatrix(mTransformMatrix3D); + mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY); + mTransformMatrix3D->postTranslate(mPivotX + mTranslationX, + mPivotY + mTranslationY); + mTransformMatrix->postConcat(*mTransformMatrix3D); + mTransformCamera->restore(); } - mTransformMatrix->reset(); - mTransformCamera->save(); - mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY); - mTransformCamera->rotateX(mRotationX); - mTransformCamera->rotateY(mRotationY); - mTransformCamera->rotateZ(-mRotation); - mTransformCamera->getMatrix(mTransformMatrix3D); - mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY); - mTransformMatrix3D->postTranslate(mPivotX + mTranslationX, - mPivotY + mTranslationY); - mTransformMatrix->postConcat(*mTransformMatrix3D); - mTransformCamera->restore(); } } mMatrixDirty = false; @@ -417,8 +418,13 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, if (mMatrixFlags != 0) { if (mMatrixFlags == TRANSLATION) { renderer.translate(mTranslationX, mTranslationY); + renderer.translateZ(mTranslationZ); } else { +#if DEBUG_ENABLE_3D + renderer.concatMatrix(mTransform); +#else renderer.concatMatrix(mTransformMatrix); +#endif } } bool clipToBoundsNeeded = mCaching ? false : mClipToBounds; @@ -436,14 +442,107 @@ void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler, saveFlags |= SkCanvas::kClipToLayer_SaveFlag; clipToBoundsNeeded = false; // clipping done by saveLayer } - handler(mSaveLayerOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, - mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags), PROPERTY_SAVECOUNT, - mClipToBounds); + + SaveLayerOp* op = new (handler.allocator()) SaveLayerOp( + 0, 0, mRight - mLeft, mBottom - mTop, + mAlpha * 255, SkXfermode::kSrcOver_Mode, saveFlags); + handler(op, PROPERTY_SAVECOUNT, mClipToBounds); } } if (clipToBoundsNeeded) { - handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op), - PROPERTY_SAVECOUNT, mClipToBounds); + ClipRectOp* op = new (handler.allocator()) ClipRectOp(0, 0, + mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op); + handler(op, PROPERTY_SAVECOUNT, mClipToBounds); + } +} + +/** + * Apply property-based transformations to input matrix + */ +void DisplayList::applyViewPropertyTransforms(mat4& matrix) { + if (mLeft != 0 || mTop != 0) { + matrix.translate(mLeft, mTop); + } + if (mStaticMatrix) { + mat4 stat(*mStaticMatrix); + matrix.multiply(stat); + } else if (mAnimationMatrix) { + mat4 anim(*mAnimationMatrix); + matrix.multiply(anim); + } + if (mMatrixFlags != 0) { + if (mMatrixFlags == TRANSLATION) { + matrix.translate(mTranslationX, mTranslationY, mTranslationZ); + } else { +#if DEBUG_ENABLE_3D + matrix.multiply(mTransform); +#else + mat4 temp(*mTransformMatrix); + matrix.multiply(temp); +#endif + } + } +} + +/** + * Organizes the DisplayList hierarchy to prepare for Z-based draw order. + * + * This should be called before a call to defer() or drawDisplayList() + * + * Each DisplayList that serves as a 3d root builds its list of composited children, + * which are flagged to not draw in the standard draw loop. + */ +void DisplayList::computeOrdering() { + ATRACE_CALL(); + mat4::identity(); + for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { + DrawDisplayListOp* childOp = mDisplayListData->children[i]; + childOp->mDisplayList->computeOrderingImpl(childOp, &m3dNodes, &mat4::identity()); + } +} + +void DisplayList::computeOrderingImpl( + DrawDisplayListOp* opState, + KeyedVector<float, Vector<DrawDisplayListOp*> >* compositedChildrenOf3dRoot, + const mat4* transformFrom3dRoot) { + // TODO: should avoid this calculation in most cases + opState->mTransformFrom3dRoot.load(*transformFrom3dRoot); + opState->mTransformFrom3dRoot.multiply(opState->mTransformFromParent); + + if (mTranslationZ != 0.0f) { // TODO: other signals, such as custom 4x4 matrix + // composited layer, insert into current 3d root and flag for out of order draw + opState->mSkipInOrderDraw = true; + + Vector3 pivot(mPivotX, mPivotY, 0.0f); + mat4 totalTransform(opState->mTransformFrom3dRoot); + applyViewPropertyTransforms(totalTransform); + totalTransform.mapPoint3d(pivot); + const float key = pivot.z; + + if (compositedChildrenOf3dRoot->indexOfKey(key) < 0) { + compositedChildrenOf3dRoot->add(key, Vector<DrawDisplayListOp*>()); + } + compositedChildrenOf3dRoot->editValueFor(key).push(opState); + } else { + // standard in order draw + opState->mSkipInOrderDraw = false; + } + + m3dNodes.clear(); + if (mIs3dRoot) { + // create a new 3d space for children by separating their ordering + compositedChildrenOf3dRoot = &m3dNodes; + transformFrom3dRoot = &mat4::identity(); + } else { + transformFrom3dRoot = &(opState->mTransformFrom3dRoot); + } + + if (mDisplayListData->children.size() > 0) { + for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) { + DrawDisplayListOp* childOp = mDisplayListData->children[i]; + childOp->mDisplayList->computeOrderingImpl(childOp, + compositedChildrenOf3dRoot, transformFrom3dRoot); + } } } @@ -454,6 +553,8 @@ public: inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) { operation->defer(mDeferStruct, saveCount, mLevel, clipToBounds); } + inline LinearAllocator& allocator() { return *(mDeferStruct.mAllocator); } + private: DeferStateStruct& mDeferStruct; const int mLevel; @@ -474,6 +575,8 @@ public: #endif operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds); } + inline LinearAllocator& allocator() { return *(mReplayStruct.mAllocator); } + private: ReplayStateStruct& mReplayStruct; const int mLevel; @@ -490,11 +593,60 @@ void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) { replayStruct.mDrawGlStatus); } +template <class T> +void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer, + T& handler, const int level) { + if (m3dNodes.size() == 0 || + (mode == kNegativeZChildren && m3dNodes.keyAt(0) > 0.0f) || + (mode == kPositiveZChildren && m3dNodes.keyAt(m3dNodes.size() - 1) < 0.0f)) { + // nothing to draw + return; + } + + LinearAllocator& alloc = handler.allocator(); + ClipRectOp* op = new (alloc) ClipRectOp(0, 0, mWidth, mHeight, + SkRegion::kIntersect_Op); // clip to 3d root bounds for now + handler(op, PROPERTY_SAVECOUNT, mClipToBounds); + int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag); + + for (int i = 0; i < m3dNodes.size(); i++) { + const float zValue = m3dNodes.keyAt(i); + + if (mode == kPositiveZChildren && zValue < 0.0f) continue; + if (mode == kNegativeZChildren && zValue > 0.0f) break; + + const Vector<DrawDisplayListOp*>& nodesAtZ = m3dNodes[i]; + for (int j = 0; j < nodesAtZ.size(); j++) { + DrawDisplayListOp* op = nodesAtZ[j]; + if (mode == kPositiveZChildren) { + /* draw shadow on renderer 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 + */ + mat4 shadowMatrix(op->mTransformFrom3dRoot); + op->mDisplayList->applyViewPropertyTransforms(shadowMatrix); + DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix, op->mDisplayList->mAlpha, + op->mDisplayList->getWidth(), op->mDisplayList->getHeight()); + handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds); + } + + renderer.concatMatrix(op->mTransformFrom3dRoot); + op->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone + handler(op, renderer.getSaveCount() - 1, mClipToBounds); + op->mSkipInOrderDraw = true; + } + } + handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds); +} + /** * This function serves both defer and replay modes, and will organize the displayList's component * operations for a single frame: * - * Every 'simple' operation that affects just the matrix and alpha (or other factors of + * Every 'simple' state operation that affects just the matrix and alpha (or other factors of * DeferredDisplayState) may be issued directly to the renderer, but complex operations (with custom * defer logic) and operations in displayListOps are issued through the 'handler' which handles the * defer vs replay logic, per operation @@ -517,8 +669,9 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) clipRect->right, clipRect->bottom); #endif + LinearAllocator& alloc = handler.allocator(); int restoreTo = renderer.getSaveCount(); - handler(mSaveOp->reinit(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag), + handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag), PROPERTY_SAVECOUNT, mClipToBounds); DISPLAY_LIST_LOGD("%*sSave %d %d", (level + 1) * 2, "", @@ -526,30 +679,31 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) setViewProperties<T>(renderer, handler, level + 1); - if (mClipToBounds && renderer.quickRejectConservative(0, 0, mWidth, mHeight)) { - DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo); - handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT, mClipToBounds); - renderer.restoreToCount(restoreTo); - renderer.setOverrideLayerAlpha(1.0f); - return; - } + bool quickRejected = mClipToBounds && renderer.quickRejectConservative(0, 0, mWidth, mHeight); + if (!quickRejected) { + // for 3d root, draw children with negative z values + iterate3dChildren(kNegativeZChildren, renderer, handler, level); - DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); - int saveCount = renderer.getSaveCount() - 1; - for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { - DisplayListOp *op = mDisplayListData->displayListOps[i]; + DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance(); + const int saveCountOffset = renderer.getSaveCount() - 1; + for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) { + DisplayListOp *op = mDisplayListData->displayListOps[i]; #if DEBUG_DISPLAY_LIST - op->output(level + 1); + op->output(level + 1); #endif - logBuffer.writeCommand(level, op->name()); - handler(op, saveCount, mClipToBounds); + logBuffer.writeCommand(level, op->name()); + handler(op, saveCountOffset, mClipToBounds); + } + + // for 3d root, draw children with positive z values + iterate3dChildren(kPositiveZChildren, renderer, handler, level); } DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo); - handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT, mClipToBounds); - renderer.restoreToCount(restoreTo); + handler(new (alloc) RestoreToCountOp(restoreTo), + PROPERTY_SAVECOUNT, mClipToBounds); renderer.setOverrideLayerAlpha(1.0f); } diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index f52181a..4bd79eb 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -26,6 +26,7 @@ #include <private/hwui/DrawGlInfo.h> +#include <utils/KeyedVector.h> #include <utils/LinearAllocator.h> #include <utils/RefBase.h> #include <utils/SortedVector.h> @@ -37,6 +38,8 @@ #include <androidfw/ResourceTypes.h> #include "Debug.h" +#include "Matrix.h" +#include "DeferredDisplayList.h" #define TRANSLATION 0x0001 #define ROTATION 0x0002 @@ -65,36 +68,70 @@ class ClipRectOp; class SaveLayerOp; class SaveOp; class RestoreToCountOp; +class DrawDisplayListOp; -struct DeferStateStruct { - DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) - : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {} - DeferredDisplayList& mDeferredList; +/** + * Holds data used in the playback a tree of DisplayLists. + */ +class PlaybackStateStruct { +protected: + PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator) + : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){} + +public: OpenGLRenderer& mRenderer; const int mReplayFlags; + + // Allocator with the lifetime of a single frame. + // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator + LinearAllocator * const mAllocator; }; -struct ReplayStateStruct { +class DeferStateStruct : public PlaybackStateStruct { +public: + DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags) + : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)), mDeferredList(deferredList) {} + + DeferredDisplayList& mDeferredList; +}; + +class ReplayStateStruct : public PlaybackStateStruct { +public: ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags) - : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags), - mDrawGlStatus(DrawGlInfo::kStatusDone) {} - OpenGLRenderer& mRenderer; + : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator), + mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {} + Rect& mDirty; - const int mReplayFlags; status_t mDrawGlStatus; + LinearAllocator mReplayAllocator; }; /** - * Refcounted structure that holds data used in display list stream + * Refcounted structure that holds the list of commands used in display list stream. */ class DisplayListData : public LightRefBase<DisplayListData> { public: + // allocator into which all ops were allocated LinearAllocator allocator; + + // pointers to all ops within display list, pointing into allocator data Vector<DisplayListOp*> displayListOps; + + // list of children display lists for quick, non-drawing traversal + Vector<DrawDisplayListOp*> children; }; /** - * Replays recorded drawing commands. + * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties. + * + * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording + * functionality is split between DisplayListRenderer (which manages the recording), DisplayListData + * (which holds the actual data), and DisplayList (which holds properties and performs playback onto + * a renderer). + * + * Note that DisplayListData is swapped out from beneath an individual DisplayList when a view's + * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay + * attached. */ class DisplayList { public: @@ -113,6 +150,7 @@ public: void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false); + void computeOrdering(); void defer(DeferStateStruct& deferStruct, const int level); void replay(ReplayStateStruct& replayStruct, const int level); @@ -188,12 +226,7 @@ public: void setTranslationX(float translationX) { if (translationX != mTranslationX) { mTranslationX = translationX; - mMatrixDirty = true; - if (mTranslationX == 0.0f && mTranslationY == 0.0f) { - mMatrixFlags &= ~TRANSLATION; - } else { - mMatrixFlags |= TRANSLATION; - } + onTranslationUpdate(); } } @@ -204,12 +237,7 @@ public: void setTranslationY(float translationY) { if (translationY != mTranslationY) { mTranslationY = translationY; - mMatrixDirty = true; - if (mTranslationX == 0.0f && mTranslationY == 0.0f) { - mMatrixFlags &= ~TRANSLATION; - } else { - mMatrixFlags |= TRANSLATION; - } + onTranslationUpdate(); } } @@ -217,6 +245,17 @@ public: return mTranslationY; } + void setTranslationZ(float translationZ) { + if (translationZ != mTranslationZ) { + mTranslationZ = translationZ; + onTranslationUpdate(); + } + } + + float getTranslationZ() const { + return mTranslationZ; + } + void setRotation(float rotation) { if (rotation != mRotation) { mRotation = rotation; @@ -454,12 +493,36 @@ public: } private: + enum ChildrenSelectMode { + kNegativeZChildren, + kPositiveZChildren + }; + + void onTranslationUpdate() { + mMatrixDirty = true; + if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) { + mMatrixFlags &= ~TRANSLATION; + } else { + mMatrixFlags |= TRANSLATION; + } + } + void outputViewProperties(const int level); + void applyViewPropertyTransforms(mat4& matrix); + + void computeOrderingImpl(DrawDisplayListOp* opState, + KeyedVector<float, Vector<DrawDisplayListOp*> >* compositedChildrenOf3dRoot, + const mat4* transformFromRoot); + template <class T> inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level); template <class T> + inline void iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer, + T& handler, const int level); + + template <class T> inline void iterate(OpenGLRenderer& renderer, T& handler, const int level); void init(); @@ -509,7 +572,7 @@ private: bool mClipToBounds; float mAlpha; bool mHasOverlappingRendering; - float mTranslationX, mTranslationY; + float mTranslationX, mTranslationY, mTranslationZ; float mRotation, mRotationX, mRotationY; float mScaleX, mScaleY; float mPivotX, mPivotY; @@ -526,23 +589,17 @@ private: SkMatrix* mTransformMatrix3D; SkMatrix* mStaticMatrix; SkMatrix* mAnimationMatrix; + Matrix4 mTransform; bool mCaching; + bool mIs3dRoot; + /** - * State operations - needed to defer displayList property operations (for example, when setting - * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's - * allocation, or null if uninitialized. - * - * These are initialized (via friend re-constructors) when a displayList is issued in either - * replay or deferred mode. If replaying, the ops are not used until the next frame. If - * deferring, the ops may be stored in the DeferredDisplayList to be played back a second time. - * - * They should be used at most once per frame (one call to 'iterate') to avoid overwriting data + * Draw time state - these properties are only set and used during rendering */ - ClipRectOp* mClipRectOp; - SaveLayerOp* mSaveLayerOp; - SaveOp* mSaveOp; - RestoreToCountOp* mRestoreToCountOp; + + // for 3d roots, contains a z sorted list of all children items + KeyedVector<float, Vector<DrawDisplayListOp*> > m3dNodes; // TODO: good data structure }; // class DisplayList }; // namespace uirenderer diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 88077d4..1980b03 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -262,7 +262,6 @@ protected: /////////////////////////////////////////////////////////////////////////////// class SaveOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: SaveOp(int flags) : mFlags(flags) {} @@ -295,7 +294,6 @@ private: }; class RestoreToCountOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: RestoreToCountOp(int count) : mCount(count) {} @@ -328,7 +326,6 @@ private: }; class SaveLayerOp : public StateOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: SaveLayerOp(float left, float top, float right, float bottom, int alpha, SkXfermode::Mode mode, int flags) @@ -524,7 +521,6 @@ protected: }; class ClipRectOp : public ClipOp { - friend class DisplayList; // give DisplayList private constructor/reinit access public: ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op) : ClipOp(op), mArea(left, top, right, bottom) {} @@ -1100,7 +1096,7 @@ private: class DrawColorOp : public DrawOp { public: DrawColorOp(int color, SkXfermode::Mode mode) - : DrawOp(0), mColor(color), mMode(mode) {}; + : DrawOp(NULL), mColor(color), mMode(mode) {}; virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawColor(mColor, mMode); @@ -1505,7 +1501,7 @@ private: class DrawFunctorOp : public DrawOp { public: DrawFunctorOp(Functor* functor) - : DrawOp(0), mFunctor(functor) {} + : DrawOp(NULL), mFunctor(functor) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { renderer.startMark("GL functor"); @@ -1525,20 +1521,21 @@ private: }; class DrawDisplayListOp : public DrawBoundedOp { + friend class DisplayList; // grant DisplayList access to info of child public: - DrawDisplayListOp(DisplayList* displayList, int flags) + DrawDisplayListOp(DisplayList* displayList, int flags, const mat4& transformFromParent) : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0), - mDisplayList(displayList), mFlags(flags) {} + mDisplayList(displayList), mFlags(flags), mTransformFromParent(transformFromParent) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) { - if (mDisplayList && mDisplayList->isRenderable()) { + if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { mDisplayList->defer(deferStruct, level + 1); } } virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level, bool useQuickReject) { - if (mDisplayList && mDisplayList->isRenderable()) { + if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) { mDisplayList->replay(replayStruct, level + 1); } } @@ -1559,13 +1556,58 @@ public: private: DisplayList* mDisplayList; - int mFlags; + const int mFlags; + + /////////////////////////// + // Properties below are used by DisplayList::computeOrderingImpl() and iterate() + /////////////////////////// + /** + * Records transform vs parent, used for computing total transform without rerunning DL contents + */ + const mat4 mTransformFromParent; + + /** + * Holds the transformation between the 3d root ViewGroup and this DisplayList drawing + * instance. Represents any translations / transformations done within the drawing of the 3d + * root ViewGroup's draw, before the draw of the View represented by this DisplayList draw + * instance. + * + * Note: doesn't include any transformation recorded within the DisplayList and its properties. + */ + mat4 mTransformFrom3dRoot; + bool mSkipInOrderDraw; +}; + +/** + * Not a canvas operation, used only by 3d / z ordering logic in DisplayList::iterate() + */ +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) {} + + virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { + return renderer.drawShadow(mCasterTransform, mCasterAlpha, mWidth, mHeight); + } + + virtual void output(int level, uint32_t logFlags) const { + OP_LOG("DrawShadow of width %.2f, height %.2f", mWidth, mHeight); + } + + virtual const char* name() { return "DrawShadow"; } + +private: + const mat4 mCasterTransform; + const float mCasterAlpha; + const float mWidth; + const float mHeight; }; class DrawLayerOp : public DrawOp { public: DrawLayerOp(Layer* layer, float x, float y) - : DrawOp(0), mLayer(layer), mX(x), mY(y) {} + : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {} virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) { return renderer.drawLayer(mLayer, mX, mY); diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp index d024923..19a027d 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -111,6 +111,7 @@ DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) { } else { displayList->initFromDisplayListRenderer(*this, true); } + // TODO: should just avoid setting the DisplayList's DisplayListData displayList->setRenderable(mHasDrawOps); return displayList; } @@ -120,7 +121,8 @@ bool DisplayListRenderer::isDeferred() { } void DisplayListRenderer::setViewport(int width, int height) { - mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); + // TODO: DisplayListRenderer shouldn't have a projection matrix, as it should never be used + mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1); mWidth = width; mHeight = height; @@ -248,7 +250,10 @@ status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList, // resources cache, but we rely on the caller (UI toolkit) to // do the right thing for now - addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags)); + DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList, flags, currentTransform()); + addDrawOp(op); + mDisplayListData->children.push(op); + return DrawGlInfo::kStatusDone; } diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index d233150..7269378 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -328,6 +328,7 @@ private: return patch; } + // TODO: move these to DisplayListData Vector<SkBitmap*> mBitmapResources; Vector<SkBitmap*> mOwnedBitmapResources; Vector<SkiaColorFilter*> mFilterResources; diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 48613fe..f7493a3 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -733,7 +733,9 @@ void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, int if (mRs == 0) { mRs = new RSC::RS(); - if (!mRs->init(RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) { + // a null path is OK because there are no custom kernels used + // hence nothing gets cached by RS + if (!mRs->init("", RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) { ALOGE("blur RS failed to init"); } diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index bd371a3..742ffd4 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -194,11 +194,9 @@ void Layer::defer() { dirtyRect.set(0, 0, width, height); } - if (deferredList) { - deferredList->reset(dirtyRect); - } else { - deferredList = new DeferredDisplayList(dirtyRect); - } + delete deferredList; + deferredList = new DeferredDisplayList(dirtyRect); + DeferStateStruct deferredState(*deferredList, *renderer, DisplayList::kReplayFlag_ClipChildren); @@ -206,6 +204,7 @@ void Layer::defer() { renderer->setupFrameState(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom, !isBlend()); + displayList->computeOrdering(); displayList->defer(deferredState, 0); deferredUpdateScheduled = false; diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp index ba22071..4f5cd26 100644 --- a/libs/hwui/Matrix.cpp +++ b/libs/hwui/Matrix.cpp @@ -89,8 +89,9 @@ uint8_t Matrix4::getType() const { float m01 = data[kSkewX]; float m10 = data[kSkewY]; float m11 = data[kScaleY]; + float m32 = data[kTranslateZ]; - if (m01 != 0.0f || m10 != 0.0f) { + if (m01 != 0.0f || m10 != 0.0f || m32 != 0.0f) { mType |= kTypeAffine; } @@ -131,11 +132,13 @@ bool Matrix4::changesBounds() const { } bool Matrix4::isPureTranslate() const { - return getGeometryType() <= kTypeTranslate; + // NOTE: temporary hack to workaround ignoreTransform behavior with Z values + // TODO: separate this into isPure2dTranslate vs isPure3dTranslate + return getGeometryType() <= kTypeTranslate && (data[kTranslateZ] == 0.0f); } bool Matrix4::isSimple() const { - return getGeometryType() <= (kTypeScale | kTypeTranslate); + return getGeometryType() <= (kTypeScale | kTypeTranslate) && (data[kTranslateZ] == 0.0f); } bool Matrix4::isIdentity() const { @@ -369,6 +372,84 @@ void Matrix4::loadMultiply(const Matrix4& u, const Matrix4& v) { mType = kTypeUnknown; } +// translated from android.opengl.Matrix#frustumM() +void Matrix4::loadFrustum(float left, float top, float right, float bottom, float near, float far) { + float r_width = 1.0f / (right - left); + float r_height = 1.0f / (top - bottom); + float r_depth = 1.0f / (near - far); + float x = 2.0f * (near * r_width); + float y = 2.0f * (near * r_height); + float A = (right + left) * r_width; + float B = (top + bottom) * r_height; + float C = (far + near) * r_depth; + float D = 2.0f * (far * near * r_depth); + + memset(&data, 0, sizeof(data)); + mType = kTypeUnknown; + + data[kScaleX] = x; + data[kScaleY] = y; + data[8] = A; + data[9] = B; + data[kScaleZ] = C; + data[kTranslateZ] = D; + data[11] = -1.0f; +} + +// translated from android.opengl.Matrix#setLookAtM() +void Matrix4::loadLookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + float fx = centerX - eyeX; + float fy = centerY - eyeY; + float fz = centerZ - eyeZ; + + // Normalize f + float rlf = 1.0f / sqrt(fx*fx + fy*fy + fz*fz); + fx *= rlf; + fy *= rlf; + fz *= rlf; + + // compute s = f x up (x means "cross product") + float sx = fy * upZ - fz * upY; + float sy = fz * upX - fx * upZ; + float sz = fx * upY - fy * upX; + + // and normalize s + float rls = 1.0f / sqrt(sx*sx + sy*sy + sz*sz); + sx *= rls; + sy *= rls; + sz *= rls; + + // compute u = s x f + float ux = sy * fz - sz * fy; + float uy = sz * fx - sx * fz; + float uz = sx * fy - sy * fx; + + mType = kTypeUnknown; + data[0] = sx; + data[1] = ux; + data[2] = -fx; + data[3] = 0.0f; + + data[4] = sy; + data[5] = uy; + data[6] = -fy; + data[7] = 0.0f; + + data[8] = sz; + data[9] = uz; + data[10] = -fz; + data[11] = 0.0f; + + data[12] = 0.0f; + data[13] = 0.0f; + data[14] = 0.0f; + data[15] = 1.0f; + + translate(-eyeX, -eyeY, -eyeZ); +} + void Matrix4::loadOrtho(float left, float right, float bottom, float top, float near, float far) { loadIdentity(); @@ -382,6 +463,14 @@ void Matrix4::loadOrtho(float left, float right, float bottom, float top, float mType = kTypeTranslate | kTypeScale | kTypeRectToRect; } +void Matrix4::mapPoint3d(Vector3& vec) const { + //TODO: optimize simple case + Vector3 orig(vec); + vec.x = orig.x * data[kScaleX] + orig.y * data[kSkewX] + orig.z * data[8] + data[kTranslateX]; + vec.y = orig.x * data[kSkewY] + orig.y * data[kScaleY] + orig.z * data[9] + data[kTranslateY]; + vec.z = orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ]; +} + #define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c) void Matrix4::mapPoint(float& x, float& y) const { diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h index b861ba4..00ca050 100644 --- a/libs/hwui/Matrix.h +++ b/libs/hwui/Matrix.h @@ -121,6 +121,10 @@ public: void loadRotate(float angle); void loadRotate(float angle, float x, float y, float z); void loadMultiply(const Matrix4& u, const Matrix4& v); + void loadFrustum(float left, float top, float right, float bottom, float near, float far); + void loadLookAt(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ); void loadOrtho(float left, float right, float bottom, float top, float near, float far); @@ -134,17 +138,18 @@ public: void multiply(float v); - void translate(float x, float y) { + void translate(float x, float y, float z = 0) { if ((getType() & sGeometryMask) <= kTypeTranslate) { data[kTranslateX] += x; data[kTranslateY] += y; + data[kTranslateZ] += z; } else { // Doing a translation will only affect the translate bit of the type // Save the type uint8_t type = mType; Matrix4 u; - u.loadTranslate(x, y, 0.0f); + u.loadTranslate(x, y, z); multiply(u); // Restore the type and fix the translate bit @@ -190,8 +195,9 @@ public: void copyTo(float* v) const; void copyTo(SkMatrix& v) const; - void mapRect(Rect& r) const; - void mapPoint(float& x, float& y) const; + void mapPoint3d(Vector3& vec) const; + void mapPoint(float& x, float& y) const; // 2d only + void mapRect(Rect& r) const; // 2d only float getTranslateX() const; float getTranslateY() const; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 214d0b1..578a251 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -36,7 +36,9 @@ #include "Fence.h" #include "PathTessellator.h" #include "Properties.h" +#include "ShadowTessellator.h" #include "Vector.h" +#include "VertexBuffer.h" namespace android { namespace uirenderer { @@ -180,7 +182,21 @@ void OpenGLRenderer::setViewport(int width, int height) { } void OpenGLRenderer::initViewport(int width, int height) { - mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1); + float dist = std::max(width, height) * 1.5; + + if (DEBUG_ENABLE_3D) { + // TODO: make view proj app configurable + Matrix4 projection; + projection.loadFrustum(-width / 2, -height / 2, width / 2, height / 2, dist, 0); + Matrix4 view; + view.loadLookAt(0, 0, dist, + 0, 0, 0, + 0, 1, 0); + mViewProjMatrix.loadMultiply(projection, view); + mViewProjMatrix.translate(-width/2, -height/2); + } else { + mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1); + } mWidth = width; mHeight = height; @@ -753,7 +769,7 @@ bool OpenGLRenderer::restoreSnapshot() { if (restoreOrtho) { Rect& r = previous->viewport; glViewport(r.left, r.top, r.right, r.bottom); - mOrthoMatrix.load(current->orthoMatrix); + mViewProjMatrix.load(current->orthoMatrix); } mSaveCount--; @@ -984,7 +1000,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom); mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight()); mSnapshot->height = bounds.getHeight(); - mSnapshot->orthoMatrix.load(mOrthoMatrix); + mSnapshot->orthoMatrix.load(mViewProjMatrix); endTiling(); debugOverdraw(false, false); @@ -1013,7 +1029,9 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { // Change the ortho projection glViewport(0, 0, bounds.getWidth(), bounds.getHeight()); - mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f); + + // TODO: determine best way to support 3d drawing within HW layers + mViewProjMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f); return true; } @@ -1539,10 +1557,8 @@ void OpenGLRenderer::getMatrix(SkMatrix* matrix) { } void OpenGLRenderer::concatMatrix(SkMatrix* matrix) { - SkMatrix transform; - currentTransform().copyTo(transform); - transform.preConcat(*matrix); - currentTransform().load(transform); + mat4 transform(*matrix); + currentTransform().multiply(transform); } /////////////////////////////////////////////////////////////////////////////// @@ -1927,10 +1943,10 @@ void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset, bool dirty = right - left > 0.0f && bottom - top > 0.0f; if (!ignoreTransform) { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform(), offset); + mCaches.currentProgram->set(mViewProjMatrix, mModelView, currentTransform(), offset); if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform()); } else { - mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity(), offset); + mCaches.currentProgram->set(mViewProjMatrix, mModelView, mat4::identity(), offset); if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom); } } @@ -2064,9 +2080,12 @@ void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) { status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags) { status_t status; + // All the usual checks and setup operations (quickReject, setupDraw, etc.) // will be performed by the display list itself if (displayList && displayList->isRenderable()) { + // compute 3d ordering + displayList->computeOrdering(); if (CC_UNLIKELY(mCaches.drawDeferDisabled)) { status = startFrame(); ReplayStateStruct replayStruct(*this, dirty, replayFlags); @@ -2082,7 +2101,7 @@ status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty, flushLayers(); status = startFrame(); - return status | deferredList.flush(*this, dirty); + return deferredList.flush(*this, dirty) | status; } return DrawGlInfo::kStatusDone; @@ -2562,7 +2581,7 @@ status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPa setupDrawColorFilterUniforms(); setupDrawShaderUniforms(); - void* vertices = vertexBuffer.getBuffer(); + const void* vertices = vertexBuffer.getBuffer(); bool force = mCaches.unbindMeshBuffer(); mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride); mCaches.resetTexCoordsVertexPointer(); @@ -3366,6 +3385,25 @@ status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint return drawColorRects(rects, count, color, mode); } +status_t OpenGLRenderer::drawShadow(const mat4& casterTransform, float casterAlpha, + float width, float height) { + if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone; + + // For now, always and scissor + // TODO: use quickReject + mCaches.enableScissor(); + + SkPaint paint; + paint.setColor(0x3f000000); + // Force the draw to use alpha values. + paint.setAntiAlias(true); + + VertexBuffer shadowVertexBuffer; + ShadowTessellator::tessellateAmbientShadow(width, height, casterTransform, + shadowVertexBuffer); + return drawVertexBuffer(shadowVertexBuffer, &paint); +} + status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color, SkXfermode::Mode mode, bool ignoreTransform, bool dirty, bool clip) { if (count == 0) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index ff37e18..6046531 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -265,6 +265,12 @@ public: ANDROID_API void getMatrix(SkMatrix* matrix); virtual void setMatrix(SkMatrix* matrix); virtual void concatMatrix(SkMatrix* matrix); + virtual void concatMatrix(Matrix4& matrix) { + currentTransform().multiply(matrix); + } + void translateZ(float z) { + currentTransform().translate(0,0,z); + } ANDROID_API const Rect& getClipBounds(); @@ -314,6 +320,9 @@ public: DrawOpMode drawOpMode = kDrawOpMode_Immediate); virtual status_t drawRects(const float* rects, int count, SkPaint* paint); + status_t drawShadow(const mat4& casterTransform, float casterAlpha, + float width, float height); + virtual void resetShader(); virtual void setupShader(SkiaShader* shader); @@ -1069,8 +1078,8 @@ private: // Dimensions of the drawing surface int mWidth, mHeight; - // Matrix used for ortho projection in shaders - mat4 mOrthoMatrix; + // Matrix used for view/projection in shaders + mat4 mViewProjMatrix; /** * Model-view matrix used to position/size objects diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h index e0044e8..236658d 100644 --- a/libs/hwui/PathTessellator.h +++ b/libs/hwui/PathTessellator.h @@ -22,84 +22,11 @@ #include "Matrix.h" #include "Rect.h" #include "Vertex.h" +#include "VertexBuffer.h" namespace android { namespace uirenderer { -class VertexBuffer { -public: - VertexBuffer(): - mBuffer(0), - mVertexCount(0), - mCleanupMethod(NULL) - {} - - ~VertexBuffer() { - if (mCleanupMethod) mCleanupMethod(mBuffer); - } - - /** - This should be the only method used by the PathTessellator. Subsequent calls to alloc will - allocate space within the first allocation (useful if you want to eventually allocate - multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines() - */ - template <class TYPE> - TYPE* alloc(int vertexCount) { - if (mVertexCount) { - TYPE* reallocBuffer = (TYPE*)mReallocBuffer; - // already have allocated the buffer, re-allocate space within - if (mReallocBuffer != mBuffer) { - // not first re-allocation, leave space for degenerate triangles to separate strips - reallocBuffer += 2; - } - mReallocBuffer = reallocBuffer + vertexCount; - return reallocBuffer; - } - mVertexCount = vertexCount; - mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; - mCleanupMethod = &(cleanup<TYPE>); - - return (TYPE*)mBuffer; - } - - template <class TYPE> - void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) { - int verticesToCopy = srcBuffer.getVertexCount(); - - TYPE* dst = alloc<TYPE>(verticesToCopy); - TYPE* src = (TYPE*)srcBuffer.getBuffer(); - - for (int i = 0; i < verticesToCopy; i++) { - TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset); - } - } - - void* getBuffer() const { return mBuffer; } // shouldn't be const, since not a const ptr? - unsigned int getVertexCount() const { return mVertexCount; } - - template <class TYPE> - void createDegenerateSeparators(int allocSize) { - TYPE* end = (TYPE*)mBuffer + mVertexCount; - for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { - memcpy(degen, degen - 1, sizeof(TYPE)); - memcpy(degen + 1, degen + 2, sizeof(TYPE)); - } - } - -private: - template <class TYPE> - static void cleanup(void* buffer) { - delete[] (TYPE*)buffer; - } - - void* mBuffer; - unsigned int mVertexCount; - - void* mReallocBuffer; // used for multi-allocation - - void (*mCleanupMethod)(void*); -}; - class PathTessellator { public: static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint); diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp new file mode 100644 index 0000000..49a3d2c --- /dev/null +++ b/libs/hwui/ShadowTessellator.cpp @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#define LOG_TAG "OpenGLRenderer" + +#include <math.h> +#include <utils/Log.h> + +#include "AmbientShadow.h" +#include "ShadowTessellator.h" + +namespace android { +namespace uirenderer { + +// TODO: Support path as the input of the polygon instead of the rect's width +// and height. +void ShadowTessellator::tessellateAmbientShadow(float width, float height, + const mat4& casterTransform, VertexBuffer& shadowVertexBuffer) { + + Vector3 pivot(width / 2, height / 2, 0.0f); + casterTransform.mapPoint3d(pivot); + + // TODO: The zScaleFactor need to be mapped to the screen. + float zScaleFactor = 0.5; + Rect blockRect(pivot.x - width * zScaleFactor, pivot.y - height * zScaleFactor, + pivot.x + width * zScaleFactor, pivot.y + height * zScaleFactor); + + // Generate the caster's polygon from the rect. + // TODO: support arbitrary polygon, and the z value need to be computed + // according to the transformation for each vertex. + const int vertexCount = 4; + Vector3 polygon[vertexCount]; + polygon[0].x = blockRect.left; + polygon[0].y = blockRect.top; + polygon[0].z = pivot.z; + polygon[1].x = blockRect.right; + polygon[1].y = blockRect.top; + polygon[1].z = pivot.z; + polygon[2].x = blockRect.right; + polygon[2].y = blockRect.bottom; + polygon[2].z = pivot.z; + polygon[3].x = blockRect.left; + polygon[3].y = blockRect.bottom; + polygon[3].z = pivot.z; + + // A bunch of parameters to tweak the shadow. + // TODO: Allow some of these changable by debug settings or APIs. + const int rays = 120; + const int layers = 2; + const float strength = 0.5; + const float heightFactor = 120; + const float geomFactor = 60; + + AmbientShadow::createAmbientShadow(polygon, vertexCount, rays, layers, strength, + heightFactor, geomFactor, shadowVertexBuffer); + +} + +}; // namespace uirenderer +}; // namespace android diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h new file mode 100644 index 0000000..05cb00c --- /dev/null +++ b/libs/hwui/ShadowTessellator.h @@ -0,0 +1,37 @@ + +/* + * 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. + */ + +#ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H +#define ANDROID_HWUI_SHADOW_TESSELLATOR_H + +#include "Debug.h" +#include "Matrix.h" + +namespace android { +namespace uirenderer { + +class ShadowTessellator { +public: + static void tessellateAmbientShadow(float width, float height, + const mat4& casterTransform, VertexBuffer& shadowVertexBuffer); + +}; // ShadowTessellator + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_SHADOW_TESSELLATOR_H diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h index 497924e..5110272 100644 --- a/libs/hwui/Vector.h +++ b/libs/hwui/Vector.h @@ -107,6 +107,21 @@ struct Vector2 { } }; // class Vector2 +class Vector3 { +public: + float x; + float y; + float z; + + Vector3() : + x(0.0f), y(0.0f), z(0.0f) { + } + + Vector3(float px, float py, float pz) : + x(px), y(py), z(pz) { + } +}; + /////////////////////////////////////////////////////////////////////////////// // Types /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h new file mode 100644 index 0000000..8b6872e --- /dev/null +++ b/libs/hwui/VertexBuffer.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_HWUI_VERTEX_BUFFER_H +#define ANDROID_HWUI_VERTEX_BUFFER_H + + +namespace android { +namespace uirenderer { + +class VertexBuffer { +public: + VertexBuffer(): + mBuffer(0), + mVertexCount(0), + mCleanupMethod(NULL) + {} + + ~VertexBuffer() { + if (mCleanupMethod) mCleanupMethod(mBuffer); + } + + /** + This should be the only method used by the Tessellator. Subsequent calls to + alloc will allocate space within the first allocation (useful if you want to + eventually allocate multiple regions within a single VertexBuffer, such as + with PathTessellator::tesselateLines()) + */ + template <class TYPE> + TYPE* alloc(int vertexCount) { + if (mVertexCount) { + TYPE* reallocBuffer = (TYPE*)mReallocBuffer; + // already have allocated the buffer, re-allocate space within + if (mReallocBuffer != mBuffer) { + // not first re-allocation, leave space for degenerate triangles to separate strips + reallocBuffer += 2; + } + mReallocBuffer = reallocBuffer + vertexCount; + return reallocBuffer; + } + mVertexCount = vertexCount; + mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount]; + mCleanupMethod = &(cleanup<TYPE>); + + return (TYPE*)mBuffer; + } + + template <class TYPE> + void copyInto(const VertexBuffer& srcBuffer, float xOffset, float yOffset) { + int verticesToCopy = srcBuffer.getVertexCount(); + + TYPE* dst = alloc<TYPE>(verticesToCopy); + TYPE* src = (TYPE*)srcBuffer.getBuffer(); + + for (int i = 0; i < verticesToCopy; i++) { + TYPE::copyWithOffset(&dst[i], src[i], xOffset, yOffset); + } + } + + const void* getBuffer() const { return mBuffer; } + unsigned int getVertexCount() const { return mVertexCount; } + + template <class TYPE> + void createDegenerateSeparators(int allocSize) { + TYPE* end = (TYPE*)mBuffer + mVertexCount; + for (TYPE* degen = (TYPE*)mBuffer + allocSize; degen < end; degen += 2 + allocSize) { + memcpy(degen, degen - 1, sizeof(TYPE)); + memcpy(degen + 1, degen + 2, sizeof(TYPE)); + } + } + +private: + template <class TYPE> + static void cleanup(void* buffer) { + delete[] (TYPE*)buffer; + } + + void* mBuffer; + unsigned int mVertexCount; + + void* mReallocBuffer; // used for multi-allocation + + void (*mCleanupMethod)(void*); +}; + +}; // namespace uirenderer +}; // namespace android + +#endif // ANDROID_HWUI_VERTEX_BUFFER_H diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java index de20227..a4d491d8 100644 --- a/media/java/android/media/MediaRouter.java +++ b/media/java/android/media/MediaRouter.java @@ -16,8 +16,6 @@ package android.media; -import com.android.internal.util.Objects; - import android.Manifest; import android.app.ActivityThread; import android.content.BroadcastReceiver; @@ -43,6 +41,7 @@ import android.view.Display; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -493,11 +492,11 @@ public class MediaRouter { boolean volumeChanged = false; boolean presentationDisplayChanged = false; - if (!Objects.equal(route.mName, globalRoute.name)) { + if (!Objects.equals(route.mName, globalRoute.name)) { route.mName = globalRoute.name; changed = true; } - if (!Objects.equal(route.mDescription, globalRoute.description)) { + if (!Objects.equals(route.mDescription, globalRoute.description)) { route.mDescription = globalRoute.description; changed = true; } diff --git a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java index c2461e6..dc9dd79 100644 --- a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java +++ b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java @@ -16,11 +16,11 @@ package com.android.media.remotedisplay; -import com.android.internal.util.Objects; - import android.media.RemoteDisplayState.RemoteDisplayInfo; import android.text.TextUtils; +import java.util.Objects; + /** * Represents a remote display that has been discovered. */ @@ -86,7 +86,7 @@ public class RemoteDisplay { } public void setName(String name) { - if (!Objects.equal(mMutableInfo.name, name)) { + if (!Objects.equals(mMutableInfo.name, name)) { mMutableInfo.name = name; mImmutableInfo = null; } @@ -97,7 +97,7 @@ public class RemoteDisplay { } public void setDescription(String description) { - if (!Objects.equal(mMutableInfo.description, description)) { + if (!Objects.equals(mMutableInfo.description, description)) { mMutableInfo.description = description; mImmutableInfo = null; } diff --git a/opengl/java/android/opengl/EGLLogWrapper.java b/opengl/java/android/opengl/EGLLogWrapper.java index 36e88a2..c677957 100644 --- a/opengl/java/android/opengl/EGLLogWrapper.java +++ b/opengl/java/android/opengl/EGLLogWrapper.java @@ -326,7 +326,7 @@ class EGLLogWrapper implements EGL11 { } public boolean eglSwapBuffers(EGLDisplay display, EGLSurface surface) { - begin("eglInitialize"); + begin("eglSwapBuffers"); arg("display", display); arg("surface", surface); end(); diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java index f6b43c7..f1dca1d 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java @@ -40,7 +40,6 @@ import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.model.RootInfo; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.Objects; import com.google.android.collect.Lists; import com.google.android.collect.Sets; import com.google.common.collect.ArrayListMultimap; @@ -51,6 +50,7 @@ import libcore.io.IoUtils; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -295,7 +295,7 @@ public class RootsCache { private RootInfo getRootLocked(String authority, String rootId) { for (RootInfo root : mRoots.get(authority)) { - if (Objects.equal(root.rootId, rootId)) { + if (Objects.equals(root.rootId, rootId)) { return root; } } @@ -308,7 +308,7 @@ public class RootsCache { synchronized (mLock) { final int rootIcon = root.derivedIcon != 0 ? root.derivedIcon : root.icon; for (RootInfo test : mRoots.get(root.authority)) { - if (Objects.equal(test.rootId, root.rootId)) { + if (Objects.equals(test.rootId, root.rootId)) { continue; } final int testIcon = test.derivedIcon != 0 ? test.derivedIcon : test.icon; diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java index 931dac9..923c79c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java @@ -46,13 +46,13 @@ import android.widget.TextView; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; -import com.android.internal.util.Objects; import com.google.common.collect.Lists; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Objects; /** * Display list of known storage backend roots. @@ -157,7 +157,7 @@ public class RootsFragment extends Fragment { final Object item = mAdapter.getItem(i); if (item instanceof RootItem) { final RootInfo testRoot = ((RootItem) item).root; - if (Objects.equal(testRoot, root)) { + if (Objects.equals(testRoot, root)) { mList.setItemChecked(i, true); return; } diff --git a/preloaded-classes b/preloaded-classes index 98b9e73a..342126d 100644 --- a/preloaded-classes +++ b/preloaded-classes @@ -1428,7 +1428,6 @@ com.android.internal.util.AsyncChannel com.android.internal.util.AsyncChannel$DeathMonitor com.android.internal.util.FastXmlSerializer com.android.internal.util.MemInfoReader -com.android.internal.util.Objects com.android.internal.util.Preconditions com.android.internal.util.XmlUtils com.android.internal.view.ActionBarPolicy diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index 14d1d13..c3ecf5f 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -39,7 +39,6 @@ import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import android.os.Trace; import android.util.Log; import com.android.internal.os.BatteryStatsImpl; -import com.android.internal.util.Objects; import com.android.server.Watchdog; import com.android.server.am.ActivityManagerService.ItemMatcher; import com.android.server.wm.AppTransition; @@ -84,6 +83,7 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Objects; /** * State and management of a single stack of activities. @@ -2392,7 +2392,7 @@ final class ActivityStack { ArrayList<ActivityRecord> activities = r.task.mActivities; for (int index = activities.indexOf(r); index >= 0; --index) { ActivityRecord cur = activities.get(index); - if (!Objects.equal(cur.taskAffinity, r.taskAffinity)) { + if (!Objects.equals(cur.taskAffinity, r.taskAffinity)) { break; } finishActivityLocked(cur, Activity.RESULT_CANCELED, null, "request-affinity", true); diff --git a/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 36ce3a4..186fbe1 100644 --- a/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -108,7 +108,7 @@ import java.util.Set; */ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { - private static final String TAG = "DevicePolicyManagerService"; + private static final String LOG_TAG = "DevicePolicyManagerService"; private static final String DEVICE_POLICIES_XML = "device_policies.xml"; @@ -177,7 +177,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { getSendingUserId()); if (Intent.ACTION_BOOT_COMPLETED.equals(action) || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) { - if (DBG) Slog.v(TAG, "Sending password expiration notifications for action " + if (DBG) Slog.v(LOG_TAG, "Sending password expiration notifications for action " + action + " for user " + userHandle); mHandler.post(new Runnable() { public void run() { @@ -209,6 +209,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { }; static class ActiveAdmin { + private static final String TAG_DISABLE_KEYGUARD_FEATURES = "disable-keyguard-features"; + private static final String TAG_DISABLE_CAMERA = "disable-camera"; + private static final String TAG_ENCRYPTION_REQUESTED = "encryption-requested"; + private static final String TAG_PASSWORD_EXPIRATION_DATE = "password-expiration-date"; + private static final String TAG_PASSWORD_EXPIRATION_TIMEOUT = "password-expiration-timeout"; + private static final String TAG_GLOBAL_PROXY_EXCLUSION_LIST = "global-proxy-exclusion-list"; + private static final String TAG_GLOBAL_PROXY_SPEC = "global-proxy-spec"; + private static final String TAG_SPECIFIES_GLOBAL_PROXY = "specifies-global-proxy"; + private static final String TAG_MAX_FAILED_PASSWORD_WIPE = "max-failed-password-wipe"; + private static final String TAG_MAX_TIME_TO_UNLOCK = "max-time-to-unlock"; + private static final String TAG_MIN_PASSWORD_NONLETTER = "min-password-nonletter"; + private static final String TAG_MIN_PASSWORD_SYMBOLS = "min-password-symbols"; + private static final String TAG_MIN_PASSWORD_NUMERIC = "min-password-numeric"; + private static final String TAG_MIN_PASSWORD_LETTERS = "min-password-letters"; + private static final String TAG_MIN_PASSWORD_LOWERCASE = "min-password-lowercase"; + private static final String TAG_MIN_PASSWORD_UPPERCASE = "min-password-uppercase"; + private static final String TAG_PASSWORD_HISTORY_LENGTH = "password-history-length"; + private static final String TAG_MIN_PASSWORD_LENGTH = "min-password-length"; + private static final String ATTR_VALUE = "value"; + private static final String TAG_PASSWORD_QUALITY = "password-quality"; + private static final String TAG_POLICIES = "policies"; + final DeviceAdminInfo info; int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; @@ -272,103 +294,103 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void writeToXml(XmlSerializer out) throws IllegalArgumentException, IllegalStateException, IOException { - out.startTag(null, "policies"); + out.startTag(null, TAG_POLICIES); info.writePoliciesToXml(out); - out.endTag(null, "policies"); + out.endTag(null, TAG_POLICIES); if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { - out.startTag(null, "password-quality"); - out.attribute(null, "value", Integer.toString(passwordQuality)); - out.endTag(null, "password-quality"); + out.startTag(null, TAG_PASSWORD_QUALITY); + out.attribute(null, ATTR_VALUE, Integer.toString(passwordQuality)); + out.endTag(null, TAG_PASSWORD_QUALITY); if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) { - out.startTag(null, "min-password-length"); - out.attribute(null, "value", Integer.toString(minimumPasswordLength)); - out.endTag(null, "min-password-length"); + out.startTag(null, TAG_MIN_PASSWORD_LENGTH); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLength)); + out.endTag(null, TAG_MIN_PASSWORD_LENGTH); } if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) { - out.startTag(null, "password-history-length"); - out.attribute(null, "value", Integer.toString(passwordHistoryLength)); - out.endTag(null, "password-history-length"); + out.startTag(null, TAG_PASSWORD_HISTORY_LENGTH); + out.attribute(null, ATTR_VALUE, Integer.toString(passwordHistoryLength)); + out.endTag(null, TAG_PASSWORD_HISTORY_LENGTH); } if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) { - out.startTag(null, "min-password-uppercase"); - out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase)); - out.endTag(null, "min-password-uppercase"); + out.startTag(null, TAG_MIN_PASSWORD_UPPERCASE); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordUpperCase)); + out.endTag(null, TAG_MIN_PASSWORD_UPPERCASE); } if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) { - out.startTag(null, "min-password-lowercase"); - out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase)); - out.endTag(null, "min-password-lowercase"); + out.startTag(null, TAG_MIN_PASSWORD_LOWERCASE); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLowerCase)); + out.endTag(null, TAG_MIN_PASSWORD_LOWERCASE); } if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) { - out.startTag(null, "min-password-letters"); - out.attribute(null, "value", Integer.toString(minimumPasswordLetters)); - out.endTag(null, "min-password-letters"); + out.startTag(null, TAG_MIN_PASSWORD_LETTERS); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordLetters)); + out.endTag(null, TAG_MIN_PASSWORD_LETTERS); } if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) { - out.startTag(null, "min-password-numeric"); - out.attribute(null, "value", Integer.toString(minimumPasswordNumeric)); - out.endTag(null, "min-password-numeric"); + out.startTag(null, TAG_MIN_PASSWORD_NUMERIC); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNumeric)); + out.endTag(null, TAG_MIN_PASSWORD_NUMERIC); } if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) { - out.startTag(null, "min-password-symbols"); - out.attribute(null, "value", Integer.toString(minimumPasswordSymbols)); - out.endTag(null, "min-password-symbols"); + out.startTag(null, TAG_MIN_PASSWORD_SYMBOLS); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordSymbols)); + out.endTag(null, TAG_MIN_PASSWORD_SYMBOLS); } if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) { - out.startTag(null, "min-password-nonletter"); - out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter)); - out.endTag(null, "min-password-nonletter"); + out.startTag(null, TAG_MIN_PASSWORD_NONLETTER); + out.attribute(null, ATTR_VALUE, Integer.toString(minimumPasswordNonLetter)); + out.endTag(null, TAG_MIN_PASSWORD_NONLETTER); } } if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) { - out.startTag(null, "max-time-to-unlock"); - out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); - out.endTag(null, "max-time-to-unlock"); + out.startTag(null, TAG_MAX_TIME_TO_UNLOCK); + out.attribute(null, ATTR_VALUE, Long.toString(maximumTimeToUnlock)); + out.endTag(null, TAG_MAX_TIME_TO_UNLOCK); } if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) { - out.startTag(null, "max-failed-password-wipe"); - out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); - out.endTag(null, "max-failed-password-wipe"); + out.startTag(null, TAG_MAX_FAILED_PASSWORD_WIPE); + out.attribute(null, ATTR_VALUE, Integer.toString(maximumFailedPasswordsForWipe)); + out.endTag(null, TAG_MAX_FAILED_PASSWORD_WIPE); } if (specifiesGlobalProxy) { - out.startTag(null, "specifies-global-proxy"); - out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy)); - out.endTag(null, "specifies_global_proxy"); + out.startTag(null, TAG_SPECIFIES_GLOBAL_PROXY); + out.attribute(null, ATTR_VALUE, Boolean.toString(specifiesGlobalProxy)); + out.endTag(null, TAG_SPECIFIES_GLOBAL_PROXY); if (globalProxySpec != null) { - out.startTag(null, "global-proxy-spec"); - out.attribute(null, "value", globalProxySpec); - out.endTag(null, "global-proxy-spec"); + out.startTag(null, TAG_GLOBAL_PROXY_SPEC); + out.attribute(null, ATTR_VALUE, globalProxySpec); + out.endTag(null, TAG_GLOBAL_PROXY_SPEC); } if (globalProxyExclusionList != null) { - out.startTag(null, "global-proxy-exclusion-list"); - out.attribute(null, "value", globalProxyExclusionList); - out.endTag(null, "global-proxy-exclusion-list"); + out.startTag(null, TAG_GLOBAL_PROXY_EXCLUSION_LIST); + out.attribute(null, ATTR_VALUE, globalProxyExclusionList); + out.endTag(null, TAG_GLOBAL_PROXY_EXCLUSION_LIST); } } if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) { - out.startTag(null, "password-expiration-timeout"); - out.attribute(null, "value", Long.toString(passwordExpirationTimeout)); - out.endTag(null, "password-expiration-timeout"); + out.startTag(null, TAG_PASSWORD_EXPIRATION_TIMEOUT); + out.attribute(null, ATTR_VALUE, Long.toString(passwordExpirationTimeout)); + out.endTag(null, TAG_PASSWORD_EXPIRATION_TIMEOUT); } if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) { - out.startTag(null, "password-expiration-date"); - out.attribute(null, "value", Long.toString(passwordExpirationDate)); - out.endTag(null, "password-expiration-date"); + out.startTag(null, TAG_PASSWORD_EXPIRATION_DATE); + out.attribute(null, ATTR_VALUE, Long.toString(passwordExpirationDate)); + out.endTag(null, TAG_PASSWORD_EXPIRATION_DATE); } if (encryptionRequested) { - out.startTag(null, "encryption-requested"); - out.attribute(null, "value", Boolean.toString(encryptionRequested)); - out.endTag(null, "encryption-requested"); + out.startTag(null, TAG_ENCRYPTION_REQUESTED); + out.attribute(null, ATTR_VALUE, Boolean.toString(encryptionRequested)); + out.endTag(null, TAG_ENCRYPTION_REQUESTED); } if (disableCamera) { - out.startTag(null, "disable-camera"); - out.attribute(null, "value", Boolean.toString(disableCamera)); - out.endTag(null, "disable-camera"); + out.startTag(null, TAG_DISABLE_CAMERA); + out.attribute(null, ATTR_VALUE, Boolean.toString(disableCamera)); + out.endTag(null, TAG_DISABLE_CAMERA); } if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) { - out.startTag(null, "disable-keyguard-features"); - out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures)); - out.endTag(null, "disable-keyguard-features"); + out.startTag(null, TAG_DISABLE_KEYGUARD_FEATURES); + out.attribute(null, ATTR_VALUE, Integer.toString(disabledKeyguardFeatures)); + out.endTag(null, TAG_DISABLE_KEYGUARD_FEATURES); } } @@ -382,67 +404,67 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { continue; } String tag = parser.getName(); - if ("policies".equals(tag)) { + if (TAG_POLICIES.equals(tag)) { info.readPoliciesFromXml(parser); - } else if ("password-quality".equals(tag)) { + } else if (TAG_PASSWORD_QUALITY.equals(tag)) { passwordQuality = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-length".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LENGTH.equals(tag)) { minimumPasswordLength = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("password-history-length".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_PASSWORD_HISTORY_LENGTH.equals(tag)) { passwordHistoryLength = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-uppercase".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_UPPERCASE.equals(tag)) { minimumPasswordUpperCase = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-lowercase".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LOWERCASE.equals(tag)) { minimumPasswordLowerCase = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-letters".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_LETTERS.equals(tag)) { minimumPasswordLetters = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-numeric".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_NUMERIC.equals(tag)) { minimumPasswordNumeric = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-symbols".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_SYMBOLS.equals(tag)) { minimumPasswordSymbols = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("min-password-nonletter".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MIN_PASSWORD_NONLETTER.equals(tag)) { minimumPasswordNonLetter = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("max-time-to-unlock".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MAX_TIME_TO_UNLOCK.equals(tag)) { maximumTimeToUnlock = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("max-failed-password-wipe".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_MAX_FAILED_PASSWORD_WIPE.equals(tag)) { maximumFailedPasswordsForWipe = Integer.parseInt( - parser.getAttributeValue(null, "value")); - } else if ("specifies-global-proxy".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_SPECIFIES_GLOBAL_PROXY.equals(tag)) { specifiesGlobalProxy = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("global-proxy-spec".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_GLOBAL_PROXY_SPEC.equals(tag)) { globalProxySpec = - parser.getAttributeValue(null, "value"); - } else if ("global-proxy-exclusion-list".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE); + } else if (TAG_GLOBAL_PROXY_EXCLUSION_LIST.equals(tag)) { globalProxyExclusionList = - parser.getAttributeValue(null, "value"); - } else if ("password-expiration-timeout".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE); + } else if (TAG_PASSWORD_EXPIRATION_TIMEOUT.equals(tag)) { passwordExpirationTimeout = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("password-expiration-date".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_PASSWORD_EXPIRATION_DATE.equals(tag)) { passwordExpirationDate = Long.parseLong( - parser.getAttributeValue(null, "value")); - } else if ("encryption-requested".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_ENCRYPTION_REQUESTED.equals(tag)) { encryptionRequested = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("disable-camera".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_DISABLE_CAMERA.equals(tag)) { disableCamera = Boolean.parseBoolean( - parser.getAttributeValue(null, "value")); - } else if ("disable-keyguard-features".equals(tag)) { + parser.getAttributeValue(null, ATTR_VALUE)); + } else if (TAG_DISABLE_KEYGUARD_FEATURES.equals(tag)) { disabledKeyguardFeatures = Integer.parseInt( - parser.getAttributeValue(null, "value")); + parser.getAttributeValue(null, ATTR_VALUE)); } else { - Slog.w(TAG, "Unknown admin tag: " + tag); + Slog.w(LOG_TAG, "Unknown admin tag: " + tag); } XmlUtils.skipCurrentTag(parser); } @@ -504,7 +526,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void handlePackagesChanged(int userHandle) { boolean removed = false; - if (DBG) Slog.d(TAG, "Handling package changes for user " + userHandle); + if (DBG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle); DevicePolicyData policy = getUserData(userHandle); IPackageManager pm = AppGlobals.getPackageManager(); for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { @@ -576,7 +598,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { void removeUserData(int userHandle) { synchronized (this) { if (userHandle == UserHandle.USER_OWNER) { - Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring."); + Slog.w(LOG_TAG, "Tried to remove device policy file for user 0! Ignoring."); return; } DevicePolicyData policy = mUserData.get(userHandle); @@ -586,7 +608,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { File policyFile = new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML); policyFile.delete(); - Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath()); + Slog.i(LOG_TAG, "Removed device policy file " + policyFile.getAbsolutePath()); } } @@ -783,10 +805,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { return new DeviceAdminInfo(mContext, infos.get(0)); } catch (XmlPullParserException e) { - Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); + Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, + e); return null; } catch (IOException e) { - Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e); + Slog.w(LOG_TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, + e); return null; } } @@ -913,7 +937,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ComponentName.unflattenFromString(name), userHandle); if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid) != userHandle)) { - Slog.w(TAG, "findAdmin returned an incorrect uid " + Slog.w(LOG_TAG, "findAdmin returned an incorrect uid " + dai.getActivityInfo().applicationInfo.uid + " for user " + userHandle); } @@ -924,7 +948,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { policy.mAdminList.add(ap); } } catch (RuntimeException e) { - Slog.w(TAG, "Failed loading admin " + name, e); + Slog.w(LOG_TAG, "Failed loading admin " + name, e); } } else if ("failed-password-attempts".equals(tag)) { policy.mFailedPasswordAttempts = Integer.parseInt( @@ -953,22 +977,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { parser.getAttributeValue(null, "nonletter")); XmlUtils.skipCurrentTag(parser); } else { - Slog.w(TAG, "Unknown tag: " + tag); + Slog.w(LOG_TAG, "Unknown tag: " + tag); XmlUtils.skipCurrentTag(parser); } } } catch (NullPointerException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (NumberFormatException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (XmlPullParserException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (FileNotFoundException e) { // Don't be noisy, this is normal if we haven't defined any policies. } catch (IOException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } catch (IndexOutOfBoundsException e) { - Slog.w(TAG, "failed parsing " + file + " " + e); + Slog.w(LOG_TAG, "failed parsing " + file + " " + e); } try { if (stream != null) { @@ -984,7 +1008,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // never normally happen. LockPatternUtils utils = new LockPatternUtils(mContext); if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) { - Slog.w(TAG, "Active password quality 0x" + Slog.w(LOG_TAG, "Active password quality 0x" + Integer.toHexString(policy.mActivePasswordQuality) + " does not match actual quality 0x" + Integer.toHexString(utils.getActivePasswordQuality())); @@ -1028,7 +1052,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } if (!haveOwner) { - Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner + Slog.w(LOG_TAG, "Previous password owner " + policy.mPasswordOwner + " no longer active; disabling"); policy.mPasswordOwner = -1; } @@ -1048,7 +1072,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { long token = Binder.clearCallingIdentity(); try { String value = cameraDisabled ? "1" : "0"; - if (DBG) Slog.v(TAG, "Change in camera state [" + if (DBG) Slog.v(LOG_TAG, "Change in camera state [" + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value); SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value); } finally { @@ -1164,7 +1188,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { long ident = Binder.clearCallingIdentity(); try { - if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { + if (!refreshing + && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { throw new IllegalArgumentException("Admin is already added"); } ActiveAdmin newAdmin = new ActiveAdmin(info); @@ -1434,7 +1459,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ap.passwordExpirationDate = expiration; ap.passwordExpirationTimeout = timeout; if (timeout > 0L) { - Slog.w(TAG, "setPasswordExpiration(): password will expire on " + Slog.w(LOG_TAG, "setPasswordExpiration(): password will expire on " + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT) .format(new Date(expiration))); } @@ -1780,11 +1805,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return true; } return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle) - && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle) - && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle) - && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle) - && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle) - && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle); + && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle) + && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle) + && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle) + && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle) + && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle); } } @@ -1862,7 +1887,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int realQuality = LockPatternUtils.computePasswordQuality(password); if (realQuality < quality && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { - Slog.w(TAG, "resetPassword: password quality 0x" + Slog.w(LOG_TAG, "resetPassword: password quality 0x" + Integer.toHexString(realQuality) + " does not meet required quality 0x" + Integer.toHexString(quality)); @@ -1872,7 +1897,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int length = getPasswordMinimumLength(null, userHandle); if (password.length() < length) { - Slog.w(TAG, "resetPassword: password length " + password.length() + Slog.w(LOG_TAG, "resetPassword: password length " + password.length() + " does not meet required length " + length); return false; } @@ -1901,40 +1926,40 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } int neededLetters = getPasswordMinimumLetters(null, userHandle); if(letters < neededLetters) { - Slog.w(TAG, "resetPassword: number of letters " + letters + Slog.w(LOG_TAG, "resetPassword: number of letters " + letters + " does not meet required number of letters " + neededLetters); return false; } int neededNumbers = getPasswordMinimumNumeric(null, userHandle); if (numbers < neededNumbers) { - Slog.w(TAG, "resetPassword: number of numerical digits " + numbers + Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + numbers + " does not meet required number of numerical digits " + neededNumbers); return false; } int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle); if (lowercase < neededLowerCase) { - Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase + Slog.w(LOG_TAG, "resetPassword: number of lowercase letters " + lowercase + " does not meet required number of lowercase letters " + neededLowerCase); return false; } int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle); if (uppercase < neededUpperCase) { - Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase + Slog.w(LOG_TAG, "resetPassword: number of uppercase letters " + uppercase + " does not meet required number of uppercase letters " + neededUpperCase); return false; } int neededSymbols = getPasswordMinimumSymbols(null, userHandle); if (symbols < neededSymbols) { - Slog.w(TAG, "resetPassword: number of special symbols " + symbols + Slog.w(LOG_TAG, "resetPassword: number of special symbols " + symbols + " does not meet required number of special symbols " + neededSymbols); return false; } int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle); if (nonletter < neededNonLetter) { - Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter + Slog.w(LOG_TAG, "resetPassword: number of non-letter characters " + nonletter + " does not meet required number of non-letter characters " + neededNonLetter); return false; @@ -1945,7 +1970,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int callingUid = Binder.getCallingUid(); DevicePolicyData policy = getUserData(userHandle); if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) { - Slog.w(TAG, "resetPassword: already set by another uid and not entered by user"); + Slog.w(LOG_TAG, "resetPassword: already set by another uid and not entered by user"); return false; } @@ -2011,7 +2036,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs); } catch (RemoteException e) { - Slog.w(TAG, "Failure talking with power manager", e); + Slog.w(LOG_TAG, "Failure talking with power manager", e); } } finally { Binder.restoreCallingIdentity(ident); @@ -2086,10 +2111,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { X509Certificate cert = parseCert(certBuffer); pemCert = Credentials.convertToPem(cert); } catch (CertificateException ce) { - Log.e(TAG, "Problem converting cert", ce); + Log.e(LOG_TAG, "Problem converting cert", ce); return false; } catch (IOException ioe) { - Log.e(TAG, "Problem reading cert", ioe); + Log.e(LOG_TAG, "Problem reading cert", ioe); return false; } try { @@ -2104,7 +2129,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } catch (InterruptedException e1) { - Log.w(TAG, "installCaCertsToKeyChain(): ", e1); + Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1); Thread.currentThread().interrupt(); } return false; @@ -2125,10 +2150,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { X509Certificate cert = parseCert(certBuffer); alias = certStore.getCertificateAlias(cert); } catch (CertificateException ce) { - Log.e(TAG, "Problem creating X509Certificate", ce); + Log.e(LOG_TAG, "Problem creating X509Certificate", ce); return; } catch (IOException ioe) { - Log.e(TAG, "Problem reading certificate", ioe); + Log.e(LOG_TAG, "Problem reading certificate", ioe); return; } try { @@ -2137,13 +2162,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { service.deleteCaCertificate(alias); } catch (RemoteException e) { - Log.e(TAG, "from CaCertUninstaller: ", e); + Log.e(LOG_TAG, "from CaCertUninstaller: ", e); } finally { keyChainConnection.close(); keyChainConnection = null; } } catch (InterruptedException ie) { - Log.w(TAG, "CaCertUninstaller: ", ie); + Log.w(LOG_TAG, "CaCertUninstaller: ", ie); Thread.currentThread().interrupt(); } } @@ -2164,7 +2189,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { try { RecoverySystem.rebootWipeUserData(mContext); } catch (IOException e) { - Slog.w(TAG, "Failed requesting data wipe", e); + Slog.w(LOG_TAG, "Failed requesting data wipe", e); } } } @@ -2255,8 +2280,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters || p.mActivePasswordUpperCase != uppercase - || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers - || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) { + || p.mActivePasswordLowerCase != lowercase + || p.mActivePasswordNumeric != numbers + || p.mActivePasswordSymbols != symbols + || p.mActivePasswordNonLetter != nonletter) { long ident = Binder.clearCallingIdentity(); try { p.mActivePasswordQuality = quality; @@ -2378,7 +2405,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // If the user is not the owner, don't set the global proxy. Fail silently. if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - Slog.w(TAG, "Only the owner is allowed to set the global proxy. User " + Slog.w(LOG_TAG, "Only the owner is allowed to set the global proxy. User " + userHandle + " is not permitted."); return null; } @@ -2459,7 +2486,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ProxyProperties proxyProperties = new ProxyProperties(data[0], proxyPort, exclusionList); if (!proxyProperties.isValid()) { - Slog.e(TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString()); + Slog.e(LOG_TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString()); return; } Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]); @@ -2485,7 +2512,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Only owner can set storage encryption if (userHandle != UserHandle.USER_OWNER || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { - Slog.w(TAG, "Only owner is allowed to set storage encryption. User " + Slog.w(LOG_TAG, "Only owner is allowed to set storage encryption. User " + UserHandle.getCallingUserId() + " is not permitted."); return 0; } @@ -2871,7 +2898,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } } catch (NameNotFoundException nnfe) { - Slog.w(TAG, "Device Owner package " + packageName + " not installed."); + Slog.w(LOG_TAG, "Device Owner package " + packageName + " not installed."); } return false; } @@ -2896,9 +2923,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mOwnerName = parser.getAttributeValue(null, ATTR_NAME); input.close(); } catch (XmlPullParserException xppe) { - Slog.e(TAG, "Error parsing device-owner file\n" + xppe); + Slog.e(LOG_TAG, "Error parsing device-owner file\n" + xppe); } catch (IOException ioe) { - Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe); + Slog.e(LOG_TAG, "IO Exception when reading device-owner file\n" + ioe); } } @@ -2926,7 +2953,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { out.flush(); file.finishWrite(output); } catch (IOException ioe) { - Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe); + Slog.e(LOG_TAG, "IO Exception when writing device-owner file\n" + ioe); } } } diff --git a/services/java/com/android/server/media/MediaRouterService.java b/services/java/com/android/server/media/MediaRouterService.java index a31695b..f91ea8c 100644 --- a/services/java/com/android/server/media/MediaRouterService.java +++ b/services/java/com/android/server/media/MediaRouterService.java @@ -16,7 +16,6 @@ package com.android.server.media; -import com.android.internal.util.Objects; import com.android.server.Watchdog; import android.Manifest; @@ -52,6 +51,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; /** * Provides a mechanism for discovering media routes and manages media playback @@ -384,7 +384,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub ClientRecord clientRecord = mAllClientRecords.get(client.asBinder()); if (clientRecord != null) { final String oldRouteId = clientRecord.mSelectedRouteId; - if (!Objects.equal(routeId, oldRouteId)) { + if (!Objects.equals(routeId, oldRouteId)) { if (DEBUG) { Slog.d(TAG, clientRecord + ": Set selected route, routeId=" + routeId + ", oldRouteId=" + oldRouteId @@ -1257,12 +1257,12 @@ public final class MediaRouterService extends IMediaRouterService.Stub mDescriptor = descriptor; if (descriptor != null) { final String name = computeName(descriptor); - if (!Objects.equal(mMutableInfo.name, name)) { + if (!Objects.equals(mMutableInfo.name, name)) { mMutableInfo.name = name; changed = true; } final String description = computeDescription(descriptor); - if (!Objects.equal(mMutableInfo.description, description)) { + if (!Objects.equals(mMutableInfo.description, description)) { mMutableInfo.description = description; changed = true; } diff --git a/services/java/com/android/server/media/RemoteDisplayProviderProxy.java b/services/java/com/android/server/media/RemoteDisplayProviderProxy.java index b248ee0..a5fe9f2 100644 --- a/services/java/com/android/server/media/RemoteDisplayProviderProxy.java +++ b/services/java/com/android/server/media/RemoteDisplayProviderProxy.java @@ -16,8 +16,6 @@ package com.android.server.media; -import com.android.internal.util.Objects; - import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -35,6 +33,7 @@ import android.util.Slog; import java.io.PrintWriter; import java.lang.ref.WeakReference; +import java.util.Objects; /** * Maintains a connection to a particular remote display provider service. @@ -101,7 +100,7 @@ final class RemoteDisplayProviderProxy implements ServiceConnection { } public void setSelectedDisplay(String id) { - if (!Objects.equal(mSelectedDisplayId, id)) { + if (!Objects.equals(mSelectedDisplayId, id)) { if (mConnectionReady && mSelectedDisplayId != null) { mActiveConnection.disconnect(mSelectedDisplayId); } @@ -293,7 +292,7 @@ final class RemoteDisplayProviderProxy implements ServiceConnection { } private void setDisplayState(RemoteDisplayState state) { - if (!Objects.equal(mDisplayState, state)) { + if (!Objects.equals(mDisplayState, state)) { mDisplayState = state; if (!mScheduledDisplayStateChangedCallback) { mScheduledDisplayStateChangedCallback = true; diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index d568b11..eb7cc4c 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -133,7 +133,6 @@ import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.IndentingPrintWriter; -import com.android.internal.util.Objects; import com.google.android.collect.Lists; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -155,6 +154,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import libcore.io.IoUtils; @@ -688,7 +688,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // mobile templates are relevant when SIM is ready and // subscriberId matches. if (tele.getSimState() == SIM_STATE_READY) { - return Objects.equal(tele.getSubscriberId(), template.getSubscriberId()); + return Objects.equals(tele.getSubscriberId(), template.getSubscriberId()); } else { return false; } @@ -946,7 +946,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // TODO: offer more granular control over radio states once // 4965893 is available. if (tele.getSimState() == SIM_STATE_READY - && Objects.equal(tele.getSubscriberId(), template.getSubscriberId())) { + && Objects.equals(tele.getSubscriberId(), template.getSubscriberId())) { setPolicyDataEnable(TYPE_MOBILE, enabled); setPolicyDataEnable(TYPE_WIMAX, enabled); } diff --git a/services/java/com/android/server/net/NetworkStatsCollection.java b/services/java/com/android/server/net/NetworkStatsCollection.java index 3169035..475482f 100644 --- a/services/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/java/com/android/server/net/NetworkStatsCollection.java @@ -34,7 +34,6 @@ import android.util.AtomicFile; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; -import com.android.internal.util.Objects; import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -50,6 +49,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import libcore.io.IoUtils; @@ -508,7 +508,7 @@ public class NetworkStatsCollection implements FileRotator.Reader { this.uid = uid; this.set = set; this.tag = tag; - hashCode = Objects.hashCode(ident, uid, set, tag); + hashCode = Objects.hash(ident, uid, set, tag); } @Override @@ -521,7 +521,7 @@ public class NetworkStatsCollection implements FileRotator.Reader { if (obj instanceof Key) { final Key key = (Key) obj; return uid == key.uid && set == key.set && tag == key.tag - && Objects.equal(ident, key.ident); + && Objects.equals(ident, key.ident); } return false; } |