diff options
27 files changed, 349 insertions, 56 deletions
diff --git a/api/current.txt b/api/current.txt index 85a3fc526480..ffdd9f73f1ae 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5511,8 +5511,8 @@ package android.app.admin { field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM = "android.app.extra.DEVICE_ADMIN_PACKAGE_CHECKSUM"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER = "android.app.extra.DEVICE_ADMIN_PACKAGE_DOWNLOAD_COOKIE_HEADER"; field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION = "android.app.extra.DEVICE_ADMIN_PACKAGE_DOWNLOAD_LOCATION"; - field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.DEVICE_ADMIN_PACKAGE_NAME"; - field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.MANAGED_PROFILE_EMAIL_ADDRESS"; + field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "android.app.extra.deviceAdminPackageName"; + field public static final java.lang.String EXTRA_PROVISIONING_EMAIL_ADDRESS = "android.app.extra.ManagedProfileEmailAddress"; field public static final java.lang.String EXTRA_PROVISIONING_LOCALE = "android.app.extra.LOCALE"; field public static final java.lang.String EXTRA_PROVISIONING_LOCAL_TIME = "android.app.extra.LOCAL_TIME"; field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.TIME_ZONE"; @@ -8902,6 +8902,7 @@ package android.content.pm { field public static final java.lang.String FEATURE_SENSOR_COMPASS = "android.hardware.sensor.compass"; field public static final java.lang.String FEATURE_SENSOR_GYROSCOPE = "android.hardware.sensor.gyroscope"; field public static final java.lang.String FEATURE_SENSOR_HEART_RATE = "android.hardware.sensor.heartrate"; + field public static final java.lang.String FEATURE_SENSOR_HEART_RATE_ECG = "android.hardware.sensor.heartrate.ecg"; field public static final java.lang.String FEATURE_SENSOR_LIGHT = "android.hardware.sensor.light"; field public static final java.lang.String FEATURE_SENSOR_PROXIMITY = "android.hardware.sensor.proximity"; field public static final java.lang.String FEATURE_SENSOR_RELATIVE_HUMIDITY = "android.hardware.sensor.relative_humidity"; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 41bbb87e55e9..b17309f16d52 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -126,7 +126,7 @@ public class DevicePolicyManager { * message containing an Nfc record with MIME type {@link #MIME_TYPE_PROVISIONING_NFC}. */ public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME - = "android.app.extra.DEVICE_ADMIN_PACKAGE_NAME"; + = "android.app.extra.deviceAdminPackageName"; /** * A String extra holding the default name of the profile that is created during managed profile @@ -149,7 +149,7 @@ public class DevicePolicyManager { * It is usually used to avoid that the user has to enter their email address twice. */ public static final String EXTRA_PROVISIONING_EMAIL_ADDRESS - = "android.app.extra.MANAGED_PROFILE_EMAIL_ADDRESS"; + = "android.app.extra.ManagedProfileEmailAddress"; /** * A String extra holding the time zone {@link android.app.AlarmManager} that the device diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 56b71643f5df..5492775d8f68 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1217,6 +1217,14 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and + * {@link #hasSystemFeature}: The heart rate sensor on this device is an Electrocargiogram. + */ + @SdkConstant(SdkConstantType.FEATURE) + public static final String FEATURE_SENSOR_HEART_RATE_ECG = + "android.hardware.sensor.heartrate.ecg"; + + /** + * Feature for {@link #getSystemAvailableFeatures} and * {@link #hasSystemFeature}: The device includes a relative humidity sensor. */ @SdkConstant(SdkConstantType.FEATURE) diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index d19418b37940..e63fd0703339 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -533,6 +533,18 @@ public final class Configuration implements Parcelable, Comparable<Configuration public static final int DENSITY_DPI_UNDEFINED = 0; /** + * Value for {@link #densityDpi} for resources that scale to any density (vector drawables). + * {@hide} + */ + public static final int DENSITY_DPI_ANY = 0xfffe; + + /** + * Value for {@link #densityDpi} for resources that are not meant to be scaled. + * {@hide} + */ + public static final int DENSITY_DPI_NONE = 0xffff; + + /** * The target screen density being rendered to, * corresponding to * <a href="{@docRoot}guide/topics/resources/providing-resources.html#DensityQualifier">density</a> @@ -1453,7 +1465,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration } switch (config.densityDpi) { - case 0: + case DENSITY_DPI_UNDEFINED: break; case 120: parts.add("ldpi"); @@ -1476,6 +1488,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration case 640: parts.add("xxxhdpi"); break; + case DENSITY_DPI_ANY: + parts.add("anydpi"); + break; + case DENSITY_DPI_NONE: + parts.add("nodpi"); default: parts.add(config.densityDpi + "dpi"); break; diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index e02aa5e5560c..6146fff58d50 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -66,6 +66,7 @@ static void Shader_setLocalMatrix(JNIEnv* env, jobject o, jlong shaderHandle, jl } else { shader->resetLocalMatrix(); } + shader->setGenerationID(shader->getGenerationID() + 1); } } diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 9ac6927ca6aa..042da5b250d5 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -119,7 +119,7 @@ import java.util.Stack; * <dd>Defines path string. This is using exactly same format as "d" attribute * in the SVG's path data. This is defined in the viewport space.</dd> * <dt><code>android:fillColor</code></dt> - * <dd>Defines the color to fill the path (black if not present).</dd> + * <dd>Defines the color to fill the path (none if not present).</dd> * <dt><code>android:strokeColor</code></dt> * <dd>Defines the color to draw the path outline (none if not present).</dd> * <dt><code>android:strokeWidth</code></dt> @@ -862,7 +862,7 @@ public class VectorDrawable extends Drawable { } mRenderPath.addPath(path, mFinalPathMatrix); - if (fullPath.mFillColor != 0) { + if (fullPath.mFillColor != Color.TRANSPARENT) { if (mFillPaint == null) { mFillPaint = new Paint(); mFillPaint.setColorFilter(mColorFilter); @@ -873,7 +873,7 @@ public class VectorDrawable extends Drawable { canvas.drawPath(mRenderPath, mFillPaint); } - if (fullPath.mStrokeColor != 0) { + if (fullPath.mStrokeColor != Color.TRANSPARENT) { if (mStrokePaint == null) { mStrokePaint = new Paint(); mStrokePaint.setColorFilter(mColorFilter); @@ -1237,9 +1237,9 @@ public class VectorDrawable extends Drawable { // Variables below need to be copied (deep copy if applicable) for mutation. private int[] mThemeAttrs; - int mStrokeColor = 0; + int mStrokeColor = Color.TRANSPARENT; float mStrokeWidth = 0; - int mFillColor = Color.BLACK; + int mFillColor = Color.TRANSPARENT; int mFillRule; float mTrimPathStart = 0; float mTrimPathEnd = 1; diff --git a/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 1af497cfb2e4..11568d280c24 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -954,6 +954,7 @@ struct ResTable_config DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH, DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH, DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH, + DENSITY_ANY = ACONFIGURATION_DENSITY_ANY, DENSITY_NONE = ACONFIGURATION_DENSITY_NONE }; diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index 239d682d1c8c..3f014ef5de1e 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -2206,13 +2206,30 @@ bool ResTable_config::isBetterThan(const ResTable_config& o, if (screenType || o.screenType) { if (density != o.density) { - // density is tough. Any density is potentially useful + // Use the system default density (DENSITY_MEDIUM, 160dpi) if none specified. + const int thisDensity = density ? density : int(ResTable_config::DENSITY_MEDIUM); + const int otherDensity = o.density ? o.density : int(ResTable_config::DENSITY_MEDIUM); + + // We always prefer DENSITY_ANY over scaling a density bucket. + if (thisDensity == ResTable_config::DENSITY_ANY) { + return true; + } else if (otherDensity == ResTable_config::DENSITY_ANY) { + return false; + } + + int requestedDensity = requested->density; + if (requested->density == 0 || + requested->density == ResTable_config::DENSITY_ANY) { + requestedDensity = ResTable_config::DENSITY_MEDIUM; + } + + // DENSITY_ANY is now dealt with. We should look to + // pick a density bucket and potentially scale it. + // Any density is potentially useful // because the system will scale it. Scaling down // is generally better than scaling up. - // Default density counts as 160dpi (the system default) - // TODO - remove 160 constants - int h = (density?density:160); - int l = (o.density?o.density:160); + int h = thisDensity; + int l = otherDensity; bool bImBigger = true; if (l > h) { int t = h; @@ -2221,17 +2238,16 @@ bool ResTable_config::isBetterThan(const ResTable_config& o, bImBigger = false; } - int reqValue = (requested->density?requested->density:160); - if (reqValue >= h) { + if (requestedDensity >= h) { // requested value higher than both l and h, give h return bImBigger; } - if (l >= reqValue) { + if (l >= requestedDensity) { // requested value lower than both l and h, give l return !bImBigger; } // saying that scaling down is 2x better than up - if (((2 * l) - reqValue) * h > reqValue * reqValue) { + if (((2 * l) - requestedDensity) * h > requestedDensity * requestedDensity) { return !bImBigger; } else { return bImBigger; @@ -2702,6 +2718,9 @@ String8 ResTable_config::toString() const { case ResTable_config::DENSITY_NONE: res.append("nodpi"); break; + case ResTable_config::DENSITY_ANY: + res.append("anydpi"); + break; default: res.appendFormat("%ddpi", dtohs(density)); break; diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk index 4ff6eecf1685..a10c38761fbd 100644 --- a/libs/androidfw/tests/Android.mk +++ b/libs/androidfw/tests/Android.mk @@ -21,8 +21,9 @@ LOCAL_PATH:= $(call my-dir) testFiles := \ ByteBucketArray_test.cpp \ + Config_test.cpp \ + ConfigLocale_test.cpp \ Idmap_test.cpp \ - ResourceTypes_test.cpp \ ResTable_test.cpp \ Split_test.cpp \ TypeWrappers_test.cpp \ diff --git a/libs/androidfw/tests/ResourceTypes_test.cpp b/libs/androidfw/tests/ConfigLocale_test.cpp index f00a2d9ea6e3..49995942a562 100644 --- a/libs/androidfw/tests/ResourceTypes_test.cpp +++ b/libs/androidfw/tests/ConfigLocale_test.cpp @@ -21,7 +21,7 @@ #include <gtest/gtest.h> namespace android { -TEST(ResourceTypesTest, ResourceConfig_packAndUnpack2LetterLanguage) { +TEST(ConfigLocaleTest, packAndUnpack2LetterLanguage) { ResTable_config config; config.packLanguage("en"); @@ -44,7 +44,7 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack2LetterLanguage) { EXPECT_EQ(0, out[3]); } -TEST(ResourceTypesTest, ResourceConfig_packAndUnpack2LetterRegion) { +TEST(ConfigLocaleTest, packAndUnpack2LetterRegion) { ResTable_config config; config.packRegion("US"); @@ -59,7 +59,7 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack2LetterRegion) { EXPECT_EQ(0, out[3]); } -TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguage) { +TEST(ConfigLocaleTest, packAndUnpack3LetterLanguage) { ResTable_config config; config.packLanguage("eng"); @@ -75,7 +75,7 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguage) { EXPECT_EQ(0, out[3]); } -TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguageAtOffset16) { +TEST(ConfigLocaleTest, packAndUnpack3LetterLanguageAtOffset16) { ResTable_config config; config.packLanguage("tgp"); @@ -88,8 +88,8 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguageAtOffset16) { // which is equivalent to: // 1 [0] [1] [2] // 1-01111-00110-10011 - EXPECT_EQ(0xbc, config.language[0]); - EXPECT_EQ(0xd3, config.language[1]); + EXPECT_EQ(char(0xbc), config.language[0]); + EXPECT_EQ(char(0xd3), config.language[1]); char out[4] = { 1, 1, 1, 1}; config.unpackLanguage(out); @@ -99,7 +99,7 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguageAtOffset16) { EXPECT_EQ(0, out[3]); } -TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterRegion) { +TEST(ConfigLocaleTest, packAndUnpack3LetterRegion) { ResTable_config config; config.packRegion("419"); @@ -131,7 +131,7 @@ TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterRegion) { } } -TEST(ResourceTypesTest, IsMoreSpecificThan) { +TEST(ConfigLocaleTest, IsMoreSpecificThan) { ResTable_config l; ResTable_config r; @@ -170,7 +170,7 @@ TEST(ResourceTypesTest, IsMoreSpecificThan) { EXPECT_TRUE(r.isMoreSpecificThan(l)); } -TEST(ResourceTypesTest, setLocale) { +TEST(ConfigLocaleTest, setLocale) { ResTable_config test; test.setBcp47Locale("en-US"); EXPECT_EQ('e', test.language[0]); diff --git a/libs/androidfw/tests/Config_test.cpp b/libs/androidfw/tests/Config_test.cpp new file mode 100644 index 000000000000..ef30df46d36c --- /dev/null +++ b/libs/androidfw/tests/Config_test.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <androidfw/ResourceTypes.h> +#include <utils/Log.h> +#include <utils/String8.h> +#include <utils/Vector.h> + +#include "TestHelpers.h" +#include <gtest/gtest.h> + +namespace android { + +static ResTable_config selectBest(const ResTable_config& target, + const Vector<ResTable_config>& configs) { + ResTable_config bestConfig; + memset(&bestConfig, 0, sizeof(bestConfig)); + const size_t configCount = configs.size(); + for (size_t i = 0; i < configCount; i++) { + const ResTable_config& thisConfig = configs[i]; + if (!thisConfig.match(target)) { + continue; + } + + if (thisConfig.isBetterThan(bestConfig, &target)) { + bestConfig = thisConfig; + } + } + return bestConfig; +} + +static ResTable_config buildDensityConfig(int density) { + ResTable_config config; + memset(&config, 0, sizeof(config)); + config.density = uint16_t(density); + config.sdkVersion = 4; + return config; +} + +TEST(ConfigTest, shouldSelectBestDensity) { + ResTable_config deviceConfig; + memset(&deviceConfig, 0, sizeof(deviceConfig)); + deviceConfig.density = ResTable_config::DENSITY_XHIGH; + deviceConfig.sdkVersion = 21; + + Vector<ResTable_config> configs; + + ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_HIGH); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + expectedBest = buildDensityConfig(ResTable_config::DENSITY_XXHIGH); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + expectedBest = buildDensityConfig(int(ResTable_config::DENSITY_XXHIGH) - 20); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + configs.add(buildDensityConfig(int(ResTable_config::DENSITY_HIGH) + 20)); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + expectedBest = buildDensityConfig(ResTable_config::DENSITY_XHIGH); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY); + expectedBest.sdkVersion = 21; + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); +} + +TEST(ConfigTest, shouldSelectBestDensityWhenNoneSpecified) { + ResTable_config deviceConfig; + memset(&deviceConfig, 0, sizeof(deviceConfig)); + deviceConfig.sdkVersion = 21; + + Vector<ResTable_config> configs; + configs.add(buildDensityConfig(ResTable_config::DENSITY_HIGH)); + + ResTable_config expectedBest = buildDensityConfig(ResTable_config::DENSITY_MEDIUM); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); + + expectedBest = buildDensityConfig(ResTable_config::DENSITY_ANY); + configs.add(expectedBest); + ASSERT_EQ(expectedBest, selectBest(deviceConfig, configs)); +} + +} // namespace android. diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h index 75a233acad26..fe2e5ce29eff 100644 --- a/libs/androidfw/tests/TestHelpers.h +++ b/libs/androidfw/tests/TestHelpers.h @@ -3,6 +3,7 @@ #include <ostream> +#include <androidfw/ResourceTypes.h> #include <utils/String8.h> #include <utils/String16.h> @@ -14,4 +15,16 @@ static inline ::std::ostream& operator<<(::std::ostream& out, const android::Str return out << android::String8(str).string(); } +namespace android { + +static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) { + return memcmp(&a, &b, sizeof(a)) == 0; +} + +static inline ::std::ostream& operator<<(::std::ostream& out, const android::ResTable_config& c) { + return out << c.toString().string(); +} + +} // namespace android + #endif // __TEST_HELPERS_H diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h index 7350082bdad7..e9c937cbeb0c 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -215,11 +215,17 @@ private: if (!paint) return NULL; const SkPaint* paintCopy = mPaintMap.valueFor(paint); - if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) { - paintCopy = new SkPaint(*paint); + if (paintCopy == NULL + || paintCopy->getGenerationID() != paint->getGenerationID() + // We can't compare shader pointers because that will always + // change as we do partial copying via wrapping. However, if the + // shader changes the paint generationID will have changed and + // so we don't hit this comparison anyway + || !(paint->getShader() && paintCopy->getShader() + && paint->getShader()->getGenerationID() == paintCopy->getShader()->getGenerationID())) { + paintCopy = copyPaint(paint); // replaceValueFor() performs an add if the entry doesn't exist mPaintMap.replaceValueFor(paint, paintCopy); - mDisplayListData->paints.add(paintCopy); } return paintCopy; @@ -228,8 +234,15 @@ private: inline SkPaint* copyPaint(const SkPaint* paint) { if (!paint) return NULL; SkPaint* paintCopy = new SkPaint(*paint); + if (paint->getShader()) { + SkShader* shaderCopy = SkShader::CreateLocalMatrixShader( + paint->getShader(), paint->getShader()->getLocalMatrix()); + paintCopy->setShader(shaderCopy); + paintCopy->setGenerationID(paint->getGenerationID()); + shaderCopy->setGenerationID(paint->getShader()->getGenerationID()); + shaderCopy->unref(); + } mDisplayListData->paints.add(paintCopy); - return paintCopy; } diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp index cb20a0b2a53f..2178cc7a5567 100644 --- a/libs/hwui/SpotShadow.cpp +++ b/libs/hwui/SpotShadow.cpp @@ -647,7 +647,7 @@ float SpotShadow::projectCasterToOutline(Vector2& outline, if (lightToPolyZ != 0) { // If any caster's vertex is almost above the light, we just keep it as 95% // of the height of the light. - ratioZ = MathUtils::min(polyVertex.z / lightToPolyZ, CASTER_Z_CAP_RATIO); + ratioZ = MathUtils::clamp(polyVertex.z / lightToPolyZ, 0.0f, CASTER_Z_CAP_RATIO); } outline.x = polyVertex.x - ratioZ * (lightCenter.x - polyVertex.x); @@ -669,6 +669,10 @@ float SpotShadow::projectCasterToOutline(Vector2& outline, void SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter, float lightSize, const Vector3* poly, int polyLength, const Vector3& polyCentroid, VertexBuffer& shadowTriangleStrip) { + if (CC_UNLIKELY(lightCenter.z <= 0)) { + ALOGW("Relative Light Z is not positive. No spot shadow!"); + return; + } OutlineData outlineData[polyLength]; Vector2 outlineCentroid; // Calculate the projected outline for each polygon's vertices from the light center. @@ -787,7 +791,7 @@ void SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3& lightCente // The ratio can be simulated by using the inverse of maximum of ratioVI for // all (V). distOutline = (outlineData[i].position - outlineCentroid).length(); - if (distOutline == 0) { + if (CC_UNLIKELY(distOutline == 0)) { // If the outline has 0 area, then there is no spot shadow anyway. ALOGW("Outline has 0 area, no spot shadow!"); return; diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h index 00448b845579..d89859b51992 100644 --- a/libs/hwui/utils/MathUtils.h +++ b/libs/hwui/utils/MathUtils.h @@ -76,6 +76,11 @@ public: return a < b ? a : b; } + template<typename T> + static inline T clamp(T a, T minValue, T maxValue) { + return min(max(a, minValue), maxValue); + } + inline static float lerp(float v1, float v2, float t) { return v1 + ((v2 - v1) * t); } diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 7110db97092d..d058d64ffa93 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -858,6 +858,7 @@ public class TvView extends ViewGroup { mSession.setStreamVolume(mStreamVolume); } } else { + mSessionCallback = null; if (mListener != null) { mListener.onConnectionFailed(mInputId); } @@ -869,6 +870,8 @@ public class TvView extends ViewGroup { if (this != mSessionCallback) { return; } + mOverlayViewCreated = false; + mOverlayViewFrame = null; mSessionCallback = null; mSession = null; if (mListener != null) { diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml index 783aa0342ae4..469b776064fc 100644 --- a/packages/SettingsProvider/AndroidManifest.xml +++ b/packages/SettingsProvider/AndroidManifest.xml @@ -16,6 +16,7 @@ android:multiprocess="false" android:exported="true" android:writePermission="android.permission.WRITE_SETTINGS" + android:singleUser="true" android:initOrder="100" /> </application> </manifest> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 0ddef48ae450..8b50a3673f91 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -21,7 +21,6 @@ import android.animation.AnimatorListenerAdapter; import android.animation.TimeInterpolator; import android.app.ActivityManager; import android.app.ActivityManagerNative; -import android.app.ActivityThread; import android.app.Notification; import android.app.PendingIntent; import android.app.TaskStackBuilder; @@ -32,16 +31,12 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageManager; -import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.database.ContentObserver; -import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Handler; @@ -579,7 +574,7 @@ public abstract class BaseStatusBar extends SystemUI implements } - protected void applyLegacyRowBackground(StatusBarNotification sbn, + protected void applyColorsAndBackgrounds(StatusBarNotification sbn, NotificationData.Entry entry) { int version = 0; try { @@ -602,6 +597,14 @@ public abstract class BaseStatusBar extends SystemUI implements entry.row.setTintColor(color); } } + + if (entry.icon != null) { + if (version >= Build.VERSION_CODES.L) { + entry.icon.setColorFilter(mContext.getResources().getColor(android.R.color.white)); + } else { + entry.icon.setColorFilter(null); + } + } } public boolean isMediaNotification(NotificationData.Entry entry) { @@ -1250,7 +1253,7 @@ public abstract class BaseStatusBar extends SystemUI implements entry.expandedPublic = publicViewLocal; entry.setBigContentView(bigContentViewLocal); - applyLegacyRowBackground(sbn, entry); + applyColorsAndBackgrounds(sbn, entry); // Restore previous flags. if (hasUserChangedExpansion) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index f427ec458c07..3338f6a245ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -298,9 +298,7 @@ public class StatusBarKeyguardViewManager { */ public boolean onBackPressed() { if (mBouncer.isShowing()) { - mBouncer.hide(false /* destroyView */); - mPhoneStatusBar.showKeyguard(); - updateStates(); + reset(); return true; } return false; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index c57563b2809c..20206b9974d4 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -2978,7 +2978,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean immersiveSticky = (sysui & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0; boolean navAllowedHidden = immersive || immersiveSticky; navTranslucent &= !immersiveSticky; // transient trumps translucent - navTranslucent &= areTranslucentBarsAllowed(); + boolean isKeyguardShowing = isStatusBarKeyguard() && !mHideLockScreen; + if (!isKeyguardShowing) { + navTranslucent &= areTranslucentBarsAllowed(); + } // When the navigation bar isn't visible, we put up a fake // input window to catch all touch events. This way we can @@ -3102,7 +3105,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean statusBarTransient = (sysui & View.STATUS_BAR_TRANSIENT) != 0; boolean statusBarTranslucent = (sysui & (View.STATUS_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT)) != 0; - statusBarTranslucent &= areTranslucentBarsAllowed(); + if (!isKeyguardShowing) { + statusBarTranslucent &= areTranslucentBarsAllowed(); + } // If the status bar is hidden, we don't want to cause // windows behind it to scroll. @@ -5611,7 +5616,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { vis = (vis & ~flags) | (oldVis & flags); } - if (!areTranslucentBarsAllowed()) { + if (!areTranslucentBarsAllowed() && transWin != mStatusBar) { vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT | View.SYSTEM_UI_TRANSPARENT); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 62a212b297f9..e794b83c281f 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6615,6 +6615,10 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags, int userId) { @@ -6767,6 +6771,10 @@ public final class ActivityManagerService extends ActivityManagerNative return targetUid; } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, final int modeFlags, int userId) { @@ -6951,6 +6959,10 @@ public final class ActivityManagerService extends ActivityManagerNative grantUriPermissionUncheckedFromIntentLocked(needed, owner); } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, final int modeFlags, int userId) { @@ -7053,6 +7065,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, int userId) { @@ -7151,9 +7167,16 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param sourceUserId The userId in which the uri is to be resolved. + * @param targetUserId The userId of the app that receives the grant. + */ @Override public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, final int modeFlags, int sourceUserId, int targetUserId) { + targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); synchronized(this) { UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); if (owner == null) { @@ -7178,6 +7201,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { synchronized(this) { @@ -7318,6 +7345,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { enforceNotIsolatedCaller("takePersistableUriPermission"); @@ -7360,6 +7391,10 @@ public final class ActivityManagerService extends ActivityManagerNative } } + /** + * @param uri This uri must NOT contain an embedded userId. + * @param userId The userId in which the uri is to be resolved. + */ @Override public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { enforceNotIsolatedCaller("releasePersistableUriPermission"); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 8aec39232248..bd8501c430b9 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2430,7 +2430,6 @@ public final class ActivityStackSupervisor implements DisplayListener { r.userId, r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); } - mWindowManager.addTask(taskId, stackId, false); } resumeHomeStackTask(HOME_ACTIVITY_TYPE, null); } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 949019ed1c41..9e169d9f6c18 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -152,7 +152,10 @@ public class SyncManager { */ private static final int DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS = 10; - private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000; + /** + * How long to wait before considering an active sync to have timed-out, and cancelling it. + */ + private static final long ACTIVE_SYNC_TIMEOUT_MILLIS = 30L * 60 * 1000; // 30 mins. private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; @@ -851,6 +854,31 @@ public class SyncManager { mSyncHandler.sendMessage(msg); } + /** + * Post a delayed message to the handler that will result in the cancellation of the provided + * running sync's context. + */ + private void postSyncExpiryMessage(ActiveSyncContext activeSyncContext) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "posting MESSAGE_SYNC_EXPIRED in " + + (ACTIVE_SYNC_TIMEOUT_MILLIS/1000) + "s"); + } + Message msg = mSyncHandler.obtainMessage(); + msg.what = SyncHandler.MESSAGE_SYNC_EXPIRED; + msg.obj = activeSyncContext; + mSyncHandler.sendMessageDelayed(msg, ACTIVE_SYNC_TIMEOUT_MILLIS); + } + + /** + * Remove any time-outs previously posted for the provided active sync. + */ + private void removeSyncExpiryMessage(ActiveSyncContext activeSyncContext) { + if (Log.isLoggable(TAG, Log.VERBOSE)) { + Log.v(TAG, "removing all MESSAGE_SYNC_EXPIRED for " + activeSyncContext.toString()); + } + mSyncHandler.removeMessages(SyncHandler.MESSAGE_SYNC_EXPIRED, activeSyncContext); + } + class SyncHandlerMessagePayload { public final ActiveSyncContext activeSyncContext; public final SyncResult syncResult; @@ -1902,6 +1930,8 @@ public class SyncManager { private static final int MESSAGE_SERVICE_CONNECTED = 4; private static final int MESSAGE_SERVICE_DISCONNECTED = 5; private static final int MESSAGE_CANCEL = 6; + /** Posted delayed in order to expire syncs that are long-running. */ + private static final int MESSAGE_SYNC_EXPIRED = 7; public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo(); private Long mAlarmScheduleTime = null; @@ -2000,10 +2030,21 @@ public class SyncManager { // to also take into account the periodic syncs. earliestFuturePollTime = scheduleReadyPeriodicSyncs(); switch (msg.what) { + case SyncHandler.MESSAGE_SYNC_EXPIRED: + ActiveSyncContext expiredContext = (ActiveSyncContext) msg.obj; + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_EXPIRED: expiring " + + expiredContext); + } + cancelActiveSync(expiredContext.mSyncOperation.target, + expiredContext.mSyncOperation.extras); + nextPendingSyncTime = maybeStartNextSyncLocked(); + break; + case SyncHandler.MESSAGE_CANCEL: { SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj; Bundle extras = msg.peekData(); - if (Log.isLoggable(TAG, Log.VERBOSE)) { + if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: " + payload + " bundle: " + extras); } @@ -2653,6 +2694,13 @@ public class SyncManager { new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid); activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext); mActiveSyncContexts.add(activeSyncContext); + if (!activeSyncContext.mSyncOperation.isInitialization() && + !activeSyncContext.mSyncOperation.isExpedited() && + !activeSyncContext.mSyncOperation.isManual() && + !activeSyncContext.mSyncOperation.isIgnoreSettings()) { + // Post message to expire this sync if it runs for too long. + postSyncExpiryMessage(activeSyncContext); + } if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext); } @@ -2757,9 +2805,7 @@ public class SyncManager { } else { Log.d(TAG, "failed sync operation " + syncOperation + ", " + syncResult); // the operation failed so increase the backoff time - if (!syncResult.syncAlreadyInProgress) { - increaseBackoffSetting(syncOperation); - } + increaseBackoffSetting(syncOperation); // reschedule the sync if so indicated by the syncResult maybeRescheduleSync(syncResult, syncOperation); historyMessage = ContentResolver.syncErrorToString( @@ -2768,7 +2814,6 @@ public class SyncManager { downstreamActivity = 0; upstreamActivity = 0; } - setDelayUntilTime(syncOperation, syncResult.delayUntil); } else { if (isLoggable) { @@ -2794,7 +2839,6 @@ public class SyncManager { stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage, upstreamActivity, downstreamActivity, elapsedTime); - // Check for full-resync and schedule it after closing off the last sync. if (info.target_provider) { if (syncResult != null && syncResult.tooManyDeletions) { @@ -2833,6 +2877,7 @@ public class SyncManager { mActiveSyncContexts.remove(activeSyncContext); mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo, activeSyncContext.mSyncOperation.target.userId); + removeSyncExpiryMessage(activeSyncContext); } /** diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java index 9a4abce7f4c8..35827cc59f9b 100644 --- a/services/core/java/com/android/server/content/SyncOperation.java +++ b/services/core/java/com/android/server/content/SyncOperation.java @@ -273,6 +273,14 @@ public class SyncOperation implements Comparable { return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false); } + public boolean isManual() { + return extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); + } + + public boolean isIgnoreSettings() { + return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false); + } + /** Changed in V3. */ public static String toKey(SyncStorageEngine.EndPoint info, Bundle extras) { StringBuilder sb = new StringBuilder(); diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java index 66337870feb1..78e360bdb831 100644 --- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java +++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; +import android.graphics.Color; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -199,6 +200,7 @@ public class FrameworkPerfActivity extends Activity mLocalCheckBox = (CheckBox)findViewById(R.id.local); mLog = (TextView)findViewById(R.id.log); + mLog.setTextColor(Color.RED); PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); mPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Scheduler"); diff --git a/tools/aapt/AaptConfig.cpp b/tools/aapt/AaptConfig.cpp index 69a9c7feca99..32a0cd3d4872 100644 --- a/tools/aapt/AaptConfig.cpp +++ b/tools/aapt/AaptConfig.cpp @@ -255,6 +255,8 @@ void applyVersionForCompatibility(ConfigDescription* config) { != ResTable_config::SCREENLONG_ANY || config->density != ResTable_config::DENSITY_DEFAULT) { minSdk = SDK_DONUT; + } else if ((config->density == ResTable_config::DENSITY_ANY)) { + minSdk = SDK_L; } if (minSdk > config->sdkVersion) { @@ -477,6 +479,11 @@ bool parseDensity(const char* name, ResTable_config* out) { return true; } + if (strcmp(name, "anydpi") == 0) { + if (out) out->density = ResTable_config::DENSITY_ANY; + return true; + } + if (strcmp(name, "nodpi") == 0) { if (out) out->density = ResTable_config::DENSITY_NONE; return true; diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index 1439f14b7fb6..af494618d6ce 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -24,6 +24,7 @@ enum { SDK_HONEYCOMB_MR2 = 13, SDK_ICE_CREAM_SANDWICH = 14, SDK_ICE_CREAM_SANDWICH_MR1 = 15, + SDK_L = 21, }; /* |