diff options
52 files changed, 727 insertions, 95 deletions
diff --git a/api/current.txt b/api/current.txt index f1aa8bf9e2a6..e15c1d742497 100644 --- a/api/current.txt +++ b/api/current.txt @@ -9926,6 +9926,7 @@ package android.graphics { 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/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index e12e961ccdb7..41afa3921a27 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -36,7 +36,6 @@ #include <ui/Rect.h> #include <ui/Region.h> #include <ui/DisplayInfo.h> -#include <ui/FramebufferNativeWindow.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 9ad2e76642a1..d513a1002540 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -18,6 +18,7 @@ package com.android.commands.pm; import android.app.ActivityManager; import android.app.ActivityManagerNative; +import android.app.IActivityManager; import android.content.ComponentName; import android.content.pm.ApplicationInfo; import android.content.pm.ContainerEncryptionParams; @@ -1089,13 +1090,16 @@ public final class Pm { public void runListUsers() { try { + IActivityManager am = ActivityManagerNative.getDefault(); + List<UserInfo> users = mUm.getUsers(false); if (users == null) { System.err.println("Error: couldn't get users"); } else { System.out.println("Users:"); for (int i = 0; i < users.size(); i++) { - System.out.println("\t" + users.get(i).toString()); + String running = am.isUserRunning(users.get(i).id, false) ? " running" : ""; + System.out.println("\t" + users.get(i).toString() + running); } } } catch (RemoteException e) { diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java index 5b6f154b9692..89c17c7f7a9b 100644 --- a/core/java/android/net/CaptivePortalTracker.java +++ b/core/java/android/net/CaptivePortalTracker.java @@ -421,6 +421,13 @@ public class CaptivePortalTracker extends StateMachine { 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/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java index 8240ea6abc56..5852ce4ab9dc 100644 --- a/core/java/android/nfc/tech/Ndef.java +++ b/core/java/android/nfc/tech/Ndef.java @@ -277,6 +277,8 @@ public final class Ndef extends BasicTagTechnology { throw new TagLostException(); } return msg; + } else if (!tagService.isPresent(serviceHandle)) { + throw new TagLostException(); } else { return null; } diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 9b23b3527968..1f211c21f0b0 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -255,8 +255,9 @@ public class SurfaceView extends View { updateWindow(false, false); } + /** @hide */ @Override - protected void onDetachedFromWindow() { + protected void onDetachedFromWindowInternal() { if (mGlobalListenersAdded) { ViewTreeObserver observer = getViewTreeObserver(); observer.removeOnScrollChangedListener(mScrollChangedListener); @@ -278,7 +279,7 @@ public class SurfaceView extends View { 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 ef0d80d73cde..3cfe5e916937 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -228,10 +228,11 @@ public class TextureView extends View { } } + /** @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 a57b3111cae7..827c4ccd1f1f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -10838,11 +10838,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } 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 9f2bf3383985..f8160c88f974 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -37,6 +37,7 @@ import android.util.Printer; 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { if (!subtype.isAuxiliary()) { isAuxIme = false; } - mSubtypes.add(subtype); + subtypes.add(subtype); } } } catch (NameNotFoundException e) { @@ -216,7 +218,7 @@ public final class InputMethodInfo implements Parcelable { if (parser != null) parser.close(); } - if (mSubtypes.size() == 0) { + if (subtypes.size() == 0) { isAuxIme = false; } @@ -225,14 +227,15 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { 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 @@ public final class InputMethodInfo implements Parcelable { mSettingsActivityName = settingsActivity; mIsDefaultResId = isDefaultResId; mIsAuxIme = isAuxIme; - if (subtypes != null) { - mSubtypes.addAll(subtypes); - } + mSubtypes = new InputMethodSubtypeArray(subtypes); mForceDefault = forceDefault; mSupportsSwitchingToNextInputMethod = true; } @@ -364,7 +365,7 @@ public final class InputMethodInfo implements Parcelable { * 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 @@ public final class InputMethodInfo implements Parcelable { * Return the count of the subtypes of Input Method. */ public int getSubtypeCount() { - return mSubtypes.size(); + return mSubtypes.getCount(); } /** @@ -479,7 +480,7 @@ public final class InputMethodInfo implements Parcelable { 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 000000000000..5bef71fcd73b --- /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 826bcecd51c9..81d36a4db1ff 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -2139,10 +2139,11 @@ public class WebView extends AbsoluteLayout 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 e5cb16fa65e3..687036ca14ef 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -4729,10 +4729,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 325a27d70a3c..e51345cb619b 100644 --- a/core/java/com/android/internal/view/IInputMethodManager.aidl +++ b/core/java/com/android/internal/view/IInputMethodManager.aidl @@ -32,7 +32,9 @@ import com.android.internal.view.IInputMethodClient; * 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 429f177c9d9d..e580d36ac867 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -72,11 +72,16 @@ public: *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 @@ static JNINativeMethod methods[] = { {"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-iw/strings.xml b/core/res/res/values-iw/strings.xml index 096c4eddb87f..d3e1cddbd698 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -605,7 +605,7 @@ <string name="permlab_accessNetworkState" msgid="4951027964348974773">"הצג חיבורי רשת"</string> <string name="permdesc_accessNetworkState" msgid="8318964424675960975">"מאפשר לאפליקציה להציג מידע לגבי חיבורי רשת, למשל, אילו רשתות קיימות ומחוברות."</string> <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"גישת רשת מלאה"</string> - <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"מאפשר לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן ואפליקציות אחרות מספקות אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string> + <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"מאפשר לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן, כמו אפליקציות אחרות, מספק אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string> <string name="permlab_writeApnSettings" msgid="505660159675751896">"שנה/עכב הגדרות רשת ותנועה"</string> <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"מאפשר לאפליקציה לשנות את הגדרות הרשת ולעכב ולבדוק את כל תנועת הרשת, לדוגמה, לשנות את ה-proxy והיציאה של כל רשת APN. אפליקציות זדוניות עלולות לעקוב אחר חבילות רשת, לבצע הפניה מחדש שלהן או לשנות אותן, ללא ידיעתך."</string> <string name="permlab_changeNetworkState" msgid="958884291454327309">"שנה את קישוריות הרשת"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index ad2f63c931be..544fd5b5e15b 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -1138,7 +1138,7 @@ <string name="chooseUsbActivity" msgid="6894748416073583509">"選取要以 USB 裝置存取的應用程式"</string> <string name="noApplications" msgid="2991814273936504689">"沒有應用程式可執行這項操作。"</string> <string name="aerr_title" msgid="1905800560317137752"></string> - <string name="aerr_application" msgid="932628488013092776">"很抱歉,<xliff:g id="APPLICATION">%1$s</xliff:g> 已停止。"</string> + <string name="aerr_application" msgid="932628488013092776">"很抱歉,<xliff:g id="APPLICATION">%1$s</xliff:g>已停止運作。"</string> <string name="aerr_process" msgid="4507058997035697579">"很抱歉,處理程序 <xliff:g id="PROCESS">%1$s</xliff:g> 已停止。"</string> <string name="anr_title" msgid="4351948481459135709"></string> <string name="anr_activity_application" msgid="1904477189057199066">"<xliff:g id="APPLICATION">%2$s</xliff:g> 沒有回應。\n\n您要結束嗎?"</string> diff --git a/core/res/res/values/styles_micro.xml b/core/res/res/values/styles_micro.xml index c35bd48187f8..52d90bce3ff9 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 e429f96928d6..7c0b7bc1103d 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 5e123ec20a2f..b0b119b47004 100755 --- a/core/tests/inputmethodtests/run_core_inputmethod_test.sh +++ b/core/tests/inputmethodtests/run_core_inputmethod_test.sh @@ -21,4 +21,4 @@ if [[ $rebuild == true ]]; then $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 000000000000..1e0a9190558e --- /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 2ce73acd12d3..c07a6dabbabc 100644 --- a/graphics/java/android/graphics/Path.java +++ b/graphics/java/android/graphics/Path.java @@ -168,6 +168,21 @@ public class Path { } /** + * 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 class Path { 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 class Path { */ 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 @@ public class Path { 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 bdb2f8d4c444..0f7648698d27 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -109,6 +109,9 @@ void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) { void DisplayList::setData(DisplayListData* data) { delete mDisplayListData; mDisplayListData = data; + if (mDisplayListData) { + Caches::getInstance().registerFunctors(mDisplayListData->functorCount); + } } /** @@ -488,6 +491,8 @@ void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) { 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 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren 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 (caster->mCastsShadow && caster->mAlpha > 0.0f) { + mat4 shadowMatrix(casterOp->mTransformFromCompositingAncestor); + caster->applyViewPropertyTransforms(shadowMatrix); + + DisplayListOp* shadowOp = new (alloc) DrawShadowOp(shadowMatrix, + caster->mAlpha, &(caster->mOutline), caster->mWidth, caster->mHeight); + handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds); + } - if (mode == kPositiveZChildren && zValue < 0.0f) continue; - if (mode == kNegativeZChildren && zValue > 0.0f) break; + 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; - 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, - child->mAlpha, &(child->mOutline), child->mWidth, child->mHeight); - handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds); - } 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 aba40b662533..a3577d411198 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -550,6 +550,13 @@ public: 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 35327c0a3be7..ed98b9630af7 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -38,6 +38,7 @@ LOCAL_SHARED_LIBRARIES := \ 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 5a2e261fa3a4..a9322b993101 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -595,13 +595,9 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback 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 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback 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 Binary files differnew file mode 100644 index 000000000000..fe6dc5296dbd --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png Binary files differnew file mode 100644 index 000000000000..0f9dfc7fdcec --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png Binary files differnew file mode 100644 index 000000000000..aea75c105bd1 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png 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 Binary files differnew file mode 100644 index 000000000000..46d2a16c5eee --- /dev/null +++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png Binary files differnew file mode 100644 index 000000000000..704b4ecf79c0 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png Binary files differnew file mode 100644 index 000000000000..d56efb5081f4 --- /dev/null +++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png 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 Binary files differnew file mode 100644 index 000000000000..18b6029649c8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png Binary files differnew file mode 100644 index 000000000000..a4dd0878879d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png Binary files differnew file mode 100644 index 000000000000..b6ea14e6dbdb --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png 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 Binary files differnew file mode 100644 index 000000000000..95cf67f008d6 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png Binary files differnew file mode 100644 index 000000000000..9331e529ea20 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png Binary files differnew file mode 100644 index 000000000000..efd8b9ee2201 --- /dev/null +++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png 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 Binary files differnew file mode 100644 index 000000000000..7f441c812b76 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png Binary files differnew file mode 100644 index 000000000000..82c3842ff3d9 --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png Binary files differnew file mode 100644 index 000000000000..ce9bae257d8b --- /dev/null +++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png 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 000000000000..cf34ba6421dc --- /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 000000000000..180668887ea1 --- /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 000000000000..5f65d8aceee4 --- /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 000000000000..a01892905b75 --- /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 000000000000..9018a90e34a7 --- /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 000000000000..91102019fa0a --- /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-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 797f713b69fa..29ca84a93fc3 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -69,7 +69,7 @@ <string name="screenshot_failed_title" msgid="705781116746922771">"Nepavyko užfiksuoti ekrano kopijos."</string> <string name="screenshot_failed_text" msgid="8134011269572415402">"Nepavyko išsaugoti ekrano kopijos. Gali būti naudojama atmintis."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string> - <string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos grotuvą (MTP)"</string> + <string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos leistuvą (MTP)"</string> <string name="use_ptp_button_title" msgid="7517127540301625751">"Įmontuoti kaip fotoaparatą (PTP)"</string> <string name="installer_cd_button_title" msgid="2312667578562201583">"Įdiegti „Mac“ skirtą „Android“ perkėl. priem. pr."</string> <string name="accessibility_back" msgid="567011538994429120">"Atgal"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 83fdd12962f9..bf2d7ce2b0bc 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -199,7 +199,7 @@ <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string> <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"未連線"</string> <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"沒有網路"</string> - <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"關閉 Wi-Fi"</string> + <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi:關閉"</string> <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"投放螢幕"</string> <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string> <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index e525fbb01bb4..5cf0453aafe2 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 48ee1ce46865..174cad8c324e 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 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, 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 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, 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 @@ class QuickSettingsModel implements BluetoothStateChangeCallback, 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 abc3fb1fcc21..8cd6e06f1717 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final Rect mTmpNavigationFrame = new Rect(); WindowState mTopFullscreenOpaqueWindowState; + boolean mHideWindowBehindKeyguard; boolean mTopIsFullscreen; boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; @@ -3355,6 +3356,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { mTopFullscreenOpaqueWindowState = null; + mHideWindowBehindKeyguard = false; mForceStatusBar = false; mForceStatusBarFromKeyguard = false; mForcingShowNavBar = false; @@ -3391,7 +3393,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 0b0b4efb3e2a..782868edf172 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1073,6 +1073,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int IMMERSIVE_MODE_LOCK_MSG = 37; static final int PERSIST_URI_GRANTS_MSG = 38; static final int REQUEST_ALL_PSS_MSG = 39; + static final int START_RELATED_USERS_MSG = 40; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1686,6 +1687,12 @@ public final class ActivityManagerService extends ActivityManagerNative requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); break; } + case START_RELATED_USERS_MSG: { + synchronized (ActivityManagerService.this) { + startRelatedUsersLocked(); + } + break; + } } } }; @@ -5164,10 +5171,11 @@ public final class ActivityManagerService extends ActivityManagerNative userId); } } + scheduleStartRelatedUsersLocked(); } } } - + final void ensureBootCompleted() { boolean booting; boolean enableScreen; @@ -5177,7 +5185,7 @@ public final class ActivityManagerService extends ActivityManagerNative enableScreen = !mBooted; mBooted = true; } - + if (booting) { finishBooting(); } @@ -16105,6 +16113,8 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException(msg); } + if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); + final long ident = Binder.clearCallingIdentity(); try { synchronized (this) { @@ -16365,6 +16375,32 @@ public final class ActivityManagerService extends ActivityManagerNative } } + void scheduleStartRelatedUsersLocked() { + if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { + mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), + DateUtils.SECOND_IN_MILLIS); + } + } + + void startRelatedUsersLocked() { + if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); + List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); + List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); + for (UserInfo relatedUser : relatedUsers) { + if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { + toStart.add(relatedUser); + } + } + final int n = toStart.size(); + int i = 0; + for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { + startUserInBackground(toStart.get(i).id); + } + if (i < n) { + Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); + } + } + void finishUserSwitch(UserStartedState uss) { synchronized (this) { if (uss.mState == UserStartedState.STATE_BOOTING @@ -16379,6 +16415,9 @@ public final class ActivityManagerService extends ActivityManagerNative android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, userId); } + + startRelatedUsersLocked(); + int num = mUserLru.size(); int i = 0; while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { @@ -16430,6 +16469,7 @@ public final class ActivityManagerService extends ActivityManagerNative } private int stopUserLocked(final int userId, final IStopUserCallback callback) { + if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); if (mCurrentUserId == userId) { return ActivityManager.USER_OP_IS_CURRENT; } |