summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt5
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java4
-rw-r--r--core/java/android/content/pm/PackageManager.java8
-rw-r--r--core/java/android/content/res/Configuration.java19
-rw-r--r--core/jni/android/graphics/Shader.cpp1
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java10
-rw-r--r--include/androidfw/ResourceTypes.h1
-rw-r--r--libs/androidfw/ResourceTypes.cpp37
-rw-r--r--libs/androidfw/tests/Android.mk3
-rw-r--r--libs/androidfw/tests/ConfigLocale_test.cpp (renamed from libs/androidfw/tests/ResourceTypes_test.cpp)18
-rw-r--r--libs/androidfw/tests/Config_test.cpp103
-rw-r--r--libs/androidfw/tests/TestHelpers.h13
-rw-r--r--libs/hwui/DisplayListRenderer.h21
-rw-r--r--libs/hwui/SpotShadow.cpp8
-rw-r--r--libs/hwui/utils/MathUtils.h5
-rw-r--r--media/java/android/media/tv/TvView.java3
-rw-r--r--packages/SettingsProvider/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java4
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindowManager.java11
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java35
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java1
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java59
-rw-r--r--services/core/java/com/android/server/content/SyncOperation.java8
-rw-r--r--tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java2
-rw-r--r--tools/aapt/AaptConfig.cpp7
-rw-r--r--tools/aapt/Bundle.h1
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,
};
/*