Merge "Separate power warnings UI from state calculation."
diff --git a/api/current.txt b/api/current.txt
index f1aa8bf..e15c1d7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9926,6 +9926,7 @@
method public void cubicTo(float, float, float, float, float, float);
method public android.graphics.Path.FillType getFillType();
method public void incReserve(int);
+ method public boolean isConvex();
method public boolean isEmpty();
method public boolean isInverseFillType();
method public boolean isRect(android.graphics.RectF);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index da6ae56..5c27072 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1625,7 +1625,7 @@
String locale = null;
if (mConfiguration.locale != null) {
- locale = localeToLanguageTag(mConfiguration.locale);
+ locale = adjustLanguageTag(localeToLanguageTag(mConfiguration.locale));
}
int width, height;
if (mMetrics.widthPixels >= mMetrics.heightPixels) {
@@ -1713,6 +1713,41 @@
}
/**
+ * {@code Locale.toLanguageTag} will transform the obsolete (and deprecated)
+ * language codes "in", "ji" and "iw" to "id", "yi" and "he" respectively.
+ *
+ * All released versions of android prior to "L" used the deprecated language
+ * tags, so we will need to support them for backwards compatibility.
+ *
+ * Note that this conversion needs to take place *after* the call to
+ * {@code toLanguageTag} because that will convert all the deprecated codes to
+ * the new ones, even if they're set manually.
+ */
+ private static String adjustLanguageTag(String languageTag) {
+ final int separator = languageTag.indexOf('-');
+ final String language;
+ final String remainder;
+
+ if (separator == -1) {
+ language = languageTag;
+ remainder = "";
+ } else {
+ language = languageTag.substring(0, separator);
+ remainder = languageTag.substring(separator);
+ }
+
+ if ("id".equals(language)) {
+ return "in" + remainder;
+ } else if ("yi".equals(language)) {
+ return "ji" + remainder;
+ } else if ("he".equals(language)) {
+ return "iw" + remainder;
+ } else {
+ return languageTag;
+ }
+ }
+
+ /**
* Update the system resources configuration if they have previously
* been initialized.
*
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index 5b6f154..89c17c7 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -421,6 +421,13 @@
case ConnectivityManager.TYPE_WIFI:
WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
if (currentWifiInfo != null) {
+ // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
+ // surrounded by double quotation marks (thus violating the Javadoc), but this
+ // was changed to match the Javadoc in API 17. Since clients may have started
+ // sanitizing the output of this method since API 17 was released, we should
+ // not change it here as it would become impossible to tell whether the SSID is
+ // simply being surrounded by quotes due to the API, or whether those quotes
+ // are actually part of the SSID.
latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
} else {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9b23b35..1f211c2 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -255,8 +255,9 @@
updateWindow(false, false);
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
if (mGlobalListenersAdded) {
ViewTreeObserver observer = getViewTreeObserver();
observer.removeOnScrollChangedListener(mScrollChangedListener);
@@ -278,7 +279,7 @@
mSession = null;
mLayout.token = null;
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index ef0d80d..3cfe5e9 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -228,10 +228,11 @@
}
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ protected void onDetachedFromWindowInternal() {
destroySurface();
+ super.onDetachedFromWindowInternal();
}
private void destroySurface() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a57b311..827c4cc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10838,11 +10838,14 @@
* Sets the outline of the view, which defines the shape of the shadow it
* casts, and can used for clipping.
* <p>
+ * The outline path of a View must be {@link android.graphics.Path#isConvex() convex}.
+ * <p>
* If the outline is not set, or {@link Path#isEmpty()}, shadows will be
* cast from the bounds of the View, and clipToOutline will be ignored.
*
- * @param outline The new outline of the view. Must be non-null.
+ * @param outline The new outline of the view. Must be non-null, and convex.
*
+ * @see #setCastsShadow(boolean)
* @see #getOutline(Path)
* @see #getClipToOutline()
* @see #setClipToOutline(boolean)
@@ -10851,6 +10854,9 @@
if (outline == null) {
throw new IllegalArgumentException("Path must be non-null");
}
+ if (!outline.isConvex()) {
+ throw new IllegalArgumentException("Path must be convex");
+ }
// always copy the path since caller may reuse
if (mOutline == null) {
mOutline = new Path(outline);
@@ -13110,6 +13116,19 @@
* @see #onAttachedToWindow()
*/
protected void onDetachedFromWindow() {
+ }
+
+ /**
+ * This is a framework-internal mirror of onDetachedFromWindow() that's called
+ * after onDetachedFromWindow().
+ *
+ * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
+ * The super method should be called at the end of the overriden method to ensure
+ * subclasses are destroyed first
+ *
+ * @hide
+ */
+ protected void onDetachedFromWindowInternal() {
mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
@@ -13297,6 +13316,7 @@
}
onDetachedFromWindow();
+ onDetachedFromWindowInternal();
ListenerInfo li = mListenerInfo;
final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 9f2bf33..f8160c8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -37,6 +37,7 @@
import android.util.Slog;
import android.util.Xml;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+import android.view.inputmethod.InputMethodSubtypeArray;
import java.io.IOException;
import java.util.ArrayList;
@@ -86,9 +87,9 @@
final int mIsDefaultResId;
/**
- * The array of the subtypes.
+ * An array-like container of the subtypes.
*/
- private final ArrayList<InputMethodSubtype> mSubtypes = new ArrayList<InputMethodSubtype>();
+ private final InputMethodSubtypeArray mSubtypes;
private final boolean mIsAuxIme;
@@ -138,6 +139,7 @@
int isDefaultResId = 0;
XmlResourceParser parser = null;
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
try {
parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA);
if (parser == null) {
@@ -206,7 +208,7 @@
if (!subtype.isAuxiliary()) {
isAuxIme = false;
}
- mSubtypes.add(subtype);
+ subtypes.add(subtype);
}
}
} catch (NameNotFoundException e) {
@@ -216,7 +218,7 @@
if (parser != null) parser.close();
}
- if (mSubtypes.size() == 0) {
+ if (subtypes.size() == 0) {
isAuxIme = false;
}
@@ -225,14 +227,15 @@
final int N = additionalSubtypes.size();
for (int i = 0; i < N; ++i) {
final InputMethodSubtype subtype = additionalSubtypes.get(i);
- if (!mSubtypes.contains(subtype)) {
- mSubtypes.add(subtype);
+ if (!subtypes.contains(subtype)) {
+ subtypes.add(subtype);
} else {
Slog.w(TAG, "Duplicated subtype definition found: "
+ subtype.getLocale() + ", " + subtype.getMode());
}
}
}
+ mSubtypes = new InputMethodSubtypeArray(subtypes);
mSettingsActivityName = settingsActivityComponent;
mIsDefaultResId = isDefaultResId;
mIsAuxIme = isAuxIme;
@@ -246,7 +249,7 @@
mIsAuxIme = source.readInt() == 1;
mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
mService = ResolveInfo.CREATOR.createFromParcel(source);
- source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
+ mSubtypes = new InputMethodSubtypeArray(source);
mForceDefault = false;
}
@@ -272,9 +275,7 @@
mSettingsActivityName = settingsActivity;
mIsDefaultResId = isDefaultResId;
mIsAuxIme = isAuxIme;
- if (subtypes != null) {
- mSubtypes.addAll(subtypes);
- }
+ mSubtypes = new InputMethodSubtypeArray(subtypes);
mForceDefault = forceDefault;
mSupportsSwitchingToNextInputMethod = true;
}
@@ -364,7 +365,7 @@
* composed of {@link #getPackageName} and the class name returned here.
*
* <p>A null will be returned if there is no settings activity associated
- * with the input method.
+ * with the input method.</p>
*/
public String getSettingsActivity() {
return mSettingsActivityName;
@@ -374,7 +375,7 @@
* Return the count of the subtypes of Input Method.
*/
public int getSubtypeCount() {
- return mSubtypes.size();
+ return mSubtypes.getCount();
}
/**
@@ -479,7 +480,7 @@
dest.writeInt(mIsAuxIme ? 1 : 0);
dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
mService.writeToParcel(dest, flags);
- dest.writeTypedList(mSubtypes);
+ mSubtypes.writeToParcel(dest);
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
new file mode 100644
index 0000000..5bef71f
--- /dev/null
+++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.inputmethod;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AndroidRuntimeException;
+import android.util.Slog;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * An array-like container that stores multiple instances of {@link InputMethodSubtype}.
+ *
+ * <p>This container is designed to reduce the risk of {@link TransactionTooLargeException}
+ * when one or more instancess of {@link InputMethodInfo} are transferred through IPC.
+ * Basically this class does following three tasks.</p>
+ * <ul>
+ * <li>Applying compression for the marshalled data</li>
+ * <li>Lazily unmarshalling objects</li>
+ * <li>Caching the marshalled data when appropriate</li>
+ * </ul>
+ *
+ * @hide
+ */
+public class InputMethodSubtypeArray {
+ private final static String TAG = "InputMethodSubtypeArray";
+
+ /**
+ * Create a new instance of {@link InputMethodSubtypeArray} from an existing list of
+ * {@link InputMethodSubtype}.
+ *
+ * @param subtypes A list of {@link InputMethodSubtype} from which
+ * {@link InputMethodSubtypeArray} will be created.
+ */
+ public InputMethodSubtypeArray(final List<InputMethodSubtype> subtypes) {
+ if (subtypes == null) {
+ mCount = 0;
+ return;
+ }
+ mCount = subtypes.size();
+ mInstance = subtypes.toArray(new InputMethodSubtype[mCount]);
+ }
+
+ /**
+ * Unmarshall an instance of {@link InputMethodSubtypeArray} from a given {@link Parcel}
+ * object.
+ *
+ * @param source A {@link Parcel} object from which {@link InputMethodSubtypeArray} will be
+ * unmarshalled.
+ */
+ public InputMethodSubtypeArray(final Parcel source) {
+ mCount = source.readInt();
+ if (mCount > 0) {
+ mDecompressedSize = source.readInt();
+ mCompressedData = source.createByteArray();
+ }
+ }
+
+ /**
+ * Marshall the instance into a given {@link Parcel} object.
+ *
+ * <p>This methods may take a bit additional time to compress data lazily when called
+ * first time.</p>
+ *
+ * @param source A {@link Parcel} object to which {@link InputMethodSubtypeArray} will be
+ * marshalled.
+ */
+ public void writeToParcel(final Parcel dest) {
+ if (mCount == 0) {
+ dest.writeInt(mCount);
+ return;
+ }
+
+ byte[] compressedData = mCompressedData;
+ int decompressedSize = mDecompressedSize;
+ if (compressedData == null && decompressedSize == 0) {
+ synchronized (mLockObject) {
+ compressedData = mCompressedData;
+ decompressedSize = mDecompressedSize;
+ if (compressedData == null && decompressedSize == 0) {
+ final byte[] decompressedData = marshall(mInstance);
+ compressedData = compress(decompressedData);
+ if (compressedData == null) {
+ decompressedSize = -1;
+ Slog.i(TAG, "Failed to compress data.");
+ } else {
+ decompressedSize = decompressedData.length;
+ }
+ mDecompressedSize = decompressedSize;
+ mCompressedData = compressedData;
+ }
+ }
+ }
+
+ if (compressedData != null && decompressedSize > 0) {
+ dest.writeInt(mCount);
+ dest.writeInt(decompressedSize);
+ dest.writeByteArray(compressedData);
+ } else {
+ Slog.i(TAG, "Unexpected state. Behaving as an empty array.");
+ dest.writeInt(0);
+ }
+ }
+
+ /**
+ * Return {@link InputMethodSubtype} specified with the given index.
+ *
+ * <p>This methods may take a bit additional time to decompress data lazily when called
+ * first time.</p>
+ *
+ * @param index The index of {@link InputMethodSubtype}.
+ */
+ public InputMethodSubtype get(final int index) {
+ if (index < 0 || mCount <= index) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ InputMethodSubtype[] instance = mInstance;
+ if (instance == null) {
+ synchronized (mLockObject) {
+ instance = mInstance;
+ if (instance == null) {
+ final byte[] decompressedData =
+ decompress(mCompressedData, mDecompressedSize);
+ // Clear the compressed data until {@link #getMarshalled()} is called.
+ mCompressedData = null;
+ mDecompressedSize = 0;
+ if (decompressedData != null) {
+ instance = unmarshall(decompressedData);
+ } else {
+ Slog.e(TAG, "Failed to decompress data. Returns null as fallback.");
+ instance = new InputMethodSubtype[mCount];
+ }
+ mInstance = instance;
+ }
+ }
+ }
+ return instance[index];
+ }
+
+ /**
+ * Return the number of {@link InputMethodSubtype} objects.
+ */
+ public int getCount() {
+ return mCount;
+ }
+
+ private final Object mLockObject = new Object();
+ private final int mCount;
+
+ private volatile InputMethodSubtype[] mInstance;
+ private volatile byte[] mCompressedData;
+ private volatile int mDecompressedSize;
+
+ private static byte[] marshall(final InputMethodSubtype[] array) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ parcel.writeTypedArray(array, 0);
+ return parcel.marshall();
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ parcel = null;
+ }
+ }
+ }
+
+ private static InputMethodSubtype[] unmarshall(final byte[] data) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ parcel.unmarshall(data, 0, data.length);
+ parcel.setDataPosition(0);
+ return parcel.createTypedArray(InputMethodSubtype.CREATOR);
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ parcel = null;
+ }
+ }
+ }
+
+ private static byte[] compress(final byte[] data) {
+ ByteArrayOutputStream resultStream = null;
+ GZIPOutputStream zipper = null;
+ try {
+ resultStream = new ByteArrayOutputStream();
+ zipper = new GZIPOutputStream(resultStream);
+ zipper.write(data);
+ } catch(IOException e) {
+ return null;
+ } finally {
+ try {
+ if (zipper != null) {
+ zipper.close();
+ }
+ } catch (IOException e) {
+ zipper = null;
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ try {
+ if (resultStream != null) {
+ resultStream.close();
+ }
+ } catch (IOException e) {
+ resultStream = null;
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ }
+ return resultStream != null ? resultStream.toByteArray() : null;
+ }
+
+ private static byte[] decompress(final byte[] data, final int expectedSize) {
+ ByteArrayInputStream inputStream = null;
+ GZIPInputStream unzipper = null;
+ try {
+ inputStream = new ByteArrayInputStream(data);
+ unzipper = new GZIPInputStream(inputStream);
+ final byte [] result = new byte[expectedSize];
+ int totalReadBytes = 0;
+ while (totalReadBytes < result.length) {
+ final int restBytes = result.length - totalReadBytes;
+ final int readBytes = unzipper.read(result, totalReadBytes, restBytes);
+ if (readBytes < 0) {
+ break;
+ }
+ totalReadBytes += readBytes;
+ }
+ if (expectedSize != totalReadBytes) {
+ return null;
+ }
+ return result;
+ } catch(IOException e) {
+ return null;
+ } finally {
+ try {
+ if (unzipper != null) {
+ unzipper.close();
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ try {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close the stream.", e);
+ // swallowed, not propagated back to the caller
+ }
+ }
+ }
+}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 826bcec..81d36a4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2139,10 +2139,11 @@
mProvider.getViewDelegate().onAttachedToWindow();
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
mProvider.getViewDelegate().onDetachedFromWindow();
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index e5cb16f..687036c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4729,10 +4729,9 @@
if (mEditor != null) mEditor.onAttachedToWindow();
}
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
+ protected void onDetachedFromWindowInternal() {
if (mPreDrawRegistered) {
getViewTreeObserver().removeOnPreDrawListener(this);
mPreDrawRegistered = false;
@@ -4741,6 +4740,8 @@
resetResolvedDrawables();
if (mEditor != null) mEditor.onDetachedFromWindow();
+
+ super.onDetachedFromWindowInternal();
}
@Override
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 325a27d..e51345c 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -32,7 +32,9 @@
* this file.
*/
interface IInputMethodManager {
+ // TODO: Use ParceledListSlice instead
List<InputMethodInfo> getInputMethodList();
+ // TODO: Use ParceledListSlice instead
List<InputMethodInfo> getEnabledInputMethodList();
List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
boolean allowsImplicitlySelectedSubtypes);
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 429f177..e580d36 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -72,11 +72,16 @@
*dst = *src;
}
+ static jboolean isConvex(JNIEnv* env, jobject clazz, jlong objHandle) {
+ SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
+ return obj->isConvex();
+ }
+
static jint getFillType(JNIEnv* env, jobject clazz, jlong objHandle) {
SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
return obj->getFillType();
}
-
+
static void setFillType(JNIEnv* env, jobject clazz, jlong pathHandle, jint ftHandle) {
SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle);
@@ -524,6 +529,7 @@
{"native_reset","(J)V", (void*) SkPathGlue::reset},
{"native_rewind","(J)V", (void*) SkPathGlue::rewind},
{"native_set","(JJ)V", (void*) SkPathGlue::assign},
+ {"native_isConvex","(J)Z", (void*) SkPathGlue::isConvex},
{"native_getFillType","(J)I", (void*) SkPathGlue::getFillType},
{"native_setFillType","(JI)V", (void*) SkPathGlue::setFillType},
{"native_isEmpty","(J)Z", (void*) SkPathGlue::isEmpty},
diff --git a/core/res/res/values/styles_micro.xml b/core/res/res/values/styles_micro.xml
index c35bd48..52d90bc 100644
--- a/core/res/res/values/styles_micro.xml
+++ b/core/res/res/values/styles_micro.xml
@@ -25,7 +25,7 @@
<item name="android:solidColor">@android:color/transparent</item>
<item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
<item name="android:selectionDividerHeight">0dip</item>
- <item name="android:selectionDividersDistance">0dip</item>
+ <item name="android:selectionDividersDistance">104dip</item>
<item name="android:internalMinWidth">64dip</item>
<item name="android:internalMaxHeight">180dip</item>
<item name="virtualButtonPressedDrawable">?android:attr/selectableItemBackground</item>
diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml
index e429f96..7c0b7bc 100644
--- a/core/res/res/values/themes_micro.xml
+++ b/core/res/res/values/themes_micro.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
<resources>
- <style name="Theme.Micro" parent="Theme.Holo">
+ <style name="Theme.Micro" parent="Theme.Holo.NoActionBar">
+ <item name="textViewStyle">@android:style/Widget.Micro.TextView</item>
<item name="numberPickerStyle">@android:style/Widget.Micro.NumberPicker</item>
<item name="windowAnimationStyle">@android:style/Animation.SwipeDismiss</item>
<item name="windowIsFloating">false</item>
diff --git a/core/tests/inputmethodtests/run_core_inputmethod_test.sh b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
index 5e123ec..b0b119b 100755
--- a/core/tests/inputmethodtests/run_core_inputmethod_test.sh
+++ b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
@@ -21,4 +21,4 @@
$COMMAND
fi
-adb shell am instrument -w -e class android.os.InputMethodTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
+adb shell am instrument -w -e class android.os.InputMethodTest,android.os.InputMethodSubtypeArrayTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
new file mode 100644
index 0000000..1e0a919
--- /dev/null
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtypeArray;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+
+import java.util.ArrayList;
+
+public class InputMethodSubtypeArrayTest extends InstrumentationTestCase {
+ @SmallTest
+ public void testInstanciate() throws Exception {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ subtypes.add(createDummySubtype(0, "en_US"));
+ subtypes.add(createDummySubtype(1, "en_US"));
+ subtypes.add(createDummySubtype(2, "ja_JP"));
+
+ final InputMethodSubtypeArray array = new InputMethodSubtypeArray(subtypes);
+ assertEquals(subtypes.size(), array.getCount());
+ assertEquals(subtypes.get(0), array.get(0));
+ assertEquals(subtypes.get(1), array.get(1));
+ assertEquals(subtypes.get(2), array.get(2));
+
+ final InputMethodSubtypeArray clonedArray = cloneViaParcel(array);
+ assertEquals(subtypes.size(), clonedArray.getCount());
+ assertEquals(subtypes.get(0), clonedArray.get(0));
+ assertEquals(subtypes.get(1), clonedArray.get(1));
+ assertEquals(subtypes.get(2), clonedArray.get(2));
+
+ final InputMethodSubtypeArray clonedClonedArray = cloneViaParcel(clonedArray);
+ assertEquals(clonedArray.getCount(), clonedClonedArray.getCount());
+ assertEquals(clonedArray.get(0), clonedClonedArray.get(0));
+ assertEquals(clonedArray.get(1), clonedClonedArray.get(1));
+ assertEquals(clonedArray.get(2), clonedClonedArray.get(2));
+ }
+
+ InputMethodSubtypeArray cloneViaParcel(final InputMethodSubtypeArray original) {
+ Parcel parcel = null;
+ try {
+ parcel = Parcel.obtain();
+ original.writeToParcel(parcel);
+ parcel.setDataPosition(0);
+ return new InputMethodSubtypeArray(parcel);
+ } finally {
+ if (parcel != null) {
+ parcel.recycle();
+ }
+ }
+ }
+
+ private static InputMethodSubtype createDummySubtype(final int id, final String locale) {
+ final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
+ return builder.setSubtypeNameResId(0)
+ .setSubtypeIconResId(0)
+ .setSubtypeId(id)
+ .setSubtypeLocale(locale)
+ .setIsAsciiCapable(true)
+ .build();
+ }
+}
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 2ce73ac..c07a6da 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -168,6 +168,21 @@
}
/**
+ * Returns the path's convexity, as defined by the content of the path.
+ * <p>
+ * A path is convex if it has a single contour, and only ever curves in a
+ * single direction.
+ * <p>
+ * This function will calculate the convexity of the path from its control
+ * points, and cache the result.
+ *
+ * @return True if the path is convex.
+ */
+ public boolean isConvex() {
+ return native_isConvex(mNativePath);
+ }
+
+ /**
* Enum for the ways a path may be filled.
*/
public enum FillType {
@@ -224,7 +239,7 @@
public void setFillType(FillType ft) {
native_setFillType(mNativePath, ft.nativeInt);
}
-
+
/**
* Returns true if the filltype is one of the INVERSE variants
*
@@ -232,18 +247,18 @@
*/
public boolean isInverseFillType() {
final int ft = native_getFillType(mNativePath);
- return (ft & 2) != 0;
+ return (ft & FillType.INVERSE_WINDING.nativeInt) != 0;
}
-
+
/**
* Toggles the INVERSE state of the filltype
*/
public void toggleInverseFillType() {
int ft = native_getFillType(mNativePath);
- ft ^= 2;
+ ft ^= FillType.INVERSE_WINDING.nativeInt;
native_setFillType(mNativePath, ft);
}
-
+
/**
* Returns true if the path is empty (contains no lines or curves)
*
@@ -719,6 +734,7 @@
private static native void native_reset(long nPath);
private static native void native_rewind(long nPath);
private static native void native_set(long native_dst, long native_src);
+ private static native boolean native_isConvex(long nPath);
private static native int native_getFillType(long nPath);
private static native void native_setFillType(long nPath, int ft);
private static native boolean native_isEmpty(long nPath);
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index bdb2f8d..0f76486 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -109,6 +109,9 @@
void DisplayList::setData(DisplayListData* data) {
delete mDisplayListData;
mDisplayListData = data;
+ if (mDisplayListData) {
+ Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+ }
}
/**
@@ -488,6 +491,8 @@
replayStruct.mDrawGlStatus);
}
+#define SHADOW_DELTA 2.0f
+
template <class T>
void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& renderer,
T& handler, const int level) {
@@ -501,34 +506,66 @@
int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
LinearAllocator& alloc = handler.allocator();
ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
- SkRegion::kIntersect_Op); // clip to 3d root bounds for now
+ SkRegion::kIntersect_Op); // clip to 3d root bounds
handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds);
- for (size_t i = 0; i < m3dNodes.size(); i++) {
- const float zValue = m3dNodes[i].key;
- DrawDisplayListOp* childOp = m3dNodes[i].value;
+ /**
+ * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
+ * with very similar Z heights to draw together.
+ *
+ * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
+ * underneath both, and neither's shadow is drawn on top of the other.
+ */
+ const size_t nonNegativeIndex = findNonNegativeIndex(m3dNodes);
+ size_t drawIndex, shadowIndex, endIndex;
+ if (mode == kNegativeZChildren) {
+ drawIndex = 0;
+ endIndex = nonNegativeIndex;
+ shadowIndex = endIndex; // draw no shadows
+ } else {
+ drawIndex = nonNegativeIndex;
+ endIndex = m3dNodes.size();
+ shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
+ }
+ float lastCasterZ = 0.0f;
+ while (shadowIndex < endIndex || drawIndex < endIndex) {
+ if (shadowIndex < endIndex) {
+ DrawDisplayListOp* casterOp = m3dNodes[shadowIndex].value;
+ DisplayList* caster = casterOp->mDisplayList;
+ const float casterZ = m3dNodes[shadowIndex].key;
+ // attempt to render the shadow if the caster about to be drawn is its caster,
+ // OR if its caster's Z value is similar to the previous potential caster
+ if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
- if (mode == kPositiveZChildren && zValue < 0.0f) continue;
- if (mode == kNegativeZChildren && zValue > 0.0f) break;
+ if (caster->mCastsShadow && caster->mAlpha > 0.0f) {
+ mat4 shadowMatrix(casterOp->mTransformFromCompositingAncestor);
+ caster->applyViewPropertyTransforms(shadowMatrix);
- DisplayList* child = childOp->mDisplayList;
- if (mode == kPositiveZChildren && zValue > 0.0f
- && child->mCastsShadow && child->mAlpha > 0.0f) {
- /* draw shadow with parent matrix applied, passing in the child's total matrix
- * TODO: consider depth in more complex scenarios (neg z, added shadow depth)
- */
- mat4 shadowMatrix(childOp->mTransformFromCompositingAncestor);
- child->applyViewPropertyTransforms(shadowMatrix);
+ DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix,
+ caster->mAlpha, &(caster->mOutline), caster->mWidth, caster->mHeight);
+ handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds);
+ }
- DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix,
- child->mAlpha, &(child->mOutline), child->mWidth, child->mHeight);
- handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds);
+ lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
+ shadowIndex++;
+ continue;
+ }
}
+ // only the actual child DL draw needs to be in save/restore,
+ // since it modifies the renderer's matrix
+ int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+
+ DrawDisplayListOp* childOp = m3dNodes[drawIndex].value;
+ DisplayList* child = childOp->mDisplayList;
+
renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
handler(childOp, renderer.getSaveCount() - 1, mClipToBounds);
childOp->mSkipInOrderDraw = true;
+
+ renderer.restoreToCount(restoreTo);
+ drawIndex++;
}
handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
}
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index aba40b6..a3577d4 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -550,6 +550,13 @@
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
+ static size_t findNonNegativeIndex(const Vector<ZDrawDisplayListOpPair>& nodes) {
+ for (size_t i = 0; i < nodes.size(); i++) {
+ if (nodes[i].key >= 0.0f) return i;
+ }
+ return nodes.size();
+ }
+
enum ChildrenSelectMode {
kNegativeZChildren,
kPositiveZChildren
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index 35327c0..ed98b96 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -38,6 +38,7 @@
libcamera_client \
libmtp \
libusbhost \
+ libjhead \
libexif \
libstagefright_amrnb_common \
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 5a2e261..a9322b9 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -595,13 +595,9 @@
mDetached = false;
}
- /**
- * This method is used as part of the View class and is not normally
- * called or subclassed by clients of GLSurfaceView.
- * Must not be called before a renderer has been set.
- */
+ /** @hide */
@Override
- protected void onDetachedFromWindow() {
+ protected void onDetachedFromWindowInternal() {
if (LOG_ATTACH_DETACH) {
Log.d(TAG, "onDetachedFromWindow");
}
@@ -609,7 +605,7 @@
mGLThread.requestExitAndWait();
}
mDetached = true;
- super.onDetachedFromWindow();
+ super.onDetachedFromWindowInternal();
}
// ----------------------------------------------------------------------
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..fe6dc52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..0f9dfc7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..aea75c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..46d2a16
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..704b4ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..d56efb5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..18b6029
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..a4dd087
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..b6ea14e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..95cf67f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..9331e52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..efd8b9e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..7f441c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..82c3842
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..ce9bae2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
new file mode 100644
index 0000000..cf34ba6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_color_space_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
new file mode 100644
index 0000000..1806688
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_color_space_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
new file mode 100644
index 0000000..5f65d8a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_contrast_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
new file mode 100644
index 0000000..a018929
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_contrast_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
new file mode 100644
index 0000000..9018a90
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_inversion_alpha"
+ android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
new file mode 100644
index 0000000..9110201
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/ic_qs_inversion_alpha"
+ android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e525fbb..5cf0453 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -39,4 +39,10 @@
<color name="status_bar_clock_color">#FFFFFFFF</color>
<drawable name="notification_item_background_color">#ff111111</drawable>
<drawable name="notification_item_background_color_pressed">#ff454545</drawable>
+
+ <!-- Tint color for inactive Quick Settings icons. -->
+ <color name="ic_qs_off">#ff404040</color>
+
+ <!-- Tint color for active Quick Settings icons. -->
+ <color name="ic_qs_on">#ffffffff</color>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 48ee1ce..174cad8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -996,8 +996,8 @@
mInversionState.toggled = enabled;
mInversionState.type = type;
// TODO: Add real icon assets.
- mInversionState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mInversionState.iconId = enabled ? R.drawable.ic_qs_inversion_on
+ : R.drawable.ic_qs_inversion_off;
mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
mInversionCallback.refreshView(mInversionTile, mInversionState);
}
@@ -1026,8 +1026,8 @@
mContrastState.contrast = contrast;
mContrastState.brightness = brightness;
// TODO: Add real icon assets.
- mContrastState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mContrastState.iconId = enabled ? R.drawable.ic_qs_contrast_on
+ : R.drawable.ic_qs_contrast_off;
mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
mContrastCallback.refreshView(mContrastTile, mContrastState);
}
@@ -1053,8 +1053,8 @@
mColorSpaceState.toggled = enabled;
mColorSpaceState.type = type;
// TODO: Add real icon assets.
- mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_bluetooth_on
- : R.drawable.ic_qs_bluetooth_off;
+ mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_color_space_on
+ : R.drawable.ic_qs_color_space_off;
mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index abc3fb1..8cd6e06 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -372,6 +372,7 @@
static final Rect mTmpNavigationFrame = new Rect();
WindowState mTopFullscreenOpaqueWindowState;
+ boolean mHideWindowBehindKeyguard;
boolean mTopIsFullscreen;
boolean mForceStatusBar;
boolean mForceStatusBarFromKeyguard;
@@ -3355,6 +3356,7 @@
@Override
public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
mTopFullscreenOpaqueWindowState = null;
+ mHideWindowBehindKeyguard = false;
mForceStatusBar = false;
mForceStatusBarFromKeyguard = false;
mForcingShowNavBar = false;
@@ -3391,7 +3393,7 @@
if (attrs.type == TYPE_KEYGUARD) {
mShowingLockscreen = true;
}
- boolean applyWindow = attrs.type >= FIRST_APPLICATION_WINDOW
+ boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
&& attrs.type <= LAST_APPLICATION_WINDOW;
if (attrs.type == TYPE_DREAM) {
// If the lockscreen was showing when the dream started then wait
@@ -3399,30 +3401,35 @@
if (!mDreamingLockscreen
|| (win.isVisibleLw() && win.hasDrawnLw())) {
mShowingDream = true;
- applyWindow = true;
+ appWindow = true;
}
}
- if (applyWindow
- && attrs.x == 0 && attrs.y == 0
- && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
- && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
- mTopFullscreenOpaqueWindowState = win;
- if ((fl & FLAG_SHOW_WHEN_LOCKED) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
- if ((fl & FLAG_DISMISS_KEYGUARD) != 0
- && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
- mDismissKeyguard = mWinDismissingKeyguard == win ?
- DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
- mWinDismissingKeyguard = win;
- mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
- }
- if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
- mAllowLockscreenWhenOn = true;
+
+ final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
+ if (appWindow) {
+ if (attrs.x == 0 && attrs.y == 0
+ && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
+ && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
+ mTopFullscreenOpaqueWindowState = win;
+ if (showWhenLocked && !mHideWindowBehindKeyguard) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
+ mHideLockScreen = true;
+ mForceStatusBarFromKeyguard = false;
+ }
+ if ((fl & FLAG_DISMISS_KEYGUARD) != 0
+ && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
+ mDismissKeyguard = mWinDismissingKeyguard == win ?
+ DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+ mWinDismissingKeyguard = win;
+ mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+ }
+ if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
+ mAllowLockscreenWhenOn = true;
+ }
+ } else if (!showWhenLocked) {
+ mHideWindowBehindKeyguard = true;
}
}
}
@@ -3509,7 +3516,7 @@
if (mKeyguard != null) {
if (localLOGV) Slog.v(TAG, "finishPostLayoutPolicyLw: mHideKeyguard="
+ mHideLockScreen);
- if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !mKeyguardDelegate.isSecure()) {
+ if (mDismissKeyguard != DISMISS_KEYGUARD_NONE && !isKeyguardSecure()) {
if (mKeyguard.hideLw(true)) {
changes |= FINISH_LAYOUT_REDO_LAYOUT
| FINISH_LAYOUT_REDO_CONFIG
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 782868e..b23ab25 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9212,8 +9212,13 @@
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
+ // We already did the pre boot receiver for this app with the current
+ // platform version, so don't do it again...
ris.remove(i);
i--;
+ // ...however, do keep it as one that has been done, so we don't
+ // forget about it when rewriting the file of last done receivers.
+ doneReceivers.add(comp);
}
}